summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--0.F_backport-inhaler-mission-no-autofail.patch12
-rw-r--r--0.F_backport-tacoma-barn-door-position.patch11
-rw-r--r--0001-quiverfull-house-correct-stairs.patch11
-rw-r--r--0003-inconsistent-ammo-names.patch193
-rw-r--r--0006-community-garden-fertilizer-not-spilled.patch17
-rw-r--r--0007-oxyacetylene-from-oxygen.patch12
-rw-r--r--0009-22-casings-can-stack.patch17
-rw-r--r--0015-normalize-drone-volume.patch56
-rw-r--r--0019-derelict-shed-is-s.patch10
-rw-r--r--0023-fix-rubbersplosion.patch19
-rw-r--r--0024-ammo-order-fix.patch167
-rw-r--r--PKGBUILD915
-rw-r--r--ammo-10_ammo-order-fix.patch763
-rw-r--r--ammo-11_fix-volume-40mm.patch22
-rw-r--r--ammo-12_fix-20x66mm-loudness.patch (renamed from 0013-fix-20x66mm-loudness.patch)4
-rw-r--r--ammo-13_fix-reloaded-50bmg.patch11
-rw-r--r--armor-01_ankle-ammo-pouch-is-not-a-backpack.patch (renamed from 0002-ankle-ammo-pouch-is-not-a-backpack.patch)6
-rw-r--r--armor-02_fix-survivor-fingerless-gloves-warmth.patch11
-rw-r--r--bionics-01_npc-can-use-more-bionics.patch (renamed from 0008-npc-can-use-more-bionics.patch)5
-rw-r--r--custom.patch254
-rw-r--r--etc-02_add-missing-price-postapoc.patch31
-rw-r--r--etc-03_fix-abstracts.patch73
-rw-r--r--faction-01_more-factions.patch62
-rw-r--r--faction-03_fix-food-supply-calculations.patch20
-rw-r--r--factioncamp-01_remove-legacy-recruiting-penalty.patch12
-rw-r--r--foods-01_fix-food-materials.patch45
-rw-r--r--foods-02_fix-food-naming.patch22
-rw-r--r--foods-03_fix-mutant-bad-taste.patch32
-rw-r--r--foods-04_allow-canned-corn-as-veggy.patch10
-rw-r--r--foods-05_fix-missing-price-postapoc.patch10
-rw-r--r--foods-06_sealed-foods-not-full.patch31
-rw-r--r--foods-07_fix-meat-scrap-description.patch19
-rw-r--r--hotfix-01_fix-negative-calories-when-creating-dry-rice-4373.patch26
-rw-r--r--hotfix-02_perf-disable-vsync-by-default-4414.patch53
-rw-r--r--hotfix-03_fix-enable-vsync-by-default-4433.patch26
-rw-r--r--hotfix-04_fix-mapgen-fix-for-level-0-of-the-Necropolis-4380.patch100
-rw-r--r--hotfix-05_fix-more-fix-for-level-0-of-the-Necropolis-4387.patch522
-rw-r--r--hotfix-06_fix-more-fix-for-level-0-of-the-Necropolis-2-4426.patch274
-rw-r--r--itemgroups-01_hk46-is-milspec.patch (renamed from 0020-hk46-is-milspec.patch)0
-rw-r--r--itemgroups-02_add-missing-mre.patch (renamed from 0011-add-missing-mre.patch)0
-rw-r--r--itemgroups-03_fix-shelter-batteries.patch41
-rw-r--r--jc_allow-bio-firestarter-on-smoker.patch39
-rw-r--r--jc_allow-hacker-laptop.patch21
-rw-r--r--jc_npcs-eat-when-hungry.patch29
-rw-r--r--meds-01_antibiotics-unhealthy.patch10
-rw-r--r--migration-01_remove-ucp.patch14
-rw-r--r--mission-01_typos.patch19
-rw-r--r--mission-02_reorder-gunslinger-quest.patch27
-rw-r--r--monsters-01_medical-zombies-called-zombies.patch (renamed from 0016-medical-zombies-called-zombies.patch)2
-rw-r--r--mutations-01_nerf-lightstep.patch (renamed from 0017-nerf-lightstep.patch)2
-rw-r--r--mutations-02_fix-evac3-background-visible.patch (renamed from 0022-fix-evac3-background-visible.patch)0
-rw-r--r--npc-01_isherwood-update.patch380
-rw-r--r--npc-02_tacoma-update.patch177
-rw-r--r--npc-03_godco-update.patch886
-rw-r--r--npc-04_island-prison-update.patch1731
-rw-r--r--npc-05_kindred-update.patch1198
-rw-r--r--npc-06_lapin-update.patch121
-rw-r--r--npc-07_lighthouse-family_v2.patch912
-rw-r--r--npc-08_nurse-takes-more-meds.patch68
-rw-r--r--npc-09_broker-takes-more-foods.patch171
-rw-r--r--npc-10_bunker-merchant.patch396
-rw-r--r--npc-11_npcs-reload-gas-mask.patch82
-rw-r--r--npc-12_fix-eddie-requiring-1000-clay.patch26
-rw-r--r--npc-20_dialogue-fixes.patch44
-rw-r--r--recipes-01_4570-dragon-can-be-dismantled.patch (renamed from 0010-4570-dragon-can-be-dismantled.patch)24
-rw-r--r--recipes-02_recon-mech-laser-typo.patch20
-rw-r--r--revert-01_removed-traits.patch149
-rw-r--r--revert-02_revert-book-revamp.patch1357
-rw-r--r--revert-03_generic-nv.patch365
-rw-r--r--revert-04_telescopic-lenses.patch53
-rw-r--r--revert-06_Obsolete-useless-hub01-basement-1457.patch1151
-rw-r--r--revert-07.5_Use-bismuth-in-recipes-related-ammo-fixes-2952.patch32
-rw-r--r--revert-07_Remove-handload-quality-distinction-1481.patch4291
-rw-r--r--revert-09_undo-yet-more-ammo-balancing.patch308
-rw-r--r--revert-11_Obsoletion-and-removal-of-useless-bathroom-fluff-247.patch515
-rw-r--r--revert-12_fix-i18n-metric-bullets-part-1-rename-.223-5.56x45mm.patch291
-rw-r--r--revert-13_fix-i18n-metric-bullets-part-2-rename-.308-7.62x51mm.patch228
-rw-r--r--revert-15_Fix-mutant-scenarios-adding-an-obsoleted-trait-2929.patch34
-rw-r--r--revert-18-Simplify-broken-limb-mending-3054.patch821
-rw-r--r--revert-19_Fix-Repair-Nanobots-3308.patch36
-rw-r--r--revert-20_Fix-tidy-warnings-3310.patch30
-rw-r--r--revert-21_fix-Erased-the-npc-Alonso-from-history-the-game-3582.patch225
-rw-r--r--revert-22_feat-content-Biodiesel-Fuel-for-Gasoline-Engines-371.patch39
-rw-r--r--revert-23_fix-balance-no-more-EXP-gain-when-a-skill-is-maxed-o.patch48
-rw-r--r--revert-24_fix-repair-nanobots-not-working-at-all-on-broken-lim.patch214
-rw-r--r--revert-26_fix-npc-splints-and-clean-up-iterator-errors-3592.patch67
-rw-r--r--revert-27_fix-NPCs-keep-their-splints-on-3589.patch30
-rw-r--r--revert-28_feat-content-semi-plausible-smokeless-gunpowder-reci.patch62
-rw-r--r--revert-30_feat-content-weapon-mount-obsoletion-part-1-4179.patch1957
-rw-r--r--revert-31_restore-vague-nether-healing.patch51
-rw-r--r--src-01_radio-can-use-ups.patch (renamed from 0.F_backport-radio-can-use-ups.patch)24
-rw-r--r--src-02_ammo-loudness-ap-times-2.patch (renamed from jc_ammo-loudness-ap-times-2.patch)0
-rw-r--r--src-03_allow-bio-firestarter-on-smoker.patch40
-rw-r--r--src-04_stop-non-faction-npc-sleep-depirvation.patch (renamed from jc_stop-non-faction-npc-sleep-depirvation.patch)0
-rw-r--r--src-05_stop-non-faction-npc-malnourishment.patch (renamed from jc_stop-non-faction-npc-malnourishment.patch)11
-rw-r--r--src-06_stop-sleeping-on-tables.patch (renamed from jc_stop-sleeping-on-tables.patch)8
-rw-r--r--src-07_allow-hacker-laptop.patch29
-rw-r--r--src-08_more-military-base-overmap.patch257
-rw-r--r--src-09_npc-eat-from-further-camp.patch11
-rw-r--r--src-10_reduced-kcal-during-sleep.patch13
-rw-r--r--src-11_fix-tacoma-farmfield.patch32
-rw-r--r--src-12_lower-lockpicking-experience.patch16
-rw-r--r--src-13_searchlights-with-plut-gen-furn.patch12
-rw-r--r--src-14_fix-npc_melee-calculations.patch11
-rw-r--r--src-15_slow-down-fungal-blossoms.patch20
-rw-r--r--src-20_fix-default-mods.patch26
-rw-r--r--terrain-02_fix-doors-for-npcs.patch (renamed from 0012-fix-doors-for-npcs.patch)0
-rw-r--r--terrain-03_tacoma-clinic-add-missing-floor.patch (renamed from 0004-tacoma-clinic-add-missing-floor.patch)0
-rw-r--r--terrain-04_lumbermill-gasoline-not-spilled.patch (renamed from 0005-lumbermill-gasoline-not-spilled.patch)0
-rw-r--r--terrain-07_rehide-redacted.patch (renamed from 0018-rehide-redacted.patch)0
-rw-r--r--terrain-09_make-firestation-shelter-wells-npc-drinkable.patch (renamed from 0.F_backport-make-firestation-shelter-wells-npc-drinkable.patch)0
-rw-r--r--terrain-10_fix-milbase_minefield.patch11
-rw-r--r--terrain-11_clean-up-map-extras.patch138
-rw-r--r--terrain-13_fix-mapgen-palettes.patch256
-rw-r--r--tools-01_foldable-bottle-is-container.patch (renamed from 0021-foldable-bottle-is-container.patch)0
-rw-r--r--tools-03_shears-use-light-battery.patch28
-rw-r--r--vampirism.patch823
-rw-r--r--vehicles-01_portable-generator-engine.patch (renamed from 0014-portable-generator-engine.patch)0
-rw-r--r--vehicles-02_fix-fbi-car-name.patch11
-rw-r--r--vehicles-03_black-box-can-be-installed.patch14
-rw-r--r--weapon-02_Fix-usp45-load-order.patch30
121 files changed, 23376 insertions, 1123 deletions
diff --git a/0.F_backport-inhaler-mission-no-autofail.patch b/0.F_backport-inhaler-mission-no-autofail.patch
deleted file mode 100644
index 32983d7..0000000
--- a/0.F_backport-inhaler-mission-no-autofail.patch
+++ /dev/null
@@ -1,12 +0,0 @@
---- a/src/mission.cpp
-+++ b/src/mission.cpp
-@@ -230,6 +230,9 @@
- } else if( type->goal == MGOAL_KILL_MONSTER_SPEC ) {
- kill_count_to_reach = kills.kill_count( monster_species ) + monster_kill_goal;
- }
-+ if( type->deadline_low != 0_turns || type->deadline_high != 0_turns ) {
-+ deadline = calendar::turn + rng( type->deadline_low, type->deadline_high );
-+ }
- type->start( this );
- status = mission_status::in_progress;
- }
diff --git a/0.F_backport-tacoma-barn-door-position.patch b/0.F_backport-tacoma-barn-door-position.patch
deleted file mode 100644
index d5f5642..0000000
--- a/0.F_backport-tacoma-barn-door-position.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- a/data/json/npcs/tacoma_ranch/NPC_ranch_foreman.json
-+++ b/data/json/npcs/tacoma_ranch/NPC_ranch_foreman.json
-@@ -122,7 +122,7 @@
- "place_nested": [ { "chunks": [ "tacoma_commune_west_wall_door" ], "x": 22, "y": 0 } ]
- },
- {
-- "om_terrain": "ranch_camp_66",
-+ "om_terrain": "ranch_camp_75",
- "translate_ter": [ { "from": "t_underbrush", "to": "t_dirt", "x": 0, "y": 0 } ],
- "place_nested": [
- { "chunks": [ "tacoma_commune_east_wall_door" ], "x": 0, "y": 0 },
diff --git a/0001-quiverfull-house-correct-stairs.patch b/0001-quiverfull-house-correct-stairs.patch
deleted file mode 100644
index ad40706..0000000
--- a/0001-quiverfull-house-correct-stairs.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- a/data/json/mapgen/house/house_quiverfull.json
-+++ b/data/json/mapgen/house/house_quiverfull.json
-@@ -29,7 +29,7 @@
- "%or E|R y| h F#.",
- "%# + + O#.",
- ".# |||R R|J 5o.",
-- ".#HHsHH|< R|n 4o.",
-+ ".#HHsHH|> R|n 4o.",
- ".#|||||| |R R|JJ 123#.",
- ".#q+ ||||+|||#.",
- ".#q+ + d#.",
diff --git a/0003-inconsistent-ammo-names.patch b/0003-inconsistent-ammo-names.patch
deleted file mode 100644
index 61d17ac..0000000
--- a/0003-inconsistent-ammo-names.patch
+++ /dev/null
@@ -1,193 +0,0 @@
---- a/data/json/items/ammo/223.json
-+++ b/data/json/items/ammo/223.json
-@@ -39,7 +39,7 @@
- "id": "556_incendiary",
- "copy-from": "556",
- "type": "AMMO",
-- "name": { "str": "5.56 NATO tracer" },
-+ "name": { "str": "5.56 NATO M856 tracer" },
- "description": "This ammunition is a one-in-five mix of M855A1 and M856 tracer rounds to help keep the weapon they are fired from on target.",
- "extend": { "effects": [ "INCENDIARY" ] }
- },
-@@ -61,7 +61,7 @@
- "id": "bp_556",
- "copy-from": "556",
- "type": "AMMO",
-- "name": { "str": "5.56 NATO, black powder" },
-+ "name": { "str": "5.56 NATO M855A1, black powder" },
- "proportional": {
- "price": 0.3,
- "damage": { "damage_type": "stab", "amount": 0.57, "armor_penetration": 0.5 },
-@@ -75,7 +75,7 @@
- "id": "bp_556_incendiary",
- "copy-from": "556_incendiary",
- "type": "AMMO",
-- "name": { "str": "5.56 NATO tracer, black powder" },
-+ "name": { "str": "5.56 NATO M856 tracer, black powder" },
- "proportional": {
- "price": 0.3,
- "damage": { "damage_type": "stab", "amount": 0.57, "armor_penetration": 0.5 },
-@@ -98,7 +98,7 @@
- "id": "reloaded_556",
- "copy-from": "556",
- "type": "AMMO",
-- "name": { "str": "5.56 NATO, reloaded" },
-+ "name": { "str": "5.56 NATO M885A1, reloaded" },
- "proportional": { "price": 0.7, "damage": { "damage_type": "stab", "amount": 0.9 }, "dispersion": 1.1 },
- "extend": { "effects": [ "RECYCLED" ] },
- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
-@@ -107,7 +107,7 @@
- "id": "reloaded_556_incendiary",
- "copy-from": "556_incendiary",
- "type": "AMMO",
-- "name": { "str": "5.56 NATO tracer, reloaded" },
-+ "name": { "str": "5.56 NATO M856 tracer, reloaded" },
- "proportional": { "price": 0.7, "damage": { "damage_type": "stab", "amount": 0.9 }, "dispersion": 1.1 },
- "extend": { "effects": [ "RECYCLED" ] },
- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
---- a/data/json/items/ammo/300blk.json
-+++ b/data/json/items/ammo/300blk.json
-@@ -26,7 +26,7 @@
- "id": "300blk_ss",
- "copy-from": "300blk",
- "type": "AMMO",
-- "name": { "str": ".300 AAC Blackout" },
-+ "name": { "str": ".300 AAC Blackout SS" },
- "description": "A subsonic .300 AAC Blackout round with a 220gr open tip match bullet. 300 BLK is an intermediate cartridge necked up from 5.56x45mm, designed to achieve similar ballistics to 7.62x39mm. It is compatible with standard AR-15 lower receivers and will feed from STANAG magazines.",
- "weight": "21 g",
- "range": 40,
---- a/data/json/items/ammo/308.json
-+++ b/data/json/items/ammo/308.json
-@@ -26,7 +26,7 @@
- "id": "762_51",
- "copy-from": "308",
- "type": "AMMO",
-- "name": { "str": "7.62x51mm M80" },
-+ "name": { "str": "7.62x51mm NATO M80" },
- "casing": "762_51_casing",
- "description": "A 7.62x51mm NATO round with a 147gr FMJ bullet. It is a powerful rifle cartridge commonly used by hunters and military snipers because of its high accuracy and long range.",
- "relative": { "damage": { "damage_type": "stab", "amount": -2, "armor_penetration": 4 }, "dispersion": -10 },
-@@ -37,7 +37,7 @@
- "id": "762_51_incendiary",
- "copy-from": "762_51",
- "type": "AMMO",
-- "name": { "str": "7.62x51mm NATO tracer" },
-+ "name": { "str": "7.62x51mm NATO M62 tracer" },
- "description": "This ammunition is a one-in-five mix of M80 and M62 tracer rounds to help keep the weapon they are fired from on target.",
- "extend": { "effects": [ "INCENDIARY" ] }
- },
-@@ -59,7 +59,7 @@
- "id": "bp_762_51",
- "copy-from": "762_51",
- "type": "AMMO",
-- "name": { "str": "7.62x51mm, black powder" },
-+ "name": { "str": "7.62x51mm NATO M80, black powder" },
- "proportional": {
- "price": 0.3,
- "damage": { "damage_type": "stab", "amount": 0.76, "armor_penetration": 0.5 },
-@@ -73,7 +73,7 @@
- "id": "bp_762_51_incendiary",
- "copy-from": "762_51_incendiary",
- "type": "AMMO",
-- "name": { "str": "7.62x51mm tracer, black powder" },
-+ "name": { "str": "7.62x51mm NATO M62 tracer, black powder" },
- "proportional": {
- "price": 0.3,
- "damage": { "damage_type": "stab", "amount": 0.76, "armor_penetration": 0.5 },
-@@ -96,7 +96,7 @@
- "id": "reloaded_762_51",
- "copy-from": "762_51",
- "type": "AMMO",
-- "name": { "str": "7.62x51mm, reloaded" },
-+ "name": { "str": "7.62x51mm NATO M80, reloaded" },
- "proportional": { "price": 0.7, "damage": { "damage_type": "stab", "amount": 0.9 }, "dispersion": 1.1 },
- "extend": { "effects": [ "RECYCLED" ] },
- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
-@@ -105,7 +105,7 @@
- "id": "reloaded_762_51_incendiary",
- "copy-from": "762_51_incendiary",
- "type": "AMMO",
-- "name": { "str": "7.62x51mm incendiary, reloaded" },
-+ "name": { "str": "7.62x51mm NATO M62 tracer, reloaded" },
- "proportional": { "price": 0.7, "damage": { "damage_type": "stab", "amount": 0.9 }, "dispersion": 1.1 },
- "extend": { "effects": [ "RECYCLED" ] },
- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
---- a/data/json/items/ammo/357mag.json
-+++ b/data/json/items/ammo/357mag.json
-@@ -2,8 +2,8 @@
- {
- "id": "357mag_fmj",
- "type": "AMMO",
-- "name": { "str": ".357 magnum FMJ" },
-- "description": "Jacketed .357 magnum ammunition. The .357 magnum round is derived from the earlier .38 special, with a marginally longer case and generating greater pressure.",
-+ "name": { "str": ".357 Magnum FMJ" },
-+ "description": "Jacketed .357 Magnum ammunition. The .357 Magnum round is derived from the earlier .38 special, with a marginally longer case and generating greater pressure.",
- "weight": "8 g",
- "volume": "250 ml",
- "price": 140,
-@@ -27,8 +27,8 @@
- "id": "357mag_jhp",
- "copy-from": "357mag_fmj",
- "type": "AMMO",
-- "name": { "str": ".357 magnum JHP" },
-- "description": "Jacketed hollow point .357 magnum ammunition. The .357 magnum round is derived from the earlier .38 special, with a marginally longer case and generating greater pressure.",
-+ "name": { "str": ".357 Magnum JHP" },
-+ "description": "Jacketed hollow point .357 Magnum ammunition. The .357 Magnum round is derived from the earlier .38 special, with a marginally longer case and generating greater pressure.",
- "damage": { "damage_type": "stab", "amount": 42, "armor_penetration": 0 }
- },
- {
---- a/data/json/items/ammo/45.json
-+++ b/data/json/items/ammo/45.json
-@@ -76,7 +76,7 @@
- "id": "reloaded_45_acp",
- "copy-from": "45_acp",
- "type": "AMMO",
-- "name": { "str": ".45 FMJ, reloaded" },
-+ "name": { "str": ".45 ACP FMJ, reloaded" },
- "proportional": { "price": 0.7, "damage": { "damage_type": "stab", "amount": 0.9 }, "dispersion": 1.1 },
- "extend": { "effects": [ "RECYCLED" ] },
- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
---- a/data/json/items/ammo/50.json
-+++ b/data/json/items/ammo/50.json
-@@ -70,7 +70,7 @@
- "id": "reloaded_50_incendiary",
- "copy-from": "50_incendiary",
- "type": "AMMO",
-- "name": { "str": ".50 BMG tracer, reloaded" },
-+ "name": { "str": ".50 BMG M17 tracer, reloaded" },
- "description": "A tracer variant of the powerful .50 BMG round. Tracer rounds help to keep the weapon they are fired from on target at the risk of igniting flammable substances. This one has been hand-reloaded.",
- "proportional": { "price": 0.7, "damage": { "damage_type": "stab", "amount": 0.9 }, "dispersion": 1.1 },
- "extend": { "effects": [ "RECYCLED" ] },
-@@ -90,7 +90,7 @@
- "id": "reloaded_50ss",
- "copy-from": "50ss",
- "type": "AMMO",
-- "name": { "str": ".50 BMG AP, reloaded" },
-+ "name": { "str": ".50 BMG M2 AP, reloaded" },
- "description": "Variant of the .50 BMG round that uses a core hardened steel. Penetration is increased, but damage is reduced. This one has been hand-reloaded.",
- "proportional": { "price": 0.7, "damage": { "damage_type": "stab", "amount": 0.9 }, "dispersion": 1.1 },
- "extend": { "effects": [ "RECYCLED" ] },
---- a/data/json/items/ammo/5x50.json
-+++ b/data/json/items/ammo/5x50.json
-@@ -38,7 +38,7 @@
- "id": "reloaded_5x50dart",
- "copy-from": "5x50dart",
- "type": "AMMO",
-- "name": { "str": "5x50mm flechette, reloaded" },
-+ "name": { "str": "RA110 5x50mm flechette, reloaded" },
- "price_postapoc": 1200,
- "description": "Designed to defeat modern body armor, the Rivtech 5x50mm flechette round features a biodegradable sabot and a single, fin-stabilized penetrator. This one has been hand-reloaded.",
- "effects": [ "COOKOFF", "RECYCLED" ],
---- a/data/json/items/ammo/762x25.json
-+++ b/data/json/items/ammo/762x25.json
-@@ -68,7 +68,8 @@
- "id": "reloaded_762_25",
- "copy-from": "762_25hot",
- "type": "AMMO",
-- "name": { "str": "7.62x25mm, reloaded" },
-- "proportional": { "price": 0.7, "damage": { "damage_type": "stab", "amount": 0.9, "armor_penetration": 0.9 }, "dispersion": 1.1 }
-+ "name": { "str": "7.62x25mm FMJ, reloaded" },
-+ "proportional": { "price": 0.7, "damage": { "damage_type": "stab", "amount": 0.9, "armor_penetration": 0.9 }, "dispersion": 1.1 },
-+ "extend": { "effects": [ "RECYCLED" ] }
- }
- ]
diff --git a/0006-community-garden-fertilizer-not-spilled.patch b/0006-community-garden-fertilizer-not-spilled.patch
deleted file mode 100644
index dfc3d29..0000000
--- a/0006-community-garden-fertilizer-not-spilled.patch
+++ /dev/null
@@ -1,17 +0,0 @@
---- a/data/json/mapgen/garden_community.json
-+++ b/data/json/mapgen/garden_community.json
-@@ -141,10 +141,10 @@
- "|": "f_null"
- },
- "place_liquids": [
-- { "liquid": "fertilizer_liquid", "chance": 1, "amount": [ 2, 3 ], "x": 4, "y": 4 },
-- { "liquid": "fertilizer_liquid", "chance": 1, "amount": [ 2, 3 ], "x": 4, "y": 5 },
-- { "liquid": "fertilizer_liquid", "chance": 1, "amount": [ 2, 3 ], "x": 5, "y": 4 },
-- { "liquid": "fertilizer_liquid", "chance": 1, "amount": [ 2, 3 ], "x": 5, "y": 5 }
-+ { "liquid": "fertilizer_liquid", "chance": 1, "amount": [ 2, 3 ], "x": 9, "y": 9 },
-+ { "liquid": "fertilizer_liquid", "chance": 1, "amount": [ 2, 3 ], "x": 10, "y": 9 },
-+ { "liquid": "fertilizer_liquid", "chance": 1, "amount": [ 2, 3 ], "x": 9, "y": 10 },
-+ { "liquid": "fertilizer_liquid", "chance": 1, "amount": [ 2, 3 ], "x": 10, "y": 10 }
- ],
- "items": { "D": { "item": "hydro", "chance": 15 }, "#": { "item": "hydro", "chance": 15 } },
- "place_items": [
diff --git a/0007-oxyacetylene-from-oxygen.patch b/0007-oxyacetylene-from-oxygen.patch
deleted file mode 100644
index 8da7688..0000000
--- a/0007-oxyacetylene-from-oxygen.patch
+++ /dev/null
@@ -1,12 +0,0 @@
---- a/data/json/recipes/ammo/weldgas.json
-+++ b/data/json/recipes/ammo/weldgas.json
-@@ -7,8 +8,9 @@
- "charges": 120,
- "book_learn": [ [ "textbook_chemistry", 4 ], [ "textbook_gaswarfare", 5 ], [ "atomic_survival", 3 ] ],
- "qualities": [ { "id": "PRESSURIZATION", "level": 1 } ],
-+ "tools": [ [ [ "oxygen_tank", 24 ], [ "oxygen_cylinder", 24 ], [ "smoxygen_tank", 24 ] ] ],
-- "components": [ [ [ "oxygen", 24 ] ], [ [ "acetylene", 96 ] ] ]
-+ "components": [ [ [ "acetylene", 96 ] ] ]
- },
- {
- "result": "acetylene",
diff --git a/0009-22-casings-can-stack.patch b/0009-22-casings-can-stack.patch
deleted file mode 100644
index e52b8bb..0000000
--- a/0009-22-casings-can-stack.patch
+++ /dev/null
@@ -1,17 +0,0 @@
---- a/data/json/items/generic/casing.json
-+++ b/data/json/items/generic/casins.json
-@@ -31,13 +31,11 @@
- },
- {
- "id": "22_casing_new",
-+ "copy-from": "casing",
- "type": "GENERIC",
-- "category": "spare_parts",
- "price": 100,
- "price_postapoc": 0,
- "name": { "str": "unused .22 casing" },
-- "symbol": "=",
-- "color": "yellow",
- "description": "An unfired, like-new .22 round casing, with the primer still intact.",
- "material": [ "powder", "brass" ],
- "volume": "3 ml",
diff --git a/0015-normalize-drone-volume.patch b/0015-normalize-drone-volume.patch
deleted file mode 100644
index a45ebf0..0000000
--- a/0015-normalize-drone-volume.patch
+++ /dev/null
@@ -1,56 +0,0 @@
---- a/data/json/items/corpses/inactive_bots.json
-+++ b/data/json/items/corpses/inactive_bots.json
-@@ -5,7 +5,7 @@
- "name": { "str": "inactive EMP hack" },
- "description": "This is an inactive EMP hack. EMP hacks are fist-sized robots that fly through the air. This one contains an EMP grenade and attacks by flying at its target and detonating. Use this item to reprogram and release the EMP hack. Electronics and computer skill determines if the targeting matrix is reprogrammed successfully.",
- "weight": "4700 g",
-- "volume": "750 ml",
-+ "volume": "250 ml",
- "price": 64500,
- "to_hit": -3,
- "bashing": 6,
-@@ -31,7 +31,7 @@
- "name": { "str": "inactive C-4 hack" },
- "description": "This is an inactive C-4 hack. C-4 hacks are fist-sized robots that fly through the air. This one contains some C-4 and attacks by flying at its target and detonating. Use this item to reprogram and activate the C-4 hack. Electronics and computer skill determines if the targeting matrix is reprogrammed successfully.",
- "weight": "5870 g",
-- "volume": "250 ml",
-+ "volume": "1000 ml",
- "price": 67500,
- "to_hit": -3,
- "bashing": 6,
-@@ -57,7 +57,7 @@
- "name": { "str": "inactive flashbang hack" },
- "description": "This is an inactive flashbang hack. Flashbang hacks are fist-sized robots that fly through the air. This one contains a flashbang and attacks by flying at its target and detonating. Use this item to reprogram and activate the flashbang hack. Electronics and computer skill determines if the targeting matrix is reprogrammed successfully.",
- "weight": "4536 g",
-- "volume": "750 ml",
-+ "volume": "250 ml",
- "price": 59500,
- "to_hit": -3,
- "bashing": 6,
-@@ -83,7 +83,7 @@
- "name": { "str": "inactive tear gas hack" },
- "description": "This is an inactive tear gas hack. Tear gas hacks are fist-sized robots that fly through the air. This one contains a tear gas canister and attacks by flying at its target and releasing tear gas. Use this item to reprogram and activate the tear gas hack. Electronics and computer skill determines if the targeting matrix is reprogrammed successfully.",
- "weight": "5360 g",
-- "volume": "750 ml",
-+ "volume": "250 ml",
- "price": 60500,
- "to_hit": -3,
- "bashing": 6,
-@@ -179,7 +179,7 @@
- "name": { "str": "inactive manhack" },
- "description": "This is an inactive manhack. Manhacks are fist-sized robots that fly through the air. They are covered with whirring blades and attack by throwing themselves against their target. Use this item to reprogram and activate the manhack. Electronics and computer skill determines if the targeting matrix is reprogrammed successfully.",
- "weight": "5400 g",
-- "volume": "750 ml",
-+ "volume": "250 ml",
- "price": 60000,
- "to_hit": -3,
- "bashing": 6,
-@@ -205,7 +205,7 @@
- "name": { "str": "inactive mininuke hack" },
- "description": "This is an inactive mininuke hack. Many times as large as a normal manhack, a mininuke hack contains a mininuke and attack by flying at their target and detonating. Use this item to reprogram and activate the mininuke hack. Electronics and computer skill determines if the targeting matrix is reprogrammed successfully.",
- "weight": "25000 g",
-- "volume": "18750 ml",
-+ "volume": "16000 ml",
- "price": 2677500,
- "to_hit": -3,
- "bashing": 6,
diff --git a/0019-derelict-shed-is-s.patch b/0019-derelict-shed-is-s.patch
deleted file mode 100644
index d97550c..0000000
--- a/0019-derelict-shed-is-s.patch
+++ /dev/null
@@ -1,10 +0,0 @@
---- a/data/json/overmap/map_extras.json
-+++ b/data/json/overmap/map_extras.json
-@@ -256,6 +256,7 @@
- "name": "Derelict shed",
- "description": "A collapsed shed.",
- "generator": { "generator_method": "update_mapgen", "generator_id": "mx_fallen_shed_map" },
-+ "sym": "s",
- "color": "brown",
- "autonote": true
- },
diff --git a/0023-fix-rubbersplosion.patch b/0023-fix-rubbersplosion.patch
deleted file mode 100644
index ef06b41..0000000
--- a/0023-fix-rubbersplosion.patch
+++ /dev/null
@@ -1,19 +0,0 @@
---- a/data/json/items/ammo.json
-+++ b/data/json/items/ammo.json
-@@ -686,7 +686,7 @@
- "count": 25
- },
- {
-- "type": "AMMO",
-+ "type": "TOOL",
- "id": "chunk_rubber",
- "category": "spare_parts",
- "price": 75,
-@@ -697,7 +697,6 @@
- "material": "rubber",
- "volume": "250 ml",
- "weight": "38 g",
-- "ammo_type": "components",
- "flags": [ "NO_SALVAGE" ]
- },
- {
diff --git a/0024-ammo-order-fix.patch b/0024-ammo-order-fix.patch
deleted file mode 100644
index 01c91fb..0000000
--- a/0024-ammo-order-fix.patch
+++ /dev/null
@@ -1,167 +0,0 @@
---- a/data/json/items/ammo/22.json
-+++ b/data/json/items/ammo/22.json
-@@ -1,16 +1,5 @@
- [
- {
-- "id": "22_cphp",
-- "copy-from": "22_lr",
-- "type": "AMMO",
-- "name": { "str": ".22 CPHP" },
-- "description": ".22 Long Rifle ammunition with 30gr copper-plated, hollow-point bullets. Has a higher velocity and slightly more stopping power than lead round-nose ammunition, but armor will have a magnified effect on its already-low penetration.",
-- "//": "Hollowpoint damage increase of 25%",
-- "damage": { "damage_type": "stab", "amount": 20, "armor_penetration": 0 },
-- "relative": { "range": 3 },
-- "proportional": { "recoil": 1.5 }
-- },
-- {
- "id": "22_lr",
- "type": "AMMO",
- "name": { "str": ".22 LR" },
-@@ -35,6 +24,17 @@
- "effects": [ "COOKOFF" ]
- },
- {
-+ "id": "22_cphp",
-+ "copy-from": "22_lr",
-+ "type": "AMMO",
-+ "name": { "str": ".22 CPHP" },
-+ "description": ".22 Long Rifle ammunition with 30gr copper-plated, hollow-point bullets. Has a higher velocity and slightly more stopping power than lead round-nose ammunition, but armor will have a magnified effect on its already-low penetration.",
-+ "//": "Hollowpoint damage increase of 25%",
-+ "damage": { "damage_type": "stab", "amount": 20, "armor_penetration": 0 },
-+ "relative": { "range": 3 },
-+ "proportional": { "recoil": 1.5 }
-+ },
-+ {
- "id": "22_ratshot",
- "copy-from": "22_cphp",
- "type": "AMMO",
---- a/data/json/items/ammo/38.json
-+++ b/data/json/items/ammo/38.json
-@@ -1,14 +1,5 @@
- [
- {
-- "id": "38_fmj",
-- "copy-from": "38_special",
-- "type": "AMMO",
-- "name": { "str": ".38 FMJ" },
-- "description": ".38 Special ammunition with brass jacketed 130gr bullets. The .38 Special round has been known from its inception for its accuracy and low recoil.",
-- "//": "Base damage of 20, balance increase of two-nineths.",
-- "relative": { "damage": { "damage_type": "stab", "amount": -6, "armor_penetration": 14 } }
-- },
-- {
- "id": "38_special",
- "type": "AMMO",
- "name": { "str": ".38 Special" },
-@@ -33,6 +24,15 @@
- "effects": [ "COOKOFF" ]
- },
- {
-+ "id": "38_fmj",
-+ "copy-from": "38_special",
-+ "type": "AMMO",
-+ "name": { "str": ".38 FMJ" },
-+ "description": ".38 Special ammunition with brass jacketed 130gr bullets. The .38 Special round has been known from its inception for its accuracy and low recoil.",
-+ "//": "Base damage of 20, balance increase of two-nineths.",
-+ "relative": { "damage": { "damage_type": "stab", "amount": -6, "armor_penetration": 14 } }
-+ },
-+ {
- "id": "reloaded_38_fmj",
- "copy-from": "38_fmj",
- "type": "AMMO",
---- a/data/json/items/ammo/40.json
-+++ b/data/json/items/ammo/40.json
-@@ -1,14 +1,5 @@
- [
- {
-- "id": "40fmj",
-- "copy-from": "40sw",
-- "type": "AMMO",
-- "name": { "str": ".40 S&W FMJ" },
-- "description": ".40 S&W ammunition with 180gr FMJ bullets. Designed to retain the 10mm Auto cartridge's power with lower recoil, the .40 S&W round became popular for law enforcement and personal defense.",
-- "//": "Base damage of 23, balance increase of two-nineths.",
-- "relative": { "damage": { "damage_type": "stab", "amount": -7, "armor_penetration": 16 } }
-- },
-- {
- "id": "40sw",
- "type": "AMMO",
- "name": { "str": ".40 S&W JHP" },
-@@ -33,6 +24,15 @@
- "effects": [ "COOKOFF" ]
- },
- {
-+ "id": "40fmj",
-+ "copy-from": "40sw",
-+ "type": "AMMO",
-+ "name": { "str": ".40 S&W FMJ" },
-+ "description": ".40 S&W ammunition with 180gr FMJ bullets. Designed to retain the 10mm Auto cartridge's power with lower recoil, the .40 S&W round became popular for law enforcement and personal defense.",
-+ "//": "Base damage of 23, balance increase of two-nineths.",
-+ "relative": { "damage": { "damage_type": "stab", "amount": -7, "armor_penetration": 16 } }
-+ },
-+ {
- "id": "bp_40fmj",
- "copy-from": "40fmj",
- "type": "AMMO",
---- a/data/json/items/ammo/45.json
-+++ b/data/json/items/ammo/45.json
-@@ -1,14 +1,5 @@
- [
- {
-- "id": "45_acp",
-- "copy-from": "45_jhp",
-- "type": "AMMO",
-- "name": { "str": ".45 ACP FMJ" },
-- "description": ".45 ACP ammunition with 230gr FMJ bullets. Noted for its stopping power, the .45 ACP round has been common for almost 150 years.",
-- "//": "Base damage of 27, balance increase of two-nineths.",
-- "relative": { "damage": { "damage_type": "stab", "amount": -8, "armor_penetration": 18 } }
-- },
-- {
- "id": "45_jhp",
- "type": "AMMO",
- "name": { "str": ".45 ACP JHP" },
-@@ -32,6 +23,15 @@
- "effects": [ "COOKOFF" ]
- },
- {
-+ "id": "45_acp",
-+ "copy-from": "45_jhp",
-+ "type": "AMMO",
-+ "name": { "str": ".45 ACP FMJ" },
-+ "description": ".45 ACP ammunition with 230gr FMJ bullets. Noted for its stopping power, the .45 ACP round has been common for almost 150 years.",
-+ "//": "Base damage of 27, balance increase of two-nineths.",
-+ "relative": { "damage": { "damage_type": "stab", "amount": -8, "armor_penetration": 18 } }
-+ },
-+ {
- "id": "45_super",
- "copy-from": "45_jhp",
- "type": "AMMO",
---- a/data/json/items/ammo/460.json
-+++ b/data/json/items/ammo/460.json
-@@ -1,13 +1,5 @@
- [
- {
-- "id": "460_fmj",
-- "copy-from": "460_rowland",
-- "type": "AMMO",
-- "name": { "str": ".460 Rowland HCFN" },
-- "description": "A plated, hard cast flat nosed variant of the .460 Rowland round. This increases penetration slightly at the cost of reduced damage from expansion.",
-- "relative": { "damage": { "damage_type": "stab", "amount": -4, "armor_penetration": 8 } }
-- },
-- {
- "id": "460_rowland",
- "copy-from": "44magnum",
- "type": "AMMO",
-@@ -18,6 +10,14 @@
- "proportional": { "range": 0.95, "damage": { "damage_type": "stab", "amount": 0.95, "armor_penetration": 0.95 }, "recoil": 0.95 }
- },
- {
-+ "id": "460_fmj",
-+ "copy-from": "460_rowland",
-+ "type": "AMMO",
-+ "name": { "str": ".460 Rowland HCFN" },
-+ "description": "A plated, hard cast flat nosed variant of the .460 Rowland round. This increases penetration slightly at the cost of reduced damage from expansion.",
-+ "relative": { "damage": { "damage_type": "stab", "amount": -4, "armor_penetration": 8 } }
-+ },
-+ {
- "id": "bp_460_fmj",
- "copy-from": "460_fmj",
- "type": "AMMO",
diff --git a/PKGBUILD b/PKGBUILD
index efb42a2..9a438a4 100644
--- a/PKGBUILD
+++ b/PKGBUILD
@@ -1,21 +1,24 @@
# Maintainer: jc_gargma <jc_gargma@iserlohn-fortress.net>
+# Contributor: aqua <aqua@iserlohn-fortress.net>
# Maintainer (Arch): Kyle Keen <keenerd@gmail.com>
# # I maintain this because:
# Arch version is not BN
# Arch version has non-functional desktop file
# Arch version lacks additional optimization and hardening flags
-# Arch version lacks the MSX++UnDeadPeopleEdition tileset
-# Arch version lacks the @ soundpack
-# Arch version lacks the CO.AG musicpack
+# Arch version lacks numerous bugfixes I created
+# Arch version has some vanilla balancing changes I disagree with
+# Arch version segfaults due to -Wp,-D_GLIBCXX_ASSERTIONS
pkgbase=cataclysm-bn
pkgname=(cataclysm-bn cataclysm-bn-tiles)
pkgname=cataclysm-bn
-_pkgname=Cataclysm-BN-cbn-experimental
-pkgver=202107310434
-_pkgver=2021-07-31-0434
-pkgrel=1
+#_pkgname=Cataclysm-BN-cbn
+_pkgname=Cataclysm-BN
+pkgver=0.6.0
+#pkgver=202310040030
+#_pkgver=2023-10-04-0030
+pkgrel=4
pkgdesc="A post-apocalyptic roguelike."
#url="http://cataclysmrl.blogspot.com/"
#url="http://www.cataclysm.glyphgryph.com/"
@@ -23,113 +26,282 @@ pkgdesc="A post-apocalyptic roguelike."
url="https://github.com/cataclysmbnteam/Cataclysm-BN"
arch=('x86_64' 'aarch64')
license=("CCPL:by-sa")
+options=('lto')
depends=('ncurses' 'hicolor-icon-theme' 'gettext')
makedepends=('sdl2_image' 'sdl2_ttf' 'sdl2_mixer' 'freetype2' 'astyle')
-source=("$pkgname-$_pkgver.tar.gz::https://github.com/cataclysmbnteam/Cataclysm-BN/archive/refs/tags/cbn-experimental-$_pkgver.tar.gz"
+#source=("$pkgname-$_pkgver.tar.gz::https://github.com/cataclysmbnteam/Cataclysm-BN/archive/refs/tags/cbn-experimental-$_pkgver.tar.gz"
+#source=("$pkgname-$pkgver.tar.gz::https://github.com/cataclysmbnteam/Cataclysm-BN/archive/refs/tags/cbn-$pkgver.tar.gz" # Pre 0.5.2
+source=("$pkgname-$pkgver.tar.gz::https://github.com/cataclysmbnteam/Cataclysm-BN/archive/refs/tags/v$pkgver.tar.gz"
"cataclysm-bn.desktop"
"cataclysm-bn-tiles.desktop"
"icon_128x128.png"
- "0.F_backport-tacoma-barn-door-position.patch"
- "0.F_backport-make-firestation-shelter-wells-npc-drinkable.patch"
- "0.F_backport-inhaler-mission-no-autofail.patch"
- "0.F_backport-radio-can-use-ups.patch"
-
- "0001-quiverfull-house-correct-stairs.patch"
- "0002-ankle-ammo-pouch-is-not-a-backpack.patch"
- "0003-inconsistent-ammo-names.patch"
- "0004-tacoma-clinic-add-missing-floor.patch"
- "0005-lumbermill-gasoline-not-spilled.patch"
- "0006-community-garden-fertilizer-not-spilled.patch"
- "0007-oxyacetylene-from-oxygen.patch"
- "0008-npc-can-use-more-bionics.patch"
- "0009-22-casings-can-stack.patch"
- "0010-4570-dragon-can-be-dismantled.patch"
- "0011-add-missing-mre.patch"
- "0012-fix-doors-for-npcs.patch"
- "0013-fix-20x66mm-loudness.patch"
- "0014-portable-generator-engine.patch"
- "0015-normalize-drone-volume.patch"
- "0016-medical-zombies-called-zombies.patch"
- "0017-nerf-lightstep.patch"
- "0018-rehide-redacted.patch"
- "0019-derelict-shed-is-s.patch"
- "0020-hk46-is-milspec.patch"
- "0021-foldable-bottle-is-container.patch"
- "0022-fix-evac3-background-visible.patch"
- "0023-fix-rubbersplosion.patch"
- "0024-ammo-order-fix.patch"
-
- "jc_ammo-loudness-ap-times-2.patch"
- "jc_allow-bio-firestarter-on-smoker.patch"
- "jc_npcs-eat-when-hungry.patch"
- "jc_stop-non-faction-npc-sleep-depirvation.patch"
- "jc_stop-non-faction-npc-malnourishment.patch"
- "jc_stop-sleeping-on-tables.patch"
- "jc_allow-hacker-laptop.patch"
- "jc_restore-inf-immune.patch"
+ "hotfix-01_fix-negative-calories-when-creating-dry-rice-4373.patch"
+ "hotfix-02_perf-disable-vsync-by-default-4414.patch"
+ "hotfix-03_fix-enable-vsync-by-default-4433.patch"
+ "hotfix-04_fix-mapgen-fix-for-level-0-of-the-Necropolis-4380.patch"
+ "hotfix-05_fix-more-fix-for-level-0-of-the-Necropolis-4387.patch"
+ "hotfix-06_fix-more-fix-for-level-0-of-the-Necropolis-2-4426.patch"
+
+ "revert-01_removed-traits.patch"
+ "revert-02_revert-book-revamp.patch"
+ "revert-03_generic-nv.patch"
+ "revert-04_telescopic-lenses.patch"
+ "revert-06_Obsolete-useless-hub01-basement-1457.patch"
+ "revert-07_Remove-handload-quality-distinction-1481.patch"
+ "revert-07.5_Use-bismuth-in-recipes-related-ammo-fixes-2952.patch"
+ "revert-09_undo-yet-more-ammo-balancing.patch"
+ "revert-11_Obsoletion-and-removal-of-useless-bathroom-fluff-247.patch"
+ "revert-12_fix-i18n-metric-bullets-part-1-rename-.223-5.56x45mm.patch"
+ "revert-13_fix-i18n-metric-bullets-part-2-rename-.308-7.62x51mm.patch"
+ "revert-15_Fix-mutant-scenarios-adding-an-obsoleted-trait-2929.patch"
+ "revert-18-Simplify-broken-limb-mending-3054.patch"
+ "revert-19_Fix-Repair-Nanobots-3308.patch"
+ "revert-20_Fix-tidy-warnings-3310.patch"
+ "revert-21_fix-Erased-the-npc-Alonso-from-history-the-game-3582.patch"
+ "revert-22_feat-content-Biodiesel-Fuel-for-Gasoline-Engines-371.patch"
+ "revert-23_fix-balance-no-more-EXP-gain-when-a-skill-is-maxed-o.patch"
+ "revert-24_fix-repair-nanobots-not-working-at-all-on-broken-lim.patch"
+ "revert-26_fix-npc-splints-and-clean-up-iterator-errors-3592.patch"
+ "revert-27_fix-NPCs-keep-their-splints-on-3589.patch"
+ "revert-28_feat-content-semi-plausible-smokeless-gunpowder-reci.patch"
+ #"revert-29_feat-balance-port-Mainline-Nonperishable-Overhaul-s-.patch"
+ "revert-30_feat-content-weapon-mount-obsoletion-part-1-4179.patch"
+ "revert-31_restore-vague-nether-healing.patch"
+
+ "ammo-10_ammo-order-fix.patch"
+ "ammo-11_fix-volume-40mm.patch"
+ "ammo-12_fix-20x66mm-loudness.patch"
+ "ammo-13_fix-reloaded-50bmg.patch"
+
+ "armor-01_ankle-ammo-pouch-is-not-a-backpack.patch"
+ "armor-02_fix-survivor-fingerless-gloves-warmth.patch"
+
+ "bionics-01_npc-can-use-more-bionics.patch"
+
+ "faction-01_more-factions.patch"
+ "faction-03_fix-food-supply-calculations.patch"
+
+ "factioncamp-01_remove-legacy-recruiting-penalty.patch"
+
+ "foods-01_fix-food-materials.patch"
+ "foods-02_fix-food-naming.patch"
+ "foods-03_fix-mutant-bad-taste.patch"
+ "foods-04_allow-canned-corn-as-veggy.patch"
+ "foods-05_fix-missing-price-postapoc.patch"
+ "foods-06_sealed-foods-not-full.patch"
+ "foods-07_fix-meat-scrap-description.patch"
+
+ "itemgroups-01_hk46-is-milspec.patch"
+ "itemgroups-02_add-missing-mre.patch"
+ "itemgroups-03_fix-shelter-batteries.patch"
+
+ "meds-01_antibiotics-unhealthy.patch"
+
+ "migration-01_remove-ucp.patch"
+
+ "mission-01_typos.patch"
+ "mission-02_reorder-gunslinger-quest.patch"
+
+ "monsters-01_medical-zombies-called-zombies.patch"
+
+ "mutations-01_nerf-lightstep.patch"
+ "mutations-02_fix-evac3-background-visible.patch"
+
+ "npc-01_isherwood-update.patch"
+ "npc-02_tacoma-update.patch"
+ "npc-03_godco-update.patch"
+ "npc-04_island-prison-update.patch"
+ "npc-05_kindred-update.patch"
+ "npc-06_lapin-update.patch"
+ "npc-07_lighthouse-family_v2.patch"
+ "npc-08_nurse-takes-more-meds.patch"
+ "npc-09_broker-takes-more-foods.patch"
+ "npc-10_bunker-merchant.patch"
+ "npc-11_npcs-reload-gas-mask.patch"
+ "npc-12_fix-eddie-requiring-1000-clay.patch"
+ "npc-20_dialogue-fixes.patch"
+
+ "recipes-01_4570-dragon-can-be-dismantled.patch"
+ "recipes-02_recon-mech-laser-typo.patch"
+
+ "terrain-02_fix-doors-for-npcs.patch"
+ "terrain-03_tacoma-clinic-add-missing-floor.patch"
+ "terrain-04_lumbermill-gasoline-not-spilled.patch"
+ "terrain-07_rehide-redacted.patch"
+ "terrain-09_make-firestation-shelter-wells-npc-drinkable.patch"
+ "terrain-10_fix-milbase_minefield.patch"
+ "terrain-11_clean-up-map-extras.patch"
+ "terrain-13_fix-mapgen-palettes.patch"
+
+ "tools-01_foldable-bottle-is-container.patch"
+ "tools-03_shears-use-light-battery.patch"
+
+ "vehicles-01_portable-generator-engine.patch"
+ "vehicles-02_fix-fbi-car-name.patch"
+ "vehicles-03_black-box-can-be-installed.patch"
+
+ "weapon-02_Fix-usp45-load-order.patch"
+
+ "etc-02_add-missing-price-postapoc.patch"
+ "etc-03_fix-abstracts.patch"
+
+ "src-01_radio-can-use-ups.patch"
+ "src-02_ammo-loudness-ap-times-2.patch"
+ "src-03_allow-bio-firestarter-on-smoker.patch"
+ "src-04_stop-non-faction-npc-sleep-depirvation.patch"
+ "src-05_stop-non-faction-npc-malnourishment.patch"
+ "src-06_stop-sleeping-on-tables.patch"
+ "src-07_allow-hacker-laptop.patch"
+ "src-08_more-military-base-overmap.patch"
+ "src-09_npc-eat-from-further-camp.patch"
+ "src-10_reduced-kcal-during-sleep.patch"
+ "src-11_fix-tacoma-farmfield.patch"
+ "src-12_lower-lockpicking-experience.patch"
+ "src-13_searchlights-with-plut-gen-furn.patch"
+ "src-14_fix-npc_melee-calculations.patch"
+ "src-15_slow-down-fungal-blossoms.patch"
+ "src-20_fix-default-mods.patch"
- "custom.patch"
-
- "cataclysm-dda-tileset_undeadpeople.tar.xz::https://library.iserlohn-fortress.net/cataclysm-dda-tileset_undeadpeople.git/snapshot/cataclysm-dda-tileset_undeadpeople-master.tar.xz"
- "cataclysm-dda-mod_battle-maid-redone-tileset.tar.xz::https://library.iserlohn-fortress.net/cataclysm-dda-mod_battle-maid-redone-tileset.git/snapshot/cataclysm-dda-mod_battle-maid-redone-tileset-master.tar.xz"
- "cataclysm-dda-soundpack_jcsoundpack.tar.xz::https://library.iserlohn-fortress.net/cataclysm-dda-soundpack_jcsoundpack.git/snapshot/cataclysm-dda-soundpack_jcsoundpack-master.tar.xz"
- "cataclysm-dda-musicpack_coag-musicpack.tar.xz::https://library.iserlohn-fortress.net/cataclysm-dda-musicpack_coag-musicpack.git/snapshot/cataclysm-dda-musicpack_coag-musicpack-master.tar.xz"
+ "vampirism.patch"
)
-b2sums=('ebb0aba2614372af488322cf9b445ea20c17e76699cd019ecb73b7dc07ecdd7d1ef98fc4bab3cb67d88dec6c45034323d80b8ed79ded32c32a04342d6cf8e3df'
+b2sums=('1a311f72d159194d8737b75a484d015caf75a1920b1e9eaa0bdbcd9c0bb8aceda1f59a58cca68e63c907fe9b960208788c8f58169e4abde01b418e704d307189'
'069ecde58859b3d44cd687c4b6e718610cefb693ff86e66f199ebfb1b3072023ad2b6f0c28e27ef9c1ce4997f6a5b2ca0d45046996b3ff35a4aeaeb1a7cf9421'
'ad88bc6c1e3c8183a313b5eec42f98d6956afea349feff34a86e4536c9921fa99d2594282caf27de8ebb7ffb56376ed2e76d572227bfd6d8173c7bb1f01e23b8'
'6f70e90359a14e4839d9a2683debb88850e5dd387add911ad68fd87e5512cfcdd435da63e1e370358153673fd5a72a9b1e9c94f1979edb7948b4da8c82407bad'
- 'ce0dd5121e814e0fcd79d68362c80a83bfe70f970be9d5d6f6fe5f6a56ed3f041be4d560aaf02225c3ce7c457dc63bc3adf0709d4b89a81c18184ff5341eb5d3'
- '2cdcf9ab03eb92f384caf1a2d90f82c75f880cb6286811e83217c883e421c116e7844ca193a010dc35e12eec46ede3663171a2f45f660ef5a8be95c474f61bfc'
- '9e2c26bf0e2bb4fd60de8cad1f9c05f329d99a56c64189bc2747915c48d208b63038d45a90f7a1c8e8bb0ac33461f217acf7e57f752f0acff117e2062459e9bb'
- '51b1324506179f7fadd8bc187eb8db939494483597b0b7b63909cec66f4e94b27888ccfa926bbd2ff8b0e80108ecc373118c202a177fc2ebd4f5231f87f09a83'
- '8232c6a10fd1f608304982ae7f03eb8afc663be76cdc00aee46ecb58de838e21fdc8673841266ccd00153263f7b15b59dcd1fc6ece86834509d7ccb2cacf08fa'
- '025213998583972e7551bd7bd7376ab65857e28d4338fab60ae792a6b3bd48983aec77e5143baaa63d4f3feb7cd590c4bded529c410e4d18f2b8c5813f25daa3'
- '57e830004122ad835f84fd45c0965b7801b7355dcfef22c4e83969460f181d86110a7e37cc87a196238aa745ac8c9db99f97cf87edf7ef0fd8cfd16cf38d22cc'
- 'b8a64accada87ee5be989c5307805610c9b5c0327bc107aab237ac3225dd9e4c51b6c79a2a7de15fe187d3c32d7cbe1c462f9b0e9fb5d5a55a74236c7061e96e'
- '85aeb5920ee5879848be4057324153a077fe907bed527ed8f9b80a3c5ee1ef64786f63ee2999f5ba74e80a43e99ded3280ce27759c1f7b73259a6e2b5e584aa8'
- '58a94409205f7b670ab5745b8cbc234a38efd6a6217cef4efb7e397f091092e3e0c7790706b0a42accaa83d7509b8e244a98b9f0ba78349ee85f3164745c3501'
- 'd34d673fe04d4317ef3c1ac3f088b6614f7c20414cfe44aa0ff71bdc932c517c4e6295492f158ced84232af8f54d1672ae56078b156593d58bf8fe7ffc3d475d'
- 'f3bdbaac5dbe9384571fe5ec14d2d25035f227a977c25349b8188e7343804e3973b898b44c34f9abe9318666294f4fdfe780fd516dcbdb29c4ac52f6d0ed6cad'
- '67cdb7e097bbb46da5cf04708bc2858b080d1a85742afc4c088da3e4e3fdeb6e4c51240fc5a6b9a1c7d927b30b3d251236e025ee4e5496142a7716d4ba51b82c'
- '9ad2986261e6613e80b4bb61b89e2d0c703d7c4d28fda98e58fbcc2623a05c05e253cd2045e64c140e5de99aa2278165948e717739eb803849ea17745e974620'
+ '211eb5f17622546e41b21a6df3a54a777773fa092cad6818fece68975ceade9064f61735d44736f6b5fe4a320fc03855532b69ae9de6652806c1468c6979caf9'
+ '4d8996d5a29b539c9dfd6a970d4a6c51faf4739038ebaf40bfc8ad066219fc1605be028fb5c00588d73d0a8c930b3c867db0ce1c3174df172d1551901b428e4a'
+ 'e2cb955fe450bd9a06b82abf755dae72d8012e454c43ad69d1654a67d0c304769817087a03604da21b9f478bdc8365c95fee3d746a58a7bd007f652e9902d244'
+ 'a22b8b17d97b09d622ca777743224a164be5b7be3e7f763aa8b94eebc2a5447d5d7875587562987faacd68613628093bf215c38ad5544a8d48a2b4e8bca7c587'
+ '2acab6e5fb1c51f6b09ee13893917c9876f0009f9c8537d93f13563b461b9855722d3c1dc55803aee5922a9283da41656ec62dbf30cf6d265e858fd397762067'
+ 'bc6b14d6000412cea47bbe1bf3a4a56f06c13afcffd555cfe93d99e5d3b16ce66b0cb2458cd211dcf097974870b78876c2f3f056eb8f9304c4c85b2655dfe831'
+ 'fdef1f81084e7b08203b8464f37a00e2efc8b11d423c6e6b82e612392d91047160d2bc472b63c836ebc48adee0b4f2b3434c3e07eed5876275b234e69d7f6b9c'
+ '2b42190f1d7189a38b3424efe64fd1b3921919a4f6fc872462ef684587de94b900e93f159597ab3e6f576268fed3e6966cddc3fa7250e1b746095fd7a2cbf6e9'
+ 'e417a1786fbafb685099431f7f9926201ab80636bf3812da67acc341c7ef2b6a3853734d5b8b1bc355acbd5c0bedefb0401f8854aa5cb00032550afc8a7b9ebe'
+ '5b0e957a5f80ea878c554711dab2fe6759deb3371532cd0f149cfc7a54ec914f445a4aeeff4263df58c947f03fe7be30f2ef175b9a81708e668fd037f9b8ccf8'
+ '36d8e081f0c374202942a6f5c50781768e45ac1c7df4b7861ef63577ec5f86c160518f2aec8b3cf9d0507061ed177286e38ef8015e7d0636c85faa2eb93f876c'
+ '4a03288ecc9bb0f342add15413bdc060cb071105d35a4f53d4cce121956e4d95e2b7a9ab9dd9fbf1009c5f54c34776e1f724c3fd171eb5b6ff41db0dbe2fce07'
+ '8ed59f0237d4becee71c5f79dd434972eda3a02c56c29642f69c8ac7e638d866df633e0e087b4392bb74017b6ea3641fd6155d86f0c71fc188be19e7a81cc23b'
+ 'aaf108d56813472ba3e53b63fabc49adbbec01008e0df17f3fecf821784221f03c77eb822858983437dce993913eaa3679217830b101e54d57c6976c52559717'
+ 'ddc40a941dae720ae89c3f21bf2a153959e449aaeac27e532714501e656b60ff78950c78f48de3c99ff4d02905c944eafaaeddb04d8ed0a4cad604f96a442204'
+ '406130adb1be38e25bf750e10166ea55bd8e5c5e500ea81d8af547131a2eea04ce1e4b415f3fe87f4825aa515186b23e612a4961d2b44f538466044d7ec49624'
+ 'c6854d23ec8eec198e3ee1ca9a7cdb2c8c6f2c20a4e670d6752eb09ec99713dd52d659690e4dce935b11954f7d435d5ea35b4eda23bee3ee5759ef395c18b6ff'
+ '2de96509a572c1eca36d63f1a049a27583cd0f2df53605b927c9b5112d4e2385bccc82ba1a37af06fe756f96cc1e8c9d4b6cd081ad70651ec09ac57b93cee84f'
+ '9c8c49c7c70a40a195e4cafcb22b7e1fab1e276bc59c186e9b09fd77c525dc63fc64719e0f87083f2761172761c9a6dfaf8ff11b405976502e7f55e9606c42c0'
+ 'dcb8a004230da09e73a340c1acaf3c0071a8c26e3bce9a707b8e1624854aadc9e45f6f3f0d99549ccef5c11a6396dc082691895c437d50188e1b292cb8c10751'
+ 'b4ca2cb0e7c6c908277b178dae1b946ecdc2b88a8b0b4930450758e03c1f280b3740118cee274886693c158cd4604dc8487211b9185538eaa72852b18f0c67f2'
+ '677c476df28e0f5d0ddf789bf2b26f2dc49a9d1523ba07f2a0607bb47d00b17c9f7ae86737d5a69f7fb8c7bfc82231a8a1d5b756ae49934adf1eff315c7a9a5b'
+ '80d5920380282ba1c9bd81e8e7055af3c88ff2ecfb1d375ad9f1ddc29b3f61760119b9ec27c14266a020a32d8bdc6f1eb1bce35e847ed87faea0c7623f8b906e'
+ '84b9d7d78ad2ab43f24aed79f6843e7fb8f600bb8edea384fa446f0a70bbbd5bdcc391de8bfa25667d3906df8ae8e9154701bb582e058d77e9326a08de3fc00e'
+ 'bdc83eecf20d82bd314ea6c053c19a990ab25aa067cdec8dab479d59b5169563bf7f368776ca18749918b5ce4a8df4e2a2e700dbbc3a36b38ee61f1b57cd416a'
+ '6735377f8611451333c8d7f009001aa652af9edeeddfcd0cd163d03ea84607803d260eb1338fa35f688954c3cb75bb7bdc41a5ad0497771815dd16afa86d54b3'
+ '13e61e9144f4d7325c409553c72ea1fca07009939b53491ea24d208fba7539e7f09063911c76e7d45f7e6bda12a61bbde17a75c319a0b79518e6639d520fa4ef'
+ 'c4ee693418d394e3b946aa2b9a5f11c04bb0ff11234f830056963f4a755357552f9a769688a086f56f492ed479cf1a44032cfde45c03627adc5fb55f88f806e6'
+ '290151179775e23b19a2ee9524b0719301b1661b76404c24341f4f5ab76df11adc6bf5e75fdd0347d59cbb203c37398a17711ea95ac9f845369ed9168dba789f'
+ '23f20b618c3a8d16080ad36a664e3cdf048b4e3b0b36d4d2145c385d299ec92f9c1d2c3ae2e87f62ce39067bf1d627df5ce87353957d414c358b5f2fc0b57eea'
+ 'df26a597afe46a35e07f02c32839e2f7f57cf4d4d9bf0e62eb645d1b720f601fe2e9787462a0ab0ba8b788c727b846272a4ca6ecf81f96bb058d070b53633dcc'
+ 'ba2964e64df20167c722e71951db28d039e637397a6be2e7f5312da10ab3c57a1982ec1ae1c37dd361317292b8c519f678472eb06360d4368294e0b636704c15'
+ '365e1ac9f9ee636f2578f6fd8ab16b6460894cb9b76cf0aee5d8a55f42d882d6ee0b04e80194f4c346bfdb0778e11e30b8c03541b4d351602ccfd63cee7e3cf0'
+ '6f79418343f29e3758e826417e475d957e0c372fab8c06855f5a86b4636ce6e8c68a770a4a3ec327361ec69d042d627062b2c2db23e5e437cef855683242545e'
+ 'bf952e4c5e8ad3851f2ab5a812fdf65e0a6e7e1726150d7fa6cb582f4408eed85edc7b8cf9dabc07fab62217d14fa7ee5493b45bddb282da44247291e84c990d'
+ 'f4ad4c90cfcf11af42c6cfc6d2027b21af3f58ac274b9bd0852a52ef60b606476766f194b281f6baf12f81647b384a98f745519bb48bc2e4f5fe03984c7c0e65'
+ '172c611008cb8893a8a8cbf83ef929f5727fbf341f3303c6f38749e3742f96ba7352624112ac231a8df7be9031649e41d54cc52152776e52e3a7a620ea8f33e3'
+ '58472d7cb093bd983833033bceededcc8c55b15ab2fdea10784c8292a30084e16c0f37a94006c8fa61dcbf9d00c2869503955972f746f592f3f851aec8f2f977'
+ '804cea67bb0a2fab62dd9cf633d1959a3fe59b3e24f0c2e01a6db951100fa4426ae946a90a93fa7fd6a7d0ece478633d0091144c2fa776858157edec1310f837'
+ 'a611964c224c7751c3afeaadb159135e5ed5d87d3ed254be63b4b12450f4f63f414c90f8e29f3d14c0b854f4c9938bf5d12db69d2e258f1947e353302ca07da7'
+ '554bc4acb13f2eb70b14dad095c609cd1515bf462a147511fefb935ad64a4dbffe6aa2a89db7342728a212e4e87f7def120c136d87202dc754700ed62449fa12'
+ '32975862668e4c28bf345cf9e2e3a2f754f7d7d50208f1d840e3b2ca47da1c19bcff9bdf6dc841ec803c64fd633b479d1d598ee22119589732f7cff1fa6dd6dd'
+ '7da2d555f4b21da6704675400dc97367ff3e6bb60213d86c972b6740f074bcef98482ad7f759ddbee09f67d0ee8687c26c425d697ab586a784385971aec72bb0'
+ 'c3b8dcce2fe41c8d9dab2d35d56304f426e06f9a6a220fcb2f413ac4aa32c7f466e2001cc7bf0bbf6127aeef55c837bb344f08afbb392f202c4ad8ce83a592a9'
+ 'e85003201457633ab56789aef908ad4e8f9ed4728fc2bceb0344b851bf65f13264dfe9459afd4c1ba69c0d89f83e841f4829dcf6b0f8fb456bc9f2176c66ca87'
+ '7b4369a2535029e214af7f51f7d6292d91989249374c9969a140f8954dedca2a2c04f626ac0bcf33f9ea8ab1710fadcc79034156405249b885b01e5c53be2188'
+ '3480ccaa4bc7c64e17d2f7904b39d98c8a3557a4af7d811c8860fa77d3b78055343fd7e4442ce6d1a11e8528496df2cdce03749d0ed046ed8b2cb94a4fd11dde'
+ '76c816df10aceec8f1a7d1356220eb3f00b16fac455e84eb8aefe76db29cd037dc74fb5cfa344b8d283b188951bd100c26e351ce2e27c16c836a547fe2c99e46'
'417cd957f188b2b06e41d5413bea5f13481c6d5bfa8f184157379d5ac2afa9ba6f7ebc966856f50603f89b9173b6fbfdb3ccf4e3cc0b1bedb53f935591e4a35c'
+ 'dae75d9cd00f1f3ceabf257f1d82d245ace6582cf7ea98a40c1d1eb9b7e1832cb2a0c13f25c814a05a70931c42a06694a67829ea55554cc680eaa8ddf16c84a8'
+ '931ac85c657c1c504de1ea629205b19f79a11acdd7c62cf71b909323ec1588610b1f575bc58ab01c3fbcd334fca8fbc114316570732f55a3f7fb3dd2984cd442'
+ 'b9bf63ed06aee848fa70adceaf9674e842343e6f92e9a2e57be372814b481d54bdfee602eac9e3c05dc5c8e35ec36146f28491de39b7ea2c8c3a8b9ac80c0354'
+ '536c59b274923d36fbfc6dc39ef373a0d1e497422dea6fcdc16cfacb6b9ba421f14c5d7c4db31bab083199d859ff57ae5b19842f95367cfa39059e7156e96093'
+ '69891c188f233e5174c2ddabce9371e84fdffdb105345686d71a9d823422969f77f9c44bc6571c6e5a72dbc9b9bdb6abf8c72cf9480bb87dca6f998f62f3de02'
+ 'e466392190e0aa58c02acda287bc8ac6fef30160207d08805ca9acd42b7f024d0680c0a76fcb4f29a7d7ca884920bba3a6714b5ad40f64dd1b40bcf0e2621d26'
+ 'f2ad02ac73e7ab5c26f986b640b88ed10ad30b103d98ede377b3868a3d0f84cabbc4c06f5f6b2e05c18c672370d1c25a7bfe3b3ea5d057ac7f3d7ef35b814c7e'
+ 'ab35d6663b864449d46da4a9e1c51e11956ff4c38e16db58c831b71f7b964fc25b0283122dbc8aa0549f240f01c4a910fb5c6c82937258c6b736c05b54bcf768'
+ '75877d9c6090a4e75529b1840f875ef04941a643c2c3b0c2e2a605c0d43d6b7ac23abf7f0316885441b8310f8a39339f2e12c7763b2d9875ee772949e6dcfcaa'
+ '761938b9d05430a72ff1102671d963e44d647ddb63b9a6e78979f365c6cd1e98b6a3763a4b9667ca75fbf23ee3812b4f09838061e8ba101d89d6f4dbd1104dc0'
+ '3bc768194ae94a95eb8a5f7e1536e81bbb885d9d2f6dd799350d272d2f87d4bfb4ebb5dbd215157b000f29821ce43fc7b0ed45a142329a5ffc207463b054d9fd'
+ 'fa3f9c021097115fd180c83a6640a696240783b165add09b48f624f3b91546aa75bdb05b12a0edfaa009f69f5aaeabb20e2e52267c7d4be4c1d4d8567d8f4eca'
+ '09ad88d1eebdb6433c2429cea4b775384b65d6cd52945e0de536dbac9fb6d9c345bec9bb49ede6fc6ce01a73e8297d3c8901c4e91d1b5a12eebc36ffd8c21ac4'
+ '4a914e5120c223e6c1e221c692a1da7e67c13c2afbe273c54e214f7c4391805a13ee21fab5441104976caa5ee2eb8bdaccec89349b4e2eb823060e198f28d15a'
+ '246a189a0002e755bbed91257c324d0f34bab724f38a31bad1d5eb8bc5b126ecb3a0af8f69a6d0f5f084930c670d2747942beabab0b684f7f66a13044dec394a'
+ '739d0a1acbf6cdd1c6e78cac75a792d475b140219ffbf8c44d4db9fa82dc93f0822763be14c81afe69ab167a611a5d89fceb3df39d28b191835e14628c369140'
+ '21130b85c325a5789e8fa60b9cd69c889d41153c20b6a3d38465a43e57c37e35ec4f0319aafb1611c333108f066520370d8423111b208d200d62f7aecd626f27'
+ 'd5fcf6d5c7984d08cd6992809b3259f90196af5e8e4953754c04f722fea06ae995e1d51fbbea8cb462b7f896026c709928252413dbda4cec553684a6d2b5fca8'
+ '0449ffab9ecf7183253cfb56c7bf489ca6f0a2002f96caa37f2cdb9c77e51e7f8561589e5179496cfb6760b1e8c34a5aefcce4fe0790cab81db3409582a2c835'
+ 'abafa39e57cf04396b841833215aca427655dd3b56ebc260b8a57d6376360b31a4b1d4493da76ec4dc0129939ab9e23cada70dd6f49e647f02bce12c81f6451a'
+ 'a549cd452cd709d7f6d7e13c77f0224785a100823c9aec3fb9ed4833efafe9e57a4c978f79a0e9b96a9adf5ac87a88b9273fae6219569482a88ae6730c1ac840'
+ '8eba2f66280defcc930424d695baff297cff32e91e73f01210bb3f26389ea9e93b4b4d9e2c5a5a048756eff219d51c3fbf3f05690c3c984afcc32c3928df91aa'
+ 'd2a88e1769a1b43e0ee52acd8797988597cdf88b535f1769afc86bbae36ae79ed8bfd7c7fa6d553ceba24b935aae5ead275d388d4b02169393a4fd4003c517df'
'80da2c341d8564a47bc460fcdaf9196ac3bb77f0f2ba56bd71089e80e7481728a3ccbdcfcbc3bf70a9c9e5d9d9b01f2ca6615b67c7ab61003808ce00f6545ba3'
- 'c1b6e59c840aee812570d9fb30f045b371473282c2289aaefe66483e6aae995fb93549882811fcb869d77f1c27a62ba4e486a8e20327846fd0602926739296ae'
- '74a51f04237fba3caa25b2e0d49659f2e8330ce82288de866943d06b53690f31d48a77a4dd2e57db1f435b715fbca792268f2e191ffb59e57170d327ed41ac0a'
- '8203bb062d72559da908a5020963503303c0aaa4a2ab61e57cfb713f58de40f1cb50b8b6dfbeec3a9addc41cbec5ae17fbf57230c3614f9b69fe6b0c55bf3fad'
- '7e49f473cd5c5811ff6456b58be6f8cb438ec712b388c156902f837b556550710bb79924f94f6818a6332e653ec0740d7688165ca105b159faeeeeec2b105dd6'
- '08f4746882b927bdff6b728630cf1e04a2b79924f694ca2d841e3115c3399feb87a8d363e4d2a0f59179c109cb6be6e840f912aadd44abb0bdb35afd2838cc4d'
+ 'b8a64accada87ee5be989c5307805610c9b5c0327bc107aab237ac3225dd9e4c51b6c79a2a7de15fe187d3c32d7cbe1c462f9b0e9fb5d5a55a74236c7061e96e'
+ '85aeb5920ee5879848be4057324153a077fe907bed527ed8f9b80a3c5ee1ef64786f63ee2999f5ba74e80a43e99ded3280ce27759c1f7b73259a6e2b5e584aa8'
'651de880cefd51665d854414c451cc80a33ed8f34e7559a95514abd81a2f58348c37dd75f272468eefd56562ba8c99093a6dd9af3ea57796a9db15164a40eda3'
- '7e41fc3a95073008ca2d71c2266d6d1a17af7803d493b447d40b15a86184c8ce3728b8d3d36765d408b1c46633d1bfa980d878cbac2e04b51ef518d44dfb7295'
- '76c816df10aceec8f1a7d1356220eb3f00b16fac455e84eb8aefe76db29cd037dc74fb5cfa344b8d283b188951bd100c26e351ce2e27c16c836a547fe2c99e46'
+ '2cdcf9ab03eb92f384caf1a2d90f82c75f880cb6286811e83217c883e421c116e7844ca193a010dc35e12eec46ede3663171a2f45f660ef5a8be95c474f61bfc'
+ 'f830baa8e9d2f2d844520ef3199a7ac62913afb016d40028d99865ba5c6143c08aa8cec9322a67d808fa526954a78416c90cf35ef31cc8dc4dec64950f58adfd'
+ '6ce1b6808b48ba0e64a07d2ff84f0283a7b172e470c8b934ab8824afe2eaf6322927807a985f4a333544f20743f39d75f7b83591ae885fcabb344f6f2476ef74'
+ '8cd8393b544a389f3d29465d9b817495e6fb7a8706ea967d0785688fbdeb393d0856c71deeeeca623c374bcbc85708733aab6a2f985417e5e1b1936ae7b1d4f3'
'7cae5e42b6e16f3c4bf64dca3c7573c1b552424ff70bb6da0a21f121b53b2546b239c87953a090cd90f46a1c3c124e2fe19c560b1830b11334f8e64c92fb614d'
- 'ab35d6663b864449d46da4a9e1c51e11956ff4c38e16db58c831b71f7b964fc25b0283122dbc8aa0549f240f01c4a910fb5c6c82937258c6b736c05b54bcf768'
- 'e1d03f68918d03f980f4c2dd966e3788afe63f14e2d18dbd4dab2cdbfa1253e4823c0f5daa3a579e47319a3c2af35bc5af0a390e2ba91fe7621f6db8b1a60994'
- 'c47d002dc55af6c74a830205626eab57922f3f79143a5e1ddbc9ac8dc75c1ef4f2adf6a1816f8abe0b43e9a81a9021d1c9c7f62d76fdf67fa5fe00bbeca73962'
+ '4c178d330117886848d232372a25ecf5cac46ad48a6fed580957d295eb1c4266836f4f807593d381f9089b2078c4185ba972f697ab353a850ebf35b6f140a4ac'
+ '74a51f04237fba3caa25b2e0d49659f2e8330ce82288de866943d06b53690f31d48a77a4dd2e57db1f435b715fbca792268f2e191ffb59e57170d327ed41ac0a'
+ '4a1724784d6b4f113e8c1954d399d07adc941a2e992e1c95ab38dbc5c31940e90ff4cec51d22da3bf971880817b4356e473747303146c2ab1be55ee4565aca41'
+ '209387731490549d7b3d546ab149cea22e0ea1291356884f358cd87ca7d5425ca9a72f6f2cb7af46956634ffdb1a61d1ebfbfdbb5a2fc9fdc26d29acdc2ab0c0'
+ '83d5a89f14ff8d79f90e677def2f58b1a8a0430ec16bbe3865315b63b3702e699bae157235e70a4c613e84f05b0f7ecf8de4ecef789cb8146edfbe92020c89f0'
+ '60fac0fd3c098c8a38f634372b889c4ac7d2d61f1e08fd79b6216ee6a7116cadc06b974ab2ea5efc74801a9f4a8ad029dde973d1494f6467c57ac860be64acad'
+ 'b41ce5db19de2f4a5857debe31560b7b8216412e5df795032363839429f732b2d2359b3679a795c55a997913588f7d495c300df402529317ef2d03de24a74273'
+ 'ccf74105e4268eaa35ba2a79b21c89ea5ce22f5d23c297688f5731681926536cfe0f430347fb6e6e70cac8110c7c64ca944b696b0248796434cf667db171e058'
'92cde696eec00e6758b58e73e8bc60ad1a73bb2a18d4fdfd24a19b5be715305a047943a02d94a9703c101ca0c769dbeb816f1f28809345bae0fec42fbc27bb34'
- 'edfccb4ccb70e174648101d68432ea14ee1e7cc9304d4545dddb65184eeafb708a898cc90778e44cf7464c82c9d350209e5ad262c50a50fa0b8ae3a22fca9ff9'
- '8e9bf6ff4bafc6397c6631392aaddd2866537943ae3bbdb95282945acba385d66f6d9879fd283eeafbb8df4e927f3ecc061fb36ecb5d38dbddecd2fd9c735e56'
+ '1d54ef96ff6875878ac6a6992de7e23a7b98cb5b68d7e444c4f02a6628f657ad26efc757fbeaff34fc89d41fa440d8b57bd0eb437a9d04ad1e06a31ba148061c'
'ce82294e480ad42f0001c799fd8131b60024b6097653f3c57564c75e54596616e376f0d7f1cf4e54d8c302a61ef164b4323f795bfa19b2c13ab9e927d37f1600'
- 'e5d7b75d3bced70d5f77bd8860c53f888b1f2495b4a6bf0b1284e3fc1e831a58bc691b4a11419cd7d14427165158d7ebf3f5c690733e4f3ee5194b9bf9bd001a'
- 'd723fcc6cce65aa296bc519a07a5d003122ad698a73a3d046dac3780ea5a00fef28f78da251bb46f80f2e0577baa26a6ae13cabf525f22a7a742435e95716dae'
- 'e9c8decf0ab74ac2dd02ddd537ca80ad2aa02d97faf6cfcb983965b4c3f400b47b2e0517f2927d1b2463c14370fd1a0bad5b4d00710b2b415b45d1a81724a9c9'
- '0bc675f798113cc744337ac2864c54510af89fc59450a3bf250cc49c1a1b17ebeddc007e38491978d367555ed7f4895266d68f50f01d30f79a7cacdc01f0f207'
- '0dc275d5e1aa79b2cf73f7e997ea2b602690787ae15e3abdd3b9195bb409d511c74d4f7dca4bf1753a9afb4618f04cb462769c24999357dea62593a379411f42'
- '59665e75f28e04a7c1da4dca3242626bab8298849fec5af099550fc3ee36cc6badd7794aaad7b8b3f1b85790df3b89b4d0bb91dcda809b109bf729bb40b0a972'
- 'ba0bd9be874e134914334a5baaef843162003adc0253dae32f1a052da6da59e108808852f51b05350ae6ae074f8d15d88cfcf93f49174c47b924f0f9d7fbd206'
- '2b506d69016b5eac7b72341d30900dded43b5c54471547db43968c7b8724d95aff622aa133afb161e200b1b8e470b47422966230458e7b41a112d47fdcdf27f0'
- 'b9309da09b165fb57e83f84e3584d2479bd3336ed86e181e5df2d27daa92bd55d03d7f3fc226f03696af5f0f32d8e0e7ecd26ae7e50eed0200d0b0feaad07efb')
+ 'd006a51f306a1397c14111788a23029a894e223a196649cac476acab761479db543bf4537ed5a2f4173ec94af04874b521a1d598ed8e98406cc2cf526d8e0083'
+ '0cb9f39fd0b87e40bbce50ec7e834803bd0d28ff3c5ad25d2542498cfc5b625e7fc20880e34d325e05c51f411cf91721fe6b5a03565686be6cd6fe88772f80d0'
+ 'f25f01c5b27dced202fe76c1717b9eaec65dfa5f28db1910529f60f5ec21cc89c1a15df26c2dd09066a0d89e3f7d87c790e7886c3c2f0978a25f5ec7d1236099'
+ 'e3302d903d053f25aa666d572f74a8bbd3b65dde40eedcbf46e537ceb2294ac22b3772087fce04c4a780c2f18e855179c6ddc8af12d72a89b82957ce09deb52f'
+ '4bd44cbe85c53902b8a360509703e3d38e8a5da75dd2c534a77f03ce6440632f6c83c92939069c60473c88ffb3abab0fbf11e39271f44f813b9f6432ea5f9a6b'
+ '6f78478f642c18101e9cd24a0c693abaa1348bb5c730c9d29b8f80d6309aa4bf16f6672dbc36161875db81a071256a0a388769c96810a7c67e3687ec750605d8'
+ 'e0a9e8f1129650208f7a5a37680091a6d2abaa60f5d4fd7fc691854d49c9f59317ca18dbe764cb05cacd4a2a95de702bbdd072571862ee0b27bd8df3be7a5764'
+ 'a5e8bca3ccec2990098e8cf1c504ce6bec03cecef03b0450a4396d5b1e0ffc4e91592f40c3e389eea74fc53114cce0f2c1d2237a779e5ec7e6c12b2863d6c731'
+ 'c0ccf5af2fbf0c9bb59bd226ce17084658cbe6bc859bd8a76c292845dbf57679ac08de339d4cb90736bfa48fcc9f2f734c3fadaa5b91b0fc6e58d157c848a328'
+ 'f10ba62a41e6c0f627b501b907c879ae66e480e90e2ca324d09ba084a6fc0f25e33b384847558f00feb992efcba44eb355ed202351597c5a10a3480bd659f88d'
+ 'c22a81615cd95c01c8722f4be7866f58f488890e518cd74e80f14d65fa3e9889b20666c729cfb317bb55e498d70e13c86b7ba3a61299f667820d4277b2c69c4e'
+ '5c605faf9fd815e39427722bf6f953cebbe77945e82b7415b7fecfba51978788298fac179ab0b26d28fc948679356f34dc2c475361c82d0149f9a9be04192ff1'
+ '978657c7b665b57acc5bffcafff55d289775c47bb7c45b924e89c09571bafbe85c5a122c40d9a76add3719c09ad237525493ae08d5501c174fc96720339e59d3')
prepare() {
- cd "${_pkgname}-${_pkgver}"
- sed -i 's/-Werror//' Makefile
- sed -i 's/ncursesw5-config/ncursesw6-config/' Makefile
- sed -i 's/shell git/shell false/' Makefile
- sed -i 's/-Os/-O3/' Makefile
-
- # Fix filenames
+# cd "${_pkgname}-${_pkgver}"
+ cd "${_pkgname}-${pkgver}"
+
+ # Assorted workarounds
+ sed \
+ -e 's/-Werror//' \
+ -e 's/ncursesw5-config/ncursesw6-config/' \
+ -e 's/shell git/shell false/' \
+ -i Makefile
+
+ # Disable default optimizations
+ sed \
+ -e 's/-Os/-O3/' \
+ -e 's/-O0/-O3/' \
+ -e 's/-Og/-O3/' \
+ -e 's/CXXFLAGS += -ffast-math/#CXXFLAGS += -ffast-math/' \
+ -i Makefile
+
+ # Remove non-existent flags generating warnings
+ sed \
+ -e 's/-Wzero-as-null-pointer-constant \\/-Wzero-as-null-pointer-constant/' \
+ -e 's/-Wno-range-loop-analysis/#-Wno-range-loop-analysis/' \
+ -e 's/-Wno-unknown-warning-option/#-Wno-unknown-warning-option/' \
+ -i Makefile
+
+ # Fix filenames and paths
sed -i 's|cataclysm-dda|cataclysm-bn|' CMakeLists.txt
sed -i 's|TARGET_NAME = cataclysm|TARGET_NAME = cataclysm-bn|' Makefile
sed -i 's|cataclysm.a|cataclysm-bn.a|' Makefile
@@ -137,153 +309,499 @@ prepare() {
sed -i 's|cataclysm-dda|cataclysm-bn|' src/path_info.cpp
# Fix version
- sed -i 's|VERSION = unstable|VERSION = 2021-07-31-0434|' Makefile
+# sed -i 's|VERSION = unstable|VERSION = "0.2-experimental 2023-10-04-0030"|' Makefile
+ sed -i 's|VERSION = unstable|VERSION = "0.6.0"|' Makefile
+
+
+ # # # Hotfixes
+ echo "Applying hotfixes"
+
+ # Fix dried rice having negative calories
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/hotfix-01_fix-negative-calories-when-creating-dry-rice-4373.patch
+
+ # Allow disabling vsync and enable vsync by default as disabling it causes problems for some users
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/hotfix-02_perf-disable-vsync-by-default-4414.patch
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/hotfix-03_fix-enable-vsync-by-default-4433.patch
+
+ # Backport some fixes for the Necropolis
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/hotfix-04_fix-mapgen-fix-for-level-0-of-the-Necropolis-4380.patch
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/hotfix-05_fix-more-fix-for-level-0-of-the-Necropolis-4387.patch
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/hotfix-06_fix-more-fix-for-level-0-of-the-Necropolis-2-4426.patch
+
+
+ # # Adjust default mods
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/src-20_fix-default-mods.patch
+
+
+ # # # Reverts
+ echo "Applying revert patches"
+
+ # Revert change to nether healing notification:
+ # It should remain vague and not use explicit numbers.
+ patch -NREp1 --no-backup-if-mismatch -i "$srcdir"/revert-31_restore-vague-nether-healing.patch
+
+ # Revert no gun mount slots patch
+ patch -NREp1 --no-backup-if-mismatch -i "$srcdir"/revert-30_feat-content-weapon-mount-obsoletion-part-1-4179.patch
+
+ # Revert easy-mode changes making numerous food never rot
+ # offload to recipe rebalance mod
+ #patch -NREp1 --no-backup-if-mismatch -i "$srcdir"/revert-29_feat-balance-port-Mainline-Nonperishable-Overhaul-s-.patch
+
+ # Revert craftable smokeless gunpowder. Not realistic and makes black powder obsolete.
+ patch -NREp1 --no-backup-if-mismatch -i "$srcdir"/revert-28_feat-content-semi-plausible-smokeless-gunpowder-reci.patch
+ # Revert hard capping skills at level 10 for now
+ patch -NREp1 --no-backup-if-mismatch -i "$srcdir"/revert-23_fix-balance-no-more-EXP-gain-when-a-skill-is-maxed-o.patch
- # Backports from 0.F
- # Fix tacoma barn doors being placed in the same spot twice
- patch -Np1 -i "$srcdir"/0.F_backport-tacoma-barn-door-position.patch
+ # # Nope, no biodiesel in petrol engines. Altered patch to allow ethanol instead.
+ patch -NREp1 --no-backup-if-mismatch -i "$srcdir"/revert-22_feat-content-Biodiesel-Fuel-for-Gasoline-Engines-371.patch
- # Fix npcs unable to drink from firestation and shelter basecamps wells
- patch -Np1 -i "$srcdir"/0.F_backport-make-firestation-shelter-wells-npc-drinkable.patch
+ # # I don't get why people are so upset about this guy.
+ patch -NREp1 --no-backup-if-mismatch -i "$srcdir"/revert-21_fix-Erased-the-npc-Alonso-from-history-the-game-3582.patch
- # Fix npcs with the inhaler mission instantly dying upon mission acceptance
- patch -Np1 -i "$srcdir"/0.F_backport-inhaler-mission-no-autofail.patch
+ # # Revert easy-mode limb mending and related commits
+ patch -NREp1 --no-backup-if-mismatch -i "$srcdir"/revert-27_fix-NPCs-keep-their-splints-on-3589.patch
+ patch -NREp1 --no-backup-if-mismatch -i "$srcdir"/revert-26_fix-npc-splints-and-clean-up-iterator-errors-3592.patch
+ patch -NREp1 --no-backup-if-mismatch -i "$srcdir"/revert-24_fix-repair-nanobots-not-working-at-all-on-broken-lim.patch
+ patch -NREp1 --no-backup-if-mismatch -i "$srcdir"/revert-20_Fix-tidy-warnings-3310.patch
+ patch -NREp1 --no-backup-if-mismatch -i "$srcdir"/revert-19_Fix-Repair-Nanobots-3308.patch
+ patch -NREp1 --no-backup-if-mismatch -i "$srcdir"/revert-18-Simplify-broken-limb-mending-3054.patch
- # Fix radio, e-ink reader music, tactical tonfa not working with UPS
- patch -Np1 -i "$srcdir"/0.F_backport-radio-can-use-ups.patch
+ # # More reverts for generic night vision
+ patch -NREp1 --no-backup-if-mismatch -i "$srcdir"/revert-15_Fix-mutant-scenarios-adding-an-obsoleted-trait-2929.patch
+ # # Yet more bad ammo ideas
+ # This prevents sorting 223 and 556 ammo into different piles as sorting is assumed wildcard.
+ # And a second for 308 and 762.
+ patch -NREp1 --no-backup-if-mismatch -i "$srcdir"/revert-13_fix-i18n-metric-bullets-part-2-rename-.308-7.62x51mm.patch
+ patch -NREp1 --no-backup-if-mismatch -i "$srcdir"/revert-12_fix-i18n-metric-bullets-part-1-rename-.223-5.56x45mm.patch
- # Various other fixes for bugs I came across
- # Fix Quiverfull house to have the correct stairs that modify json
- patch -Np1 -i "$srcdir"/0001-quiverfull-house-correct-stairs.patch
+ # Needless item removal
+ patch -NREp1 --no-backup-if-mismatch -i "$srcdir"/revert-11_Obsoletion-and-removal-of-useless-bathroom-fluff-247.patch
- # Fix Ankle Ammo Pouch to not look like a backpack
- patch -Np1 -i "$srcdir"/0002-ankle-ammo-pouch-is-not-a-backpack.patch
+ # Revert ammo reblance 6,7,8
+ #patch -NREp1 --no-backup-if-mismatch -i "$srcdir"/revert-10_still-another-ammo-patch-to-undo.patch
+ patch -NREp1 --no-backup-if-mismatch -i "$srcdir"/revert-09_undo-yet-more-ammo-balancing.patch
+ #patch -NREp1 --no-backup-if-mismatch -i "$srcdir"/revert-08_undo-rifle-balance-pass.patch
- # Fix mulitple inconsistent ammuntion names and handloaded status
- patch -Np1 -i "$srcdir"/0003-inconsistent-ammo-names.patch
+ # Fix the duplication of 4570_bp
+ patch -NREp1 --no-backup-if-mismatch -i "$srcdir"/revert-07.5_Use-bismuth-in-recipes-related-ammo-fixes-2952.patch
- # Fix missing floor in tacoma clinic
- patch -Np1 -i "$srcdir"/0004-tacoma-clinic-add-missing-floor.patch
+ # Revert removal of reloaded ammunition.
+ patch -NREp1 --no-backup-if-mismatch -i "$srcdir"/revert-07_Remove-handload-quality-distinction-1481.patch
- # Fix lumbermill gasoline being spilled instead of being inside the gas pump
- patch -Np1 -i "$srcdir"/0005-lumbermill-gasoline-not-spilled.patch
+ # Revert Hub 01 basement removal.
+ patch -NREp1 --no-backup-if-mismatch -i "$srcdir"/revert-06_Obsolete-useless-hub01-basement-1457.patch
- # Fix community garden liquid fertilizer being in a pit instead of in the storage tanks
- patch -Np1 -i "$srcdir"/0006-community-garden-fertilizer-not-spilled.patch
+ # Revert the removal of book chapters and the generic overhaul of them.
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/revert-02_revert-book-revamp.patch
+ rm -f data/json/items/book/bloat.json
- # Fix oxyacetylene to be craftable from oxygen tanks
- patch -Np1 -i "$srcdir"/0007-oxyacetylene-from-oxygen.patch
+ # Revert generic night vision.
+ patch -NRp1 --no-backup-if-mismatch -i "$srcdir"/revert-03_generic-nv.patch
+ # Revert telescopic lenses.
+ patch -NRp1 --no-backup-if-mismatch -i "$srcdir"/revert-04_telescopic-lenses.patch
+
+ # Revert the Infection Immune Trait and Revert Infection Resistant to as before. Also keep Truthteller.
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/revert-01_removed-traits.patch
+
+
+ # # # Various fixes for bugs I came across
+ # # Ammo fixes
+ echo "Applying ammo fixes"
+ # Fix mulitple inconsistent ammunition names and handloaded status.
+ # Offladed to ammo rebalance mod
+ #patch -Np1 --no-backup-if-mismatch -i "$srcdir"/ammo-01_inconsistent-ammo-names.patch
+
+ # Fix black powder scrap shot not being flagged as black powder.
+ # Offloaded to ammo rebalance mod
+ #patch -Np1 --no-backup-if-mismatch -i "$srcdir"/ammo-06_fix-bp-scrap-not-being-bp.patch
+
+ # Fix ammo ordering so as to not prevent those items being modded:
+ # Having copy-from items occuring earlier in a json than the item being copied from prevents items based on it being modified.
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/ammo-10_ammo-order-fix.patch
+
+ # Fix 40mm round volume:
+ # Changing abstracts with mods does not seem to work, so here this is.
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/ammo-11_fix-volume-40mm.patch
+
+ # Set a fixed loudness for 20x66mm shotgun shells like that of other shotguns:
+ # Other shotguns have fixed loudness to work around how the short range causes the loudness value to be far lower than one would otherwise expect.
+ # Abstract change, so this cannot be fixed by a mod.
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/ammo-12_fix-20x66mm-loudness.patch
+
+ # Change reloaded_50bmg to be based on 50bmg:
+ # The id and description make it pretty clear that reloaded_50bmg is not supposed to be based on Match rounds.
+ # This is fixed here instead of a mod so as to prevent copy-from dependency loops.
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/ammo-13_fix-reloaded-50bmg.patch
+
+
+ # # armor fixes
+ echo "Applying armor fixes"
+ # Fix Ankle Ammo Pouch to not look like a backpack:
+ # SDG added a tile for ammo pouches to bypass this bug, but this fix still makes sense.
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/armor-01_ankle-ammo-pouch-is-not-a-backpack.patch
+
+ # Fix fingerless survivor gloves losing base warmth:
+ # They lose warmth already from the lack of coverage, no need to double up.
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/armor-02_fix-survivor-fingerless-gloves-warmth.patch
+
+
+ # # bionics fixes
+ echo "Applying bionic fixes"
# Fix npc not being able to install some additional CBMs:
- # ie, soporific inducer, gasoline fuel cell, enhanced hearing, surgical scalpels
- patch -Np1 -i "$srcdir"/0008-npc-can-use-more-bionics.patch
+ # ie, soporific inducer, gasoline fuel cell, enhanced hearing, surgical scalpels.
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/bionics-01_npc-can-use-more-bionics.patch
+
+
+ # # faction fixes
+ echo "Applying faction fixes"
+ # Backport the factions.json updates from DDA
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/faction-01_more-factions.patch
+
+ # Fix faction food supply being calculated at 288 calories per person instead of 2500.
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/faction-03_fix-food-supply-calculations.patch
+
+
+ # # faction camp fixes
+ echo "Applying faction camp fixes"
+ # cur_level is set to -1 on all modern basecamps. Remove the recruiting penalty this legacy variable inadvertently induces.
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/factioncamp-01_remove-legacy-recruiting-penalty.patch
+
+
+ # # food fixes
+ echo "Applying food fixes"
+ # Fix several foods not being marked as the correct material:
+ # This prevents odd outcomes such as carnivores drinking almond/soy milk and eating peanut butter.
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/foods-01_fix-food-materials.patch
+
+ # Fix several foods using unclear naming:
+ # Rename can_corn from corn to canned corn to make its limited use in recipes more clear.
+ # Fix pluralization of canned beans to also be canned beans.
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/foods-02_fix-food-naming.patch
+
+ # Fix several mutant components lacking the BAD_TASTE flag:
+ # If raw mutant meat is flagged as disgusting, raw mutant fat must be just awful.
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/foods-03_fix-mutant-bad-taste.patch
+
+ # Allow canned corn to be used as a veggy_any requirement:
+ # Canned corn was pretty much useless beyond making fish soup despite being a perfectly fine cooked vegetable.
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/foods-04_allow-canned-corn-as-veggy.patch
+
+ # Fix some foods lacking price_postapoc values:
+ # Fruit slices were several times as valuable as canned fruit.
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/foods-05_fix-missing-price-postapoc.patch
+
+ # Fix several sealed foods spawning only half full:
+ # And one spawning double-full.
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/foods-06_sealed-foods-not-full.patch
+
+ # Fix cooked meat scrap description:
+ # The description for cooked scrap of mutant meat was incorrectly used for cooked scrap of non-mutant meat.
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/foods-07_fix-meat-scrap-description.patch
- # Fix .22 casings not stacking when every other casing stacks
- patch -Np1 -i "$srcdir"/0009-22-casings-can-stack.patch
- # Fix reloaded 45-70 rounds and reloaded dragon shot were not allowing dismantling when every other non-caseless does
- patch -Np1 -i "$srcdir"/0010-4570-dragon-can-be-dismantled.patch
+ # # itemgroups fixes
+ echo "Applying itemgroup fixes"
+ # Stop police and SWAT carrying 4.6mm magazines despite having no compatible weapons:
+ # The H&K UCP was removed from the base game some time ago.
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/itemgroups-01_hk46-is-milspec.patch
- # Fix the pepperjack beef and burrito bowl MREs never dropping
- patch -Np1 -i "$srcdir"/0011-add-missing-mre.patch
+ # Fix the pepperjack beef and burrito bowl MREs never dropping:
+ # They weren't in the itemgroups for MREs or soldier class.
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/itemgroups-02_add-missing-mre.patch
- # Fix some doors being unusable by npcs (incorrect door flag)
- patch -Np1 -i "$srcdir"/0012-fix-doors-for-npcs.patch
+ # Fix items in unlooted, unused lockers and cabinets missing batteries:
+ # They need to be marked as the battery contained inside the item.
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/itemgroups-03_fix-shelter-batteries.patch
- # Fix the loudness of 20x66mm shotgun shells like other shotguns
- patch -Np1 -i "$srcdir"/0013-fix-20x66mm-loudness.patch
- # Replace the portable generator twin engine with a large 1 cylinder so it can actually function as is
- patch -Np1 -i "$srcdir"/0014-portable-generator-engine.patch
+ # # medicine fixes
+ echo "Applying medicine fixes"
+ # Add -4 health to antibiotics:
+ # weak are -2, strong are -10, this feels like a nice middle ground.
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/meds-01_antibiotics-unhealthy.patch
- # Normalize the manhack volumes to that of the base grenade/explosive
- patch -Np1 -i "$srcdir"/0015-normalize-drone-volume.patch
- # Prefix medical zombies with "zombie" like other zombies.
- patch -Np1 -i "$srcdir"/0016-medical-zombies-called-zombies.patch
+ # # missions fixes
+ echo "Applying migration fixes"
+ # Remove UCP from migration list:
+ # Removing item migrations with mods does not seem to work, so here this is.
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/migration-01_remove-ucp.patch
- # Light Step feels too powerful in Bright Nights
- patch -Np1 -i "$srcdir"/0017-nerf-lightstep.patch
- # Re-hide something that feels like spoilers
- patch -Np1 -i "$srcdir"/0018-rehide-redacted.patch
+ # # missions fixes
+ echo "Applying mission fixes"
+ # Fix Typos:
+ # Foraging encounter has inconsistent monster references. Change all to cougar.
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/mission-01_typos.patch
- # Set the overmap note for Derelict Shed to s to better match use of the first letter
- patch -Np1 -i "$srcdir"/0019-derelict-shed-is-s.patch
+ # Move the gunslinger quest in front of the zombie horde quest:
+ # The context of the horde mission suggests that the player should obtain another follower before attempting it,
+ # thus it makes more sense to have the obtain gunslinger mission occur before, not after. Simultaneously makes even more sense, but the game doesn't support it.
+ # Note: The gunslinger mission is prone to errors. Save before accepting it, make sure you are on ground level, and increase the search_range if it still fails.
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/mission-02_reorder-gunslinger-quest.patch
- # Stop police and SWAT carrying 4.6mm magazines despite having no compatible weapons
- patch -Np1 -i "$srcdir"/0020-hk46-is-milspec.patch
- # Mark the foldable plastic bottle and steel water bottle as containers
- patch -Np1 -i "$srcdir"/0021-foldable-bottle-is-container.patch
+ # # monster fixes
+ echo "Applying monster fixes"
+ # Prefix medical zombies with "zombie" like other zombies:
+ # It just felt weird seeing "nurse" in the enemy list.
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/monsters-01_medical-zombies-called-zombies.patch
- # Fix Evacuee 3 background 3 being player visible
- patch -Np1 -i "$srcdir"/0022-fix-evac3-background-visible.patch
- # Fix rubber items dismantling into 10x item volume of rubber
- patch -Np1 -i "$srcdir"/0023-fix-rubbersplosion.patch
+ # # mutation fixes
+ echo "Applying mutation fixes"
+ # Light Step feels too powerful in Bright Nights.
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/mutations-01_nerf-lightstep.patch
- # Fix ammo ordering so as to not prevent those items being modded
- patch -Np1 -i "$srcdir"/0024-ammo-order-fix.patch
+ # Fix Evacuee 3 background 3 being player visible:
+ # It was missing "player_display": false
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/mutations-02_fix-evac3-background-visible.patch
- # Various other fixes for bugs I came across that modify src
- # Fix ammo loudness mulitplying by six instead of two
- patch -Np1 -i "$srcdir"/jc_ammo-loudness-ap-times-2.patch
+ # # npc fixes
+ echo "Applying NPC fixes"
+ # Port the updates to Isherwood Farm from DDA
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/npc-01_isherwood-update.patch
- # Fix smoker racks not accepting bionic firestarter
- patch -Np1 -i "$srcdir"/jc_allow-bio-firestarter-on-smoker.patch
+ # Port the updates to Tacoma Commune from DDA
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/npc-02_tacoma-update.patch
- # Fix NPCs not eating until they drop below normal weight and not becoming full from eating the basecamp stockpile
- patch -Np1 -i "$srcdir"/jc_npcs-eat-when-hungry.patch
+ # Port the updates to New England Church Community from DDA
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/npc-03_godco-update.patch
- # Fix Non-Player facton NPCs from becoming sleep deprived
- patch -Np1 -i "$srcdir"/jc_stop-non-faction-npc-sleep-depirvation.patch
+ # Port the updates to prison and island prison from DDA
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/npc-04_island-prison-update.patch
- # Fix Non-Player facton NPCs from becoming malnourished
- patch -Np1 -i "$srcdir"/jc_stop-non-faction-npc-malnourishment.patch
+ # Port the updates to kindred from DDA
+ rm data/json/npcs/NPC_Brigitte_LaCroix.json
+ patch -NEp1 --no-backup-if-mismatch -i "$srcdir"/npc-05_kindred-update.patch
- # Fix NPCs preferring tables to cots or woodstoves to the floor
- patch -Np1 -i "$srcdir"/jc_stop-sleeping-on-tables.patch
+ # Port the updates to Mr Lapin from DDA
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/npc-06_lapin-update.patch
- # Allow the hacker_laptop to utilize the extra functions
- patch -Np1 -i "$srcdir"/jc_allow-hacker-laptop.patch
+ # Port the lighthouse family from DDA
+ # Hack in some effects to use as timers and probe NPC mechanic skill.
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/npc-07_lighthouse-family_v2.patch
- # Restore the Infection Immune Trait and Revert Infection Resistant to as before
- patch -Np1 -i "$srcdir"/jc_restore-inf-immune.patch
+ # Update the Tacoma Nurse to buy almost every non-dangerous, non-electrical, and non-expensive medicine.
+ # Also remove acceptance for various tools that are not correctly taken, such as first aid kits.
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/npc-08_nurse-takes-more-meds.patch
+ # Update the FMC broker to buy most preserved foods.
+ # Also update the dialogue to specify that he buys more types.
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/npc-09_broker-takes-more-foods.patch
- # Some personal quirks that simply lack a means short of patching the source
- patch -Np1 -i "$srcdir"/custom.patch
+ # Port the bunker merchant from DDA
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/npc-10_bunker-merchant.patch
+
+ # Fix npcs failing to reload activated gas masks:
+ # Most masks lacked a "charges_per_use: 1" field, required for npcs to know they can reload it.
+ # They still won't activate a fresh mask on their own though. :/
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/npc-11_npcs-reload-gas-mask.patch
+
+ # Reduce Eddie Isherwood mission from requiring 1000 clay down to 100:
+ # 1000 units of clay is such an enormous amount compared to the previous 100 sand,
+ # I can only reason it is a typo.
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/npc-12_fix-eddie-requiring-1000-clay.patch
+
+ # Assorted typos in NPC dialogue.
+ # Fix Jack Isherwood mission listing 10 jars, when it is actually 20.
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/npc-20_dialogue-fixes.patch
+
+
+ # # recipe fixes
+ echo "Applying recipe fixes"
+ # Fix reloaded 45-70 rounds and reloaded dragon shot not allowing dismantling when every other non-caseless round does.
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/recipes-01_4570-dragon-can-be-dismantled.patch
+
+ # Fix the rebuilt gatling laser recipe incorrectly being listed twice:
+ # The second is obviously supposed to be the missing rebuilt recon laser recipe.
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/recipes-02_recon-mech-laser-typo.patch
+
+
+ # # terrain and overmap fixes
+ echo "Applying terrain and overmap fixes"
+ # Fix some doors being unusable by npcs (incorrect door flag):
+ # The DOOR flag is for terrain that can be opened, not those already open.
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/terrain-02_fix-doors-for-npcs.patch
+
+ # Fix missing floor in the tacoma clinic:
+ # The hospital is still a mess. :/
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/terrain-03_tacoma-clinic-add-missing-floor.patch
+
+ # Fix lumbermill gasoline being spilled instead of being inside the gas pump:
+ # The gas pump was placed on top of a tile that didn't allow items inside, causing the gasoline to be shunted to the next valid one.
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/terrain-04_lumbermill-gasoline-not-spilled.patch
+
+ # Re-hide something that feels like spoilers.
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/terrain-07_rehide-redacted.patch
+
+ # Fix npcs unable to drink from firestation and shelter basecamps wells:
+ # They were missing the water_well blueprint_provides.
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/terrain-09_make-firestation-shelter-wells-npc-drinkable.patch
+
+ # Fix military base minefield entrance rotation:
+ # Both sides use the same tile, but it was incorrectly rotated 180 degrees. Fixed to 270 degrees.
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/terrain-10_fix-milbase_minefield.patch
+
+ # Fix up several typos, missing symbols, odd naming, and many extras lacking map notes support in map extras:
+ # More choice is better than less. You can disable undesired map notes in the map notes settings menu.
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/terrain-11_clean-up-map-extras.patch
+
+ # Fix mismatched mapgen palettes:
+ # Fixes light machinery incorrectly appearing under various lab furniture
+ # All said items define C as the tile in question, but C is already in lab_palette as t_machinery_electronic.
+ # Changed all such C to K since it was unused in either lab_palette or lab_loot_home_office.
+ # Also fixes sandbag walls at fema camps having indoor flooring underneath.
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/terrain-13_fix-mapgen-palettes.patch
+
+
+ # # tool fixes
+ echo "Applying tool fixes"
+ # Mark the foldable plastic bottle and steel water bottle as containers:
+ # Being counted as tools didn't seem to fit their role.
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/tools-01_foldable-bottle-is-container.patch
+
+ # Fix electric shears not using batteries nor charging via UPS:
+ # Item was unusable without this patch.
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/tools-03_shears-use-light-battery.patch
+
+
+ # # vehicle fixes
+ echo "Applying vehicle fixes"
+ # Replace the portable generator twin engine with a large 1 cylinder:
+ # This way it can actually function as is.
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/vehicles-01_portable-generator-engine.patch
+
+ # Rename the FBI Car:
+ # The stock name was clearly a typo of some sort.
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/vehicles-02_fix-fbi-car-name.patch
+
+ # Fix the black box to actually be installable:
+ # No tool provided screwing 3 and wrenching 3.
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/vehicles-03_black-box-can-be-installed.patch
+
+
+ # # weapon fixes
+ echo "Applying weapon fixes"
+ # Fix the USP45 handgun not being modifiable:
+ # It uses copy-from usp_9mm that loads later, which prevented modifying it.
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/weapon-02_Fix-usp45-load-order.patch
+
+
+ # # Uncategorized for now
+ echo "Applying uncategorized fixes"
+
+ # Add price_postapoc to a number of items that did not have one set.
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/etc-02_add-missing-price-postapoc.patch
+
+ # Convert a number of items to abstracts:
+ # From the usage, these are intended to be abstracts but have not yet been converted from legacy items.
+ # This fixes some erroneous weapon listings in custom martial arts.
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/etc-03_fix-abstracts.patch
+
+
+ # # # Various other fixes for bugs I came across that modify src
+ echo "Applying source code fixes"
+ # Fix radio, e-ink reader music, tactical tonfa not working with UPS.
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/src-01_radio-can-use-ups.patch
+
+ # Fix ammo loudness mulitplying by six instead of two.
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/src-02_ammo-loudness-ap-times-2.patch
+
+ # Fix smoker racks not accepting bionic firestarter.
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/src-03_allow-bio-firestarter-on-smoker.patch
+
+ # Fix Non-Player facton NPCs from becoming sleep deprived.
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/src-04_stop-non-faction-npc-sleep-depirvation.patch
+
+ # Fix Non-Player facton NPCs from becoming malnourished.
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/src-05_stop-non-faction-npc-malnourishment.patch
+
+ # Fix NPCs preferring tables to cots or woodstoves to the floor.
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/src-06_stop-sleeping-on-tables.patch
+
+ # Allow the hacker_laptop to utilize the extra functions.
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/src-07_allow-hacker-laptop.patch
+
+ # Expand the overmap tiles for the miltiary base to be less MMMM
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/src-08_more-military-base-overmap.patch
+
+ # Allow npcs to pull food from the camp larder at the full range of tiles camp actions can be assigned from:
+ # Should allow bases larger than 3x3 to have less food micromanagment for NPCs.
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/src-09_npc-eat-from-further-camp.patch
+
+ # Revert removal of half calorie consumption while sleeping:
+ # Managing the food supply of more than a few NPCs in BN is extremely difficult compared to DDA.
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/src-10_reduced-kcal-during-sleep.patch
+
+ # Fix tacoma crop overseer failing to detect player current cash:
+ # The two plot purchasing functions use the seemingly obsolete player_character.cash instead of g->u.cash
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/src-11_fix-tacoma-farmfield.patch
+
+ # Reduce the mechanical skill experience from lockpicking:
+ # With lock_roll being 1-120 and used in place of difficulty,
+ # it often caused a level up with every lock, even at very high skill levels
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/src-12_lower-lockpicking-experience.patch
+
+ # Allow military searchlights to be powered by the plutonium generator grid furniture:
+ # Searchlights check for a nearby plutonium generator terrain to function,
+ # but the function was never updated to include the new grid furniture version.
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/src-13_searchlights-with-plut-gen-furn.patch
+
+ # Fix calculation of npc npc_melee assessment:
+ # dist == 1 always fails, but dist <= 1 works.
+ # Without this, npcs in melee range will never take any action and be swiftly slain.
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/src-14_fix-npc_melee-calculations.patch
+
+ # Slow down fungal blossoms:
+ # This patch reduces the transform chance. It was so high compared to 'vulnerable' young trees,
+ # I can only conclude the 100 was meant to be 1000, and thus 8% chance instead of 80%
+ # Without this patch, x_in_y is 100, fungal blossoms increase their numbers by roughly a factor of 10 every 60 seconds. 10->100->1000 in two minutes, yikes.
+ # With x_in_y changed to 1000, fungal blossoms increase their numbers by roughly double every 60 seconds.
+ # With x_in_y changed to 2000, fungal blossoms increase their numbers by roughly half every 60 seconds.
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/src-15_slow-down-fungal-blossoms.patch
+
+
+ # # # Additional changes
+ echo "Applying vampirism patch"
+ # Add vampire mutation lines and modify a number of functions to facilitate these traits.
+ patch -Np1 --no-backup-if-mismatch -i "$srcdir"/vampirism.patch
}
build() {
- cd "${_pkgname}-${_pkgver}"
+# cd "${_pkgname}-${_pkgver}"
+ cd "${_pkgname}-${pkgver}"
#export CFLAGS="$CFLAGS -fPIE"
export CXXFLAGS="$CXXFLAGS -fPIE"
export LDFLAGS="$LDFLAGS,-pie"
- # tests "ifdef TILES" so "TILES=0" will enable tiles!
- # DYNAMIC_LINKING appears to be a windows flag?
- make PREFIX=/usr RELEASE=1 USE_XDG_DIR=1 BACKTRACE=0 LTO=1 LOCALIZE=1 LANGUAGES=all
- make PREFIX=/usr RELEASE=1 USE_XDG_DIR=1 BACKTRACE=0 LTO=1 LOCALIZE=1 LANGUAGES=all TILES=1 SOUND=1
+ # Prevent segfaults when examine tile->search returns no results.
+ #export CXXFLAGS="$(echo $CXXFLAGS | sed -i 's/-Wp,-D_GLIBCXX_ASSERTIONS//' - )" # No longer works
+ export CXXFLAGS="$(echo $CXXFLAGS | sed 's/-Wp,-D_GLIBCXX_ASSERTIONS//')"
+ #echo $CXXFLAGS
+
+ make PREFIX=/usr RELEASE=1 USE_XDG_DIR=1 BACKTRACE=0 LOCALIZE=1 LANGUAGES=all RUNTESTS=0 VERBOSE=1 PCH=0 LUA=0 CCACHE=0
+ make PREFIX=/usr RELEASE=1 USE_XDG_DIR=1 BACKTRACE=0 LOCALIZE=1 LANGUAGES=all RUNTESTS=0 VERBOSE=1 PCH=0 LUA=0 CCACHE=0 TILES=1 SOUND=1
./lang/compile_mo.sh
}
package_cataclysm-bn() {
- cd "${_pkgname}-${_pkgver}"
+# cd "${_pkgname}-${_pkgver}"
+ cd "${_pkgname}-${pkgver}"
- make DESTDIR="$pkgdir" PREFIX="/usr" RELEASE=1 USE_HOME_DIR=1 LTO=1 LOCALIZE=1 LANGUAGES=all install
+ make DESTDIR="$pkgdir" PREFIX="/usr" RELEASE=1 USE_HOME_DIR=1 LOCALIZE=1 LANGUAGES=all RUNTESTS=0 VERBOSE=1 PCH=0 LUA=0 CCACHE=0 install
# Docs
install -d "$pkgdir/usr/share/doc/cataclysm-bn"
cp --reflink -r doc/* "$pkgdir/usr/share/doc/cataclysm-bn"
- # undo symlink
- rm "$pkgdir/usr/share/doc/cataclysm-bn/JSON_LOADING_ORDER.md"
- cp --reflink 'data/json/LOADING_ORDER.md' "$pkgdir/usr/share/doc/cataclysm-bn/JSON_LOADING_ORDER.md"
+
+ # Fix tileset readme being duplicated in curses package
+ rm "$pkgdir/usr/share/cataclysm-bn/json/external_tileset/README.md"
# License
install -Dm644 LICENSE.txt "$pkgdir/usr/share/licenses/$pkgname/LICENSE"
@@ -305,44 +823,33 @@ package_cataclysm-bn() {
package_cataclysm-bn-tiles() {
pkgdesc="A graphical post-apocalyptic roguelike."
depends=('cataclysm-bn' 'sdl2_image' 'sdl2_ttf' 'freetype2' 'sdl2_mixer')
- cd "${_pkgname}-${_pkgver}"
+# cd "${_pkgname}-${_pkgver}"
+ cd "${_pkgname}-${pkgver}"
- make DESTDIR="$pkgdir" PREFIX="/usr" RELEASE=1 LTO=1 LOCALIZE=1 LANGUAGES=all TILES=1 SOUND=1 install
+ make DESTDIR="$pkgdir" PREFIX="/usr" RELEASE=1 LOCALIZE=1 LANGUAGES=all RUNTESTS=0 VERBOSE=1 PCH=0 LUA=0 CCACHE=0 TILES=1 SOUND=1 install
# Icon
#install -D 'data/osx/AppIcon.iconset/icon_128x128.png' "$pkgdir/usr/share/icons/hicolor/128x128/apps/$pkgname.png"
#install -D 'data/osx/AppIcon.iconset/icon_128x128.png' "$pkgdir/usr/share/pixmaps/$pkgname.png"
- install -D "${srcdir}/icon_128x128.png" "$pkgdir/usr/share/icons/hicolor/128x128/apps/$pkgname.png"
- install -D "${srcdir}/icon_128x128.png" "$pkgdir/usr/share/pixmaps/$pkgname.png"
+ install -Dm644 "${srcdir}/icon_128x128.png" "$pkgdir/usr/share/icons/hicolor/128x128/apps/$pkgname.png"
+ install -Dm644 "${srcdir}/icon_128x128.png" "$pkgdir/usr/share/pixmaps/$pkgname.png"
install -Dm644 "${srcdir}/$pkgname.desktop" "${pkgdir}/usr/share/applications/$pkgname.desktop"
install -Dm644 LICENSE.txt "$pkgdir/usr/share/licenses/$pkgname/LICENSE"
- # Tileset
- mv "$srcdir/cataclysm-dda-tileset_undeadpeople-master" "$srcdir/undeadpeople"
- cp --reflink -r "$srcdir/undeadpeople" "$pkgdir/usr/share/cataclysm-bn/gfx"
+ # Remove unmaintained UDP tileset
+ # Use my forked cataclysm-bn-tileset package for a working UDP tileset
rm -rf "$pkgdir/usr/share/cataclysm-bn/gfx/MSX++UnDeadPeopleEdition"
- #mv "$srcdir/cataclysm-dda-mod_battle-maid-redone-tileset-master" "$srcdir/battle-maid-redone-tileset"
- cp --reflink -r "$srcdir/cataclysm-dda-mod_battle-maid-redone-tileset-master/battle-maid-redone-tileset-pt1" "$pkgdir/usr/share/cataclysm-bn/mods"
- cp --reflink -r "$srcdir/cataclysm-dda-mod_battle-maid-redone-tileset-master/battle-maid-redone-tileset-pt2" "$pkgdir/usr/share/cataclysm-bn/mods"
-
-
- # Sound
- mv "$srcdir/cataclysm-dda-soundpack_jcsoundpack-master" "$srcdir/jcsoundpack"
- cp --reflink -r "$srcdir/jcsoundpack" "$pkgdir/usr/share/cataclysm-bn/sound"
-
- # Music
- mv "$srcdir/cataclysm-dda-musicpack_coag-musicpack-master" "$srcdir/coag-musicpack"
- install -Dm644 "$srcdir/coag-musicpack/musicset.json" "$pkgdir/usr/share/cataclysm-bn/sound/jcsoundpack/musicset.json"
- cp --reflink -r "$srcdir/coag-musicpack/music" "$pkgdir/usr/share/cataclysm-bn/sound/jcsoundpack"
-
# hack: remove overlapping files
cd "$pkgdir/../cataclysm-bn"
find . -type f -exec rm -f "$pkgdir"/{} \;
cd "$pkgdir"
find . -type d -empty -delete
+
+ # Fix mapgen readme being duplicated in tileset package
+ rm "$pkgdir/usr/share/cataclysm-bn/json/mapgen/lab/README.md"
}
diff --git a/ammo-10_ammo-order-fix.patch b/ammo-10_ammo-order-fix.patch
new file mode 100644
index 0000000..65b0d32
--- /dev/null
+++ b/ammo-10_ammo-order-fix.patch
@@ -0,0 +1,763 @@
+--- a/data/json/items/ammo/20x66mm.json
++++ b/data/json/items/ammo/20x66mm.json
+@@ -1,5 +1,35 @@
+ [
+ {
++ "abstract": "20x66_shot_abstract",
++ "type": "AMMO",
++ "name": { "str": "20x66mm buckshot" },
++ "//": "2.5x the Generic Rate of $1/shot",
++ "description": "20x66mm caseless shotgun rounds, buckshot type. Proprietary ammunition for Rivtech shotguns. Being caseless rounds, these cannot be disassembled or reloaded.",
++ "weight": "56 g",
++ "volume": "250 ml",
++ "price": "15 USD",
++ "price_postapoc": "40 USD",
++ "flags": [ "IRREPLACEABLE_CONSUMABLE" ],
++ "material": [ "steel", "powder" ],
++ "symbol": "=",
++ "color": "pink",
++ "count": 20,
++ "stack_size": 20,
++ "ammo_type": "20x66mm",
++ "range": 12,
++ "damage": { "damage_type": "bullet", "amount": 100 },
++ "recoil": 2500,
++ "effects": [ "COOKOFF", "SHOT", "NEVER_MISFIRES" ]
++ },
++ {
++ "id": "20x66_shot",
++ "copy-from": "20x66_shot_abstract",
++ "type": "AMMO",
++ "name": { "str": "20x66mm buckshot" },
++ "//": "2.5x the Generic Rate of $1/shot",
++ "description": "20x66mm caseless shotgun rounds, buckshot type. Proprietary ammunition for Rivtech shotguns. Being caseless rounds, these cannot be disassembled or reloaded."
++ },
++ {
+ "id": "20x66_beanbag",
+ "copy-from": "20x66_shot",
+ "type": "AMMO",
+@@ -14,6 +45,19 @@
+ "extend": { "effects": [ "LARGE_BEANBAG", "NOGIB" ] }
+ },
+ {
++ "id": "20x66_flechette",
++ "copy-from": "20x66_shot",
++ "type": "AMMO",
++ "name": { "str": "20x66mm flechette" },
++ "description": "20x66mm caseless shotgun rounds, flechette type. Proprietary ammunition for Rivtech shotguns. Being caseless rounds, these cannot be disassembled or reloaded.",
++ "price": "40 USD",
++ "price_postapoc": "40 USD",
++ "flags": [ "IRREPLACEABLE_CONSUMABLE" ],
++ "count": 10,
++ "//": "Balanced as AP.",
++ "relative": { "damage": { "damage_type": "bullet", "amount": -18, "armor_penetration": 36 } }
++ },
++ {
+ "id": "20x66_flechette_reloaded",
+ "copy-from": "20x66_flechette",
+ "type": "AMMO",
+@@ -34,6 +78,21 @@
+ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+ },
+ {
++ "id": "20x66_slug",
++ "copy-from": "20x66_shot_abstract",
++ "type": "AMMO",
++ "name": { "str": "20x66mm slug" },
++ "description": "20x66mm caseless shotgun rounds, solid projectile type. Proprietary ammunition for Rivtech shotguns. Being caseless rounds, these cannot be disassembled or reloaded.",
++ "price": "15 USD",
++ "price_postapoc": "40 USD",
++ "flags": [ "IRREPLACEABLE_CONSUMABLE" ],
++ "//": "Balanced as FMJ",
++ "damage": { "damage_type": "bullet", "amount": 84, "armor_penetration": 21 },
++ "relative": { "range": 20 },
++ "proportional": { "dispersion": 1.3 },
++ "delete": { "effects": [ "SHOT" ] }
++ },
++ {
+ "id": "20x66_slug_reloaded",
+ "copy-from": "20x66_slug",
+ "type": "AMMO",
+@@ -75,19 +134,6 @@
+ "effects": [ "NO_EMBED" ]
+ },
+ {
+- "id": "20x66_flechette",
+- "copy-from": "20x66_shot",
+- "type": "AMMO",
+- "name": { "str": "20x66mm flechette" },
+- "description": "20x66mm caseless shotgun rounds, flechette type. Proprietary ammunition for Rivtech shotguns. Being caseless rounds, these cannot be disassembled or reloaded.",
+- "price": "40 USD",
+- "price_postapoc": "40 USD",
+- "flags": [ "IRREPLACEABLE_CONSUMABLE" ],
+- "count": 10,
+- "//": "Balanced as AP.",
+- "relative": { "damage": { "damage_type": "bullet", "amount": -18, "armor_penetration": 36 } }
+- },
+- {
+ "id": "20x66_frag",
+ "copy-from": "20x66_slug",
+ "type": "AMMO",
+@@ -111,50 +157,5 @@
+ "flags": [ "IRREPLACEABLE_CONSUMABLE" ],
+ "count": 10,
+ "extend": { "effects": [ "INCENDIARY" ] }
+- },
+- {
+- "abstract": "20x66_shot_abstract",
+- "type": "AMMO",
+- "name": { "str": "20x66mm buckshot" },
+- "//": "2.5x the Generic Rate of $1/shot",
+- "description": "20x66mm caseless shotgun rounds, buckshot type. Proprietary ammunition for Rivtech shotguns. Being caseless rounds, these cannot be disassembled or reloaded.",
+- "weight": "56 g",
+- "volume": "250 ml",
+- "price": "15 USD",
+- "price_postapoc": "40 USD",
+- "flags": [ "IRREPLACEABLE_CONSUMABLE" ],
+- "material": [ "steel", "powder" ],
+- "symbol": "=",
+- "color": "pink",
+- "count": 20,
+- "stack_size": 20,
+- "ammo_type": "20x66mm",
+- "range": 20,
+- "damage": { "damage_type": "bullet", "amount": 100 },
+- "recoil": 2500,
+- "effects": [ "COOKOFF", "SHOT", "NEVER_MISFIRES" ]
+- },
+- {
+- "id": "20x66_shot",
+- "copy-from": "20x66_shot_abstract",
+- "type": "AMMO",
+- "name": { "str": "20x66mm buckshot" },
+- "//": "2.5x the Generic Rate of $1/shot",
+- "description": "20x66mm caseless shotgun rounds, buckshot type. Proprietary ammunition for Rivtech shotguns. Being caseless rounds, these cannot be disassembled or reloaded."
+- },
+- {
+- "id": "20x66_slug",
+- "copy-from": "20x66_shot_abstract",
+- "type": "AMMO",
+- "name": { "str": "20x66mm slug" },
+- "description": "20x66mm caseless shotgun rounds, solid projectile type. Proprietary ammunition for Rivtech shotguns. Being caseless rounds, these cannot be disassembled or reloaded.",
+- "price": "15 USD",
+- "price_postapoc": "40 USD",
+- "flags": [ "IRREPLACEABLE_CONSUMABLE" ],
+- "//": "Balanced as FMJ",
+- "damage": { "damage_type": "bullet", "amount": 84, "armor_penetration": 21 },
+- "relative": { "range": 20 },
+- "proportional": { "dispersion": 1.3 },
+- "delete": { "effects": [ "SHOT" ] }
+ }
+ ]
+
+--- a/data/json/items/ammo/22.json
++++ b/data/json/items/ammo/22.json
+@@ -1,16 +1,5 @@
+ [
+ {
+- "id": "22_cphp",
+- "copy-from": "22_lr",
+- "type": "AMMO",
+- "name": { "str": ".22 CPHP" },
+- "description": ".22 Long Rifle ammunition with 30gr copper-plated, hollow-point bullets. Has a higher velocity and slightly more stopping power than lead round-nose ammunition, but armor will have a magnified effect on its already-low penetration.",
+- "//": "Hollowpoint damage increase of 25%",
+- "damage": { "damage_type": "bullet", "amount": 20, "armor_penetration": 0 },
+- "relative": { "range": 3 },
+- "proportional": { "recoil": 1.5 }
+- },
+- {
+ "id": "22_lr",
+ "type": "AMMO",
+ "name": { "str": ".22 LR" },
+@@ -35,6 +24,17 @@
+ "effects": [ "COOKOFF" ]
+ },
+ {
++ "id": "22_cphp",
++ "copy-from": "22_lr",
++ "type": "AMMO",
++ "name": { "str": ".22 CPHP" },
++ "description": ".22 Long Rifle ammunition with 30gr copper-plated, hollow-point bullets. Has a higher velocity and slightly more stopping power than lead round-nose ammunition, but armor will have a magnified effect on its already-low penetration.",
++ "//": "Hollowpoint damage increase of 25%",
++ "damage": { "damage_type": "bullet", "amount": 20, "armor_penetration": 0 },
++ "relative": { "range": 3 },
++ "proportional": { "recoil": 1.5 }
++ },
++ {
+ "id": "22_ratshot",
+ "copy-from": "22_cphp",
+ "type": "AMMO",
+
+--- a/data/json/items/ammo/38.json
++++ b/data/json/items/ammo/38.json
+@@ -1,14 +1,5 @@
+ [
+ {
+- "id": "38_fmj",
+- "copy-from": "38_special",
+- "type": "AMMO",
+- "name": { "str": ".38 FMJ" },
+- "description": ".38 Special ammunition with brass jacketed 130gr bullets. The .38 Special round has been known from its inception for its accuracy and low recoil.",
+- "//": "Base damage of 20, balance increase of two-nineths.",
+- "relative": { "damage": { "damage_type": "bullet", "amount": -6, "armor_penetration": 14 } }
+- },
+- {
+ "id": "38_special",
+ "type": "AMMO",
+ "name": { "str": ".38 Special" },
+@@ -33,6 +24,15 @@
+ "effects": [ "COOKOFF" ]
+ },
+ {
++ "id": "38_fmj",
++ "copy-from": "38_special",
++ "type": "AMMO",
++ "name": { "str": ".38 FMJ" },
++ "description": ".38 Special ammunition with brass jacketed 130gr bullets. The .38 Special round has been known from its inception for its accuracy and low recoil.",
++ "//": "Base damage of 20, balance increase of two-nineths.",
++ "relative": { "damage": { "damage_type": "bullet", "amount": -6, "armor_penetration": 14 } }
++ },
++ {
+ "id": "bp_38_fmj",
+ "copy-from": "38_fmj",
+ "type": "AMMO",
+
+--- a/data/json/items/ammo/40.json
++++ b/data/json/items/ammo/40.json
+@@ -1,14 +1,5 @@
+ [
+ {
+- "id": "40fmj",
+- "copy-from": "40sw",
+- "type": "AMMO",
+- "name": { "str": ".40 S&W FMJ" },
+- "description": ".40 S&W ammunition with 180gr FMJ bullets. Designed to retain the 10mm Auto cartridge's power with lower recoil, the .40 S&W round became popular for law enforcement and personal defense.",
+- "//": "Base damage of 23, balance increase of two-nineths.",
+- "relative": { "damage": { "damage_type": "bullet", "amount": -7, "armor_penetration": 16 } }
+- },
+- {
+ "id": "40sw",
+ "type": "AMMO",
+ "name": { "str": ".40 S&W JHP" },
+@@ -33,6 +24,15 @@
+ "effects": [ "COOKOFF" ]
+ },
+ {
++ "id": "40fmj",
++ "copy-from": "40sw",
++ "type": "AMMO",
++ "name": { "str": ".40 S&W FMJ" },
++ "description": ".40 S&W ammunition with 180gr FMJ bullets. Designed to retain the 10mm Auto cartridge's power with lower recoil, the .40 S&W round became popular for law enforcement and personal defense.",
++ "//": "Base damage of 23, balance increase of two-nineths.",
++ "relative": { "damage": { "damage_type": "bullet", "amount": -7, "armor_penetration": 16 } }
++ },
++ {
+ "id": "bp_40fmj",
+ "copy-from": "40fmj",
+ "type": "AMMO",
+
+--- a/data/json/items/ammo/44.json
++++ b/data/json/items/ammo/44.json
+@@ -1,14 +1,5 @@
+ [
+ {
+- "id": "44fmj",
+- "copy-from": "44magnum",
+- "type": "AMMO",
+- "name": { "str": ".44 Magnum FMJ" },
+- "description": "A brass-jacketed variant of the .44 Magnum round. This increases penetration at the cost of reduced damage from expansion.",
+- "//": "Base damage of 36, balance increase of one-nineth.",
+- "relative": { "damage": { "damage_type": "bullet", "amount": -10, "armor_penetration": 23 } }
+- },
+- {
+ "id": "44magnum",
+ "type": "AMMO",
+ "name": { "str": ".44 Magnum" },
+@@ -33,6 +24,15 @@
+ "effects": [ "COOKOFF" ]
+ },
+ {
++ "id": "44fmj",
++ "copy-from": "44magnum",
++ "type": "AMMO",
++ "name": { "str": ".44 Magnum FMJ" },
++ "description": "A brass-jacketed variant of the .44 Magnum round. This increases penetration at the cost of reduced damage from expansion.",
++ "//": "Base damage of 36, balance increase of one-nineth.",
++ "relative": { "damage": { "damage_type": "bullet", "amount": -10, "armor_penetration": 23 } }
++ },
++ {
+ "id": "bp_44magnum",
+ "copy-from": "44magnum",
+ "type": "AMMO",
+
+--- a/data/json/items/ammo/45.json
++++ b/data/json/items/ammo/45.json
+@@ -1,14 +1,5 @@
+ [
+ {
+- "id": "45_acp",
+- "copy-from": "45_jhp",
+- "type": "AMMO",
+- "name": { "str": ".45 ACP FMJ" },
+- "description": ".45 ACP ammunition with 230gr FMJ bullets. Noted for its stopping power, the .45 ACP round has been common for almost 150 years.",
+- "//": "Base damage of 27, balance increase of two-nineths.",
+- "relative": { "damage": { "damage_type": "bullet", "amount": -8, "armor_penetration": 18 } }
+- },
+- {
+ "id": "45_jhp",
+ "type": "AMMO",
+ "name": { "str": ".45 ACP JHP" },
+@@ -32,6 +23,15 @@
+ "effects": [ "COOKOFF" ]
+ },
+ {
++ "id": "45_acp",
++ "copy-from": "45_jhp",
++ "type": "AMMO",
++ "name": { "str": ".45 ACP FMJ" },
++ "description": ".45 ACP ammunition with 230gr FMJ bullets. Noted for its stopping power, the .45 ACP round has been common for almost 150 years.",
++ "//": "Base damage of 27, balance increase of two-nineths.",
++ "relative": { "damage": { "damage_type": "bullet", "amount": -8, "armor_penetration": 18 } }
++ },
++ {
+ "id": "45_super",
+ "copy-from": "45_jhp",
+ "type": "AMMO",
+
+--- a/data/json/items/ammo/460.json
++++ b/data/json/items/ammo/460.json
+@@ -1,13 +1,5 @@
+ [
+ {
+- "id": "460_fmj",
+- "copy-from": "460_rowland",
+- "type": "AMMO",
+- "name": { "str": ".460 Rowland HCFN" },
+- "description": "A plated, hard cast flat nosed variant of the .460 Rowland round. This increases penetration slightly at the cost of reduced damage from expansion.",
+- "relative": { "damage": { "damage_type": "bullet", "amount": -4, "armor_penetration": 8 } }
+- },
+- {
+ "id": "460_rowland",
+ "copy-from": "44magnum",
+ "type": "AMMO",
+@@ -18,6 +10,14 @@
+ "proportional": { "range": 0.95, "damage": { "damage_type": "bullet", "amount": 0.95, "armor_penetration": 0.95 }, "recoil": 0.95 }
+ },
+ {
++ "id": "460_fmj",
++ "copy-from": "460_rowland",
++ "type": "AMMO",
++ "name": { "str": ".460 Rowland HCFN" },
++ "description": "A plated, hard cast flat nosed variant of the .460 Rowland round. This increases penetration slightly at the cost of reduced damage from expansion.",
++ "relative": { "damage": { "damage_type": "bullet", "amount": -4, "armor_penetration": 8 } }
++ },
++ {
+ "id": "bp_460_fmj",
+ "copy-from": "460_fmj",
+ "type": "AMMO",
+
+--- a/data/json/items/ammo/50.json
++++ b/data/json/items/ammo/50.json
+@@ -1,15 +1,5 @@
+ [
+ {
+- "id": "50_incendiary",
+- "copy-from": "50bmg",
+- "type": "AMMO",
+- "name": { "str": ".50 BMG M17 tracer" },
+- "description": "A tracer variant of the powerful .50 BMG round. Tracer rounds help to keep the weapon they are fired from on target at the risk of igniting flammable substances.",
+- "count": 10,
+- "effects": [ "INCENDIARY" ],
+- "dispersion": 310
+- },
+- {
+ "id": "50bmg",
+ "type": "AMMO",
+ "name": { "str": ".50 BMG M33 Ball" },
+@@ -34,6 +24,16 @@
+ "effects": [ "COOKOFF", "NEVER_MISFIRES" ]
+ },
+ {
++ "id": "50_incendiary",
++ "copy-from": "50bmg",
++ "type": "AMMO",
++ "name": { "str": ".50 BMG M17 tracer" },
++ "description": "A tracer variant of the powerful .50 BMG round. Tracer rounds help to keep the weapon they are fired from on target at the risk of igniting flammable substances.",
++ "count": 10,
++ "effects": [ "INCENDIARY" ],
++ "dispersion": 310
++ },
++ {
+ "id": "50match",
+ "copy-from": "50bmg",
+ "type": "AMMO",
+
+--- a/data/json/items/ammo/8x40mm.json
++++ b/data/json/items/ammo/8x40mm.json
+@@ -1,5 +1,36 @@
+ [
+ {
++ "id": "8mm_caseless",
++ "type": "AMMO",
++ "name": { "str_sp": "8x40mm caseless" },
++ "//": "Cased ammo tends to be roughly $1/shot, more or less. Rivtech ammo, being New and Proprietary and Expensive, $2-2.50 or so.",
++ "description": "8x40mm caseless rounds. Proprietary ammunition for Rivtech firearms. Being caseless rounds, these cannot be disassembled or reloaded.",
++ "weight": "12 g",
++ "volume": "250 ml",
++ "price": "225 cent",
++ "price_postapoc": "80 USD",
++ "flags": [ "IRREPLACEABLE_CONSUMABLE" ],
++ "material": [ "plastic", "powder" ],
++ "symbol": "=",
++ "color": "pink",
++ "count": 40,
++ "stack_size": 40,
++ "ammo_type": "8x40mm",
++ "range": 42,
++ "damage": { "damage_type": "bullet", "amount": 45, "armor_penetration": 25 },
++ "dispersion": 75,
++ "recoil": 2200,
++ "effects": [ "NEVER_MISFIRES" ]
++ },
++ {
++ "id": "8mm_jhp",
++ "copy-from": "8mm_caseless",
++ "type": "AMMO",
++ "name": { "str": "8x40mm JHP" },
++ "description": "8x40mm caseless rounds, jacketed hollowpoint. Military grade ammunition for Rivtech firearms. Being caseless rounds, these cannot be disassembled or reloaded.",
++ "relative": { "damage": { "damage_type": "bullet", "amount": 11, "armor_penetration": -22 } }
++ },
++ {
+ "id": "8mm_jhp_reloaded",
+ "copy-from": "8mm_jhp",
+ "type": "AMMO",
+@@ -20,6 +51,19 @@
+ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+ },
+ {
++ "id": "8mm_hvp",
++ "copy-from": "8mm_caseless",
++ "type": "AMMO",
++ "name": { "str": "8x40mm HVP" },
++ "description": "8x40mm caseless rounds, saboted high-velocity penetrator type. Advanced military grade, armor-piercing ammunition that fires a single depleted uranium flechette. Being caseless rounds, these cannot be disassembled or reloaded.",
++ "price": "25 USD",
++ "price_postapoc": "500 USD",
++ "count": 20,
++ "//": "Balanced as AP, with 25% higher damage and 50% higher arpen",
++ "relative": { "damage": { "damage_type": "bullet", "amount": 4, "armor_penetration": 34 } },
++ "proportional": { "dispersion": 1.5, "recoil": 1.5 }
++ },
++ {
+ "id": "8mm_hvp_reloaded",
+ "copy-from": "8mm_hvp",
+ "type": "AMMO",
+@@ -30,6 +74,16 @@
+ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+ },
+ {
++ "id": "8mm_inc",
++ "copy-from": "8mm_caseless",
++ "type": "AMMO",
++ "name": { "str": "8x40mm tracer" },
++ "description": "8x40mm caseless rounds with tracers to help keep the weapon they are fired from on target at the risk of igniting flammable substances. Military grade ammunition for Rivtech firearms. Being caseless rounds, these cannot be disassembled or reloaded.",
++ "count": 20,
++ "proportional": { "dispersion": 0.8 },
++ "extend": { "effects": [ "INCENDIARY" ] }
++ },
++ {
+ "id": "8mm_inc_reloaded",
+ "copy-from": "8mm_inc",
+ "type": "AMMO",
+@@ -40,29 +94,6 @@
+ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+ },
+ {
+- "id": "8mm_caseless",
+- "type": "AMMO",
+- "name": { "str_sp": "8x40mm caseless" },
+- "//": "Cased ammo tends to be roughly $1/shot, more or less. Rivtech ammo, being New and Proprietary and Expensive, $2-2.50 or so.",
+- "description": "8x40mm caseless rounds. Proprietary ammunition for Rivtech firearms. Being caseless rounds, these cannot be disassembled or reloaded.",
+- "weight": "12 g",
+- "volume": "250 ml",
+- "price": "225 cent",
+- "price_postapoc": "80 USD",
+- "flags": [ "IRREPLACEABLE_CONSUMABLE" ],
+- "material": [ "plastic", "powder" ],
+- "symbol": "=",
+- "color": "pink",
+- "count": 40,
+- "stack_size": 40,
+- "ammo_type": "8x40mm",
+- "range": 42,
+- "damage": { "damage_type": "bullet", "amount": 45, "armor_penetration": 25 },
+- "dispersion": 75,
+- "recoil": 2200,
+- "effects": [ "NEVER_MISFIRES" ]
+- },
+- {
+ "id": "8mm_civilian",
+ "copy-from": "8mm_caseless",
+ "type": "AMMO",
+@@ -83,36 +114,5 @@
+ "dispersion": 1.2,
+ "recoil": 0.5
+ }
+- },
+- {
+- "id": "8mm_hvp",
+- "copy-from": "8mm_caseless",
+- "type": "AMMO",
+- "name": { "str": "8x40mm HVP" },
+- "description": "8x40mm caseless rounds, saboted high-velocity penetrator type. Advanced military grade, armor-piercing ammunition that fires a single depleted uranium flechette. Being caseless rounds, these cannot be disassembled or reloaded.",
+- "price": "25 USD",
+- "price_postapoc": "500 USD",
+- "count": 20,
+- "//": "Balanced as AP, with 25% higher damage and 50% higher arpen",
+- "relative": { "damage": { "damage_type": "bullet", "amount": 4, "armor_penetration": 34 } },
+- "proportional": { "dispersion": 1.5, "recoil": 1.5 }
+- },
+- {
+- "id": "8mm_inc",
+- "copy-from": "8mm_caseless",
+- "type": "AMMO",
+- "name": { "str": "8x40mm tracer" },
+- "description": "8x40mm caseless rounds with tracers to help keep the weapon they are fired from on target at the risk of igniting flammable substances. Military grade ammunition for Rivtech firearms. Being caseless rounds, these cannot be disassembled or reloaded.",
+- "count": 20,
+- "proportional": { "dispersion": 0.8 },
+- "extend": { "effects": [ "INCENDIARY" ] }
+- },
+- {
+- "id": "8mm_jhp",
+- "copy-from": "8mm_caseless",
+- "type": "AMMO",
+- "name": { "str": "8x40mm JHP" },
+- "description": "8x40mm caseless rounds, jacketed hollowpoint. Military grade ammunition for Rivtech firearms. Being caseless rounds, these cannot be disassembled or reloaded.",
+- "relative": { "damage": { "damage_type": "bullet", "amount": 11, "armor_penetration": -22 } }
+ }
+ ]
+
+--- a/data/json/items/ammo/shot.json
++++ b/data/json/items/ammo/shot.json
+@@ -1,5 +1,50 @@
+ [
+ {
++ "abstract": "shot_abstract",
++ "type": "AMMO",
++ "name": { "str": "00 shot" },
++ "description": "A shell filled with metal pellets. Extremely damaging, plus the spread makes it very accurate at short range. Favored by SWAT forces.",
++ "weight": "32 g",
++ "volume": "250 ml",
++ "price": "5 USD",
++ "price_postapoc": "8 USD",
++ "flags": [ "IRREPLACEABLE_CONSUMABLE" ],
++ "material": [ "plastic", "powder" ],
++ "symbol": "=",
++ "color": "red",
++ "dispersion": 10,
++ "count": 20,
++ "stack_size": 20,
++ "ammo_type": "shot",
++ "casing": "shot_hull",
++ "range": 12,
++ "damage": { "damage_type": "bullet", "amount": 80, "armor_multiplier": 2 },
++ "recoil": 2500,
++ "loudness": 160,
++ "effects": [ "COOKOFF", "SHOT" ]
++ },
++ {
++ "id": "shot_00",
++ "copy-from": "shot_abstract",
++ "type": "AMMO",
++ "name": { "str": "00 shot" },
++ "description": "A shell filled with metal pellets. Extremely damaging, plus the spread makes it very accurate at short range. Favored by SWAT forces."
++ },
++ {
++ "id": "shot_bird",
++ "copy-from": "shot_00",
++ "type": "AMMO",
++ "name": { "str": "birdshot" },
++ "description": "Weak shotgun ammunition. Designed for hunting birds and other small game, its applications in combat are very limited.",
++ "price": "1 USD",
++ "price_postapoc": "4 USD",
++ "range": 0,
++ "damage": { "damage_type": "bullet", "amount": 50, "armor_multiplier": 3 },
++ "loudness": 80,
++ "shape": [ "cone", { "half_angle": 15, "length": 8 } ],
++ "extend": { "effects": [ "NOGIB" ] }
++ },
++ {
+ "id": "reloaded_shot_bird",
+ "copy-from": "shot_bird",
+ "type": "AMMO",
+@@ -9,6 +54,21 @@
+ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+ },
+ {
++ "id": "shot_dragon",
++ "copy-from": "shot_00",
++ "type": "AMMO",
++ "name": { "str": "dragon's breath shell" },
++ "description": "A shotgun shell filled with magnesium pellets or shards, used mostly as a distress flare or pyrotechnics tool. When the round is fired, high temperature sparks and flames shoot out of the barrel, igniting everything in their path.",
++ "price": "10 USD",
++ "price_postapoc": "16 USD",
++ "flags": [ "IRREPLACEABLE_CONSUMABLE" ],
++ "damage": { "damage_type": "heat", "amount": 30 },
++ "proportional": { "recoil": 0.6, "loudness": 0.8, "dispersion": 1.2 },
++ "range": 0,
++ "shape": [ "cone", { "half_angle": 15, "length": 8 } ],
++ "extend": { "effects": [ "INCENDIARY", "STREAM", "NOGIB" ] }
++ },
++ {
+ "id": "reloaded_shot_dragon",
+ "copy-from": "shot_dragon",
+ "type": "AMMO",
+@@ -27,6 +87,19 @@
+ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+ },
+ {
++ "id": "shot_flechette",
++ "copy-from": "shot_00",
++ "type": "AMMO",
++ "name": { "str": "flechette shell" },
++ "description": "A shotgun shell filled with tiny steel darts. Extremely damaging, plus the spread makes it very accurate at short range. Slices through most forms of armor with ease.",
++ "price": "20 USD",
++ "price_postapoc": "8 USD",
++ "flags": [ "IRREPLACEABLE_CONSUMABLE" ],
++ "count": 10,
++ "//": "Balanced as standard AP.",
++ "relative": { "damage": { "damage_type": "bullet", "amount": -20, "armor_penetration": 30, "armor_multiplier": -1 } }
++ },
++ {
+ "id": "reloaded_shot_flechette",
+ "copy-from": "shot_flechette",
+ "type": "AMMO",
+@@ -36,6 +109,21 @@
+ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+ },
+ {
++ "id": "shot_slug",
++ "copy-from": "shot_abstract",
++ "type": "AMMO",
++ "name": { "str": "shotgun slug" },
++ "description": "A heavy metal slug used with shotguns to give them the range capabilities of a rifle. Extremely damaging but rather inaccurate.",
++ "price": "4 USD",
++ "price_postapoc": "4 USD",
++ "flags": [ "IRREPLACEABLE_CONSUMABLE" ],
++ "dispersion": 80,
++ "//": "Balanced as FMJ",
++ "relative": { "range": 12, "damage": { "damage_type": "bullet", "amount": -15, "armor_penetration": 18, "armor_multiplier": -0.5 } },
++ "proportional": { "recoil": 1.4 },
++ "delete": { "effects": [ "SHOT" ] }
++ },
++ {
+ "id": "reloaded_shot_slug",
+ "copy-from": "shot_slug",
+ "type": "AMMO",
+@@ -89,37 +177,6 @@
+ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+ },
+ {
+- "abstract": "shot_abstract",
+- "type": "AMMO",
+- "name": { "str": "00 shot" },
+- "description": "A shell filled with metal pellets. Extremely damaging, plus the spread makes it very accurate at short range. Favored by SWAT forces.",
+- "weight": "32 g",
+- "volume": "250 ml",
+- "price": "5 USD",
+- "price_postapoc": "8 USD",
+- "flags": [ "IRREPLACEABLE_CONSUMABLE" ],
+- "material": [ "plastic", "powder" ],
+- "symbol": "=",
+- "color": "red",
+- "dispersion": 10,
+- "count": 20,
+- "stack_size": 20,
+- "ammo_type": "shot",
+- "casing": "shot_hull",
+- "range": 20,
+- "damage": { "damage_type": "bullet", "amount": 80, "armor_multiplier": 2 },
+- "recoil": 2500,
+- "loudness": 160,
+- "effects": [ "COOKOFF", "SHOT" ]
+- },
+- {
+- "id": "shot_00",
+- "copy-from": "shot_abstract",
+- "type": "AMMO",
+- "name": { "str": "00 shot" },
+- "description": "A shell filled with metal pellets. Extremely damaging, plus the spread makes it very accurate at short range. Favored by SWAT forces."
+- },
+- {
+ "id": "shot_beanbag",
+ "copy-from": "shot_00",
+ "type": "AMMO",
+@@ -133,48 +191,6 @@
+ "extend": { "effects": [ "BEANBAG", "NOGIB" ] }
+ },
+ {
+- "id": "shot_bird",
+- "copy-from": "shot_00",
+- "type": "AMMO",
+- "name": { "str": "birdshot" },
+- "description": "Weak shotgun ammunition. Designed for hunting birds and other small game, its applications in combat are very limited.",
+- "price": "1 USD",
+- "price_postapoc": "4 USD",
+- "range": 0,
+- "damage": { "damage_type": "bullet", "amount": 50, "armor_multiplier": 3 },
+- "loudness": 80,
+- "shape": [ "cone", { "half_angle": 15, "length": 8 } ],
+- "extend": { "effects": [ "NOGIB" ] }
+- },
+- {
+- "id": "shot_dragon",
+- "copy-from": "shot_00",
+- "type": "AMMO",
+- "name": { "str": "dragon's breath shell" },
+- "description": "A shotgun shell filled with magnesium pellets or shards, used mostly as a distress flare or pyrotechnics tool. When the round is fired, high temperature sparks and flames shoot out of the barrel, igniting everything in their path.",
+- "price": "10 USD",
+- "price_postapoc": "16 USD",
+- "flags": [ "IRREPLACEABLE_CONSUMABLE" ],
+- "damage": { "damage_type": "heat", "amount": 30 },
+- "proportional": { "recoil": 0.6, "loudness": 0.8, "dispersion": 1.2 },
+- "range": 0,
+- "shape": [ "cone", { "half_angle": 15, "length": 8 } ],
+- "extend": { "effects": [ "INCENDIARY", "STREAM", "NOGIB" ] }
+- },
+- {
+- "id": "shot_flechette",
+- "copy-from": "shot_00",
+- "type": "AMMO",
+- "name": { "str": "flechette shell" },
+- "description": "A shotgun shell filled with tiny steel darts. Extremely damaging, plus the spread makes it very accurate at short range. Slices through most forms of armor with ease.",
+- "price": "20 USD",
+- "price_postapoc": "8 USD",
+- "flags": [ "IRREPLACEABLE_CONSUMABLE" ],
+- "count": 10,
+- "//": "Balanced as standard AP.",
+- "relative": { "damage": { "damage_type": "bullet", "amount": -20, "armor_penetration": 30, "armor_multiplier": -1 } }
+- },
+- {
+ "id": "shot_he",
+ "copy-from": "shot_slug",
+ "type": "AMMO",
+@@ -207,20 +222,5 @@
+ "proportional": { "price": 0.6, "damage": { "damage_type": "bullet", "amount": 0.8 } },
+ "extend": { "effects": [ "RECYCLED", "MUZZLE_SMOKE" ] },
+ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+- },
+- {
+- "id": "shot_slug",
+- "copy-from": "shot_abstract",
+- "type": "AMMO",
+- "name": { "str": "shotgun slug" },
+- "description": "A heavy metal slug used with shotguns to give them the range capabilities of a rifle. Extremely damaging but rather inaccurate.",
+- "price": "4 USD",
+- "price_postapoc": "4 USD",
+- "flags": [ "IRREPLACEABLE_CONSUMABLE" ],
+- "dispersion": 80,
+- "//": "Balanced as FMJ",
+- "relative": { "range": 12, "damage": { "damage_type": "bullet", "amount": -15, "armor_penetration": 18, "armor_multiplier": -0.5 } },
+- "proportional": { "recoil": 1.4 },
+- "delete": { "effects": [ "SHOT" ] }
+ }
+ ]
diff --git a/ammo-11_fix-volume-40mm.patch b/ammo-11_fix-volume-40mm.patch
new file mode 100644
index 0000000..54bd26a
--- /dev/null
+++ b/ammo-11_fix-volume-40mm.patch
@@ -0,0 +1,22 @@
+--- a/data/json/items/ammo/40x46mm.json
++++ b/data/json/items/ammo/40x46mm.json
+@@ -3,7 +3,7 @@
+ "abstract": "40x46mm_grenade",
+ "type": "AMMO",
+ "name": { "str": "40x46mm grenade" },
+- "volume": "250 ml",
++ "volume": "129 ml",
+ "price": "100 USD",
+ "price_postapoc": "60 USD",
+ "flags": [ "IRREPLACEABLE_CONSUMABLE" ],
+--- a/data/json/items/ammo/40x53mm.json
++++ b/data/json/items/ammo/40x53mm.json
+@@ -3,7 +3,7 @@
+ "name": { "str": "40x53mm grenade" },
+ "price": "100 USD",
+ "price_postapoc": "60 USD",
+- "volume": "260 ml",
++ "volume": "137 ml",
+ "flags": [ "IRREPLACEABLE_CONSUMABLE" ],
+ "material": [ "steel", "powder" ],
+ "symbol": "=",
diff --git a/0013-fix-20x66mm-loudness.patch b/ammo-12_fix-20x66mm-loudness.patch
index c9128cd..803f76d 100644
--- a/0013-fix-20x66mm-loudness.patch
+++ b/ammo-12_fix-20x66mm-loudness.patch
@@ -1,8 +1,8 @@
--- a/data/json/items/ammo/20x66mm.json
+++ b/data/json/items/ammo/20x66mm.json
@@ -124,6 +124,7 @@
- "range": 12,
- "damage": 60,
+ "range": 20,
+ "damage": { "damage_type": "bullet", "amount": 100 },
"recoil": 2500,
+ "loudness": 160,
"effects": [ "COOKOFF", "SHOT", "NEVER_MISFIRES" ]
diff --git a/ammo-13_fix-reloaded-50bmg.patch b/ammo-13_fix-reloaded-50bmg.patch
new file mode 100644
index 0000000..5a47596
--- /dev/null
+++ b/ammo-13_fix-reloaded-50bmg.patch
@@ -0,0 +1,11 @@
+--- a/data/json/items/ammo/50.json
++++ b/data/json/items/ammo/50.json
+@@ -78,7 +78,7 @@
+ },
+ {
+ "id": "reloaded_50bmg",
+- "copy-from": "50match",
++ "copy-from": "50bmg",
+ "type": "AMMO",
+ "name": { "str": ".50 BMG Match, reloaded" },
+ "description": ".50 BMG ammunition with lead-cored FMJ bullets. The .50 BMG is a very powerful rifle round designed for anti-aircraft use, later adapted to anti-vehicular and anti-personnel roles. Its stupendous energy and armor piercing capabilities make it one of the most deadly rounds available, offset only by its drastic recoil and noise.",
diff --git a/0002-ankle-ammo-pouch-is-not-a-backpack.patch b/armor-01_ankle-ammo-pouch-is-not-a-backpack.patch
index ca51551..6add0fb 100644
--- a/0002-ankle-ammo-pouch-is-not-a-backpack.patch
+++ b/armor-01_ankle-ammo-pouch-is-not-a-backpack.patch
@@ -1,11 +1,11 @@
--- a/data/json/items/armor/ammo_pouch.json
+++ b/data/json/items/armor/ammo_pouch.json
@@ -192,7 +192,7 @@
- "price_postapoc": 4500,
- "material": "cotton",
+ "price_postapoc": "750 cent",
+ "material": [ "cotton" ],
"symbol": "[",
- "looks_like": "ragpouch",
+ "looks_like": "bootstrap",
"color": "dark_gray",
- "covers": [ "FOOT_EITHER" ],
+ "covers": [ "foot_either" ],
"coverage": 5,
diff --git a/armor-02_fix-survivor-fingerless-gloves-warmth.patch b/armor-02_fix-survivor-fingerless-gloves-warmth.patch
new file mode 100644
index 0000000..1e79099
--- /dev/null
+++ b/armor-02_fix-survivor-fingerless-gloves-warmth.patch
@@ -0,0 +1,11 @@
+--- a/data/json/items/armor/gloves.json
++++ b/data/json/items/armor/gloves.json
+@@ -447,7 +447,7 @@
+ "covers": [ "hands" ],
+ "coverage": 85,
+ "encumbrance": 8,
+- "warmth": 12,
++ "warmth": 15,
+ "material_thickness": 3,
+ "environmental_protection": 3,
+ "flags": [ "VARSIZE", "WATERPROOF", "STURDY", "ALLOWS_NATURAL_ATTACKS" ]
diff --git a/0008-npc-can-use-more-bionics.patch b/bionics-01_npc-can-use-more-bionics.patch
index d140ab1..b32fe0c 100644
--- a/0008-npc-can-use-more-bionics.patch
+++ b/bionics-01_npc-can-use-more-bionics.patch
@@ -15,8 +15,9 @@
"occupied_bodyparts": [ [ "head", 1 ] ],
- "flags": [ "BIONIC_TOGGLED" ]
+ "flags": [ "BIONIC_TOGGLED", "BIONIC_NPC_USABLE" ]
- }
- ]
+ },
+ {
+ "id": "bn_bio_solar",
--- a/data/json/items/bionics.json
+++ b/data/json/items/bionics.json
@@ -268,7 +268,7 @@
diff --git a/custom.patch b/custom.patch
deleted file mode 100644
index d669295..0000000
--- a/custom.patch
+++ /dev/null
@@ -1,254 +0,0 @@
---- a/src/character.cpp
-+++ b/src/character.cpp
-@@ -288,9 +288,11 @@
- static const trait_id trait_THRESH_INSECT( "THRESH_INSECT" );
- static const trait_id trait_THRESH_PLANT( "THRESH_PLANT" );
- static const trait_id trait_THRESH_SPIDER( "THRESH_SPIDER" );
-+static const trait_id trait_THRESH_VAMP( "THRESH_VAMP" );
- static const trait_id trait_TOUGH_FEET( "TOUGH_FEET" );
- static const trait_id trait_TRANSPIRATION( "TRANSPIRATION" );
- static const trait_id trait_URSINE_EYE( "URSINE_EYE" );
-+static const trait_id trait_VAMP_HUNGER( "VAMP_HUNGER" );
- static const trait_id trait_VISCOUS( "VISCOUS" );
- static const trait_id trait_WATERSLEEP( "WATERSLEEP" );
- static const trait_id trait_WEBBED( "WEBBED" );
-@@ -4545,6 +4547,7 @@
- const bool npc_no_food = is_npc() && get_option<bool>( "NO_NPC_FOOD" );
- const bool foodless = debug_ls || npc_no_food;
- const bool mouse = has_trait( trait_NO_THIRST );
-+ const bool vamp = has_trait( trait_VAMP_HUNGER );
- const bool mycus = has_trait( trait_M_DEPENDENT );
- const float kcal_per_time = bmr() / ( 12.0f * 24.0f );
- const int five_mins = ticks_between( from, to, 5_minutes );
-@@ -4568,7 +4571,7 @@
- }
- // Mycus and Metabolic Rehydration makes thirst unnecessary
- // since water is not limited by intake but by absorption, we can just set thirst to zero
-- if( mycus || mouse ) {
-+ if( mycus || mouse || vamp ) {
- set_thirst( 0 );
- }
- }
-@@ -4985,7 +4988,7 @@
-
- void Character::update_bodytemp( const map &m, weather_manager &weather )
- {
-- if( has_trait( trait_DEBUG_NOTEMP ) ) {
-+ if( has_trait( trait_DEBUG_NOTEMP ) || has_trait( trait_THRESH_VAMP ) ) {
- temp_cur.fill( BODYTEMP_NORM );
- temp_conv.fill( BODYTEMP_NORM );
- return;
-
---- a/src/map_field.cpp
-+++ b/src/map_field.cpp
-@@ -88,6 +88,7 @@
- static const trait_id trait_M_SKIN3( "M_SKIN3" );
- static const trait_id trait_THRESH_MARLOSS( "THRESH_MARLOSS" );
- static const trait_id trait_THRESH_MYCUS( "THRESH_MYCUS" );
-+static const trait_id trait_THRESH_VAMP( "THRESH_VAMP" );
- static const trait_id trait_WEB_WALKER( "WEB_WALKER" );
-
- void map::create_burnproducts( const tripoint &p, const item &fuel, const units::mass &burned_mass )
-@@ -1395,7 +1396,8 @@
- if( ( cur.get_field_intensity() > 1 || !one_in( 3 ) ) && ( !inside || one_in( 3 ) ) ) {
- u.add_env_effect( effect_teargas, bp_mouth, 5, 20_seconds );
- }
-- if( cur.get_field_intensity() > 1 && ( !inside || one_in( 3 ) ) ) {
-+ if( !( u.has_trait( trait_THRESH_VAMP ) ) && cur.get_field_intensity() > 1 && ( !inside ||
-+ one_in( 3 ) ) ) {
- u.add_env_effect( effect_blind, bp_eyes, cur.get_field_intensity() * 2, 10_seconds );
- }
- }
-@@ -1526,8 +1528,9 @@
- // The gas won't harm you inside a vehicle.
- if( !inside ) {
- // Full body suits protect you from the effects of the gas.
-- if( !( u.worn_with_flag( flag_GAS_PROOF ) && u.get_env_resist( bodypart_id( "mouth" ) ) >= 15 &&
-- u.get_env_resist( bodypart_id( "eyes" ) ) >= 15 ) ) {
-+ if( !( u.has_trait( trait_THRESH_VAMP ) ) && !( u.worn_with_flag( flag_GAS_PROOF ) &&
-+ u.get_env_resist( bodypart_id( "mouth" ) ) >= 15 &&
-+ u.get_env_resist( bodypart_id( "eyes" ) ) >= 15 ) ) {
- const int intensity = cur.get_field_intensity();
- bool inhaled = u.add_env_effect( effect_poison, bp_mouth, 5, intensity * 1_minutes );
- if( u.has_trait( trait_THRESH_MYCUS ) || u.has_trait( trait_THRESH_MARLOSS ) ||
---- a/src/suffer.cpp
-+++ b/src/suffer.cpp
-@@ -143,10 +143,13 @@
- static const trait_id trait_SHOUT3( "SHOUT3" );
- static const trait_id trait_SORES( "SORES" );
- static const trait_id trait_SUNBURN( "SUNBURN" );
-+static const trait_id trait_THRESH_GYNOID( "THRESH_GYNOID" );
-+static const trait_id trait_THRESH_VAMP( "THRESH_VAMP" );
- static const trait_id trait_TROGLO( "TROGLO" );
- static const trait_id trait_TROGLO2( "TROGLO2" );
- static const trait_id trait_TROGLO3( "TROGLO3" );
- static const trait_id trait_UNSTABLE( "UNSTABLE" );
-+static const trait_id trait_VAMP_CURSE( "VAMP_CURSE" );
- static const trait_id trait_VOMITOUS( "VOMITOUS" );
- static const trait_id trait_WEB_SPINNER( "WEB_SPINNER" );
- static const trait_id trait_WEB_WEAVER( "WEB_WEAVER" );
-@@ -243,7 +246,8 @@
-
- void Character::suffer_while_underwater()
- {
-- if( !has_trait( trait_GILLS ) && !has_trait( trait_GILLS_CEPH ) ) {
-+ if( !has_trait( trait_GILLS ) && !has_trait( trait_GILLS_CEPH ) &&
-+ !has_trait( trait_THRESH_GYNOID ) && !has_trait( trait_THRESH_VAMP ) ) {
- oxygen--;
- }
- if( oxygen < 12 && worn_with_flag( "REBREATHER" ) ) {
-@@ -759,6 +763,17 @@
- }
- }
-
-+ if( has_trait( trait_VAMP_CURSE ) && one_in( 10 ) ) {
-+ if( !( weapon.has_flag( "RAIN_PROTECT" ) ) ) {
-+ add_msg_if_player( m_bad, _( "The sunlight sears your skin!" ) );
-+ if( has_effect( effect_sleep ) && !has_effect( effect_narcosis ) ) {
-+ wake_up();
-+ }
-+ mod_pain( 5 );
-+ hurtall( 5, nullptr );
-+ }
-+ }
-+
- if( ( has_trait( trait_TROGLO ) || has_trait( trait_TROGLO2 ) ) &&
- g->weather.weather == WEATHER_SUNNY ) {
- mod_str_bonus( -1 );
---- a/src/monattack.cpp
-+++ b/src/monattack.cpp
-@@ -143,6 +143,7 @@
- static const trait_id trait_TAIL_CATTLE( "TAIL_CATTLE" );
- static const trait_id trait_THRESH_MARLOSS( "THRESH_MARLOSS" );
- static const trait_id trait_THRESH_MYCUS( "THRESH_MYCUS" );
-+static const trait_id trait_THRESH_VAMP( "THRESH_VAMP" );
-
- static const mtype_id mon_ant_acid_larva( "mon_ant_acid_larva" );
- static const mtype_id mon_ant_acid_queen( "mon_ant_acid_queen" );
-@@ -2758,6 +2759,9 @@
- damage_instance dam = damage_instance();
- dam.add_damage( DT_STAB, 6, 10, 0.6, 1 );
- bool hit = sting_shoot( z, target, dam, range );
-+ if( target->has_trait( trait_THRESH_VAMP ) ) {
-+ return true;
-+ }
- if( hit ) {
- //Add checks if previous NPC/player conditions are removed
- dynamic_cast<player *>( target )->mutate();
---- a/src/player_hardcoded_effects.cpp
-+++ b/src/player_hardcoded_effects.cpp
-@@ -114,7 +114,9 @@
- static const trait_id trait_NOPAIN( "NOPAIN" );
- static const trait_id trait_SEESLEEP( "SEESLEEP" );
- static const trait_id trait_SCHIZOPHRENIC( "SCHIZOPHRENIC" );
-+static const trait_id trait_THRESH_GYNOID( "THRESH_GYNOID" );
- static const trait_id trait_THRESH_MYCUS( "THRESH_MYCUS" );
-+static const trait_id trait_THRESH_VAMP( "THRESH_VAMP" );
- static const trait_id trait_WATERSLEEP( "WATERSLEEP" );
-
- static void eff_fun_onfire( player &u, effect &it )
-@@ -1095,6 +1097,11 @@
- // Determine the strength of effects or dreams based upon category strength
- int strength = 0; // Category too weak for any effect or dream
- if( crossed_threshold() ) {
-+ if( has_trait( trait_THRESH_VAMP ) ) {
-+ highcat = "VAMP";
-+ } else if( has_trait( trait_THRESH_GYNOID ) ) {
-+ highcat = "GYNOID";
-+ }
- strength = 4; // Post-human.
- } else if( highest >= 20 && highest < 35 ) {
- strength = 1; // Low strength
---- a/data/json/field_type.json
-+++ b/data/json/field_type.json
-@@ -303,7 +303,7 @@
- "dirty_transparency_cache": true,
- "percent_spread": 10,
- "outdoor_age_speedup": "0 turns",
-- "immunity_data": { "body_part_env_resistance": [ [ "MOUTH", 7 ] ] },
-+ "immunity_data": { "body_part_env_resistance": [ [ "MOUTH", 7 ] ], "traits": [ "THRESH_VAMP" ] },
- "priority": 8,
- "half_life": "2 minutes",
- "phase": "gas",
-@@ -389,7 +389,7 @@
- "outdoor_age_speedup": "3 minutes",
- "dirty_transparency_cache": true,
- "has_fume": true,
-- "immunity_data": { "body_part_env_resistance": [ [ "MOUTH", 15 ] ] },
-+ "immunity_data": { "body_part_env_resistance": [ [ "MOUTH", 15 ] ], "traits": [ "THRESH_VAMP" ] },
- "priority": 8,
- "half_life": "10 minutes",
- "phase": "gas",
-@@ -418,7 +418,7 @@
- "outdoor_age_speedup": "0 turns",
- "dirty_transparency_cache": true,
- "has_fume": true,
-- "immunity_data": { "body_part_env_resistance": [ [ "MOUTH", 15 ] ] },
-+ "immunity_data": { "body_part_env_resistance": [ [ "MOUTH", 15 ], [ "EYES", 15 ] ], "traits": [ "THRESH_VAMP" ] },
- "priority": 8,
- "half_life": "5 minutes",
- "phase": "gas",
-@@ -464,7 +464,7 @@
- "wandering_field": "fd_toxic_gas",
- "gas_absorption_factor": 15,
- "dirty_transparency_cache": true,
-- "immunity_data": { "body_part_env_resistance": [ [ "MOUTH", 15 ] ] },
-+ "immunity_data": { "body_part_env_resistance": [ [ "MOUTH", 15 ] ], "traits": [ "THRESH_VAMP" ] },
- "phase": "gas",
- "display_items": false,
- "display_field": true,
-@@ -956,7 +956,7 @@
- "outdoor_age_speedup": "5 minutes",
- "dirty_transparency_cache": true,
- "has_fume": true,
-- "immunity_data": { "body_part_env_resistance": [ [ "MOUTH", 15 ] ] },
-+ "immunity_data": { "body_part_env_resistance": [ [ "MOUTH", 15 ] ], "traits": [ "THRESH_VAMP" ] },
- "priority": 8,
- "half_life": "50 minutes",
- "phase": "gas",
-@@ -978,7 +978,7 @@
- "outdoor_age_speedup": "1 minutes",
- "dirty_transparency_cache": true,
- "has_fume": true,
-- "immunity_data": { "body_part_env_resistance": [ [ "MOUTH", 15 ] ] },
-+ "immunity_data": { "body_part_env_resistance": [ [ "MOUTH", 15 ] ], "traits": [ "THRESH_VAMP" ] },
- "priority": 8,
- "half_life": "15 minutes",
- "phase": "gas",
-@@ -1233,7 +1233,7 @@
- "outdoor_age_speedup": "3 minutes",
- "dirty_transparency_cache": true,
- "has_fume": true,
-- "immunity_data": { "body_part_env_resistance": [ [ "MOUTH", 15 ] ] },
-+ "immunity_data": { "body_part_env_resistance": [ [ "MOUTH", 15 ] ], "traits": [ "THRESH_VAMP" ] },
- "priority": 8,
- "half_life": "10 minutes",
- "phase": "gas"
-@@ -1253,7 +1253,7 @@
- "outdoor_age_speedup": "1 minutes",
- "dirty_transparency_cache": true,
- "has_fume": true,
-- "immunity_data": { "body_part_env_resistance": [ [ "MOUTH", 15 ] ] },
-+ "immunity_data": { "body_part_env_resistance": [ [ "MOUTH", 15 ] ], "traits": [ "THRESH_VAMP" ] },
- "priority": 8,
- "half_life": "30 minutes",
- "phase": "gas",
-@@ -1275,7 +1275,7 @@
- "outdoor_age_speedup": "1 minutes",
- "dirty_transparency_cache": true,
- "has_fume": true,
-- "immunity_data": { "body_part_env_resistance": [ [ "MOUTH", 15 ] ] },
-+ "immunity_data": { "body_part_env_resistance": [ [ "MOUTH", 15 ] ], "traits": [ "THRESH_VAMP" ] },
- "priority": 8,
- "half_life": "30 minutes",
- "phase": "gas",
---- a/data/json/mutations/mutation_ordering.json
-+++ b/data/json/mutations/mutation_ordering.json
-@@ -73,6 +73,7 @@
- "TROGLO2",
- "TROGLO3",
- "URSINE_FUR",
-+ "VAMP_SKIN",
- "VISCOUS"
- ],
- "order": 1500
diff --git a/etc-02_add-missing-price-postapoc.patch b/etc-02_add-missing-price-postapoc.patch
new file mode 100644
index 0000000..bad63af
--- /dev/null
+++ b/etc-02_add-missing-price-postapoc.patch
@@ -0,0 +1,31 @@
+--- a/data/json/items/gun/223.json
++++ b/data/json/items/gun/223.json
+@@ -118,6 +118,7 @@
+ "volume": "4162 ml",
+ "barrel_length": "250 ml",
+ "price": "28 kUSD",
++ "price_postapoc": "50 USD",
+ "material": [ "steel", "plastic" ],
+ "color": "dark_gray",
+ "ammo": "223",
+@@ -302,7 +303,8 @@
+ ]
+ ]
+ ],
+- "relative": { "ranged_damage": { "damage_type": "bullet", "amount": 1 }, "durability": 1 }
++ "relative": { "ranged_damage": { "damage_type": "bullet", "amount": 1 }, "durability": 1 },
++ "proportional": { "price": 1.1 }
+ },
+ {
+ "id": "m4a1",
+
+--- a/data/json/items/magazine/223.json
++++ b/data/json/items/magazine/223.json
+@@ -366,6 +375,7 @@
+ "weight": "190 g",
+ "volume": "620 ml",
+ "price": "86 USD",
++ "price_postapoc": "275 cent",
+ "material": [ "steel", "plastic" ],
+ "symbol": "#",
+ "color": "light_gray",
diff --git a/etc-03_fix-abstracts.patch b/etc-03_fix-abstracts.patch
new file mode 100644
index 0000000..4bf8f72
--- /dev/null
+++ b/etc-03_fix-abstracts.patch
@@ -0,0 +1,73 @@
+--- a/data/json/items/generic/dining_kitchen.json
++++ b/data/json/items/generic/dining_kitchen.json
+@@ -1,6 +1,6 @@
+ [
+ {
+- "id": "base_silverware",
++ "abstract": "base_silverware",
+ "name": { "str": "generic silverware" },
+ "type": "GENERIC",
+ "description": "generic item template",
+@@ -16,7 +16,7 @@
+ "to_hit": -1
+ },
+ {
+- "id": "base_utensil",
++ "abstract": "base_utensil",
+ "name": { "str": "generic utensil" },
+ "type": "GENERIC",
+ "description": "generic item template",
+@@ -32,7 +32,7 @@
+ "to_hit": -1
+ },
+ {
+- "id": "base_plastic_silverware",
++ "abstract": "base_plastic_silverware",
+ "name": { "str": "generic silverware" },
+ "type": "GENERIC",
+ "description": "generic item template",
+@@ -48,7 +48,7 @@
+ "to_hit": -2
+ },
+ {
+- "id": "base_ceramic_dish",
++ "abstract": "base_ceramic_dish",
+ "name": { "str": "generic dish", "str_pl": "generic dishes" },
+ "description": "generic item template",
+ "type": "GENERIC",
+@@ -63,7 +63,7 @@
+ "to_hit": -1
+ },
+ {
+- "id": "base_glass_dish",
++ "abstract": "base_glass_dish",
+ "name": { "str": "generic dish", "str_pl": "generic dishes" },
+ "description": "generic item template",
+ "type": "GENERIC",
+@@ -78,7 +78,7 @@
+ "to_hit": -1
+ },
+ {
+- "id": "base_tin_dish",
++ "abstract": "base_tin_dish",
+ "name": { "str": "generic dish", "str_pl": "generic dishes" },
+ "description": "generic item template",
+ "type": "GENERIC",
+@@ -93,7 +93,7 @@
+ "to_hit": -1
+ },
+ {
+- "id": "base_plastic_dish",
++ "abstract": "base_plastic_dish",
+ "name": { "str": "generic dish", "str_pl": "generic dishes" },
+ "description": "generic item template",
+ "type": "GENERIC",
+@@ -108,7 +108,7 @@
+ "to_hit": -1
+ },
+ {
+- "id": "base_cookpot",
++ "abstract": "base_cookpot",
+ "name": { "str": "generic cook pot" },
+ "description": "generic item template",
+ "type": "GENERIC",
diff --git a/faction-01_more-factions.patch b/faction-01_more-factions.patch
new file mode 100644
index 0000000..07c2f23
--- /dev/null
+++ b/faction-01_more-factions.patch
@@ -0,0 +1,62 @@
+--- a/data/json/npcs/factions.json
++++ b/data/json/npcs/factions.json
+@@ -54,6 +54,7 @@
+ "type": "faction",
+ "id": "robofac",
+ "name": "Hub 01",
++ "mon_faction": "robofac",
+ "likes_u": -200,
+ "respects_u": 0,
+ "known_by_u": false,
+@@ -578,5 +579,51 @@
+ "marloss": { "kill on sight": true }
+ },
+ "description": "A small group of churchgoers that formed a community in the woods. They welcome anyone in their faction, but hate the unnatural."
++ },
++ {
++ "type": "faction",
++ "id": "fisherman_family",
++ "name": "Fisherman Family",
++ "likes_u": 0,
++ "respects_u": 0,
++ "known_by_u": false,
++ "size": 3,
++ "power": 3,
++ "food_supply": 100,
++ "wealth": 20000,
++ "relations": {
++ "free_merchants": { "knows your voice": true },
++ "old_guard": { "knows your voice": true },
++ "your_followers": { "knows your voice": true },
++ "no_faction": { "knows your voice": true }
++ },
++ "description": "A small family trying to survive in this new world."
++ },
++ {
++ "type": "faction",
++ "id": "prisoners",
++ "name": "Prisoners",
++ "likes_u": 0,
++ "respects_u": 0,
++ "known_by_u": true,
++ "size": 100,
++ "power": 100,
++ "food_supply": 230400,
++ "wealth": 45000000,
++ "relations": {
++ "hells_raiders": {
++ "kill on sight": false,
++ "watch your back": true,
++ "share my stuff": true,
++ "guard your stuff": true,
++ "lets you in": true,
++ "defends your space": true,
++ "knows your voice": true
++ },
++ "free_merchants": { "kill on sight": true },
++ "old_guard": { "kill on sight": true },
++ "your_followers": { "kill on sight": false }
++ },
++ "description": "Former prisoners who got their freedom during the apocalypse."
+ }
+ ]
diff --git a/faction-03_fix-food-supply-calculations.patch b/faction-03_fix-food-supply-calculations.patch
new file mode 100644
index 0000000..54e62ae
--- /dev/null
+++ b/faction-03_fix-food-supply-calculations.patch
@@ -0,0 +1,20 @@
+--- a/src/faction.cpp
++++ b/src/faction.cpp
+@@ -292,7 +292,7 @@
+ std::string faction::food_supply_text()
+ {
+ //Convert to how many days you can support the population
+- int val = food_supply / ( size * 288 );
++ int val = food_supply / ( size * 2500 );
+ if( val >= 30 ) {
+ return pgettext( "Faction food", "Overflowing" );
+ }
+@@ -310,7 +310,7 @@
+
+ nc_color faction::food_supply_color()
+ {
+- int val = food_supply / ( size * 288 );
++ int val = food_supply / ( size * 2500 );
+ if( val >= 30 ) {
+ return c_green;
+ } else if( val >= 14 ) {
diff --git a/factioncamp-01_remove-legacy-recruiting-penalty.patch b/factioncamp-01_remove-legacy-recruiting-penalty.patch
new file mode 100644
index 0000000..d389f12
--- /dev/null
+++ b/factioncamp-01_remove-legacy-recruiting-penalty.patch
@@ -0,0 +1,12 @@
+--- a/src/faction_camp.cpp
++++ b/src/faction_camp.cpp
+@@ -3699,7 +3699,8 @@
+ sbonus = 0;
+ return 0;
+ }
+- sbase = e->second.cur_level * 5;
++ //sbase = e->second.cur_level * 5;
++ sbase = 0;
+ sexpansions = expansions.size() * 2;
+
+ //How could we ever starve?
diff --git a/foods-01_fix-food-materials.patch b/foods-01_fix-food-materials.patch
new file mode 100644
index 0000000..aefbd0f
--- /dev/null
+++ b/foods-01_fix-food-materials.patch
@@ -0,0 +1,45 @@
+--- a/data/json/items/comestibles/bread.json
++++ b/data/json/items/comestibles/bread.json
+@@ -183,7 +183,7 @@
+ "description": "A dense and tasty fried bread treat.",
+ "price": "275 cent",
+ "price_postapoc": "3 USD",
+- "material": [ "wheat", "junk" ],
++ "material": [ "veggy", "junk" ],
+ "primary_material": "wheat",
+ "volume": "250 ml",
+ "charges": 6,
+
+--- a/data/json/items/comestibles/drink_other.json
++++ a/data/json/items/comestibles/drink_other.json
+@@ -146,6 +146,7 @@
+ "volume": "250 ml",
+ "comestible_type": "DRINK",
+ "container": "jar_glass_sealed",
++ "material": [ "nut", "junk" ],
+ "primary_material": "junk",
+ "quench": -2,
+ "calories": 190,
+
+--- a/data/json/items/comestibles/other.json
++++ b/data/json/items/comestibles/other.json
+@@ -80,6 +80,7 @@
+ "description": "A translucent hexagonal chunk of wax, filled with dense, milky jelly. Though some hold it as a panacea, it doesn't have any medical benefit. Still, it is delicious, and rich with the most beneficial substances the hive can produce.",
+ "price": "200 USD",
+ "price_postapoc": "40 USD",
++ "material": "honey",
+ "volume": "250 ml",
+ "flags": [ "EDIBLE_FROZEN", "NUTRIENT_OVERRIDE" ],
+ "fun": 7
+
+--- a/data/json/items/comestibles/junkfood.json
++++ b/data/json/items/comestibles/junkfood.json
+@@ -663,7 +663,7 @@
+ "description": "Plain cornflake cereal. They're not that good, but it beats nothing.",
+ "price": "3 USD",
+ "price_postapoc": "75 cent",
+- "material": "junk",
++ "material": "veggy",
+ "volume": "250 ml",
+ "vitamins": [ [ "iron", 42 ] ],
+ "fun": 6
diff --git a/foods-02_fix-food-naming.patch b/foods-02_fix-food-naming.patch
new file mode 100644
index 0000000..b96e49c
--- /dev/null
+++ b/foods-02_fix-food-naming.patch
@@ -0,0 +1,22 @@
+--- a/data/json/items/comestibles/veggy_dishes.json
++++ b/data/json/items/comestibles/veggy_dishes.json
+@@ -162,7 +162,7 @@
+ {
+ "type": "COMESTIBLE",
+ "id": "can_corn",
+- "name": { "str_sp": "corn" },
++ "name": { "str_sp": "canned corn" },
+ "comestible_type": "FOOD",
+ "weight": "178 g",
+ "color": "yellow",
+--- a/data/json/items/comestibles/other.json
++++ b/data/json/items/comestibles/other.json
+@@ -265,7 +265,7 @@
+ {
+ "type": "COMESTIBLE",
+ "id": "can_beans",
+- "name": { "str": "canned beans", "str_pl": "beans" },
++ "name": { "str": "canned beans", "str_pl": "canned beans" },
+ "weight": "256 g",
+ "color": "brown",
+ "spoils_in": "2 days",
diff --git a/foods-03_fix-mutant-bad-taste.patch b/foods-03_fix-mutant-bad-taste.patch
new file mode 100644
index 0000000..5903b88
--- /dev/null
+++ b/foods-03_fix-mutant-bad-taste.patch
@@ -0,0 +1,32 @@
+--- a/data/json/items/comestibles/carnivore.json
++++ b/data/json/items/comestibles/carnivore.json
+@@ -154,7 +154,8 @@
+ "cooks_like": "mutant_meat_scrap_cooked",
+ "proportional": { "price": 0.2, "calories": 0.5 },
+ "vitamins": [ [ "mutant_toxin", 2 ] ],
+- "delete": { "flags": [ "SMOKABLE" ] }
++ "delete": { "flags": [ "SMOKABLE" ] },
++ "extend": { "flags": [ "BAD_TASTE" ] }
+ },
+ {
+ "id": "mutant_human_flesh",
+@@ -621,7 +622,8 @@
+ "description": "Freshly butchered fat from a heavily mutated animal. You could eat it raw, but it is better used as an ingredient in other foods or projects.",
+ "looks_like": "fat",
+ "proportional": { "price": 0.2 },
+- "vitamins": [ [ "mutant_toxin", 360 ] ]
++ "vitamins": [ [ "mutant_toxin", 360 ] ],
++ "extend": { "flags": [ "BAD_TASTE" ] }
+ },
+ {
+ "id": "mutant_tallow",
+@@ -631,7 +633,8 @@
+ "description": "A smooth white block of cleaned and rendered fat sourced from a mutant animal. It will remain edible for a very long time, and can be used as an ingredient in many foods and projects.",
+ "looks_like": "tallow",
+ "proportional": { "price": 0.2 },
+- "vitamins": [ [ "mutant_toxin", 180 ] ]
++ "vitamins": [ [ "mutant_toxin", 180 ] ],
++ "extend": { "flags": [ "BAD_TASTE" ] }
+ },
+ {
+ "id": "mutant_lard",
diff --git a/foods-04_allow-canned-corn-as-veggy.patch b/foods-04_allow-canned-corn-as-veggy.patch
new file mode 100644
index 0000000..727f96a
--- /dev/null
+++ b/foods-04_allow-canned-corn-as-veggy.patch
@@ -0,0 +1,10 @@
+--- a/data/json/requirements/cooking_components.json
++++ b/data/json/requirements/cooking_components.json
+@@ -650,6 +650,7 @@
+ [ "veggy_any_uncooked", 1, "LIST" ],
+ [ "veggy_canned", 1 ],
+ [ "veggy_salted", 1 ],
++ [ "can_corn", 1 ],
+ [ "chili_pepper_roasted", 1 ]
+ ]
+ ]
diff --git a/foods-05_fix-missing-price-postapoc.patch b/foods-05_fix-missing-price-postapoc.patch
new file mode 100644
index 0000000..ec1e555
--- /dev/null
+++ b/foods-05_fix-missing-price-postapoc.patch
@@ -0,0 +1,10 @@
+--- a/data/json/items/comestibles/fruit_dishes.json
++++ b/data/json/items/comestibles/fruit_dishes.json
+@@ -221,6 +221,7 @@
+ "calories": 82,
+ "description": "Fruit slices soaked in a sugar syrup, to preserve freshness and appearance.",
+ "price": "450 cent",
++ "price_postapoc": "50 cent",
+ "material": "fruit",
+ "volume": "250 ml",
+ "charges": 4,
diff --git a/foods-06_sealed-foods-not-full.patch b/foods-06_sealed-foods-not-full.patch
new file mode 100644
index 0000000..b186449
--- /dev/null
+++ b/foods-06_sealed-foods-not-full.patch
@@ -0,0 +1,31 @@
+--- a/data/json/itemgroups/SUS/domestic.json
++++ b/data/json/itemgroups/SUS/domestic.json
+@@ -148,7 +148,7 @@
+ {
+ "distribution": [
+ { "item": "coffee_raw", "prob": 50 },
+- { "item": "coffee_raw", "prob": 50, "charges": [ 1, 200 ], "container-item": "can_food_big" }
++ { "item": "coffee_raw", "prob": 50, "charges": 240, "container-item": "can_food_big" }
+ ],
+ "prob": 80
+ },
+
+--- a/data/json/itemgroups/collections_domestic.json
++++ b/data/json/itemgroups/collections_domestic.json
+@@ -552,13 +552,13 @@
+ { "item": "thermos", "prob": 15 },
+ { "item": "meat_canned", "prob": 4, "charges": 12, "container-item": "jar_3l_glass_sealed" },
+ { "item": "veggy_canned", "prob": 4, "charges": 12, "container-item": "jar_3l_glass_sealed" },
+- { "item": "apple_canned", "prob": 4, "charges": 12, "container-item": "jar_3l_glass_sealed" },
+- { "item": "can_tomato", "prob": 4, "charges": 12, "container-item": "jar_3l_glass_sealed" },
++ { "item": "apple_canned", "prob": 4, "charges": 24, "container-item": "jar_3l_glass_sealed" },
++ { "item": "can_tomato", "prob": 4, "charges": 24, "container-item": "jar_3l_glass_sealed" },
+ { "item": "fish_pickled", "prob": 4, "charges": 12, "container-item": "jar_3l_glass_sealed" },
+ { "item": "meat_pickled", "prob": 4, "charges": 12, "container-item": "jar_3l_glass_sealed" },
+ { "item": "veggy_pickled", "prob": 4, "charges": 12, "container-item": "jar_3l_glass_sealed" },
+ { "item": "fish_pickled", "prob": 4, "charges": 12, "container-item": "jar_3l_glass_sealed" },
+- { "item": "sauce_red", "prob": 4, "charges": 12, "container-item": "jar_3l_glass_sealed" },
++ { "item": "sauce_red", "prob": 4, "charges": 48, "container-item": "jar_3l_glass_sealed" },
+ { "item": "kompot", "prob": 4, "charges": 12, "container-item": "jar_3l_glass_sealed" },
+ { "group": "big_canned_food", "prob": 4 }
+ ]
diff --git a/foods-07_fix-meat-scrap-description.patch b/foods-07_fix-meat-scrap-description.patch
new file mode 100644
index 0000000..668a3a9
--- /dev/null
+++ b/foods-07_fix-meat-scrap-description.patch
@@ -0,0 +1,19 @@
+--- a/data/json/items/comestibles/carnivore.json
++++ b/data/json/items/comestibles/carnivore.json
+@@ -311,7 +311,7 @@
+ "copy-from": "meat_scrap",
+ "type": "COMESTIBLE",
+ "name": { "str": "cooked scrap of meat", "str_pl": "cooked scraps of meat" },
+- "description": "This is a tiny scrap of cooked mutant meat. It is small enough that it's hard to tell how disgusting it is.",
++ "description": "This is a tiny scrap of cooked meat. It's not much, but it'll do in a pinch.",
+ "spoils_in": "2 days",
+ "parasites": 0,
+ "fun": 0,
+@@ -338,6 +338,7 @@
+ "type": "COMESTIBLE",
+ "copy-from": "mutant_meat_scrap",
+ "name": { "str": "cooked scrap of mutant meat", "str_pl": "cooked scraps of mutant meat" },
++ "description": "This is a tiny scrap of cooked mutant meat. It is small enough that it's hard to tell how disgusting it is.",
+ "looks_like": "meat_scrap_cooked",
+ "spoils_in": "2 days",
+ "parasites": 0,
diff --git a/hotfix-01_fix-negative-calories-when-creating-dry-rice-4373.patch b/hotfix-01_fix-negative-calories-when-creating-dry-rice-4373.patch
new file mode 100644
index 0000000..8579837
--- /dev/null
+++ b/hotfix-01_fix-negative-calories-when-creating-dry-rice-4373.patch
@@ -0,0 +1,26 @@
+From 637b6c242d7bd261ab61a2eb273a6be552aab1a2 Mon Sep 17 00:00:00 2001
+From: Viss Valdyr <33199510+Lamandus@users.noreply.github.com>
+Date: Thu, 21 Mar 2024 01:25:59 +0100
+Subject: [PATCH] fix: negative calories when creating dry rice (#4373)
+
+---
+ data/json/items/comestibles/veggy_dishes.json | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/data/json/items/comestibles/veggy_dishes.json b/data/json/items/comestibles/veggy_dishes.json
+index 88f6e8d97f0..b60fad08e43 100644
+--- a/data/json/items/comestibles/veggy_dishes.json
++++ b/data/json/items/comestibles/veggy_dishes.json
+@@ -302,7 +302,8 @@
+ "milling": { "into": "flour", "conversion_rate": 3 },
+ "charges": 3,
+ "vitamins": [ [ "iron", 3 ] ],
+- "fun": -15
++ "fun": -15,
++ "flags": [ "NUTRIENT_OVERRIDE" ]
+ },
+ {
+ "type": "COMESTIBLE",
+--
+2.43.0
+
diff --git a/hotfix-02_perf-disable-vsync-by-default-4414.patch b/hotfix-02_perf-disable-vsync-by-default-4414.patch
new file mode 100644
index 0000000..4220a06
--- /dev/null
+++ b/hotfix-02_perf-disable-vsync-by-default-4414.patch
@@ -0,0 +1,53 @@
+From 404ca35f036358419353107cfbbfcf7c95f89ba8 Mon Sep 17 00:00:00 2001
+From: scarf <greenscarf005@gmail.com>
+Date: Mon, 1 Apr 2024 00:50:26 +0900
+Subject: [PATCH] perf: disable vsync by default (#4414)
+
+* perf: disable vsync by default
+
+* fix: warn vsync performance
+---
+ src/options.cpp | 7 +++++++
+ src/sdltiles.cpp | 8 ++++++--
+ 2 files changed, 13 insertions(+), 2 deletions(-)
+
+diff --git a/src/options.cpp b/src/options.cpp
+index 85832403dc0..684e8cbd48e 100644
+--- a/src/options.cpp
++++ b/src/options.cpp
+@@ -2090,6 +2090,13 @@ void options_manager::add_options_graphics()
+ false, COPT_CURSES_HIDE
+ );
+
++#if defined(SDL_HINT_RENDER_VSYNC)
++ add( "VSYNC", graphics, translate_marker( "Use VSync" ),
++ translate_marker( "Enable vertical synchronization to prevent screen tearing. VSync can slow the game down a lot. Requires restart." ),
++ false, COPT_CURSES_HIDE
++ );
++#endif
++
+ #if defined(__ANDROID__)
+ get_option( "FRAMEBUFFER_ACCEL" ).setPrerequisite( "SOFTWARE_RENDERING" );
+ #else
+diff --git a/src/sdltiles.cpp b/src/sdltiles.cpp
+index 226513ad2ff..561d2e767da 100644
+--- a/src/sdltiles.cpp
++++ b/src/sdltiles.cpp
+@@ -350,8 +350,12 @@ static void WinCreate()
+ if( !software_renderer ) {
+ dbg( DL::Info ) << "Attempting to initialize accelerated SDL renderer.";
+
+- renderer.reset( SDL_CreateRenderer( ::window.get(), renderer_id, SDL_RENDERER_ACCELERATED |
+- SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE ) );
++ int init_flags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE;
++ if( get_option<bool>( "VSYNC" ) ) {
++ init_flags |= SDL_RENDERER_PRESENTVSYNC;
++ }
++
++ renderer.reset( SDL_CreateRenderer( ::window.get(), renderer_id, init_flags ) );
+ if( printErrorIf( !renderer,
+ "Failed to initialize accelerated renderer, falling back to software rendering" ) ) {
+ software_renderer = true;
+--
+2.43.0
+
diff --git a/hotfix-03_fix-enable-vsync-by-default-4433.patch b/hotfix-03_fix-enable-vsync-by-default-4433.patch
new file mode 100644
index 0000000..1122713
--- /dev/null
+++ b/hotfix-03_fix-enable-vsync-by-default-4433.patch
@@ -0,0 +1,26 @@
+From 4cc938973fab92800916dc99da5542bbcee14fa7 Mon Sep 17 00:00:00 2001
+From: scarf <greenscarf005@gmail.com>
+Date: Thu, 4 Apr 2024 18:14:18 +0900
+Subject: [PATCH] fix: enable vsync by default (#4433)
+
+was causing issues on windows
+---
+ src/options.cpp | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/options.cpp b/src/options.cpp
+index 684e8cbd48e..6bd5219ee22 100644
+--- a/src/options.cpp
++++ b/src/options.cpp
+@@ -2093,7 +2093,7 @@ void options_manager::add_options_graphics()
+ #if defined(SDL_HINT_RENDER_VSYNC)
+ add( "VSYNC", graphics, translate_marker( "Use VSync" ),
+ translate_marker( "Enable vertical synchronization to prevent screen tearing. VSync can slow the game down a lot. Requires restart." ),
+- false, COPT_CURSES_HIDE
++ true, COPT_CURSES_HIDE
+ );
+ #endif
+
+--
+2.43.0
+
diff --git a/hotfix-04_fix-mapgen-fix-for-level-0-of-the-Necropolis-4380.patch b/hotfix-04_fix-mapgen-fix-for-level-0-of-the-Necropolis-4380.patch
new file mode 100644
index 0000000..081464a
--- /dev/null
+++ b/hotfix-04_fix-mapgen-fix-for-level-0-of-the-Necropolis-4380.patch
@@ -0,0 +1,100 @@
+From 0992ddd7cea7c1f16101951367fa8a222d67f8b0 Mon Sep 17 00:00:00 2001
+From: 0Monet <146018959+0Monet@users.noreply.github.com>
+Date: Fri, 22 Mar 2024 22:58:30 +0100
+Subject: [PATCH] fix: mapgen fix for level 0 of the Necropolis (#4380)
+
+* Add symbols to the palette
+
+* Change symbols
+---
+ data/json/mapgen/necropolis/necropolis.json | 17 +++++++++--------
+ .../necropolis/necropolis_a.json | 10 ++++++++--
+ 2 files changed, 17 insertions(+), 10 deletions(-)
+
+diff --git a/data/json/mapgen/necropolis/necropolis.json b/data/json/mapgen/necropolis/necropolis.json
+index 32b64ed0835..111d183670e 100644
+--- a/data/json/mapgen/necropolis/necropolis.json
++++ b/data/json/mapgen/necropolis/necropolis.json
+@@ -98,6 +98,7 @@
+ "..........................ss_______,,_______ss..|-www-[[-www-|777777778."
+ ],
+ "palettes": [ "necropolis_a" ],
++ "terrain": { "1": "t_floor", "2": "t_floor", "3": "t_floor" },
+ "furniture": { "1": "f_rack", "2": "f_rack", "3": "f_counter" },
+ "items": {
+ "1": { "item": "farming_tools", "chance": 30 },
+@@ -649,18 +650,18 @@
+ "...........sssssss{{{s8ssssMMMMsMsMMMMMmmmmmmmmmMMMMMssssMssMssMssssssss",
+ "...........sss{{{sssssMsMMsMssMssMMMMMmm]]]]]]]mmMMMMMsMsMssssssssssssMs",
+ "......|--------{{{--sssssssssMM_MMMMMmm]]]]]]]]]mmMMMMM__MMMM_M___M_____",
+- "......| 33 222{{{{{sssssMsMM___MMMMMmm]]]]]]]]]]]mmMMMMM________M___M___",
+- "......| 11 2 {{{{ssssssMss_MMMMMMmm]]]]]]]]]]]]]mmMMMMM_M_M__M________",
+- "......| 11 { {{{){sMssMssss_MMMMMmm]]]]]]]]]]]]]]]mmMMMMM_____M________",
++ "......| èè ééé{{{{{sssssMsMM___MMMMMmm]]]]]]]]]]]mmMMMMM________M___M___",
++ "......| àà é {{{{ssssssMss_MMMMMMmm]]]]]]]]]]]]]mmMMMMM_M_M__M________",
++ "......| àà { {{{){sMssMssss_MMMMMmm]]]]]]]]]]]]]]]mmMMMMM_____M________",
+ ".#....| {{ {{{{{ssssMsMsMMMMMmm]]]]]]]]]]]]]]]]]mmMMMMM_MMMMM_MM_M_M",
+ "......|c {{{{){sssssMsMMMMMMmm]]]]]]]]]]]]]]]]]]]mmMMMMM_M______M___",
+- "......|c 11{){{{ssssss.ssMMMMMmm]]]]]]]]]]]]]]]]]]]mmMMMMM_M_MM_______",
++ "......|c àà{){{{ssssss.ssMMMMMmm]]]]]]]]]]]]]]]]]]]mmMMMMM_M_MM_______",
+ "......|c {{{{{{sssssMsMsMMMMMMmm]]]]]]]]]]]]]]]]]]]mmMMMMM,M_,,,M,,,_,",
+ "......|J J{){{){{ssssM.sMMMMMMmm]]]]]]]]]]]]]]]]]]]mmMMMMMMM_MM,_MM,_,",
+ "......| {{ {)ssssssMssMMMMMmm]]]]]]]]]]]]]]]]]]]mmMMMMM_MM______M__",
+- "......|c11 {{{{{{{sMsssssMMMMMMmm]]]]]]]]]]]]]]]]]]]mmMMMMM_____MM_____",
+- "......|c11 1{{{{{ssssssMMMMMMMmm]]]]]]]]]]]]]]]]]]]mmMMMMM_MM__M_M_M__",
+- "......| KK1 {{{{{MssMwsssMMMMMmm]]]]]]]]]]]]]]]]]mmMMMMM_M__M________",
++ "......|càà {{{{{{{sMsssssMMMMMMmm]]]]]]]]]]]]]]]]]]]mmMMMMM_____MM_____",
++ "......|càà à{{{{{ssssssMMMMMMMmm]]]]]]]]]]]]]]]]]]]mmMMMMM_MM__M_M_M__",
++ "......| KKà {{{{{MssMwsssMMMMMmm]]]]]]]]]]]]]]]]]mmMMMMM_M__M________",
+ "..x...|-|----{{{)--ssssMMMss_MMMMMmm]]]]]]]]]]]]]]]mmMMMMM____M__MMM__M_",
+ "........|RRRRR{{{{sssssssssMM_MMMMMmm]]]]]]]]]]]]]mmMMMMM_MMM_M__M______",
+ "........|R {{{{{{sssssMsMM___MMMMMmm]]]]]]]]]]]mmMMMMM__MM__M____M____",
+@@ -695,7 +696,7 @@
+ ],
+ "palettes": [ "necropolis_a" ],
+ "terrain": { "D": "t_floor", "R": "t_floor", "l": "t_floor", "u": "t_floor", "z": "t_floor" },
+- "furniture": { "1": "f_bed", "2": "f_desk", "3": "f_dresser", "R": "f_rack" },
++ "furniture": { "R": "f_rack" },
+ "set": [
+ { "square": "radiation", "amount": [ 0, 1 ], "x": 0, "x2": 23, "y": 0, "y2": 23 },
+ { "square": "radiation", "amount": [ 0, 1 ], "x": 24, "x2": 47, "y": 0, "y2": 23 },
+diff --git a/data/json/mapgen_palettes/necropolis/necropolis_a.json b/data/json/mapgen_palettes/necropolis/necropolis_a.json
+index 657f5399bac..da883f01f07 100644
+--- a/data/json/mapgen_palettes/necropolis/necropolis_a.json
++++ b/data/json/mapgen_palettes/necropolis/necropolis_a.json
+@@ -3,9 +3,12 @@
+ "type": "palette",
+ "id": "necropolis_a",
+ "furniture": {
++ "@": "f_bed",
++ "à": "f_bed",
++ "é": "f_desk",
++ "è": "f_dresser",
+ ")": "f_wreckage",
+ "?": "f_sofa",
+- "@": "f_bed",
+ "B": "f_bathtub",
+ "C": "f_region_weed",
+ "D": "f_trashcan",
+@@ -41,6 +44,10 @@
+ "u": "f_barricade_road"
+ },
+ "terrain": {
++ "@": "t_floor",
++ "à": "t_floor",
++ "é": "t_floor",
++ "è": "t_floor",
+ "!": "t_bars",
+ "#": "t_region_shrub",
+ "&": "t_sidewalk",
+@@ -65,7 +72,6 @@
+ "=": "t_door_metal_locked",
+ ">": "t_stairs_down",
+ "?": "t_floor",
+- "@": "t_floor",
+ "A": "t_railing_h",
+ "B": "t_floor",
+ "C": "t_region_groundcover_urban",
+--
+2.43.0
+
diff --git a/hotfix-05_fix-more-fix-for-level-0-of-the-Necropolis-4387.patch b/hotfix-05_fix-more-fix-for-level-0-of-the-Necropolis-4387.patch
new file mode 100644
index 0000000..6f478f3
--- /dev/null
+++ b/hotfix-05_fix-more-fix-for-level-0-of-the-Necropolis-4387.patch
@@ -0,0 +1,522 @@
+From 3fbd2bfd731810410770039835c9cfee9c89bfcd Mon Sep 17 00:00:00 2001
+From: 0Monet <146018959+0Monet@users.noreply.github.com>
+Date: Sun, 24 Mar 2024 23:42:32 +0100
+Subject: [PATCH] fix: more fix for level 0 of the Necropolis (#4387)
+
+* Update necropolis.json
+
+* Update necropolis_a.json
+
+* Update necropolis.json
+
+* style(autofix.ci): automated formatting
+
+---------
+
+Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
+---
+ data/json/mapgen/necropolis/necropolis.json | 265 +++++++++---------
+ .../necropolis/necropolis_a.json | 14 +
+ 2 files changed, 150 insertions(+), 129 deletions(-)
+
+diff --git a/data/json/mapgen/necropolis/necropolis.json b/data/json/mapgen/necropolis/necropolis.json
+index 111d183670e..f03d1340342 100644
+--- a/data/json/mapgen/necropolis/necropolis.json
++++ b/data/json/mapgen/necropolis/necropolis.json
+@@ -44,6 +44,12 @@
+ ]
+ },
+ {
++ "type": "mapgen",
++ "om_terrain": [
++ [ "necropolis_a_1", "necropolis_a_2", "necropolis_a_3" ],
++ [ "necropolis_a_10", "necropolis_a_11", "necropolis_a_12" ]
++ ],
++ "weight": 250,
+ "method": "json",
+ "object": {
+ "fill_ter": "t_floor",
+@@ -87,11 +93,11 @@
+ ".q....V ;sssssssssss_______,,_______ss...8srrrrrrrrrsssssZZssr8.",
+ ".q....| ooP|....s...qss_______,,_______ss..|------------|rssssssr8.",
+ ".q....|;|--+----|--|es...qss________________ss..|222222222222|rssssssr8.",
+- ".q..ssss|r =_______________,,_______ss..w3 2|rssZZssr8.",
+- ".q..shss|r =_______________,,_______ss..w3 11 11 2|rssZZssr8.",
+- ".q..snss|r =_______________,,_______ss..w3 11 11 2|rssssssr8.",
+- ".q..shss|r =________________________ss..|r [sssssssr8.",
+- ".q..ssss|r =_______________,,_______ss..w3 11 [sssssssr8.",
++ ".q..ssss|r̲~~~~~~~~~=_______________,,_______ss..w3 2|rssZZssr8.",
++ ".q..sЮss|r̲~~~~~~~~~=_______________,,_______ss..w3 11 11 2|rssZZssr8.",
++ ".q..sЯss|r̲~~~~~~~~~=_______________,,_______ss..w3 11 11 2|rssssssr8.",
++ ".q..sЮss|r̲~~~~~~~~~=________________________ss..|r [sssssssr8.",
++ ".q..ssss|r̲~~~~~~~~~=_______________,,_______ss..w3 11 [sssssssr8.",
+ ".q......|----------|.....qss_______,,_______ss..w3 11 cc 1|rssssssr8.",
+ ".q.......................qss_______,,_______ss..w3 6 1|rssZZssr8.",
+ ".qQQQQQQQQQQQQQQQQQQQQQQQqss________________ss..|r333r c 1|rssZZssr8.",
+@@ -110,9 +116,9 @@
+ { "group": "SUS_junk_drawer", "x": 42, "y": 8, "chance": 75 },
+ { "group": "SUS_junk_drawer", "x": 42, "y": 10, "chance": 75 },
+ { "item": "television", "x": 32, "y": [ 11, 12 ], "chance": 80 },
+- { "item": "television", "x": 10, "y": [ 32, 33 ], "chance": 80 },
+- { "group": "tools_general", "x": 9, "y": [ 40, 44 ], "chance": 50, "repeat": 2 },
+- { "group": "supplies_mechanics", "x": 9, "y": [ 40, 44 ], "chance": 50, "repeat": 2 },
++ { "item": "television", "x": 10, "y": 32, "chance": 80 },
++ { "group": "tools_general", "x": 9, "y": [ 39, 43 ], "chance": 50, "repeat": 2 },
++ { "group": "supplies_mechanics", "x": 9, "y": [ 39, 43 ], "chance": 50, "repeat": 2 },
+ { "group": "fertilizers", "x": 25, "y": [ 52, 61 ], "chance": 40, "repeat": 4 },
+ { "group": "farming_seeds", "x": [ 25, 47 ], "y": 69, "chance": 30, "repeat": 10 }
+ ],
+@@ -128,15 +134,15 @@
+ { "vehicle": "electric_car", "x": 15, "y": 41, "chance": 75, "rotation": 0 },
+ { "vehicle": "flatbed_truck", "x": 55, "y": 30, "chance": 50, "rotation": 180 }
+ ]
+- },
+- "om_terrain": [
+- [ "necropolis_a_1", "necropolis_a_2", "necropolis_a_3" ],
+- [ "necropolis_a_10", "necropolis_a_11", "necropolis_a_12" ]
+- ],
+- "type": "mapgen",
+- "weight": 250
++ }
+ },
+ {
++ "type": "mapgen",
++ "om_terrain": [
++ [ "necropolis_a_4", "necropolis_a_5", "necropolis_a_6" ],
++ [ "necropolis_a_13", "necropolis_a_14", "necropolis_a_15" ]
++ ],
++ "weight": 250,
+ "method": "json",
+ "object": {
+ "fill_ter": "t_floor",
+@@ -222,15 +228,15 @@
+ { "vehicle": "policecar", "x": 60, "y": 16, "chance": 25, "rotation": 90 },
+ { "vehicle": "car", "x": 30, "y": 31, "chance": 100, "rotation": 135 }
+ ]
+- },
+- "om_terrain": [
+- [ "necropolis_a_4", "necropolis_a_5", "necropolis_a_6" ],
+- [ "necropolis_a_13", "necropolis_a_14", "necropolis_a_15" ]
+- ],
+- "type": "mapgen",
+- "weight": 250
++ }
+ },
+ {
++ "type": "mapgen",
++ "om_terrain": [
++ [ "necropolis_a_7", "necropolis_a_8", "necropolis_a_9" ],
++ [ "necropolis_a_16", "necropolis_a_17", "necropolis_a_18" ]
++ ],
++ "weight": 250,
+ "method": "json",
+ "object": {
+ "fill_ter": "t_floor",
+@@ -336,15 +342,15 @@
+ { "vehicle": "policecar", "x": 57, "y": 38, "chance": 50, "rotation": 180 },
+ { "vehicle": "policecar", "x": 57, "y": 45, "chance": 50, "rotation": 180 }
+ ]
+- },
+- "om_terrain": [
+- [ "necropolis_a_7", "necropolis_a_8", "necropolis_a_9" ],
+- [ "necropolis_a_16", "necropolis_a_17", "necropolis_a_18" ]
+- ],
+- "type": "mapgen",
+- "weight": 250
++ }
+ },
+ {
++ "type": "mapgen",
++ "om_terrain": [
++ [ "necropolis_a_19", "necropolis_a_20", "necropolis_a_21" ],
++ [ "necropolis_a_28", "necropolis_a_29", "necropolis_a_30" ]
++ ],
++ "weight": 250,
+ "method": "json",
+ "object": {
+ "fill_ter": "t_floor",
+@@ -374,20 +380,20 @@
+ ".....ssssssssssssssssssssssssssssssssssssssssssss..........ssss.........",
+ "......IsssssI..................ssssssss......sss............ss.........T",
+ ".....|-=====-|--|---HHH-HHH-HHH-[[--[[-HHH-|.sss............ss..........",
+- ".....|e | r[ ccccccccccc cccc|.sss....T.......ss...T......",
+- "..#..| EEEEE | r[ c|.sss............bss.........",
+- ".....| EEEEE | r[ cc cc ZZ c|.sss............bss.........",
+- ".....|zYEEEE | r[ rrrrrrrrr c c ZZ c|.sss............bss.........",
+- ".....|zYEEEE | r[ rrrrrrrrr 6c 6c cV.sss........T.....ss........",
+- "....X| EEEEE | r[ cV.sss..............ss......T.",
++ ".....|e~~~~~~| r[ ccccccccccc cccc|.sss....T.......ss...T......",
++ "..#..|~EEEEE~| r[ c|.sss............bss.........",
++ ".....|~EEEEE~| r[ cc cc ZZ c|.sss............bss.........",
++ ".....|zYEEEE~| r[ rrrrrrrrr c c ZZ c|.sss............bss.........",
++ ".....|zYEEEE~| r[ rrrrrrrrr 6c 6c cV.sss........T.....ss........",
++ "....X|~EEEEE~| r[ cV.sss..............ss......T.",
+ ".....|zYEEEYz| r[ cV.sss.............ssss.......",
+ ".....|zYEEEYz| r[ rrrrrrrrr ZZ ZZ c c|.sss...T........ssssss......",
+- ".....| EEEEE + r[ rrrrrrrrr ZZ ZZ c c|.sss........aAassssssss.....",
+- ".....|zYEEEE |--| c {c{.sss........aUasssssssssssss",
+- ".....|zz6% + Z{ ZZ c {{.sss........aUasssssssssssss",
+- ".....| + rrrrrrrrr Z{{ ZZ {{{{sss........aAassssssss.....",
+- ".....|-------| | rrrrrrrrr { { {{){|.sss...T........ssssss......",
+- "...........ss: | {{ {{){{{{|.sss.............ssss......T",
++ ".....|~EEEEE~+ r[ rrrrrrrrr ZZ ZZ c c|.sss........aAassssssss.....",
++ ".....|zYEEEE~|--| c {c{.sss........aUasssssssssssss",
++ ".....|zz6%~~~~~~+ Z{ ZZ c {{.sss........aUasssssssssssss",
++ ".....|~~~~~~~~~~+ rrrrrrrrr Z{{ ZZ {{{{sss........aAassssssss.....",
++ ".....|-------|~~| rrrrrrrrr { { {{){|.sss...T........ssssss......",
++ "...........ss:~~| {{ {{){{{{|.sss.............ssss......T",
+ "...........ss|--| {{ { rr{{{{{{{{{ss.sss..NNNNNNNNNN..ss........",
+ "...#.....x.ss| rrrrrr{rr {{{{{){{sssss.sss.MNNNNNNNNNNN..ss.......",
+ "...........ss|r rrrrr{rr){{{{){{{{{MssMssMMMsMNN55555NNNNNN.ss..T....",
+@@ -399,7 +405,14 @@
+ "...........ss|r {{ {{{{sMsssssMsMMsMMMMMMMMMMMMMMMNNNMNNMNNNNNNMss....."
+ ],
+ "palettes": [ "necropolis_a" ],
+- "terrain": { "%": "t_elevator_control_off", "Y": "t_elevator", "Z": "t_floor", "l": "t_floor", "u": "t_floor", "z": "t_floor" },
++ "terrain": {
++ "%": "t_elevator_control_off",
++ "Y": "t_elevator",
++ "Z": "t_floor",
++ "l": "t_floor",
++ "u": "t_floor",
++ "z": "t_thconc_floor"
++ },
+ "furniture": { "Y": "f_crate_c" },
+ "set": [
+ { "square": "radiation", "amount": [ 0, 1 ], "x": 0, "x2": 23, "y": 0, "y2": 23 },
+@@ -449,15 +462,15 @@
+ { "vehicle": "car", "x": 15, "y": 17, "chance": 25, "rotation": 270 },
+ { "vehicle": "car_mini", "x": 22, "y": 18, "chance": 25, "rotation": 270 }
+ ]
+- },
+- "om_terrain": [
+- [ "necropolis_a_19", "necropolis_a_20", "necropolis_a_21" ],
+- [ "necropolis_a_28", "necropolis_a_29", "necropolis_a_30" ]
+- ],
+- "type": "mapgen",
+- "weight": 250
++ }
+ },
+ {
++ "type": "mapgen",
++ "om_terrain": [
++ [ "necropolis_a_22", "necropolis_a_23", "necropolis_a_24" ],
++ [ "necropolis_a_31", "necropolis_a_32", "necropolis_a_33" ]
++ ],
++ "weight": 250,
+ "method": "json",
+ "object": {
+ "fill_ter": "t_floor",
+@@ -546,15 +559,15 @@
+ { "vehicle": "fire_truck", "x": 15, "y": 8, "chance": 90, "rotation": 45 },
+ { "vehicle": "car", "x": 45, "y": 5, "chance": 100, "rotation": 45 }
+ ]
+- },
+- "om_terrain": [
+- [ "necropolis_a_22", "necropolis_a_23", "necropolis_a_24" ],
+- [ "necropolis_a_31", "necropolis_a_32", "necropolis_a_33" ]
+- ],
+- "type": "mapgen",
+- "weight": 250
++ }
+ },
+ {
++ "type": "mapgen",
++ "om_terrain": [
++ [ "necropolis_a_25", "necropolis_a_26", "necropolis_a_27" ],
++ [ "necropolis_a_34", "necropolis_a_35", "necropolis_a_36" ]
++ ],
++ "weight": 250,
+ "method": "json",
+ "object": {
+ "fill_ter": "t_floor",
+@@ -632,15 +645,15 @@
+ { "group": "GROUP_NECROPOLIS", "x": [ 25, 46 ], "y": [ 25, 46 ], "repeat": [ 1, 5 ] },
+ { "group": "GROUP_NECROPOLIS", "x": [ 49, 70 ], "y": [ 25, 46 ], "repeat": [ 1, 5 ] }
+ ]
+- },
+- "om_terrain": [
+- [ "necropolis_a_25", "necropolis_a_26", "necropolis_a_27" ],
+- [ "necropolis_a_34", "necropolis_a_35", "necropolis_a_36" ]
+- ],
+- "type": "mapgen",
+- "weight": 250
++ }
+ },
+ {
++ "type": "mapgen",
++ "om_terrain": [
++ [ "necropolis_a_37", "necropolis_a_38", "necropolis_a_39" ],
++ [ "necropolis_a_46", "necropolis_a_47", "necropolis_a_48" ]
++ ],
++ "weight": 250,
+ "method": "json",
+ "object": {
+ "fill_ter": "t_floor",
+@@ -723,15 +736,15 @@
+ { "vehicle": "fire_truck", "x": 32, "y": 28, "chance": 90, "rotation": 270 }
+ ],
+ "place_vendingmachines": [ { "item_group": "vending_drink", "x": 64, "y": 47 } ]
+- },
+- "om_terrain": [
+- [ "necropolis_a_37", "necropolis_a_38", "necropolis_a_39" ],
+- [ "necropolis_a_46", "necropolis_a_47", "necropolis_a_48" ]
+- ],
+- "type": "mapgen",
+- "weight": 250
++ }
+ },
+ {
++ "type": "mapgen",
++ "om_terrain": [
++ [ "necropolis_a_40", "necropolis_a_41", "necropolis_a_42" ],
++ [ "necropolis_a_49", "necropolis_a_50", "necropolis_a_51" ]
++ ],
++ "weight": 250,
+ "method": "json",
+ "object": {
+ "fill_ter": "t_floor",
+@@ -759,24 +772,24 @@
+ "sssssssssssssssssssssssssss__________________sssssssssssssssssssssssssss",
+ "ssssssssssssssssssssssssssss_________,,,,,,_ssssssssssssssssssssssssssss",
+ "..ss{{{{--|--|--|-----|sssss________________sss#######|--ww-++-ww---|sss",
+- "..ss{{ {@d|BB|BB|d@@ n|ss.ss_______,,_______ss##shhsss|hh chNNh|sss",
+- "..ss{{{@@ | t|t | @@ hwss.ss_______,,_______ss#shNNhss|NN chNNh|sss",
+- "..ss{ | S|S | wss.ss_______,,_______ss#shNNhsswNN h |sss",
+- "..ss{ |+-|-+| |ss.ss________________ssssshhssswhh N hcc |777",
++ "..ss{{ {@d|BB|BB|d@@ n|ss.ss_______,,_______ss##sh̲h̲sss|hh chNNh|sss",
++ "..ss{{{@@ | t|t | @@ hwss.ss_______,,_______ss#sh̲n̲n̲h̲ss|NN chNNh|sss",
++ "..ss{ | S|S | wss.ss_______,,_______ss#sh̲n̲n̲h̲sswNN h |sss",
++ "..ss{ |+-|-+| |ss.ss________________sssssh̲h̲ssswhh N hcc |777",
+ "..ss; f|f ;ss.ss_______,,_______sssssssssswcc h hc r|sss",
+ "..ss| nnnn | nnnn |ss.ss_______,,_______ss#sssssss|hh hc r|sss",
+- "..ss|-----|--|--|-----|ss.ss_______,,_______ss#sshhsss|NN h hc f|sss",
+- "..ss|n @@d|BB|BB|d@@ n|ss.ss________________ss#shNNhsswNN N hc f|sss",
+- "..sswh @@ | t|t | @@ hwss.ss_______,,_______ss#shNNhsswhh h hc c|sss",
+- "..ssw | S|S | wss.ss_______,,_______ss#sshhssswcc hc S|sss",
++ "..ss|-----|--|--|-----|ss.ss_______,,_______ss#ssh̲h̲sss|NN h hc f|sss",
++ "..ss|n @@d|BB|BB|d@@ n|ss.ss________________ss#sh̲n̲n̲h̲sswNN N hc f|sss",
++ "..sswh @@ | t|t | @@ hwss.ss_______,,_______ss#sh̲n̲n̲h̲sswhh h hc c|sss",
++ "..ssw | S|S | wss.ss_______,,_______ss#ssh̲h̲ssswcc hc S|sss",
+ "..ss| |+-|-+| |ss.ss_______,,_______ss#sssssss| c r|sss",
+ "..ss; f|f ;ss.ss________________ssssssssss[ c r|sss",
+ "..ss| nnnn | nnnn |ss.ss_______,,_______ssssssssss[ |----|c-- -|sss",
+ "..ss|-----|--|--|-----|ss.ss_______,,_______ss#sssssss| + | c|sss",
+- "..ss|n @@d|BB|BB|d@@ n|ss.ss_______,,_______ss#sshhsssw |S t |c S|Dss",
+- "..sswh @@ | t|t | @@ hwss.ss________________ss#shNNhssw |----|c S|Dss",
+- "..ssw | S|S | wss.ss_______,,_______ss#shNNhssw + |c ;sss",
+- "..ss| |+-|-+| |ss.ss_______,,_______ss##shhsss| |S t |cOOff|797",
++ "..ss|n @@d|BB|BB|d@@ n|ss.ss_______,,_______ss#ssh̲h̲sssw |S t |c S|d̲ss",
++ "..sswh @@ | t|t | @@ hwss.ss________________ss#sh̲n̲n̲h̲ssw |----|c S|d̲ss",
++ "..ssw | S|S | wss.ss_______,,_______ss#sh̲n̲n̲h̲ssw + |c ;sss",
++ "..ss| |+-|-+| |ss.ss_______,,_______ss##sh̲h̲sss| |S t |cOOff|797",
+ "..ss; f|f ;ss.ss_______,,________ss#####ss|--|----|-----|sss",
+ "..ss| nnnnn | nnnn |ss.ss_______________________,__,_________________",
+ "..ss|--------|--------|ss.ss_______,,______________,,,,_________________",
+@@ -804,15 +817,15 @@
+ { "group": "GROUP_NECROPOLIS", "x": [ 25, 46 ], "y": [ 25, 46 ], "repeat": [ 1, 5 ] },
+ { "group": "GROUP_NECROPOLIS", "x": [ 49, 70 ], "y": [ 25, 46 ], "repeat": [ 1, 5 ] }
+ ]
+- },
+- "om_terrain": [
+- [ "necropolis_a_40", "necropolis_a_41", "necropolis_a_42" ],
+- [ "necropolis_a_49", "necropolis_a_50", "necropolis_a_51" ]
+- ],
+- "type": "mapgen",
+- "weight": 250
++ }
+ },
+ {
++ "type": "mapgen",
++ "om_terrain": [
++ [ "necropolis_a_43", "necropolis_a_44", "necropolis_a_45" ],
++ [ "necropolis_a_52", "necropolis_a_53", "necropolis_a_54" ]
++ ],
++ "weight": 250,
+ "method": "json",
+ "object": {
+ "fill_ter": "t_floor",
+@@ -899,15 +912,15 @@
+ { "group": "GROUP_NECROPOLIS", "x": [ 25, 46 ], "y": [ 25, 46 ], "repeat": [ 1, 5 ] },
+ { "group": "GROUP_NECROPOLIS", "x": [ 49, 70 ], "y": [ 25, 46 ], "repeat": [ 1, 5 ] }
+ ]
+- },
+- "om_terrain": [
+- [ "necropolis_a_43", "necropolis_a_44", "necropolis_a_45" ],
+- [ "necropolis_a_52", "necropolis_a_53", "necropolis_a_54" ]
+- ],
+- "type": "mapgen",
+- "weight": 250
++ }
+ },
+ {
++ "type": "mapgen",
++ "om_terrain": [
++ [ "necropolis_a_55", "necropolis_a_56", "necropolis_a_57" ],
++ [ "necropolis_a_64", "necropolis_a_65", "necropolis_a_66" ]
++ ],
++ "weight": 250,
+ "method": "json",
+ "object": {
+ "fill_ter": "t_floor",
+@@ -988,15 +1001,15 @@
+ { "vehicle": "policecar", "x": 23, "y": 35, "chance": 90, "rotation": 90 }
+ ],
+ "place_vendingmachines": [ { "item_group": "vending_food", "x": 64, "y": 0 }, { "item_group": "vending_drink", "x": 68, "y": 17 } ]
+- },
+- "om_terrain": [
+- [ "necropolis_a_55", "necropolis_a_56", "necropolis_a_57" ],
+- [ "necropolis_a_64", "necropolis_a_65", "necropolis_a_66" ]
+- ],
+- "type": "mapgen",
+- "weight": 250
++ }
+ },
+ {
++ "type": "mapgen",
++ "om_terrain": [
++ [ "necropolis_a_58", "necropolis_a_59", "necropolis_a_60" ],
++ [ "necropolis_a_67", "necropolis_a_68", "necropolis_a_69" ]
++ ],
++ "weight": 250,
+ "method": "json",
+ "object": {
+ "fill_ter": "t_floor",
+@@ -1074,15 +1087,15 @@
+ { "vehicle": "pickup", "x": 64, "y": 21, "chance": 50, "rotation": 270 },
+ { "vehicle": "car", "x": 71, "y": 21, "chance": 50, "rotation": 270 }
+ ]
+- },
+- "om_terrain": [
+- [ "necropolis_a_58", "necropolis_a_59", "necropolis_a_60" ],
+- [ "necropolis_a_67", "necropolis_a_68", "necropolis_a_69" ]
+- ],
+- "type": "mapgen",
+- "weight": 250
++ }
+ },
+ {
++ "type": "mapgen",
++ "om_terrain": [
++ [ "necropolis_a_61", "necropolis_a_62", "necropolis_a_63" ],
++ [ "necropolis_a_70", "necropolis_a_71", "necropolis_a_72" ]
++ ],
++ "weight": 250,
+ "method": "json",
+ "object": {
+ "fill_ter": "t_floor",
+@@ -1160,15 +1173,12 @@
+ { "vehicle": "pickup", "x": 15, "y": 21, "chance": 25, "rotation": 270 },
+ { "vehicle": "car", "x": 23, "y": 21, "chance": 25, "rotation": 270 }
+ ]
+- },
+- "om_terrain": [
+- [ "necropolis_a_61", "necropolis_a_62", "necropolis_a_63" ],
+- [ "necropolis_a_70", "necropolis_a_71", "necropolis_a_72" ]
+- ],
+- "type": "mapgen",
+- "weight": 250
++ }
+ },
+ {
++ "type": "mapgen",
++ "om_terrain": [ [ "necropolis_a_73", "necropolis_a_74", "necropolis_a_75" ] ],
++ "weight": 250,
+ "method": "json",
+ "object": {
+ "fill_ter": "t_floor",
+@@ -1216,12 +1226,12 @@
+ { "group": "GROUP_NECROPOLIS", "x": [ 25, 46 ], "y": [ 1, 22 ], "repeat": [ 1, 5 ] },
+ { "group": "GROUP_NECROPOLIS", "x": [ 49, 70 ], "y": [ 1, 22 ], "repeat": [ 1, 5 ] }
+ ]
+- },
+- "om_terrain": [ [ "necropolis_a_73", "necropolis_a_74", "necropolis_a_75" ] ],
+- "type": "mapgen",
+- "weight": 250
++ }
+ },
+ {
++ "type": "mapgen",
++ "om_terrain": [ [ "necropolis_a_76", "necropolis_a_77", "necropolis_a_78" ] ],
++ "weight": 250,
+ "method": "json",
+ "object": {
+ "fill_ter": "t_floor",
+@@ -1267,12 +1277,12 @@
+ { "group": "GROUP_NECROPOLIS", "x": [ 49, 70 ], "y": [ 1, 22 ], "repeat": [ 1, 5 ] }
+ ],
+ "place_vehicles": [ { "vehicle": "policecar", "x": 33, "y": 9, "chance": 90, "rotation": 0 } ]
+- },
+- "om_terrain": [ [ "necropolis_a_76", "necropolis_a_77", "necropolis_a_78" ] ],
+- "type": "mapgen",
+- "weight": 250
++ }
+ },
+ {
++ "type": "mapgen",
++ "om_terrain": [ [ "necropolis_a_79", "necropolis_a_80", "necropolis_a_81" ] ],
++ "weight": 250,
+ "method": "json",
+ "object": {
+ "fill_ter": "t_floor",
+@@ -1325,9 +1335,6 @@
+ { "vehicle": "car", "x": 10, "y": 10, "chance": 75, "rotation": 270 },
+ { "vehicle": "pickup", "x": 21, "y": 10, "chance": 75, "rotation": 270 }
+ ]
+- },
+- "om_terrain": [ [ "necropolis_a_79", "necropolis_a_80", "necropolis_a_81" ] ],
+- "type": "mapgen",
+- "weight": 250
++ }
+ }
+ ]
+diff --git a/data/json/mapgen_palettes/necropolis/necropolis_a.json b/data/json/mapgen_palettes/necropolis/necropolis_a.json
+index da883f01f07..8e785c6163e 100644
+--- a/data/json/mapgen_palettes/necropolis/necropolis_a.json
++++ b/data/json/mapgen_palettes/necropolis/necropolis_a.json
+@@ -3,10 +3,16 @@
+ "type": "palette",
+ "id": "necropolis_a",
+ "furniture": {
++ "Ю": "f_camp_chair",
++ "Я": "f_tourist_table",
+ "@": "f_bed",
+ "à": "f_bed",
+ "é": "f_desk",
+ "è": "f_dresser",
++ "n̲": "f_table",
++ "h̲": "f_chair",
++ "d̲": "f_dumpster",
++ "r̲": "f_rack",
+ ")": "f_wreckage",
+ "?": "f_sofa",
+ "B": "f_bathtub",
+@@ -44,10 +50,17 @@
+ "u": "f_barricade_road"
+ },
+ "terrain": {
++ "Ю": "t_sidewalk",
++ "Я": "t_sidewalk",
+ "@": "t_floor",
+ "à": "t_floor",
+ "é": "t_floor",
+ "è": "t_floor",
++ "n̲": "t_sidewalk",
++ "h̲": "t_sidewalk",
++ "d̲": "t_sidewalk",
++ "~": "t_thconc_floor",
++ "r̲": "t_thconc_floor",
+ "!": "t_bars",
+ "#": "t_region_shrub",
+ "&": "t_sidewalk",
+@@ -137,6 +150,7 @@
+ "(": { "item": "pantry", "chance": 50, "repeat": 3 },
+ "@": { "item": "bed", "chance": 50, "repeat": 2 },
+ ".": { "item": "field", "chance": 1 },
++ "d̲": { "item": "trash", "chance": 65, "repeat": 4 },
+ "D": { "item": "floor_trash", "chance": 90, "repeat": 3 },
+ "O": { "item": "oven", "chance": 50, "repeat": 2 },
+ "d": { "item": "dresser", "chance": 50, "repeat": 3 },
+--
+2.43.0
+
diff --git a/hotfix-06_fix-more-fix-for-level-0-of-the-Necropolis-2-4426.patch b/hotfix-06_fix-more-fix-for-level-0-of-the-Necropolis-2-4426.patch
new file mode 100644
index 0000000..e02f479
--- /dev/null
+++ b/hotfix-06_fix-more-fix-for-level-0-of-the-Necropolis-2-4426.patch
@@ -0,0 +1,274 @@
+From d9a4610515b9c18d11ed97df0dd1e212719a5a77 Mon Sep 17 00:00:00 2001
+From: 0Monet <146018959+0Monet@users.noreply.github.com>
+Date: Thu, 4 Apr 2024 01:03:11 +0200
+Subject: [PATCH] fix: more fix for level 0 of the Necropolis 2 (#4426)
+
+* Update necropolis.json
+
+* Update necropolis_a.json
+
+* style(autofix.ci): automated formatting
+
+---------
+
+Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
+---
+ data/json/mapgen/necropolis/necropolis.json | 87 +++++++++----------
+ .../necropolis/necropolis_a.json | 10 ++-
+ 2 files changed, 47 insertions(+), 50 deletions(-)
+
+diff --git a/data/json/mapgen/necropolis/necropolis.json b/data/json/mapgen/necropolis/necropolis.json
+index f03d1340342..3e621b18774 100644
+--- a/data/json/mapgen/necropolis/necropolis.json
++++ b/data/json/mapgen/necropolis/necropolis.json
+@@ -79,28 +79,28 @@
+ "......................................ss................................",
+ "...............X......................ss................................",
+ ".qQQQQQQQQQQQQQQQQQQQQQQQq......sssssssssssssssss8777777777777777777778.",
+- ".q.......................q.....ssssssssssssssssss8ssrrrrrrrrrrsssssssr8.",
+- ".q..|-vv-|----|-|-----|..q....ss_________________9sssssssssssssssssssr8.",
+- ".q..|((Sc|BtcS|>|d @@ |..q...ss__________________9sssssssssssssssZZssr8.",
+- ".q..|( |B | + @@ v..q..ss___________________9sssssssssssssssZZssr8.",
+- ".q..vO |--+-|-| |..q.ss____________________9sssssssssssssssssssr8.",
+- ".q..vc + v..qss_____________________9sssssssssssssssssssr8.",
+- ".q..|f |c ?| ddd |..qss_____________________9sssssssssssssssZZssr8.",
+- ".q..|-| -|c ?|-----|..qss_________________s...8sssZZssssZZssssZZssr8.",
+- ".q....| ?v........qss________________ss...8sssZZssssZZssssssssr8.",
+- ".q....V hnnh |........qss________________ss...8sssssssssssssssssssr8.",
+- ".q....V hnnh ;sssssssssss_______,,_______ss...8sssssssssssssssZZssr8.",
+- ".q....V ;sssssssssss_______,,_______ss...8srrrrrrrrrsssssZZssr8.",
+- ".q....| ooP|....s...qss_______,,_______ss..|------------|rssssssr8.",
+- ".q....|;|--+----|--|es...qss________________ss..|222222222222|rssssssr8.",
+- ".q..ssss|r̲~~~~~~~~~=_______________,,_______ss..w3 2|rssZZssr8.",
+- ".q..sЮss|r̲~~~~~~~~~=_______________,,_______ss..w3 11 11 2|rssZZssr8.",
+- ".q..sЯss|r̲~~~~~~~~~=_______________,,_______ss..w3 11 11 2|rssssssr8.",
+- ".q..sЮss|r̲~~~~~~~~~=________________________ss..|r [sssssssr8.",
+- ".q..ssss|r̲~~~~~~~~~=_______________,,_______ss..w3 11 [sssssssr8.",
+- ".q......|----------|.....qss_______,,_______ss..w3 11 cc 1|rssssssr8.",
+- ".q.......................qss_______,,_______ss..w3 6 1|rssZZssr8.",
+- ".qQQQQQQQQQQQQQQQQQQQQQQQqss________________ss..|r333r c 1|rssZZssr8.",
++ ".q.......................q.....ssssssssssssssssss8ssṟṟṟṟṟṟṟṟṟṟsssssssṟ8.",
++ ".q..|-vv-|----|-|-----|..q....ss_________________9sssssssssssssssssssṟ8.",
++ ".q..|((Sc|BtcS|>|d @@ |..q...ss__________________9sssssssssssssssZZssṟ8.",
++ ".q..|( |B | + @@ v..q..ss___________________9sssssssssssssssZZssṟ8.",
++ ".q..vO |--+-|-| |..q.ss____________________9sssssssssssssssssssṟ8.",
++ ".q..vc + v..qss_____________________9sssssssssssssssssssṟ8.",
++ ".q..|f |c ?| ddd |..qss_____________________9sssssssssssssssZZssṟ8.",
++ ".q..|-| -|c ?|-----|..qss_________________s...8sssZZssssZZssssZZssṟ8.",
++ ".q....| ?v........qss________________ss...8sssZZssssZZssssssssṟ8.",
++ ".q....V hnnh |........qss________________ss...8sssssssssssssssssssṟ8.",
++ ".q....V hnnh ;sssssssssss_______,,_______ss...8sssssssssssssssZZssṟ8.",
++ ".q....V ;sssssssssss_______,,_______ss...8sṟṟṟṟṟṟṟṟṟsssssZZssṟ8.",
++ ".q....| ooP|....s...qss_______,,_______ss..|------------|ṟssssssṟ8.",
++ ".q....|;|--+----|--|es...qss________________ss..|222222222222|ṟssssssṟ8.",
++ ".q..ssss|r̲~~~~~~~~~=_______________,,_______ss..w3 2|ṟssZZssṟ8.",
++ ".q..sЮss|r̲~~~~~~~~~=_______________,,_______ss..w3 11 11 2|ṟssZZssṟ8.",
++ ".q..sЯss|r̲~~~~~~~~~=_______________,,_______ss..w3 11 11 2|ṟssssssṟ8.",
++ ".q..sЮss|r̲~~~~~~~~~=________________________ss..|r [sssssssṟ8.",
++ ".q..ssss|r̲~~~~~~~~~=_______________,,_______ss..w3 11 [sssssssṟ8.",
++ ".q......|----------|.....qss_______,,_______ss..w3 11 cc 1|ṟssssssṟ8.",
++ ".q.......................qss_______,,_______ss..w3 6 1|ṟssZZssṟ8.",
++ ".qQQQQQQQQQQQQQQQQQQQQQQQqss________________ss..|r333r c 1|ṟssZZssṟ8.",
+ "..........................ss_______,,_______ss..|-www-[[-www-|777777778."
+ ],
+ "palettes": [ "necropolis_a" ],
+@@ -197,7 +197,7 @@
+ ".|-{{{-sss-ssssssM.MMMsMMmm]]]]]]]]]]]]]]]]]mmMMMMMs_M_M___,,_______sss."
+ ],
+ "palettes": [ "necropolis_a" ],
+- "terrain": { "l": "t_floor", "u": "t_floor" },
++ "terrain": { "l": "t_floor" },
+ "set": [
+ { "square": "radiation", "amount": [ 0, 1 ], "x": 0, "x2": 23, "y": 0, "y2": 23 },
+ { "square": "radiation", "amount": [ 0, 1 ], "x": 24, "x2": 47, "y": 0, "y2": 23 },
+@@ -291,7 +291,7 @@
+ "..|P : | hhhhh |ss________________,________,________8........."
+ ],
+ "palettes": [ "necropolis_a" ],
+- "terrain": { "Z": "t_floor", "l": "t_floor", "u": "t_floor", "z": "t_floor" },
++ "terrain": { "Z": "t_floor", "l": "t_floor", "z": "t_floor" },
+ "furniture": { "F": "f_filing_cabinet" },
+ "items": {
+ "F": { "item": "office_paper", "chance": 40, "repeat": 5 },
+@@ -355,8 +355,8 @@
+ "object": {
+ "fill_ter": "t_floor",
+ "rows": [
+- ".....sssssssssssssssssssssss_______,,_______ss..........................",
+- "....ssssssssssssssssssssssss_______,,_______sss.........................",
++ ".....sssssssssssssssssssssss_______,,_______ss........ss................",
++ "....ssssssssssssssssssssssss_______,,_______sss.......ss................",
+ "....sss_____,______,_____sss________________ssssssssssssssssssssssssssss",
+ "....ss______,______,______ss_______,,________sssssssssssssssssssssssssss",
+ "....ss______,______,______ss_______,,___________________________________",
+@@ -405,14 +405,7 @@
+ "...........ss|r {{ {{{{sMsssssMsMMsMMMMMMMMMMMMMMMNNNMNNMNNNNNNMss....."
+ ],
+ "palettes": [ "necropolis_a" ],
+- "terrain": {
+- "%": "t_elevator_control_off",
+- "Y": "t_elevator",
+- "Z": "t_floor",
+- "l": "t_floor",
+- "u": "t_floor",
+- "z": "t_thconc_floor"
+- },
++ "terrain": { "%": "t_elevator_control_off", "Y": "t_elevator", "Z": "t_floor", "l": "t_floor", "z": "t_thconc_floor" },
+ "furniture": { "Y": "f_crate_c" },
+ "set": [
+ { "square": "radiation", "amount": [ 0, 1 ], "x": 0, "x2": 23, "y": 0, "y2": 23 },
+@@ -525,7 +518,7 @@
+ "..ss________________sss..........|c |---------| h @@ |--|.."
+ ],
+ "palettes": [ "necropolis_a" ],
+- "terrain": { "Z": "t_floor", "l": "t_floor", "u": "t_floor", "z": "t_floor" },
++ "terrain": { "Z": "t_floor", "l": "t_floor", "z": "t_floor" },
+ "set": [
+ { "square": "radiation", "amount": [ 0, 1 ], "x": 0, "x2": 23, "y": 0, "y2": 23 },
+ { "square": "radiation", "amount": [ 0, 1 ], "x": 24, "x2": 47, "y": 0, "y2": 23 },
+@@ -622,7 +615,7 @@
+ "......|-{{{{ssMsMssMssMMMMMMMmm]]]]]]]]]]]]]]]]]]]mmMMMMM.M..M..MM......"
+ ],
+ "palettes": [ "necropolis_a" ],
+- "terrain": { "Z": "t_floor", "l": "t_floor", "u": "t_floor", "z": "t_floor" },
++ "terrain": { "Z": "t_floor", "l": "t_floor", "z": "t_floor" },
+ "furniture": { "$": "f_safe_l" },
+ "set": [
+ { "square": "radiation", "amount": [ 0, 1 ], "x": 0, "x2": 23, "y": 0, "y2": 23 },
+@@ -708,7 +701,7 @@
+ "........|BB|d@@d@@ n|sss________________________sss| jjjjjj D|l |ss"
+ ],
+ "palettes": [ "necropolis_a" ],
+- "terrain": { "D": "t_floor", "R": "t_floor", "l": "t_floor", "u": "t_floor", "z": "t_floor" },
++ "terrain": { "D": "t_floor", "R": "t_floor", "l": "t_floor", "z": "t_floor" },
+ "furniture": { "R": "f_rack" },
+ "set": [
+ { "square": "radiation", "amount": [ 0, 1 ], "x": 0, "x2": 23, "y": 0, "y2": 23 },
+@@ -799,7 +792,7 @@
+ "ss________________________ss_______,,______________,,,,_________________"
+ ],
+ "palettes": [ "necropolis_a" ],
+- "terrain": { "Z": "t_floor", "l": "t_floor", "N": "t_floor", "u": "t_floor", "z": "t_floor" },
++ "terrain": { "Z": "t_floor", "l": "t_floor", "N": "t_floor", "z": "t_floor" },
+ "furniture": { "N": "f_table" },
+ "items": { "n": { "item": "traveler", "chance": 50 } },
+ "place_loot": [
+@@ -880,7 +873,7 @@
+ "___________________________________,,_______ss......C..................."
+ ],
+ "palettes": [ "necropolis_a" ],
+- "terrain": { "Z": "t_floor", "l": "t_floor", "u": "t_floor", "z": "t_floor" },
++ "terrain": { "Z": "t_floor", "l": "t_floor", "z": "t_floor" },
+ "furniture": { "$": "f_safe_l" },
+ "set": [
+ { "square": "radiation", "amount": [ 0, 1 ], "x": 0, "x2": 23, "y": 0, "y2": 23 },
+@@ -960,8 +953,8 @@
+ "________________u_______________________________________________________",
+ "________________________________________________________________________",
+ "__________________u_____________________________________________________",
+- "_,,,_,,,_,,,_,,,_,u,_,,,_,,,_,,,_,,,_,,,_,,,_,,,_,,,_,,,_,,,_,,,_,,,_,,,",
+- "_,,,_,,,_,,,_,,,_,u,_,,,_,,,_,,,_,,,_,,,_,,,_,,,_,,,_,,,_,,,_,,,_,,,_,,,",
++ "_,,,_,,,_,,,_,,,_,u̲,_,,,_,,,_,,,_,,,_,,,_,,,_,,,_,,,_,,,_,,,_,,,_,,,_,,,",
++ "_,,,_,,,_,,,_,,,_,u̲,_,,,_,,,_,,,_,,,_,,,_,,,_,,,_,,,_,,,_,,,_,,,_,,,_,,,",
+ "________________________________________________________________________",
+ "_________________u______________________________________________________",
+ "_________________u______________________________________________________",
+@@ -975,7 +968,7 @@
+ ".............###.s______,______,______,______s##s___,,___s|hnnh hnnh|ss"
+ ],
+ "palettes": [ "necropolis_a" ],
+- "terrain": { "D": "t_floor", "Z": "t_floor", "l": "t_floor", "u": "t_floor", "z": "t_floor" },
++ "terrain": { "D": "t_floor", "Z": "t_floor", "l": "t_floor", "z": "t_floor" },
+ "items": { "n": { "item": "traveler", "chance": 50 } },
+ "place_loot": [
+ { "group": "dining", "x": [ 56, 57 ], "y": [ 17, 18 ], "chance": 70 },
+@@ -1150,7 +1143,7 @@
+ "_____________________________s.......#.................................."
+ ],
+ "palettes": [ "necropolis_a" ],
+- "terrain": { "Z": "t_floor", "l": "t_floor", "u": "t_floor", "z": "t_floor" },
++ "terrain": { "Z": "t_floor", "l": "t_floor", "z": "t_floor" },
+ "items": { "r": { "item": "SUS_junk_drawer", "chance": 75 } },
+ "place_loot": [
+ { "group": "SUS_bathroom_medicine", "x": 59, "y": 10, "chance": 50 },
+@@ -1209,7 +1202,7 @@
+ "........................................................#..............."
+ ],
+ "palettes": [ "necropolis_a" ],
+- "terrain": { "D": "t_floor", "Z": "t_floor", "l": "t_floor", "u": "t_floor", "z": "t_floor" },
++ "terrain": { "D": "t_floor", "Z": "t_floor", "l": "t_floor", "z": "t_floor" },
+ "items": {
+ "L": { "item": "cleaning", "chance": 50, "repeat": 2 },
+ "n": { "item": "dining", "chance": 50 },
+@@ -1248,7 +1241,7 @@
+ "__________________________ss_______,,_______ss________s________ssD|r cc ",
+ "s_________________________ss____________uuu_ss________s________sss[ ",
+ "sssssss____________,,,,,,,ss_______,,_______ss________I________sss[ ",
+- "__________________________ss_______,uuu_____ss________&________ssD|r ",
++ "__________________________ss_______,u̲uu_____ss________&________ssD|r ",
+ "__________________________ss_______,,________s________I________sssw ",
+ "__________________________ss__uuu______________________________sssw rrr ",
+ "__________________________ss_______,,__________________________sss| rrr ",
+@@ -1262,7 +1255,7 @@
+ "............................________________ss.........................."
+ ],
+ "palettes": [ "necropolis_a" ],
+- "terrain": { "Z": "t_floor", "l": "t_floor", "u": "t_floor", "z": "t_floor" },
++ "terrain": { "Z": "t_floor", "l": "t_floor", "z": "t_floor" },
+ "gaspumps": { "&": { } },
+ "place_loot": [
+ { "group": "alcohol", "x": [ 67, 71 ], "y": 19, "chance": 30, "repeat": 3 },
+@@ -1313,7 +1306,7 @@
+ "..............#........................................................."
+ ],
+ "palettes": [ "necropolis_a" ],
+- "terrain": { "Z": "t_floor", "l": "t_floor", "u": "t_floor", "z": "t_floor" },
++ "terrain": { "Z": "t_floor", "l": "t_floor", "z": "t_floor" },
+ "place_vendingmachines": [ { "item_group": "vending_food", "x": 3, "y": 5 }, { "item_group": "vending_drink", "x": 4, "y": 5 } ],
+ "items": { "o": { "item": "hardware_books", "chance": 50 } },
+ "place_loot": [
+diff --git a/data/json/mapgen_palettes/necropolis/necropolis_a.json b/data/json/mapgen_palettes/necropolis/necropolis_a.json
+index 8e785c6163e..c474e5ced74 100644
+--- a/data/json/mapgen_palettes/necropolis/necropolis_a.json
++++ b/data/json/mapgen_palettes/necropolis/necropolis_a.json
+@@ -13,6 +13,9 @@
+ "h̲": "f_chair",
+ "d̲": "f_dumpster",
+ "r̲": "f_rack",
++ "u": "f_barricade_road",
++ "u̲": "f_barricade_road",
++ "ṟ": "f_rack",
+ ")": "f_wreckage",
+ "?": "f_sofa",
+ "B": "f_bathtub",
+@@ -46,8 +49,7 @@
+ "z": "f_crate_c",
+ "(": "f_cupboard",
+ "{": "f_rubble",
+- "t": "f_toilet",
+- "u": "f_barricade_road"
++ "t": "f_toilet"
+ },
+ "terrain": {
+ "Ю": "t_sidewalk",
+@@ -61,6 +63,9 @@
+ "d̲": "t_sidewalk",
+ "~": "t_thconc_floor",
+ "r̲": "t_thconc_floor",
++ "u": "t_pavement",
++ "u̲": "t_pavement_y",
++ "ṟ": "t_sidewalk",
+ "!": "t_bars",
+ "#": "t_region_shrub",
+ "&": "t_sidewalk",
+@@ -133,7 +138,6 @@
+ "r": "t_floor",
+ "s": "t_sidewalk",
+ "t": "t_floor",
+- "u": "t_pavement",
+ "v": "t_window_domestic",
+ "w": "t_window",
+ "x": "t_region_groundcover_urban",
+--
+2.43.0
+
diff --git a/0020-hk46-is-milspec.patch b/itemgroups-01_hk46-is-milspec.patch
index 3df910d..3df910d 100644
--- a/0020-hk46-is-milspec.patch
+++ b/itemgroups-01_hk46-is-milspec.patch
diff --git a/0011-add-missing-mre.patch b/itemgroups-02_add-missing-mre.patch
index f776e12..f776e12 100644
--- a/0011-add-missing-mre.patch
+++ b/itemgroups-02_add-missing-mre.patch
diff --git a/itemgroups-03_fix-shelter-batteries.patch b/itemgroups-03_fix-shelter-batteries.patch
new file mode 100644
index 0000000..33c2c04
--- /dev/null
+++ b/itemgroups-03_fix-shelter-batteries.patch
@@ -0,0 +1,41 @@
+--- a/data/json/itemgroups/SUS/evac_shelter.json
++++ b/data/json/itemgroups/SUS/evac_shelter.json
+@@ -10,7 +10,13 @@
+ { "item": "jacket_evac", "prob": 75 },
+ { "item": "emer_blanket", "prob": 75 },
+ { "item": "mask_gas", "prob": 2 },
+- { "item": "flashlight", "prob": 50 },
++ {
++ "item": "light_disposable_cell",
++ "charges-min": 150,
++ "charges-max": 300,
++ "container-item": "flashlight",
++ "prob": 50
++ },
+ { "item": "light_disposable_cell", "prob": 10 },
+ { "item": "lighter", "prob": 20 },
+ { "item": "whistle", "prob": 70 },
+@@ -65,9 +71,21 @@
+ "collection": [
+ { "item": "extinguisher", "prob": 70 },
+ { "item": "1st_aid", "count": [ 1, 3 ], "prob": 65 },
+- { "item": "two_way_radio", "prob": 65 },
++ {
++ "item": "light_disposable_cell",
++ "charges-min": 150,
++ "charges-max": 300,
++ "container-item": "two_way_radio",
++ "prob": 65
++ },
+ { "item": "light_disposable_cell", "count": [ 2, 4 ], "prob": 65 },
+- { "item": "electric_lantern", "prob": 35 },
++ {
++ "item": "light_disposable_cell",
++ "charges-min": 150,
++ "charges-max": 300,
++ "container-item": "electric_lantern",
++ "prob": 35
++ },
+ { "item": "barometer", "prob": 8 }
+ ],
+ "prob": 10
diff --git a/jc_allow-bio-firestarter-on-smoker.patch b/jc_allow-bio-firestarter-on-smoker.patch
deleted file mode 100644
index 6ced728..0000000
--- a/jc_allow-bio-firestarter-on-smoker.patch
+++ /dev/null
@@ -1,39 +0,0 @@
---- a/src/iexamine.cpp
-+++ b/src/iexamine.cpp
-@@ -4866,18 +4866,30 @@
- return;
- }
-
-- if( !p.has_charges( "fire", 1 ) ) {
-+ const bool has_bionic_firestarter = p.has_bionic( bio_lighter ) &&
-+ p.enough_power_for( bio_lighter );
-+
-+ if( !has_bionic_firestarter && !p.has_charges( "fire", 1 ) ) {
- add_msg( _( "This smoking rack is ready to be fired, but you have no fire source." ) );
- return;
- } else if( !query_yn( _( "Fire the smoking rack?" ) ) ) {
- return;
- }
-
-- p.use_charges( "fire", 1 );
-- for( auto &it : g->m.i_at( examp ) ) {
-- if( it.has_flag( flag_SMOKABLE ) ) {
-- it.process_rot( 1, false, examp, nullptr );
-- it.set_flag( flag_PROCESSING );
-+ if( has_bionic_firestarter ) {
-+ for( auto &it : g->m.i_at( examp ) ) {
-+ if( it.has_flag( flag_SMOKABLE ) ) {
-+ it.process_rot( 1, false, examp, nullptr );
-+ it.set_flag( flag_PROCESSING );
-+ }
-+ }
-+ } else {
-+ p.use_charges( "fire", 1 );
-+ for( auto &it : g->m.i_at( examp ) ) {
-+ if( it.has_flag( flag_SMOKABLE ) ) {
-+ it.process_rot( 1, false, examp, nullptr );
-+ it.set_flag( flag_PROCESSING );
-+ }
- }
- }
- g->m.furn_set( examp, next_smoker_type );
diff --git a/jc_allow-hacker-laptop.patch b/jc_allow-hacker-laptop.patch
deleted file mode 100644
index 69ca8b2..0000000
--- a/jc_allow-hacker-laptop.patch
+++ /dev/null
@@ -1,21 +0,0 @@
---- a/src/game.cpp
-+++ b/src/game.cpp
-@@ -2432,7 +2432,8 @@
- remoteveh_cache_time = calendar::turn;
- std::stringstream remote_veh_string( u.get_value( "remote_controlling_vehicle" ) );
- if( remote_veh_string.str().empty() ||
-- ( !u.has_active_bionic( bio_remote ) && !u.has_active_item( "remotevehcontrol" ) ) ) {
-+ ( !u.has_active_bionic( bio_remote ) && !u.has_active_item( "remotevehcontrol" )
-+ && !u.has_active_item( "hacker_laptop" ) ) ) {
- remoteveh_cache = nullptr;
- } else {
- tripoint vp;
-@@ -2452,7 +2453,7 @@
- remoteveh_cache_time = calendar::turn;
- remoteveh_cache = veh;
- if( veh != nullptr && !u.has_active_bionic( bio_remote ) &&
-- !u.has_active_item( "remotevehcontrol" ) ) {
-+ !u.has_active_item( "remotevehcontrol" ) && !u.has_active_item( "hacker_laptop" ) ) {
- debugmsg( "Tried to set remote vehicle without bio_remote or remotevehcontrol" );
- veh = nullptr;
- }
diff --git a/jc_npcs-eat-when-hungry.patch b/jc_npcs-eat-when-hungry.patch
deleted file mode 100644
index 1c7bf0c..0000000
--- a/jc_npcs-eat-when-hungry.patch
+++ /dev/null
@@ -1,29 +0,0 @@
---- a/src/npcmove.cpp
-+++ b/src/npcmove.cpp
-@@ -1858,7 +1858,9 @@
- }
-
- if( one_in( 3 ) && ( get_thirst() > thirst_levels::thirsty ||
-- get_stored_kcal() + stomach.get_calories() < get_healthy_kcal() * 0.95 ) ) {
-+ get_stored_kcal() + stomach.get_calories() < get_healthy_kcal() * 0.95 ||
-+ ( get_hunger() > 160 &&
-+ ( get_stored_kcal() + stomach.get_calories() < get_healthy_kcal() ) ) ) ) {
- if( consume_food_from_camp() ) {
- return npc_noop;
- }
-@@ -3820,13 +3822,14 @@
- return true;
- }
- faction *yours = g->u.get_faction();
-- int camp_kcals = std::min( std::max( 0, 19 * get_healthy_kcal() / 20 - get_stored_kcal() -
-+ int camp_kcals = std::min( std::max( 0, get_healthy_kcal() - get_stored_kcal() -
- stomach.get_calories() ), yours->food_supply );
- if( camp_kcals > 0 ) {
- complain_about( "camp_food_thanks", 1_hours, "<camp_food_thanks>", false );
- mod_hunger( -camp_kcals );
- mod_stored_kcal( camp_kcals );
- yours->food_supply -= camp_kcals;
-+ stomach.mod_calories( camp_kcals );
- return true;
- }
- complain_about( "camp_larder_empty", 1_hours, "<camp_larder_empty>", false );
diff --git a/meds-01_antibiotics-unhealthy.patch b/meds-01_antibiotics-unhealthy.patch
new file mode 100644
index 0000000..9eee550
--- /dev/null
+++ b/meds-01_antibiotics-unhealthy.patch
@@ -0,0 +1,10 @@
+--- a/data/json/items/comestibles/med.json
++++ b/data/json/items/comestibles/med.json
+@@ -86,6 +86,7 @@
+ "stack_size": 200,
+ "symbol": "!",
+ "color": "white",
++ "healthy": -4,
+ "use_action": "ANTIBIOTIC",
+ "flags": [ "NPC_SAFE", "IRREPLACEABLE_CONSUMABLE" ]
+ },
diff --git a/migration-01_remove-ucp.patch b/migration-01_remove-ucp.patch
new file mode 100644
index 0000000..f2488cb
--- /dev/null
+++ b/migration-01_remove-ucp.patch
@@ -0,0 +1,14 @@
+--- a/data/json/obsoletion/migration.json
++++ b/data/json/obsoletion/migration.json
+@@ -784,11 +784,6 @@
+ "flags": [ "HIDDEN_HALLU" ]
+ },
+ {
+- "id": "hk_ucp",
+- "type": "MIGRATION",
+- "replace": "hk_mp7"
+- },
+- {
+ "id": "rechargable_battery",
+ "type": "MIGRATION",
+ "replace": "heavy_battery_cell"
diff --git a/mission-01_typos.patch b/mission-01_typos.patch
new file mode 100644
index 0000000..2558467
--- /dev/null
+++ b/mission-01_typos.patch
@@ -0,0 +1,19 @@
+--- a/src/mission_companion.cpp
++++ b/src/mission_companion.cpp
+@@ -1448,14 +1448,14 @@
+ int monsters = rng( 0, 10 );
+ if( skill * rng_float( .80, 1.2 ) > monsters * rng_float( .8, 1.2 ) ) {
+ if( one_in( 2 ) ) {
+- popup( _( "%s was able to scare off the bear after delivering a nasty "
++ popup( _( "%s was able to scare off the cougar after delivering a nasty "
+ "blow!" ), comp->name );
+ } else {
+ popup( _( "%s beat the cougar into a bloody pulp!" ), comp->name );
+ }
+ } else {
+ if( one_in( 2 ) ) {
+- popup( _( "%s was able to hold off the first wolf but the others that were "
++ popup( _( "%s was able to hold off the first cougar but the others that were "
+ "skulking in the tree line caught up…" ), comp->name );
+ popup( _( "I'm sorry, there wasn't anything we could do…" ) );
+ } else {
diff --git a/mission-02_reorder-gunslinger-quest.patch b/mission-02_reorder-gunslinger-quest.patch
new file mode 100644
index 0000000..037fd86
--- /dev/null
+++ b/mission-02_reorder-gunslinger-quest.patch
@@ -0,0 +1,27 @@
+--- a/data/json/npcs/missiondef.json
++++ b/data/json/npcs/missiondef.json
+@@ -451,7 +451,7 @@
+ "start": { "effect": "follow_only" },
+ "end": { "effect": "stop_following" },
+ "origins": [ "ORIGIN_SECONDARY" ],
+- "followup": "MISSION_KILL_HORDE_MASTER",
++ "followup": "MISSION_RECRUIT_TRACKER",
+ "dialogue": {
+ "describe": "You seem to know this new world better than most…",
+ "offer": "You're kitted out better than most… would you be interested in making this world a little better for the rest of us? The towns have enough supplies for us survivors to start securing a foothold but we don't have anyone with the skills and equipment to thin the masses of undead. I'll lend you a hand to the best of my ability but you really showed promise taking out that other beast. You, I, and a 100 zombies laid to rest, what do you say?",
+@@ -475,7 +475,6 @@
+ "start": "kill_horde_master",
+ "end": { "effect": "stop_following" },
+ "origins": [ "ORIGIN_SECONDARY" ],
+- "followup": "MISSION_RECRUIT_TRACKER",
+ "dialogue": {
+ "describe": "I've heard some bad rumors so I hope you are up for another challenge…",
+ "offer": "Apparently one of the other survivors picked up on an unusually dense horde of undead moving into the area. At the center of this throng there was a 'leader' of some sort. The short of it is, kill the son of a bitch. We don't know what it is capable of or why it is surrounded by other zombies but this thing reeks of trouble. Do whatever it takes but we can't risk it getting away.",
+@@ -670,6 +669,7 @@
+ "update_mapgen": { "place_npcs": [ { "class": "tracker_gunslinger", "x": 11, "y": 11, "target": true } ] }
+ },
+ "origins": [ "ORIGIN_SECONDARY" ],
++ "followup": "MISSION_KILL_HORDE_MASTER",
+ "dialogue": {
+ "describe": "You seem to know this new world better than most…",
+ "offer": "We've got another problem to deal with but I don't think we can handle it on our own. So, I sent word out and found us a volunteer… of sorts. He's vain as hell but has a little skill with firearms. He was supposed to collect whatever he had of value and is going to meet us at a cabin in the woods. Wasn't sure how long we were going to be so I told him to just camp there until we picked him up.",
diff --git a/0016-medical-zombies-called-zombies.patch b/monsters-01_medical-zombies-called-zombies.patch
index fe0b222..f315c99 100644
--- a/0016-medical-zombies-called-zombies.patch
+++ b/monsters-01_medical-zombies-called-zombies.patch
@@ -10,9 +10,9 @@
"default_faction": "zombie",
"bodytype": "human",
@@ -33,7 +33,7 @@
- "id": "mon_zombie_surgeon",
"type": "MONSTER",
"copy-from": "mon_zombie_nurse",
+ "delete": { "categories": [ "CLASSIC" ] },
- "name": { "str": "surgeon" },
+ "name": { "str": "zombie surgeon" },
"description": "A dripping stinger where one hand would be, a set of razor-like claws in place of the other one. This zombie's cold, focused eyes look down at you from above a \"mask\" of melded flesh.",
diff --git a/0017-nerf-lightstep.patch b/mutations-01_nerf-lightstep.patch
index 8fa46cd..c970e02 100644
--- a/0017-nerf-lightstep.patch
+++ b/mutations-01_nerf-lightstep.patch
@@ -9,7 +9,7 @@
"starting_trait": true,
"category": [ "BIRD", "ELFA", "FELINE" ],
"cancels": [ "CLUMSY" ],
-- "noise_modifier": 0.0
+- "noise_modifier": 0
+ "noise_modifier": 0.4
},
{
diff --git a/0022-fix-evac3-background-visible.patch b/mutations-02_fix-evac3-background-visible.patch
index 7c61c9e..7c61c9e 100644
--- a/0022-fix-evac3-background-visible.patch
+++ b/mutations-02_fix-evac3-background-visible.patch
diff --git a/npc-01_isherwood-update.patch b/npc-01_isherwood-update.patch
new file mode 100644
index 0000000..8ab7913
--- /dev/null
+++ b/npc-01_isherwood-update.patch
@@ -0,0 +1,380 @@
+--- a/data/json/npcs/isherwood_farm/NPC_Barry_Isherwood.json
++++ b/data/json/npcs/isherwood_farm/NPC_Barry_Isherwood.json
+@@ -64,7 +64,7 @@
+ {
+ "type": "talk_topic",
+ "id": "TALK_ISHERWOOD_BARRY_TOWER",
+- "dynamic_line": [ "Yeah, I think we need to talk about it, but I'm not ready yet. Let me reclaim my life for a while. " ],
++ "dynamic_line": [ "Yeah, I think we need to talk about it, but I'm not ready yet. Let me reclaim my life for a while." ],
+ "responses": [ { "text": "Sounds good, Barry.", "topic": "TALK_DONE" } ]
+ },
+ {
+@@ -77,7 +77,7 @@
+ "destination": "dairy_farm_isherwood_W",
+ "start": {
+ "effect": [ { "u_add_var": "u_have_barry_escape", "type": "general", "context": "meeting", "value": "yes" } ],
+- "assign_mission_target": { "om_terrain": "dairy_farm_isherwood_W", "reveal_radius": 3 }
++ "assign_mission_target": { "om_terrain": "dairy_farm_isherwood_W", "om_special": "Isherwood Farm", "reveal_radius": 3, "search_range": 240 }
+ },
+ "end": {
+ "opinion": { "trust": 5, "value": 5 },
+--- a/data/json/npcs/isherwood_farm/NPC_Carlos_Isherwood.json
++++ b/data/json/npcs/isherwood_farm/NPC_Carlos_Isherwood.json
+@@ -28,7 +28,7 @@
+ "skill": "ALL",
+ "level": { "mul": [ { "one_in": 3 }, { "sum": [ { "dice": [ 2, 2 ] }, { "constant": -2 }, { "one_in": 4 } ] } ] }
+ },
+- { "skill": "barter", "bonus": { "rng": [ 2, 4 ] } },
++ { "skill": "speech", "bonus": { "rng": [ 2, 4 ] } },
+ { "skill": "melee", "bonus": { "rng": [ 3, 6 ] } },
+ { "skill": "survival", "bonus": { "rng": [ 7, 10 ] } },
+ { "skill": "gun", "bonus": { "rng": [ 4, 8 ] } },
+@@ -47,14 +47,14 @@
+ "responses": [
+ {
+ "text": "Yeah, I'm a Marshal, what are you going to do about it?",
+- "topic": "TALK_LEAVE_NOW",
++ "topic": "TALK_LEAVE_NOW_MARSHAL",
+ "effect": "hostile",
+ "opinion": { "trust": -20, "value": -20 },
+ "condition": { "u_is_wearing": "badge_marshal" }
+ },
+ {
+ "text": "…",
+- "topic": "TALK_LEAVE_NOW",
++ "topic": "TALK_LEAVE_NOW_MARSHAL",
+ "opinion": { "trust": -20, "value": -20 },
+ "condition": { "u_is_wearing": "badge_marshal" }
+ },
+@@ -144,14 +144,8 @@
+ },
+ {
+ "type": "talk_topic",
+- "id": "TALK_LEAVE_NOW",
+- "dynamic_line": "You should get off my farm, I won't deal with a government stooge.",
+- "responses": [ { "text": "…", "topic": "TALK_DONE" } ]
+- },
+- {
+- "type": "talk_topic",
+ "id": "TALK_ISHERWOOD_CARLOS_TOPICS",
+- "dynamic_line": "Go on...",
++ "dynamic_line": "Go on…",
+ "responses": [
+ {
+ "text": "I heard about Barry, can you tell me what captured him?",
+--- a/data/json/npcs/isherwood_farm/NPC_Chris_Isherwood.json
++++ b/data/json/npcs/isherwood_farm/NPC_Chris_Isherwood.json
+@@ -28,7 +28,7 @@
+ "skill": "ALL",
+ "level": { "mul": [ { "one_in": 3 }, { "sum": [ { "dice": [ 2, 2 ] }, { "constant": -2 }, { "one_in": 4 } ] } ] }
+ },
+- { "skill": "barter", "bonus": { "rng": [ 2, 4 ] } },
++ { "skill": "speech", "bonus": { "rng": [ 2, 4 ] } },
+ { "skill": "melee", "bonus": { "rng": [ 3, 6 ] } },
+ { "skill": "survival", "bonus": { "rng": [ 7, 10 ] } },
+ { "skill": "gun", "bonus": { "rng": [ 4, 8 ] } },
+@@ -47,7 +47,7 @@
+ "responses": [
+ {
+ "text": "…",
+- "topic": "TALK_LEAVE_NOW",
++ "topic": "TALK_LEAVE_NOW_MARSHAL_CHRIS",
+ "opinion": { "trust": -20, "value": -20 },
+ "condition": { "u_is_wearing": "badge_marshal" }
+ },
+@@ -137,14 +137,14 @@
+ },
+ {
+ "type": "talk_topic",
+- "id": "TALK_LEAVE_NOW",
++ "id": "TALK_LEAVE_NOW_MARSHAL_CHRIS",
+ "dynamic_line": "You should leave before my family sees you.",
+ "responses": [ { "text": "…", "topic": "TALK_DONE" } ]
+ },
+ {
+ "type": "talk_topic",
+ "id": "TALK_ISHERWOOD_CHRIS_TOPICS",
+- "dynamic_line": "Go on...",
++ "dynamic_line": "Go on…",
+ "responses": [
+ {
+ "text": "Your dad asked me to come find you, said you've been looking for your uncle.",
+--- a/data/json/npcs/isherwood_farm/NPC_Claire_Isherwood.json
++++ b/data/json/npcs/isherwood_farm/NPC_Claire_Isherwood.json
+@@ -28,7 +28,7 @@
+ "skill": "ALL",
+ "level": { "mul": [ { "one_in": 3 }, { "sum": [ { "dice": [ 2, 2 ] }, { "constant": -2 }, { "one_in": 4 } ] } ] }
+ },
+- { "skill": "barter", "bonus": { "rng": [ 2, 4 ] } },
++ { "skill": "speech", "bonus": { "rng": [ 2, 4 ] } },
+ { "skill": "cooking", "bonus": { "rng": [ 4, 8 ] } },
+ { "skill": "firstaid", "bonus": { "rng": [ 3, 6 ] } },
+ { "skill": "survival", "bonus": { "rng": [ 3, 6 ] } },
+@@ -113,13 +113,13 @@
+ "responses": [
+ {
+ "text": "Yes, I'm a marshal.",
+- "topic": "TALK_LEAVE_NOW",
++ "topic": "TALK_LEAVE_NOW_MARSHAL_CLAIRE",
+ "opinion": { "trust": -20, "value": -20 },
+ "condition": { "u_is_wearing": "badge_marshal" }
+ },
+ {
+ "text": "…",
+- "topic": "TALK_LEAVE_NOW",
++ "topic": "TALK_LEAVE_NOW_MARSHAL_CLAIRE",
+ "opinion": { "trust": -20, "value": -20 },
+ "condition": { "u_is_wearing": "badge_marshal" }
+ },
+@@ -251,7 +251,7 @@
+ },
+ {
+ "type": "talk_topic",
+- "id": "TALK_LEAVE_NOW",
++ "id": "TALK_LEAVE_NOW_MARSHAL_CLAIRE",
+ "dynamic_line": "You should get off our land, you have no business here.",
+ "responses": [ { "text": "…", "topic": "TALK_DONE" } ]
+ },
+--- a/data/json/npcs/isherwood_farm/NPC_Eddie_Isherwood.json
++++ b/data/json/npcs/isherwood_farm/NPC_Eddie_Isherwood.json
+@@ -29,7 +29,7 @@
+ "skill": "ALL",
+ "level": { "mul": [ { "one_in": 3 }, { "sum": [ { "dice": [ 2, 2 ] }, { "constant": -2 }, { "one_in": 4 } ] } ] }
+ },
+- { "skill": "barter", "bonus": { "rng": [ 2, 4 ] } },
++ { "skill": "speech", "bonus": { "rng": [ 2, 4 ] } },
+ { "skill": "melee", "bonus": { "rng": [ 3, 6 ] } },
+ { "skill": "survival", "bonus": { "rng": [ 3, 6 ] } },
+ { "skill": "gun", "bonus": { "rng": [ 3, 6 ] } },
+@@ -61,14 +61,14 @@
+ "responses": [
+ {
+ "text": "Yeah, I'm a Marshal, what are you going to do about it?",
+- "topic": "TALK_LEAVE_NOW",
++ "topic": "TALK_LEAVE_NOW_MARSHAL",
+ "effect": "hostile",
+ "opinion": { "trust": -20, "value": -20 },
+ "condition": { "u_is_wearing": "badge_marshal" }
+ },
+ {
+ "text": "…",
+- "topic": "TALK_LEAVE_NOW",
++ "topic": "TALK_LEAVE_NOW_MARSHAL",
+ "opinion": { "trust": -20, "value": -20 },
+ "condition": { "u_is_wearing": "badge_marshal" }
+ },
+@@ -174,14 +174,8 @@
+ },
+ {
+ "type": "talk_topic",
+- "id": "TALK_LEAVE_NOW",
+- "dynamic_line": "You should get off my farm, I won't deal with a government stooge.",
+- "responses": [ { "text": "…", "topic": "TALK_DONE" } ]
+- },
+- {
+- "type": "talk_topic",
+ "id": "TALK_ISHERWOOD_EDDIE_TOPICS",
+- "dynamic_line": "Go on...",
++ "dynamic_line": "Go on…",
+ "responses": [
+ { "text": "Your son helps with the dairy?", "topic": "TALK_EDDIE_LUKE" },
+ { "text": "So, Jesse runs the horse farm?", "topic": "TALK_EDDIE_JESSE" },
+--- a/data/json/npcs/isherwood_farm/NPC_Jack_Isherwood.json
++++ b/data/json/npcs/isherwood_farm/NPC_Jack_Isherwood.json
+@@ -29,7 +29,7 @@
+ "skill": "ALL",
+ "level": { "mul": [ { "one_in": 3 }, { "sum": [ { "dice": [ 2, 2 ] }, { "constant": -2 }, { "one_in": 4 } ] } ] }
+ },
+- { "skill": "barter", "bonus": { "rng": [ 2, 4 ] } },
++ { "skill": "speech", "bonus": { "rng": [ 2, 4 ] } },
+ { "skill": "gun", "bonus": { "rng": [ 4, 8 ] } },
+ { "skill": "melee", "bonus": { "rng": [ 3, 6 ] } },
+ { "skill": "survival", "bonus": { "rng": [ 3, 6 ] } },
+@@ -96,7 +97,7 @@
+ { "item": "cheese_hard", "prob": 50 },
+ { "item": "vinegar", "prob": 55 },
+ { "item": "veggy_pickled", "prob": 50, "charges": 2, "container-item": "jar_glass_sealed" },
+- { "item": "jar_sauerkraut_pickled", "prob": 50 },
++ { "item": "sauerkraut", "prob": 50, "charges": 4, "container-item": "jar_glass_sealed" },
+ { "item": "meat_pickled", "prob": 50, "charges": 2, "container-item": "jar_glass_sealed" },
+ { "item": "fish_pickled", "prob": 60, "charges": 2, "container-item": "jar_glass_sealed" },
+ { "item": "meat_canned", "prob": 40, "charges": 12, "container-item": "jar_3l_glass_sealed" },
+@@ -122,14 +123,14 @@
+ "responses": [
+ {
+ "text": "Yes, I'm a marshal.",
+- "topic": "TALK_LEAVE_NOW",
++ "topic": "TALK_LEAVE_NOW_MARSHAL_JACK",
+ "effect": "hostile",
+ "opinion": { "trust": -20, "value": -20 },
+ "condition": { "u_is_wearing": "badge_marshal" }
+ },
+ {
+ "text": "…",
+- "topic": "TALK_LEAVE_NOW",
++ "topic": "TALK_LEAVE_NOW_MARSHAL_JACK",
+ "opinion": { "trust": -20, "value": -20 },
+ "condition": { "u_is_wearing": "badge_marshal" }
+ },
+@@ -198,7 +199,7 @@
+ {
+ "type": "talk_topic",
+ "id": "TALK_JACK_FARM",
+- "dynamic_line": "Even out here we've had some attacks and seen … other things. We have been working on our defenses, but it takes time. We've been able to keep up with the crops and animals though so we won't have to risk our necks for supplies.",
++ "dynamic_line": "Even out here we've had some attacks and seen… other things. We have been working on our defenses, but it takes time. We've been able to keep up with the crops and animals though so we won't have to risk our necks for supplies.",
+ "responses": [
+ { "text": "What sort of defenses do you want?", "topic": "TALK_FARM_DEFENSE" },
+ { "text": "Let's talk about something else.", "topic": "TALK_ISHERWOOD_JACK_TOPICS" },
+@@ -250,14 +251,14 @@
+ },
+ {
+ "type": "talk_topic",
+- "id": "TALK_LEAVE_NOW",
++ "id": "TALK_LEAVE_NOW_MARSHAL_JACK",
+ "dynamic_line": "You should get off my land, the government proved its incompetence with this catastrophe.",
+ "responses": [ { "text": "…", "topic": "TALK_DONE" } ]
+ },
+ {
+ "type": "talk_topic",
+ "id": "TALK_ISHERWOOD_JACK_TOPICS",
+- "dynamic_line": "Go on ...",
++ "dynamic_line": "Go on…",
+ "responses": [
+ {
+ "text": "I'm here to deliver some resources.",
+--- a/data/json/npcs/isherwood_farm/NPC_Jesse_Isherwood.json
++++ b/data/json/npcs/isherwood_farm/NPC_Jesse_Isherwood.json
+@@ -28,7 +28,7 @@
+ "skill": "ALL",
+ "level": { "mul": [ { "one_in": 3 }, { "sum": [ { "dice": [ 2, 2 ] }, { "constant": -2 }, { "one_in": 4 } ] } ] }
+ },
+- { "skill": "barter", "bonus": { "rng": [ 6, 9 ] } },
++ { "skill": "speech", "bonus": { "rng": [ 6, 9 ] } },
+ { "skill": "melee", "bonus": { "rng": [ 3, 6 ] } },
+ { "skill": "survival", "bonus": { "rng": [ 3, 6 ] } },
+ { "skill": "gun", "bonus": { "rng": [ 3, 6 ] } },
+@@ -51,14 +51,14 @@
+ "responses": [
+ {
+ "text": "Yeah, I'm a Marshal, what are you going to do about it?",
+- "topic": "TALK_LEAVE_NOW",
++ "topic": "TALK_LEAVE_NOW_MARSHAL",
+ "effect": "hostile",
+ "opinion": { "trust": -20, "value": -20 },
+ "condition": { "u_is_wearing": "badge_marshal" }
+ },
+ {
+ "text": "…",
+- "topic": "TALK_LEAVE_NOW",
++ "topic": "TALK_LEAVE_NOW_MARSHAL",
+ "opinion": { "trust": -20, "value": -20 },
+ "condition": { "u_is_wearing": "badge_marshal" }
+ },
+@@ -124,7 +124,7 @@
+ "id": "TALK_MET_JACK_CLAIRE",
+ "dynamic_line": "Oh good, I'm sure Jack wanted to put you to work. If you're interested, I could use a hand clearing out the woods. My son, Chris has his hands full trying to keep the predators under control.",
+ "responses": [
+- { "text": "I'd like to speak with Carlos too about some work.", "topic": "TALK_JESSE_CARLOS" },
++ { "text": "I'd like to speak with Carlos too about some work.", "topic": "TALK_JESSE_CARLOS1" },
+ {
+ "text": "Is Chris around? I'd like to know what he's run into out in the woods.",
+ "topic": "TALK_JESSE_CHRIS"
+@@ -136,7 +136,7 @@
+ },
+ {
+ "type": "talk_topic",
+- "id": "TALK_JESSE_CARLOS",
++ "id": "TALK_JESSE_CARLOS1",
+ "dynamic_line": "He's out back in the workshop.",
+ "responses": [
+ { "text": "Let's talk about something else.", "topic": "TALK_ISHERWOOD_JESSE_TOPICS" },
+@@ -154,7 +154,7 @@
+ },
+ {
+ "type": "talk_topic",
+- "id": "TALK_JESSE_CARLOS",
++ "id": "TALK_JESSE_CARLOS2",
+ "dynamic_line": "Carlos will be in his workshop if he isn't out hunting. He is trying to get a forge set up.",
+ "responses": [
+ { "text": "Let's talk about something else.", "topic": "TALK_ISHERWOOD_JESSE_TOPICS" },
+@@ -163,19 +163,19 @@
+ },
+ {
+ "type": "talk_topic",
+- "id": "TALK_LEAVE_NOW",
++ "id": "TALK_LEAVE_NOW_MARSHAL",
+ "dynamic_line": "You should get off my farm, I won't deal with a government stooge.",
+ "responses": [ { "text": "…", "topic": "TALK_DONE" } ]
+ },
+ {
+ "type": "talk_topic",
+ "id": "TALK_ISHERWOOD_JESSE_TOPICS",
+- "dynamic_line": "Go on...",
++ "dynamic_line": "Go on…",
+ "responses": [
+ { "text": "Looks like you are doing well here.", "topic": "TALK_ISHERWOOD_JESSE_TALK1" },
+ { "text": "Do you have any animal care tips?", "topic": "TALK_ISHERWOOD_JESSE_TIPS" },
+ { "text": "Jack and Claire suggested I come talk to you.", "topic": "TALK_MET_JACK_CLAIRE" },
+- { "text": "I'd like to speak with Carlos too about some work.", "topic": "TALK_JESSE_CARLOS" },
++ { "text": "I'd like to speak with Carlos too about some work.", "topic": "TALK_JESSE_CARLOS2" },
+ { "text": "Is Chris around?", "topic": "TALK_JESSE_CHRIS" },
+ { "text": "Can I do anything for you?", "topic": "TALK_MISSION_LIST" },
+ { "text": "I'd better get going.", "topic": "TALK_DONE" }
+--- a/data/json/npcs/isherwood_farm/NPC_Lisa_Isherwood.json
++++ b/data/json/npcs/isherwood_farm/NPC_Lisa_Isherwood.json
+@@ -45,7 +45,7 @@
+ "responses": [
+ {
+ "text": "…",
+- "topic": "TALK_LEAVE_NOW",
++ "topic": "TALK_LEAVE_NOW_MARSHAL",
+ "opinion": { "trust": -20, "value": -20 },
+ "condition": { "u_is_wearing": "badge_marshal" }
+ },
+@@ -123,17 +123,11 @@
+ {
+ "type": "talk_topic",
+ "id": "TALK_ISHERWOOD_LISA_TOPICS",
+- "dynamic_line": "Go on...",
++ "dynamic_line": "Go on…",
+ "responses": [
+ { "text": "Hi, I'm looking for Jesse.", "topic": "TALK_LISA_JESSE" },
+ { "text": "Hi, I'm looking for Chris.", "topic": "TALK_LISA_CHRIS" },
+ { "text": "I'd better get going.", "topic": "TALK_DONE" }
+ ]
+- },
+- {
+- "type": "talk_topic",
+- "id": "TALK_LEAVE_NOW",
+- "dynamic_line": "You should get off my farm, I won't deal with a government stooge.",
+- "responses": [ { "text": "…", "topic": "TALK_DONE" } ]
+ }
+ ]
+--- a/data/json/npcs/isherwood_farm/NPC_Luke_Isherwood.json
++++ b/data/json/npcs/isherwood_farm/NPC_Luke_Isherwood.json
+@@ -47,7 +47,7 @@
+ "responses": [
+ {
+ "text": "…",
+- "topic": "TALK_LEAVE_NOW",
++ "topic": "TALK_LEAVE_NOW_LUKE",
+ "opinion": { "trust": -20, "value": -20 },
+ "condition": { "u_is_wearing": "badge_marshal" }
+ },
+@@ -135,14 +135,14 @@
+ },
+ {
+ "type": "talk_topic",
+- "id": "TALK_LEAVE_NOW",
++ "id": "TALK_LEAVE_NOW_LUKE",
+ "dynamic_line": "You won't find any help here.",
+ "responses": [ { "text": "…", "topic": "TALK_DONE" } ]
+ },
+ {
+ "type": "talk_topic",
+ "id": "TALK_ISHERWOOD_LUKE_TOPICS",
+- "dynamic_line": "Go on...",
++ "dynamic_line": "Go on…",
+ "responses": [
+ {
+ "text": "Must be tough having the world fall apart when you had you future to look forward to.",
diff --git a/npc-02_tacoma-update.patch b/npc-02_tacoma-update.patch
new file mode 100644
index 0000000..4a3d9b5
--- /dev/null
+++ b/npc-02_tacoma-update.patch
@@ -0,0 +1,177 @@
+--- a/data/json/npcs/tacoma_ranch/NPC_ranch_barber.json
++++ b/data/json/npcs/tacoma_ranch/NPC_ranch_barber.json
+@@ -47,7 +47,7 @@
+ {
+ "type": "talk_topic",
+ "id": "TALK_RANCH_BARBER_CUT",
+- "dynamic_line": "Stand still while I get my clippers...",
++ "dynamic_line": "Stand still while I get my clippers…",
+ "responses": [ { "text": "Thanks…", "topic": "TALK_DONE" } ]
+ }
+ ]
+--- a/data/json/npcs/tacoma_ranch/NPC_ranch_foreman.json
++++ b/data/json/npcs/tacoma_ranch/NPC_ranch_foreman.json
+@@ -122,7 +122,7 @@
+ "place_nested": [ { "chunks": [ "tacoma_commune_west_wall_door" ], "x": 22, "y": 0 } ]
+ },
+ {
+- "om_terrain": "ranch_camp_66",
++ "om_terrain": "ranch_camp_75",
+ "translate_ter": [ { "from": "t_underbrush", "to": "t_dirt", "x": 0, "y": 0 } ],
+ "place_nested": [
+ { "chunks": [ "tacoma_commune_east_wall_door" ], "x": 0, "y": 0 },
+@@ -269,7 +269,7 @@
+ "dialogue": {
+ "describe": "We need help…",
+ "offer": "I'm sure you've noticed the new workers that have started trickling in. The Free Merchant counsel is demanding that we immediately begin projects to become self-sufficient due to limited supplies. We are going to need to rapidly setup an agricultural industry before winter and starvation catches us unprepared and unsupported. In order to get a half dozen shovels and a couple of bags of seeds, we are going to have to trade for it. I've already got the deal lined up but the only thing they are willing to trade it for is salt. I negotiated them down from 500 units to 300… we were hoping you might have access to a source.",
+- "accepted": "Salt is key to preserving meat and other perishables… without any excess food it wouldn't do us much good now but I imagine we'll need to send you out to get more in the future. ",
++ "accepted": "Salt is key to preserving meat and other perishables… without any excess food it wouldn't do us much good now but I imagine we'll need to send you out to get more in the future.",
+ "rejected": "Come back when you get a chance. We need skilled survivors.",
+ "advice": "If you can find a source of salt water you should be able to boil it down.",
+ "inquire": "Do you have the salt?",
+@@ -332,7 +332,7 @@
+ "followup": "MISSION_RANCH_FOREMAN_6",
+ "dialogue": {
+ "describe": "We need help…",
+- "offer": "Well, our first crop will be planted shortly but I'm starting to suspect that our profit margin is going to be much smaller than we expect. With limited seed for our original crop our next course of action is to increase the soil's fertility. Is there any way you could find or produce a basic liquid fertilizer for us? We'd need at least 30 units to make a significant improvement in our output. ",
++ "offer": "Well, our first crop will be planted shortly but I'm starting to suspect that our profit margin is going to be much smaller than we expect. With limited seed for our original crop our next course of action is to increase the soil's fertility. Is there any way you could find or produce a basic liquid fertilizer for us? We'd need at least 30 units to make a significant improvement in our output.",
+ "accepted": "I don't know the exact recipe but I'm sure you could make it from a commercial fertilizer or produce it from bonemeal.",
+ "rejected": "Come back when you get a chance. We need skilled survivors.",
+ "advice": "I'd look through a few basic chemistry books to find a simple recipe.",
+@@ -377,7 +377,7 @@
+ "followup": "MISSION_RANCH_FOREMAN_7",
+ "dialogue": {
+ "describe": "We need help…",
+- "offer": "Our current assessment for survivability has increased significantly thanks to your efforts. The next priority issue is securing a cleaner water source. Drinking from the pond on the back end of the ranch has led to an outbreak of dysentery. As quickly as possible we need to improve the sanitary conditions in the camp. To do so the first step is to dig a well and construct stone fireplaces in the barn for the migrants to boil water. We are going to need at least 75 rocks from you if we hope to accomplish the task before we all get sick. After we have them installed you will have free access to them, guaranteed. ",
++ "offer": "Our current assessment for survivability has increased significantly thanks to your efforts. The next priority issue is securing a cleaner water source. Drinking from the pond on the back end of the ranch has led to an outbreak of dysentery. As quickly as possible we need to improve the sanitary conditions in the camp. To do so the first step is to dig a well and construct stone fireplaces in the barn for the migrants to boil water. We are going to need at least 75 rocks from you if we hope to accomplish the task before we all get sick. After we have them installed you will have free access to them, guaranteed.",
+ "accepted": "If you take a shovel to a pile of rubble you should be able to pull out structural grade stone.",
+ "rejected": "Come back when you get a chance. We need skilled survivors.",
+ "advice": "Mining would always be an option if you had the resources.",
+@@ -475,7 +475,7 @@
+ "dialogue": {
+ "describe": "We need help…",
+ "offer": "With the well's completion we are rapidly closing the sustainability gap. In order to expand from here we will need massive quantities of lumber to construct fortifications and new buildings. We have already begun work on a manually operated sawmill but we will need two motors to control the actual blades. We were hoping you might be able to secure the motors for us.",
+- "accepted": "Power for the motors will be provided by a salvaged truck battery, you need not bring additional mechanical components. ",
++ "accepted": "Power for the motors will be provided by a salvaged truck battery, you need not bring additional mechanical components.",
+ "rejected": "Come back when you get a chance. We need skilled survivors.",
+ "advice": "Motors of this kind are pretty commonplace in industrial machinery.",
+ "inquire": "Do you have the motors?",
+@@ -531,7 +531,7 @@
+ "item": "bleach",
+ "count": 150,
+ "origins": [ "ORIGIN_SECONDARY" ],
+- "followup": "MISSION_RANCH_FOREMAN_10",
++ "followup": "MISSION_RANCH_FOREMAN_10_1",
+ "dialogue": {
+ "describe": "We need help…",
+ "offer": "Disease and infection remains a persistent problem among the refugees. Without dedicated medical personnel and facilities I doubt everyone will be willing to stick around when the next outbreak happens. Until we can get a former medic or nurse I'm just going to have to improvise. Sterilization would be the first step I imagine. Bring me 5 gallon jugs of bleach so we can get started.",
+@@ -560,23 +560,46 @@
+ }
+ },
+ {
++ "id": "MISSION_RANCH_FOREMAN_10_1",
++ "type": "mission_definition",
++ "name": { "str": "Gather 36 bandages" },
++ "goal": "MGOAL_FIND_ITEM",
++ "difficulty": 5,
++ "value": 50000,
++ "item": "bandages",
++ "count": 36,
++ "origins": [ "ORIGIN_SECONDARY" ],
++ "followup": "MISSION_RANCH_FOREMAN_10",
++ "dialogue": {
++ "describe": "We need help…",
++ "offer": "We've started planning a medical clinic but we are going to need a lot more supplies if we hope to warrant sending one of the few people with medical experience from the refugee center to our outpost. I know first aid equipment is rare but they have all the basic supplies that I'm uncertain of. If you could bring in thirty-six bandages I'm sure we could supplement them to make them last a bit longer.",
++ "accepted": "We'll do our best to make them last…",
++ "rejected": "Come back when you get a chance. We need skilled survivors.",
++ "advice": "Homes, hospitals, labs, and doctor offices would be where I'd check.",
++ "inquire": "Do you have the bandages?",
++ "success": "I appreciate it.",
++ "success_lie": "What good does this do us?",
++ "failure": "It was a lost cause anyways…"
++ }
++ },
++ {
+ "id": "MISSION_RANCH_FOREMAN_10",
+ "type": "mission_definition",
+- "name": { "str": "Gather 6 First Aid Kits" },
++ "name": { "str": "Gather 6 bottles of antiseptic" },
+ "goal": "MGOAL_FIND_ITEM",
+ "difficulty": 5,
+ "value": 50000,
+- "item": "1st_aid",
+- "count": 6,
++ "item": "disinfectant",
++ "count": 60,
+ "origins": [ "ORIGIN_SECONDARY" ],
+ "followup": "MISSION_RANCH_FOREMAN_11",
+ "dialogue": {
+ "describe": "We need help…",
+- "offer": "We've started planning a medical clinic but we are going to need a lot more supplies if we hope to warrant sending one of the few people with medical experience from the refugee center to our outpost. I know first aid kits are rare but they have all the basic supplies that I'm uncertain of. If you could bring in 6 full kits I'm sure we could supplement them to make them last a bit longer.",
++ "offer": "We've started planning a medical clinic but we are going to need a lot more supplies if we hope to warrant sending one of the few people with medical experience from the refugee center to our outpost. I know first aid equipment is rare but they have all the basic supplies that I'm uncertain of. If you could bring in 6 bottles of antiseptic I'm sure we could supplement them to make them last a bit longer.",
+ "accepted": "We'll do our best to make them last…",
+ "rejected": "Come back when you get a chance. We need skilled survivors.",
+ "advice": "Homes, hospitals, labs, and doctor offices would be where I'd check.",
+- "inquire": "Do you have the first aid kits?",
++ "inquire": "Do you have the antiseptic?",
+ "success": "I appreciate it.",
+ "success_lie": "What good does this do us?",
+ "failure": "It was a lost cause anyways…"
+@@ -657,7 +680,7 @@
+ "offer": "We have the basic equipment that we need but without a functioning power grid we are forced to rely on the readily available vehicle batteries. This is going to be a chore but I'll need twelve car batteries to swap between charging and powering our equipment. The good news is that they don't need to be charged, we can take care of that.",
+ "accepted": "I'm counting on you.",
+ "rejected": "Come back when you get a chance. We need skilled survivors.",
+- "advice": "Cars can be found in traffic jams along roads or in parking lots… I'm sure you can find a few.",
++ "advice": "Cars can be found in traffic jams along roads or in parking lots… I'm sure you can find a few.",
+ "inquire": "Do you have the car batteries?",
+ "success": "I'm impressed with your abilities.",
+ "success_lie": "What good does this do us?",
+--- a/data/json/npcs/tacoma_ranch/NPC_ranch_guard.json
++++ b/data/json/npcs/tacoma_ranch/NPC_ranch_guard.json
+@@ -14,7 +14,7 @@
+ "id": "TALK_RANCH_GUARD",
+ "type": "talk_topic",
+ "dynamic_line": [
+- "I'm not in charge here, you're looking for someone else...",
++ "I'm not in charge here, you're looking for someone else…",
+ "Keep civil or I'll bring the pain.",
+ "Just on watch, move along.",
+ {
+--- a/data/json/npcs/tacoma_ranch/NPC_ranch_scavenger.json
++++ b/data/json/npcs/tacoma_ranch/NPC_ranch_scavenger.json
+@@ -127,7 +127,7 @@
+ "followup": "MISSION_RANCH_SCAVENGER_4",
+ "dialogue": {
+ "describe": "We need help…",
+- "offer": "When outnumbered or forced to pull back my scavengers have been taught to throw Molotov cocktails to keep monsters from chasing them. We go through one or two on every mission so we can always use a few more. Would you be willing to make us a dozen? I'm willing to pay you what I can for your assistance. ",
++ "offer": "When outnumbered or forced to pull back my scavengers have been taught to throw Molotov cocktails to keep monsters from chasing them. We go through one or two on every mission so we can always use a few more. Would you be willing to make us a dozen? I'm willing to pay you what I can for your assistance.",
+ "accepted": "I'm counting on you.",
+ "rejected": "Come back when you get a chance. We need skilled survivors.",
+ "advice": "Alcohol or lamp oil is probably easier to refine rather than find in large quantities.",
+--- a/data/json/npcs/tacoma_ranch/NPC_ranch_sickly_laborer.json
++++ b/data/json/npcs/tacoma_ranch/NPC_ranch_sickly_laborer.json
+@@ -13,7 +13,7 @@
+ {
+ "type": "talk_topic",
+ "id": "TALK_RANCH_ILL_1",
+- "dynamic_line": "Please leave me alone...",
++ "dynamic_line": "Please leave me alone…",
+ "responses": [
+ { "text": "What is your job here?", "topic": "TALK_RANCH_ILL_1_JOB" },
+ { "text": "Do you need any help?", "topic": "TALK_RANCH_ILL_1_HIRE" },
+@@ -30,13 +30,13 @@
+ {
+ "type": "talk_topic",
+ "id": "TALK_RANCH_ILL_1_HIRE",
+- "dynamic_line": "I don't know what you could do. I've tried everything. Just give me time...",
++ "dynamic_line": "I don't know what you could do. I've tried everything. Just give me time…",
+ "responses": [ { "text": "OK.", "topic": "TALK_RANCH_ILL_1" } ]
+ },
+ {
+ "type": "talk_topic",
+ "id": "TALK_RANCH_ILL_1_SICK",
+- "dynamic_line": "I keep getting sick! At first I thought it was something I ate but now it seems like I can't keep anything down...",
++ "dynamic_line": "I keep getting sick! At first I thought it was something I ate but now it seems like I can't keep anything down…",
+ "responses": [ { "text": "Uhm.", "topic": "TALK_RANCH_ILL_1" } ]
+ }
+ ]
diff --git a/npc-03_godco-update.patch b/npc-03_godco-update.patch
new file mode 100644
index 0000000..f68459e
--- /dev/null
+++ b/npc-03_godco-update.patch
@@ -0,0 +1,886 @@
+--- a/data/json/npcs/godco/NPC_Chloe_Taylor_King.json
++++ b/data/json/npcs/godco/NPC_Chloe_Taylor_King.json
+@@ -0,0 +1,173 @@
++[
++ {
++ "type": "npc",
++ "id": "godco_chloe",
++ "name_unique": "Chloe Taylor King",
++ "gender": "female",
++ "name_suffix": "member",
++ "class": "NC_godco_chloe",
++ "attitude": 0,
++ "mission": 7,
++ "chat": "TALK_GODCO_Chloe_1",
++ "faction": "gods_community"
++ },
++ {
++ "type": "npc_class",
++ "id": "NC_godco_chloe",
++ "name": { "str": "Member" },
++ "job_description": "I am a member of the New England Church Community.",
++ "common": false,
++ "bonus_str": { "rng": [ -3, -2 ] },
++ "bonus_dex": { "rng": [ 0, 2 ] },
++ "bonus_int": { "rng": [ -2, -2 ] },
++ "bonus_per": { "rng": [ 0, 2 ] },
++ "worn_override": "GODCO_chloe_worn",
++ "carry_override": "GODCO_chloe_carried",
++ "weapon_override": "GODCO_chloe_wield",
++ "traits": [ { "group": "NPC_starting_traits" }, { "group": "Skin_Any" }, { "trait": "hair_black_long" } ],
++ "skills": [
++ { "skill": "ALL", "level": { "mul": [ { "one_in": 3 }, { "sum": [ { "dice": [ 2, 2 ] }, { "rng": [ 0, -4 ] } ] } ] } },
++ { "skill": "melee", "bonus": 1 },
++ { "skill": "stabbing", "bonus": 1 }
++ ]
++ },
++ {
++ "type": "item_group",
++ "id": "GODCO_chloe_worn",
++ "subtype": "collection",
++ "entries": [
++ { "item": "sports_bra" },
++ { "item": "boxer_shorts" },
++ { "item": "socks" },
++ { "item": "tshirt_text" },
++ { "item": "skirt" },
++ { "item": "sneakers" },
++ { "item": "gloves_light" },
++ { "item": "knit_scarf" },
++ { "item": "holy_symbol_wood" },
++ { "item": "hat_knit", "prob": 50 },
++ { "item": "coat_rain" }
++ ]
++ },
++ {
++ "type": "item_group",
++ "id": "GODCO_chloe_carried",
++ "subtype": "collection",
++ "entries": [ { "item": "portable_game" }, { "item": "lemonlime" } ]
++ },
++ {
++ "type": "item_group",
++ "id": "GODCO_chloe_wield",
++ "subtype": "collection",
++ "entries": [ { "item": "knife_combat" } ]
++ },
++ {
++ "type": "talk_topic",
++ "id": [
++ "TALK_GODCO_Chloe_2",
++ "TALK_GODCO_Chloe_Story",
++ "TALK_GODCO_Chloe_Mood",
++ "TALK_GODCO_Chloe_Help",
++ "TALK_GODCO_Chloe_Sonia",
++ "TALK_GODCO_Chloe_Knife"
++ ],
++ "responses": [
++ { "text": "What's your story?", "topic": "TALK_GODCO_Chloe_Story" },
++ { "text": "What's your take on the situation here?", "topic": "TALK_GODCO_Chloe_Mood" },
++ { "text": "Who takes care of you here?", "topic": "TALK_GODCO_Chloe_Help" }
++ ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_GODCO_Chloe_1",
++ "dynamic_line": {
++ "u_has_var": "u_met_godco_chloe",
++ "type": "general",
++ "context": "meeting",
++ "value": "yes",
++ "yes": "Aw hey, it's you again.",
++ "no": "Oh… hi. I don't know you. My name's Chloe."
++ },
++ "responses": [
++ {
++ "text": "Nice to meet you, kid. What's up?",
++ "effect": { "u_add_var": "u_met_godco_chloe", "type": "general", "context": "meeting", "value": "yes" },
++ "condition": { "not": { "u_has_var": "u_met_godco_chloe", "type": "general", "context": "meeting", "value": "yes" } },
++ "topic": "TALK_GODCO_Chloe_2"
++ },
++ {
++ "text": "Hello, Chloe. What's up?",
++ "topic": "TALK_GODCO_Chloe_2",
++ "condition": { "u_has_var": "u_met_godco_chloe", "type": "general", "context": "meeting", "value": "yes" }
++ },
++ { "text": "Hi, Chloe. I can't stay to talk.", "topic": "TALK_DONE" }
++ ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_GODCO_Chloe_2",
++ "dynamic_line": "Things suck right now, but you know that anyway. I don't even know why you bother asking these stupid questions.",
++ "responses": [ { "text": "I'd better get going.", "topic": "TALK_DONE" } ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_GODCO_Chloe_Story",
++ "dynamic_line": "You're creepy. I'm sorry for your lack of friends but, like, I'm literally a kid. Everyone on Earth turned into a zombie, we're running out of toilet paper and everything, and my parents are gone. I know they're still alive and they're looking for me. I miss them. Is that enough personal stuff for you?",
++ "responses": [
++ { "text": "I'm sorry for your loss. What were you saying before?", "topic": "TALK_GODCO_Chloe_Loss" },
++ { "text": "I'm sorry for your loss. I'd better get going.", "topic": "TALK_GODCO_Chloe_Loss" }
++ ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_GODCO_Chloe_Loss",
++ "dynamic_line": "They are not dead.",
++ "responses": [ { "text": "…", "topic": "TALK_DONE" } ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_GODCO_Chloe_Mood",
++ "dynamic_line": "I told you already: it sucks. Nobody's happy here, everyone's hungry, Sonia's songs are getting repetitive, and turns out, the boogeyman is friggin' real. We can hear it screaming every night.",
++ "responses": [
++ { "text": "What were you saying before?", "topic": "TALK_NONE" },
++ { "text": "I'd better get going.", "topic": "TALK_DONE" }
++ ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_GODCO_Chloe_Help",
++ "dynamic_line": "I'm not a baby, you know? I don't need a babysitter. Sonia looks out for me though. She's not so weird, I guess. She promised to give me guitar lessons and she even signed me an autograph. I know she's only nice to me because I saved her, but that's okay; we're equal now.",
++ "responses": [
++ {
++ "text": "Saving Sonia sounds like an interesting story; can you tell me what happened?",
++ "topic": "TALK_GODCO_Chloe_Sonia"
++ },
++ { "text": "Aren't you a bit too young to be carrying a knife?", "topic": "TALK_GODCO_Chloe_Knife" },
++ { "text": "What were you saying before?", "topic": "TALK_NONE" },
++ { "text": "I'd better get going.", "topic": "TALK_DONE" }
++ ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_GODCO_Chloe_Sonia",
++ "dynamic_line": "I was home alone during the ongoing riots. My parents chose the worst possible time to reconnect, which sucks, but I'm also kinda happy for them. Anyway, they were part of the NECC people, so they knew about this place and their plans and all. Thing is, it was, like, really far away. I kinda didn't want to go alone but I also didn't want the rioters to eat me, so I asked Sonia - my neighbor - to evacuate with me, I guess. So that was fun; escaping my hometown, walking down the country road, waiting for a horror to ambush us. Spoiler alert: we were attacked. So this zombie shambles in front of us and Sonia whacks it real hard with her guitar! Its brain splatters all over the pavement, and it was super cool, but I also vomited because it was really disgusting. We got here soon after that. My parents weren't here, obviously. Oh man, they must worry about me so much…",
++ "responses": [
++ { "text": "Aren't you a bit too young to be carrying a knife?", "topic": "TALK_GODCO_Chloe_Knife" },
++ { "text": "Thanks for telling me that. What were you saying before?", "topic": "TALK_NONE" },
++ { "text": "Thanks for telling me that. I'd better get going.", "topic": "TALK_DONE" }
++ ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_GODCO_Chloe_Knife",
++ "dynamic_line": "Aren't you a bit too old not to realize how dangerous the world is for a kid like me? I know how to handle one without hurting myself! My dad taught me everything, he's a real pro.",
++ "responses": [
++ {
++ "text": "Saving Sonia sounds like an interesting story; can you tell me what happened?",
++ "topic": "TALK_GODCO_Chloe_Sonia"
++ },
++ { "text": "What were you saying before?", "topic": "TALK_NONE" },
++ { "text": "I'd better get going.", "topic": "TALK_DONE" }
++ ]
++ }
++]
+--- a/data/json/npcs/godco/NPC_Sonia_Greene.json
++++ b/data/json/npcs/godco/NPC_Sonia_Greene.json
+@@ -0,0 +1,163 @@
++[
++ {
++ "type": "npc",
++ "id": "godco_sonia",
++ "name_unique": "Sonia Greene",
++ "name_suffix": "joinee",
++ "gender": "female",
++ "class": "NC_godco_sonia",
++ "attitude": 0,
++ "mission": 7,
++ "chat": "TALK_GODCO_Sonia_1",
++ "faction": "gods_community"
++ },
++ {
++ "type": "npc_class",
++ "id": "NC_godco_sonia",
++ "name": { "str": "Joinee" },
++ "job_description": "I'm just trying to survive.",
++ "common": false,
++ "bonus_str": { "rng": [ -3, -1 ] },
++ "bonus_dex": { "rng": [ -1, 1 ] },
++ "bonus_int": { "rng": [ -2, 2 ] },
++ "bonus_per": { "rng": [ 0, 1 ] },
++ "worn_override": "GODCO_sonia_worn",
++ "carry_override": "GODCO_sonia_carried",
++ "weapon_override": "GODCO_sonia_wield",
++ "traits": [
++ { "trait": "PRETTY" },
++ { "trait": "PACIFIST" },
++ { "group": "NPC_starting_traits" },
++ { "trait": "SKIN_LIGHT" },
++ { "trait": "hair_blond_long" }
++ ],
++ "skills": [ { "skill": "speech", "bonus": { "rng": [ 3, 4 ] } }, { "bonus": 1, "skill": "bashing" } ]
++ },
++ {
++ "type": "item_group",
++ "id": "GODCO_sonia_worn",
++ "subtype": "collection",
++ "entries": [
++ { "item": "socks" },
++ { "item": "sneakers" },
++ { "item": "briefs" },
++ { "item": "bra" },
++ { "item": "tshirt_tour" },
++ { "item": "pants_cargo" },
++ { "item": "leather_belt" },
++ { "item": "trenchcoat_leather" },
++ { "item": "wristwatch" },
++ { "item": "bead_bracelet" }
++ ]
++ },
++ {
++ "type": "item_group",
++ "id": "GODCO_sonia_carried",
++ "subtype": "collection",
++ "entries": [ { "item": "smart_phone", "ammo-item": "battery", "charges": 120 }, { "group": "snacks", "count": [ 1, 2 ] } ]
++ },
++ {
++ "type": "item_group",
++ "id": "GODCO_sonia_wield",
++ "subtype": "collection",
++ "entries": [ { "item": "acoustic_guitar", "damage": 1 } ]
++ },
++ {
++ "type": "talk_topic",
++ "id": [
++ "TALK_GODCO_Sonia_2",
++ "TALK_GODCO_Sonia_Guitar",
++ "TALK_GODCO_Sonia_Story",
++ "TALK_GODCO_Sonia_Story1",
++ "TALK_GODCO_Sonia_Mood",
++ "TALK_GODCO_Sonia_Firstmeet",
++ "TALK_GODCO_Sonia_Community"
++ ],
++ "responses": [
++ { "text": "So, how did you get here?", "topic": "TALK_GODCO_Sonia_Story" },
++ { "text": "How are things, living here?", "topic": "TALK_GODCO_Sonia_Mood" },
++ { "text": "Are the non-joinees treating you fairly?", "topic": "TALK_GODCO_Sonia_Community" },
++ { "text": "That's a nice guitar you have.", "topic": "TALK_GODCO_Sonia_Guitar" }
++ ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_GODCO_Sonia_1",
++ "dynamic_line": {
++ "u_has_var": "u_met_godco_sonia",
++ "type": "general",
++ "context": "meeting",
++ "value": "yes",
++ "yes": "Well now, good to see you again, friend.",
++ "no": "Good to see people like you in the world. I'm Sonia, Sonia Greene. I entertain the people."
++ },
++ "responses": [
++ {
++ "text": "Sonia, hey? Nice to meet you. How are things here?",
++ "effect": { "u_add_var": "u_met_godco_sonia", "type": "general", "context": "meeting", "value": "yes" },
++ "condition": { "not": { "u_has_var": "u_met_godco_sonia", "type": "general", "context": "meeting", "value": "yes" } },
++ "topic": "TALK_GODCO_Sonia_Mood"
++ },
++ {
++ "text": "Hey, Sonia. What's up?",
++ "condition": { "u_has_var": "u_met_godco_sonia", "type": "general", "context": "meeting", "value": "yes" },
++ "topic": "TALK_GODCO_Sonia_2"
++ },
++ { "text": "Hey, Sonia. I can't stay to talk.", "topic": "TALK_DONE" }
++ ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_GODCO_Sonia_2",
++ "dynamic_line": [
++ "Just playing some good ol' tunes. There's so much negativity around here, someone's gotta cheer the people up, you know?"
++ ],
++ "responses": [ { "text": "I'd better get going.", "topic": "TALK_DONE" } ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_GODCO_Sonia_Guitar",
++ "dynamic_line": "You are damn right. I like its scars, makes it look like it has a history, you know? We've been through a lot, him and I. Those pesky <zombies> forced me to inflict harm on my sweet, sweet guitar. But I retaliated, and bashed their head in! I lost a part of me that day, yeah. The guitar's all right, thank you very much. Just a bit rusted from all that blood and gore.",
++ "responses": [
++ { "text": "What were you saying before?", "topic": "TALK_NONE" },
++ { "text": "I'd better get going.", "topic": "TALK_DONE" }
++ ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_GODCO_Sonia_Story",
++ "dynamic_line": "Now that's a wild, wild story. I owe my life to this kid, Chloe, really. I'll let her tell the tale.",
++ "responses": [
++ { "text": "What did you do before <the_cataclysm>?", "topic": "TALK_GODCO_Sonia_Story1" },
++ { "text": "What were you saying before?", "topic": "TALK_NONE" },
++ { "text": "I'd better get going.", "topic": "TALK_DONE" }
++ ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_GODCO_Sonia_Story1",
++ "dynamic_line": "I was in an underground band - Taurists was our name - before all this. Performing gigs at local venues, jamming with my friends; that's all my life was about. Now, I'm a badass soloist with a war-torn guitar, a singer of the old-world, preserving the wonders of music and the Taurist legacy for generations to come. That's also a synonym for not having all that much going on in my life, yeah.",
++ "responses": [
++ { "text": "What were you saying before?", "topic": "TALK_NONE" },
++ { "text": "I'd better get going.", "topic": "TALK_DONE" }
++ ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_GODCO_Sonia_Mood",
++ "dynamic_line": "Oh, you know, just fine. A bit malnourished and all, but I can't really complain if that's the worst of it, right? My guitar makes our twisted little world a bit more tolerable, though. Takes my mind off stuff, muffles the screams of the boogeyman, you know?",
++ "responses": [
++ { "text": "What were you saying before?", "topic": "TALK_NONE" },
++ { "text": "I'd better get going.", "topic": "TALK_DONE" }
++ ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_GODCO_Sonia_Community",
++ "dynamic_line": "Fairly? There's no such thing as fairness in the world. The NECC wouldn't give a damn if I starved to death on this very bench. At least I have friends here, ones that appreciate what I do. I make music. That's all I have left, and it means everything to me.",
++ "responses": [
++ { "text": "What were you saying before?", "topic": "TALK_NONE" },
++ { "text": "I'd better get going.", "topic": "TALK_DONE" }
++ ]
++ }
++]
+--- a/data/json/npcs/godco/NPC_Zachary_Montes.json
++++ b/data/json/npcs/godco/NPC_Zachary_Montes.json
+@@ -0,0 +1,178 @@
++[
++ {
++ "type": "npc",
++ "id": "godco_zachary",
++ "name_unique": "Zachary Montes",
++ "name_suffix": "joinee",
++ "gender": "male",
++ "class": "NC_godco_zachary",
++ "attitude": 0,
++ "mission": 7,
++ "chat": "TALK_GODCO_Zachary_1",
++ "faction": "gods_community"
++ },
++ {
++ "type": "npc_class",
++ "id": "NC_godco_zachary",
++ "name": { "str": "Joinee" },
++ "job_description": "I'm just trying to survive.",
++ "common": false,
++ "bonus_str": { "rng": [ 0, 2 ] },
++ "bonus_dex": { "rng": [ 0, 2 ] },
++ "bonus_int": { "rng": [ -1, 1 ] },
++ "bonus_per": { "rng": [ -1, 1 ] },
++ "worn_override": "GODCO_zachary_worn",
++ "carry_override": "GODCO_zachary_carried",
++ "weapon_override": "GODCO_zachary_wield",
++ "traits": [ { "group": "NPC_starting_traits" }, { "group": "Appearance_demographics" }, { "trait": "FACIAL_HAIR_BEARD" } ],
++ "skills": [
++ { "bonus": 1, "skill": "melee" },
++ { "bonus": 2, "skill": "cutting" },
++ { "bonus": 2, "skill": "survival" },
++ { "bonus": 3, "skill": "bashing" },
++ { "bonus": 4, "skill": "fabrication" }
++ ]
++ },
++ {
++ "type": "item_group",
++ "id": "GODCO_zachary_worn",
++ "subtype": "collection",
++ "entries": [
++ { "item": "socks" },
++ { "item": "boots" },
++ { "item": "boxer_shorts" },
++ { "item": "jeans" },
++ { "item": "undershirt" },
++ { "item": "leather_belt" },
++ { "item": "gloves_work" },
++ { "item": "gold_ear" },
++ { "item": "hat_hard_hooded" }
++ ]
++ },
++ {
++ "type": "item_group",
++ "id": "GODCO_zachary_carried",
++ "subtype": "collection",
++ "entries": [ { "item": "nail" }, { "item": "hammer" } ]
++ },
++ {
++ "type": "item_group",
++ "id": "GODCO_zachary_wield",
++ "subtype": "collection",
++ "entries": [ { "item": "fire_ax" } ]
++ },
++ {
++ "type": "talk_topic",
++ "id": [
++ "TALK_GODCO_Zachary_2",
++ "TALK_GODCO_Zachary_Story",
++ "TALK_GODCO_Zachary_Mood",
++ "TALK_GODCO_Zachary_Result_rewardIcon",
++ "TALK_GODCO_Zachary_Result_rewardRation",
++ "TALK_GODCO_Zachary_Community",
++ "TALK_GODCO_Zachary_Firstmeet",
++ "TALK_GODCO_Zachary_Story1"
++ ],
++ "responses": [
++ { "text": "So, how did you get here?", "topic": "TALK_GODCO_Zachary_Story" },
++ { "text": "How are things, living here?", "topic": "TALK_GODCO_Zachary_Mood" },
++ { "text": "Are the non-joinees treating you fairly?", "topic": "TALK_GODCO_Zachary_Community" }
++ ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_GODCO_Zachary_1",
++ "dynamic_line": "I got my rights to be here, chum. Squatter's rights!",
++ "responses": [
++ {
++ "text": "Don't worry, I'm not going to hurt you.",
++ "effect": { "u_add_var": "u_met_godco_zachary", "type": "general", "context": "meeting", "value": "yes" },
++ "condition": { "not": { "u_has_var": "u_met_godco_zachary", "type": "general", "context": "meeting", "value": "yes" } },
++ "topic": "TALK_GODCO_Zachary_Firstmeet"
++ },
++ {
++ "text": "Hey, good to see you're still around.",
++ "condition": { "u_has_var": "u_met_godco_zachary", "type": "general", "context": "meeting", "value": "yes" },
++ "topic": "TALK_GODCO_Zachary_2"
++ },
++ { "text": "…", "topic": "TALK_DONE" }
++ ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_GODCO_Zachary_Firstmeet",
++ "dynamic_line": "I got here first, therefore this place belongs to me. Them's the rules in the Cataclysm.",
++ "responses": [ { "text": "Now that's an archaic belief. I'll see you around.", "topic": "TALK_DONE" } ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_GODCO_Zachary_2",
++ "dynamic_line": [ "I ain't leaving, bruv. Not until that eldritch screechin' nightmare is dead 'n buried." ],
++ "responses": [ { "text": "I'll see you around then.", "topic": "TALK_DONE" } ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_GODCO_Zachary_Story",
++ "dynamic_line": "That ain't the point here, chum. Don'tcha get it? This was MY territory, but they took it away from me. Now they think of us as nothin' but a goddamn nuisance.",
++ "responses": [
++ { "text": "What did you do before <the_cataclysm>?", "topic": "TALK_GODCO_Zachary_Story1" },
++ { "text": "What were you saying before?", "topic": "TALK_NONE" },
++ { "text": "I'd better get going.", "topic": "TALK_DONE" }
++ ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_GODCO_Zachary_Story1",
++ "dynamic_line": "Who I was is gone, dead… died when I put down the monsters wearing the face of my friends. Ever since then, I've felt nothing but disgust for myself. Let's not fuckin' reminisce.",
++ "responses": [
++ { "text": "What were you saying before?", "topic": "TALK_NONE" },
++ { "text": "I'd better get going.", "topic": "TALK_DONE" }
++ ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_GODCO_Zachary_Community",
++ "dynamic_line": "They are nice people, lettin' us crash here 'n all. I got friends here. We may not be members but we belong here. We'll fight together if they ever try to kick us out.",
++ "responses": [
++ { "text": "What were you saying before?", "topic": "TALK_NONE" },
++ { "text": "I'd better get going.", "topic": "TALK_DONE" }
++ ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_GODCO_Zachary_Mood",
++ "dynamic_line": "It ain't so bad. I got shelter, heat, and people to defend me if any <zombie> shuffles its way here. If I want to eat then I'll be doin' construction work from dusk till dawn.",
++ "responses": [
++ {
++ "text": "How have things changed after that deal with Helena?",
++ "topic": "TALK_GODCO_Zachary_Result_rewardIcon",
++ "condition": { "u_has_var": "godco_machine_reward", "type": "mission", "context": "reward", "value": "icon" }
++ },
++ {
++ "text": "How have things changed after that deal with Helena?",
++ "topic": "TALK_GODCO_Zachary_Result_rewardRation",
++ "condition": { "u_has_var": "godco_machine_reward", "type": "mission", "context": "reward", "value": "ration" }
++ },
++ { "text": "What were you saying before?", "topic": "TALK_NONE" },
++ { "text": "I'd better get going.", "topic": "TALK_DONE" }
++ ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_GODCO_Zachary_Result_rewardRation",
++ "dynamic_line": "Food is the only thing a starving man needs. Thanks for the help, bruv.",
++ "responses": [
++ { "text": "What were you saying before?", "topic": "TALK_NONE" },
++ { "text": "I'd better get going.", "topic": "TALK_DONE" }
++ ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_GODCO_Zachary_Result_rewardIcon",
++ "dynamic_line": "Ha ha ha! Think before you speak, chum. Eight icons for an honest day's work. The system's broken!",
++ "responses": [
++ { "text": "Sorry to hear that. What were you saying before?", "topic": "TALK_NONE" },
++ { "text": "No rest for the weary…", "topic": "TALK_DONE" }
++ ]
++ }
++]
+--- a/data/json/npcs/godco/cook.json
++++ b/data/json/npcs/godco/cook.json
+@@ -184,7 +184,7 @@
+ {
+ "type": "talk_topic",
+ "id": "TALK_GODCO_cook_currency",
+- "dynamic_line": "We use religious icons as our currency. These were made before <the_cataclysm>, and the name of our community is written on the back. It's a lot more handy than old-world dollars, those are basicly just firestarters here.",
++ "dynamic_line": "We use religious icons as our currency. These were made before <the_cataclysm>, and the name of our community is written on the back. It's a lot more handy than old-world dollars, those are basically just firestarters here.",
+ "responses": [
+ { "text": "Oh, okay.", "topic": "TALK_GODCO_cook_1" },
+ { "text": "What can I buy here?", "topic": "TALK_GODCO_cook_ask_goods" }
+@@ -209,8 +209,8 @@
+ "rejected": "It's okay, I can do without them. Just let me know if you reconsider.",
+ "advice": "There's a lot of places to look. They are common in house kitchens, restaurants or grocery stores.",
+ "inquire": "How is the search going? Have you found 'em?",
+- "success": "I really apreciate your help. Don't worry, you won't leave empty-handed.",
+- "success_lie": "Thanks for trying… I guess.",
++ "success": "I really appreciate your help. Don't worry, you won't leave empty-handed.",
++ "success_lie": "Thanks for trying… I guess.",
+ "failure": "Don't worry about it, it's not that important."
+ },
+ "end": { "effect": [ { "u_buy_item": "icon", "count": 2 } ] }
+@@ -232,10 +232,10 @@
+ "offer": "This task is bit more serious. I don't have enough jars to preserve perishables for the future, and we can't just store everything in salt. We could do our own canning if we had some more glass jars. I could get by with 5 for now.",
+ "accepted": "Thanks for accepting this task. It'll take a load off my shoulders. I finally won't have to worry about this problem anymore.",
+ "rejected": "Just let me know if you change your mind.",
+- "advice": "Glass jars are not that hard to find. I'd look for them in residental areas.",
++ "advice": "Glass jars are not that hard to find. I'd look for them in residential areas.",
+ "inquire": "Have you found the jars?",
+ "success": "Thank you for your help. Here's your reward. I have one more task to do.",
+- "success_lie": "Thanks for trying… I guess.",
++ "success_lie": "Thanks for trying… I guess.",
+ "failure": "It's not a big deal, it isn't that urgent."
+ },
+ "end": { "effect": [ { "u_buy_item": "icon", "count": 5 } ] }
+@@ -259,7 +259,7 @@
+ "advice": "Butcher knives are not that rare to find. They are commonly found in kitchens.",
+ "inquire": "Do you have that knife now?",
+ "success": "I am grateful for the help you've done.",
+- "success_lie": "Thanks for trying… I guess.",
++ "success_lie": "Thanks for trying… I guess.",
+ "failure": "Don't worry about it, it's not that important."
+ },
+ "end": { "effect": [ { "u_buy_item": "icon", "count": 3 } ] }
+--- a/data/json/mapgen/cground3x3.json
++++ b/data/json/mapgen/cground3x3.json
+@@ -22,83 +22,120 @@
+ ],
+ "fill_ter": "t_floor",
+ "rows": [
+- ",7,,,,,,7,*,,7,,,7,,*,7,,7,,7,* _________ 7 ,,,7,*,7,,,7,,,,*7,,,*,,",
+- ",,,,*7,,||||v||||||v|||,*,,,,7, _________ *,,,7,,,,,,,*,,,,7,,,,*,7,*",
+- "7,,*,G,7|^.fff.^|ddddd|,,7,*, __________7* ,,7,,,,,*,,7,,,,,*,,,,7,,,,7",
+- ",,G,,,,t|.d.?..X|d..hdv7,, __________ ||||||||||||||vv||vv||vv||||,",
+- "G* G,G*|.dddd.Y|dh..dv,,*, ___________F |???|T+.a|^...............^|7",
+- " 7 ,v..?.?..|.....v,,,,* ___________ v?.?|||.S|.bnb.bnb.bnb.bnb.v,",
+- ",G G G 7v.......+.ff.g|,,7, ____________ v...|T+.S|.bnb.bnb.bnb.bnb.v*",
+- ",* G|hh..bbb|.||+||,,, ____________F |..n|||.S|.bnb|bnb.bnb.bnb.|7",
+- "G,G G G,||||+||||+|..Y||| _____________ ||..n|T+..|.bnb.bnb.bnb.bnb.||",
+- "7 * ,,|???.|ST|.d.....|_______________ *|^...|||+||..................|",
+- " G G *G|?n..|..|hd.....+ _____________ |.........|Y.bbbb.bbbb....nh.v",
+- "G G |?...|a.|fd...bb| _______________+..g......+..nnnn.nnnn....nh.v",
+- "7,G G G|...^||+|||^..||| _____________ |+||||||+||..bbbb.bbbb....nh.v",
+- "G,*; *,,|a.......g||+||*, _____________ |<..OOcc.a|a.................|",
+- ",7 ;;G7*v..hh|fh..@@.M|7,* _____________ |||.......U.....bnb.bnb.bnb.||",
+- ",*G ;*,,v..nn|fdd....Mv,,,,____________ F*|e.SSsu..U....|bnb.bnb.bnb.|7",
+- "7, ; G,7|c.hh|df@.@@.@v,*,7,___________ *ve.cccu..U.....bnb.bnb.bnb.v,",
+- ",,*; ,*,|u...|dh@....@v,,,,,__________* vu.......U.....bnb.bnb.bnb.v*",
+- ",7 ;;7,*|uSOe|dh^.@@.a|,7,*,__________ F |uucccu..|.$$.............^|,",
+- ",*, ;;,7|||||||||||v|||,,*,*__________ * ||||||||+|+|||vv||vv||vv||||,",
+- "*,,* ;;;; *,,*7,,7,*,7,*,,,7,_________ * HDDD_|<....| ;; ; ,,7",
+- "7,,,* ;;;;;;;;*,,,,7,7,,7,*,, _____________m____+..hnh| ooooooooooooo ,",
+- ",*,7,,,*7, ;;;;;;;;; *,*,,*,7, ________ *,,HR_DD|..hnh| ;; ",
+- "*,,,,7,,*,7,,7,* ;;;;;;7,*,,,, ________ ,,7,HHHHH|||v||| ooooooooooooooo",
+- ",7,*,,,7,7,*,,,7,,*,7;;;;;7,*,________,,*,*,,7,,7 ; ;; ; ;; ",
+- ",*,,,7,*,,*,7*,,,7,,*,, ;;;;7,________7,*,,,*, ; oooooooooooooooooooo ",
+- "*7,7,,*,,7,,*,7,*,,7,,*,7 ;;;;________*,,7*,7 ; ; ;; ; ",
+- ",,*,,,7,*,t*7,*,,7*,*7,,,*,,7________7*,,,* ooooooooooooooooooooooooo,*",
+- "||vvv||vv||vvv|||||||,,*,,7,,________,,,*7, ;; ; ; ;; ,7,",
+- "|^....a..Y....^|llll|*,7,,,*,________*,,,* oooooooooooooooooooooooooo,,,",
+- "|.l@@..h...@@l.|....|7,,,*,,7________,7,,; ; ;; ; ; *,7",
+- "v.....bnnb.....|.lll|,*,7,7,___________* oooooooooooooooooooooooooooo ,",
+- "|.l@@.bnnb.@@l.|+||||,7,,,*,_____________ ; ; ;; ; ;; ",
+- "|.....h.h......|.???|*,,7,7,________*,,*_oooooooooooooooooooooooooooooo ",
+- "|.l@@......@@l.....?|,7,,*,*________,7, _ ;; ; ; ;; ; ",
+- "v......h............v*,,7,,________*,*,, oooooooooooooooooooooooooooooo",
+- "|.l@@.bnnb.@@l.nn..^|7,,*,*________7,,*,7 ; ; ; ;; ; ",
+- "|.....bnnb.....||++||,,7,__________*,7,,,* ooooooooooooooooooooooooooooo",
+- "|.l@@...h..@@l.| __ *,*, ___________,*,*7,* ; ; ;; ; * ",
+- "v.....h........v __ 7 _____________*,,*,,*, ooooooooooooooooooooo 7,, ",
+- "|^...^....????.|* __________________7,*,,7,,,,7,,7 ; ;; ,,*,7,*,,7",
+- "|||+|||++|||||||,,, _____*,*7_______,*7,,*,*,,,*,,*ooooooooo,7,,,,*,,*,",
+- " |h.p|....|,*7,,,*,, ___*,,,,____BBBB,,*7,,7,*7,,7,,,7,*7,*,,*,,7,,,7,,",
+- " |.h.|?..nv*,,*,7,,*,____,,7*,,___NNNN7*,,7,,,,*,,,,* *,,*,,7*,,*,*,*,,7",
+- " |h.L|?..nv,7,,*,*7,,___,7*,,7*___BBBB,,7,,*,7,,,*,,7,,,7,,*,*,7,,,7,*,,",
+- " |h.L|^...|,*,7,7*,,*___*,,,*,,_______,*,,7, *,,7*,*,,7,,*,,7,,,*,,,,,7,",
+- "|||+|||++|||||||,,*, ___,,*7,________,,7,,,*,7,*,,,7,,,*,,,*,,7,,,7* 7,,",
+- "|nn..a....???.^|*7, ____________i__ *,,,,*,,,*7,,*,,*,7,||vv||||v|||,,*",
+- "v..............v, __________________ * 7,,*,*,,7,,7,*,,|euuO|h..@@|,7,",
+- "|.l@@..bb..@@l.| __ __________________* *,,7,,*, ______+....+...hl|,*,",
+- "|......nnh.....||++||,7* BNB_____________ , _______ |n..?|n...l|,,7",
+- "|.l@@.hnn..@@l.Y...^|7,,7* BNB_____BNB_____________ ,,,|n..?|n..@@|*,,",
+- "v......bb...........v,*,*,7 BNB ___ BNB *, ______ *,,7,*||h.?|||||||,*,",
+- "|.l@@......@@l.....?|,7,,,* BNB __* BNB ,7*,,,*,,,7,,*,,7,|...+...@@|*7,",
+- "|......bb......|.???|*,*,,7*, ___7 BNB*,,,7*,7,,,,*7,,,*,v...|h...l|,,*",
+- "|.l@@..nnh.@@l.|+||||7,,,*,,7* __*,, *,,7*,,,,*,,*,,,*,7,,|a.^|nn..l|7,7",
+- "v.....hnn......|.lll|,*,,7,,*, __,7*,,*,,,7,,*,,,7,,,,,*,7||+||.h.@@|,7,",
+- "|.l@@..bb..@@l.|....|*,7*,,, ,7___,,*7 7*,,*7,,7,,*,,,7,,,|n.h|||||||7,*",
+- "|^.......h....^|llll|7,*,,7,*,* __*,,,*,,7,,*,,,,,7,,*,,7,|.....|pL|*,,7",
+- "||vvv||vv||vvv|||||||,*,7,*,,7, __,7*,,7*,*7,7,,7,,,,,7,*,|@...@||+|,7,,",
+- "7,*,,7,,7*t,,*,7,*,,*,7*|||v|||v++v|||v|||,,,,7,,,7,*,,,,7|@lhl@|t;;*,,7",
+- ",,7,,*7,,,,7*,,*,,7,,*,,|T+.+T|^..a|T+.+T|7,7,,7,,*,,7*,,,|||v|||;;,7*,,",
+- ",*,,7,,*,7*,,7,,7,*,7,,7|||.|||S..S|||.|||,*,,*,,7,,*,,7,*,7,,,7,,*,*,7,",
+- "7,*,,*,,*,,7,*,,,,*,,,*,|T+.+T|S..S|T+.+T|t7,,7,,,*,7,,*,,,,,7,*,,,,,,*,",
+- ",,7,,,*7,,*,*,,7*,7*,7,*|||.|||S..S|||.|||,,*,,*,,7,,,7,,7*,,*,,7,*,,7,,",
+- "*,,*7*,,,7,,7,*,,,*,,*,,v^....+....+....^v*,,,,,7,*,,*,,*,,7,,,,*,7,,*,,",
+- "7,,,*,,7,,,*,,,7,*,,,,7|||+|+||b..b||+|+|||,7,,*,,,,7,,*7,,*,,7,,,,,7,,,",
+- ",*7,,7,*,,7,,*,*,,7 *,*|!..|..|b..b|..|..!|,*,7,,7,*,*,,,,7,,,*,,7*,,,,*",
+- "7,,*,,,,7,*,,7,,,*,,,7,|||.||.|b..b|.||.|||7,,,,*,,7,,7,,*,,7,,7,,,,*,7,",
+- "*,*,,7,*,,7,,*,,7,,*,*,|!..|!.|Y..Y|.!|..!|*,,*,7,,*,,*,7,,,,*,,,,,7,,,*",
+- ",,7,*,,,,*,,,7,*,,,7,,,||v|||!|..^.|!|||v||,,7,*,,,,7,,,,*,7,,,*,7,,,7,,",
+- "7,,,7,*,7,*7,*,7,,*,,7,*,,7*||||vv||||,7*,,7*,,7,*,,*,7*,,,,*,7,,,*7,*,,"
++ ",7,,,,,,7,*,,7,,,7,,*,7,,,,,7,* _________ 7 ,,,,7*,,,,7,,,,,*,,,,*7,",
++ ",,,,*7,,||||v||||||v|||,*,,,,,, _________ *,,,7,,,,,,,*,,,,7,,7,*,,,*",
++ "7,,*,G,7|^.fff.^|ddddd|,F*,*, __________7* ,,7,,,,,*,,77**,,**,,**,7,,7",
++ ",,G,;;,t|.d.h..X|d..hdv*,,*,* __________ ,||||||||||||||vv||vv||vv||||,",
++ "G* ;G,G*|.dddd.Y|dh..dv*,*,,, ___________F,|???|T+.a|^...............^|,",
++ " ;7;;;;*v..h.h..|.....v*,,,* ___________ *v?.?|||.S|.bnb.bnb.bnb.bnb.v*",
++ ",G;G G;*v.......+.ff.g|,F*, ____________ *v...|T+.S|.bnb.bnb.bnb.bnb.v*",
++ ",*;;;;;G|hh..bbb|.||+||,,* ____________F,|..n|||.S|.bnb|bnb.bnb.bnb.|,",
++ "G,G G;G,||||+||||+|..Y||| _____________,||..n|T+..|.bnb^bnb.bnb.bnb.||",
++ "7 ;;*;;7|???.|ST|.d.....|;;_____________ *|^...|||+||..................|",
++ " G G7;*G|?n..|..|hd.....+_______________;;|.........|Y.bbbb.bbbb....nh.v",
++ "G;;;,G;;|?...|a.|fd...bb|;;_______________+..g......+..nnnn.nnnn....nh.v",
++ "7,G;G;;G|...^||+|||^..|||, _____________;;|+||||||+||..bbbb.bbbb....nh.v",
++ "G,*;;;;,|hh......g||+||*,, _____________ ,|<..ccss.a|a.................|",
++ ",7 ;;G7*vnn..|fh..@@.M|,F* _____________ ,|||.......U.....bnb.bnb.bnb.||",
++ ",*G;;*,*vnn..ufdd....Mv*,,,____________ F*|u.SSsu..U....|bnb.bnb.bnb.|,",
++ ",, ;;G,7|hh..udf@.@@.@v**,7,___________ *vu.cccu..U.....bnb.bnb.bnb.v*",
++ ",,*;;,*,|....cdh@....@v*,,,,__________* ,*ve.......U.....bnb.bnb.bnb.v*",
++ ",7 ;;7,*|acOe|dh^.@@.a|,F;;;__________ F,|e.uuuu..|.$$.............^|,",
++ ",*, ;;,7|||||||||||v|||,;;,*__________ *,,||||||||+|+|||vv||vv||vv||||,",
++ "*,,* ;;;; *,,*7,,7,*77,;;,,7,_________ * HDDD_|<....|,**,,**,***, ,,7",
++ ",,,,* ;;;;;;;;*,,,,,,7;,7,*,, _____________m____+..hnh|,*oooooooooooo,*",
++ ",*,7,,,*,, ;;;;;;;;; *;;,,*,7, ________ *,,HR_DD|L.hnh|,7, ;;;;;;,*,,",
++ "*7,,,7,,*,,,,7,* ;;;;;;7,*,,,, ________ ,,7,HHHHH|||v|||,,,ooooooooooooo",
++ ",,,*,,,77,,*,,,7,,*,7;;;;;7,*,________,,*,*,,7,,7 ;*** ,*;; ;;;;;;;;;;;,",
++ "7*,,*7,*,,*,7*,,,7,,*,, ;;;;7,________7,*,7,*,,*,, oooooooooooooooooooo,",
++ "*,,,,,*,,7,,*,,,*,,,,,*,7 ;;;;________*,,7*,7,*,, * ;;;;;;;;;;;;;;;;; ,,",
++ ",,***,7**,t***7,,7*,*7,,,*,,7________7*,,,*, ooooooooooooooooooooooooo,*",
++ "||vvv||vv||vvv|||||||,,*,,7,,________,,,*7, ;;;;;;;;;;;;;;;;;;;;; ,7,",
++ "|.....a..Y....^|llll|*,7,,,*,________*,,,* oooooooooooooooooooooooooo,,,",
++ "|.l@@..h...@@l.|....|7,,,*,,7________,7,,;;;;;;;;;;;;;;;;;;;;;;;;;;; *,7",
++ "v.....bnnb.....|.lll|,*,,,77___________* oooooooooooooooooooooooooooo,,",
++ "|.l@@.bnnb.@@l.|+||||,7,,,*,_____________;;;;;;;;;;;;;;;;;;;;;;;;;;;; ,*",
++ "|.....h.h......|.???|*,,7,,,________*,___oooooooooooooooooooooooooooooo,",
++ "|.l@@......@@l.....?|,7,,*,*________7,, _;;;;;;;;;;;;;;;;;;;;;;;;;;;; ,*",
++ "v......h............v*,,7,,________*,*7,* oooooooooooooooooooooooooooooo",
++ "|.l@@.bnnb.@@l.nn..^|7,,*,*________77,*,, ;;;;;;;;;;;;;;;;;;;;;;;;;;; ,",
++ "|.....bnnb.....||++||,,7,__________*,7,7,* ooooooooooooooooooooooooooooo",
++ "|.l@@...h..@@l.| __ *,*, ___________,*,*,,*,, ;;;;;;;;;;;;;;;;;;;;;;,*,",
++ "v.....h........v __ 7 _____________*,,*7,,*,ooooooooooooooooooooo,7,,,",
++ "|.........????.|* __________________7,*,,* ;;;;;;;;;;;;;;;;;;;;;;,,*,,7",
++ "|||+|||++|||||||,,, _____*,*7_______,*7,7,oooooooooooooooooooooooooo7*,",
++ "t|h.p|....|,*7,,7*,, ___*,,,,____BBB *,*,* ;;;;;;;;;;;;;;;;;;;;;;,,,*,",
++ "_|.h.|?..nv*,,*,7,,*,____,,7*,,___NNN 7*,,7,oooooooooooooooooooooooo*,,7",
++ "*|h.L|?..nv*_,,*,*,,,___,7*,,7*___BBB_*,*7 ;;;;;;;;;;;;;;;;;;;;;;;,,, ",
++ "*|h.L|^...|t_,,,7*,,*___*,,,*,,_______,*,*ooooooooooooooooooooooooooo,7,",
++ "|||+|||++|||||||,,*, ___,,*7,________,7,,;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ,",
++ "|nn..a^...???.^|*7, ____________i__ *,7,oooooooooooooooooooooooooooooo*",
++ "v^.............v, __________________ _;_;;;;;;;;;;;;;;;;;;;;;;;;;;; ,7",
++ "|.l@@..bb..@@l.| __ _______________;___oooooooooooooooooooooooooooooo,",
++ "|......nnh.....||++||,7* BNB_______;___;_;;;;;;;;;;;;;;;;;;;;;;;;; *7",
++ "|.l@@.hnn..@@l.Y...^|7,,7* BNB_____BNB__;_ooooooooooooooooooooooooooo,,",
++ "v......bb...........v**,*,7 BNB ___ BNB *, __;;;;;;;;;;;;;;;;;;;;;;; ,,,",
++ "|.l@@......@@l.^...?|,7,,,* __* BNB ,7*ooooooooooooooooooooooooo,*7,",
++ "|......bb......|.???|*,*,,7*, ___7 *,,;;;;;;;;;;;;;;;;;;;;;;;;;; ,,,",
++ "|.l@@..nnh.@@l.|+||||7,,,*,,7* __*,, *,,7ooooooooooooooooooooooooooooo,7",
++ "v.....hnn......|.lll|,*,,7,,*, __,7*,,*,,,;;;;;;;;;;;;;;;;;;;;;;;;;;; ,",
++ "|.l@@..bb..@@l.|....|*,7*,,, ,7___,,*7 7oooooooooooooooooooooooooooooo,*",
++ "|^.......h....^|llll|7,*,,7,*,* __*,,,*,,7 *;;;;;;;;;;;;;;;;;;;;;;; ,,7",
++ "||vvv||vv||vvv|||||||,*,7,*,,7, __,7*,,7*,*oooooooooooooooooooooooo ,7,,",
++ "7,***7,***t***,7,*,,*,7*|||v|||v++v|||v||| ;;;;;;;;;;;;;;;;;;;;;;,,,,*",
++ ",,,,,*7,,,,,*,,*,,7,,*,,|T+.+T|^..a|T+.+T|7,7ooooooooooooooooooooooo*7,,",
++ ",*,,7,,*,7*,77,,7,*,7,,7|||.|||S..S|||.|||,, ;;;;;;;;;;;;;;;;;;;;;;; ,*",
++ ",,*,,*,,*,,7,*,,,,*,,,*,|T+.+T|S..S|T+.+T|t7,,ooooooooooooooooooooooooo,",
++ ",,7,,,*7,,*,*,,7*,7*,7,*|||.|||S..S|||.|||* ;;;;;;;;;;;;;;;;;;;;;;;;; *",
++ "*,,*7*,,,7,,,,*,,,*,,*,*v^....+....+....^v*,,ooooooooooooooooooooooooo,7",
++ ",,,,*,,,,,,*,,,,,*,,,,7*||+|+||....||+|+||* ;;;;;;;;;;;;;;;;;;;;;;;;; ,",
++ ",*7,,7,*,,7,,*,,,,7 *,*,|!.|.!|b..b|!.|.!|7,oooooooooooooooooooooooooooo",
++ ",,,*,,,77,*,,,,,,*,,,7,,||.|.||b..b||.|.||,7 ;;;;;;;;;;;;;;;;;;;;;;; ,,,",
++ "*,,,,7,*,,,,,*,,,,,*,*,,|!.|.!|b..b|!.|.!|,*,,oooooooooooooooooooooooo,*",
++ ",,,,*,,,,,,,,,,*,,,7,,,,||||||||vv||||||||,,,,7,,,, ;;;;;;;;;;;; ,,,,,7,",
++ ",,,,,,,,,,*,,,,,,,*,,7,*,,7*,,,****7,,,7*,,7*,,7*,,oooooooooooooo,*,7,*,"
+ ],
+ "palettes": [ "cground" ],
+- "place_vehicles": [ { "vehicle": "bus", "x": 33, "y": [ 18, 18 ], "chance": 100, "status": 4, "rotation": 90 } ],
+- "place_npcs": [ { "class": "godco_cook", "x": [ 46, 47 ], "y": 14 } ],
+- "place_loot": [ { "item": "oil_lamp_on", "x": 47, "y": 16 } ]
++ "place_zones": [
++ { "type": "NPC_RETREAT", "faction": "gods_community", "x": [ 48, 69 ], "y": [ 4, 18 ] },
++ { "type": "NPC_RETREAT", "faction": "gods_community", "x": [ 44, 47 ], "y": [ 4, 18 ] },
++ { "type": "NPC_RETREAT", "faction": "gods_community", "x": [ 51, 55 ], "y": [ 20, 23 ] },
++ { "type": "NPC_INVESTIGATE_ONLY", "faction": "gods_community", "x": [ 0, 23 ], "y": [ 0, 23 ] },
++ { "type": "NPC_INVESTIGATE_ONLY", "faction": "gods_community", "x": [ 0, 23 ], "y": [ 24, 47 ] },
++ { "type": "NPC_INVESTIGATE_ONLY", "faction": "gods_community", "x": [ 0, 23 ], "y": [ 48, 71 ] },
++ { "type": "NPC_INVESTIGATE_ONLY", "faction": "gods_community", "x": [ 24, 47 ], "y": [ 0, 23 ] },
++ { "type": "NPC_INVESTIGATE_ONLY", "faction": "gods_community", "x": [ 24, 47 ], "y": [ 24, 47 ] },
++ { "type": "NPC_INVESTIGATE_ONLY", "faction": "gods_community", "x": [ 24, 47 ], "y": [ 48, 71 ] },
++ { "type": "NPC_INVESTIGATE_ONLY", "faction": "gods_community", "x": [ 48, 71 ], "y": [ 0, 23 ] },
++ { "type": "NPC_INVESTIGATE_ONLY", "faction": "gods_community", "x": [ 48, 71 ], "y": [ 24, 47 ] },
++ { "type": "NPC_INVESTIGATE_ONLY", "faction": "gods_community", "x": [ 48, 71 ], "y": [ 48, 71 ] }
++ ],
++ "place_vehicles": [
++ { "vehicle": "bus", "x": 33, "y": [ 18, 18 ], "chance": 100, "status": 1, "rotation": 90 },
++ { "vehicle": "wheelchair", "x": 8, "y": 35, "chance": 100, "status": 0, "rotation": 90 },
++ { "vehicle": "wheelbarrow", "x": [ 39, 40 ], "y": [ 48, 49 ], "chance": 100, "status": 0, "rotation": 90 }
++ ],
++ "place_loot": [
++ { "item": "mess_tray", "repeat": [ 15, 20 ], "x": 52, "y": 14 },
++ { "item": "plastic_plate", "repeat": [ 15, 20 ], "x": 52, "y": 15 },
++ { "item": "cup_plastic", "repeat": [ 15, 20 ], "x": 52, "y": 16 },
++ { "item": "fork", "repeat": [ 15, 20 ], "x": 52, "y": 17 },
++ { "item": "plastic_knife", "repeat": [ 15, 20 ], "x": 52, "y": 17 },
++ { "item": "spoon", "repeat": [ 15, 20 ], "x": 52, "y": 17 },
++ { "item": "log", "x": [ 31, 34 ], "y": [ 66, 70 ], "repeat": 200 },
++ { "item": "stick_long", "x": [ 31, 34 ], "y": [ 66, 70 ], "repeat": 75 },
++ { "item": "cowboy_hat", "x": 35, "y": 43 },
++ { "item": "months_old_newspaper", "x": 8, "y": 38, "repeat": [ 3, 5 ] },
++ { "item": "one_year_old_newspaper", "x": 8, "y": 38, "repeat": [ 3, 5 ] },
++ { "item": "ZSG", "x": 8, "y": 37 },
++ { "item": "story_book", "x": 8, "y": 37 },
++ { "item": "classic_literature", "x": 8, "y": 37 },
++ { "item": "deck_of_cards", "x": 7, "y": 56 },
++ { "item": "fertilizer_commercial", "repeat": [ 1, 3 ], "x": [ 39, 40 ], "y": [ 48, 49 ] },
++ { "item": "stick_long", "x": 50, "y": 18, "repeat": [ 5, 20 ] },
++ { "item": "log", "x": 50, "y": 18, "repeat": [ 4, 8 ] },
++ { "item": "stick_long", "x": 33, "y": 47, "repeat": [ 1, 5 ] }
++ ]
+ }
+ },
+ {
+@@ -128,25 +165,25 @@
+ "########(=============)#################################################",
+ "########(zzzzzzzzzzzzz)#################################################",
+ "########:zzzzzzzzzzzzz)####################||||||||||||||vv||vv||vv||||#",
+- "########(zzzzzzzzzzwzz)####################|xxxxxxxx..hhhq%%%%%%%%%%%%|#",
++ "########(zzzzzzzzzzwzz)####################|xxxxxxx...hhhq%%%%%%%%%%%%|#",
+ "########(zzzzzzzzzzzzz)####################vxxxxxxx....hhq%%%%%%%%%%%%v#",
+- "########(zzzzzzzzzzzzz)####################vxxx.xxx...h..q%%%%%%%%%%%%v#",
+- "########(zzzzzzzzzzzzz)####################|xx.......xqqq|%%%%%%%%%%%%|#",
++ "########(zzzzzzzzzzzzz)####################vxxx.xx....h..q%%%%%%%%%%%%v#",
++ "########(zzzzzzzzzzzzz)####################|xx........qqq|%%%%%%%%%%%%|#",
+ "########(zzzzzzzzzzzzz)=)#################||x.??.xx...q%%%%%%%%%%%%%%%||",
+- "########(zzzzzzzzzzzzzzz)#################|...nnhx....q%%%%%%%%%%%%%%%%|",
+- "########(zzzjzzzzzzzzzzz)#################v..xxxx...?.q%%%%%%%%%%%%%%%%v",
++ "########(zzzzzzzzzzzzzzz)#################|x..nnxxx...q%%%%%%%%%%%%%%%%|",
++ "########(zzzjzzzzzzZZZzz)#################v..xxxxx..?.q%%%%%%%%%%%%%%%%v",
+ "########(zzzzzzzzzzzzzzz)#################v...xx....?.q%%%%%%%%%%%%%%%%v",
+ "########(zzzzzzzzzzzzz)-)#################v.|.......?.q%%%%%%%%%%%%%%%%v",
+ "########(zzzzzzzzzzzzz)###################|>|.........q%%%%%%%%%%%%%%%%|",
+ "########(zzzzzzzzzzzzz)###################|||...h.....q%%%%%%%%%%%%%%%||",
+- "########(zzzzzzzzzzzzz)####################|..hnn.....qqq|%%%%%%%%%%%%|#",
+- "########(zzzzzzzzzzzzz)####################v...nnh...^...q%%%%%%%%%%%%v#",
+- "########(zzzzzzzzzzzzz)####################v..h......??.bq%%%%%%%%%%%%v#",
++ "########(zZZzzzzzzZZzz)####################|..hnn.....qqq|%%%%%%%%%%%%|#",
++ "########(zZZzzzzzzZZzz)####################v...nnh...^...q%%%%%%%%%%%%v#",
++ "########(zZZzzzzzzZZzz)####################v..h......??.bq%%%%%%%%%%%%v#",
+ "########(zzzzzzzzzzzzz)####################|............bq%%%%%%%%%%%%|#",
+ "########(-------------)####################||||||||+|+|||vv||vv||vv||||#",
+ "#################################################|>...<|################",
+ "#################################################|.....|################",
+- "#################################################|LLSpp|################",
++ "#################################################|...pp|################",
+ "#################################################|||v|||################",
+ "########################################################################",
+ "########################################################################",
+@@ -157,35 +194,35 @@
+ "(zzzzzzzzzzzzzzzzzzz)###################################################",
+ "(zzzzzzzzzzzzzzzzzzz)###################################################",
+ "(zzzzzzzzzzzzzzzzzzz)###################################################",
+- "(zzzzwzzzzzzzzzzzzzz)###################################################",
+- "(zzzzzzzzzzzzzzzzzzz)###################################################",
+- "(zzzzzzzzzzzzzzzzzzz)###################################################",
++ "(zzzzwZZZZzzzzzzzzzz)###################################################",
++ "(zzzzzZZZZzzzzzzzzzz)###################################################",
++ "(zzzzzZZZZzzzzzzzzzz)###################################################",
+ "(zzzzzzzzzzzzzzzzzzz)###################################################",
+ "(zzzzzzzzzzzzzz)----)###################################################",
+ "(zzzzzzzzzzzzzz)########################################################",
+ "(zzzzzzzzzzzzzz)########################################################",
+ "(zzzzzzzzzzzzzz)########################################################",
+ "((zzzzzzzz)----)########################################################",
+- "#(zWzzzzzz)#############################################################",
++ "#:zWzzzzzz)#############################################################",
+ "#(zzzzzzzz)#############################################################",
+ "#(zzzzzzzz)#############################################################",
+- "#(zWzzzzzz)#############################################################",
++ "#(zWzzzzzz:#############################################################",
+ "((zzzzzzzz)====)########################################################",
+- "(zzzzzzzzzzzzzz)#########################################(==========)###",
+- "(zzzzzzzzzzzjzz)#########################################(zzzzzzzzzz)###",
+- "(zzzzzzzzzzzzzz)#########################################(zzzzzzzzzz)###",
+- "(zzzzzzzzzzzzzz)====)####################################(zzzzzzzzzz)###",
+- "(zzzzzzzzzzzzzzzzzzz)####################################(zzzzzzzzzz)###",
+- "(zzzzzzzzzzzzzzzzzzz)####################################((zzzzzzzzz)###",
+- "(zzzzzzzzzzzzzzzzzzz)#####################################(zzzzzzzzz)###",
+- "(zzzzwzzzzzzzzzzzzzz)#####################################(zzzzzzzzz)###",
+- "(zzzzzzzzzzzzzzzzzzz)#####################################(zzzzzzzzz)###",
+- "(zzzzzzzzzzzzzzzzzzz)#####################################(zzzzzzzzz)###",
+- "(zzzzzzzzzzzzzzzzzzz)#####################################(zzzzzzzz))###",
+- "(zzzzzzzzzzzzzzzzzzz)#####################################(zzwzzzzz)####",
+- "(---------:---------)#####################################(zzzzz)--)####",
+- "########################(================)################(zzzzz:#######",
+- "########################(zzzzzzzzzzzzzzzz)################(-----)#######",
++ "(zzzzzzzzzzzzzz)########################################################",
++ "(zzzzzzzzzzzjzz)########################################################",
++ "(zzzzzzzzzzzzzz)########################################################",
++ "(zzzzzzzzzzzzzz)====)###################################################",
++ "(zzzzzzzzzzzzzzzzzzz)###################################################",
++ "(zzzzzZZZZzzzzzzzzzz)###################################################",
++ "(zzzzzZZZZzzzzzzzzzz)###################################################",
++ "(zzzzwZZZZzzzzzzzzzz)###################################################",
++ "(zzzzzzzzzzzzzzzzzzz)###################################################",
++ "(zzzzzzzzzzzzzzzzzzz)###################################################",
++ "(zzzzzzzzzzzzzzzzzzz)###################################################",
++ "(zzzzzzzzzzzzzzzzzzz)###################################################",
++ "(---------:---------)###################################################",
++ "########################(================)##############################",
++ "########################(zzzzzzzzzzzzzzzz)##############################",
+ "########################(zzzzzzzzzzzzzzzz)##############################",
+ "########################(zzzzzzzzzzzzzzzz:##############################",
+ "########################(zzzzzzzzzzzzzzzz)##############################",
+@@ -199,11 +236,7 @@
+ ],
+ "palettes": [ "cground" ],
+ "place_nested": [ { "chunks": [ [ "roof_4x4_utility", 10 ], [ "roof_4x4_utility_1", 10 ] ], "x": 31, "y": 65 } ],
+- "place_npcs": [ { "class": "godco_food_guard", "x": 47, "y": 8 } ],
+- "place_loot": [
+- { "group": "novels", "x": [ 46, 47 ], "y": 9, "repeat": [ 6, 10 ], "chance": 100 },
+- { "item": "oil_lamp_on", "x": [ 46, 47 ], "y": 9 }
+- ]
++ "place_loot": [ { "group": "novels", "x": [ 46, 47 ], "y": 9, "repeat": [ 6, 10 ], "chance": 100 } ]
+ }
+ },
+ {
+@@ -237,11 +270,11 @@
+ "###################(zzzzzzzzzzzzzzzzzzzzzzzzzz)#",
+ "###################(zzzzzzzzzzzWzWzzzzzzzzzzzz)#",
+ "###################(zzzzzzzzzzzzzzzzzzzzzzzzzz)#",
+- "###################(-----qqq'qqq------:-------)#",
+- "#########################q''''>q################",
+- "#########################q'''''q################",
+- "#########################q'''''q################",
+- "#########################qqqqqqq################"
++ "###################(-----('''|||------:-------)#",
++ "#########################('''+>|################",
++ "#########################('''|||################",
++ "#########################(''''')################",
++ "#########################(-----)################"
+ ],
+ "palettes": [ "cground" ]
+ }
diff --git a/npc-04_island-prison-update.patch b/npc-04_island-prison-update.patch
new file mode 100644
index 0000000..27d9629
--- /dev/null
+++ b/npc-04_island-prison-update.patch
@@ -0,0 +1,1731 @@
+--- a/data/json/npcs/island_prison/prisoners.json
++++ b/data/json/npcs/island_prison/prisoners.json
+@@ -0,0 +1,631 @@
++[
++ {
++ "type": "npc",
++ "id": "prisoner_generic",
++ "//": "Former prisoner with a melee or ranged weapon and prison clothing. Sometimes they also have prison guards' gear.",
++ "name_suffix": "prisoner",
++ "class": "NC_THUG_PRISONER",
++ "attitude": 0,
++ "mission": 8,
++ "chat": "TALK_PRISONER_GENERIC",
++ "faction": "prisoners"
++ },
++ {
++ "type": "npc",
++ "id": "prisoner_greeter",
++ "//": "Former prisoner with a melee or ranged weapon and prison clothing. Sometimes they also have prison guards' gear.",
++ "name_suffix": "gatekeeper",
++ "class": "NC_THUG_PRISONER",
++ "attitude": 0,
++ "mission": 8,
++ "chat": "TALK_PRISONER_GREET",
++ "faction": "prisoners"
++ },
++ {
++ "type": "npc",
++ "id": "prisoner_leader",
++ "//": "Former prisoner with a melee or ranged weapon and prison clothing. Sometimes they also have prison guards' gear.",
++ "name_suffix": "leader of prisoners",
++ "class": "NC_THUG_PRISONER",
++ "attitude": 0,
++ "mission": 8,
++ "chat": "TALK_PRISONER_LEADER_GREET",
++ "faction": "prisoners",
++ "mission_offered": "MISSION_PRISONER_LEADER_GET_ID_CARD"
++ },
++ {
++ "type": "npc_class",
++ "id": "NC_THUG_PRISONER",
++ "name": { "str": "Prisoner" },
++ "job_description": "I'm here to kick ass.",
++ "traits": [
++ { "group": "BG_survival_story_CRIMINAL" },
++ { "group": "NPC_starting_traits" },
++ { "group": "Appearance_demographics" }
++ ],
++ "bonus_str": { "rng": [ 2, 4 ] },
++ "bonus_dex": { "rng": [ 0, 2 ] },
++ "skills": [
++ { "skill": "ALL", "level": { "sum": [ { "dice": [ 3, 2 ] }, { "constant": -4 } ] } },
++ { "skill": "dodge", "bonus": { "rng": [ 1, 3 ] } },
++ { "skill": "melee", "bonus": { "rng": [ 2, 4 ] } },
++ { "skill": "unarmed", "bonus": { "rng": [ 1, 3 ] } },
++ { "skill": "bashing", "bonus": { "rng": [ 1, 5 ] } },
++ { "skill": "stabbing", "bonus": { "rng": [ 1, 5 ] } },
++ { "skill": "cutting", "bonus": { "rng": [ 1, 5 ] } }
++ ],
++ "worn_override": "NC_THUG_PRISONER_worn",
++ "weapon_override": "NC_THUG_PRISONER_wield"
++ },
++ {
++ "type": "item_group",
++ "id": "NC_THUG_PRISONER_worn",
++ "subtype": "collection",
++ "entries": [
++ { "group": "male_underwear" },
++ { "distribution": [ { "group": "clothing_prisoner_shoes" }, { "group": "cop_shoes" } ] },
++ { "distribution": [ { "item": "striped_shirt" }, { "group": "cop_torso" } ] },
++ { "distribution": [ { "item": "striped_pants" }, { "group": "cop_pants" } ] },
++ { "distribution": [ { "item": "tacvest" }, { "item": "kevlar" } ], "prob": 15 },
++ { "group": "socks_unisex" },
++ { "group": "cop_gloves", "prob": 20 },
++ { "distribution": [ { "item": "bandana" }, { "group": "cop_helmet" } ], "prob": 50 },
++ { "group": "clothing_glasses", "prob": 20 },
++ { "group": "clothing_watch", "prob": 20 },
++ { "item": "police_belt", "prob": 20 }
++ ]
++ },
++ {
++ "type": "item_group",
++ "id": "NC_THUG_PRISONER_wield",
++ "items": [
++ [ "baton-extended", 50 ],
++ [ "PR24-retracted", 50 ],
++ [ "knife_steak", 30 ],
++ [ "knife_chef", 30 ],
++ [ "knife_paring", 30 ],
++ [ "knife_butcher", 30 ],
++ [ "knife_meat_cleaver", 30 ],
++ [ "knife_carving", 30 ],
++ [ "pointy_stick", 30 ],
++ [ "cudgel", 20 ],
++ [ "knuckle_nail", 20 ],
++ [ "spear_spike", 20 ],
++ [ "spear_knife", 15 ],
++ [ "makeshift_sap", 15 ],
++ [ "homewrecker", 15 ],
++ [ "makeshift_knife", 15 ],
++ [ "nailboard", 15 ],
++ [ "sword_wood", 10 ],
++ [ "glass_shiv", 5 ],
++ [ "rock_sock", 5 ],
++ [ "sharp_toothbrush", 5 ],
++ [ "chisel", 5 ],
++ [ "scissors", 5 ],
++ [ "screwdriver", 5 ],
++ [ "knife_steak", 5 ],
++ [ "knuckle_brass", 5 ],
++ [ "switchblade", 5 ],
++ [ "throwing_knife", 5 ],
++ { "group": "guns_cop", "prob": 50 }
++ ]
++ },
++ {
++ "id": "TALK_PRISONER_GENERIC",
++ "type": "talk_topic",
++ "dynamic_line": "<get_lost>",
++ "responses": [
++ { "text": "Ok, sorry, I'm already leaving!", "topic": "TALK_DONE" },
++ { "text": "Hey, <fuck_you>!", "topic": "TALK_DONE", "effect": "hostile" }
++ ]
++ },
++ {
++ "id": "TALK_PRISONER_GREET",
++ "type": "talk_topic",
++ "dynamic_line": {
++ "u_has_var": "first_meeting",
++ "type": "dialogue",
++ "context": "first_meeting",
++ "value": "yes",
++ "no": "Hey, who the fuck are you? I haven't seen you 'round. Ah, fuck it, it doesn't matter.\nHere's the rules. The first and most important one: ALWAYS CLOSE THE FUCKING ENTRY DOOR BEHIND YOUR ASS! If you're okay with that, the following rules are: don't fuck with us, don't steal from us, don't start a fight without a reason with someone from us. Got it, punk? Now get lost.",
++ "yes": "<get_lost>"
++ },
++ "speaker_effect": { "effect": { "u_add_var": "first_meeting", "type": "dialogue", "context": "first_meeting", "value": "yes" } },
++ "responses": [
++ {
++ "text": "Yeah, I got it. See ya.",
++ "topic": "TALK_DONE",
++ "condition": { "not": { "u_has_var": "first_meeting", "type": "dialogue", "context": "first_meeting", "value": "yes" } }
++ },
++ {
++ "text": "I just wanted to ask if you have a job for me.",
++ "topic": "TALK_PRISONER_ANNOYED",
++ "condition": {
++ "and": [
++ { "u_has_var": "first_meeting", "type": "dialogue", "context": "first_meeting", "value": "yes" },
++ {
++ "not": { "u_has_var": "talked_to_greeter", "type": "dialogue", "context": "annoyed_greeter", "value": "yes" }
++ }
++ ]
++ }
++ },
++ {
++ "text": "I'm just hungry, and I thought you might give me some food for some job.",
++ "topic": "TALK_PRISONER_ANGRY",
++ "condition": {
++ "and": [
++ { "u_has_var": "first_meeting", "type": "dialogue", "context": "first_meeting", "value": "yes" },
++ { "u_has_var": "talked_to_greeter", "type": "dialogue", "context": "annoyed_greeter", "value": "yes" },
++ {
++ "not": { "u_has_var": "talked_to_greeter", "type": "dialogue", "context": "angry_greeter", "value": "yes" }
++ }
++ ]
++ }
++ },
++ {
++ "text": "Can we just talk it over?",
++ "topic": "TALK_PRISONER_READY_TO_MUG",
++ "condition": {
++ "and": [
++ { "u_has_var": "first_meeting", "type": "dialogue", "context": "first_meeting", "value": "yes" },
++ { "u_has_var": "talked_to_greeter", "type": "dialogue", "context": "angry_greeter", "value": "yes" }
++ ]
++ }
++ },
++ { "text": "Hey, <fuck_you>!", "topic": "TALK_DONE", "effect": "hostile" }
++ ]
++ },
++ {
++ "id": "TALK_PRISONER_ANNOYED",
++ "type": "talk_topic",
++ "dynamic_line": {
++ "u_has_var": "talked_to_greeter",
++ "type": "dialogue",
++ "context": "annoyed_greeter",
++ "value": "yes",
++ "no": "Do I have a <swear> exclamation sign over my <swear> head, like I'm a <swear> quest-giver from some <swear> video game?",
++ "yes": "<get_lost>"
++ },
++ "speaker_effect": { "effect": { "u_add_var": "talked_to_greeter", "type": "dialogue", "context": "annoyed_greeter", "value": "yes" } },
++ "responses": [
++ {
++ "text": "No, of course not! Sorry, I'm leaving.",
++ "topic": "TALK_DONE",
++ "condition": { "not": { "u_has_var": "talked_to_greeter", "type": "dialogue", "context": "annoyed_greeter", "value": "yes" } }
++ },
++ { "text": "Hey, <fuck_you>!", "topic": "TALK_DONE", "effect": "hostile" }
++ ]
++ },
++ {
++ "id": "TALK_PRISONER_ANGRY",
++ "type": "talk_topic",
++ "dynamic_line": {
++ "u_has_var": "talked_to_greeter",
++ "type": "dialogue",
++ "context": "annoyed_greeter",
++ "value": "yes",
++ "no": "<get_lost>",
++ "yes": "Are you deaf or stupid? I said I don't give a fuck for you and your <swear> problems. Bother me one more time, and you'll regret that. <get_lost>"
++ },
++ "speaker_effect": { "effect": { "u_add_var": "talked_to_greeter", "type": "dialogue", "context": "angry_greeter", "value": "yes" } },
++ "responses": [
++ {
++ "text": "Ok, sorry, I promise I won't bother you anymore.",
++ "topic": "TALK_DONE",
++ "condition": { "not": { "u_has_var": "talked_to_greeter", "type": "dialogue", "context": "angry_greeter", "value": "yes" } }
++ },
++ { "text": "Hey, <fuck_you>!", "topic": "TALK_DONE", "effect": "hostile" }
++ ]
++ },
++ {
++ "id": "TALK_PRISONER_READY_TO_MUG",
++ "type": "talk_topic",
++ "dynamic_line": "You think you're immortal, huh, <name_b>?",
++ "responses": [
++ { "text": "Gee, what's the matter with you? Okay, okay, I'm leaving.", "topic": "TALK_PRISONER_MUG" },
++ {
++ "text": "It would be you who will regret talking to me like that.",
++ "topic": "TALK_DONE",
++ "effect": "hostile"
++ }
++ ]
++ },
++ {
++ "id": "TALK_PRISONER_MUG",
++ "type": "talk_topic",
++ "dynamic_line": [ "Not so fast, I think you need to pay for breaking your promise and bothering me. Give me your shit, now!" ],
++ "responses": [
++ { "text": "Please don't hurt me! Take all that you want.", "topic": "TALK_MUG" },
++ { "text": "What, <no>!", "topic": "TALK_DONE", "effect": "hostile" }
++ ]
++ },
++ {
++ "id": "TALK_PRISONER_LEADER_GREET",
++ "type": "talk_topic",
++ "dynamic_line": {
++ "u_has_var": "prisoner_leader_mission",
++ "type": "mission",
++ "context": "military_id",
++ "value": "yes",
++ "yes": "I have nothing more to say to you. <get_lost>",
++ "no": {
++ "u_has_var": "prisoner_leader_mission",
++ "type": "mission",
++ "context": "accepted",
++ "value": "yes",
++ "yes": "So, what are you waiting for?",
++ "no": {
++ "u_has_var": "prisoner_leader_mission",
++ "type": "mission",
++ "context": "completed",
++ "value": "yes",
++ "yes": "I don't know if you know, but there are sewers underneath the prison. I was planning an escape long before <the_cataclysm>, and while I was working on cleaning the sewers, I noticed a damaged wall section. There was a flow of fresh air coming out of it, so I think it's leading to the surface. It could be your way to freedom. Feel free to use it.",
++ "no": {
++ "u_has_var": "talked_to_leader",
++ "type": "dialogue",
++ "context": "first_meeting",
++ "value": "yes",
++ "yes": {
++ "u_has_var": "talked_to_leader",
++ "type": "dialogue",
++ "context": "cannibal",
++ "value": "yes",
++ "no": "It's you again.",
++ "yes": "You are what you eat, as they say."
++ },
++ "no": "Hello there. Haven't seen you around before. You must be from the other wing. Managed to survive, huh?"
++ }
++ }
++ }
++ },
++ "speaker_effect": { "effect": { "u_add_var": "talked_to_leader", "type": "dialogue", "context": "first_meeting", "value": "yes" } },
++ "responses": [
++ {
++ "text": "Yeah, I've been through situations far worse than that.",
++ "topic": "TALK_PRISONER_LEADER_INQUIRY",
++ "condition": {
++ "and": [
++ { "not": { "u_has_var": "talked_to_leader", "type": "dialogue", "context": "first_meeting", "value": "yes" } },
++ {
++ "not": { "u_has_var": "prisoner_leader_mission", "type": "mission", "context": "completed", "value": "yes" }
++ }
++ ]
++ }
++ },
++ {
++ "text": "It was a nightmare, lots of <zombies>, blood everywhere! Thank god I'm among living people again.",
++ "topic": "TALK_PRISONER_LEADER_FROWN",
++ "condition": {
++ "and": [
++ { "not": { "u_has_var": "talked_to_leader", "type": "dialogue", "context": "first_meeting", "value": "yes" } },
++ {
++ "not": { "u_has_var": "prisoner_leader_mission", "type": "mission", "context": "completed", "value": "yes" }
++ }
++ ]
++ }
++ },
++ {
++ "text": "[Cannibal] It's hard to die of hunger when there's so many tasty corpses lying around.",
++ "topic": "TALK_PRISONER_LEADER_LEARNED_ABOUT_CANNIBAL",
++ "condition": {
++ "and": [
++ { "u_has_trait": "CANNIBAL" },
++ {
++ "not": { "u_has_var": "talked_to_leader", "type": "dialogue", "context": "first_meeting", "value": "yes" }
++ },
++ { "not": { "u_has_var": "talked_to_leader", "type": "dialogue", "context": "cannibal", "value": "yes" } },
++ {
++ "not": { "u_has_var": "prisoner_leader_mission", "type": "mission", "context": "completed", "value": "yes" }
++ }
++ ]
++ }
++ },
++ {
++ "text": "I want to get out of this <swear> prison. I hoped you could help me with that.",
++ "topic": "TALK_PRISONER_LEADER_GIVES_WORK",
++ "condition": {
++ "and": [
++ { "u_has_var": "talked_to_leader", "type": "dialogue", "context": "first_meeting", "value": "yes" },
++ {
++ "not": { "u_has_var": "prisoner_leader_mission", "type": "mission", "context": "accepted", "value": "yes" }
++ },
++ {
++ "not": { "u_has_var": "prisoner_leader_mission", "type": "mission", "context": "completed", "value": "yes" }
++ },
++ {
++ "not": { "u_has_var": "prisoner_leader_mission", "type": "mission", "context": "military_id", "value": "yes" }
++ }
++ ]
++ }
++ },
++ {
++ "text": "I'm on my way.",
++ "topic": "TALK_DONE",
++ "condition": { "u_has_var": "prisoner_leader_mission", "type": "mission", "context": "accepted", "value": "yes" }
++ },
++ {
++ "text": "I don't know if I'll take your advice, but thanks nevertheless.",
++ "topic": "TALK_DONE",
++ "condition": {
++ "and": [
++ { "u_has_var": "prisoner_leader_mission", "type": "mission", "context": "completed", "value": "yes" },
++ {
++ "not": { "u_has_var": "prisoner_leader_mission", "type": "mission", "context": "military_id", "value": "yes" }
++ }
++ ]
++ }
++ },
++ {
++ "text": "Wait, what? A <swear> can of beans?! I went through hell to get this <swear> thing for you, and all you give me as reward is a <swear> can of beans?! I demand something more substantial.",
++ "topic": "TALK_PRISONER_LEADER_DEMANDED_SUBSTANTIAL_REWARD",
++ "condition": {
++ "and": [
++ { "u_has_var": "prisoner_leader_mission", "type": "mission", "context": "completed", "value": "yes" },
++ {
++ "not": { "u_has_var": "prisoner_leader_mission", "type": "mission", "context": "military_id", "value": "yes" }
++ }
++ ]
++ }
++ },
++ {
++ "text": "Nice talking to ya. Farewell.",
++ "topic": "TALK_DONE",
++ "condition": {
++ "and": [
++ { "u_has_var": "talked_to_leader", "type": "dialogue", "context": "first_meeting", "value": "yes" },
++ {
++ "not": { "u_has_var": "prisoner_leader_mission", "type": "mission", "context": "accepted", "value": "yes" }
++ },
++ {
++ "not": { "u_has_var": "prisoner_leader_mission", "type": "mission", "context": "completed", "value": "yes" }
++ },
++ {
++ "not": { "u_has_var": "prisoner_leader_mission", "type": "mission", "context": "military_id", "value": "yes" }
++ }
++ ]
++ }
++ },
++ {
++ "text": "Okay.",
++ "topic": "TALK_DONE",
++ "condition": { "u_has_var": "prisoner_leader_mission", "type": "mission", "context": "military_id", "value": "yes" }
++ }
++ ]
++ },
++ {
++ "id": "TALK_PRISONER_LEADER_LEARNED_ABOUT_CANNIBAL",
++ "type": "talk_topic",
++ "dynamic_line": [
++ "Huh, even so? I'm not saying I approve your… tastes, but I definitely respect people who use all possibilities life has to offer."
++ ],
++ "speaker_effect": { "effect": { "u_add_var": "talked_to_leader", "type": "dialogue", "context": "cannibal", "value": "yes" } },
++ "responses": [ { "text": "Yeah, we share the same opinions on this matter.", "topic": "TALK_NONE" } ]
++ },
++ {
++ "id": "TALK_PRISONER_LEADER_INQUIRY",
++ "type": "talk_topic",
++ "dynamic_line": [
++ "Well, that's a boastful statement. Not that I don't believe it, it's just…. Ah, nevermind. Let's get to the point. What do you want?"
++ ],
++ "responses": [
++ {
++ "text": "I want to get out of this <swear> prison. I hoped you could help me with that.",
++ "topic": "TALK_PRISONER_LEADER_GIVES_WORK"
++ }
++ ]
++ },
++ {
++ "id": "TALK_PRISONER_LEADER_FROWN",
++ "type": "talk_topic",
++ "dynamic_line": [ "Hold the horses, pal. Nobody allowed you to stay here - yet." ],
++ "responses": [
++ {
++ "text": "Please! I don't want to go back there! I'm tired and hungry! I just need time to rest!",
++ "topic": "TALK_PRISONER_LEADER_ANNOYED"
++ },
++ { "text": "Shit! Looks like I'm on my own now. Thanks for nothing. Bye.", "topic": "TALK_DONE" }
++ ]
++ },
++ {
++ "id": "TALK_PRISONER_LEADER_ANNOYED",
++ "type": "talk_topic",
++ "dynamic_line": [
++ "We don't have much space, and there's not much food. Besides, I don't know you at all, and something tells me you won't survive another day."
++ ],
++ "responses": [
++ {
++ "text": "[STR 11] I'm tougher than it seems!",
++ "topic": "TALK_PRISONER_LEADER_NO",
++ "condition": { "u_has_strength": 11 }
++ },
++ {
++ "text": "[Survival 2] I have some survival expertise!",
++ "topic": "TALK_PRISONER_LEADER_NO",
++ "condition": { "u_has_skill": { "skill": "survival", "level": 2 } }
++ },
++ { "text": "I guess I need to find some other place…", "topic": "TALK_DONE" }
++ ]
++ },
++ {
++ "id": "TALK_PRISONER_LEADER_NO",
++ "type": "talk_topic",
++ "dynamic_line": [
++ "The answer is still no. In fact it might be better for us to kill you right away - you know, the less mouths to feed, the better. But I'm in a good mood today, so I've decided to help you get out of this island."
++ ],
++ "responses": [
++ { "text": "Ok, I'm listening.", "topic": "TALK_PRISONER_LEADER_GIVES_WORK" },
++ { "text": "You know, I think I'll manage without your help. Bye.", "topic": "TALK_DONE" }
++ ]
++ },
++ {
++ "id": "TALK_PRISONER_LEADER_GIVES_WORK",
++ "type": "talk_topic",
++ "dynamic_line": {
++ "u_has_var": "prisoner_leader_mission",
++ "type": "mission",
++ "context": "accepted",
++ "value": "yes",
++ "no": "I need you to retrieve some stuff from a locked safe. Interested?",
++ "yes": "So, what are you waiting for?"
++ },
++ "responses": [
++ {
++ "text": "[Show the military id card] You mean this stuff?",
++ "topic": "TALK_PRISONER_LEADER_SHOW_MILITARY_ID",
++ "condition": {
++ "and": [
++ { "u_has_item": "id_military" },
++ {
++ "not": { "u_has_var": "prisoner_leader_mission", "type": "mission", "context": "accepted", "value": "yes" }
++ }
++ ]
++ }
++ },
++ {
++ "text": "What's in the safe?",
++ "topic": "TALK_PRISONER_LEADER_ASKED_ABOUT_SAFE_CONTENTS",
++ "condition": {
++ "and": [
++ { "not": { "u_has_var": "prisoner_leader_mission", "type": "mission", "context": "military_id", "value": "yes" } },
++ {
++ "not": { "u_has_var": "prisoner_leader_mission", "type": "mission", "context": "accepted", "value": "yes" }
++ }
++ ]
++ }
++ },
++ {
++ "text": "What for do you need it?",
++ "topic": "TALK_PRISONER_LEADER_ASKED_ABOUT_WHAT_FOR_DO_YOU_NEED_IT",
++ "condition": {
++ "and": [
++ { "not": { "u_has_var": "prisoner_leader_mission", "type": "mission", "context": "military_id", "value": "yes" } },
++ {
++ "not": { "u_has_var": "prisoner_leader_mission", "type": "mission", "context": "accepted", "value": "yes" }
++ }
++ ]
++ }
++ },
++ {
++ "text": "Yeah, sure.",
++ "topic": "TALK_MISSION_OFFER",
++ "condition": {
++ "and": [
++ { "not": { "u_has_var": "prisoner_leader_mission", "type": "mission", "context": "military_id", "value": "yes" } },
++ {
++ "not": { "u_has_var": "prisoner_leader_mission", "type": "mission", "context": "accepted", "value": "yes" }
++ }
++ ]
++ }
++ },
++ {
++ "text": "I have a bad feeling about this. Sorry, I'll pass.",
++ "topic": "TALK_DONE",
++ "condition": { "not": { "u_has_var": "prisoner_leader_mission", "type": "mission", "context": "accepted", "value": "yes" } }
++ },
++ {
++ "text": "I'm on my way.",
++ "topic": "TALK_DONE",
++ "condition": {
++ "and": [
++ { "not": { "u_has_var": "prisoner_leader_mission", "type": "mission", "context": "military_id", "value": "yes" } },
++ { "u_has_var": "prisoner_leader_mission", "type": "mission", "context": "accepted", "value": "yes" }
++ ]
++ }
++ }
++ ]
++ },
++ {
++ "id": "TALK_PRISONER_LEADER_ASKED_ABOUT_SAFE_CONTENTS",
++ "type": "talk_topic",
++ "dynamic_line": [
++ "As I said, that's the thing I need. You don't need to know what's that exactly. Just grab all things you find in the safe, and call it a day."
++ ],
++ "responses": [
++ { "text": "That's weird.", "topic": "TALK_NONE" },
++ { "text": "I have a bad feeling about this. Sorry, I'll pass.", "topic": "TALK_DONE" }
++ ]
++ },
++ {
++ "id": "TALK_PRISONER_LEADER_ASKED_ABOUT_WHAT_FOR_DO_YOU_NEED_IT",
++ "type": "talk_topic",
++ "dynamic_line": [ "Let's say that's none of your <swear> business. Other questions?" ],
++ "responses": [
++ { "text": "That's weird.", "topic": "TALK_NONE" },
++ { "text": "I have a bad feeling about this. Sorry, I'll pass.", "topic": "TALK_DONE" }
++ ]
++ },
++ {
++ "id": "TALK_PRISONER_LEADER_SHOW_MILITARY_ID",
++ "type": "talk_topic",
++ "speaker_effect": { "effect": { "u_add_var": "prisoner_leader_mission", "type": "mission", "context": "military_id", "value": "yes" } },
++ "dynamic_line": [ "Hey, where did you get it? Nevermind, just give it to me. Just <swear> now." ],
++ "responses": [
++ {
++ "text": "Hey, no need to be hostile. Here you go, I don't need it anyway.",
++ "topic": "TALK_DONE",
++ "effect": { "u_sell_item": "id_military" }
++ },
++ {
++ "text": "I went through incredible hardships to get it. Please, can I keep this to myself?",
++ "trial": { "type": "PERSUADE", "difficulty": 5, "mod": [ [ "ALTRUISM", 3 ], [ "TRUST", 1 ] ] },
++ "failure": { "topic": "TALK_DONE", "effect": "hostile" },
++ "success": { "topic": "TALK_PRISONER_LEADER_TRIAL_SUCCESS" }
++ },
++ {
++ "text": "I killed tons of <zombies> while I was trying to get this thing. Do you really think you and your handful of losers pose a threat to me?",
++ "trial": { "type": "INTIMIDATE", "difficulty": 30, "mod": [ [ "BRAVERY", -1 ], [ "FEAR", 3 ] ] },
++ "failure": { "topic": "TALK_DONE", "effect": "hostile" },
++ "success": { "topic": "TALK_PRISONER_LEADER_TRIAL_SUCCESS" }
++ },
++ { "text": "What, <no>!", "topic": "TALK_DONE", "effect": "hostile" }
++ ]
++ },
++ {
++ "id": "TALK_PRISONER_LEADER_TRIAL_SUCCESS",
++ "type": "talk_topic",
++ "dynamic_line": [
++ "Okay. It was convincing. I'll still get what I want, one way or another. You better watch your back from now on."
++ ],
++ "responses": [ { "text": "Noted. Bye.", "topic": "TALK_DONE" } ]
++ },
++ {
++ "id": "TALK_PRISONER_LEADER_DEMANDED_SUBSTANTIAL_REWARD",
++ "type": "talk_topic",
++ "speaker_effect": { "effect": { "u_add_var": "prisoner_leader_mission", "type": "mission", "context": "military_id", "value": "yes" } },
++ "dynamic_line": [ "I'm afraid you're not in the position to demand anything from me, <name_b>. <get_lost>" ],
++ "responses": [
++ { "text": "Hey, <fuck_you>! You'll regret that!", "topic": "TALK_DONE", "effect": "hostile" },
++ { "text": "Okay, fine. Cheapskate!", "topic": "TALK_DONE" }
++ ]
++ },
++ {
++ "id": "MISSION_PRISONER_LEADER_GET_ID_CARD",
++ "type": "mission_definition",
++ "name": { "str": "Get The Thing from the chief's office" },
++ "difficulty": 1,
++ "value": 0,
++ "goal": "MGOAL_FIND_ITEM",
++ "item": "id_military",
++ "origins": [ "ORIGIN_SECONDARY" ],
++ "dialogue": {
++ "describe": "Here's the job…",
++ "offer": "My snitch whispered in my ear that the thing I need is located in the chief's safe in his office. You need to crack it open and bring the contents to me. Don't try to use anything you find in there! Just bring all the stuff to me, and I'll help you. Deal?",
++ "accepted": "Great! Don't forget that I need all stuff from the safe, try not to lose a thing.",
++ "rejected": "Fine, I'll get the thing in any case, sooner or later.",
++ "advice": "The chief's office is on the other side of the prison. I think the road there is full of <zombies>, so you better find a weapon. Also you probably will need some tools to crack the safe open.",
++ "inquire": "Did you get the stuff already?",
++ "success": "At last! Give me a few moments to check if it isn't damaged. Here, take this for your troubles.",
++ "success_lie": "Huh. This isn't going to work like I thought.",
++ "failure": "You're useless. I should've killed you when I met you."
++ },
++ "has_generic_rewards": false,
++ "start": { "effect": [ { "u_add_var": "prisoner_leader_mission", "type": "mission", "context": "accepted", "value": "yes" } ] },
++ "end": {
++ "effect": [
++ { "u_add_var": "prisoner_leader_mission", "type": "mission", "context": "completed", "value": "yes" },
++ { "u_lose_var": "prisoner_leader_mission", "type": "mission", "context": "accepted" },
++ { "u_buy_item": "can_beans", "container": "can_medium" }
++ ]
++ }
++ }
++]
+--- a/data/json/monsters/zed_prisoner.json
++++ b/data/json/monsters/zed_prisoner.json
+@@ -10,5 +10,32 @@
+ "color": "green",
+ "melee_dice_sides": 4,
+ "death_drops": "mon_zombie_prisoner_death_drops"
++ },
++ {
++ "id": "mon_zombie_prisoner_brute",
++ "type": "MONSTER",
++ "name": { "str": "prisoner brute" },
++ "description": "This muscular zombie wears black and white striped prisoner clothes.",
++ "copy-from": "mon_zombie_brute",
++ "looks_like": "mon_zombie_brute",
++ "death_drops": "mon_zombie_prisoner_death_drops"
++ },
++ {
++ "id": "mon_zombie_prisoner_fat",
++ "type": "MONSTER",
++ "name": { "str": "fat prisoner" },
++ "description": "This fat zombie wears black and white striped prisoner clothes.",
++ "copy-from": "mon_zombie_fat",
++ "looks_like": "mon_zombie_fat",
++ "death_drops": "mon_zombie_prisoner_death_drops"
++ },
++ {
++ "id": "mon_zombie_prisoner_tough",
++ "type": "MONSTER",
++ "name": { "str": "tough prisoner" },
++ "description": "This tough-looking zombie wears black and white striped prisoner clothes.",
++ "copy-from": "mon_zombie_tough",
++ "looks_like": "mon_zombie_tough",
++ "death_drops": "mon_zombie_prisoner_death_drops"
+ }
+ ]
+--- a/data/json/mapgen/prison_1.json
++++ b/data/json/mapgen/prison_1.json
+@@ -25,12 +25,12 @@
+ " s_____________________________________s+,,,,d,|--------+---|G|h|h|h|h| ",
+ " s_____________________________________s+,,,,dh|S,T|l,,,,,+<|,|g|g|g|g| ",
+ " s_____________________________________s|hhh,,,+,,,|l,,,,,--|,|h|h|h|h| ",
+- " s____Y____Y____Y____Y____Y____Y_______s|------|---|l,3333,l|,|,,,,,,,| ",
++ " s____Y____Y____Y____Y____Y____Y_______s|------|---|l,5555,l|,|,,,,,,,| ",
+ " s____Y____Y____Y____Y____Y____Y_______s|,,,,,,,,,,|l,,,,,,l|G|------G| ",
+- " s____Y____Y____Y____Y____Y____Y_______s@,,,,,,,,d,|l,3333,l|,,,,,,,|,| ",
++ " s____Y____Y____Y____Y____Y____Y_______s@,,,,,,,,d,|l,5555,l|,,,,,,,|,| ",
+ " s____Y____Y____Y____Y____Y____Y_______s@,,,,,,,,dh|l,,,,,,l|hth,hth|,| ",
+- " s____Y____Y____Y____Y____Y____Y_______s|,,,,,,,,d,|l,3333,l|hth,hth|,| ",
+- " sssssssssssssssssssssssssssssssssssssss|33333,,,,,|l,,,,,,l|,,,,,,,|,| ",
++ " s____Y____Y____Y____Y____Y____Y_______s|,,,,,,,,d,|l,5555,l|hth,hth|,| ",
++ " sssssssssssssssssssssssssssssssssssssss|55555,,,,,|l,,,,,,l|,,,,,,,|,| ",
+ " |---------------------------------------------@@-------@-----R-G-R--G| ",
+ " | f ss f s s s| ",
+ " | sssssssssssssssssssssssssssssssssHssssHsssssssssssssssssss| ",
+@@ -168,9 +168,20 @@
+ "^": "t_concrete",
+ "P": "t_concrete",
+ "Y": "t_pavement_y",
++ "C": "t_floor",
++ "L": "t_floor",
++ "5": "t_floor",
+ "Z": "t_door_bar_o"
+ },
+- "furniture": { "X": "f_exercise", "C": "f_counter", "P": "f_rack", "2": "f_home_furnace", "4": "f_water_heater", "L": "f_locker" },
++ "furniture": {
++ "X": "f_exercise",
++ "C": "f_counter",
++ "5": "f_bench",
++ "P": "f_rack",
++ "2": "f_home_furnace",
++ "4": "f_water_heater",
++ "L": "f_locker"
++ },
+ "items": {
+ "l": [
+ { "item": "prison_weapons", "chance": 30 },
+@@ -465,7 +476,14 @@
+ ],
+ "?": { "item": "autodoc_supplies", "chance": 100 }
+ },
+- "monster": { "Z": { "monster": "mon_zombie_prisoner" }, "C": { "monster": "mon_broken_cyborg" } }
++ "monster": {
++ "Z": [
++ { "monster": "mon_zombie_prisoner" },
++ { "monster": "mon_zombie_prisoner_fat" },
++ { "monster": "mon_zombie_prisoner_tough" }
++ ],
++ "C": { "monster": "mon_broken_cyborg" }
++ }
+ }
+ },
+ {
+@@ -602,7 +620,6 @@
+ "L": [ "t_floor" ],
+ "M": [ "t_floor" ],
+ "N": [ "t_floor" ],
+- "O": [ "t_floor" ],
+ "P": [ "t_floor" ],
+ "Q": [ "t_floor" ],
+ "R": [ "t_floor" ],
+@@ -628,7 +645,6 @@
+ "L": [ "f_drill_press" ],
+ "M": [ "f_heavy_lathe" ],
+ "N": [ "f_utility_shelf" ],
+- "O": [ "f_shredder" ],
+ "P": [ "f_workbench" ],
+ "Q": [ "f_cupboard" ],
+ "R": [ "f_locker" ],
+@@ -663,7 +679,7 @@
+ "U": { "item": "prison_canine_bowl", "chance": 70 },
+ "Y": { "item": "clothing_outdoor_torso", "chance": 60 },
+ "q": { "item": "trash_cart", "chance": 50, "repeat": [ 2, 3 ] },
+- "n": { "item": "oven", "chance": 70 },
++ "n": { "item": "SUS_oven", "chance": 70 },
+ "r": { "item": "cleaning", "chance": 50 },
+ ":": { "item": "animalshelter_toys", "chance": 5 },
+ "1": { "item": "office_paper", "chance": 50 },
+@@ -672,19 +688,39 @@
+ "2": [ { "item": "cannedfood", "chance": 70, "repeat": [ 1, 3 ] }, { "item": "pasta", "chance": 70, "repeat": [ 1, 3 ] } ]
+ },
+ "monster": {
+- ",": [ { "monster": "mon_zombie_cop", "chance": 1 }, { "monster": "mon_zombie_prisoner", "chance": 2 } ],
+- "_": [ { "monster": "mon_zombie_cop", "chance": 1 }, { "monster": "mon_zombie_prisoner", "chance": 2 } ],
+- "(": [ { "monster": "mon_zombie_cop", "chance": 1 }, { "monster": "mon_zombie_prisoner", "chance": 2 } ],
+- "#": [ { "monster": "mon_zombie_cop", "chance": 1 }, { "monster": "mon_zombie_prisoner", "chance": 2 } ],
++ ",": [
++ { "monster": "mon_zombie_cop", "chance": 1 },
++ { "monster": "mon_zombie_prisoner", "chance": 2 },
++ { "monster": "mon_zombie_prisoner_fat", "chance": 2 },
++ { "monster": "mon_zombie_prisoner_tough", "chance": 2 }
++ ],
++ "_": [
++ { "monster": "mon_zombie_cop", "chance": 1 },
++ { "monster": "mon_zombie_prisoner", "chance": 2 },
++ { "monster": "mon_zombie_prisoner_fat", "chance": 2 },
++ { "monster": "mon_zombie_prisoner_tough", "chance": 2 }
++ ],
++ "(": [
++ { "monster": "mon_zombie_cop", "chance": 1 },
++ { "monster": "mon_zombie_prisoner", "chance": 2 },
++ { "monster": "mon_zombie_prisoner_fat", "chance": 2 },
++ { "monster": "mon_zombie_prisoner_tough", "chance": 2 }
++ ],
++ "#": [
++ { "monster": "mon_zombie_cop", "chance": 1 },
++ { "monster": "mon_zombie_prisoner", "chance": 2 },
++ { "monster": "mon_zombie_prisoner_fat", "chance": 2 },
++ { "monster": "mon_zombie_prisoner_tough", "chance": 2 }
++ ],
+ "`": { "monster": "mon_zhark", "chance": 1 },
+ ".": { "monster": "mon_zombie_cop", "chance": 1 },
+- "^": { "monster": "mon_zombie_brute", "chance": 1 },
++ "^": { "monster": "mon_zombie_prisoner_brute", "chance": 1 },
+ " ": { "monster": "mon_dog_zombie_cop", "chance": 1 },
+ "U": { "monster": "mon_dog_gshepherd", "chance": 10 },
+ ":": { "monster": "mon_dog_gshepherd", "chance": 1 },
+ "<": { "monster": "mon_turret_riot" }
+ },
+- "place_monster": [ { "monster": "mon_zombie_hulk", "x": 45, "y": 3 }, { "monster": "mon_zombie_brute", "x": 60, "y": 56 } ],
++ "place_monster": [ { "monster": "mon_zombie_hulk", "x": 45, "y": 3 }, { "monster": "mon_zombie_prisoner_brute", "x": 60, "y": 56 } ],
+ "place_graffiti": [ { "text": "Dufresne was here", "x": 19, "y": 22 } ],
+ "computers": {
+ "a": {
+@@ -740,7 +776,7 @@
+ " ",
+ " ",
+ " ",
+- " 54444444444444444445 54444444444444444444444444445 ",
++ " Ю444444444444444444Ю Ю444444444444444444444444444Ю ",
+ " 1..................1 1...........................1 ",
+ " 1..................1 1...........................1 ",
+ " 1..................1 1...........................1 ",
+@@ -757,7 +793,7 @@
+ " wdh,,qw(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((wq,,hdw ",
+ " |-w+w-| |-w+w-| ",
+ " (^( (^( ",
+- " (^( 5444444444444444444444444444444444444444444444444444444444444444444444445 (^( ",
++ " (^( Ю44444444444444444444444444444444444444444444444444444444444444444444444Ю (^( ",
+ " (^( 1.......................................................................1 (^( ",
+ " (^( 1.......................................................................1 (^( ",
+ " (^( 1.......................................................................1 (^( ",
+@@ -783,10 +819,10 @@
+ " (^( 1.......................1 1...............................1 (^( ",
+ " (^( 1.......................1 1...............................1 (^( ",
+ " (^( 1.......................1 1...............................1 (^( ",
+- " (^( 54444444444441..........1 1...............................1 (^( ",
++ " (^( Ю4444444444441..........1 1...............................1 (^( ",
+ " (^( 1 1..........1 1...............................1 (^( ",
+ " (^( 1 1..........1 1...............................1 (^( ",
+- " (^( 1444444444444444444444445444444444444444544444444444444444444444444444445 (^( ",
++ " (^( 144444444444444444444444Ю444444444444444Ю4444444444444444444444444444444Ю (^( ",
+ " (^( (^( ",
+ " |-w+w-| |-w+w-| ",
+ " wdh,,qw(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((wq,,hdw ",
+@@ -806,7 +842,7 @@
+ "^": [ "t_concrete" ],
+ "1": [ "t_gutter_north" ],
+ "4": [ "t_gutter_west" ],
+- "5": [ "t_gutter_drop" ],
++ "Ю": [ "t_gutter_drop" ],
+ "q": [ "t_floor" ]
+ },
+ "furniture": { "q": [ "f_locker" ] },
+@@ -816,6 +852,682 @@
+ }
+ },
+ {
++ "type": "mapgen",
++ "method": "json",
++ "om_terrain": [
++ [ "prison_island_1_1", "prison_island_1_2", "prison_island_1_3", "prison_island_1_4", "prison_island_1_5" ],
++ [ "prison_island_1_6", "prison_island_1_7", "prison_island_1_8", "prison_island_1_9", "prison_island_1_10" ],
++ [ "prison_island_1_11", "prison_island_1_12", "prison_island_1_13", "prison_island_1_14", "prison_island_1_15" ]
++ ],
++ "object": {
++ "faction_owner": [ { "id": "prisoners", "x": [ 5, 18 ], "y": [ 33, 47 ] }, { "id": "prisoners", "x": [ 5, 18 ], "y": [ 48, 56 ] } ],
++ "fill_ter": "t_region_groundcover_barren",
++ "rows": [
++ "````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````",
++ "````````````###*********````````````````№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№````````````````````",
++ "```````*****###****#¦***```````````````№№''''''''''''''''''''''''''''''''''''''''''''''''''''''''''№````````````````````",
++ "``******###***##***#****``````````````№№'' |----------| '№№№№№'№````````````````````",
++ "``*####*###***##***#******####```````№№'' |7Б7Б77Б7Б7| '№..>№'№````````````````````",
++ "***########******###******######````№№'' |7Б7Б77Б7Б7| '№...№'№````````````````````",
++ "*#############*###################`№№'' |7ББББББББ7| '№№@№№'№````````````````````",
++ "*№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№'' |----?-----| '''''''№````````````````````",
++ "*№''''''''''''''''''''''''''''''''''' /|,,,,,,,,,,| ' №````````````````````",
++ "*№'№№№№№' |--g--|XXX,,,3333|/ ' №````````````````````",
++ "*№'№>пп№' |-----------------------------|,,,,,|----?-----|--------------------------| ' №````````````````````",
++ "*№'№ппп№' |bo|bo|bo|bo|bo|bo|bo|bo|bo|bo|,,,,,,,,,,,,,,,,|bo|bo|bo|bo|bo|bo|bo|bo|b<| ' №````````````````````",
++ "`№'№№@№№' |b,|b,|b,|b,|b,|b,|b,|b,|b,|b,|,,,,,,,,,,,,,,,,|b,|b,|b,|b,|b,|b,|b,|b,|b,| ' №````````````````````",
++ "`№''''''' |T,|T,|T,|T,|T,|T,|T,|T,|T,|T,|,,,|---@----|,,,|T,|T,|T,|T,|T,|T,|T,|T,|T,| ' №````````````````````",
++ "`№'' |-G|-G|-G|-G|-G|-G|-G|-G|-G|-G|,,,|h...Y.А%|,,,|-G|-G|-G|-G|-G|-G|-G|-G|-G| ' №````````````````````",
++ "`№'' |,,,,,,,,,,,,,,,,,,,,,,,,,,,,,|,,,|dd.....1|,,,|,,,,,,,,,,,,,,,,,,,,,,,,,,| ' №````````````````````",
++ "`№'' |,,,,,,,,,,,,,,,,,,,,,,,,,,,,,B,,,|.......1|,,,B,,,,,,,,,,,,,,,,,,,,,,,,,,| ' №````````````````````",
++ "`№'' g,,,3333,,,3333,,,3333,,,3333,G,,,|dh.11..6|,,,G,3333,,,3333,,,3333,,,3333g ' №````````````````````",
++ "`№'' |,,,,,,,,,,,,,,,,,,,,,,,,,,,,,B,,,|d..66...|,,,B,,,,,,,,,,,,,,,,,,,,,,,,,,| ' №````````````````````",
++ "`№'' |,,,,,,,,,,,,,,,,,,,,,,,,,,,,,|,,,|6h..h..6|,,,|,,,,,,,,,,,,,,,,,,,,,,,,,,| ' №````````````````````",
++ "`№'' |-G|-G|-G|-G|-G|-G|-G|-G|-G|-G|,,,|6.....h6|,,,|-G|-G|-G|-G|-G|-G|-G|-G|-G| ' №````````````````````",
++ "`№'' |T,|T,|T,|T,|T,|T,|T,|T,|T,|T,|,,,|--------|,,,|T,|T,|T,|T,|T,|T,|T,|T,|T,| ' №````````````````````",
++ "`№'' |b,|b,|b,|b,|b,|b,|b,|b,|b,|b,|,,,,,,,,,,,,,,,,|b,|b,|b,|b,|b,|b,|b,|b,|b,| ' №````````````````````",
++ "`№'' |bo|bo|bo|bo|bo|bo|bo|bo|bo|bo|,,,,,,,,,,,,,,,,|bo|bo|bo|bo|bo|bo|bo|bo|bo| ' №````````````````````",
++ "`№'' |-----------------------------|,,,,,,,,,,,,,,,,|-----------|--------------| ' №````````````````````",
++ "`№'' B^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|------BGGB------|,,,,,,,,,,,|Н,,,,,,?¡¡¡¡¡¿B ' №````````````````````",
++ "`№'' B^E^^^888^^^E^^^^^^^^^^^^^^^^^^|bbT|,,,,,,|Tbb|L,,,P,,P,,,M|dh,,,,н|-?|¡¡¿B ' №````````````````````",
++ "`№'' B^^^^^^^^^^^^^^^^^^^^^^^^^^^^^8|o,,G,,,,,,G,,o|,,,,P,,P,,,,|---?---|О,|¡¡¿B ' №````````````````````",
++ "`№'' B^E^^^888^^^E^^^^^^^^^^^^^^^^^8|---|,,3,,,|---|L,,,P,,P,,,M|,,,,,,,|--|-----|-| ' №````````````````````",
++ "`№'' B^^^^^^^^^^^^^^^^^^^^^^^^^^^^^8|bbT|,,3,,,|Tbb|,,,,P,,P,,,,|,,ttt,,|,,+,hgh,=,|/ ' №````````````````````",
++ "`№'' B^E^^^888^^^K^^^^^^^^^^^^^^^^^^|o,,G,,3,,,G,,o|L,,,P,,P,,,M|,,,,,,,|,,|-----|,|---|№№Ĝ№№````````````````````",
++ "`№'' / B^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|---|,,3,,,|---|,,,,,,,,,,,,|333,333|,,+,hgh,=,=,,3| ' №````````````````````",
++ "`№''|-------|------|-------|))_____)_____))|bbT|,,,,,,|Tbb|lll,,,,,NNNN|,,,,,,,|,,|-----|,|,,3| ' №№```````````````````",
++ "`№''|°°°°°°°°°°°°°°|o,,T,,o|_))____)____))_|o,,G,,,,,,G,,o|---|,,,|----|333,333|,,+,hgh,=,|,,3| ' №№ZZZZZZZ!!{!!ZZZZZZ",
++ "`№''|°33333°°33333°|bb,,,bb|__))___)___))__|---|,,,,,,|---|М,ММ,,,,мммм|---?---|@-|-----|-|,,,|''''''№!!!!!!!!!!!!!!!!!Z",
++ "`№''|°uuuuu°°uuuuu°|-o,3,o-|f__)___)___)__f|bbT|,,3,,,|Tbb|М,,,,,,,,,,,|^^^^^^^^^^Ĝ,,,,,,,,,,,g''''''B!!!!!!!!!!!!!!!!!Z",
++ "`№''|°33333°°33333°|bb,3,bb|__))___)___))__|o,,G,,3,,,G,,o|М,ММ,,,,,,,,@^^^^^^^^^^Ĝ,,,,,,,,,,,@''''''Ĝ!!!!!!!!!!!!!!!!!Z",
++ "`№''|°°°°°°°°°°°°°°|-o,3,o-|_))____)____))_|---|,,3,,,|---|М,ММ,,,,,,,,|^^^^^|-gg-|------|,,,,g''''''B!!!!!!!!!!!!!!!!!Z",
++ "`№''|°°°°°°°°°°°°°°|bb,3,bb|))_____)_____))|bbT|,,3,,,|Tbb|М,,,,,,,мммм|^^^^^|hd.6|qd...o|,,,,|''''''№!!!!!!!!!!!!!!!!!Z",
++ "`№''|°33333°°33333°|-o,,,o-|^^^^^^^^^^^^^^^|o,,G,,,,,,G,,o|М,ММ,,,,,,,,|^^^^^|.d.6|hd..h.?,,,,| ' №№ZZZZZZZ!!{!!ZZZZZZ",
++ "`№''|°uuuuu°°uuu°°°|bb,,,bb|^^^^^88888^^^^-|---|-BGGB-|---|---|-?-|мммм|^^^^^@...6|......|,,,,| ' №№```````````````````",
++ "`№''|°33333°°33333°|---G---|--G--|--------|^^^^^^^^^^^^|,X|777|,,,|----|-BĜB-|Y..1|%А.11Y|,,,А| ' №````````````````````",
++ "`№''|°°°°°°°°°°°°°°|^^^^^^^^^^^^^|66666611|^^^^^^^^^^^^|,X|БББ|Л,л|йББи|^^^^^|%...|----|-|-?--|№№Ĝ№№````````````````````",
++ "`№''|°°°°°°°°°°°°°°ПØ^^^^^^^^^^^^|..h..h..|^^^^^^^^^^^^|,X|Б77|Л,л|КБББ=^^^^^|66..|Аd.1|vV...J| ' №````````````````````",
++ "`№''|°°°°°°°°°°°°°°ПØ^^^^^^^^^^^^g........@^^^^^^^^^^^^?,,?Б77|Л,л|----|^^^^^|--|?|hd.1|......g ' №±±±±±±``````````````",
++ "`№''|°°°°°°°°°°°°°°|Ø^^^^^^^^^^^^|.h,.....|^^^^^^^^^^^^|,3|БББ|Л,л|КБББ=^^^|-|А%|'|....|...t,A| ' №`````}``````````````",
++ "`№''|°33333°°°°3u3°|^^^^^^^^^^^^^|ddd66А%Y|^^|---|^^^^^|,3|777|,,,|йББи|^^^|Y...|'|A..A|A..t,A| ' №`````}``````````````",
++ "`№''|°uuuuu°°°°3u3°|^^^^^^^^^^^^^|--------|^^|%dq|^^^^^|--|---|-@-|----|^^^@....|'|A..A|A..t,A| ' №`````}``````````````",
++ "`№''|°33333°°°°3u3°|^^^^^^^^^^^^^^^^^^^^^^^^^|hd,?^^^^^^^^^^^^^^^^^^^^^^^^^|1.d.|'|....?......g ''}!!!!µ±``````````````",
++ "`№''|°°°°°°°°°°°°°°|^^^^^^^^^^^^^^^^^^^^^^^^^|,,,|^^^^^^^^^^^^^^^^^^^^^^^^^|1.dH|'|11.%|qА%ooа| ''¶±±±±±±``````````````",
++ "`№''|-------??-----|ĜĜ|------|-ĜĜ-|---?--|---|,,,|^^^^^^^^^^^^^^^^^^^^^^^^^|o.dƼ|'|----|-|----| ' №````````````````````",
++ "`№'' /|22²²ИИИИ³³©©|''||00000|^^^^|x,,,,y|,s,s,,s|^^^^^^^^^^^^^^^^^^^^^^^^^|----|''''''''|дддД| ' №````````````````````",
++ "`№'' |°°°°°°°°°°°°|''}Ĝ....0|^^^^|x,,,,y|,h,h,,h|^^^^|-@---|^^^^^^^^^^^^^^?....|-?----|'|§¢¢¢| ' №````````````````````",
++ "`№'' g§°°°nnnn°°°°@''||....0|^^^^|,,,,,,|,,,,,,,|^^^^|%...6|^^^^^^^^^^^^^^|....|¢¢¢¢¥¢|'|--?-| ' №````````````````````",
++ "`№'' g§°°°nnnn°°°°|'a||00000|^^^^|DDDWWW|,s,s,,s|^^^^|...h6|^^^^^^^^^^^^^^|ЖЖЖЖ|оЁ£|''''''В ' №````````````````````",
++ "`№'' |°°°°°°°°°°°°|---------|^^^^|-------|h,h,,h|^^^^|А1ddd|----G----|-@--|----|---|--|ГВВВВВВ ' №````````````````````",
++ "`№'' |qqИИeeИИИИSS|b|b|b|b|b|^^^^|АAAAooo|------|-G--|--|gg|bo|,,,|ob|Y..А|S44|%.dq|/ ' №````````````````````",
++ "`№''|--------------|bobobobob|^^^^|,,,,,,,H|b,T|.....|T,b| |b,G,,,G,b|........?..dHg''''''''''''' №````````````````````",
++ "`№''|U|U|U|U|З...dd|,,,,,,,,,|^^^^?,,ddd,,,|b,,G.....G,,b| |,T|,,,|T,|........|....|' |w-|w-|w-|--№````````````````````",
++ "`№''|Г|Г|Г|Г|1....h|T,,3333,,G^^^^|%,,h,,,H|---|.....|---| |--|,,,|--|=-|=-|=-|m.1-|' |CI|CI|CI|Кй№````````````````````",
++ "`№''g..............|,,,,,,,,,|^^^^|--------|b,T|.....|T,b| |bo|,,,|ob|,c|,c|,c|m.З|'' |C.|C.|C.|ББ№````````````````````",
++ "`№''|..........|-@-|,obobobob|^^^^@......d5|b,,G.....G,,b| |b,G,,,G,b|,,|,,|,,|---|' |.h|.h|.h|ББ№````````````````````",
++ "`№''|QQQRRRcccS|/''|9|b|b|b|b|^^^^|-=|Y..dH|---|.....|---| |,T|,,,|T,|bb|bb|bb|/ '' /|.d|.d|.d|Би№````````````````````",
++ "`№''|-------g--|'''|---------|-ĜĜ-|ББ|.....|b,T|.ddd.|T,b| |--|---|--|--------| '|--|+-|+-|+-|=-№````````````````````",
++ "`№'''''''В::::::'''Г'''''''''''''/|йи|11.%q|b,,G.6h..G,,b|''''''''''''''''''''''''''+..............g````````````````````",
++ "`№'№№@№№'В:::::::::В ''' |-----g--|---|-----|---|' №№@№№ |+-|+-|+-|+-|=-№````````````````````",
++ "`№'№...№'В:;;;:::::В ''''''''''''''''''''''''''''' №...№ |.d|.d|.d|.d|БЙ№````````````````````",
++ "`№'№>..№'В:::::::::В '' №..>№ |.h|.h|.h|.h|ББ№````````````````````",
++ "`№'№№№№№'ВВВВВВВВВВВ '' №№№№№ |C.|C.|C.|C.|ББ№````````````````````",
++ "`№''''''''''''''''''''''''''' |CI|CI|CI|CI|Б7№````````````````````",
++ "`№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№g№№g№№g№№g№№№№№````````````````````",
++ "````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````"
++ ],
++ "palettes": [ "prison_palette" ],
++ "terrain": {
++ " ": [
++ [ "t_region_groundcover_urban", 20 ],
++ [ "t_region_groundcover_barren", 5 ],
++ [ "t_region_shrub", 2 ],
++ [ "t_region_tree", 1 ]
++ ],
++ "-": "t_brick_wall",
++ "|": "t_brick_wall",
++ "№": "t_concrete_wall",
++ ".": [ "t_floor" ],
++ ":": [ "t_region_groundcover_barren" ],
++ "#": [ "t_sand" ],
++ "*": [ "t_region_groundcover_barren" ],
++ ";": [ "t_trunk" ],
++ "/": [ "t_gutter_downspout" ],
++ "<": [ "t_slope_down" ],
++ "¦": [ "t_slope_down" ],
++ "§": [ "t_stairs_down" ],
++ "!": [ "t_dock" ],
++ "¡": [ "t_region_groundcover" ],
++ "¿": [ "t_shrub_rose" ],
++ "µ": [ "t_gates_control_metal" ],
++ "{": [ "t_dock" ],
++ ")": [ "t_pavement_y" ],
++ "}": [ "t_door_metal_locked" ],
++ "`": [ [ "t_water_dp", 20 ], "t_water_sh" ],
++ "^": [ "t_concrete" ],
++ "'": [ "t_concrete" ],
++ "Ø": [ "t_concrete" ],
++ "£": [ "t_thconc_floor" ],
++ "¢": [ "t_thconc_floor" ],
++ "¤": [ "t_thconc_floor" ],
++ "¥": [ "t_thconc_floor" ],
++ "²": [ "t_floor" ],
++ "³": [ "t_floor" ],
++ "©": [ "t_floor" ],
++ "°": [ "t_floor" ],
++ "¶": [ "t_card_industrial" ],
++ "@": [ "t_door_metal_pickable" ],
++ "?": [ "t_door_locked" ],
++ "%": [ "t_floor" ],
++ "±": [ "t_wall_metal" ],
++ "0": [ "t_floor" ],
++ "1": [ "t_floor" ],
++ "2": [ "t_floor" ],
++ "3": [ "t_floor" ],
++ "4": [ "t_floor" ],
++ "5": [ "t_floor" ],
++ "Ƽ": [ "t_floor" ],
++ "6": [ "t_console_broken" ],
++ "7": [ "t_floor" ],
++ "8": [ "t_concrete" ],
++ "9": [ "t_floor" ],
++ "a": [ "t_card_military" ],
++ "A": [ "t_floor" ],
++ "C": [ "t_floor" ],
++ "E": [ "t_concrete" ],
++ "f": [ "t_backboard" ],
++ "Ĝ": [ "t_door_bar_locked" ],
++ "G": [ "t_door_bar_c", "t_door_bar_o" ],
++ "H": [ "t_floor" ],
++ "I": [ "t_floor" ],
++ "J": [ "t_floor" ],
++ "K": [ "t_concrete" ],
++ "L": [ "t_floor" ],
++ "M": [ "t_floor" ],
++ "N": [ "t_floor" ],
++ "P": [ "t_floor" ],
++ "q": [ "t_floor" ],
++ "Q": [ "t_floor" ],
++ "R": [ "t_floor" ],
++ "s": [ "t_floor" ],
++ "u": [ "t_floor" ],
++ "U": [ "t_concrete" ],
++ "v": [ "t_floor" ],
++ "V": [ "t_floor" ],
++ "y": [ "t_floor" ],
++ "Y": [ "t_floor" ],
++ "x": [ "t_floor" ],
++ "X": [ "t_floor" ],
++ "Z": [ "t_fence_rope" ],
++ "А": [ "t_floor" ],
++ "а": [ "t_floor" ],
++ "Б": [ "t_linoleum_white" ],
++ "В": [ "t_chainfence" ],
++ "Г": [ "t_chaingate_l" ],
++ "Д": [ "t_sewage_pump" ],
++ "д": [ "t_sewage_pipe" ],
++ "Е": [ "t_water_pump" ],
++ "Ё": [ "t_thconc_floor" ],
++ "Ж": [ "t_floor" ],
++ "З": [ "t_floor" ],
++ "И": [ "t_floor" ],
++ "и": [ "t_linoleum_white" ],
++ "Й": [ "t_linoleum_white" ],
++ "й": [ "t_linoleum_white" ],
++ "К": [ "t_linoleum_white" ],
++ "Л": [ "t_floor" ],
++ "л": [ "t_floor" ],
++ "М": [ "t_floor" ],
++ "м": [ "t_floor" ],
++ "Н": [ "t_floor" ],
++ "н": [ "t_floor" ],
++ "О": [ "t_floor" ],
++ "о": [ "t_thconc_floor" ],
++ "П": [ "t_door_boarded" ],
++ "п": [ "t_floor" ]
++ },
++ "furniture": {
++ "²": [ "f_cupboard" ],
++ "³": [ "f_cupboard" ],
++ "©": [ "f_cupboard" ],
++ "<": [ "f_bookcase" ],
++ "{": [ "f_bitts" ],
++ "%": [ "f_air_conditioner" ],
++ "*": [ "f_boulder_large" ],
++ "Ø": [ "f_dumpster" ],
++ "0": [ "f_locker" ],
++ "1": [ "f_filing_cabinet" ],
++ "2": [ "f_cupboard" ],
++ "3": [ "f_metal_bench" ],
++ "4": [ "f_glass_fridge" ],
++ "5": [ "f_safe_l" ],
++ "Ƽ": [ "f_safe_l" ],
++ "7": [ "f_shower" ],
++ "8": [ "f_metal_bench" ],
++ "9": [ "f_dumpster" ],
++ "A": [ "f_sofa" ],
++ "C": [ "f_bed" ],
++ "H": [ "f_armchair" ],
++ "I": [ "f_dresser" ],
++ "J": [ "f_pinball_machine" ],
++ "K": [ "f_floor_canvas" ],
++ "L": [ "f_drill_press" ],
++ "M": [ "f_heavy_lathe" ],
++ "N": [ "f_utility_shelf" ],
++ "P": [ "f_workbench" ],
++ "q": [ "f_trashcan" ],
++ "Q": [ "f_cupboard" ],
++ "R": [ "f_locker" ],
++ "s": [ "f_desk" ],
++ "u": [ "f_table" ],
++ "U": [ "f_fiber_mat" ],
++ "x": [ "f_clothing_rail" ],
++ "X": [ "f_rack_coat" ],
++ "y": [ "f_locker" ],
++ "Y": [ "f_rack_coat" ],
++ "А": [ "f_speaker_cabinet" ],
++ "а": [ "f_fridge" ],
++ "Ж": [ "f_locker" ],
++ "З": [ "f_bookcase" ],
++ "И": [ "f_counter" ],
++ "и": [ "f_sink" ],
++ "Й": [ "f_rack_coat" ],
++ "й": [ "f_toilet" ],
++ "К": [ "f_trashcan" ],
++ "Л": [ "f_utility_shelf" ],
++ "л": [ "f_rack_coat" ],
++ "М": [ "f_crate_c" ],
++ "м": [ "f_crate_c" ],
++ "Н": [ "f_bookcase" ],
++ "н": [ "f_wardrobe" ],
++ "О": [ "f_locker" ],
++ "о": [ "f_locker" ],
++ "п": [ "f_bookcase" ]
++ },
++ "toilets": { "й": { } },
++ "place_item": [
++ { "item": "stethoscope", "x": 82, "y": 56, "chance": 100 },
++ { "item": "basketball", "x": [ 29, 41 ], "y": [ 32, 38 ], "chance": 100, "repeat": [ 1, 2 ] },
++ { "item": "baseball", "x": [ 28, 42 ], "y": [ 25, 28 ], "chance": 100, "repeat": [ 1, 3 ] },
++ { "item": "holy_symbol", "x": 74, "y": 29, "chance": 90 },
++ { "item": "holybook_bible1", "x": 75, "y": 29, "chance": 90 },
++ { "item": "icon", "x": 76, "y": 29, "chance": 90 },
++ { "item": "pliers", "x": 81, "y": 54, "chance": 100 },
++ { "item": "hammer", "x": 59, "y": 32, "chance": 100 },
++ { "item": "id_industrial", "x": 42, "y": 61, "chance": 100 },
++ { "item": "id_military", "x": 79, "y": 50, "chance": 100 },
++ { "item": "holster", "x": 79, "y": 50, "chance": 100 },
++ { "item": "m9", "x": 79, "y": 50, "chance": 100 },
++ { "item": "m9mag", "x": 79, "y": 50, "chance": 100 },
++ { "item": "9mm", "x": 79, "y": 50, "chance": 100 }
++ ],
++ "item": { "н": { "item": "cassock", "chance": 95 } },
++ "place_items": [
++ { "item": "table_destruction", "x": 16, "y": 40, "chance": 100 },
++ { "item": "table_destruction", "x": 17, "y": 40, "chance": 100 }
++ ],
++ "items": {
++ "²": { "item": "SUS_knife_drawer", "chance": 80 },
++ "³": { "item": "SUS_cookware", "chance": 80 },
++ "©": { "item": "SUS_spice_collection", "chance": 80 },
++ "Ø": { "item": "trash_cart", "chance": 50, "repeat": [ 2, 3 ] },
++ "c": { "item": "animalshelter_utility", "chance": 45, "repeat": [ 2, 3 ] },
++ "C": { "item": "bed", "chance": 70 },
++ "I": [ { "item": "cop_torso", "chance": 33 }, { "item": "cop_pants", "chance": 33 }, { "item": "cop_shoes", "chance": 33 } ],
++ "l": [ { "item": "hand_tools", "chance": 50 }, { "item": "tools_carpentry", "chance": 50 } ],
++ "m": [ { "item": "drugs_rare", "chance": 80, "repeat": [ 1, 2 ] } ],
++ "N": [ { "item": "hand_tools", "chance": 50 }, { "item": "tools_carpentry", "chance": 50 } ],
++ "n": { "item": "SUS_oven", "chance": 70 },
++ "q": { "item": "trash_cart", "chance": 50, "repeat": [ 2, 3 ] },
++ "Q": { "item": "prison_canine_food", "chance": 70, "repeat": [ 3, 5 ] },
++ "R": [
++ { "item": "animalshelter_softdrug", "chance": 70, "repeat": [ 1, 2 ] },
++ { "item": "animalshelter_hardrug", "chance": 30, "repeat": [ 1, 2 ] }
++ ],
++ "u": { "item": "mil_base_mess_hall", "chance": 30 },
++ "U": { "item": "prison_canine_bowl", "chance": 70 },
++ "x": [ { "item": "prison_textile", "chance": 90, "repeat": [ 1, 5 ] } ],
++ "Y": { "item": "clothing_outdoor_torso", "chance": 60 },
++ ":": { "item": "animalshelter_toys", "chance": 5 },
++ "0": [
++ { "item": "prison_weapons", "chance": 50, "repeat": [ 1, 3 ] },
++ { "item": "prison_armor", "chance": 50, "repeat": [ 1, 3 ] }
++ ],
++ "1": { "item": "SUS_office_filing_cabinet", "chance": 50 },
++ "2": { "item": "SUS_utensils", "chance": 80 },
++ "4": [ { "item": "softdrugs", "chance": 50 }, { "item": "harddrugs", "chance": 50 } ],
++ "5": { "item": "alcohol_bottled_canned", "chance": 95, "repeat": [ 1, 3 ] },
++ "9": { "item": "trash_cart", "chance": 50, "repeat": [ 2, 3 ] },
++ "а": { "item": "SUS_coffee_cupboard", "chance": 65 },
++ "Ж": { "item": "SUS_janitors_closet", "chance": 95 },
++ "З": { "item": "doctors_books", "chance": 75, "repeat": [ 1, 2 ] },
++ "Л": { "item": "prison_workshop_safety", "chance": 75 },
++ "л": { "item": "prison_jumpsuit", "chance": 75 },
++ "М": { "item": "wood_workshop", "chance": 75 },
++ "м": { "item": "supplies_metal", "chance": 75 },
++ "Н": { "item": "religious_books", "chance": 90, "repeat": [ 1, 3 ] },
++ "О": [
++ { "item": "tools_earthworking", "chance": 90, "repeat": [ 1, 2 ] },
++ { "item": "farming_tools", "chance": 90, "repeat": [ 1, 2 ] },
++ { "item": "hazmat_boots", "chance": 90 }
++ ],
++ "о": { "item": "tools_electronics", "chance": 90, "repeat": [ 1, 2 ] }
++ },
++ "vendingmachines": { "v": { "item_group": "vending_drink" }, "V": { "item_group": "vending_food" } },
++ "monster": {
++ ",": [
++ { "monster": "mon_zombie_prisoner", "chance": 2 },
++ { "monster": "mon_zombie_prisoner_fat", "chance": 2 },
++ { "monster": "mon_zombie_prisoner_tough", "chance": 2 }
++ ],
++ ".": { "monster": "mon_zombie_cop", "chance": 1 },
++ "¢": { "monster": "mon_zombie_technician", "chance": 20 },
++ "^": { "monster": "mon_zombie_prisoner_brute", "chance": 1 },
++ "`": { "monster": "mon_zhark", "chance": 1 },
++ ":": { "monster": "mon_dog_gshepherd", "chance": 1 },
++ "U": { "monster": "mon_dog_gshepherd", "chance": 10 },
++ "'": [ { "monster": "mon_dog_zombie_cop", "chance": 1 }, { "monster": "mon_zombie_cop", "chance": 1 } ]
++ },
++ "place_monster": [
++ { "monster": "mon_zombie_brute_shocker", "x": 65, "y": 36, "name": "The Foreman" },
++ { "monster": "mon_zombie_master", "x": 40, "y": 63, "name": "The Warden" },
++ { "monster": "mon_zombie_kevlar_2", "x": 77, "y": 48, "name": "The Chief" },
++ { "monster": "mon_zombie_scientist", "x": 81, "y": 58, "name": "The Doctor" },
++ { "monster": "mon_zombie_necro", "x": 75, "y": 28, "name": "The Priest" },
++ { "monster": "mon_zombie_prisoner_brute", "x": 50, "y": 33, "name": "The Bully" }
++ ],
++ "place_npcs": [
++ { "class": "prisoner_generic", "x": 17, "y": 53 },
++ { "class": "prisoner_greeter", "x": 17, "y": 43 },
++ { "class": "prisoner_generic", "x": 15, "y": 41 },
++ { "class": "prisoner_generic", "x": 10, "y": 41 },
++ { "class": "prisoner_generic", "x": 8, "y": 41 },
++ { "class": "prisoner_generic", "x": 9, "y": 53 },
++ { "class": "prisoner_generic", "x": 17, "y": 47 }
++ ],
++ "place_zones": [
++ { "type": "NPC_INVESTIGATE_ONLY", "faction": "prisoners", "x": [ 5, 18 ], "y": [ 33, 47 ] },
++ { "type": "NPC_INVESTIGATE_ONLY", "faction": "prisoners", "x": [ 5, 18 ], "y": [ 48, 56 ] }
++ ],
++ "nested": {
++ "^": { "chunks": [ [ "corpse_blood_3x3", 5 ], [ "null", 95 ] ] },
++ ".": { "chunks": [ [ "corpse_blood_3x3", 5 ], [ "null", 95 ] ] },
++ ",": { "chunks": [ [ "corpse_blood_3x3", 5 ], [ "null", 95 ] ] },
++ "'": { "chunks": [ [ "corpse_blood_3x3", 5 ], [ "null", 95 ] ] },
++ "Б": { "chunks": [ [ "corpse_blood_3x3", 5 ], [ "null", 95 ] ] }
++ },
++ "place_vehicles": [ { "vehicle": "boat_motor_single", "x": 100, "y": 45, "chance": 100, "status": 0 } ]
++ }
++ },
++ {
++ "type": "mapgen",
++ "method": "json",
++ "om_terrain": [
++ [
++ "prison_island_1_2f_1",
++ "prison_island_1_2f_2",
++ "prison_island_1_2f_3",
++ "prison_island_1_2f_4",
++ "prison_island_1_2f_5"
++ ],
++ [
++ "prison_island_1_2f_6",
++ "prison_island_1_2f_7",
++ "prison_island_1_2f_8",
++ "prison_island_1_2f_9",
++ "prison_island_1_2f_10"
++ ],
++ [
++ "prison_island_1_2f_11",
++ "prison_island_1_2f_12",
++ "prison_island_1_2f_13",
++ "prison_island_1_2f_14",
++ "prison_island_1_2f_15"
++ ]
++ ],
++ "object": {
++ "rows": [
++ " ",
++ " №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№ ",
++ " №№ № ",
++ " №№ |----------| 14w41 № ",
++ " №№ |..........| wd,<1 № ",
++ " №№ |..........| wdh,1 № ",
++ " №№ |..........| 14w41 № ",
++ " №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№ |..........| № ",
++ " № |..........| № ",
++ " № 14w41 |-----Ю..........| № ",
++ " № 1<,dw |-----------------------------|................Ю--------------------------| № ",
++ " № 1,hdw |.........................................................................| № ",
++ " № 14w41 |.........................................................................| № ",
++ " № |.........................................................................| № ",
++ " № |.........................................................................| № ",
++ " № |.........................................................................| № ",
++ " № |.........................................................................| № ",
++ " № |.........................................................................| № ",
++ " № |.........................................................................| № ",
++ " № |.........................................................................| № ",
++ " № |.........................................................................| № ",
++ " № |.........................................................................| № ",
++ " № |.........................................................................| № ",
++ " № |.........................................................................| № ",
++ " № |-----------------------------|....................................|------| № ",
++ " № |-...................................| № ",
++ " № |...................................|--| № ",
++ " № |......................................| № ",
++ " № |......................................|-------| № ",
++ " № |..............................................| № ",
++ " № |..............................................Ю---| № ",
++ " № |..................................................| № ",
++ " № |---Ю------------------| |..................................................| №№ ",
++ " № |......................| |..................................................| №№ ",
++ " № |......................| |...........................|----------|...........| № ",
++ " № |......................| |...........................| |...........| № ",
++ " № |......................| |...........................| |...........| № ",
++ " № |......................| |...........................| |----|...........| № ",
++ " № |......................| |...........................| |................| № ",
++ " № |......................| |...........................| |................| №№ ",
++ " № |......................| -|-----------|...............| |................| №№ ",
++ " № |..............|-------| |--------| |...............| |................| № ",
++ " № |..............| |........| |...............| |................| № ",
++ " № |..............| |........| |...............| |................| № ",
++ " № |..............| |........| |...............| |..|-|...........| № ",
++ " № |..............| |........| |...............| |-|..| |...........| №..... ",
++ " № |..............| |........| |---| |...............| |....| |...........| №..... ",
++ " № |..............| |--------| |...| |---------------| |....| |...........| №..... ",
++ " № |..............| |...| |....| |...........| №..... ",
++ " № |..............| |...| |....| |...........| № ",
++ " № |-Ю............|---------| |----------|...| |....| |------|....| № ",
++ " № |......................| |..............| |....| |....| № ",
++ " № |......................| |..............| |-----| |....|------| |....| № ",
++ " № |......................| |..............| |.....| |...........| |----| № ",
++ " № |......................| |..............| |.....| |...........| № ",
++ " № |......................| |..............| |.....|--------------|........Ю--| № ",
++ " № |......................| |..............|----|..|--|.......................| № ",
++ " № |-|......................| |......................| |.......................| № ",
++ " № |........................| |......................| |.......................| |----------|№ ",
++ " № |........................| |......................| |......................-| |..........|№ ",
++ " № |........................| |......................| |......................| |..........|№ ",
++ " № |..........|---|.........| |......................| |..................Ю---| |..........|№ ",
++ " № |..........| |.........| |......................| |..................| |..........|№ ",
++ " № |----------| |---------| |......................| |------------------| |--Ю..........|№ ",
++ " № |......................| |.............|№ ",
++ " № 14w41 Ю----------------------| 14w41 |.............|№ ",
++ " № 1,hdw wdh,1 |.............|№ ",
++ " № 1<,dw wd,<1 |.............|№ ",
++ " № 14w41 44w41 |.............|№ ",
++ " № |-------------|№ ",
++ " №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№ ",
++ " "
++ ],
++ "palettes": [ "prison_palette" ],
++ "terrain": {
++ " ": [ "t_open_air" ],
++ ".": [ "t_flat_roof" ],
++ "№": "t_concrete_wall",
++ "1": "t_brick_wall",
++ "4": "t_brick_wall",
++ "|": [ "t_gutter_north" ],
++ "-": [ "t_gutter_west" ],
++ "w": [ "t_metal_grate_window_noglass" ],
++ "Ю": [ "t_gutter_drop" ]
++ },
++ "item": { ".": { "item": "feces_bird", "chance": 2 } }
++ }
++ },
++ {
++ "type": "mapgen",
++ "method": "json",
++ "om_terrain": [
++ [
++ "prison_island_1_ug_1",
++ "prison_island_1_ug_2",
++ "prison_island_1_ug_3",
++ "prison_island_1_ug_4",
++ "prison_island_1_ug_5"
++ ],
++ [
++ "prison_island_1_ug_6",
++ "prison_island_1_ug_7",
++ "prison_island_1_ug_8",
++ "prison_island_1_ug_9",
++ "prison_island_1_ug_10"
++ ],
++ [
++ "prison_island_1_ug_11",
++ "prison_island_1_ug_12",
++ "prison_island_1_ug_13",
++ "prison_island_1_ug_14",
++ "prison_island_1_ug_15"
++ ]
++ ],
++ "object": {
++ "faction_owner": [ { "id": "prisoners", "x": [ 8, 23 ], "y": [ 50, 57 ] } ],
++ "rows": [
++ " ",
++ " ",
++ " @ ",
++ " ` |----------| ",
++ " ```````` |~~~~~~~~~~| ",
++ " ` |---|~|----| ",
++ " ``````` |~| ",
++ " ` |---|~|----| ",
++ " ``` |~~~~~~~~~~| ",
++ " ` |---|~|----| ",
++ " ` |~| ",
++ " ` |~| ",
++ " `` |---------------------------------------|~|-------------------------------| ",
++ " `` |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~@| ",
++ " ` |---------------------------------------|~|-------------------------------| ",
++ " `` |~| ",
++ " ` |~| ",
++ " ` |~| ",
++ " ` |~| ",
++ " ` |~| ",
++ " ` |---------------------------------------|~|-------------------------------| ",
++ " `` |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| ",
++ " ``` |--------------------------------|~|-------------------|~|----------------| ",
++ " `` |~| |~| ",
++ " ` ^^^^^^ |~| |~| ",
++ " `` ^ ^^^^' |~| |~| ",
++ " ` ^ ' |~| |~| ",
++ " ``` ^ ' |~| |~| ",
++ " `` ^^^^^^^^^ ' |~| |~| ",
++ " ` ^ ^ ' |~| |~| ",
++ " ` ^ ^ '' |~| |~| ",
++ " ` ^ ' |~| |~| ",
++ " ` ^^^^ '' |~| |~| ",
++ " `` ^^^^^^^ ' |~| |~| ",
++ " ` ^^^ ^^^^^^^^ '' |~| |~| ",
++ " ` ^^^ ^^ ^ ' |~| |~| ",
++ " `` ^^^ ^^ ^ ' |~| |~| ",
++ " ` ^^^ ^ ' |~| |~| ",
++ " ` ^^^ ^ ' |~| |~| ",
++ " ` ^^^ ^^ ' |~| |~| ",
++ " ` ^^^````` ^^ '' |~| |-| |~| ",
++ " ` ````` '' |~| |~| |~| ",
++ " ``````````` '' |~|-----------|~|-----|~| ",
++ " ' |~~~~~~~~~~~~~~~~~~~~~~~| ",
++ " '' |~|-----------|~|-----|~| ",
++ " '' |~| |~| |~| ",
++ " ' |~| |~| |~| ",
++ " ' |~| |-| |~| ",
++ " ' |~| |~| ",
++ " !!!!!!!!!!!!!!!!! '''' |~| |~| |----| ",
++ " !1.2!3.4!5.6!7.8! ' |------------|~|--------------------~|-------------------|____| ",
++ " !1:2!3:4!5:6!7:8! ' |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~д___| ",
++ " !!!!?!!!?!!!?!!!?!! '' |~|---|~|----|~|-------------------|~|-----------------|~|>___| ",
++ " !>.d..:.......:...! ''' |~| ||~|| |~| |~| |~|----| ",
++ " !>.h..:.......:...! ' |~| |~~~| |~| |~| |~| ",
++ " !!!!?!!!?!!!?!!!?!! |--/---~| |---| |~| |~| |~| ",
++ " !9:9!0:A!B:C!D:D! |~~~~~~~| |~| |~| |~| ",
++ " !9.9!0.A!B.C!D.D! |-------| |~| |~| |~| ",
++ " !!!!!!!!!!!!!!!!! |~| |~| |~| ",
++ " |~| |~| |~| ",
++ " |~| |~| |~| ",
++ " |~| |~| |~| ",
++ " |-------------------------------|~|-------------------|~|-----------------|~|---------| ",
++ " |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| ",
++ " |-----------------------------------------------------------------------------------|~| ",
++ " |~| ",
++ " |~| ",
++ " |~| ",
++ " |~| ",
++ " |~| ",
++ " |-| ",
++ " "
++ ],
++ "palettes": [ "prison_palette" ],
++ "terrain": {
++ " ": [ "t_rock" ],
++ "^": [ "t_rock_floor" ],
++ "_": [ "t_grate" ],
++ "~": [ "t_sewage" ],
++ "'": [ "t_water_sh_murky_underground" ],
++ "`": [ "t_swater_dp_underground" ],
++ "|": [ "t_brick_wall" ],
++ "-": [ "t_brick_wall" ],
++ "/": [ "t_brick_wall_halfway" ],
++ ">": [ "t_stairs_up" ],
++ "@": [ "t_slope_up" ],
++ ".": [ "t_thconc_floor" ],
++ ":": [ "t_thconc_floor_olight" ],
++ "!": [ "t_concrete_wall" ],
++ "?": [ "t_door_bar_locked" ],
++ "1": [ "t_thconc_floor" ],
++ "2": [ "t_thconc_floor" ],
++ "3": [ "t_thconc_floor" ],
++ "4": [ "t_thconc_floor" ],
++ "5": [ "t_thconc_floor" ],
++ "6": [ "t_thconc_floor" ],
++ "7": [ "t_thconc_floor" ],
++ "8": [ "t_thconc_floor" ],
++ "9": [ "t_thconc_floor" ],
++ "0": [ "t_thconc_floor" ],
++ "A": [ "t_thconc_floor" ],
++ "B": [ "t_thconc_floor" ],
++ "C": [ "t_thconc_floor" ],
++ "D": [ "t_thconc_floor" ],
++ "d": [ "t_thconc_floor" ],
++ "h": [ "t_thconc_floor" ],
++ "д": [ "t_sewage_pipe" ]
++ },
++ "furniture": {
++ "1": "f_crate_o",
++ "2": "f_crate_o",
++ "3": "f_crate_o",
++ "4": "f_crate_o",
++ "5": "f_crate_o",
++ "6": "f_crate_o",
++ "7": "f_crate_o",
++ "8": "f_crate_o",
++ "9": "f_utility_shelf",
++ "0": "f_utility_shelf",
++ "A": "f_utility_shelf",
++ "B": "f_utility_shelf",
++ "C": "f_utility_shelf",
++ "D": "f_fridge"
++ },
++ "item": {
++ "1": { "item": "carrot", "chance": 95, "repeat": [ 1, 20 ] },
++ "2": { "item": "potato", "chance": 95, "repeat": [ 1, 20 ] },
++ "3": { "item": "onion", "chance": 95, "repeat": [ 1, 20 ] },
++ "4": { "item": "cabbage", "chance": 95, "repeat": [ 1, 20 ] },
++ "5": { "item": "corn", "chance": 95, "repeat": [ 1, 20 ] },
++ "6": { "item": "garlic", "chance": 95, "repeat": [ 1, 10 ] },
++ "7": { "item": "apple", "chance": 95, "repeat": [ 1, 20 ] },
++ "8": { "item": "lemon", "chance": 95, "repeat": [ 1, 10 ] }
++ },
++ "items": {
++ "9": { "item": "SUS_pantry", "chance": 95 },
++ "0": { "item": "teashop_bulk_teas", "chance": 95, "repeat": [ 1, 20 ] },
++ "A": { "item": "groce_ingredient", "chance": 95, "repeat": [ 1, 20 ] },
++ "B": { "item": "groce_bread", "chance": 95, "repeat": [ 1, 20 ] },
++ "C": { "item": "groce_cereal", "chance": 95, "repeat": [ 1, 20 ] },
++ "D": { "item": "butcher_raw_meat", "chance": 95, "repeat": [ 1, 20 ] },
++ "d": { "item": "magazines", "chance": 50 }
++ },
++ "monster": { "~": { "monster": "mon_sewer_fish", "chance": 2 }, "'": { "monster": "mon_sewer_snake", "chance": 10 } },
++ "place_npcs": [
++ { "class": "prisoner_leader", "x": 9, "y": 54 },
++ { "class": "prisoner_generic", "x": 14, "y": 53 },
++ { "class": "prisoner_generic", "x": 18, "y": 54 },
++ { "class": "prisoner_generic", "x": 22, "y": 53 }
++ ]
++ }
++ },
++ {
++ "id": "table_destruction",
++ "type": "item_group",
++ "subtype": "collection",
++ "items": [
++ { "item": "2x4", "count": [ 2, 4 ] },
++ { "item": "wood_panel", "count": [ 0, 1 ] },
++ { "item": "nail", "charges": [ 4, 8 ] },
++ { "item": "splinter", "count": 1 }
++ ]
++ },
++ {
+ "id": "prison_canine_food",
+ "type": "item_group",
+ "items": [ { "item": "dogfood", "prob": 100, "container-item": "can_medium" } ]
+@@ -839,5 +1552,63 @@
+ [ "jerky", 40 ],
+ [ "rope_6", 15 ]
+ ]
++ },
++ {
++ "type": "item_group",
++ "id": "prison_workshop_safety",
++ "subtype": "collection",
++ "items": [
++ { "item": "mask_dust", "prob": 75, "damage": [ 1, 4 ] },
++ { "item": "gloves_work", "prob": 75, "damage": [ 1, 4 ] },
++ { "item": "glasses_safety", "prob": 75, "damage": [ 1, 4 ] }
++ ]
++ },
++ {
++ "id": "prison_jumpsuit",
++ "type": "item_group",
++ "items": [ { "item": "jumpsuit", "prob": 75, "damage": [ 1, 4 ] } ]
++ },
++ {
++ "type": "item_group",
++ "id": "prisoner_or_cop_clothes",
++ "subtype": "collection",
++ "entries": [
++ { "group": "male_underwear", "damage": [ 1, 4 ] },
++ {
++ "distribution": [
++ {
++ "collection": [
++ { "item": "striped_shirt", "damage": [ 1, 4 ] },
++ { "item": "striped_pants", "damage": [ 1, 4 ] },
++ { "group": "clothing_prisoner_shoes", "damage": [ 1, 4 ], "prob": 20 },
++ { "item": "bandana", "damage": [ 1, 4 ] }
++ ]
++ },
++ {
++ "collection": [
++ { "group": "cop_pants", "damage": [ 1, 4 ] },
++ { "group": "cop_shoes", "damage": [ 1, 4 ], "prob": 20 },
++ { "group": "cop_torso", "damage": [ 1, 4 ] },
++ { "group": "clothing_watch", "prob": 20 },
++ { "item": "police_belt", "damage": [ 1, 4 ], "prob": 20 }
++ ]
++ }
++ ],
++ "prob": 90
++ },
++ { "group": "socks_unisex", "damage": [ 1, 4 ] },
++ { "group": "clothing_glasses", "prob": 20 },
++ { "item": "corpse_generic_human", "damage": 4 }
++ ]
++ },
++ {
++ "type": "mapgen",
++ "method": "json",
++ "nested_mapgen_id": "corpse_blood_3x3",
++ "object": {
++ "mapgensize": [ 3, 3 ],
++ "place_items": [ { "item": "prisoner_or_cop_clothes", "x": 0, "y": 0, "chance": 30 } ],
++ "place_fields": [ { "field": "fd_blood", "x": [ 0, 2 ], "y": [ 0, 2 ], "intensity": 1, "age": 10 } ]
++ }
+ }
+ ]
+--- a/data/json/overmap/overmap_special/specials.json
++++ b/data/json/overmap/overmap_special/specials.json
+@@ -948,6 +982,67 @@
+ },
+ {
+ "type": "overmap_special",
++ "id": "Island prison",
++ "overmaps": [
++ { "point": [ -1, -1, 0 ], "overmap": "lake_surface" },
++ { "point": [ 0, -1, 0 ], "overmap": "lake_surface" },
++ { "point": [ 1, -1, 0 ], "overmap": "lake_surface" },
++ { "point": [ 2, -1, 0 ], "overmap": "lake_surface" },
++ { "point": [ 3, -1, 0 ], "overmap": "lake_surface" },
++ { "point": [ 4, -1, 0 ], "overmap": "lake_surface" },
++ { "point": [ 5, -1, 0 ], "overmap": "lake_surface" },
++ { "point": [ 5, 0, 0 ], "overmap": "lake_surface" },
++ { "point": [ 5, 1, 0 ], "overmap": "lake_surface" },
++ { "point": [ 5, 2, 0 ], "overmap": "lake_surface" },
++ { "point": [ 5, 3, 0 ], "overmap": "lake_surface" },
++ { "point": [ 4, 3, 0 ], "overmap": "lake_surface" },
++ { "point": [ 3, 3, 0 ], "overmap": "lake_surface" },
++ { "point": [ 2, 3, 0 ], "overmap": "lake_surface" },
++ { "point": [ 1, 3, 0 ], "overmap": "lake_surface" },
++ { "point": [ 0, 3, 0 ], "overmap": "lake_surface" },
++ { "point": [ -1, 3, 0 ], "overmap": "lake_surface" },
++ { "point": [ -1, 2, 0 ], "overmap": "lake_surface" },
++ { "point": [ -1, 1, 0 ], "overmap": "lake_surface" },
++ { "point": [ -1, 0, 0 ], "overmap": "lake_surface" },
++ { "point": [ 0, 0, 0 ], "overmap": "prison_island_1_1_north" },
++ { "point": [ 1, 0, 0 ], "overmap": "prison_island_1_2_north" },
++ { "point": [ 2, 0, 0 ], "overmap": "prison_island_1_3_north" },
++ { "point": [ 3, 0, 0 ], "overmap": "prison_island_1_4_north" },
++ { "point": [ 4, 0, 0 ], "overmap": "prison_island_1_5_north" },
++ { "point": [ 0, 1, 0 ], "overmap": "prison_island_1_6_north" },
++ { "point": [ 1, 1, 0 ], "overmap": "prison_island_1_7_north" },
++ { "point": [ 2, 1, 0 ], "overmap": "prison_island_1_8_north" },
++ { "point": [ 3, 1, 0 ], "overmap": "prison_island_1_9_north" },
++ { "point": [ 4, 1, 0 ], "overmap": "prison_island_1_10_north" },
++ { "point": [ 0, 2, 0 ], "overmap": "prison_island_1_11_north" },
++ { "point": [ 1, 2, 0 ], "overmap": "prison_island_1_12_north" },
++ { "point": [ 2, 2, 0 ], "overmap": "prison_island_1_13_north" },
++ { "point": [ 3, 2, 0 ], "overmap": "prison_island_1_14_north" },
++ { "point": [ 4, 2, 0 ], "overmap": "prison_island_1_15_north" },
++ { "point": [ 0, 0, 1 ], "overmap": "prison_island_1_2f_1_north" },
++ { "point": [ 1, 0, 1 ], "overmap": "prison_island_1_2f_2_north" },
++ { "point": [ 2, 0, 1 ], "overmap": "prison_island_1_2f_3_north" },
++ { "point": [ 3, 0, 1 ], "overmap": "prison_island_1_2f_4_north" },
++ { "point": [ 4, 0, 1 ], "overmap": "prison_island_1_2f_5_north" },
++ { "point": [ 0, 1, 1 ], "overmap": "prison_island_1_2f_6_north" },
++ { "point": [ 1, 1, 1 ], "overmap": "prison_island_1_2f_7_north" },
++ { "point": [ 2, 1, 1 ], "overmap": "prison_island_1_2f_8_north" },
++ { "point": [ 3, 1, 1 ], "overmap": "prison_island_1_2f_9_north" },
++ { "point": [ 4, 1, 1 ], "overmap": "prison_island_1_2f_10_north" },
++ { "point": [ 0, 2, 1 ], "overmap": "prison_island_1_2f_11_north" },
++ { "point": [ 1, 2, 1 ], "overmap": "prison_island_1_2f_12_north" },
++ { "point": [ 2, 2, 1 ], "overmap": "prison_island_1_2f_13_north" },
++ { "point": [ 3, 2, 1 ], "overmap": "prison_island_1_2f_14_north" },
++ { "point": [ 4, 2, 1 ], "overmap": "prison_island_1_2f_15_north" }
++ ],
++ "locations": [ "lake_surface" ],
++ "city_distance": [ 3, -1 ],
++ "city_sizes": [ 4, 12 ],
++ "occurrences": [ 15, 100 ],
++ "flags": [ "CLASSIC", "LAKE", "UNIQUE" ]
++ },
++ {
++ "type": "overmap_special",
+ "id": "Prison Hidden Lab",
+ "overmaps": [
+ { "point": [ 0, -1, 0 ], "overmap": "road_end_north" },
+--- a/data/json/overmap/overmap_terrain/overmap_terrain_public_institutional.json
++++ b/data/json/overmap/overmap_terrain/overmap_terrain_public_institutional.json
+@@ -256,7 +285,52 @@
+ "prison_alcatraz_12_2f",
+ "prison_alcatraz_13_2f",
+ "prison_alcatraz_14_2f",
+- "prison_alcatraz_15_2f"
++ "prison_alcatraz_15_2f",
++ "prison_island_1_1",
++ "prison_island_1_2",
++ "prison_island_1_3",
++ "prison_island_1_4",
++ "prison_island_1_5",
++ "prison_island_1_6",
++ "prison_island_1_7",
++ "prison_island_1_8",
++ "prison_island_1_9",
++ "prison_island_1_10",
++ "prison_island_1_11",
++ "prison_island_1_12",
++ "prison_island_1_13",
++ "prison_island_1_14",
++ "prison_island_1_15",
++ "prison_island_1_2f_1",
++ "prison_island_1_2f_2",
++ "prison_island_1_2f_3",
++ "prison_island_1_2f_4",
++ "prison_island_1_2f_5",
++ "prison_island_1_2f_6",
++ "prison_island_1_2f_7",
++ "prison_island_1_2f_8",
++ "prison_island_1_2f_9",
++ "prison_island_1_2f_10",
++ "prison_island_1_2f_11",
++ "prison_island_1_2f_12",
++ "prison_island_1_2f_13",
++ "prison_island_1_2f_14",
++ "prison_island_1_2f_15",
++ "prison_island_1_ug_1",
++ "prison_island_1_ug_2",
++ "prison_island_1_ug_3",
++ "prison_island_1_ug_4",
++ "prison_island_1_ug_5",
++ "prison_island_1_ug_6",
++ "prison_island_1_ug_7",
++ "prison_island_1_ug_8",
++ "prison_island_1_ug_9",
++ "prison_island_1_ug_10",
++ "prison_island_1_ug_11",
++ "prison_island_1_ug_12",
++ "prison_island_1_ug_13",
++ "prison_island_1_ug_14",
++ "prison_island_1_ug_15"
+ ],
+ "name": "prison",
+ "sym": "p",
+--- a/data/json/start_locations.json
++++ b/data/json/start_locations.json
+@@ -303,11 +348,17 @@
+ {
+ "type": "start_location",
+ "id": "sloc_prison_alcatraz",
+- "name": "Island prison",
++ "name": "Island prison type A",
+ "terrain": [ "prison_alcatraz_3" ]
+ },
+ {
+ "type": "start_location",
++ "id": "sloc_prison_island",
++ "name": "Island prison type B",
++ "terrain": [ "prison_island_1_1" ]
++ },
++ {
++ "type": "start_location",
+ "id": "sloc_mi-go_camp",
+ "name": "Mi-go camp",
+ "terrain": [ "mi-go_camp1" ]
diff --git a/npc-05_kindred-update.patch b/npc-05_kindred-update.patch
new file mode 100644
index 0000000..8b728b4
--- /dev/null
+++ b/npc-05_kindred-update.patch
@@ -0,0 +1,1198 @@
+--- a/data/json/npcs/Kindred/NPC_Brigitte_LaCroix.json
++++ b/data/json/npcs/Kindred/NPC_Brigitte_LaCroix.json
+@@ -0,0 +1,553 @@
++[
++ {
++ "type": "npc_class",
++ "id": "NC_BONE_SEER",
++ "name": { "str": "Bone Seer" },
++ "job_description": "I wish to sing the song of the Bones",
++ "traits": [
++ { "trait": "OUTDOORSMAN" },
++ { "trait": "HEAVYSLEEPER" },
++ { "trait": "GOODCARDIO" },
++ { "trait": "LIGHTSTEP" },
++ { "trait": "ROBUST" },
++ { "trait": "SKIN_DARK" },
++ { "trait": "seer_mark" },
++ { "trait": "hair_black_mohawk" }
++ ],
++ "common": false,
++ "bonus_per": { "rng": [ 0, 2 ] },
++ "bonus_str": { "rng": [ 0, 2 ] },
++ "bonus_int": { "rng": [ 0, 2 ] },
++ "worn_override": "BONE_SEER_Brigitte_worn",
++ "weapon_override": "BONE_SEER_Brigitte_wield",
++ "shopkeeper_item_group": "NC_BONE_SEER_misc",
++ "skills": [
++ {
++ "skill": "ALL",
++ "level": { "mul": [ { "one_in": 3 }, { "sum": [ { "dice": [ 2, 2 ] }, { "constant": -2 }, { "one_in": 4 } ] } ] }
++ },
++ { "skill": "survival", "bonus": { "rng": [ 2, 4 ] } },
++ { "skill": "dodge", "bonus": { "rng": [ 4, 8 ] } },
++ { "skill": "melee", "bonus": { "rng": [ 6, 8 ] } },
++ { "skill": "bashing", "bonus": { "rng": [ 3, 6 ] } },
++ { "skill": "cutting", "bonus": { "rng": [ 3, 6 ] } }
++ ]
++ },
++ {
++ "type": "item_group",
++ "id": "BONE_SEER_Brigitte_worn",
++ "subtype": "collection",
++ "entries": [
++ { "item": "boxer_briefs" },
++ { "item": "socks" },
++ { "item": "tshirt_tour" },
++ { "item": "jacket_leather_bone" },
++ { "item": "gloves_liner" },
++ { "item": "helmet_skull" },
++ { "item": "gloves_leather" },
++ { "item": "pants_leather" },
++ { "item": "boots_bone" },
++ { "item": "backpack_leather" }
++ ]
++ },
++ {
++ "type": "item_group",
++ "id": "BONE_SEER_Brigitte_wield",
++ "subtype": "collection",
++ "entries": [ { "item": "2h_flail_steel" } ]
++ },
++ {
++ "type": "item_group",
++ "id": "NC_BONE_SEER_misc",
++ "subtype": "distribution",
++ "entries": [
++ { "item": "needle_bone", "prob": 40 },
++ { "item": "bone_glue", "prob": 20 },
++ { "item": "bone_flute", "prob": 10 },
++ { "item": "bone_human", "prob": 10 },
++ { "item": "broth_bone", "prob": 60 },
++ { "item": "water_clean", "prob": 90 }
++ ]
++ },
++ {
++ "type": "mutation",
++ "id": "seer_mark",
++ "name": { "str": "Mark of the Seer" },
++ "points": 1,
++ "description": "A strange occult symbol carved into your hand by Brigitte LaCroix.",
++ "starting_trait": false,
++ "valid": false,
++ "purifiable": false
++ },
++ {
++ "type": "npc",
++ "id": "SEER_Brigitte_LaCroix",
++ "//": "A mysterious member of a doomsday cult.",
++ "name_unique": "Brigitte LaCroix",
++ "gender": "female",
++ "name_suffix": "Bone Seer",
++ "class": "NC_BONE_SEER",
++ "attitude": 7,
++ "mission": 3,
++ "chat": "TALK_BONE_SEER",
++ "faction": "no_faction",
++ "mission_offered": "MISSION_SEER_GATHER_BONE"
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_BONE_SEER",
++ "dynamic_line": {
++ "u_has_var": "talked_to_seer",
++ "type": "dialogue",
++ "context": "first_meeting",
++ "value": "yes",
++ "no": "You there. Quiet down. Can you hear it? The song?",
++ "yes": {
++ "u_has_var": "asked_about_song",
++ "type": "dialogue",
++ "context": "song",
++ "value": "yes",
++ "no": "You're back. Have you come to listen to the song?",
++ "yes": {
++ "u_has_trait": "seer_mark",
++ "no": "Traveller.",
++ "yes": { "u_female": true, "yes": "Greetings, sister.", "no": "Greetings, brother." }
++ }
++ }
++ },
++ "speaker_effect": { "effect": { "u_add_var": "talked_to_seer", "type": "dialogue", "context": "first_meeting", "value": "yes" } },
++ "responses": [
++ {
++ "text": "What song?",
++ "topic": "TALK_BONE_SEER_SONG",
++ "condition": { "not": { "u_has_var": "asked_about_song", "type": "dialogue", "context": "song", "value": "yes" } }
++ },
++ {
++ "text": "So about the songs…",
++ "topic": "TALK_BONE_SEER_SONG2",
++ "condition": { "u_has_var": "asked_about_song", "type": "dialogue", "context": "song", "value": "yes" }
++ },
++ {
++ "text": "Do others follow this belief as well?",
++ "topic": "TALK_BONE_SEER_OTHERS",
++ "condition": { "u_has_var": "asked_about_song", "type": "dialogue", "context": "song", "value": "yes" }
++ },
++ {
++ "text": "Can you tell me more about yourself?",
++ "topic": "TALK_BONE_SEER_ABOUT",
++ "condition": { "u_has_var": "asked_about_song", "type": "dialogue", "context": "song", "value": "yes" }
++ },
++ {
++ "text": "You mentioned some cycle before. What does that mean?",
++ "topic": "TALK_BONE_SEER_CYCLE",
++ "condition": { "u_has_var": "asked_about_song", "type": "dialogue", "context": "song", "value": "yes" }
++ },
++ {
++ "text": "I've met Cooper.",
++ "topic": "TALK_BONE_SEER_METCOOPER",
++ "condition": {
++ "and": [
++ { "u_has_var": "talked_to_cooper", "type": "dialogue", "context": "first_meeting", "value": "yes" },
++ { "u_has_var": "knows_cooper", "type": "dialogue", "context": "kindred_cooper", "value": "yes" }
++ ]
++ }
++ },
++ {
++ "text": "Would you like to join me on my travels?",
++ "topic": "TALK_SUGGEST_FOLLOW_SEER",
++ "condition": {
++ "and": [
++ { "not": "npc_following" },
++ { "u_has_var": "asked_about_song", "type": "dialogue", "context": "song", "value": "yes" }
++ ]
++ }
++ },
++ {
++ "text": "Is there a way I can help you with your song?",
++ "topic": "TALK_MISSION_LIST_SEER",
++ "condition": { "u_has_var": "asked_about_song", "type": "dialogue", "context": "song", "value": "yes" }
++ },
++ {
++ "text": "I have to go.",
++ "topic": "TALK_DONE",
++ "condition": { "not": { "u_has_var": "asked_about_song", "type": "dialogue", "context": "song", "value": "yes" } }
++ },
++ {
++ "text": "I have to get going. Take care, Seer.",
++ "topic": "TALK_DONE",
++ "condition": { "u_has_var": "asked_about_song", "type": "dialogue", "context": "song", "value": "yes" }
++ }
++ ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_BONE_SEER_SONG",
++ "dynamic_line": "Listen carefully. The bones… they hum. Can you hear it? The song they weave? The stories they hold?",
++ "responses": [
++ { "text": "Bones? What are you talking about?", "topic": "TALK_BONE_SEER_SONG2" },
++ { "text": "Uh… yeah, sure. I think I'll just be on my way.", "topic": "TALK_DONE" }
++ ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_BONE_SEER_SONG2",
++ "dynamic_line": "When it all happened, the Cataclysm, something… changed. You can see it in all creatures, most of all in their bones. They break, morph, rise again, over and over - a never-ending cycle. The dead walk again, horrors rip and tear each other apart. And within each one… the quiet hum of raw strength. Only by taking the bones does the cycle end - their story, their song, their strength; they become yours to use.",
++ "speaker_effect": { "effect": { "u_add_var": "asked_about_song", "type": "dialogue", "context": "song", "value": "yes" } },
++ "responses": [
++ { "text": "So what do you actually do with the bones?", "topic": "TALK_BONE_SEER_BONES" },
++ { "text": "I'm still not sure what you mean.", "topic": "TALK_BONE_SEER_SONG3" },
++ { "text": "Does anyone else, uh, believe this?", "topic": "TALK_BONE_SEER_OTHERS" }
++ ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_BONE_SEER_SONG3",
++ "dynamic_line": "Only when you crush the bones of a body does it cease to rise. Only if you examine the bones can you see what was, the story of the bones. Whatever causes this change is alive, writhing within us all; an inevitable part of this new world. It holds the power of change. When we hold the bones, we hold the power. Thus the strength. Together… they form a beautiful song.",
++ "responses": [
++ { "text": "What do you actually do with the bones?", "topic": "TALK_BONE_SEER_BONES" },
++ { "text": "Does anyone else share this belief?", "topic": "TALK_BONE_SEER_OTHERS" }
++ ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_BONE_SEER_OTHERS",
++ "dynamic_line": "There are others who know the power the bones hold, but not all of them are my kin. Not anymore, at least.",
++ "speaker_effect": { "effect": { "u_add_var": "knows_kindred", "type": "dialogue", "context": "kindred", "value": "yes" } },
++ "responses": [
++ { "text": "What do you mean 'not anymore'?", "topic": "TALK_BONE_SEER_COOPER" },
++ { "text": "Why do you gather these bones again?", "topic": "TALK_BONE_SEER_BONES" },
++ { "text": "Thank you for all the information, but I have to go now.", "topic": "TALK_DONE" }
++ ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_BONE_SEER_COOPER",
++ "dynamic_line": "Some time ago, a man named Cooper joined me and my kin. He showed great promise and devotion to our cause, but in his effort to weave songs, he justified increasingly grim actions. We tried to stop him when we learned of this, but he managed to get away. If you ever come across him, be sure to thread carefully, and if you can, stop him.",
++ "speaker_effect": { "effect": { "u_add_var": "knows_cooper", "type": "dialogue", "context": "kindred_cooper", "value": "yes" } },
++ "responses": [
++ {
++ "text": "Wait, Cooper? Darren Cooper? I've already met him.",
++ "topic": "TALK_BONE_SEER_METCOOPER2",
++ "condition": { "u_has_var": "talked_to_cooper", "type": "dialogue", "context": "first_meeting", "value": "yes" }
++ },
++ { "text": "What exactly did he do?", "topic": "TALK_BONE_SEER_COOPER2" },
++ {
++ "text": "Sounds like there is another side to this. Sometimes, what is necessary is not pretty.",
++ "topic": "TALK_BONE_SEER_COOPER3",
++ "effect": { "u_add_var": "admires_cooper", "type": "dialogue", "context": "kindred", "value": "yes" }
++ },
++ { "text": "What cause is that? What do you do with the bones?", "topic": "TALK_BONE_SEER_BONES" },
++ { "text": "I see. I wanted to ask about something else…", "topic": "TALK_BONE_SEER" }
++ ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_BONE_SEER_COOPER2",
++ "dynamic_line": "He began killing others to get their bones as fresh as possible. Later, he… he started carving the bones of the living. Thought the anguish alone would empower the song. The goal of the Kindred is to banish the shadow of the cataclysm, not to cast it. Such heinous acts will likely twist the song of the world, but I don't think Cooper realises it. To him, the end justifies any means.",
++ "speaker_effect": { "effect": { "u_add_var": "knows_cooper_kill", "type": "dialogue", "context": "kindred_cooper", "value": "yes" } },
++ "responses": [
++ { "text": "Well… shit. Maybe we should talk about something else.", "topic": "TALK_BONE_SEER" },
++ {
++ "text": "What if he is right? Maybe what you do isn't enough and he's the only one to do what it takes.",
++ "topic": "TALK_BONE_SEER_COOPER3",
++ "effect": { "u_add_var": "admires_cooper", "type": "dialogue", "context": "kindred", "value": "yes" }
++ }
++ ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_BONE_SEER_COOPER3",
++ "dynamic_line": "You do not realize the gravity of your claim. When you understand the Song better, you will understand the danger of his actions.",
++ "responses": [ { "text": "I see.", "topic": "TALK_BONE_SEER" }, { "text": "We'll see about that.", "topic": "TALK_BONE_SEER" } ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_BONE_SEER_BONES",
++ "dynamic_line": "The song can be woven in many forms. Carved bone charms, weapons and armor all hold immense power, and when the time comes, me and my Kindred shall amass enough Song to restore this world as it was before. Restore it, or end it. Makes no difference.",
++ "responses": [ { "text": "End the world? What?", "topic": "TALK_BONE_SEER_END" } ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_BONE_SEER_END",
++ "dynamic_line": "The Song holds immeasurable power. A grand symphony could revert the Cataclysm - or accelerate it to a time beyond all. But with the world looking as is, both options are preferable.",
++ "responses": [
++ { "text": "A strange belief, but maybe there is some truth to it.", "topic": "TALK_BONE_SEER_POSITIVE" },
++ { "text": "Well, at least you're trying to help.", "topic": "TALK_BONE_SEER_POSITIVE" },
++ { "text": "You're nuts.", "topic": "TALK_BONE_SEER_INSULT" }
++ ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_BONE_SEER_POSITIVE",
++ "dynamic_line": "Your mind is open. More than most. Perhaps one day, you too will feel the power of the song and become Kindred. For now, traveller, listen, listen and feel the song.",
++ "responses": [ { "text": "I… thank you.", "topic": "TALK_BONE_SEER" } ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_BONE_SEER_INSULT",
++ "dynamic_line": "Your skepticism does not surprise me. Perhaps one day, you too will hear the inevitability of the song, feel its power. But until you do, you will remain just another survivor, path to the Kindred closed.",
++ "responses": [ { "text": "Alright.", "topic": "TALK_BONE_SEER" } ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_BONE_SEER_ABOUT",
++ "dynamic_line": "I grew up in Louisiana with my grandmother. Great cook. Made the best boudin I've ever had. Each night, she would tell me stories; mostly folklore and myths, like about the rougarou, or the Honey Island Swamp monster but… she sometimes told me about me about the Song, and the bones. The way she talked about it was… different, serious. Didn't give it much thought back then; I was just a child, after all. I moved here a few years back for work, before the Cataclysm, before everything changed. I do miss home sometimes, but at least the rats here are smaller. Never could stand the things. Anyway… thank you for asking. Been a while since I could simply talk to someone.",
++ "responses": [
++ { "text": "Why didn't your parents raise you?", "topic": "TALK_BONE_SEER_PARENTS" },
++ { "text": "What's boudin?", "topic": "TALK_BONE_SEER_BOUDIN" },
++ { "text": "What do you mean she talked about the Song 'differently'?", "topic": "TALK_BONE_SEER_GRANDMA" },
++ { "text": "What's wrong with rats?", "topic": "TALK_BONE_SEER_RATS" },
++ { "text": "Thank you for sharing. Let's talk about something else.", "topic": "TALK_BONE_SEER" }
++ ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_BONE_SEER_PARENTS",
++ "dynamic_line": "They died when I was very young. Car accident. I… don't have any memories of them, but my grandmother raised me as her own.",
++ "responses": [ { "text": "She sounds nice.", "topic": "TALK_BONE_SEER_ABOUT" } ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_BONE_SEER_BOUDIN",
++ "dynamic_line": "Spicy sausage, green onions, rice. She'd batter and deep fry them, make boudin balls. A dish to die for.",
++ "responses": [
++ { "text": "Sounds delicious.", "topic": "TALK_BONE_SEER_ABOUT" },
++ { "text": "Not my kind of thing.", "topic": "TALK_BONE_SEER_ABOUT" }
++ ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_BONE_SEER_GRANDMA",
++ "dynamic_line": "Unlike the other stories, she spoke with determination, reverence even. I didn't realize it back then but it wasn't just a story; she knew that this wasn't just another tale.",
++ "responses": [ { "text": "I see.", "topic": "TALK_BONE_SEER_ABOUT" } ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_BONE_SEER_RATS",
++ "dynamic_line": "Ever since a young age, I hated rats. Can't quite say why; they always struck me as something… foul. I even have nightmares about them sometimes. Not too long ago, I had one about a man-sized rat, shambling on it's hind legs. It chased me up a tall building and then pushed me off, snickering. Maybe the Song was trying to tell me something, but then again, maybe it was just a bad dream.",
++ "responses": [ { "text": "Strange dream, but we all have fears, sometimes irrational.", "topic": "TALK_BONE_SEER_ABOUT" } ]
++ },
++ {
++ "id": "MISSION_SEER_GATHER_BONE",
++ "type": "mission_definition",
++ "name": { "str": "Collect Bones" },
++ "description": {
++ "str": "Brigitte LaCroix asked you to collect clean, untainted bones in order to better understand her beliefs. 8 bones should be sufficient."
++ },
++ "difficulty": 1,
++ "value": 10000,
++ "goal": "MGOAL_FIND_ITEM",
++ "item": "bone",
++ "count": 8,
++ "origins": [ "ORIGIN_SECONDARY" ],
++ "end": {
++ "effect": [
++ { "u_add_var": "NC_SEER_MISSION_1", "type": "general", "context": "mission", "value": "yes" },
++ { "u_add_trait": "seer_mark" }
++ ]
++ },
++ "dialogue": {
++ "describe": "There is always work to be done, song to be woven.",
++ "offer": "If you wish to be set on the path to enlightenment, first you must learn to listen and hear the song. Go out, butcher an untainted creature and feel the power between your fingertips. Then bring me the bones and I shall carve them for you.",
++ "accepted": "Excellent. Now be on your way.",
++ "rejected": "I understand your reluctancy. Feel free to return when you see the way.",
++ "advice": "The shambling corpses we see all around move in discord. Their song can be used, but for an Acolyte, this would be needlessly hard. Be sure to carve an unspoiled living creature.",
++ "inquire": "Have you felt the song in your hands yet?",
++ "success": "And so, another cycle ends. You have done well. I will now bestow my mark upon you, so that others may know the path you walk and aid you.",
++ "success_lie": "So you say, but the song sings otherwise.",
++ "failure": "Then you shall try again, until you hear."
++ }
++ },
++ {
++ "id": "TALK_MISSION_LIST_SEER",
++ "type": "talk_topic",
++ "dynamic_line": {
++ "has_no_available_mission": {
++ "has_no_assigned_mission": "The song is… quiet for now. Perhaps with time, more notes will be etched in the bones of this world.",
++ "no": { "has_many_assigned_missions": "An acolyte should not take on too many songs at once.", "no": "That is all for now." }
++ },
++ "no": {
++ "has_many_available_missions": {
++ "has_no_assigned_mission": "There are bones to etch, songs to sing. Wish to join me?",
++ "no": {
++ "has_many_assigned_missions": "Do you wish to take on more songs?",
++ "no": "Do you believe you can take on the burden of additional bones?"
++ }
++ },
++ "no": {
++ "has_no_assigned_mission": "A song may yet be sung by you, should you wish to.",
++ "no": {
++ "has_many_assigned_missions": "There is an additional song you could take on, if you'd like.",
++ "no": "I know of certain bones that could be of use, if you'd like to know more."
++ }
++ }
++ }
++ },
++ "responses": [
++ { "text": "I see.", "topic": "TALK_NONE", "condition": "has_no_available_mission" },
++ {
++ "text": "I'm listening.",
++ "topic": "TALK_MISSION_OFFER_SEER",
++ "condition": { "not": "has_no_available_mission" }
++ },
++ {
++ "text": "Perhaps another time, Seer.",
++ "topic": "TALK_NONE",
++ "condition": { "not": "has_no_available_mission" }
++ }
++ ]
++ },
++ {
++ "id": "TALK_MISSION_OFFER_SEER",
++ "type": "talk_topic",
++ "dynamic_line": "If you wish to be set on the path to enlightenment, first you must learn to listen and hear the song. Go out, butcher an untainted creature and feel the power between your fingertips. Then bring me the bones and I shall carve them for you.",
++ "responses": [
++ {
++ "text": "Well, I guess I oughta see where this goes. I'm in.",
++ "topic": "TALK_MISSION_ACCEPTED_SEER",
++ "effect": "assign_mission"
++ },
++ { "text": "Not interested.", "topic": "TALK_MISSION_REJECTED_SEER" }
++ ]
++ },
++ {
++ "id": "TALK_MISSION_ACCEPTED_SEER",
++ "type": "talk_topic",
++ "dynamic_line": "Excellent. Now be on your way.",
++ "responses": [
++ { "text": "Consider it done. But I also wanted to ask…", "topic": "TALK_BONE_SEER" },
++ { "text": "Where should I start?", "topic": "TALK_MISSION_ADVICE_SEER" },
++ { "text": "Can you share some equipment to aid me in this?", "topic": "TALK_SHARE_EQUIPMENT_SEER" },
++ { "text": "I'm off then.", "topic": "TALK_DONE" }
++ ]
++ },
++ {
++ "id": "TALK_MISSION_ADVICE_SEER",
++ "type": "talk_topic",
++ "dynamic_line": "The shambling corpses we see all around move in discord. Their song can be used, but for an Acolyte, this would be needlessly hard. Be sure to carve an unspoiled living creature.",
++ "responses": [ { "text": "So, a creature that isn't a zombie, or a monster. Got it.", "topic": "TALK_NONE" } ]
++ },
++ {
++ "id": "TALK_SHARE_EQUIPMENT_SEER",
++ "type": "talk_topic",
++ "dynamic_line": "The path to enlightenment is for you to walk. For me to aid you would ultimately impede your progress and muddle your song.",
++ "responses": [ { "text": "I see. Very well then.", "topic": "TALK_NONE" } ]
++ },
++ {
++ "id": "TALK_SUGGEST_FOLLOW_SEER",
++ "type": "talk_topic",
++ "dynamic_line": {
++ "u_has_trait": "seer_mark",
++ "no": "Only those who bear my mark will prove themselves worthy of my skills.",
++ "yes": "You bear my mark, meaning I believe you have potential to learn to truly listen to the Song. Yes, I will lend my skills to you, for now."
++ },
++ "responses": [
++ { "text": "I see. Very well then.", "topic": "TALK_NONE", "condition": { "not": { "u_has_trait": "seer_mark" } } },
++ {
++ "text": "I am glad to hear it. Let's go then.",
++ "effect": "follow",
++ "condition": { "u_has_trait": "seer_mark" },
++ "topic": "TALK_DONE"
++ },
++ {
++ "text": "That's good, but I need to go at it alone right now. Maybe later.",
++ "condition": { "u_has_trait": "seer_mark" },
++ "topic": "TALK_NONE"
++ }
++ ]
++ },
++ {
++ "id": "TALK_MISSION_REJECTED_SEER",
++ "type": "talk_topic",
++ "dynamic_line": "I understand your reluctancy. Feel free to return when you see the way.",
++ "responses": [
++ { "text": "Maybe some other time. Changing the topic…", "topic": "TALK_NONE" },
++ { "text": "Alright, but I have to go now.", "topic": "TALK_DONE" }
++ ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_BONE_SEER_CYCLE",
++ "dynamic_line": "It's not just walking horrors and monsters that have changed with the Cataclysm. It started a… cycle, of sorts. Everything repeats. We can only see it in others, but it happens to us, even you and I. How many times have you fallen? Your flesh rent from your body, devoured. Or perhaps it was the quiet whimper of succumbing to the elements. But your bones rose again. Different flesh, different name, sometimes even different knowledge, but the bones, the same. We are all trapped in the same cycle. We just keep forgetting. That's why we need to amass the Song. That's why it has to end, even if it means the destruction, not restoration.",
++ "responses": [
++ { "text": "That's… certainly something.", "topic": "TALK_NONE" },
++ { "text": "That's insane.", "topic": "TALK_BONE_SEER_INSULT" },
++ { "text": "Right… I think I'll go now.", "topic": "TALK_DONE" }
++ ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_BONE_SEER_METCOOPER",
++ "dynamic_line": "I see. And you live still. Does that mean you managed to stop him?",
++ "responses": [
++ {
++ "text": "I've confronted him. He ended up attacking me.",
++ "topic": "TALK_BONE_SEER_COOPERFIGHT",
++ "condition": { "u_has_var": "fought_cooper", "type": "dialogue", "context": "cooper", "value": "yes" }
++ },
++ {
++ "text": "He was reasonable. We talked, then parted ways peacefully.",
++ "topic": "TALK_BONE_SEER_COOPERPEACE",
++ "condition": { "not": { "u_has_var": "fought_cooper", "type": "dialogue", "context": "cooper", "value": "yes" } }
++ },
++ {
++ "text": "I agree with him. What he does is necessary.",
++ "topic": "TALK_BONE_SEER_COOPERAGREE",
++ "condition": {
++ "and": [
++ { "not": { "u_has_var": "fought_cooper", "type": "dialogue", "context": "cooper", "value": "yes" } },
++ { "u_has_var": "cooper_friendly", "type": "dialogue", "context": "cooper", "value": "yes" }
++ ]
++ }
++ }
++ ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_BONE_SEER_COOPERFIGHT",
++ "dynamic_line": "It saddens me to see a talented Kindred lose his way so greatly, but I take solace in the fact that you are unscathed.",
++ "responses": [ { "text": "Best not to dwell on it. Let's move on.", "topic": "TALK_BONE_SEER" } ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_BONE_SEER_COOPERPEACE",
++ "dynamic_line": "I am glad your meeting ended without conflict. Perhaps he's understanding the Song more and the harm his actions caused. If so… there may be hope yet. Never the less, his action can not go unpunished.",
++ "responses": [ { "text": "A topic for another time. Let's move on.", "topic": "TALK_BONE_SEER" } ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_BONE_SEER_METCOOPER2",
++ "dynamic_line": "You have? A most peculiar coincidence. How did he act towards you?",
++ "responses": [
++ {
++ "text": "I've confronted him. He ended up attacking me.",
++ "topic": "TALK_BONE_SEER_COOPERFIGHT",
++ "condition": { "u_has_var": "fought_cooper", "type": "dialogue", "context": "cooper", "value": "yes" }
++ },
++ {
++ "text": "He was reasonable. We talked, then parted ways peacefully.",
++ "topic": "TALK_BONE_SEER_COOPERPEACE",
++ "condition": { "not": { "u_has_var": "fought_cooper", "type": "dialogue", "context": "cooper", "value": "yes" } }
++ },
++ {
++ "text": "I agree with him. What he does is necessary.",
++ "topic": "TALK_BONE_SEER_COOPERAGREE",
++ "condition": {
++ "and": [
++ { "not": { "u_has_var": "fought_cooper", "type": "dialogue", "context": "cooper", "value": "yes" } },
++ { "u_has_var": "cooper_friendly", "type": "dialogue", "context": "cooper", "value": "yes" }
++ ]
++ }
++ }
++ ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_BONE_SEER_COOPERAGREE",
++ "dynamic_line": "Tread carefully. I can't allow anyone else to go down such a path. I can't fail again.",
++ "responses": [
++ { "text": "I'm sorry. I'll think about it some more.", "topic": "TALK_BONE_SEER" },
++ { "text": "Just saying he has a point, that's all.", "topic": "TALK_BONE_SEER" }
++ ]
++ }
++]
+--- a/data/json/npcs/Kindred/NPC_Darren_Cooper.json
++++ b/data/json/npcs/Kindred/NPC_Darren_Cooper.json
+@@ -0,0 +1,613 @@
++[
++ {
++ "type": "npc_class",
++ "id": "NC_KINDRED_COOPER",
++ "name": { "str": "Rogue Kindred" },
++ "job_description": "I have to gather more bones",
++ "traits": [
++ { "trait": "OUTDOORSMAN" },
++ { "trait": "INSOMNIA" },
++ { "trait": "GOODCARDIO2" },
++ { "trait": "STRONGSTOMACH" },
++ { "trait": "SPIRITUAL" },
++ { "trait": "TERRIFYING" },
++ { "trait": "KILLER" },
++ { "trait": "seer_mark" },
++ { "group": "Appearance_Caucasian" },
++ { "trait": "hair_brown_short" },
++ { "trait": "FACIAL_HAIR_3DAYSTUBBLE" }
++ ],
++ "common": false,
++ "bonus_per": { "rng": [ 0, 2 ] },
++ "bonus_str": { "rng": [ 0, 2 ] },
++ "worn_override": "KINDRED_COOPER_worn",
++ "weapon_override": "KINDRED_COOPER_wield",
++ "shopkeeper_item_group": "NC_KINDRED_COOPER_misc",
++ "skills": [
++ {
++ "skill": "ALL",
++ "level": { "mul": [ { "one_in": 3 }, { "sum": [ { "dice": [ 2, 2 ] }, { "constant": -2 }, { "one_in": 4 } ] } ] }
++ },
++ { "skill": "dodge", "bonus": { "rng": [ 2, 4 ] } },
++ { "skill": "melee", "bonus": { "rng": [ 5, 7 ] } },
++ { "skill": "cutting", "bonus": { "rng": [ 4, 6 ] } }
++ ]
++ },
++ {
++ "type": "item_group",
++ "id": "KINDRED_COOPER_worn",
++ "subtype": "collection",
++ "entries": [
++ { "item": "loincloth_leather" },
++ { "item": "socks" },
++ { "item": "kevlar" },
++ { "item": "helmet_liner" },
++ { "item": "gloves_liner" },
++ { "item": "boots_larmor" },
++ { "item": "swat_armor" },
++ { "item": "gauntlets_larmor" },
++ { "item": "leather_belt" },
++ { "item": "canteen" },
++ { "item": "armguard_larmor" },
++ { "item": "backpack_leather" },
++ { "item": "knee_pads" },
++ { "item": "knit_scarf" }
++ ]
++ },
++ {
++ "type": "item_group",
++ "id": "KINDRED_COOPER_wield",
++ "subtype": "collection",
++ "entries": [ { "item": "survivor_machete" } ]
++ },
++ {
++ "type": "item_group",
++ "id": "NC_KINDRED_COOPER_misc",
++ "subtype": "distribution",
++ "entries": [
++ { "item": "needle_bone", "prob": 40 },
++ { "item": "bone_glue", "prob": 20 },
++ { "item": "bone_flute", "prob": 10 },
++ { "item": "bone_human", "prob": 10 },
++ { "item": "broth_bone", "prob": 60 },
++ { "item": "water_clean", "prob": 90 }
++ ]
++ },
++ {
++ "type": "npc",
++ "id": "KINDRED_Darren_Cooper",
++ "//": "A once member of a doomsday cult.",
++ "name_unique": "Darren Cooper",
++ "gender": "male",
++ "name_suffix": "Rogue Kindred",
++ "class": "NC_KINDRED_COOPER",
++ "attitude": 0,
++ "mission": 7,
++ "chat": "TALK_KINDRED_COOPER",
++ "faction": "no_faction"
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_KINDRED_COOPER",
++ "dynamic_line": {
++ "u_has_var": "talked_to_cooper",
++ "type": "dialogue",
++ "context": "first_meeting",
++ "value": "yes",
++ "no": {
++ "u_has_trait": "seer_mark",
++ "yes": "How do you do. Name's Cooper. What's your- wait… that's the Mark of the Seer on your hand. You're Kindred. So I guess you know who I am then.",
++ "no": "How do you do. Name's Cooper. And you are?"
++ },
++ "yes": {
++ "u_has_trait": "seer_mark",
++ "no": {
++ "u_has_var": "cooper_friendly",
++ "type": "dialogue",
++ "context": "cooper",
++ "value": "yes",
++ "yes": "Hello again, traveller.",
++ "no": "Yes?"
++ },
++ "yes": {
++ "u_has_var": "cooper_friendly",
++ "type": "dialogue",
++ "context": "cooper",
++ "value": "yes",
++ "no": "What do you want, Kindred?",
++ "yes": "Kindred. What can I do for you?"
++ }
++ }
++ },
++ "speaker_effect": { "effect": { "u_add_var": "talked_to_cooper", "type": "dialogue", "context": "first_meeting", "value": "yes" } },
++ "responses": [
++ {
++ "text": "I do. Brigitte told me about you, and that you're dangerous.",
++ "topic": "TALK_KNOWS_COOPER1",
++ "condition": {
++ "and": [
++ { "not": { "u_has_var": "confronted_cooper", "type": "dialogue", "context": "cooper", "value": "yes" } },
++ { "u_has_trait": "seer_mark" },
++ { "u_has_var": "knows_cooper", "type": "dialogue", "context": "kindred_cooper", "value": "yes" },
++ {
++ "not": { "u_has_var": "knows_cooper_kill", "type": "dialogue", "context": "kindred_cooper", "value": "yes" }
++ }
++ ]
++ }
++ },
++ {
++ "text": "Brigitte told me everything. What could drive a man to carve the bones of living people?",
++ "topic": "TALK_KNOWS_COOPER_CARVE",
++ "condition": {
++ "and": [
++ { "not": { "u_has_var": "confronted_cooper", "type": "dialogue", "context": "cooper", "value": "yes" } },
++ { "u_has_trait": "seer_mark" },
++ { "u_has_var": "knows_cooper", "type": "dialogue", "context": "kindred_cooper", "value": "yes" },
++ { "u_has_var": "knows_cooper_kill", "type": "dialogue", "context": "kindred_cooper", "value": "yes" }
++ ]
++ }
++ },
++ {
++ "text": "Brigitte told me about you. I think what you do might be what's necessary, even if Brigitte doesn't agree.",
++ "topic": "TALK_COOPER_AGREE",
++ "condition": {
++ "and": [
++ { "not": { "u_has_var": "confronted_cooper", "type": "dialogue", "context": "cooper", "value": "yes" } },
++ { "u_has_trait": "seer_mark" },
++ { "u_has_var": "knows_cooper", "type": "dialogue", "context": "kindred_cooper", "value": "yes" },
++ { "u_has_var": "knows_cooper_kill", "type": "dialogue", "context": "kindred_cooper", "value": "yes" },
++ { "u_has_var": "admires_cooper", "type": "dialogue", "context": "kindred", "value": "yes" }
++ ]
++ }
++ },
++ {
++ "text": "I can't say that I do. Should I?",
++ "topic": "TALK_COOPER_NOTFMLR",
++ "condition": {
++ "and": [
++ { "not": { "u_has_var": "talked_to_cooper", "type": "dialogue", "context": "first_meeting", "value": "yes" } },
++ { "u_has_trait": "seer_mark" },
++ {
++ "not": { "u_has_var": "knows_cooper", "type": "dialogue", "context": "kindred_cooper", "value": "yes" }
++ }
++ ]
++ }
++ },
++ {
++ "text": "Just a traveller, trying to survive. What about you? Scavenging?",
++ "topic": "TALK_COOPER_INTRODUCTION",
++ "condition": {
++ "and": [
++ { "not": { "u_has_trait": "seer_mark" } },
++ {
++ "not": { "u_has_var": "knows_cooper", "type": "dialogue", "context": "kindred_cooper", "value": "yes" }
++ },
++ {
++ "not": { "u_has_var": "talked_to_cooper", "type": "dialogue", "context": "first_meeting", "value": "yes" }
++ }
++ ]
++ }
++ },
++ {
++ "text": "Wait, Cooper? Brigitte LaCroix mentioned someone by that name. You're the man who carved the bones of living people.",
++ "topic": "TALK_KNOWS_COOPER_CARVE",
++ "condition": {
++ "and": [
++ { "not": { "u_has_trait": "seer_mark" } },
++ {
++ "not": { "u_has_var": "talked_to_cooper", "type": "dialogue", "context": "first_meeting", "value": "yes" }
++ },
++ { "u_has_var": "knows_cooper", "type": "dialogue", "context": "kindred_cooper", "value": "yes" },
++ { "u_has_var": "knows_cooper_kill", "type": "dialogue", "context": "kindred_cooper", "value": "yes" }
++ ]
++ }
++ },
++ {
++ "text": "Cooper? I met a woman who mentioned you, Brigitte. She said you're dangerous.",
++ "topic": "TALK_COOPER_INTRODUCTION_QUERY",
++ "condition": {
++ "and": [
++ { "not": { "u_has_trait": "seer_mark" } },
++ {
++ "not": { "u_has_var": "talked_to_cooper", "type": "dialogue", "context": "first_meeting", "value": "yes" }
++ },
++ { "u_has_var": "knows_cooper", "type": "dialogue", "context": "kindred_cooper", "value": "yes" },
++ {
++ "not": { "u_has_var": "knows_cooper_kill", "type": "dialogue", "context": "kindred_cooper", "value": "yes" }
++ }
++ ]
++ }
++ },
++ {
++ "text": "Wait, Cooper? I heard about you. A woman, Brigitte LaCroix, said that you're dangerous, but seems to me like you're just doing what it takes.",
++ "topic": "TALK_COOPER_AGREE",
++ "condition": {
++ "and": [
++ { "not": { "u_has_trait": "seer_mark" } },
++ {
++ "not": { "u_has_var": "talked_to_cooper", "type": "dialogue", "context": "first_meeting", "value": "yes" }
++ },
++ { "u_has_var": "knows_cooper", "type": "dialogue", "context": "kindred_cooper", "value": "yes" },
++ { "u_has_var": "admires_cooper", "type": "dialogue", "context": "kindred", "value": "yes" }
++ ]
++ }
++ },
++ {
++ "text": "Why did Brigitte say you're dangerous?",
++ "topic": "TALK_COOPERS_SIDE",
++ "condition": {
++ "and": [
++ { "not": { "u_has_trait": "seer_mark" } },
++ { "u_has_var": "talked_to_cooper", "type": "dialogue", "context": "first_meeting", "value": "yes" },
++ { "u_has_var": "knows_cooper", "type": "dialogue", "context": "kindred_cooper", "value": "yes" },
++ {
++ "not": { "u_has_var": "cooper_goal_k", "type": "dialogue", "context": "first_meeting", "value": "yes" }
++ },
++ {
++ "not": { "u_has_var": "knows_cooper_kill", "type": "dialogue", "context": "kindred_cooper", "value": "yes" }
++ }
++ ]
++ }
++ },
++ {
++ "text": "Why do you kill people?",
++ "topic": "TALK_COOPER_GOAL",
++ "condition": {
++ "and": [
++ { "not": { "u_has_trait": "seer_mark" } },
++ { "u_has_var": "talked_to_cooper", "type": "dialogue", "context": "first_meeting", "value": "yes" },
++ { "u_has_var": "knows_cooper", "type": "dialogue", "context": "kindred_cooper", "value": "yes" },
++ {
++ "not": { "u_has_var": "cooper_goal_k", "type": "dialogue", "context": "first_meeting", "value": "yes" }
++ },
++ { "u_has_var": "knows_cooper_kill", "type": "dialogue", "context": "kindred_cooper", "value": "yes" }
++ ]
++ }
++ },
++ {
++ "text": "Could you tell me about yourself?",
++ "topic": "TALK_COOPER_ABOUT",
++ "condition": { "and": [ { "u_has_var": "talked_to_cooper", "type": "dialogue", "context": "first_meeting", "value": "yes" } ] }
++ },
++ {
++ "text": "I'll be going now.",
++ "topic": "TALK_DONE",
++ "condition": {
++ "and": [
++ { "u_has_var": "talked_to_cooper", "type": "dialogue", "context": "first_meeting", "value": "yes" },
++ { "not": { "u_has_var": "cooper_friendly", "type": "dialogue", "context": "cooper", "value": "yes" } }
++ ]
++ }
++ },
++ {
++ "text": "Remind me what happened between you and Brigitte.",
++ "topic": "TALK_COOPERS_SIDE",
++ "condition": {
++ "and": [
++ { "u_has_var": "talked_to_cooper", "type": "dialogue", "context": "first_meeting", "value": "yes" },
++ { "u_has_trait": "seer_mark" }
++ ]
++ }
++ },
++ {
++ "text": "I've been thinking about what you do. I can't let you keep hurting people. You have to be stopped.",
++ "topic": "TALK_COOPER_FIGHT",
++ "condition": {
++ "and": [
++ { "u_has_var": "talked_to_cooper", "type": "dialogue", "context": "first_meeting", "value": "yes" },
++ { "u_has_var": "knows_cooper_kill", "type": "dialogue", "context": "kindred_cooper", "value": "yes" }
++ ]
++ }
++ },
++ {
++ "text": "Could you remind me of your goal again?",
++ "topic": "TALK_COOPER_GOAL",
++ "condition": {
++ "and": [
++ { "not": { "u_has_trait": "seer_mark" } },
++ { "u_has_var": "talked_to_cooper", "type": "dialogue", "context": "first_meeting", "value": "yes" },
++ { "u_has_var": "cooper_goal_k", "type": "dialogue", "context": "first_meeting", "value": "yes" }
++ ]
++ }
++ },
++ {
++ "text": "You mentioned that you have a goal. What is that exactly?",
++ "topic": "TALK_COOPER_GOAL",
++ "condition": {
++ "and": [
++ { "not": { "u_has_trait": "seer_mark" } },
++ { "u_has_var": "talked_to_cooper", "type": "dialogue", "context": "first_meeting", "value": "yes" },
++ { "u_has_var": "cooper_goal_dk", "type": "dialogue", "context": "first_meeting", "value": "yes" }
++ ]
++ }
++ },
++ {
++ "text": "The woman you mentioned - Brigitte - why isn't she with you?",
++ "topic": "TALK_COOPERS_SIDE",
++ "condition": { "u_has_var": "cooper_goal_k", "type": "dialogue", "context": "first_meeting", "value": "yes" }
++ },
++ {
++ "text": "I was just checking in. Take care.",
++ "topic": "TALK_DONE",
++ "condition": {
++ "and": [
++ { "u_has_var": "talked_to_cooper", "type": "dialogue", "context": "first_meeting", "value": "yes" },
++ { "u_has_var": "cooper_friendly", "type": "dialogue", "context": "cooper", "value": "yes" }
++ ]
++ }
++ }
++ ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_KNOWS_COOPER1",
++ "dynamic_line": "I suppose she probably said I'm some sort of a maniac and that you should kill me on the spot, correct?",
++ "speaker_effect": { "effect": { "u_add_var": "confronted_cooper", "type": "dialogue", "context": "cooper", "value": "yes" } },
++ "responses": [
++ {
++ "text": "I want to hear your side of the story. You make it sound like it's not so cut and dry.",
++ "topic": "TALK_COOPERS_SIDE"
++ },
++ {
++ "text": "You kill innocent people and butcher them like animals. I don't care what you say. You have to be stopped.",
++ "topic": "TALK_COOPER_FIGHT"
++ }
++ ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_COOPER_INTRODUCTION_QUERY",
++ "dynamic_line": "I see. Would you like to hear my side, or is your mind made up already?",
++ "responses": [
++ { "text": "I'm curious. Go on.", "topic": "TALK_COOPERS_SIDE" },
++ { "text": "She told me to stop you, and that's what I'll do.", "topic": "TALK_COOPER_FIGHT" },
++ { "text": "I don't care about any of this. Bye.", "topic": "TALK_DONE" }
++ ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_KNOWS_COOPER_CARVE",
++ "dynamic_line": "What? I'd never do anything like that! Dammit… if she thinks I did that, that would explain why she's not willing to work with me. Maybe there's still some hope she'll understand what's necessary.",
++ "responses": [
++ { "text": "So what happened then?", "topic": "TALK_COOPERS_SIDE" },
++ { "text": "You're still a killer, and I can't let you keep going.", "topic": "TALK_COOPER_FIGHT" },
++ { "text": "I don't really care. I'm leaving.", "topic": "TALK_DONE" }
++ ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_COOPERS_SIDE",
++ "dynamic_line": "I met Brigitte shortly after everything collapsed. Seeing so much death and insanity around me… it almost crushed me, but when she explained everything about the bones to me, it gave me a sliver of hope, that one time, things might turn around. For that, I am grateful to her. But we'll never change anything if we keep using scraps of bones found on corpses on the side of the road. By the time the animals are done with those, there is barely any Song left to be used. It's not enough. I had to leave, to work on my own. To do what's necessary.",
++ "responses": [
++ {
++ "text": "What do you mean by 'necessary'?",
++ "topic": "TALK_COOPER_NECESSARY",
++ "condition": { "not": { "u_has_var": "knows_cooper_kill", "type": "dialogue", "context": "kindred_cooper", "value": "yes" } }
++ },
++ {
++ "text": "What are you actually trying to accomplish?",
++ "topic": "TALK_COOPER_GOAL",
++ "condition": { "not": { "u_has_var": "cooper_goal_k", "type": "dialogue", "context": "first_meeting", "value": "yes" } }
++ },
++ { "text": "Can't have been easy to split off, but I understand why you did it.", "topic": "TALK_COOPER_AGREE" },
++ {
++ "text": "Necessary? You kill innocent people!",
++ "topic": "TALK_COOPER_NECESSARY",
++ "condition": { "u_has_var": "knows_cooper_kill", "type": "dialogue", "context": "kindred_cooper", "value": "yes" }
++ }
++ ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_COOPER_NECESSARY",
++ "dynamic_line": "People will die in this world overrun with monsters. There is no avoiding it. But I can give those deaths meaning, allow them to help the world after death, more than they could in life. It brings me no pleasure, but… yes, some must give their life for the greater good. It's the only way. Wish there was an alternative, but it must be done. I only take people from this world to save it. Make no mistake though, the only people that I… kill are those who would not survive anyway.",
++ "speaker_effect": { "effect": { "u_add_var": "knows_cooper_kill", "type": "dialogue", "context": "kindred_cooper", "value": "yes" } },
++ "responses": [
++ {
++ "text": "Why do you kill people?",
++ "topic": "TALK_COOPER_GOAL",
++ "condition": { "not": { "u_has_var": "cooper_goal_k", "type": "dialogue", "context": "first_meeting", "value": "yes" } }
++ },
++ { "text": "Are you going to kill me?", "topic": "TALK_COOPER_KILL_PLAYER" },
++ { "text": "You're a monster.", "topic": "TALK_COOPER_MONSTER" },
++ {
++ "text": "You're just a murderer with a shoddy excuse. I can't let you keep doing this.",
++ "topic": "TALK_COOPER_FIGHT"
++ },
++ { "text": "You have a point. The ends justify the means.", "topic": "TALK_COOPER_AGREE" },
++ {
++ "text": "Do you have any proof that this will work?",
++ "topic": "TALK_COOPER_WORK",
++ "condition": { "u_has_var": "cooper_goal_k", "type": "dialogue", "context": "first_meeting", "value": "yes" }
++ }
++ ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_COOPER_MONSTER",
++ "dynamic_line": "And how many people have you killed? Maybe it was in self defense, maybe because you wanted their gear. It's all the same. I give their death meaning. I hate that I have to do it, I truly do, but you really must understand, there is no other way. The sooner I finish my mission, the sooner all this madness can end.",
++ "responses": [
++ { "text": "I suppose you're right.", "topic": "TALK_COOPER_AGREE" },
++ { "text": "You're mad. You have to be stopped.", "topic": "TALK_COOPER_FIGHT" },
++ { "text": "Whatever. I'm leaving.", "topic": "TALK_DONE" }
++ ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_COOPER_FIGHT",
++ "dynamic_line": {
++ "u_has_trait": "seer_mark",
++ "no": "I can't allow you to stop me. If you try, I'll have no option but to fight you. Maybe I'll die, or maybe you will. But know that should you win, you'll be ridding the world of the only hope it has.",
++ "yes": "I knew a Kindred would not understand. But I can't allow you to stop me. If you try, I'll have no option but to fight you. But know that should you win, you'll be ridding the world of the only hope it has."
++ },
++ "responses": [
++ {
++ "text": "All I'm ridding the world of is a dangerous madman. Now die.",
++ "topic": "TALK_DONE",
++ "effect": [ "hostile", { "u_add_var": "fought_cooper", "type": "dialogue", "context": "cooper", "value": "yes" } ]
++ },
++ { "text": "This is a waste of time not worth the risk. I'm out of here.", "topic": "TALK_DONE" }
++ ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_COOPER_AGREE",
++ "dynamic_line": {
++ "u_has_trait": "seer_mark",
++ "yes": "You're like me then, Kindred. I'm glad I'm not the only one who realizes what's necessary. Perhaps one day, we'll be able to work together, but what I do now, I must do alone.",
++ "no": "I'm glad you realize the necessity of the burden I bear. Maybe someday we'll even join our forces, but for now, I have to do this alone."
++ },
++ "speaker_effect": { "effect": { "u_add_var": "cooper_friendly", "type": "dialogue", "context": "cooper", "value": "yes" } },
++ "responses": [
++ { "text": "I won't delay you then. Good luck.", "topic": "TALK_DONE" },
++ {
++ "text": "That being said, I need to know why you do it - what purpose it fills.",
++ "topic": "TALK_COOPER_GOAL",
++ "condition": { "not": { "u_has_var": "cooper_goal_k", "type": "dialogue", "context": "first_meeting", "value": "yes" } }
++ }
++ ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_COOPER_WORK",
++ "dynamic_line": {
++ "u_has_trait": "seer_mark",
++ "yes": "You're Kindred, and yet you question the power the bones hold, the Song itself? This hypocrisy is why I set off on my own. Stop wasting my time and get out of my way.",
++ "no": "I know it's hard to comprehend when you can't hear the song. The bones hold power, you just don't hear it yet. But you will, eventually."
++ },
++ "responses": [
++ { "text": "I meant no offense. I'm sure you have your reasons.", "topic": "TALK_COOPER_AGREE" },
++ {
++ "text": "What about the woman you mentioned - Brigitte - what happened to her?",
++ "topic": "TALK_COOPERS_SIDE",
++ "condition": { "u_has_var": "cooper_goal_k", "type": "dialogue", "context": "first_meeting", "value": "yes" }
++ },
++ {
++ "text": "Brigitte was right. I can't reason with you. You have to be stopped.",
++ "topic": "TALK_COOPER_FIGHT",
++ "condition": {
++ "and": [
++ { "u_has_var": "knows_cooper", "type": "dialogue", "context": "kindred_cooper", "value": "yes" },
++ { "u_has_var": "knows_cooper_kill", "type": "dialogue", "context": "cooper", "value": "yes" }
++ ]
++ }
++ },
++ {
++ "text": "You're rambling. I can't let you keep hurting people. This ends now.",
++ "topic": "TALK_COOPER_FIGHT",
++ "condition": {
++ "and": [
++ { "not": { "u_has_var": "knows_cooper", "type": "dialogue", "context": "kindred_cooper", "value": "yes" } },
++ { "u_has_var": "knows_cooper_kill", "type": "dialogue", "context": "cooper", "value": "yes" }
++ ]
++ }
++ },
++ { "text": "This is a waste of time. I'm leaving.", "topic": "TALK_DONE" }
++ ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_COOPER_NOTFMLR",
++ "dynamic_line": "Brigitte did not mention me? I'm surprised. Perhaps she's starting to understand I was right. I was with her for a time, learned from her. I'm still on her side, but she doesn't realize it yet.",
++ "responses": [ { "text": "You know Brigitte? What happened with you two?", "topic": "TALK_COOPERS_SIDE" } ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_COOPER_INTRODUCTION",
++ "dynamic_line": "I scavenge only so I can survive, but I have a much greater goal than just to live.",
++ "speaker_effect": { "effect": { "u_add_var": "cooper_goal_dk", "type": "dialogue", "context": "first_meeting", "value": "yes" } },
++ "responses": [
++ { "text": "A… goal? What do you mean? What is there to do other than survive?", "topic": "TALK_COOPER_GOAL" },
++ { "text": "Uh, okay then. I have to go now; have a nice day.", "topic": "TALK_DONE" }
++ ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_COOPER_GOAL",
++ "dynamic_line": "Something changed during the Collapse - the apocalypse, if you prefer that. The way the dead rise again and again, it's tied to their bones - notice that only when you pulp and crush them properly do they actually die. A woman I met - Brigitte was her name - taught me how to use the power. We call it the Song, since if you know how, you can hear it, a quiet hum in the bones. If I collect enough Song, the concentrated power can reverse the Cataclysm. Undo all of this.",
++ "speaker_effect": {
++ "effect": [
++ { "u_lose_var": "cooper_goal_dk", "type": "dialogue", "context": "first_meeting" },
++ { "u_add_var": "cooper_goal_k", "type": "dialogue", "context": "first_meeting", "value": "yes" }
++ ]
++ },
++ "responses": [
++ { "text": "Do you have any proof that this will work?", "topic": "TALK_COOPER_WORK" },
++ {
++ "text": "You mentioned a woman, Brigitte. Why isn't she with you? What happened?",
++ "topic": "TALK_COOPERS_SIDE",
++ "condition": { "not": { "u_has_var": "asked_about_song", "type": "dialogue", "context": "song", "value": "yes" } }
++ },
++ {
++ "text": "Wait, Brigitte LaCroix? I've met her.",
++ "topic": "TALK_COOPER_KNOWBRIG",
++ "condition": {
++ "and": [
++ { "u_has_var": "asked_about_song", "type": "dialogue", "context": "song", "value": "yes" },
++ { "not": { "u_has_var": "cooper_friendly", "type": "dialogue", "context": "cooper", "value": "yes" } }
++ ]
++ }
++ },
++ { "text": "That's insane. I'm going.", "topic": "TALK_DONE" }
++ ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_COOPER_KNOWBRIG",
++ "dynamic_line": "Small world, huh? I hope she's doing fine. Despite our differences, I owe everything to her. I hope one day we'll be able to reconcile.",
++ "responses": [
++ { "text": "So, how do you know that any of this works?", "topic": "TALK_COOPER_WORK" },
++ { "text": "What differences? Why did you part ways?", "topic": "TALK_COOPERS_SIDE" }
++ ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_COOPER_ABOUT",
++ "dynamic_line": {
++ "u_has_var": "cooper_friendly",
++ "type": "dialogue",
++ "context": "cooper",
++ "value": "yes",
++ "no": "Sorry, but I don't know you that well and I'd rather not go into that.",
++ "yes": "I was born here in New England, lived here all my life. Was an accountant before the Collapse, if you can believe that. There wasn't really anything special about my life before I learned about the Song, so there isn't much to say."
++ },
++ "responses": [
++ {
++ "text": "I understand.",
++ "topic": "TALK_KINDRED_COOPER",
++ "condition": { "not": { "u_has_var": "cooper_friendly", "type": "dialogue", "context": "cooper", "value": "yes" } }
++ },
++ {
++ "text": "Do you have a favorite food?",
++ "topic": "TALK_COOPER_FOOD",
++ "condition": { "u_has_var": "cooper_friendly", "type": "dialogue", "context": "cooper", "value": "yes" }
++ },
++ {
++ "text": "I see. Thanks for sharing.",
++ "topic": "TALK_KINDRED_COOPER",
++ "condition": { "u_has_var": "cooper_friendly", "type": "dialogue", "context": "cooper", "value": "yes" }
++ }
++ ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_COOPER_FOOD",
++ "dynamic_line": "I've always loved crêpes.",
++ "responses": [ { "text": "Fair enough.", "topic": "TALK_KINDRED_COOPER" } ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_COOPER_KILL_PLAYER",
++ "dynamic_line": "No. You seem like you have a chance of surviving in this world. Plus, you took the time to actually hear me out, so there is a chance one day you'll hear the Song the same way I do.",
++ "responses": [
++ { "text": "Nevertheless, I can't allow you to keep killing people.", "topic": "TALK_COOPER_FIGHT" },
++ {
++ "text": "I'm glad you see it that way.",
++ "topic": "TALK_COOPER_AGREE",
++ "condition": { "not": { "u_has_trait": "seer_mark" } }
++ },
++ { "text": "Maybe one day I will.", "topic": "TALK_COOPER_AGREE", "condition": { "u_has_trait": "seer_mark" } },
++ { "text": "This is a waste of time. I'm leaving", "topic": "TALK_DONE" }
++ ]
++ }
++]
+--- a/data/json/mapgen/nested/city_npc_nested_spawns.json
++++ b/data/json/mapgen/nested/city_npc_nested_spawns.json
+@@ -138,5 +138,11 @@
+ "method": "json",
+ "nested_mapgen_id": "SEER_Brigitte_LaCroix_spawn",
+ "object": { "mapgensize": [ 1, 1 ], "place_npcs": [ { "class": "SEER_Brigitte_LaCroix", "x": 0, "y": 0 } ] }
++ },
++ {
++ "type": "mapgen",
++ "method": "json",
++ "nested_mapgen_id": "KINDRED_Darren_Cooper_spawn",
++ "object": { "mapgensize": [ 1, 1 ], "place_npcs": [ { "class": "KINDRED_Darren_Cooper", "x": 0, "y": 0 } ] }
+ }
+ ]
+--- a/data/json/mapgen/cabin.json
++++ b/data/json/mapgen/cabin.json
+@@ -33,7 +33,8 @@
+ "-----------GG-----------"
+ ],
+ "palettes": [ { "distribution": [ [ "cabin_palette", 1 ], [ "cabin_palette_abandoned", 1 ] ] } ],
+- "place_monsters": [ { "monster": "GROUP_ZOMBIE", "x": 7, "y": 4 } ]
++ "place_monsters": [ { "monster": "GROUP_ZOMBIE", "x": 7, "y": 4 } ],
++ "place_nested": [ { "chunks": [ [ "KINDRED_Darren_Cooper_spawn", 20 ], [ "null", 80 ] ], "x": 12, "y": 14 } ]
+ }
+ },
+ {
diff --git a/npc-06_lapin-update.patch b/npc-06_lapin-update.patch
new file mode 100644
index 0000000..779640a
--- /dev/null
+++ b/npc-06_lapin-update.patch
@@ -0,0 +1,121 @@
+--- a/data/json/npcs/holdouts/Mr_Lapin.json
++++ b/data/json/npcs/holdouts/Mr_Lapin.json
+@@ -47,6 +47,7 @@
+ { "text": "Heard anything about the outside world?", "topic": "TALK_WARRENER_WORLD" },
+ { "text": "You look different?", "topic": "TALK_WARRENER_MUTATION" },
+ { "text": "Anything I can help with?", "topic": "TALK_MISSION_LIST" },
++ { "text": "Do you need any resources?", "topic": "TALK_LAPIN_RESOURCES" },
+ { "text": "Well, bye.", "topic": "TALK_DONE" }
+ ]
+ },
+@@ -68,10 +69,37 @@
+ "dynamic_line": "People come to me to learn how to keep rabbits. They learn and they go. I like to think I'm making the world better.",
+ "responses": [
+ { "text": "…", "topic": "TALK_WARRENER" },
++ {
++ "text": "Anyone nearby I should meet?",
++ "topic": "TALK_WARRENER_ISHERWOOD",
++ "condition": { "u_has_var": "u_met_carlos_isherwood", "type": "general", "context": "meeting", "value": "no" }
++ },
+ { "text": "That sounds optimistic?", "topic": "TALK_WARRENER_WORLD_OPTIMISTIC" }
+ ]
+ },
+ {
++ "id": "TALK_WARRENER_ISHERWOOD",
++ "type": "talk_topic",
++ "dynamic_line": "There is a family of nearby farmers that I trade with. I'd appreciate it if you could go check on them.",
++ "responses": [
++ {
++ "text": "Seems like a deal to me.",
++ "topic": "TALK_WARRENER_ISHERWOOD_MISSION_ACCEPTED",
++ "effect": { "add_mission": "MISSION_Warrener_ISHERWOOD" }
++ },
++ { "text": "That seems rather dangerous, I think I'll pass.", "topic": "TALK_EVAC_MERCHANT" }
++ ]
++ },
++ {
++ "id": "TALK_WARRENER_ISHERWOOD_MISSION_ACCEPTED",
++ "type": "talk_topic",
++ "dynamic_line": "It can be quite a hike depending on your transportation. Lot of bad news between here and there.",
++ "responses": [
++ { "text": "Don't worry, I'll be careful.", "topic": "TALK_DONE" },
++ { "text": "Just a walk in the woods.", "topic": "TALK_DONE" }
++ ]
++ },
++ {
+ "type": "talk_topic",
+ "id": "TALK_WARRENER_WORLD_OPTIMISTIC",
+ "dynamic_line": "If I teach one hundred people how to raise rabbits, that's potentially a hundred communities given food and fur before those people teach anyone else.",
+@@ -106,6 +130,41 @@
+ ]
+ },
+ {
++ "type": "talk_topic",
++ "id": "TALK_LAPIN_RESOURCES",
++ "dynamic_line": "The bunnies and I love adding some diversity to the menu and I always need materials for patching fences.",
++ "repeat_responses": {
++ "for_item": [
++ "log",
++ "2x4",
++ "wood_panel",
++ "wood_sheet",
++ "material_sand",
++ "clay_lump",
++ "nail",
++ "wire",
++ "apple",
++ "banana",
++ "orange",
++ "blueberries",
++ "strawberries",
++ "raspberries",
++ "huckleberries",
++ "mulberries",
++ "plums",
++ "carrot",
++ "cabbage",
++ "lettuce",
++ "onion"
++ ],
++ "response": { "text": "Delivering <topic_item>.", "topic": "TALK_DELIVER_ASK" }
++ },
++ "responses": [
++ { "text": "That's all for now. Can we discuss something else?", "topic": "TALK_WARRENER" },
++ { "text": "That's all for now. I'd best get going.", "topic": "TALK_DONE" }
++ ]
++ },
++ {
+ "id": "MISSION_Warrener_LOG_1",
+ "type": "mission_definition",
+ "name": { "str": "Timber!" },
+@@ -153,5 +212,30 @@
+ "failure": "It's not a big deal, it isn't that urgent."
+ },
+ "end": { "effect": [ { "u_buy_item": "petpack", "count": 2 } ] }
++ },
++ {
++ "id": "MISSION_Warrener_ISHERWOOD",
++ "type": "mission_definition",
++ "name": { "str": "Visit the Isherwoods" },
++ "description": "There is a family that nearby that I'd like you to check in on. After you talk to all of them come back to me and tell me how they are doing.",
++ "goal": "MGOAL_CONDITION",
++ "difficulty": 3,
++ "start": {
++ "assign_mission_target": { "om_terrain": "farm_isherwood_2", "om_special": "Isherwood Farms", "reveal_radius": 3, "search_range": 360 }
++ },
++ "goal_condition": { "u_has_var": "u_met_carlos_isherwood", "type": "general", "context": "meeting", "value": "yes" },
++ "value": 5000,
++ "origins": [ "ORIGIN_SECONDARY" ],
++ "dialogue": {
++ "describe": "…",
++ "offer": "…",
++ "accepted": "…",
++ "rejected": "…",
++ "advice": "…",
++ "inquire": "Have you checked on them?",
++ "success": "Good, that's one less thing to worry about.",
++ "success_lie": "I'm glad to hear they are fine. Why haven't they been by then?",
++ "failure": "At least you came back with your life…"
++ }
+ }
+ ]
diff --git a/npc-07_lighthouse-family_v2.patch b/npc-07_lighthouse-family_v2.patch
new file mode 100644
index 0000000..b9292aa
--- /dev/null
+++ b/npc-07_lighthouse-family_v2.patch
@@ -0,0 +1,912 @@
+--- a/data/json/npcs/Lighthouse_Family/NPC_lighthouse_girl.json
++++ b/data/json/npcs/Lighthouse_Family/NPC_lighthouse_girl.json
+@@ -0,0 +1,121 @@
++[
++ {
++ "type": "npc",
++ "id": "NPC_lighthouse_girl",
++ "name_unique": "Angelina Frolova",
++ "gender": "female",
++ "class": "NC_NONE",
++ "attitude": 1,
++ "mission": 8,
++ "chat": "TALK_lighthouse_girl_start",
++ "faction": "fisherman_family"
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_lighthouse_girl_start",
++ "dynamic_line": "I'm scared. Where is my papa?",
++ "speaker_effect": { "sentinel": "met", "effect": [ "follow_only", { "add_mission": "MISSION_lighthouse_girl_0" } ] },
++ "responses": [
++ {
++ "text": "I want you to use this item.",
++ "topic": "TALK_lighthouse_girl_start",
++ "condition": "npc_following",
++ "effect": "npc_gets_item_to_use"
++ },
++ {
++ "text": "We're here.",
++ "topic": "TALK_lighthouse_girl_safe",
++ "condition": { "npc_at_om_location": "lighthouse_ground" },
++ "effect": [
++ "mission_success",
++ "clear_mission",
++ "stop_following",
++ { "npc_first_topic": "TALK_lighthouse_girl_safe" },
++ { "u_add_var": "lighthouse_girl", "type": "flag", "context": "safe", "value": "yes" }
++ ]
++ },
++ { "text": "Let's go.", "topic": "TALK_DONE" }
++ ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_lighthouse_girl_safe",
++ "dynamic_line": {
++ "u_has_mission": "MISSION_lighthouse_man_3",
++ "yes": {
++ "u_has_var": "lighthouse_woman_dead",
++ "type": "flag",
++ "context": "death",
++ "value": "yes",
++ "yes": "Thank you for saving me. It's a shame my mother didn't make it… you did everything you could, and I don't blame you for it…",
++ "no": "Thank you!"
++ },
++ "no": {
++ "u_has_var": "lighthouse_woman_dead",
++ "type": "flag",
++ "context": "death",
++ "value": "yes",
++ "yes": "Poor, poor mama…",
++ "no": "Hello."
++ }
++ },
++ "responses": [
++ {
++ "text": "Hi.",
++ "condition": { "u_has_var": "lighthouse_family_safe", "type": "flag", "context": "help", "value": "yes" },
++ "topic": "TALK_lighthouse_girl_1",
++ "effect": { "npc_first_topic": "TALK_lighthouse_girl_1" },
++ "switch": true
++ },
++ {
++ "truefalsetext": {
++ "true": "I'm sorry…",
++ "false": "…",
++ "condition": { "u_has_var": "lighthouse_woman_dead", "type": "flag", "context": "death", "value": "yes" }
++ },
++ "topic": "TALK_DONE",
++ "switch": true
++ }
++ ]
++ },
++ {
++ "type": "talk_topic",
++ "id": [ "TALK_lighthouse_girl_1", "TALK_lighthouse_girl_Background" ],
++ "dynamic_line": "How are you today?",
++ "responses": [
++ { "text": "About that job…", "condition": "has_assigned_mission", "topic": "TALK_MISSION_INQUIRE" },
++ { "text": "<BGSS_intro_question>", "topic": "TALK_lighthouse_girl_Background" },
++ { "text": "Do you need any help?", "topic": "TALK_MISSION_LIST" },
++ { "text": "Goodbye.", "topic": "TALK_DONE" }
++ ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_lighthouse_girl_Background",
++ "dynamic_line": "I don't have much to tell, sorry. I'm busy with helping my mom, tiding this place to make it our new home. You should talk to my dad, he doesn't look busy right now. Or always…"
++ },
++ {
++ "id": "MISSION_lighthouse_girl_0",
++ "type": "mission_definition",
++ "has_generic_rewards": false,
++ "name": { "str": "Protect fisherman's daughter" },
++ "description": "She looks like a nice girl. Maybe you should not let her die?",
++ "goal": "MGOAL_CONDITION",
++ "goal_condition": { "npc_has_var": "-", "type": "-", "context": "-", "value": "-" },
++ "difficulty": 0,
++ "value": 0,
++ "origins": [ "ORIGIN_SECONDARY" ],
++ "dialogue": {
++ "describe": "-",
++ "offer": "-",
++ "accepted": "-",
++ "rejected": "-",
++ "advice": "-",
++ "inquire": "-",
++ "success": "-",
++ "success_lie": "-",
++ "failure": "-"
++ },
++ "fail": { "effect": [ { "u_add_var": "lighthouse_girl_dead", "type": "flag", "context": "death", "value": "yes" } ] }
++ }
++]
+--- a/data/json/npcs/Lighthouse_Family/NPC_lighthouse_man.json
++++ b/data/json/npcs/Lighthouse_Family/NPC_lighthouse_man.json
+@@ -0,0 +1,487 @@
++[
++ {
++ "type": "npc",
++ "id": "NPC_lighthouse_man",
++ "gender": "male",
++ "class": "NC_NONE",
++ "name_unique": "Mikhail Frolov",
++ "name_suffix": "Fisherman",
++ "attitude": 0,
++ "mission": 8,
++ "chat": "TALK_lighthouse_man_1",
++ "faction": "fisherman_family",
++ "mission_offered": "MISSION_lighthouse_man_1"
++ },
++ {
++ "type": "npc_class",
++ "id": "NC_lighthouse_man",
++ "common": false,
++ "name": { "str": "Fisherman" },
++ "job_description": "I'm just wandering.",
++ "shopkeeper_item_group": "NPC_lighthouse_man_shop",
++ "traits": [ { "group": "NPC_starting_traits" }, { "group": "Appearance_Caucasian" } ],
++ "skills": [
++ { "skill": "ALL", "level": { "mul": [ { "one_in": 3 }, { "sum": [ { "dice": [ 4, 2 ] }, { "rng": [ -4, -1 ] } ] } ] } }
++ ]
++ },
++ {
++ "type": "item_group",
++ "id": "NPC_lighthouse_man_shop",
++ "subtype": "collection",
++ "items": [
++ { "item": "fish_bait", "count": [ 15, 35 ] },
++ { "item": "fish", "count": [ 5, 20 ] },
++ { "item": "fish_smoked", "count": [ 1, 4 ] },
++ { "item": "fish_cooked", "count": [ 4, 14 ] },
++ { "item": "salted_fish", "count": [ 2, 6 ] },
++ { "item": "fish_fried", "count": [ 2, 6 ] },
++ { "item": "soup_fish", "count": [ 35, 50 ], "container-item": "bottle_plastic" },
++ { "item": "fishspear", "prob": 20, "count": [ 4, 8 ] },
++ [ "doublespeargun", 20 ],
++ [ "fish_trap", 55 ],
++ [ "fishing_hook_bone", 100 ],
++ [ "fishing_rod_basic", 100 ]
++ ]
++ },
++ {
++ "type": "talk_topic",
++ "id": [
++ "TALK_lighthouse_man_1",
++ "TALK_lighthouse_man_Background",
++ "TALK_lighthouse_man_hay",
++ "TALK_lighthouse_man_survivors_yes",
++ "TALK_lighthouse_man_survivors_no"
++ ],
++ "dynamic_line": "<greet>",
++ "responses": [
++ { "text": "About that job…", "condition": "has_assigned_mission", "topic": "TALK_MISSION_INQUIRE" },
++ { "text": "<BGSS_intro_question>", "topic": "TALK_lighthouse_man_Background" },
++ {
++ "text": "How are you doing?",
++ "topic": "TALK_lighthouse_man_hay",
++ "condition": { "npc_has_var": "helped_lighthouse_man", "type": "flag", "context": "help", "value": "yes" }
++ },
++ { "text": "Do you need any help?", "topic": "TALK_MISSION_LIST" },
++ {
++ "text": "Care to trade?",
++ "topic": "TALK_lighthouse_man_1",
++ "condition": { "npc_has_var": "helped_lighthouse_man", "type": "flag", "context": "help", "value": "yes" },
++ "effect": "start_trade"
++ },
++ {
++ "text": "Has anyone come recently?",
++ "condition": { "u_has_var": "lighthouse_fixed", "type": "global", "context": "safe_space", "value": "yes" },
++ "trial": { "type": "CONDITION", "condition": { "not": { "npc_has_effect": "lighthouse_survivor_delay" } } },
++ "success": {
++ "topic": "TALK_lighthouse_man_survivors_yes",
++ "effect": [
++ { "npc_add_effect": "lighthouse_survivor_delay", "duration": 1209600 },
++ { "mapgen_update": "lighthouse_man_survivor", "om_terrain": "lighthouse_ground" }
++ ]
++ },
++ "failure": { "topic": "TALK_lighthouse_man_survivors_no" }
++ },
++ { "text": "Goodbye.", "topic": "TALK_DONE" }
++ ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_lighthouse_man_Background",
++ "dynamic_line": "I'm just a simple man from a simple family. Before <the_cataclysm> I had a fishing boat, and I went to sea on it, to catch fish and other marine life. This is how my grandfather lived, my father lived, and I began to live like that. I had a large family, 7 children, but not many survived, only my wife and daughter remained…"
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_lighthouse_man_hay",
++ "dynamic_line": "You know, <very> good. It is cozy here, there is a lot of space, and most importantly, it's safe. We even started considering this place as our new home. By the way, while I was fishing, a bottle with a piece of paper came to the shore of our island. Here, take a look.\", he gave you a piece of paper, something was written on it: '0030045-0030045-35321700', with something similar to lightning scribbled nearby. \"I wonder what it could mean…"
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_lighthouse_man_survivors_yes",
++ "dynamic_line": "Good news, <name_g>. One survivor sailed to us recently."
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_lighthouse_man_survivors_no",
++ "dynamic_line": "Nobody came, <name_g>. I'm beginning to doubt that anyone else has survived besides us…"
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_lighthouse_man_lighthouse",
++ "dynamic_line": "Are we there yet, <name_g>?",
++ "responses": [
++ { "text": "I want you to use this item.", "topic": "TALK_lighthouse_man_lighthouse", "effect": "npc_gets_item_to_use" },
++ {
++ "text": "We're here.",
++ "topic": "TALK_MISSION_INQUIRE",
++ "condition": "mission_complete",
++ "effect": [ "stop_following", { "npc_first_topic": "TALK_lighthouse_man_1" } ]
++ },
++ { "text": "Almost.", "topic": "TALK_DONE" }
++ ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_lighthouse_man_cleaning",
++ "dynamic_line": "Is it safe, my <name_g>?",
++ "responses": [
++ {
++ "text": "Yes. Ground floor is clear.",
++ "topic": "TALK_lighthouse_man_cleaned",
++ "condition": {
++ "and": [
++ { "npc_has_var": "lighthouse_man", "type": "count", "context": "cleaning", "value": "0" },
++ "at_safe_space",
++ { "npc_at_om_location": "lighthouse_ground" }
++ ]
++ },
++ "effect": { "npc_adjust_var": "lighthouse_man", "type": "count", "context": "cleaning", "adjustment": 1 }
++ },
++ {
++ "text": "Yes. First floor is clear.",
++ "topic": "TALK_lighthouse_man_cleaned",
++ "condition": {
++ "and": [
++ { "npc_has_var": "lighthouse_man", "type": "count", "context": "cleaning", "value": "1" },
++ "at_safe_space",
++ { "npc_at_om_location": "lighthouse_z1" }
++ ]
++ },
++ "effect": { "npc_adjust_var": "lighthouse_man", "type": "count", "context": "cleaning", "adjustment": 1 }
++ },
++ {
++ "text": "Yes. Second floor is clear.",
++ "topic": "TALK_lighthouse_man_cleaned",
++ "condition": {
++ "and": [
++ { "npc_has_var": "lighthouse_man", "type": "count", "context": "cleaning", "value": "2" },
++ "at_safe_space",
++ { "npc_at_om_location": "lighthouse_z2" }
++ ]
++ },
++ "effect": { "npc_adjust_var": "lighthouse_man", "type": "count", "context": "cleaning", "adjustment": 1 }
++ },
++ {
++ "text": "Yes. Third floor is clear.",
++ "topic": "TALK_lighthouse_man_cleaned",
++ "condition": {
++ "and": [
++ { "npc_has_var": "lighthouse_man", "type": "count", "context": "cleaning", "value": "3" },
++ "at_safe_space",
++ { "npc_at_om_location": "lighthouse_z3" }
++ ]
++ },
++ "effect": { "npc_adjust_var": "lighthouse_man", "type": "count", "context": "cleaning", "adjustment": 1 }
++ },
++ {
++ "text": "Yes. Fourth floor is clear.",
++ "topic": "TALK_lighthouse_man_cleaned",
++ "condition": {
++ "and": [
++ { "npc_has_var": "lighthouse_man", "type": "count", "context": "cleaning", "value": "4" },
++ "at_safe_space",
++ { "npc_at_om_location": "lighthouse_z4" }
++ ]
++ },
++ "effect": { "npc_adjust_var": "lighthouse_man", "type": "count", "context": "cleaning", "adjustment": 1 }
++ },
++ {
++ "text": "Yes. Top floor is clear.",
++ "condition": {
++ "and": [
++ { "npc_has_var": "lighthouse_man", "type": "count", "context": "cleaning", "value": "5" },
++ "at_safe_space",
++ { "npc_at_om_location": "lighthouse_z5" }
++ ]
++ },
++ "effect": { "npc_adjust_var": "lighthouse_man", "type": "count", "context": "cleaning", "adjustment": 1 },
++ "topic": "TALK_lighthouse_man_cleaned_done"
++ },
++ {
++ "text": "Looks like that's over.",
++ "condition": {
++ "and": [
++ { "npc_has_var": "lighthouse_man", "type": "count", "context": "cleaning", "value": "6" },
++ "at_safe_space",
++ { "npc_at_om_location": "lighthouse_ground" }
++ ]
++ },
++ "effect": { "npc_adjust_var": "lighthouse_man", "type": "count", "context": "cleaning", "adjustment": 1 },
++ "topic": "TALK_MISSION_INQUIRE"
++ },
++ { "text": "Not yet.", "topic": "TALK_DONE" }
++ ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_lighthouse_man_cleaned",
++ "dynamic_line": "<its_safe> Let's clean the next floor.",
++ "responses": [ { "text": "…", "topic": "TALK_DONE" } ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_lighthouse_man_cleaned_done",
++ "dynamic_line": "<its_safe> Let's return to the first floor.",
++ "responses": [ { "text": "…", "topic": "TALK_DONE" } ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_lighthouse_man_family",
++ "dynamic_line": "Did you find them, <name_g>?",
++ "responses": [
++ {
++ "text": "We did it. All safe.",
++ "topic": "TALK_MISSION_SUCCESS",
++ "condition": {
++ "and": [
++ { "u_has_mission": "MISSION_lighthouse_man_3" },
++ { "not": "mission_complete" },
++ { "u_has_var": "lighthouse_woman", "type": "flag", "context": "safe", "value": "yes" },
++ { "u_has_var": "lighthouse_girl", "type": "flag", "context": "safe", "value": "yes" }
++ ]
++ },
++ "effect": [ "mission_success", { "npc_first_topic": "TALK_lighthouse_man_1" } ]
++ },
++ {
++ "text": "I'm sorry, I failed you… I couldn't bring them alive…",
++ "topic": "TALK_lighthouse_man_fail",
++ "condition": {
++ "and": [
++ "mission_complete",
++ { "not": { "u_has_var": "lighthouse_woman", "type": "flag", "context": "safe", "value": "yes" } },
++ { "u_has_var": "lighthouse_girl_dead", "type": "flag", "context": "death", "value": "yes" }
++ ]
++ }
++ },
++ {
++ "text": "I'm sorry, I failed you… I couldn't bring your wife alive…",
++ "topic": "TALK_lighthouse_man_fail",
++ "condition": { "and": [ "mission_complete", { "u_has_var": "lighthouse_girl", "type": "flag", "context": "safe", "value": "yes" } ] }
++ },
++ {
++ "text": "I'm sorry, I failed you… I couldn't bring your daughter alive…",
++ "topic": "TALK_lighthouse_man_fail",
++ "condition": {
++ "and": [
++ { "not": "mission_complete" },
++ { "u_has_var": "lighthouse_woman", "type": "flag", "context": "safe", "value": "yes" },
++ { "u_has_var": "lighthouse_girl_dead", "type": "flag", "context": "death", "value": "yes" }
++ ]
++ }
++ },
++ { "text": "Nothing, really.", "topic": "TALK_DONE" }
++ ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_lighthouse_man_fail",
++ "dynamic_line": "<name_g>… I entrusted you with the most valuable thing that I have left, and you…",
++ "responses": [
++ { "text": "I'm sorry…", "topic": "TALK_DONE", "effect": [ "mission_failure", "clear_mission", "end_conversation" ] }
++ ]
++ },
++ {
++ "id": "MISSION_lighthouse_man_1",
++ "type": "mission_definition",
++ "has_generic_rewards": false,
++ "name": { "str": "Lighthouse" },
++ "description": "Lead Mikhail to lighthouse.",
++ "goal": "MGOAL_GO_TO",
++ "difficulty": 0,
++ "value": 5000,
++ "start": {
++ "assign_mission_target": { "om_terrain": "lighthouse_ground", "om_special": "Lighthouse Island", "reveal_radius": 10, "search_range": 360 },
++ "update_mapgen": [
++ {
++ "om_terrain": "lighthouse_ground",
++ "place_monsters": [ { "monster": "GROUP_ZOMBIE", "x": [ 1, 22 ], "y": [ 1, 22 ], "density": 0.3 } ]
++ },
++ {
++ "om_terrain": "lighthouse_z1",
++ "place_monsters": [ { "monster": "GROUP_ZOMBIE", "x": [ 11, 16 ], "y": [ 8, 16 ], "density": 0.3 } ]
++ },
++ {
++ "om_terrain": "lighthouse_z2",
++ "place_monsters": [ { "monster": "GROUP_ZOMBIE", "x": [ 11, 16 ], "y": [ 8, 16 ], "density": 0.3 } ]
++ },
++ {
++ "om_terrain": "lighthouse_z3",
++ "place_monsters": [ { "monster": "GROUP_ZOMBIE", "x": [ 11, 16 ], "y": [ 8, 16 ], "density": 0.3 } ]
++ },
++ {
++ "om_terrain": "lighthouse_z4",
++ "place_monsters": [ { "monster": "GROUP_ZOMBIE", "x": [ 11, 16 ], "y": [ 8, 16 ], "density": 0.3 } ]
++ },
++ {
++ "om_terrain": "lighthouse_z5",
++ "place_monsters": [ { "monster": "GROUP_ZOMBIE", "x": [ 11, 16 ], "y": [ 8, 16 ], "density": 0.3 } ]
++ }
++ ],
++ "effect": [ "follow_only", { "npc_first_topic": "TALK_lighthouse_man_lighthouse" } ]
++ },
++ "end": { "opinion": { "trust": 3, "value": 3 } },
++ "origins": [ "ORIGIN_SECONDARY" ],
++ "followup": "MISSION_lighthouse_man_2",
++ "dialogue": {
++ "describe": "-",
++ "offer": "We've been wandering around the state with my family for a long time since <the_cataclysm>, and I realized that the safest hideout is the island. I left my family in a shelter, and went to explore the area, looking for some island nearby, in a lake or in the ocean. And you know, I found a sea map marked with navigational beacons near here. If you want, you can help me get to one of these and take a good look at it.",
++ "accepted": "Good. I'll be right behind you.",
++ "rejected": "Well, it's your choice.",
++ "advice": "First we need to find a transport to get there.",
++ "inquire": "We finally reached it.",
++ "success": "Looks nice, <name_g>. Now I need to clean it from <zombies> somehow…",
++ "success_lie": "-",
++ "failure": "-"
++ }
++ },
++ {
++ "id": "MISSION_lighthouse_man_2",
++ "type": "mission_definition",
++ "has_generic_rewards": false,
++ "name": { "str": "House cleaning" },
++ "description": "Clean lighthouse from <zombies> with Mikhail.",
++ "goal": "MGOAL_CONDITION",
++ "goal_condition": { "npc_has_var": "lighthouse_man", "type": "count", "context": "cleaning", "value": "7" },
++ "difficulty": 0,
++ "value": 5000,
++ "start": {
++ "effect": [
++ "follow_only",
++ { "npc_first_topic": "TALK_lighthouse_man_cleaning" },
++ { "npc_add_var": "lighthouse_man", "type": "count", "context": "cleaning", "value": "0" }
++ ]
++ },
++ "end": {
++ "opinion": { "trust": 3, "value": 3 },
++ "update_mapgen": {
++ "om_terrain": "lighthouse_ground",
++ "faction_owner": [ { "id": "fisherman_family", "x": [ 0, 23 ], "y": [ 0, 23 ] } ],
++ "place_zones": [ { "type": "NPC_INVESTIGATE_ONLY", "faction": "fisherman_family", "x": [ 0, 23 ], "y": [ 0, 23 ] } ]
++ },
++ "effect": [
++ "stop_following",
++ { "npc_first_topic": "TALK_lighthouse_man_1" },
++ { "npc_lose_var": "lighthouse_man", "type": "count", "context": "cleaning" }
++ ]
++ },
++ "origins": [ "ORIGIN_SECONDARY" ],
++ "followup": "MISSION_lighthouse_man_3",
++ "dialogue": {
++ "describe": "-",
++ "offer": "So, we found the lighthouse. Now, I need to clean it. Want to help me with it?",
++ "accepted": "Great. Let's do it together. I'll be right behind you. We will clean floor by floor. If you decide that the floor is clean, tell me about it, and we will move on to the next, and so on to the very top.",
++ "rejected": "Well, it's your choice.",
++ "advice": "Be <very> careful. These <name_b>s are most dangerous in tight spaces.",
++ "inquire": "<its_safe>",
++ "success": "Great, <very> great. All that remains is to wash all the floors…",
++ "success_lie": "-",
++ "failure": "-"
++ }
++ },
++ {
++ "id": "MISSION_lighthouse_man_3",
++ "type": "mission_definition",
++ "name": { "str": "Fisherman's family" },
++ "description": "Mikhail asked you to bring back his family.",
++ "goal": "MGOAL_ASSASSINATE",
++ "difficulty": 0,
++ "value": 25000,
++ "start": {
++ "effect": { "npc_first_topic": "TALK_lighthouse_man_family" },
++ "assign_mission_target": { "om_terrain": "house_04_basement", "reveal_radius": 2 },
++ "update_mapgen": {
++ "place_npcs": [
++ { "class": "NPC_lighthouse_woman", "x": 4, "y": 8, "target": true },
++ { "class": "NPC_lighthouse_girl", "x": 3, "y": 8 }
++ ]
++ }
++ },
++ "end": {
++ "opinion": { "trust": 6, "value": 6 },
++ "effect": { "u_add_var": "lighthouse_family_safe", "type": "flag", "context": "help", "value": "yes" }
++ },
++ "origins": [ "ORIGIN_SECONDARY" ],
++ "followup": "MISSION_lighthouse_man_4",
++ "dialogue": {
++ "describe": "-",
++ "offer": "We found the lighthouse and cleared it of <zombies>. Now, I need to bring my family here. May I ask you for a favor? Since you bring me here, can you go back, find my family and bring them here?",
++ "accepted": "You are my savior! I'll take a look around here for a while, prepare everything here for their arrival.",
++ "rejected": "Well, it's your choice.",
++ "advice": "Please be very careful. I don't want to lose them…",
++ "inquire": "-",
++ "success": "I don't even know how to thank you, <name_g>. I am in eternal debt to you.",
++ "success_lie": "-",
++ "failure": "-"
++ }
++ },
++ {
++ "id": "MISSION_lighthouse_man_4",
++ "type": "mission_definition",
++ "name": { "str": "Fisherman's boat" },
++ "description": "Help Mikhail make a boat. Bring 250 nails.",
++ "goal": "MGOAL_FIND_ITEM",
++ "item": "nail",
++ "count": 250,
++ "difficulty": 0,
++ "value": 10000,
++ "end": {
++ "opinion": { "trust": 3, "value": 3 },
++ "update_mapgen": {
++ "om_terrain": "lighthouse_ground",
++ "place_vehicles": [ { "vehicle": "canoe", "x": 3, "y": 3, "rotation": 0, "status": 0, "chance": 100 } ]
++ },
++ "effect": [ { "npc_add_var": "helped_lighthouse_man", "type": "flag", "context": "help", "value": "yes" } ]
++ },
++ "origins": [ "ORIGIN_SECONDARY" ],
++ "followup": "MISSION_lighthouse_man_5",
++ "dialogue": {
++ "describe": "-",
++ "offer": "The building has been cleared of <zombies>, my family is here, everything is going very well. It remains only to provide ourselves with food, transport and we can not worry about the future. You helped me and my family so much, can you help us with something else? I need a boat for fishing, or just to explore the area. Can you help me make a boat?",
++ "accepted": "Thank you, <name_g>. I need only 250 nails. I'll find the planks, the rest of the tools too, but the main problem is the nails. Too much for one boat, but I want to have resources in reserve, just in case.",
++ "rejected": "Well, it's your choice.",
++ "advice": "Please, if you can, don't disassemble furniture here. It can still be useful.",
++ "inquire": "Did you find it?",
++ "success": "<very> good, <name_g>, thank you! Now we are not afraid of hunger, rain, or other bad weather, he-he. By the way, I have a small supply of fish, tackle, baits and rods. If you are interested, I can share some with you.",
++ "success_lie": "-",
++ "failure": "-"
++ }
++ },
++ {
++ "id": "MISSION_lighthouse_man_5",
++ "type": "mission_definition",
++ "name": { "str": "Fixing lighthouse" },
++ "description": "Mikhail asked you to find someone, who have enough expertise to fix the mechanism of lighthouse.",
++ "goal": "MGOAL_CONDITION",
++ "goal_condition": { "u_has_var": "lighthouse_fixed", "type": "global", "context": "safe_space", "value": "ready" },
++ "difficulty": 0,
++ "value": 100000,
++ "end": {
++ "opinion": { "trust": 3, "value": 3 },
++ "update_mapgen": {
++ "om_terrain": "lighthouse_z5",
++ "place_terrain": [ { "ter": "t_thconc_floor_olight", "x": 11, "y": 12 }, { "ter": "t_thconc_floor_olight", "x": 13, "y": 13 } ]
++ },
++ "effect": [
++ { "npc_add_effect": "lighthouse_survivor_delay", "duration": 1209600 },
++ { "u_add_var": "lighthouse_fixed", "type": "global", "context": "safe_space", "value": "yes" }
++ ]
++ },
++ "origins": [ "ORIGIN_SECONDARY" ],
++ "dialogue": {
++ "describe": "-",
++ "offer": "My family is here, we have food, water, boat and a roof over our heads, all thanks to you, <name_g>. Now, I also want to help other survivors. Here's what I thought: if I can get this old lighthouse up and running, other survivors will see its light from afar. If they see it, they will think that there are living people here, and will try to get here. Can you help me fix it?",
++ "accepted": "I knew you wouldn't refuse! But there is one problem: I have no idea how to fix it. Maybe if you met someone who have experience in electrical engineering, we can figure out how to start this old junk.",
++ "rejected": "Well, it's your choice.",
++ "advice": "I'm sure that not all burned in flames of <the_cataclysm> and you can find someone suitable.",
++ "inquire": "Well, have you fixed it?",
++ "success": "Splendid, <name_g>! We can only wait now…",
++ "success_lie": "-",
++ "failure": "-"
++ }
++ },
++ {
++ "type": "mapgen",
++ "update_mapgen_id": "lighthouse_man_survivor",
++ "method": "json",
++ "object": { "place_npcs": [ { "class": "NPC_survivor_lighthouse", "x": [ 7, 17 ], "y": [ 10, 15 ] } ] }
++ }
++]
+--- a/data/json/npcs/Lighthouse_Family/NPC_lighthouse_woman.json
++++ b/data/json/npcs/Lighthouse_Family/NPC_lighthouse_woman.json
+@@ -0,0 +1,121 @@
++[
++ {
++ "type": "npc",
++ "id": "NPC_lighthouse_woman",
++ "name_unique": "Heather Frolova",
++ "gender": "female",
++ "class": "NC_NONE",
++ "attitude": 1,
++ "mission": 8,
++ "chat": "TALK_lighthouse_woman_start",
++ "faction": "fisherman_family"
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_lighthouse_woman_start",
++ "dynamic_line": "I'm scared. Where is my husband?",
++ "speaker_effect": { "sentinel": "met", "effect": [ "follow_only", { "add_mission": "MISSION_lighthouse_woman_0" } ] },
++ "responses": [
++ {
++ "text": "I want you to use this item.",
++ "topic": "TALK_lighthouse_woman_start",
++ "condition": "npc_following",
++ "effect": "npc_gets_item_to_use"
++ },
++ {
++ "text": "We're here.",
++ "topic": "TALK_lighthouse_woman_safe",
++ "condition": { "npc_at_om_location": "lighthouse_ground" },
++ "effect": [
++ "mission_success",
++ "clear_mission",
++ "stop_following",
++ { "npc_first_topic": "TALK_lighthouse_woman_safe" },
++ { "u_add_var": "lighthouse_woman", "type": "flag", "context": "safe", "value": "yes" }
++ ]
++ },
++ { "text": "Let's go.", "topic": "TALK_DONE" }
++ ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_lighthouse_woman_safe",
++ "dynamic_line": {
++ "u_has_mission": "MISSION_lighthouse_man_3",
++ "yes": {
++ "u_has_var": "lighthouse_girl_dead",
++ "type": "flag",
++ "context": "death",
++ "value": "yes",
++ "yes": "Thank you for saving me. It's a shame my Angelina didn't make it… you did everything you could, and I don't blame you for it…",
++ "no": "Thank you!"
++ },
++ "no": {
++ "u_has_var": "lighthouse_girl_dead",
++ "type": "flag",
++ "context": "death",
++ "value": "yes",
++ "yes": "Poor, poor Angelina…",
++ "no": "Hello."
++ }
++ },
++ "responses": [
++ {
++ "text": "Hi.",
++ "condition": { "u_has_var": "lighthouse_family_safe", "type": "flag", "context": "help", "value": "yes" },
++ "topic": "TALK_lighthouse_woman_1",
++ "effect": { "npc_first_topic": "TALK_lighthouse_woman_1" },
++ "switch": true
++ },
++ {
++ "truefalsetext": {
++ "true": "I'm sorry…",
++ "false": "…",
++ "condition": { "u_has_var": "lighthouse_girl_dead", "type": "flag", "context": "death", "value": "yes" }
++ },
++ "topic": "TALK_DONE",
++ "switch": true
++ }
++ ]
++ },
++ {
++ "type": "talk_topic",
++ "id": [ "TALK_lighthouse_woman_1", "TALK_lighthouse_woman_Background" ],
++ "dynamic_line": "How are you today?",
++ "responses": [
++ { "text": "About that job…", "condition": "has_assigned_mission", "topic": "TALK_MISSION_INQUIRE" },
++ { "text": "<BGSS_intro_question>", "topic": "TALK_lighthouse_woman_Background" },
++ { "text": "Do you need any help?", "topic": "TALK_MISSION_LIST" },
++ { "text": "Goodbye.", "topic": "TALK_DONE" }
++ ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_lighthouse_woman_Background",
++ "dynamic_line": "I don't have much to tell, sorry. I'm busy with tiding this place, making it our new home. You should talk to my husband, he doesn't look busy right now. Or always…"
++ },
++ {
++ "id": "MISSION_lighthouse_woman_0",
++ "type": "mission_definition",
++ "has_generic_rewards": false,
++ "name": { "str": "Protect fisherman's wife" },
++ "description": "She looks like a nice woman. Maybe you should not let her die?",
++ "goal": "MGOAL_CONDITION",
++ "goal_condition": { "npc_has_var": "-", "type": "-", "context": "-", "value": "-" },
++ "difficulty": 0,
++ "value": 0,
++ "origins": [ "ORIGIN_SECONDARY" ],
++ "dialogue": {
++ "describe": "-",
++ "offer": "-",
++ "accepted": "-",
++ "rejected": "-",
++ "advice": "-",
++ "inquire": "-",
++ "success": "-",
++ "success_lie": "-",
++ "failure": "-"
++ },
++ "fail": { "effect": [ { "u_add_var": "lighthouse_wife_dead", "type": "flag", "context": "death", "value": "yes" } ] }
++ }
++]
+--- a/data/json/npcs/Lighthouse_Family/TALK_fix_lighthouse.json
++++ b/data/json/npcs/Lighthouse_Family/TALK_fix_lighthouse.json
+@@ -0,0 +1,79 @@
++[
++ {
++ "type": "talk_topic",
++ "id": [ "TALK_FRIEND", "TALK_GIVE_ITEM", "TALK_USE_ITEM", "TALK_RADIO" ],
++ "responses": [
++ {
++ "text": "You said that you have experience in electrical engineering…",
++ "topic": "TALK_ENG_LIGHTHOUSE",
++ "condition": {
++ "and": [ { "npc_has_skill": { "skill": "mechanics", "level": 6 } }, { "u_has_mission": "MISSION_lighthouse_man_5" } ]
++ }
++ }
++ ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_ENG_LIGHTHOUSE",
++ "dynamic_line": "I did, actually. Why are you asking?",
++ "responses": [
++ {
++ "text": "We're here. Ready to start?",
++ "topic": "TALK_ENG_LIGHTHOUSE_2",
++ "condition": { "npc_at_om_location": "lighthouse_z4" },
++ "effect": [ "leave", "assign_guard" ]
++ },
++ { "text": "Can you repair the mechanism of the lighthouse?", "topic": "TALK_ENG_LIGHTHOUSE_1" },
++ { "text": "<done_conversation_section>", "topic": "TALK_NONE" }
++ ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_ENG_LIGHTHOUSE_1",
++ "dynamic_line": "Sure thing, boss. Take me there and in a few days it will be like new.",
++ "responses": [ { "text": "<done_conversation_section>", "topic": "TALK_DONE" } ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_ENG_LIGHTHOUSE_2",
++ "dynamic_line": "Hmm, looks <shitty>. I'll do my best.",
++ "responses": [
++ {
++ "text": "Start working.",
++ "topic": "TALK_DONE",
++ "effect": [
++ { "npc_first_topic": "TALK_ENG_LIGHTHOUSE_WORKING" },
++ { "npc_add_effect": "lighthouse_repairs_underway", "duration": 172800 }
++ ]
++ }
++ ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_ENG_LIGHTHOUSE_WORKING",
++ "dynamic_line": {
++ "npc_has_effect": "lighthouse_repairs_underway",
++ "yes": "I'm still working, boss.",
++ "no": "All done, boss. Tell that fisherman to try it in action."
++ },
++ "speaker_effect": {
++ "sentinel": "done",
++ "condition": { "not": { "npc_has_effect": "lighthouse_repairs_underway" } },
++ "effect": { "u_add_var": "lighthouse_fixed", "type": "global", "context": "safe_space", "value": "ready" }
++ },
++ "responses": [
++ {
++ "text": "We're done here. <end_talking>",
++ "topic": "TALK_DONE",
++ "condition": {
++ "and": [
++ { "not": { "npc_has_effect": "lighthouse_repairs_underway" } },
++ { "not": { "u_has_mission": "MISSION_lighthouse_man_5" } }
++ ]
++ },
++ "effect": "follow"
++ },
++ { "text": "Good.", "topic": "TALK_DONE" }
++ ]
++ }
++]
+--- a/data/json/npcs/Lighthouse_Family/npc_survivor.json
++++ b/data/json/npcs/Lighthouse_Family/npc_survivor.json
+@@ -0,0 +1,43 @@
++[
++ {
++ "type": "npc",
++ "id": "NPC_survivor_lighthouse",
++ "//": "Generic random survivor related to lighthouse family",
++ "class": "NC_NONE",
++ "attitude": 0,
++ "mission": 7,
++ "chat": "TALK_LIGHTHOUSE_SURVIVOR",
++ "faction": "fisherman_family"
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_LIGHTHOUSE_SURVIVOR",
++ "dynamic_line": "Hello! Glad to meet another survivor.",
++ "responses": [ { "text": "Me too. How did you manage to get here?", "topic": "TALK_LIGHTHOUSE_SURVIVOR1" } ]
++ },
++ {
++ "//": "Could use more variety.",
++ "type": "talk_topic",
++ "id": "TALK_LIGHTHOUSE_SURVIVOR1",
++ "dynamic_line": {
++ "and": [
++ [
++ "During one of my night searches of food and supplies, I noticed a bright glow that came from somewhere far away. I thought that one of the survivors had lit it to indicate their location. As you can see, I was right. I managed to find a boat near the nearest shore, on which I set sail.",
++ "I have been sailing on my little boat from coast to coast for a long time. In truth, the boat was not entirely mine, but it doesn't matter. That way of life provided me with sufficient safety from the <zombies>, and I managed to get around the sea creatures deftly. When I saw a distant light, at first, I could not believe my eyes. Then, I decided to find out what it is."
++ ],
++ [
++ " Unfortunately, during my 'voyage' to this lighthouse, luck turned away from me. I was attacked by some <monster> from the underwater depths. I couldn't fight off him and he dragged my ship to the bottom. The waves brought me straight to the shore of this little island. I still don't understand by what miracle I managed to survive, <name_g>.",
++ " Unfortunately, when I arrived here, I forgot to tie my boat, and during yesterday's storm it was carried off somewhere. Well, you don't always have to be lucky, right?",
++ " I sailed here a few days ago. Mikhail and his family are very hospitable. Unfortunately, during our joint fishing, we were attacked by a swarm of underwater <monster>'s, and my boat was smashed to pieces. It was <very> scary, we could barely sail away on Mikhail's ship."
++ ]
++ ]
++ },
++ "responses": [
++ {
++ "text": "I'm glad you are OK.",
++ "topic": "TALK_STRANGER_FRIENDLY",
++ "effect": { "npc_first_topic": "TALK_STRANGER_FRIENDLY" }
++ }
++ ]
++ }
++]
+--- a/data/json/npcs/Lighthouse_Family/effects.json
++++ b/data/json/npcs/Lighthouse_Family/effects.json
+@@ -0,0 +1,20 @@
++[
++ {
++ "type": "effect_type",
++ "id": "lighthouse_survivor_delay",
++ "name": [ "Asked about survivors" ],
++ "desc": [ "AI tag: for having recently asked an NPC about new people. This is a bug if you have it." ],
++ "max_intensity": 1,
++ "int_dur_factor": "336 h",
++ "base_mods": { "per_mod": [ 0 ] }
++ },
++ {
++ "type": "effect_type",
++ "id": "lighthouse_repairs_underway",
++ "name": [ "Repairing lighthouse" ],
++ "desc": [ "AI tag: for repairing the lighthouse. This is a bug if you have it." ],
++ "max_intensity": 1,
++ "int_dur_factor": "48 h",
++ "base_mods": { "per_mod": [ 0 ] }
++ }
++]
+--- a/data/json/mapgen/dock.json
++++ b/data/json/mapgen/dock.json
+@@ -74,7 +74,8 @@
+ " dddddddddddd ",
+ " dddddddddddd "
+ ],
+- "palettes": [ "dock_small" ]
++ "palettes": [ "dock_small" ],
++ "place_nested": [ { "chunks": [ [ "NPC_lighthouse_man_spawn", 25 ], [ "null", 75 ] ], "x": 12, "y": 21 } ]
+ }
+ },
+ {
+--- a/data/json/mapgen/nested/npc_nested_spawns.json
++++ b/data/json/mapgen/nested/npc_nested_spawns.json
+@@ -0,0 +1,8 @@
++[
++ {
++ "type": "mapgen",
++ "method": "json",
++ "nested_mapgen_id": "NPC_lighthouse_man_spawn",
++ "object": { "mapgensize": [ 1, 1 ], "place_npcs": [ { "class": "NPC_lighthouse_man", "x": 0, "y": 0 } ] }
++ }
++]
diff --git a/npc-08_nurse-takes-more-meds.patch b/npc-08_nurse-takes-more-meds.patch
new file mode 100644
index 0000000..0724172
--- /dev/null
+++ b/npc-08_nurse-takes-more-meds.patch
@@ -0,0 +1,68 @@
+--- a/data/json/npcs/tacoma_ranch/NPC_ranch_nurse.json
++++ b/data/json/npcs/tacoma_ranch/NPC_ranch_nurse.json
+@@ -36,25 +36,62 @@
+ "repeat_responses": {
+ "for_item": [
+- "1st_aid",
++ "adderall",
++ "adrenaline_injector",
++ "anesthetic",
+ "antibiotics",
++ "antifungal",
++ "antiparasitic",
+ "aspirin",
+ "bandages",
++ "bandages_makeshift",
++ "bandages_makeshift_bleached",
++ "bandages_makeshift_boiled",
+ "bfipowder",
++ "bonemeal_tablet",
++ "caffeine",
++ "calcium_tablet",
++ "cattail_jelly",
+ "chem_hydrogen_peroxide",
+ "codeine",
++ "contacts",
++ "cotton_ball",
+ "dayquil",
++ "disincottonball",
+ "disinfectant",
++ "disinfectant_makeshift",
++ "disinrag",
++ "diazepam",
++ "eyedrops",
++ "flavored_bonemeal_tablet",
++ "gummy_vitamins",
++ "inj_vitb",
++ "inj_iron",
++ "iodine",
++ "medical_gauze",
++ "medical_tape",
+ "morphine",
++ "mugwort_oil",
++ "nic_gum",
+ "nyquil",
+ "oxycodone",
++ "pepto",
++ "pills_sleep",
+ "poppy_pain",
+ "poppysyrup",
++ "prozac",
++ "prussian_blue",
+ "quikclot",
++ "saline",
++ "tea_bark",
++ "thermometer",
++ "thorazine",
+ "thyme_oil",
+ "tramadol",
+ "vaccine_shot",
+- "weak_antibiotic",
+- "cattail_jelly"
++ "vitamins",
++ "weak_antibiotic",
++ "wrapped_rad_badge",
++ "xanax"
+ ],
+ "response": { "text": "Delivering <topic_item>.", "topic": "TALK_DELIVER_ASK" }
+ },
diff --git a/npc-09_broker-takes-more-foods.patch b/npc-09_broker-takes-more-foods.patch
new file mode 100644
index 0000000..14af7c2
--- /dev/null
+++ b/npc-09_broker-takes-more-foods.patch
@@ -0,0 +1,171 @@
+--- a/data/json/npcs/refugee_center/surface_staff/NPC_free_merchant_broker.json
++++ b/data/json/npcs/refugee_center/surface_staff/NPC_free_merchant_broker.json
+@@ -88,20 +88,142 @@
+ "dynamic_line": "Excellent. What've you brought us?",
+ "repeat_responses": {
+ "for_item": [
+- "jerky",
+- "meat_smoked",
+- "fish_smoked",
+- "dry_veggy",
+- "dry_fruit",
++ "acorn_roasted",
++ "almond_roasted",
++ "apple_canned",
++ "apple_sugar",
++ "bacon",
++ "beer",
++ "belgian_ale",
++ "bum_wine",
++ "burdock_wine",
++ "can_beans",
++ "can_chicken",
++ "can_chowder",
++ "can_clams",
++ "can_corn",
++ "can_herring",
++ "can_peach",
++ "can_pineapple",
++ "can_salmon",
++ "can_sardine",
++ "can_spam",
++ "can_tuna",
++ "can_tomato",
++ "cheese_hard",
++ "chestnut_roasted",
++ "con_milk",
++ "cooked_pumpkin",
+ "cooking_oil",
+ "cooking_oil2",
+ "cornmeal",
++ "dandelion_wine",
++ "dried_salad",
++ "drink_kalimotxo",
++ "dry_beans",
++ "dry_fish",
++ "dry_fruit",
++ "dry_meat",
++ "dry_mushroom",
++ "dry_lentils",
++ "dry_rice",
++ "dry_tofu",
++ "dry_veggy",
++ "edamame_roasted",
++ "european_pilsner",
++ "fish_canned",
++ "fish_pickled",
++ "fish_smoked",
+ "flour",
++ "fruit_leather",
+ "fruit_wine",
+- "beer",
+- "sugar",
++ "granola",
++ "hardtack",
++ "hazelnut_roasted",
++ "hb_beer",
++ "hickory_nut_roasted",
++ "imperial_stout",
++ "india_pale_ale",
++ "irradiated_rose_hips",
++ "irradiated_elderberries",
++ "irradiated_mulberries",
++ "irradiated_huckleberries",
++ "irradiated_raspberries",
++ "irradiated_cranberries",
++ "irradiated_strawberries",
++ "irradiated_blueberries",
++ "irradiated_apple",
++ "irradiated_banana",
++ "irradiated_orange",
++ "irradiated_lemon",
++ "irradiated_grapefruit",
++ "irradiated_pear",
++ "irradiated_cherries",
++ "irradiated_plums",
++ "irradiated_grapes",
++ "irradiated_pineapple",
++ "irradiated_peach",
++ "irradiated_watermelon",
++ "irradiated_melon",
++ "irradiated_blackberries",
++ "irradiated_mango",
++ "irradiated_pomegranate",
++ "irradiated_papaya",
++ "irradiated_kiwi",
++ "irradiated_apricot",
++ "irradiated_lettuce",
++ "irradiated_cabbage",
++ "irradiated_tomato",
++ "irradiated_broccoli",
++ "irradiated_zucchini",
++ "irradiated_onion",
++ "irradiated_carrot",
++ "irradiated_corn",
++ "irradiated_pumpkin",
++ "irradiated_potato",
++ "irradiated_cucumber",
++ "irradiated_celery",
++ "irradiated_rhubarb",
++ "jam_fruit",
++ "jerky",
++ "kompot",
++ "mead",
++ "meat_canned",
++ "meat_pickled",
++ "meat_salted",
++ "meat_smoked",
++ "milk_evap",
++ "milk_powder",
++ "milk_UHT",
++ "oatmeal",
++ "pale_ale",
++ "peanutbutter",
++ "pecan_roasted",
++ "pemmican",
++ "pine_wine",
++ "pistachio_roasted",
++ "pork_beans",
++ "potted_meat",
++ "powder_eggs",
++ "ravioli",
++ "drink_rumcola",
+ "salt",
+- "vinegar"
++ "salted_fish",
++ "sauce_red",
++ "sausage",
++ "soup_chicken",
++ "soup_dumplings",
++ "soup_tomato",
++ "soy_nuts",
++ "stout",
++ "sugar",
++ "veggy_canned",
++ "veggy_pickled",
++ "veggy_salted",
++ "vinegar",
++ "walnut_roasted",
++ "wine_barley",
++ "yeast"
+ ],
+ "response": { "text": "Delivering <topic_item>.", "topic": "TALK_DELIVER_ASK" }
+ },
+@@ -141,7 +210,7 @@
+ {
+ "type": "talk_topic",
+ "id": "TALK_FREE_MERCHANT_STOCKS_WHY",
+- "dynamic_line": "All three are easy to locally produce in significant quantities and are non-perishable. We have a local farmer or two and a few hunter types that have been making attempts to provide us with the nutritious supplies. We do always need more suppliers though. This stuff is rather cheap in bulk, so I can pay a premium for any you have on you. Canned food and other edibles are handled by the merchant in the front in trade.",
++ "dynamic_line": "All three are easy to locally produce in significant quantities and are non-perishable. We have a local farmer or two and a few hunter types that have been making attempts to provide us with nutritious supplies. We do always need more suppliers though. This stuff is rather cheap in bulk, so I can pay a premium for any you have on you.",
+ "responses": [
+ { "text": "Are you looking to buy anything else?", "topic": "TALK_FREE_MERCHANT_STOCKS_ALL" },
+ { "text": "Very well… let's talk about something else.", "topic": "TALK_FREE_MERCHANT_STOCKS" }
+@@ -155,7 +224,7 @@
+ {
+ "type": "talk_topic",
+ "id": "TALK_FREE_MERCHANT_STOCKS_ALL",
+- "dynamic_line": "I'm actually accepting a number of different foodstuffs: beer, sugar, flour, smoked meat, smoked fish, dried fruit and vegetables, cooking oil, preservatives like salt and vinegar; and as mentioned before, jerky, cornmeal, and fruit wine."
++ "dynamic_line": "I'm actually accepting a number of different foodstuffs: Basic cooking supplies like flour, sugar, yeast, cooking oils, powdered eggs, powdered milk; Any sort of preserved meat, fish, cheese, fruit, nut, or vegetable; preservation supplies like salt and vinegar; low alcohol content liquors like fruit wine and beer; and of course, any sort of pre-cataclysm factory-sealed foods you can get your hands on."
+ },
+ {
+ "type": "talk_topic",
diff --git a/npc-10_bunker-merchant.patch b/npc-10_bunker-merchant.patch
new file mode 100644
index 0000000..4ec3c31
--- /dev/null
+++ b/npc-10_bunker-merchant.patch
@@ -0,0 +1,396 @@
+--- a/data/json/mapgen/bunker_shop.json
++++ b/data/json/mapgen/bunker_shop.json
+@@ -0,0 +1,180 @@
++[
++ {
++ "type": "mapgen",
++ "method": "json",
++ "om_terrain": [ "bunker_shop_g" ],
++ "object": {
++ "fill_ter": "t_floor",
++ "rows": [
++ "kkkkkkkkkkkkkkkkkkkkkkkk",
++ "kkkkkkkkkkkkkkkkkkkkkkkk",
++ "kkkkkkkkkkkkkkkkkkkkkkkk",
++ "kkaasaaGnnGnnGnnGnnoookk",
++ "kkaEDDakkkkkkkkkkkkoqokk",
++ "GnaEDDakkkkzkkkkkkkopokk",
++ "nkaaCaakkkkkkkkAkkkktnkk",
++ "nkkktttttttttttttttttnkk",
++ "GkkktkkkiicjaraaaajktGkk",
++ "nkkktkkkjkkkwwyakkjktnkk",
++ "nttttttkjkkkww a krktnkk",
++ "Gttttttkakk a jktGkk",
++ "nttttttkaaagaaaaagaagaak",
++ "nttttttka lj akkkak",
++ "Gttttttka ljvv gkk sk",
++ "nttttttbbd i akk ak",
++ "nttttttbedk iia a sk",
++ "Gttttttbbdkk a ak",
++ "nttttttkakkkk iijjak",
++ "nttttttFjkkkkkk jkkkkk",
++ "GBBBBBBGiijrcjgjjijkkkkk",
++ "kttttttFkf kkkkgkkkAkkk",
++ "kttttttkkj kkkjkkkkkkk",
++ "kttttttkkjjrrcrjjkkkkkkk"
++ ],
++ "terrain": {
++ "a": "t_wall_wood",
++ "b": "t_rock",
++ "c": "t_window_empty",
++ "d": "t_rock_floor",
++ "e": "t_rock_floor",
++ "f": "t_door_b",
++ "g": "t_door_frame",
++ "h": "t_door_c",
++ "i": "t_wall_wood_broken",
++ "j": "t_wall_wood_chipped",
++ "k": [ "t_grass", "t_grass", "t_grass", "t_dirt" ],
++ "m": "t_dirt",
++ "n": "t_chainfence_h",
++ "o": "t_concrete_wall",
++ "p": "t_door_metal_c",
++ "q": "t_stairs_down",
++ "r": "t_window_frame",
++ "s": "t_window_boarded",
++ "t": "t_dirt",
++ "l": "t_floor",
++ "u": "t_floor",
++ "v": "t_floor",
++ "w": "t_floor",
++ "x": "t_wall_wood_chipped",
++ "y": "t_floor",
++ "z": "t_tree_plum",
++ "A": "t_tree_apple",
++ "B": "t_door_metal_locked",
++ "C": "t_door_c",
++ "D": "t_dirtfloor",
++ "E": "t_dirtfloor",
++ "F": "t_gates_mech_control",
++ "G": "t_wall"
++ },
++ "furniture": {
++ "e": "f_brazier",
++ "m": "f_rubble",
++ "l": "f_crate_o",
++ "u": "f_woodstove",
++ "v": "f_table",
++ "w": "f_bed",
++ "y": "f_dresser",
++ "E": "f_locker"
++ },
++ "place_loot": [
++ { "group": "floor_trash", "chance": 90, "repeat": 5, "x": [ 9, 12 ], "y": [ 13, 19 ] },
++ { "group": "floor_trash", "chance": 90, "repeat": 5, "x": [ 13, 17 ], "y": [ 17, 19 ] },
++ { "group": "floor_trash", "chance": 90, "repeat": 5, "x": [ 14, 17 ], "y": [ 13, 15 ] },
++ { "group": "floor_trash", "chance": 90, "repeat": 5, "x": [ 9, 14 ], "y": [ 9, 11 ] },
++ { "group": "floor_trash", "chance": 90, "repeat": 5, "x": [ 19, 21 ], "y": [ 13, 17 ] },
++ { "group": "floor_trash", "chance": 90, "repeat": 5, "x": [ 10, 15 ], "y": [ 21, 22 ] },
++ { "group": "floor_trash", "chance": 90, "repeat": 3, "x": [ 16, 17 ], "y": [ 9, 11 ] }
++ ]
++ }
++ },
++ {
++ "type": "mapgen",
++ "method": "json",
++ "om_terrain": [ "bunker_shop_b" ],
++ "object": {
++ "fill_ter": "t_rock",
++ "rows": [
++ " fff ",
++ " fvffffff ",
++ " fbbbbbbf ",
++ " fbffffbf ",
++ " fffff fbf faf ",
++ " fftsrf fbf fff ",
++ " fvbbbf fbf ",
++ " ffffffdfffdfffff ",
++ " fnccmfbfjubbxfvf ",
++ " fllccbbdbbbbbebf ",
++ " fvccofjfbbbbbfbf ",
++ " fffffffffgggffbf ",
++ " fjhhhbfbf ",
++ " fffffffffbbpbbdbf ",
++ " fviiiiivfibbbbfff ",
++ " fffbbbbbbbfibvbwf ",
++ " fkdbiiiiibdbbbbhf ",
++ " fffbbbbbbbfiqqbhf ",
++ " fviiiiivffffdff ",
++ " ffffffffffnlcmf ",
++ " fvbbbdclcmf ",
++ " fftsrfcccvf ",
++ " ffffffffff ",
++ " "
++ ],
++ "terrain": {
++ "a": "t_stairs_up",
++ "b": "t_thconc_floor",
++ "c": "t_floor",
++ "d": "t_door_metal_c",
++ "e": "t_door_metal_locked",
++ "f": "t_concrete_wall",
++ "g": "t_reinforced_glass",
++ "h": "t_thconc_floor",
++ "i": "t_thconc_floor",
++ "j": "t_thconc_floor",
++ "k": "t_plut_generator",
++ "l": "t_floor",
++ "m": "t_floor",
++ "n": "t_floor",
++ "o": "t_floor",
++ "p": "t_thconc_floor",
++ "q": "t_thconc_floor",
++ "r": "t_thconc_floor",
++ "s": "t_thconc_floor",
++ "t": "t_thconc_floor",
++ "u": "t_thconc_floor",
++ "v": "t_utility_light",
++ "w": "t_console_broken",
++ "x": "t_atm"
++ },
++ "furniture": {
++ "h": "f_table",
++ "i": "f_rack",
++ "j": "f_locker",
++ "l": "f_bed",
++ "m": "f_dresser",
++ "n": "f_table",
++ "o": "f_sofa",
++ "p": "f_chair",
++ "q": "f_sofa",
++ "r": "f_toilet",
++ "s": "f_sink",
++ "t": "f_shower",
++ "u": "f_crate_o"
++ },
++ "place_loot": [
++ { "group": "mil_food_nodrugs", "chance": 90, "repeat": [ 10 ], "x": [ 6, 10 ], "y": [ 18, 18 ] },
++ { "group": "ammo_rifle_milspec", "chance": 90, "repeat": [ 10 ], "x": [ 6, 10 ], "y": [ 16, 16 ] },
++ { "group": "camping", "chance": 90, "repeat": [ 10 ], "x": [ 6, 10 ], "y": [ 14, 14 ] },
++ { "group": "allclothes", "chance": 90, "repeat": [ 4 ], "x": [ 17, 17 ], "y": [ 19, 20 ] },
++ { "group": "allclothes", "chance": 90, "repeat": [ 4 ], "x": [ 9, 9 ], "y": [ 8, 8 ] },
++ { "group": "book_military", "chance": 90, "repeat": [ 1 ], "x": [ 6, 6 ], "y": [ 8, 8 ] },
++ { "group": "book_military", "chance": 90, "repeat": [ 1 ], "x": [ 14, 14 ], "y": [ 12, 12 ] },
++ { "group": "cleaning_bulk", "chance": 90, "repeat": [ 2 ], "x": [ 11, 11 ], "y": [ 10, 10 ] },
++ { "group": "cleaning_bulk", "chance": 90, "repeat": [ 2 ], "x": [ 13, 13 ], "y": [ 12, 12 ] },
++ { "group": "guns_milspec", "chance": 90, "repeat": [ 2 ], "x": [ 13, 13 ], "y": [ 14, 15 ] },
++ { "group": "mil_food_nodrugs", "chance": 90, "repeat": [ 5 ], "x": [ 13, 13 ], "y": [ 17, 17 ] },
++ { "group": "mil_armor", "chance": 90, "repeat": [ 5 ], "x": [ 17, 17 ], "y": [ 15, 17 ] }
++ ],
++ "place_npcs": [ { "class": "bunker_merchant", "x": 15, "y": 13 } ]
++ }
++ }
++]
+--- a/data/json/npcs/bunker_shop/NC_BUNKER_MERCHANT.json
++++ b/data/json/npcs/bunker_shop/NC_BUNKER_MERCHANT.json
+@@ -0,0 +1,72 @@
++[
++ {
++ "type": "item_group",
++ "id": "NC_BUNKER_MERCHANT_pants_male",
++ "items": [ [ "pants_cargo", 60 ], [ "pants", 20 ], [ "shorts_cargo", 20 ] ]
++ },
++ {
++ "type": "item_group",
++ "id": "NC_BUNKER_MERCHANT_pants_female",
++ "items": [ [ "pants_cargo", 60 ], [ "pants", 20 ], [ "shorts_cargo", 20 ] ]
++ },
++ {
++ "type": "item_group",
++ "id": "NC_BUNKER_MERCHANT_shoes",
++ "items": [ [ "boots_combat", 90 ], [ "boots", 10 ] ]
++ },
++ {
++ "type": "item_group",
++ "id": "NC_BUNKER_MERCHANT_shirt_male",
++ "items": [ [ "undershirt", 30 ], [ "sweatshirt", 20 ], [ "under_armor", 20 ], [ "longshirt", 20 ] ]
++ },
++ {
++ "type": "item_group",
++ "id": "NC_BUNKER_MERCHANT_shirt_female",
++ "items": [ [ "undershirt", 30 ], [ "sweatshirt", 20 ], [ "under_armor", 20 ], [ "longshirt", 20 ] ]
++ },
++ {
++ "type": "item_group",
++ "id": "NC_BUNKER_MERCHANT_gloves",
++ "items": [ [ "null", 20 ], [ "gloves_tactical", 60 ], [ "gloves_fingerless", 20 ] ]
++ },
++ {
++ "type": "item_group",
++ "id": "NC_BUNKER_MERCHANT_coat",
++ "items": [ [ "hoodie", 50 ], [ "kevlar", 50 ] ]
++ },
++ {
++ "type": "item_group",
++ "id": "NC_BUNKER_MERCHANT_extra",
++ "items": [ [ "rucksack", 100 ] ]
++ },
++ {
++ "type": "item_group",
++ "id": "NC_BUNKER_MERCHANT_hat",
++ "items": [ [ "hat_ball", 100 ] ]
++ },
++ {
++ "type": "item_group",
++ "id": "NC_BUNKER_MERCHANT_eyes",
++ "items": [ [ "null", 80 ], [ "glasses_bal", 20 ] ]
++ },
++ {
++ "type": "item_group",
++ "id": "NC_BUNKER_MERCHANT_masks",
++ "items": [ [ "scarf", 100 ] ]
++ },
++ {
++ "type": "item_group",
++ "id": "NC_BUNKER_MERCHANT_misc",
++ "items": [
++ { "group": "ammo_reloaded", "prob": 100, "count-min": 5, "count-max": 10 },
++ { "group": "everyday_gear", "prob": 100, "count-min": 5, "count-max": 25 },
++ { "group": "guns_survival", "prob": 100, "count-min": 5, "count-max": 5 },
++ { "group": "tools_survival", "prob": 100, "count-min": 5, "count-max": 5 },
++ { "group": "supplies_electronics", "prob": 100, "count-min": 5, "count-max": 5 },
++ { "group": "clothing_outdoor_torso", "prob": 100, "count-min": 5, "count-max": 5 },
++ { "group": "clothing_outdoor_pants", "prob": 100, "count-min": 5, "count-max": 5 },
++ { "group": "clothing_outdoor_shoes", "prob": 100, "count-min": 5, "count-max": 5 },
++ { "group": "drugs_soldier", "prob": 100, "count-min": 5, "count-max": 5 }
++ ]
++ }
++]
+--- a/data/json/npcs/bunker_shop/TALK_BUNKER_MERCHANT.json
++++ b/data/json/npcs/bunker_shop/TALK_BUNKER_MERCHANT.json
+@@ -0,0 +1,46 @@
++[
++ {
++ "type": "talk_topic",
++ "id": "TALK_BUNKER_MERCHANT",
++ "dynamic_line": "Heya, scav.",
++ "responses": [
++ { "text": "Did you build this place?", "topic": "TALK_BUNKER_MERCHANT_HERE" },
++ { "text": "Who are you?", "topic": "TALK_BUNKER_MERCHANT_WHO" },
++ { "text": "Why do you still use cash?", "topic": "TALK_BUNKER_MERCHANT_WHY" },
++ { "text": "You're a trader?", "topic": "TALK_BUNKER_MERCHANT_TRADE" },
++ { "text": "I need some supplies.", "effect": "start_trade", "topic": "TALK_BUNKER_MERCHANT" },
++ { "text": "Need help with anything?", "topic": "TALK_BUNKER_MERCHANT_MISSION" },
++ { "text": "Well, bye.", "topic": "TALK_DONE" }
++ ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_BUNKER_MERCHANT_HERE",
++ "dynamic_line": "No, no… well, maybe a little. It was just as wrecked down here as it is up top when I found it, wasn't too hard to fix up. You're welcome to stay in the spare room awhile, just don't hog it. You're not the only scav out there.",
++ "responses": [ { "text": "Interesting…", "topic": "TALK_BUNKER_MERCHANT" } ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_BUNKER_MERCHANT_WHO",
++ "dynamic_line": "Just a scav who got lucky. Now I'm content to sit around here on my pile of treasure. I'm more than willing to trade if you've got the cash.",
++ "responses": [ { "text": "I see…", "topic": "TALK_BUNKER_MERCHANT" } ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_BUNKER_MERCHANT_WHY",
++ "dynamic_line": "Why not? Everyone else does, so I suppose that's all that matters. My ATM over there still works, connected to the bank servers and everything.",
++ "responses": [ { "text": "Hmm…", "topic": "TALK_BUNKER_MERCHANT" } ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_BUNKER_MERCHANT_TRADE",
++ "dynamic_line": "I suppose I am. Scavs like you need supplies, right? And I could always use more money.",
++ "responses": [ { "text": "Alright…", "topic": "TALK_BUNKER_MERCHANT" } ]
++ },
++ {
++ "type": "talk_topic",
++ "id": "TALK_BUNKER_MERCHANT_MISSION",
++ "dynamic_line": "Not at the moment, check back later perhaps.",
++ "responses": [ { "text": "Sure…", "topic": "TALK_BUNKER_MERCHANT" } ]
++ }
++]
+--- a/data/json/npcs/bunker_shop/classes.json
++++ b/data/json/npcs/bunker_shop/classes.json
+@@ -0,0 +1,21 @@
++[
++ {
++ "type": "npc_class",
++ "id": "NC_BUNKER_MERCHANT",
++ "name": "Merchant",
++ "common": false,
++ "job_description": "",
++ "bonus_str": { "rng": [ -1, 2 ] },
++ "bonus_dex": { "rng": [ -1, 1 ] },
++ "bonus_int": { "rng": [ -1, 4 ] },
++ "bonus_per": { "rng": [ -1, 2 ] },
++ "skills": [
++ { "skill": "ALL", "level": { "mul": [ { "one_in": 3 }, { "sum": [ { "dice": [ 2, 2 ] }, { "constant": 0 } ] } ] } },
++ { "skill": "gun", "bonus": { "rng": [ 1, 5 ] } },
++ { "skill": "rifle", "bonus": { "rng": [ 1, 5 ] } },
++ { "skill": "pistol", "bonus": { "rng": [ 1, 4 ] } },
++ { "skill": "smg", "bonus": { "rng": [ 1, 3 ] } },
++ { "skill": "speech", "bonus": { "rng": [ 1, 6 ] } }
++ ]
++ }
++]
+--- a/data/json/npcs/bunker_shop/npc.json
++++ b/data/json/npcs/bunker_shop/npc.json
+@@ -0,0 +1,12 @@
++[
++ {
++ "type": "npc",
++ "id": "bunker_merchant",
++ "name_suffix": "Merchant",
++ "class": "NC_BUNKER_MERCHANT",
++ "attitude": 0,
++ "mission": 3,
++ "chat": "TALK_BUNKER_MERCHANT",
++ "faction": "no_faction"
++ }
++]
+--- a/data/json/overmap/overmap_special/specials.json
++++ b/data/json/overmap/overmap_special/specials.json
+@@ -7151,5 +7151,19 @@
+ "city_sizes": [ 4, -1 ],
+ "occurrences": [ 0, 2 ],
+ "flags": [ "CLASSIC", "WILDERNESS", "ELECTRIC_GRID" ]
++ },
++ {
++ "type": "overmap_special",
++ "id": "bunker shop",
++ "overmaps": [
++ { "point": [ 0, 0, 0 ], "overmap": "bunker_shop_g_south" },
++ { "point": [ 0, 0, -1 ], "overmap": "bunker_shop_b_south" }
++ ],
++ "connections": [ { "point": [ 0, -1, 0 ], "existing": true, "connection": "local_road", "from": [ 0, 0, 0 ] } ],
++ "locations": [ "wilderness" ],
++ "city_distance": [ 10, -1 ],
++ "city_sizes": [ 1, 12 ],
++ "occurrences": [ 5, 100 ],
++ "flags": [ "CLASSIC", "UNIQUE", "WILDERNESS", "ELECTRIC_GRID" ]
+ }
+ ]
+--- a/data/json/overmap/overmap_terrain/overmap_terrain_residential.json
++++ b/data/json/overmap/overmap_terrain/overmap_terrain_residential.json
+@@ -491,5 +491,25 @@
+ "name": "derelict property",
+ "sym": "X",
+ "color": "i_brown"
++ },
++ {
++ "type": "overmap_terrain",
++ "id": "bunker_shop_g",
++ "name": "derelict property",
++ "sym": "X",
++ "color": "i_brown",
++ "see_cost": 5,
++ "extras": "build",
++ "mondensity": 2
++ },
++ {
++ "type": "overmap_terrain",
++ "id": "bunker_shop_b",
++ "name": "scavenger bunker",
++ "sym": "B",
++ "color": "light_green",
++ "see_cost": 5,
++ "extras": "build",
++ "mondensity": 2
+ }
+ ]
diff --git a/npc-11_npcs-reload-gas-mask.patch b/npc-11_npcs-reload-gas-mask.patch
new file mode 100644
index 0000000..e56b214
--- /dev/null
+++ b/npc-11_npcs-reload-gas-mask.patch
@@ -0,0 +1,82 @@
+--- a/data/json/items/tool_armor.json
++++ b/data/json/items/tool_armor.json
+@@ -1109,7 +1109,8 @@
+ "max_charges": 100,
+ "initial_charges": 100,
+ "ammo": "gasfilter_s",
+- "use_action": "GASMASK"
++ "use_action": "GASMASK",
++ "charges_per_use": 1
+ },
+ {
+ "id": "mask_gas",
+@@ -1136,7 +1137,8 @@
+ "max_charges": 100,
+ "initial_charges": 100,
+ "ammo": "gasfilter_m",
+- "use_action": "GASMASK"
++ "use_action": "GASMASK",
++ "charges_per_use": 1
+ },
+ {
+ "id": "mask_gas_xl",
+@@ -1163,7 +1165,8 @@
+ "initial_charges": 100,
+ "ammo": "gasfilter_m",
+ "use_action": "GASMASK",
+- "flags": [ "OVERSIZE", "SLEEP_IGNORE" ]
++ "flags": [ "OVERSIZE", "SLEEP_IGNORE" ],
++ "charges_per_use": 1
+ },
+ {
+ "id": "mask_fsurvivor",
+@@ -1191,7 +1194,8 @@
+ "initial_charges": 100,
+ "ammo": "gasfilter_m",
+ "use_action": "GASMASK",
+- "flags": [ "VARSIZE", "STURDY", "SUN_GLASSES", "SLEEP_IGNORE" ]
++ "flags": [ "VARSIZE", "STURDY", "SUN_GLASSES", "SLEEP_IGNORE" ],
++ "charges_per_use": 1
+ },
+ {
+ "id": "mask_bunker",
+@@ -1248,7 +1253,8 @@
+ "encumbrance": 20,
+ "coverage": 100,
+ "qualities": [ [ "GLARE", 2 ] ],
+- "material_thickness": 3
++ "material_thickness": 3,
++ "charges_per_use": 1
+ },
+ {
+ "id": "mask_hsurvivor",
+@@ -1276,7 +1282,8 @@
+ "environmental_protection": 1,
+ "environmental_protection_with_filter": 15,
+ "qualities": [ [ "GLARE", 1 ] ],
+- "flags": [ "VARSIZE", "STURDY", "SUN_GLASSES", "SLEEP_IGNORE" ]
++ "flags": [ "VARSIZE", "STURDY", "SUN_GLASSES", "SLEEP_IGNORE" ],
++ "charges_per_use": 1
+ },
+ {
+ "id": "mask_lsurvivor",
+@@ -1333,7 +1340,8 @@
+ "environmental_protection": 1,
+ "environmental_protection_with_filter": 15,
+ "qualities": [ [ "GLARE", 1 ] ],
+- "flags": [ "VARSIZE", "STURDY", "SUN_GLASSES", "SLEEP_IGNORE" ]
++ "flags": [ "VARSIZE", "STURDY", "SUN_GLASSES", "SLEEP_IGNORE" ],
++ "charges_per_use": 1
+ },
+ {
+ "id": "mask_wsurvivor",
+@@ -1389,7 +1398,8 @@
+ "environmental_protection": 1,
+ "environmental_protection_with_filter": 15,
+ "qualities": [ [ "GLARE", 1 ] ],
+- "flags": [ "VARSIZE", "STURDY", "SUN_GLASSES", "SLEEP_IGNORE" ]
++ "flags": [ "VARSIZE", "STURDY", "SUN_GLASSES", "SLEEP_IGNORE" ],
++ "charges_per_use": 1
+ },
+ {
+ "id": "goggles_nv",
diff --git a/npc-12_fix-eddie-requiring-1000-clay.patch b/npc-12_fix-eddie-requiring-1000-clay.patch
new file mode 100644
index 0000000..8ed1383
--- /dev/null
+++ b/npc-12_fix-eddie-requiring-1000-clay.patch
@@ -0,0 +1,26 @@
+--- a/data/json/npcs/isherwood_farm/NPC_Eddie_Isherwood.json
++++ b/data/json/npcs/isherwood_farm/NPC_Eddie_Isherwood.json
+@@ -264,12 +264,12 @@
+ {
+ "id": "MISSION_ISHERWOOD_EDDIE_3",
+ "type": "mission_definition",
+- "name": { "str": "Gather 1000 units of clay" },
++ "name": { "str": "Gather 100 units of clay" },
+ "goal": "MGOAL_FIND_ITEM",
+ "difficulty": 3,
+ "value": 20000,
+ "item": "clay_lump",
+- "count": 1000,
++ "count": 100,
+ "end": {
+ "opinion": { "trust": 2, "value": 2 },
+ "effect": [
+@@ -283,7 +283,7 @@
+ "has_generic_rewards": false,
+ "dialogue": {
+ "describe": "I do have some resource gathering I could use help if you have time.",
+- "offer": "Now that the clay kiln is set up, we could use 1000 units of clay to get production going.",
++ "offer": "Now that the clay kiln is set up, we could use 100 units of clay to get production going.",
+ "accepted": "Thank you.",
+ "rejected": "Oh well. I'll try to find time to get it myself, thanks.",
+ "advice": "You can find it along river banks, or maybe look for deposits in the forest.",
diff --git a/npc-20_dialogue-fixes.patch b/npc-20_dialogue-fixes.patch
new file mode 100644
index 0000000..d5bd3cc
--- /dev/null
+++ b/npc-20_dialogue-fixes.patch
@@ -0,0 +1,44 @@
+--- a/data/json/npcs/isherwood_farm/NPC_Lisa_Isherwood.json
++++ b/data/json/npcs/isherwood_farm/NPC_Lisa_Isherwood.json
+@@ -84,7 +84,7 @@
+ {
+ "type": "talk_topic",
+ "id": "TALK_ISHERWOOD_LISA_TALK1",
+- "dynamic_line": "My family owns all the land around here, my parents are out in the barn and my other family is down he road.",
++ "dynamic_line": "My family owns all the land around here, my parents are out in the barn and my other family is down the road.",
+ "responses": [
+ { "text": "Ok, I'll go find them.", "topic": "TALK_DONE" },
+ { "text": "Let's talk about something else.", "topic": "TALK_ISHERWOOD_LISA_TOPICS" },
+
+--- a/data/json/npcs/isherwood_farm/NPC_Jack_Isherwood.json
++++ b/data/json/npcs/isherwood_farm/NPC_Jack_Isherwood.json
+@@ -179,7 +179,7 @@
+ {
+ "type": "talk_topic",
+ "id": "TALK_ISHERWOOD_JACK_TALK1",
+- "dynamic_line": "I live here with my wife, this is our family's land. My daughter's family and son live down the road.",
++ "dynamic_line": "I live here with my wife, this is our family's land. My daughter's family live down the road, and my brother-in-law with his son just past them.",
+ "responses": [
+ { "text": "Your whole family survived?", "topic": "TALK_ISHERWOOD_JACK2" },
+ { "text": "Let's talk about something else.", "topic": "TALK_ISHERWOOD_JACK_TOPICS" },
+@@ -306,7 +306,7 @@
+ {
+ "id": "MISSION_ISHERWOOD_JACK_1",
+ "type": "mission_definition",
+- "name": { "str": "Find 10 3L jars" },
++ "name": { "str": "Find 20 3L jars" },
+ "goal": "MGOAL_FIND_ITEM",
+ "difficulty": 3,
+ "value": 20000,
+
+--- a/data/json/npcs/refugee_center/surface_refugees/NPC_Boris_Borichenko.json
++++ b/data/json/npcs/refugee_center/surface_refugees/NPC_Boris_Borichenko.json
+@@ -406,7 +406,7 @@
+ {
+ "id": "MISSION_REFUGEE_Boris_LAPTOP",
+ "type": "mission_definition",
+- "name": { "str": "Bring Boris his son's lost writing." },
++ "name": { "str": "Bring Boris his son's lost laptop." },
+ "difficulty": 1,
+ "value": 0,
+ "goal": "MGOAL_FIND_ITEM",
diff --git a/0010-4570-dragon-can-be-dismantled.patch b/recipes-01_4570-dragon-can-be-dismantled.patch
index 2db6e2a..03e25df 100644
--- a/0010-4570-dragon-can-be-dismantled.patch
+++ b/recipes-01_4570-dragon-can-be-dismantled.patch
@@ -1,6 +1,6 @@
--- a/data/json/recipes/ammo/rifle.json
+++ b/data/json/recipes/ammo/rifle.json
-@@ -385,6 +385,7 @@
+@@ -355,6 +355,7 @@
"batch_time_factors": [ 60, 5 ],
"book_learn": [ [ "recipe_bullets", 2 ], [ "mag_rifle", 4 ] ],
"charges": 1,
@@ -8,29 +8,21 @@
"using": [ [ "bullet_forming", 15 ], [ "ammo_bullet", 8 ] ],
"components": [
[ [ "4570_casing", 1 ] ],
-@@ -406,6 +407,7 @@
+@@ -376,6 +377,7 @@
"batch_time_factors": [ 60, 5 ],
"book_learn": [ [ "recipe_bullets", 2 ], [ "mag_rifle", 4 ] ],
"charges": 1,
+ "reversible": true,
"using": [ [ "bullet_forming", 15 ], [ "ammo_bullet", 8 ] ],
- "components": [
- [ [ "4570_casing", 1 ] ],
-@@ -426,6 +428,7 @@
- "batch_time_factors": [ 60, 5 ],
- "book_learn": [ [ "recipe_bullets", 2 ], [ "mag_rifle", 4 ] ],
- "charges": 1,
-+ "reversible": true,
- "using": [ [ "bullet_forming", 15 ], [ "ammo_bullet", 8 ] ],
- "components": [
- [ [ "4570_casing", 1 ] ],
-@@ -446,6 +449,7 @@
+ "components": [ [ [ "4570_casing", 1 ] ], [ [ "lgrifle_primer", 1 ] ], [ [ "gunpowder", 17 ] ], [ [ "copper", 7 ] ] ]
+ },
+@@ -356,6 +358,7 @@
"batch_time_factors": [ 60, 5 ],
"book_learn": [ [ "recipe_bullets", 2 ], [ "mag_rifle", 4 ] ],
"charges": 1,
+ "reversible": true,
"using": [ [ "bullet_forming", 15 ], [ "ammo_bullet", 8 ] ],
- "components": [ [ [ "4570_casing", 1 ] ], [ [ "lgrifle_primer", 1 ] ], [ [ "chem_black_powder", 12 ] ], [ [ "lead", 9 ] ] ]
+ "components": [ [ [ "4570_casing", 1 ] ], [ [ "lgrifle_primer", 1 ] ], [ [ "gunpowder", 12 ] ] ]
},
--- a/data/json/recipes/ammo/shot.json
+++ b/data/json/recipes/ammo/shot.json
@@ -40,5 +32,5 @@
"charges": 1,
+ "reversible": true,
"using": [ [ "ammo_shot", 1 ] ],
- "tools": [ [ [ "press", -1 ] ] ],
- "components": [ [ [ "gunpowder", 3 ], [ "gunpowder_pistol", 3 ], [ "gunpowder_shotgun", 3 ] ], [ [ "magnesium", 5 ] ] ]
+ "tools": [ [ [ "press", -1 ], [ "press_dowel", -1 ] ] ],
+ "components": [ [ [ "gunpowder", 3 ] ], [ [ "magnesium", 5 ] ] ]
diff --git a/recipes-02_recon-mech-laser-typo.patch b/recipes-02_recon-mech-laser-typo.patch
new file mode 100644
index 0000000..98bcf87
--- /dev/null
+++ b/recipes-02_recon-mech-laser-typo.patch
@@ -0,0 +1,20 @@
+--- a/data/json/recipes/weapon/ranged.json
++++ b/data/json/recipes/weapon/ranged.json
+@@ -754,7 +754,7 @@
+ },
+ {
+ "type": "recipe",
+- "result": "gatling_mech_laser_rebuilt",
++ "result": "recon_mech_laser_rebuilt",
+ "category": "CC_WEAPON",
+ "subcategory": "CSC_WEAPON_RANGED",
+ "skill_used": "electronics",
+@@ -764,7 +764,7 @@
+ "autolearn": true,
+ "using": [ [ "welding_standard", 5 ], [ "steel_tiny", 2 ] ],
+ "qualities": [ { "id": "SAW_M_FINE", "level": 1 }, { "id": "SCREW_FINE", "level": 1 } ],
+- "components": [ [ [ "gatling_mech_laser_salvaged", 1 ] ], [ [ "battery_ups", 1 ] ], [ [ "cable", 25 ] ] ]
++ "components": [ [ [ "recon_mech_laser_salvaged", 1 ] ], [ [ "battery_ups", 1 ] ], [ [ "cable", 25 ] ] ]
+ },
+ {
+ "type": "recipe",
diff --git a/revert-01_removed-traits.patch b/revert-01_removed-traits.patch
new file mode 100644
index 0000000..9b98d83
--- /dev/null
+++ b/revert-01_removed-traits.patch
@@ -0,0 +1,149 @@
+--- a/data/json/mutations/mutations.json
++++ b/data/json/mutations/mutations.json
+@@ -2538,10 +2538,11 @@
+ {
+ "type": "mutation",
+ "id": "INFRESIST",
+- "name": { "str": "Infection Immune" },
+- "points": 1,
+- "description": "Your immune system is particularly good at resisting infections. Your wounds will no longer become infected, altough existing infections are still dangerous. You will also be able to install non-sterile CBMs.",
++ "name": { "str": "Infection Resistant" },
++ "points": 2,
++ "description": "Your immune system is particularly good at resisting infections. You have an increased chance for bad wounds and infections to heal on their own, and only suffer reduced penalties from them.",
+ "starting_trait": true,
++ "changes_to": [ "INFIMMUNE" ],
+ "category": [ "TROGLOBITE", "RAT", "MEDICAL" ]
+ },
+ {
+
+--- a/data/json/obsoletion/mutations.json
++++ b/data/json/obsoletion/mutations.json
+@@ -109,7 +109,7 @@
+ "id": "INFIMMUNE",
+ "name": { "str": "Infection Immune" },
+ "points": 3,
+- "description": "Your bloodstream has developed antibiotic properties. Your wounds will never become infected.",
++ "description": "Your bloodstream has developed antibiotic properties. Your wounds will never become infected. You will also be able to install non-sterile CBMs.",
+ "prereqs": [ "DISRESISTANT" ],
+ "prereqs2": [ "INFRESIST" ],
+ "valid": false
+
+--- a/data/json/scenarios.json
++++ b/data/json/scenarios.json
+@@ -319,7 +319,7 @@
+ "allowed_locs": [ "sloc_hospital" ],
+ "start_name": "Hospital",
+ "forced_traits": [ "FLIMSY2" ],
+- "forbidden_traits": [ "TOUGH" ],
++ "forbidden_traits": [ "TOUGH", "DISRESISTANT" ],
+ "professions": [ "unemployed", "bionic_patient", "patient", "broken_cyborg", "senior" ],
+ "flags": [ "CHALLENGE", "CITY_START", "LONE_START" ]
+ },
+
+--- a/data/json/npcs/starting_traits.json
++++ b/data/json/npcs/starting_traits.json
+@@ -34,6 +34,7 @@
+ { "group": "trait_group_PAINRESIST", "prob": 10 },
+ { "group": "trait_group_PROJUNK", "prob": 5 },
+ { "trait": "DEFT", "prob": 10 },
++ { "trait": "DISRESISTANT", "prob": 10 },
+ { "trait": "ADRENALINE", "prob": 10 },
+ { "trait": "INFRESIST", "prob": 15 },
+ { "trait": "MASOCHIST", "prob": 10 },
+@@ -200,7 +201,7 @@
+ "id": "trait_group_LIAR",
+ "subtype": "distribution",
+ "//": "NOTE: These traits should be used as conditionals to affect the difficulty of NPCs lying about the expertise they have.",
+- "traits": [ { "trait": "LIAR" } ]
++ "traits": [ { "trait": "LIAR" }, { "trait": "TRUTHTELLER" } ]
+ },
+ {
+ "type": "trait_group",
+
+--- a/src/character_turn.cpp
++++ b/src/character_turn.cpp
+@@ -42,6 +42,7 @@
+ static const trait_id trait_FAT( "FAT" );
+ static const trait_id trait_FELINE_FUR( "FELINE_FUR" );
+ static const trait_id trait_FUR( "FUR" );
++static const trait_id trait_INFIMMUNE( "INFIMMUNE" );
+ static const trait_id trait_INSECT_ARMS_OK( "INSECT_ARMS_OK" );
+ static const trait_id trait_INSECT_ARMS( "INSECT_ARMS" );
+ static const trait_id trait_LIGHTFUR( "LIGHTFUR" );
+@@ -60,6 +61,7 @@
+ static const trait_id trait_WHISKERS_RAT( "WHISKERS_RAT" );
+ static const trait_id trait_WHISKERS( "WHISKERS" );
+
++static const efftype_id effect_bite( "bite" );
+ static const efftype_id effect_bloodworms( "bloodworms" );
+ static const efftype_id effect_brainworms( "brainworms" );
+ static const efftype_id effect_darkness( "darkness" );
+@@ -69,11 +71,13 @@
+ static const efftype_id effect_fungus( "fungus" );
+ static const efftype_id effect_happy( "happy" );
+ static const efftype_id effect_irradiated( "irradiated" );
++static const efftype_id effect_infected( "infected" );
+ static const efftype_id effect_masked_scent( "masked_scent" );
+ static const efftype_id effect_narcosis( "narcosis" );
+ static const efftype_id effect_onfire( "onfire" );
+ static const efftype_id effect_paincysts( "paincysts" );
+ static const efftype_id effect_pkill( "pkill" );
++static const efftype_id effect_recover( "recover" );
+ static const efftype_id effect_sad( "sad" );
+ static const efftype_id effect_sleep_deprived( "sleep_deprived" );
+ static const efftype_id effect_sleep( "sleep" );
+@@ -566,6 +570,12 @@
+ remove_effect( effect_tapeworm );
+ add_msg_if_player( m_good, _( "Your bowels gurgle as something inside them dies." ) );
+ }
++ if( has_trait( trait_INFIMMUNE ) && ( has_effect( effect_bite ) || has_effect( effect_infected ) ||
++ has_effect( effect_recover ) ) ) {
++ remove_effect( effect_bite );
++ remove_effect( effect_infected );
++ remove_effect( effect_recover );
++ }
+
+ //Human only effects
+ for( auto &elem : *effects ) {
+
+--- a/src/game_inventory.cpp
++++ b/src/game_inventory.cpp
+@@ -79,7 +79,7 @@
+ static const trait_id trait_NOPAIN( "NOPAIN" );
+ static const trait_id trait_SAPROPHAGE( "SAPROPHAGE" );
+ static const trait_id trait_SAPROVORE( "SAPROVORE" );
+-static const trait_id trait_INFRESIST( "INFRESIST" );
++static const trait_id trait_INFIMMUNE( "INFIMMUNE" );
+
+ static const std::string flag_ALLOWS_REMOTE_USE( "ALLOWS_REMOTE_USE" );
+ static const std::string flag_FILTHY( "FILTHY" );
+@@ -1879,7 +1879,7 @@
+ const itype *itemtype = it->type;
+ const bionic_id &bid = itemtype->bionic->id;
+
+- if( it->has_fault( fault_bionic_nonsterile ) && !p.has_trait( trait_INFRESIST ) ) {
++ if( it->has_fault( fault_bionic_nonsterile ) && !p.has_trait( trait_INFIMMUNE ) ) {
+ // NOLINTNEXTLINE(cata-text-style): single space after the period for symmetry
+ return _( "/!\\ CBM is not sterile. /!\\ Please use autoclave or other methods to sterilize." );
+ } else if( pa.has_bionic( bid ) ) {
+
+--- a/src/iuse_actor.cpp
++++ b/src/iuse_actor.cpp
+@@ -131,7 +131,7 @@
+ static const trait_id trait_CENOBITE( "CENOBITE" );
+ static const trait_id trait_DEBUG_BIONICS( "DEBUG_BIONICS" );
+ static const trait_id trait_TOLERANCE( "TOLERANCE" );
+-static const trait_id trait_INFRESIST( "INFRESIST" );
++static const trait_id trait_INFIMMUNE( "INFIMMUNE" );
+ static const trait_id trait_LIGHTWEIGHT( "LIGHTWEIGHT" );
+ static const trait_id trait_PACIFIST( "PACIFIST" );
+ static const trait_id trait_PSYCHOPATH( "PSYCHOPATH" );
+@@ -4419,7 +4419,7 @@
+ !p.has_trait( trait_DEBUG_BIONICS ) ) {
+ return ret_val<bool>::make_failure( _( "You can't self-install bionics." ) );
+ } else if( !p.has_trait( trait_DEBUG_BIONICS ) ) {
+- if( it.has_fault( fault_bionic_nonsterile ) && !p.has_trait( trait_INFRESIST ) ) {
++ if( it.has_fault( fault_bionic_nonsterile ) && !p.has_trait( trait_INFIMMUNE ) ) {
+ return ret_val<bool>::make_failure( _( "This CBM is not sterile, you can't install it." ) );
+ } else if( units::energy_max - p.get_max_power_level() < bid->capacity ) {
+ return ret_val<bool>::make_failure( _( "Max power capacity already reached" ) );
diff --git a/revert-02_revert-book-revamp.patch b/revert-02_revert-book-revamp.patch
new file mode 100644
index 0000000..8822d85
--- /dev/null
+++ b/revert-02_revert-book-revamp.patch
@@ -0,0 +1,1357 @@
+--- a/data/json/items/book/misc.json
++++ b/data/json/items/book/misc.json
+@@ -4,46 +4,36 @@
+ "type": "BOOK",
+ "name": { "str": "paperback abstract" },
+ "description": "An ordinary paperback book. Or is it? It is.",
+- "weight": "400 g",
+- "volume": "750 ml",
++ "weight": "371 g",
++ "volume": "700 ml",
+ "price": "750 cent",
+ "price_postapoc": "50 cent",
+ "material": [ "paper" ],
+- "bashing": 5,
+- "intelligence": 6,
+ "symbol": "?",
+ "looks_like": "story_book",
+ "color": "light_cyan",
+ "flags": [ "TINDER", "FLAMMABLE" ],
+- "time": "40 m",
+- "fun": 2
+- },
+- {
+- "id": "mag_comic",
+- "type": "BOOK",
+- "name": { "str": "comic book" },
+- "description": "A super-hero comic.",
+- "copy-from": "paperback_novel",
+- "weight": "60 g",
+- "volume": "200 ml",
+- "price": "3 USD",
+- "bashing": 1,
+ "intelligence": 4,
+ "time": "15 m",
+- "fun": 1
++ "chapters": 16,
++ "fun": 2
+ },
+ {
+- "id": "holybook_bible1",
++ "id": "ZSG",
+ "type": "BOOK",
+- "name": { "str": "King James Bible", "str_pl": "copies of King James Bible" },
+- "description": "An English translation of the Christian Bible, which originated in England in the early 1600s.",
+- "copy-from": "paperback_novel",
+- "price": "550 cent",
+- "color": "dark_gray",
+- "time": "40 m",
++ "name": { "str": "Zombie Survival Guide", "str_pl": "copies of Zombie Survival Guide" },
++ "description": "While this seems like it would be very useful in this situation, the sheer amount of misinformation present makes it practically useless.",
++ "weight": "227 g",
++ "volume": "1 L",
++ "price": "1290 cent",
++ "price_postapoc": "50 cent",
++ "material": [ "paper" ],
++ "symbol": "?",
++ "color": "green",
+ "intelligence": 7,
+- "fun": 1,
+- "flags": [ "INSPIRATIONAL" ]
++ "time": "18 m",
++ "chapters": 28,
++ "fun": 2
+ },
+ {
+ "id": "black_box_transcript",
+@@ -51,18 +41,32 @@
+ "name": { "str": "black box transcript" },
+ "//": "ooh, military records, probably Classified!",
+ "description": "A full flight log for a military aircraft. Nothing of interest stands out.",
+- "copy-from": "paperback_novel",
++ "weight": "566 g",
++ "volume": "1250 ml",
+ "price": "50 USD",
++ "price_postapoc": "50 cent",
++ "bashing": 5,
++ "material": [ "paper" ],
++ "symbol": "?",
+ "color": "light_green",
+- "fun": -2
++ "intelligence": 8,
++ "time": "30 m",
++ "fun": -1
+ },
+ {
+ "id": "child_book",
+ "type": "BOOK",
+ "name": { "str": "children's book" },
+ "description": "A little book for little readers. The colorful cartoon characters and sweet stories contained herein belong to a different time, before the dead walked and the world moved on.",
+- "copy-from": "paperback_novel",
++ "weight": "52 g",
++ "volume": "250 ml",
+ "price": "550 cent",
++ "price_postapoc": "50 cent",
++ "material": [ "paper" ],
++ "symbol": "?",
++ "color": "light_cyan",
++ "time": "4 m",
++ "chapters": 4,
+ "fun": 1
+ },
+ {
+@@ -70,33 +74,66 @@
+ "type": "BOOK",
+ "name": { "str_sp": "Ranch Prospectus" },
+ "description": "A short paper of the economic viability of constructing an agricultural outpost.",
+- "copy-from": "paperback_novel",
+- "price": "30 USD"
++ "weight": "1 g",
++ "volume": "250 ml",
++ "price": "30 USD",
++ "price_postapoc": "50 cent",
++ "bashing": 1,
++ "material": [ "paper" ],
++ "symbol": "?",
++ "color": "light_cyan",
++ "intelligence": 5,
++ "time": "10 m"
+ },
+ {
+ "id": "decoy_elfa",
+ "type": "BOOK",
+ "name": { "str": "standpipe maintenance log" },
+ "description": "This binder details the scheduled maintenance for several plumbing systems throughout the facility.",
+- "copy-from": "black_box_transcript",
++ "weight": "400 g",
++ "volume": "750 ml",
+ "price": "4 USD",
+- "material": [ "paper", "plastic" ]
++ "price_postapoc": "50 cent",
++ "material": [ "paper", "plastic" ],
++ "symbol": "?",
++ "color": "light_green",
++ "intelligence": 8,
++ "time": "45 m",
++ "fun": -2
+ },
+ {
+ "id": "essay_book",
+ "type": "BOOK",
+ "name": { "str": "book of essays", "str_pl": "books of essays" },
+ "description": "A collection of essays by various authors from around the world, including works by Churchill, Mailer, Eco, and Voltaire.",
+- "copy-from": "paperback_novel",
+- "price": "1250 cent"
++ "weight": "700 g",
++ "volume": "750 ml",
++ "price": "1250 cent",
++ "price_postapoc": "50 cent",
++ "material": [ "paper" ],
++ "symbol": "?",
++ "color": "light_blue",
++ "intelligence": 10,
++ "time": "26 m",
++ "chapters": 40,
++ "fun": 3
+ },
+ {
+ "id": "fairy_tales",
+ "type": "BOOK",
+ "name": { "str": "book of fairy tales", "str_pl": "books of fairy tales" },
+ "description": "An amusing collection of folklore featuring the usual cast of fairies, goblins, and trolls.",
+- "copy-from": "paperback_novel",
++ "weight": "410 g",
++ "volume": "750 ml",
+ "price": "950 cent",
++ "price_postapoc": "50 cent",
++ "material": [ "paper" ],
++ "symbol": "?",
++ "color": "light_blue",
++ "intelligence": 6,
++ "time": "18 m",
++ "chapters": 24,
++ "fun": 3,
+ "//": "The ids below represent the Aarne-Thompson System of folklore classification. Do not change.",
+ "snippet_category": [
+ {
+@@ -180,171 +217,577 @@
+ ]
+ },
+ {
++ "id": "guidebook",
++ "type": "BOOK",
++ "name": { "str": "The Hitchhiker's Guide to the Cataclysm", "str_pl": "copies of The Hitchhiker's Guide to the Cataclysm" },
++ "description": "Inscribed on the cover in large, friendly letters, is the message \"Don't Panic\".",
++ "weight": "1764 g",
++ "volume": "1 L",
++ "price": "882 USD",
++ "price_postapoc": "50 cent",
++ "bashing": 2,
++ "material": [ "paper" ],
++ "symbol": "?",
++ "color": "green",
++ "intelligence": 3,
++ "time": "1 m"
++ },
++ {
++ "id": "mycenacean_hymns",
++ "type": "BOOK",
++ "name": { "str": "Mycenacean Hymns", "str_pl": "copies of Mycenacean Hymns" },
++ "description": "A vellum book containing the hymns central to Marloss faith. As the verses lead to each other, the text sings of unity and promised paradise.",
++ "weight": "368 g",
++ "volume": "1 L",
++ "price": "550 cent",
++ "price_postapoc": "50 cent",
++ "material": [ "paper" ],
++ "symbol": "?",
++ "color": "cyan",
++ "intelligence": 8,
++ "time": "10 m",
++ "fun": 1,
++ "flags": [ "INSPIRATIONAL" ]
++ },
++ {
++ "abstract": "holybook_abstract",
++ "type": "BOOK",
++ "name": { "str": "Holy Book", "str_pl": "copies of Holy Book" },
++ "description": "This is an abstract used for holy books. If you see this, it is a bug.",
++ "weight": "368 g",
++ "volume": "1 L",
++ "price": "550 cent",
++ "price_postapoc": "50 cent",
++ "material": [ "paper" ],
++ "symbol": "?",
++ "color": "dark_gray",
++ "intelligence": 8,
++ "time": "10 m",
++ "fun": 1,
++ "flags": [ "INSPIRATIONAL" ]
++ },
++ {
++ "id": "holybook_bible1",
++ "copy-from": "holybook_abstract",
++ "type": "BOOK",
++ "name": { "str": "King James Bible", "str_pl": "copies of King James Bible" },
++ "description": "An English translation of the Christian Bible, which originated in England in the early 1600s."
++ },
++ {
++ "id": "holybook_bible2",
++ "copy-from": "holybook_abstract",
++ "type": "BOOK",
++ "name": { "str": "Eastern Orthodox Bible", "str_pl": "copies of Eastern Orthodox Bible" },
++ "description": "An English copy of the Eastern Orthodox translation of The Holy Bible.",
++ "weight": "428 g",
++ "volume": "1250 ml"
++ },
++ {
++ "id": "holybook_bible3",
++ "copy-from": "holybook_abstract",
++ "type": "BOOK",
++ "name": { "str": "Gideon Bible", "str_pl": "copies of Gideon Bible" },
++ "description": "An English translation of the Christian Bible, distributed free of charge by Gideons International."
++ },
++ {
++ "id": "holybook_bible4",
++ "copy-from": "holybook_abstract",
++ "type": "BOOK",
++ "name": { "str": "Catholic Bible", "str_pl": "copies of Catholic Bible" },
++ "description": "An English copy of the Catholic Bible, including the whole 73 book canon recognized by the Catholic church."
++ },
++ {
++ "id": "holybook_granth",
++ "copy-from": "holybook_abstract",
++ "type": "BOOK",
++ "name": { "str": "The Guru Granth Sahib", "str_pl": "copies of The Guru Granth Sahib" },
++ "description": "A single-volume copy of the central religious texts of Sikhism.",
++ "weight": "590 g"
++ },
++ {
++ "id": "holybook_hadith",
++ "copy-from": "holybook_abstract",
++ "type": "BOOK",
++ "name": { "str": "Hadith", "str_pl": "copies of Hadith" },
++ "description": "A Muslim religious text containing an account of the sayings and actions of the prophet Muhammad.",
++ "weight": "398 g",
++ "volume": "500 ml"
++ },
++ {
++ "id": "holybook_kallisti",
++ "copy-from": "holybook_abstract",
++ "type": "BOOK",
++ "name": { "str": "Principia Discordia", "str_pl": "copies of Principia Discordia" },
++ "description": "A book that embodies the main beliefs of Discordianism. It seems to primarily concern chaos, and features a card in the back which informs you that you are now a 'genuine and authorized Pope of Discordia'.",
++ "weight": "292 g",
++ "volume": "150 ml"
++ },
++ {
++ "id": "holybook_kojiki",
++ "copy-from": "holybook_abstract",
++ "type": "BOOK",
++ "name": { "str": "The Kojiki", "str_pl": "copies of The Kojiki" },
++ "description": "The oldest extant chronicle of Japan's myths and history, the stories contained in the Kojiki are part of the inspiration behind Shinto practices.",
++ "volume": "600 ml"
++ },
++ {
++ "id": "holybook_mormon",
++ "copy-from": "holybook_abstract",
++ "type": "BOOK",
++ "name": { "str": "The Book of Mormon", "str_pl": "copies of The Book of Mormon" },
++ "description": "The sacred text of the Latter Day Saint movement of Christianity, originally published in 1830 by Joseph Smith.",
++ "volume": "600 ml"
++ },
++ {
++ "id": "holybook_pastafarian",
++ "copy-from": "holybook_abstract",
++ "type": "BOOK",
++ "name": {
++ "str": "The Gospel of the Flying Spaghetti Monster",
++ "str_pl": "copies of The Gospel of the Flying Spaghetti Monster"
++ },
++ "description": "A book that embodies the main beliefs of the Church of the Flying Spaghetti Monster. It seems to involve a lot of pirates and some sort of invisible drunken monster made of pasta.",
++ "weight": "292 g",
++ "volume": "500 ml"
++ },
++ {
++ "id": "holybook_quran",
++ "copy-from": "holybook_abstract",
++ "type": "BOOK",
++ "name": { "str": "Quran", "str_pl": "copies of Quran" },
++ "description": "An English translation of the Muslim book of holy scriptures, with explanatory notes and commentaries to aid in understanding.",
++ "weight": "412 g",
++ "volume": "600 ml"
++ },
++ {
++ "id": "holybook_scientology",
++ "copy-from": "holybook_abstract",
++ "type": "BOOK",
++ "name": { "str": "Dianetics", "str_pl": "copies of Dianetics" },
++ "description": "This book is the canonical text of Scientology. Written by a science fiction author, it contains self-improvement techniques and musings on psychology called Dianetics.",
++ "weight": "486 g",
++ "volume": "1300 ml"
++ },
++ {
++ "id": "holybook_slack",
++ "copy-from": "holybook_abstract",
++ "type": "BOOK",
++ "name": { "str": "The Book of the SubGenius", "str_pl": "copies of The Book of the SubGenius" },
++ "description": "A book about the Church of the SubGenius. It seems to involve a salesman named J. R. \"Bob\" Dobbs and a concept called 'slack'.",
++ "weight": "292 g",
++ "volume": "600 ml"
++ },
++ {
++ "id": "holybook_sutras",
++ "copy-from": "holybook_abstract",
++ "type": "BOOK",
++ "name": { "str": "The Sutras of the Buddha", "str_pl": "copies of The Sutras of the Buddha" },
++ "description": "A collection of discourses attributed to the Buddha and his close disciples.",
++ "weight": "496 g"
++ },
++ {
++ "id": "holybook_talmud",
++ "copy-from": "holybook_abstract",
++ "type": "BOOK",
++ "name": { "str": "Talmud", "str_pl": "copies of Talmud" },
++ "description": "One of the central texts of Rabbinic Judaism, the Talmud expounds upon the Hebrew Bible with teachings and opinions of thousands of rabbis.",
++ "weight": "460 g"
++ },
++ {
++ "id": "holybook_tanakh",
++ "copy-from": "holybook_abstract",
++ "type": "BOOK",
++ "name": { "str": "Tanakh", "str_pl": "copies of Tanakh" },
++ "description": "A single-volume book containing the complete canon of the Jewish Bible.",
++ "weight": "512 g",
++ "volume": "1800 ml"
++ },
++ {
++ "id": "holybook_tripitaka",
++ "copy-from": "holybook_abstract",
++ "type": "BOOK",
++ "name": { "str": "The Tripitaka", "str_pl": "copies of The Tripitaka" },
++ "description": "A collection of sacred Buddhist writings describing their canons of scriptures.",
++ "weight": "513 g"
++ },
++ {
++ "id": "holybook_upanishads",
++ "copy-from": "holybook_abstract",
++ "type": "BOOK",
++ "name": { "str": "The Upanishads", "str_pl": "copies of The Upanishads" },
++ "description": "A collection of sacred Hindu writings regarding the nature of reality and describing the character and form of human salvation.",
++ "weight": "482 g",
++ "volume": "750 ml"
++ },
++ {
++ "id": "holybook_vedas",
++ "copy-from": "holybook_abstract",
++ "type": "BOOK",
++ "name": { "str": "The Four Vedas", "str_pl": "copies of The Four Vedas" },
++ "description": "A single volume containing all four Vedas, which are the oldest scriptures of Hinduism.",
++ "weight": "540 g",
++ "volume": "1700 ml"
++ },
++ {
++ "id": "holybook_satanic",
++ "copy-from": "holybook_abstract",
++ "type": "BOOK",
++ "name": { "str": "The Satanic Bible", "str_pl": "copies of The Satanic Bible" },
++ "description": "A collection of essays, observations, and rituals published by Anton LaVey in 1969.",
++ "weight": "130 g",
++ "volume": "250 ml"
++ },
++ {
++ "id": "holybook_taoism",
++ "copy-from": "holybook_abstract",
++ "type": "BOOK",
++ "name": { "str": "Tao Te Ching", "str_pl": "copies of Tao Te Ching" },
++ "description": "An English translation of the collection of poetry and sayings that guides Taoist thought and actions.",
++ "weight": "513 g"
++ },
++ {
++ "id": "holybook_confucianism",
++ "copy-from": "holybook_abstract",
++ "type": "BOOK",
++ "name": { "str": "Lunyu", "str_pl": "copies of the Lunyu" },
++ "description": "An English translation of the most-revered sacred scripture in the Confucian tradition, compiled by the succeeding generations of Confucius's disciples. It is sometimes viewed as a philosophy and sometimes as a religion.",
++ "weight": "513 g"
++ },
++ {
++ "id": "holybook_paganism",
++ "copy-from": "holybook_abstract",
++ "//": "ISBN 1-57863-255-2",
++ "type": "BOOK",
++ "name": { "str": "Book of Pagan prayer", "str_pl": "copies of Book of Pagan prayer" },
++ "description": "A comprehensive selection of prayers to guide the reader on Pagan and Wiccan worship."
++ },
++ {
++ "id": "holybook_shamanism",
++ "copy-from": "holybook_abstract",
++ "//": "There's hundreds of shamanistic religions and folk beliefs, we can't model them all.",
++ "type": "BOOK",
++ "name": { "str": "Book of shamanistic and folk practices", "str_pl": "copies of Book of shamanistic and folk practices" },
++ "description": "A comprehensive book detailing the practices of a single region of shamanistic or folk beliefs."
++ },
++ {
++ "id": "mag_comic",
++ "type": "BOOK",
++ "name": { "str": "comic book" },
++ "description": "A super-hero comic.",
++ "weight": "60 g",
++ "volume": "250 ml",
++ "price": "300 cent",
++ "price_postapoc": "50 cent",
++ "material": [ "paper" ],
++ "symbol": "?",
++ "color": "light_cyan",
++ "time": "7 m",
++ "fun": 2
++ },
++ {
+ "id": "mag_gaming",
+ "type": "BOOK",
+ "name": { "str": "Computer Gaming", "str_pl": "issues of Computer Gaming" },
+ "description": "Reviews of recently released computer games and previews of upcoming titles.",
+- "copy-from": "mag_comic"
++ "weight": "60 g",
++ "volume": "250 ml",
++ "price": "300 cent",
++ "price_postapoc": "50 cent",
++ "material": [ "paper" ],
++ "symbol": "?",
++ "color": "pink",
++ "intelligence": 7,
++ "time": "8 m",
++ "fun": 2
+ },
+ {
+ "id": "mag_news",
+ "type": "BOOK",
+ "name": { "str": "TIME magazine" },
+ "description": "Current events concerning a bunch of people who're all (un)dead now.",
+- "copy-from": "mag_comic",
+- "price": "4 USD"
++ "weight": "60 g",
++ "volume": "250 ml",
++ "price": "400 cent",
++ "price_postapoc": "50 cent",
++ "material": [ "paper" ],
++ "symbol": "?",
++ "color": "pink",
++ "intelligence": 7,
++ "time": "10 m",
++ "fun": 2
+ },
+ {
+ "id": "mag_porn",
+ "type": "BOOK",
+ "name": { "str": "Playboy", "str_pl": "issues of Playboy" },
+ "description": "You can read it for the articles. Or not.",
+- "copy-from": "mag_comic",
+- "price": "4 USD",
+- "price_postapoc": "250 cent",
+- "intelligence": 0,
+- "color": "pink"
++ "weight": "60 g",
++ "volume": "250 ml",
++ "price": "400 cent",
++ "price_postapoc": 250,
++ "material": [ "paper" ],
++ "symbol": "?",
++ "color": "pink",
++ "time": "10 m",
++ "chapters": 4,
++ "fun": 1
+ },
+ {
+ "id": "necropolis_freq",
+ "type": "BOOK",
+ "name": { "str": "frequency list" },
+ "description": "A notepad with a number of frequencies scribbled on it.",
+- "copy-from": "mag_comic",
++ "weight": "1 g",
++ "volume": "250 ml",
+ "price": "30 USD",
+- "fun": -2
++ "price_postapoc": "50 cent",
++ "bashing": 1,
++ "material": [ "paper" ],
++ "symbol": "?",
++ "color": "light_cyan",
++ "intelligence": 2,
++ "time": "10 m"
+ },
+ {
+ "id": "necropolis_datasheet",
++ "copy-from": "necropolis_freq",
+ "type": "BOOK",
+ "name": { "str": "reclamation team report" },
+- "description": "A short written report on the findings of a team sent to reclaim an underground civil defense shelter. It lists several hazards and technical problems encountered during their exploration of the site, but mentions several military systems they expect could be repaired and used for communication.",
+- "copy-from": "necropolis_freq"
++ "description": "A short written report on the findings of a team sent to reclaim an underground civil defense shelter. It lists several hazards and technical problems encountered during their exploration of the site, but mentions several military systems they expect could be repaired and used for communication."
+ },
+ {
+ "id": "news_regional",
+ "type": "BOOK",
+ "name": { "str": "Rural Digest-Examiner", "str_pl": "issues of Rural Digest-Examiner" },
+ "description": "A newsweekly covering regional events. There is an article on the winter's snowstorms and several letters to the editor concerning the community response.",
+- "copy-from": "mag_comic",
+- "price": "350 cent"
++ "weight": "80 g",
++ "volume": "250 ml",
++ "price": "350 cent",
++ "price_postapoc": "50 cent",
++ "material": [ "paper" ],
++ "symbol": "?",
++ "color": "pink",
++ "intelligence": 5,
++ "time": "5 m",
++ "fun": 1
+ },
+ {
+ "id": "novel_adventure",
++ "copy-from": "paperback_novel",
+ "type": "BOOK",
+ "name": { "str": "adventure novel" },
+ "description": "The stirring tale of a race against time, in search of a lost city located in the dark heart of the African continent.",
+- "copy-from": "paperback_novel",
+- "price": "850 cent"
++ "price": "850 cent",
++ "time": "20 m",
++ "fun": 3
+ },
+ {
+ "id": "novel_buddy",
++ "copy-from": "paperback_novel",
+ "type": "BOOK",
+ "name": { "str": "buddy novel" },
+ "description": "A gripping tale of two friends struggling to survive on the streets of New York City.",
+- "copy-from": "paperback_novel",
+- "price": "650 cent"
++ "weight": "244 g",
++ "volume": "500 ml",
++ "price": "650 cent",
++ "time": "20 m"
+ },
+ {
+ "id": "novel_coa",
++ "copy-from": "paperback_novel",
+ "type": "BOOK",
+ "name": { "str": "coming of age novel" },
+ "description": "A classic tale about growing up, portraying one young man's funny and poignant experiences with life, love, and sex.",
+- "copy-from": "paperback_novel"
++ "weight": "187 g",
++ "volume": "500 ml",
++ "time": "20 m",
++ "snippet_category": [
++ {
++ "id": "coa1_1",
++ "text": "A classic tale about growing up, portraying one young man's funny and poignant experiences with life, love, and sex."
++ },
++ {
++ "id": "coa1_2",
++ "text": "A graphic novel about a young girl living in Iran during the 1980's, seeing the world change around her as Iraq invaded her country."
++ }
++ ]
+ },
+ {
+ "id": "novel_crime",
++ "copy-from": "paperback_novel",
+ "type": "BOOK",
+ "name": { "str": "crime novel" },
+ "description": "After their diamond heist goes wrong, the surviving criminals begin to suspect that one of them is a police informant.",
+- "copy-from": "paperback_novel",
+- "price": "850 cent"
++ "weight": "227 g",
++ "volume": "750 ml",
++ "price": "850 cent",
++ "intelligence": 6,
++ "time": "20 m",
++ "chapters": 24,
++ "fun": 3,
++ "snippet_category": [
++ {
++ "id": "crime1_1",
++ "text": "After their diamond heist goes wrong, the surviving criminals begin to suspect that one of them is a police informant."
++ },
++ {
++ "id": "crime1_2",
++ "text": "A story about three people in the fictional city of Los Santos, a gangster, an upper-class man, and a psychopath, eventually banding together to pull-off the biggest heist in the city's history."
++ },
++ {
++ "id": "crime1_3",
++ "text": "This is a copy of Murdered by the Grapevine. This cheap paperback tells the story of a mob boss done in by mere suspicion. She never breaks a confidence, never rats out an accomplice, and never turns her back on a friend. Nonetheless her grip on the reigns of the underworld is eroded by rumor and paranoia."
++ }
++ ]
+ },
+ {
+ "id": "novel_drama",
++ "copy-from": "paperback_novel",
+ "type": "BOOK",
+ "name": { "str": "drama novel" },
+ "description": "A real book for real adults.",
+- "copy-from": "paperback_novel"
++ "intelligence": 7,
++ "time": "25 m",
++ "chapters": 28,
++ "fun": 3
+ },
+ {
+ "id": "novel_erotic",
++ "copy-from": "paperback_novel",
+ "type": "BOOK",
+ "name": { "str": "erotic novel" },
+ "description": "A hackneyed fictional narrative concealing low-grade literary smut.",
+- "copy-from": "paperback_novel"
++ "weight": "200 g",
++ "volume": "500 ml",
++ "time": "18 m",
++ "chapters": 28
+ },
+ {
+ "id": "novel_experimental",
++ "copy-from": "paperback_novel",
+ "type": "BOOK",
+ "name": { "str": "experimental novel" },
+ "description": "A bizarre play about the philosophy of existential absurdity. Or maybe it's about two guys waiting for their friend to show up. It's confusing.",
+- "copy-from": "paperback_novel"
++ "weight": "142 g",
++ "volume": "500 ml",
++ "intelligence": 7,
++ "time": "20 m",
++ "chapters": 20
+ },
+ {
+ "id": "novel_fantasy",
++ "copy-from": "paperback_novel",
+ "type": "BOOK",
+ "name": { "str": "fantasy novel" },
+ "description": "Basic sword & sorcery.",
+- "copy-from": "paperback_novel"
++ "weight": "227 g",
++ "volume": "1 L",
++ "intelligence": 7,
++ "time": "20 m",
++ "chapters": 28,
++ "fun": 3
+ },
+ {
+ "id": "novel_horror",
++ "copy-from": "paperback_novel",
+ "type": "BOOK",
+ "name": { "str": "horror novel" },
+ "description": "Maybe not the best reading material considering the situation.",
+- "copy-from": "paperback_novel"
++ "weight": "227 g",
++ "intelligence": 7,
++ "time": "18 m",
++ "chapters": 28
+ },
+ {
+ "id": "novel_mystery",
++ "copy-from": "paperback_novel",
+ "type": "BOOK",
+ "name": { "str": "mystery novel" },
+ "description": "A detective investigates an unusual murder in a secluded location.",
+- "copy-from": "paperback_novel"
++ "intelligence": 7,
++ "time": "18 m",
++ "chapters": 28,
++ "fun": 3
+ },
+ {
+ "id": "novel_pulp",
++ "copy-from": "paperback_novel",
+ "type": "BOOK",
+ "name": { "str": "pulp novel" },
+ "description": "A hardboiled detective tale filled with hard hitting action and intrigue.",
+- "copy-from": "paperback_novel"
++ "intelligence": 6,
++ "time": "18 m",
++ "chapters": 24,
++ "fun": 3
+ },
+ {
+ "id": "novel_road",
++ "copy-from": "paperback_novel",
+ "type": "BOOK",
+ "name": { "str": "road novel" },
+ "description": "A tale about a group of friends who wander the USA in the 1960s against a backdrop of jazz, poetry and drug use.",
+- "copy-from": "paperback_novel"
++ "weight": "244 g",
++ "volume": "500 ml",
++ "time": "20 m",
++ "fun": 3
+ },
+ {
+ "id": "novel_romance",
++ "copy-from": "paperback_novel",
+ "type": "BOOK",
+ "name": { "str": "romance novel" },
+- "description": "Drama and mild smut.",
+- "copy-from": "paperback_novel"
++ "description": "Drama and mild smut."
+ },
+ {
+ "id": "novel_samurai",
+ "type": "BOOK",
+ "name": { "str": "samurai novel" },
+ "description": "The classic tale of a wandering swordsman who comes to a small settlement and is hired to help the townsfolk defend themselves from a band of marauding outlaws.",
+- "copy-from": "paperback_novel"
++ "weight": "322 g",
++ "volume": "750 ml",
++ "price": "750 cent",
++ "price_postapoc": "50 cent",
++ "material": [ "paper" ],
++ "symbol": "?",
++ "color": "light_blue",
++ "intelligence": 7,
++ "time": "20 m",
++ "chapters": 28,
++ "fun": 4
+ },
+ {
+ "id": "novel_satire",
+ "type": "BOOK",
+ "name": { "str": "satire novel" },
+ "description": "A political satire of the pre-apocalypse world. Looking back on it from this side of Armageddon makes it seem all the more ridiculous.",
+- "copy-from": "paperback_novel",
+- "price": "850 cent"
++ "weight": "520 g",
++ "volume": "750 ml",
++ "price": "850 cent",
++ "price_postapoc": "50 cent",
++ "material": [ "paper" ],
++ "symbol": "?",
++ "color": "light_blue",
++ "intelligence": 7,
++ "time": "36 m",
++ "chapters": 28,
++ "fun": 2
+ },
+ {
+ "id": "novel_scifi",
+ "type": "BOOK",
+ "name": { "str": "scifi novel" },
+ "description": "Aliens, ray guns, and space ships.",
+- "copy-from": "paperback_novel",
++ "weight": "227 g",
++ "volume": "750 ml",
+ "price": "850 cent",
++ "price_postapoc": "50 cent",
++ "material": [ "paper" ],
++ "symbol": "?",
++ "color": "light_blue",
++ "intelligence": 6,
++ "time": "20 m",
++ "chapters": 24,
++ "fun": 3,
+ "snippet_category": [
+ {
+ "id": "scifi1_1",
+@@ -492,59 +935,111 @@
+ },
+ {
+ "id": "novel_sports",
++ "copy-from": "paperback_novel",
+ "type": "BOOK",
+ "name": { "str": "sports novel" },
+ "description": "The dramatic tale of a small-time boxer who gets a rare chance to fight the heavy-weight champion, and seize his one chance to make a better life for himself while impressing the cute girl who works in the pet store.",
+- "copy-from": "paperback_novel"
++ "intelligence": 7,
++ "time": "20 m",
++ "chapters": 28,
++ "fun": 3
+ },
+ {
+ "id": "novel_spy",
+ "type": "BOOK",
+ "name": { "str": "spy novel" },
+ "description": "A tale of intrigue and espionage amongst Nazis, no, Commies, no, Iraqis!",
+- "copy-from": "paperback_novel"
++ "copy-from": "paperback_novel",
++ "intelligence": 5,
++ "time": "18 m",
++ "chapters": 20,
++ "fun": 3,
++ "snippet_category": [
++ { "id": "spy1_1", "text": "A tale of intrigue and espionage amongst Nazis, no, Commies, no, Iraqis!" },
++ {
++ "id": "spy1_2",
++ "text": "This is a copy of Come Fly the Treacherous Skies. A tale of intrigue betrays the story of a debonair mechanic driven by a lust for revenge. As she uncovers a sophisticated network of amateur pilots turned smugglers, the good guys and the bad guys begin to all look the same."
++ },
++ {
++ "id": "spy1_3",
++ "text": "This is a copy of Lies, Damn Lies, and Rocket Science. This spy novel tells the story of a jaded rocket scientist looking for redemption in all the wrong places. As selling state secrets becomes her career, she learns there isn't much of difference between a double-agent and a triple-agent."
++ }
++ ]
+ },
+ {
+ "id": "novel_swash",
++ "copy-from": "paperback_novel",
+ "type": "BOOK",
+ "name": { "str": "swashbuckling novel" },
+ "description": "An exciting seventeenth century tale of how an enslaved Irish doctor and his comrades-in-chains escape and become heroic pirates of the Robin Hood variety.",
+- "copy-from": "paperback_novel"
++ "weight": "582 g",
++ "volume": "750 ml",
++ "intelligence": 7,
++ "time": "20 m",
++ "chapters": 28,
++ "fun": 4
+ },
+ {
+ "id": "novel_thriller",
++ "copy-from": "paperback_novel",
+ "type": "BOOK",
+ "name": { "str": "thriller novel" },
+ "description": "A suspenseful tale of betrayal and revenge.",
+- "copy-from": "paperback_novel"
++ "intelligence": 5,
++ "time": "18 m",
++ "chapters": 20,
++ "fun": 3
+ },
+ {
+ "id": "novel_tragedy",
++ "copy-from": "paperback_novel",
+ "type": "BOOK",
+ "name": { "str": "tragedy novel" },
+ "description": "The story of two young lovers whose feuding families threaten to keep them apart.",
+- "copy-from": "paperback_novel"
++ "weight": "263 g",
++ "volume": "1 L",
++ "intelligence": 7,
++ "time": "18 m",
++ "chapters": 28
+ },
+ {
+ "id": "novel_war",
++ "copy-from": "paperback_novel",
+ "type": "BOOK",
+ "name": { "str": "war novel" },
+ "description": "A thrilling narrative of survival in a prisoner of war camp during the Second World War, filled with riveting subplots about rat farming and dysentery.",
+- "copy-from": "paperback_novel"
++ "weight": "686 g",
++ "intelligence": 7,
++ "time": "20 m",
++ "chapters": 28,
++ "fun": 3,
++ "snippet_category": [
++ {
++ "id": "war1_1",
++ "text": "A thrilling narrative of survival in a prisoner of war camp during the Second World War, filled with riveting subplots about rat farming and dysentery."
++ },
++ {
++ "id": "war1_2",
++ "text": "A story about a Bosnian citizen who goes through many hardships and near death during the breakup of Yugoslavia."
++ }
++ ]
+ },
+ {
+ "id": "novel_western",
++ "copy-from": "paperback_novel",
+ "type": "BOOK",
+ "name": { "str": "western novel" },
+ "description": "The classic tale of a gunfighting stranger who comes to a small settlement and is hired to help the townsfolk defend themselves from a band of marauding outlaws.",
+- "copy-from": "paperback_novel"
++ "intelligence": 5,
++ "time": "20 m",
++ "chapters": 28,
++ "fun": 4
+ },
+ {
+ "id": "philosophy_book",
+ "type": "BOOK",
+ "name": { "str": "book of philosophy", "str_pl": "books of philosophy" },
+ "description": "A deep discussion of morality with an emphasis on epistemology and logic.",
+- "copy-from": "paperback_novel",
+ "snippet_category": [
+ {
+ "id": "philosophy1",
+@@ -694,59 +1189,137 @@
+ },
+ { "id": "philosophy45", "text": "This is a copy of \"Anti-Capitalist Mentality\" by Ludwig von Mises." }
+ ],
+- "price": "1250 cent"
++ "weight": "350 g",
++ "volume": "750 ml",
++ "price": "1250 cent",
++ "price_postapoc": "50 cent",
++ "material": [ "paper" ],
++ "symbol": "?",
++ "color": "light_blue",
++ "intelligence": 9,
++ "time": "36 m",
++ "chapters": 44,
++ "fun": 3
+ },
+ {
+ "id": "phonebook",
+ "type": "BOOK",
+ "name": { "str": "phone book" },
+ "description": "This hefty volume contains the telephone numbers of individuals, businesses, and utilities in the nearby area, pretty useless during the apocalypse and all.",
+- "copy-from": "black_box_transcript",
+- "weight": "2 kg",
+- "volume": "1500 ml",
+- "price": "8 USD"
++ "weight": "854 g",
++ "volume": "2500 ml",
++ "price": "8 USD",
++ "price_postapoc": "50 cent",
++ "bashing": 2,
++ "material": [ "paper" ],
++ "symbol": "?",
++ "color": "yellow",
++ "intelligence": 4,
++ "time": "1 m",
++ "chapters": 200,
++ "fun": -5
+ },
+ {
+ "id": "photo_album",
+ "type": "BOOK",
+ "name": { "str": "photo album" },
+ "description": "A leather album full of photos of somebody's family. You don't know any of the people in them, but seeing these pictures still makes you think of happier times.",
+- "copy-from": "paperback_novel",
++ "weight": "180 g",
++ "volume": "250 ml",
+ "price": "30 USD",
++ "price_postapoc": "50 cent",
+ "material": [ "paper", "leather" ],
+- "fun": 1
++ "symbol": "?",
++ "color": "light_gray",
++ "time": "10 m",
++ "chapters": 4,
++ "fun": 1,
++ "flags": [ "INSPIRATIONAL" ]
+ },
+ {
+ "id": "plays_book",
+ "type": "BOOK",
+ "name": { "str": "book of plays", "str_pl": "books of plays" },
+ "description": "A collection of plays by various authors from around the world, including scripts by Wilde, Beckett, Checkov, and Shakespeare.",
+- "copy-from": "paperback_novel",
+- "price": "1150 cent"
++ "weight": "700 g",
++ "volume": "750 ml",
++ "price": "1150 cent",
++ "price_postapoc": "50 cent",
++ "material": [ "paper" ],
++ "symbol": "?",
++ "color": "light_blue",
++ "intelligence": 9,
++ "time": "18 m",
++ "chapters": 36,
++ "fun": 2
+ },
+ {
+ "id": "poetry_book",
+ "type": "BOOK",
+ "name": { "str": "book of poetry", "str_pl": "books of poetry" },
+ "description": "A collection of poetry by various authors from around the world, including writings by Dickinson, Goethe, Thoreau, and Yeats.",
+- "copy-from": "paperback_novel",
+- "price": "1050 cent"
++ "weight": "400 g",
++ "volume": "500 ml",
++ "price": "1050 cent",
++ "price_postapoc": "50 cent",
++ "material": [ "paper" ],
++ "symbol": "?",
++ "color": "light_blue",
++ "intelligence": 9,
++ "time": "18 m",
++ "chapters": 36,
++ "fun": 2
++ },
++ {
++ "id": "priest_diary",
++ "type": "BOOK",
++ "name": { "str": "priest's diary", "str_pl": "priests' diaries" },
++ "description": "A small book filled with journal entries in Latin.",
++ "weight": "340 g",
++ "volume": "750 ml",
++ "price": "15 USD",
++ "price_postapoc": "50 cent",
++ "bashing": 3,
++ "material": [ "paper" ],
++ "symbol": "?",
++ "color": "light_gray",
++ "intelligence": 15,
++ "time": "30 m",
++ "fun": -1,
++ "flags": [ "INSPIRATIONAL", "MORBID" ]
+ },
+ {
+ "id": "record_accounting",
+ "type": "BOOK",
+ "name": { "str": "corporate accounting ledger" },
+ "description": "If you knew what to look for something might stand out…",
+- "copy-from": "black_box_transcript",
+- "price": "20 USD"
++ "weight": "566 g",
++ "volume": "1250 ml",
++ "price": "20 USD",
++ "price_postapoc": "50 cent",
++ "bashing": 5,
++ "material": [ "paper" ],
++ "symbol": "?",
++ "color": "light_green",
++ "intelligence": 10,
++ "time": "30 m",
++ "fun": -1
+ },
+ {
+ "id": "record_patient",
+ "type": "BOOK",
+ "name": { "str_sp": "patient treatment records" },
+ "description": "A massive stack of medical records that contain every gory detail.",
+- "copy-from": "paperback_novel",
++ "weight": "680 g",
++ "volume": "1500 ml",
+ "price": "5 USD",
++ "price_postapoc": "50 cent",
++ "bashing": 6,
++ "material": [ "paper" ],
++ "symbol": "?",
++ "color": "light_green",
++ "intelligence": 8,
++ "time": "30 m",
+ "fun": -1,
+ "flags": [ "MORBID" ]
+ },
+@@ -755,31 +1328,92 @@
+ "type": "BOOK",
+ "name": { "str_sp": "national weather transcripts" },
+ "description": "Old weather records are about as interesting as a rock.",
+- "copy-from": "black_box_transcript",
+- "price": "5 USD"
++ "weight": "454 g",
++ "volume": "1750 ml",
++ "price": "5 USD",
++ "price_postapoc": "50 cent",
++ "bashing": 7,
++ "material": [ "paper" ],
++ "symbol": "?",
++ "color": "light_green",
++ "intelligence": 4,
++ "time": "30 m",
++ "fun": -1
+ },
+ {
+ "id": "story_book",
+ "type": "BOOK",
+ "name": { "str": "big book of short stories", "str_pl": "big books of short stories" },
+ "description": "This humongous volume contains a vast collection of short stories by different authors, spanning a wide variety of topics and genres.",
+- "copy-from": "paperback_novel",
+- "price": "14 USD"
++ "weight": "1720 g",
++ "volume": "1 L",
++ "price": "14 USD",
++ "price_postapoc": "50 cent",
++ "material": [ "paper" ],
++ "symbol": "?",
++ "color": "light_blue",
++ "intelligence": 7,
++ "time": "48 m",
++ "chapters": 28,
++ "fun": 5
+ },
+ {
+ "id": "tall_tales",
+ "type": "BOOK",
+ "name": { "str": "book of tall tales", "str_pl": "books of tall tales" },
+ "description": "An entertaining collection of early American folklore, featuring tales of larger than life individuals and their amazing adventures.",
+- "copy-from": "paperback_novel",
+- "price": "1050 cent"
++ "weight": "360 g",
++ "volume": "750 ml",
++ "price": "1050 cent",
++ "price_postapoc": "50 cent",
++ "material": [ "paper" ],
++ "symbol": "?",
++ "color": "light_blue",
++ "intelligence": 6,
++ "time": "18 m",
++ "chapters": 24,
++ "fun": 3
++ },
++ {
++ "id": "visions_solitude",
++ "type": "BOOK",
++ "name": { "str": "Visions in Solitude", "str_pl": "copies of Visions in Solitude" },
++ "description": "A small book detailing 'visions' a prisoner had on death row.",
++ "weight": "227 g",
++ "volume": "750 ml",
++ "price": "29 USD",
++ "price_postapoc": "50 cent",
++ "bashing": 3,
++ "material": [ "paper" ],
++ "symbol": "?",
++ "color": "light_cyan",
++ "intelligence": 6,
++ "time": "30 m",
++ "fun": 2,
++ "flags": [ "INSPIRATIONAL", "MORBID" ]
++ },
++ {
++ "id": "holybook_havamal",
++ "type": "BOOK",
++ "name": { "str": "Hávamál", "str_pl": "copies of Hávamál" },
++ "description": "An English translation of several Old Norse poems. The poems contain proverbs and stories attributed to the god Odin, many transcribed from oral history.",
++ "weight": "292 g",
++ "volume": "750 ml",
++ "price": "550 cent",
++ "price_postapoc": "50 cent",
++ "material": [ "paper" ],
++ "symbol": "?",
++ "color": "dark_gray",
++ "intelligence": 8,
++ "time": "10 m",
++ "fun": 1,
++ "flags": [ "INSPIRATIONAL" ]
+ },
+ {
+ "type": "BOOK",
+ "id": "classic_literature",
+ "name": { "str": "book of classic literature", "str_pl": "books of classic literature" },
+ "description": "A book of classic literature, timeless and enjoyable but a bit dense to read.",
+- "copy-from": "paperback_novel",
+ "snippet_category": [
+ { "id": "classic1", "text": "This is a copy of Dickens' \"Bleak House\"." },
+ { "id": "classic2", "text": "This is a copy of \"Great Expectations\" by Charles Dickens." },
+@@ -805,84 +1439,97 @@
+ },
+ {
+ "id": "classic14",
+- "text": "This is a copy of \"Jane Eyre\". The cover art is quite out of place, making it look more like a dime-store romance novel."
++ "text": "This is a paperback copy of the well-known classic \"Dark Days Ahead\", by K. G. Ranade. There are scrawled margin notes all over it, apparently the workings of a confused and feverish mind."
+ },
+ {
+ "id": "classic15",
+- "text": "This is a perfectly preserved hardcover copy of \"The Gunslinger\" by Stephen King, autographed by the author. It contains a certificate of authenticity pronouncing it to be a first edition."
++ "text": "This is a copy of \"Jane Eyre\". The cover art is quite out of place, making it look more like a dime-store romance novel."
+ },
+ {
+ "id": "classic16",
+- "text": "This paperback copy of \"Wuthering Heights\" has a large coffee stain on the first page."
++ "text": "This is a perfectly preserved hardcover copy of \"The Gunslinger\" by Stephen King, autographed by the author. It contains a certificate of authenticity pronouncing it to be a first edition."
+ },
+ {
+ "id": "classic17",
+- "text": "This is a hardbound copy of \"Lady Chatterly's Lover\", by D. H. Lawrence. It has some very explicit illustrations."
++ "text": "This paperback copy of \"Wuthering Heights\" has a large coffee stain on the first page."
+ },
+ {
+ "id": "classic18",
+- "text": "This is a hardbound copy of \"The Catcher in the Rye.\". It has some very nicely done illustrations."
++ "text": "This is a hardbound copy of \"Lady Chatterly's Lover\", by D. H. Lawrence. It has some very explicit illustrations."
+ },
+ {
+ "id": "classic19",
++ "text": "This is a hardbound copy of \"The Catcher in the Rye.\". It has some very nicely done illustrations."
++ },
++ {
++ "id": "classic20",
+ "text": "This is a collection of classic renaissance era stories, headlined by \"Don Quixote\"."
+ },
+- { "id": "classic20", "text": "This is a paperback copy of \"The Fellowship of the Ring\" by Tolkien." },
+- { "id": "classic21", "text": "This is a paperback copy of \"The Two Towers\" by Tolkien." },
+- { "id": "classic22", "text": "This is a paperback copy of \"The Return of the King\" by Tolkien." },
++ { "id": "classic21", "text": "This is a paperback copy of \"The Fellowship of the Ring\" by Tolkien." },
++ { "id": "classic22", "text": "This is a paperback copy of \"The Two Towers\" by Tolkien." },
++ { "id": "classic23", "text": "This is a paperback copy of \"The Return of the King\" by Tolkien." },
+ {
+- "id": "classic23",
++ "id": "classic24",
+ "text": "This is a hardbound collection of George Orwell's works, including \"1984\" and \"Animal Farm\" as well as many of his less infamous titles."
+ },
+ {
+- "id": "classic24",
++ "id": "classic25",
+ "text": "This is a paperback copy of \"Little Women\" by Louisa May Alcott. It appears to have been read a great many times."
+ },
+- { "id": "classic25", "text": "This is a paperback copy of \"Of Mice and Men\" by Steinbeck." },
++ { "id": "classic26", "text": "This is a paperback copy of \"Of Mice and Men\" by Steinbeck." },
+ {
+- "id": "classic26",
++ "id": "classic27",
+ "text": "This is a hefty hardcover copy of \"Run and Run Again\" by Finn Calpay. There is a lengthy forward about the controversy around the book's release."
+ },
+ {
+- "id": "classic27",
++ "id": "classic28",
+ "text": "This is a hardcover copy of \"The Gates Have Opened\" by Arianna Methusalah. You feel like you've read this before, but can't remember where. Something about the book fills you with unease."
+ },
+- { "id": "classic28", "text": "This is a copy of \"The Count of Monte Cristo\" by Dumas." },
+- { "id": "classic29", "text": "This is a copy of \"The Secret Garden\" by Frances Burnett." },
+- { "id": "classic30", "text": "This is a copy of \"Lieutenant Hornblower\" by C.S. Forester." },
+- { "id": "classic31", "text": "This is a copy of \"Master and Commander\" by Patrick O'Brian." },
+- { "id": "classic32", "text": "This is a copy of \"The Warden\" by Anthony Trollope." },
+- { "id": "classic33", "text": "This is a copy of \"The Far Side of the World\" by Patrick O'Brian." },
+- { "id": "classic34", "text": "This is a copy of \"HMS Surprise\" by Patrick O'Brian." },
+- { "id": "classic35", "text": "This is a copy of \"Barchester Towers\" by Anthony Trollope." },
+- { "id": "classic36", "text": "This is a copy of \"The Land Ironclads\" by H.G. Wells." },
+- { "id": "classic37", "text": "This is a copy of \"The Great Boer War\" by Arthur Conan Doyle." },
+- { "id": "classic38", "text": "This is a copy of \"The Crime of the Congo\" by Arthur Conan Doyle." },
+- { "id": "classic39", "text": "This is a copy of \"The Parasite\" by Arthur Conan Doyle." },
+- { "id": "classic40", "text": "This is a copy of \"By Stroke of Sword\" by Andrew Balfour." },
+- { "id": "classic41", "text": "This is a copy of \"The Secret Agent\" by Joseph Conrad." },
+- { "id": "classic42", "text": "This is a copy of \"Lord Jim\" by Joseph Conrad." },
+- { "id": "classic43", "text": "This is a copy of \"Vanity Fair\" by William Makepeace Thackeray." },
+- { "id": "classic44", "text": "This is a copy of \"The Luck of Barry Lyndon\" by William Makepeace Thackeray." },
+- { "id": "classic45", "text": "This is a copy of \"North and South\" by Elizabeth Gaskell." },
+- { "id": "classic46", "text": "This is a copy of \"The Mayor of Casterbridge\" by Thomas Hardy." },
+- { "id": "classic47", "text": "This is a copy of \"Wessex Tales\" by Thomas Hardy." },
+- { "id": "classic48", "text": "This is a copy of \"Far from the Madding Crowd\" by Thomas Hardy." },
+- { "id": "classic49", "text": "This is a copy of \"Captains Courageous\" by Rudyard Kipling." },
+- { "id": "classic50", "text": "This is a copy of \"The Canterbury Tales\" by Geoffrey Chaucer." },
+- { "id": "classic51", "text": "This is a copy of \"Harold, the Last of the Saxons\" by Edward Bulwer-Lytton." },
+- { "id": "classic52", "text": "This is a copy of \"Mr Midshipman Easy\" by Frederick Marryat." },
+- { "id": "classic53", "text": "This is a copy of \"Peter Simple\" by Frederick Marryat." }
++ { "id": "classic29", "text": "This is a copy of \"The Count of Monte Cristo\" by Dumas." },
++ { "id": "classic30", "text": "This is a copy of \"The Secret Garden\" by Frances Burnett." },
++ { "id": "classic31", "text": "This is a copy of \"Lieutenant Hornblower\" by C.S. Forester." },
++ { "id": "classic32", "text": "This is a copy of \"Master and Commander\" by Patrick O'Brian." },
++ { "id": "classic33", "text": "This is a copy of \"The Warden\" by Anthony Trollope." },
++ { "id": "classic34", "text": "This is a copy of \"The Far Side of the World\" by Patrick O'Brian." },
++ { "id": "classic35", "text": "This is a copy of \"HMS Surprise\" by Patrick O'Brian." },
++ { "id": "classic36", "text": "This is a copy of \"Barchester Towers\" by Anthony Trollope." },
++ { "id": "classic37", "text": "This is a copy of \"The Land Ironclads\" by H.G. Wells." },
++ { "id": "classic38", "text": "This is a copy of \"The Great Boer War\" by Arthur Conan Doyle." },
++ { "id": "classic39", "text": "This is a copy of \"The Crime of the Congo\" by Arthur Conan Doyle." },
++ { "id": "classic40", "text": "This is a copy of \"The Parasite\" by Arthur Conan Doyle." },
++ { "id": "classic41", "text": "This is a copy of \"By Stroke of Sword\" by Andrew Balfour." },
++ { "id": "classic42", "text": "This is a copy of \"The Secret Agent\" by Joseph Conrad." },
++ { "id": "classic43", "text": "This is a copy of \"Lord Jim\" by Joseph Conrad." },
++ { "id": "classic44", "text": "This is a copy of \"Vanity Fair\" by William Makepeace Thackeray." },
++ { "id": "classic45", "text": "This is a copy of \"The Luck of Barry Lyndon\" by William Makepeace Thackeray." },
++ { "id": "classic46", "text": "This is a copy of \"North and South\" by Elizabeth Gaskell." },
++ { "id": "classic47", "text": "This is a copy of \"The Mayor of Casterbridge\" by Thomas Hardy." },
++ { "id": "classic48", "text": "This is a copy of \"Wessex Tales\" by Thomas Hardy." },
++ { "id": "classic49", "text": "This is a copy of \"Far from the Madding Crowd\" by Thomas Hardy." },
++ { "id": "classic50", "text": "This is a copy of \"Captains Courageous\" by Rudyard Kipling." },
++ { "id": "classic51", "text": "This is a copy of \"The Canterbury Tales\" by Geoffrey Chaucer." },
++ { "id": "classic52", "text": "This is a copy of \"Harold, the Last of the Saxons\" by Edward Bulwer-Lytton." },
++ { "id": "classic53", "text": "This is a copy of \"Mr Midshipman Easy\" by Frederick Marryat." },
++ { "id": "classic54", "text": "This is a copy of \"Peter Simple\" by Frederick Marryat." }
+ ],
++ "weight": "350 g",
++ "volume": "750 ml",
+ "price": "20 USD",
+- "looks_like": "tall_tales"
++ "price_postapoc": "50 cent",
++ "material": [ "paper" ],
++ "looks_like": "tall_tales",
++ "color": "light_blue",
++ "symbol": "?",
++ "intelligence": 7,
++ "time": "28 m",
++ "chapters": 40,
++ "fun": 3
+ },
+ {
+ "type": "BOOK",
+ "id": "collector_book",
+ "name": { "str": "collector's edition book" },
+ "description": "A unique, valuable book that has been kept as a collector's item.",
+- "copy-from": "paperback_novel",
+ "snippet_category": [
+ { "id": "fancy1", "text": "This is a high-quality leather bound copy of Charles Dickens' \"A Tale of Two Cities\"." },
+ { "id": "fancy2", "text": "This is a very old but well-preserved copy of Charles Dickens' \"Oliver Twist\"." },
+@@ -929,36 +1576,49 @@
+ },
+ {
+ "id": "fancy14",
+- "text": "This is a well-kept leather bound copy of \"Oryx and Crake\" by Margaret Atwood. Inscribed in the inner cover is a faded note wishing the owner a happy birthday."
++ "text": "This is a high-quality leather bound copy of the well-known classic \"Dark Days Ahead\", by K. G. Ranade."
+ },
+ {
+ "id": "fancy15",
+- "text": "This is a perfectly preserved hardcover copy of \"The Gunslinger\" by Stephen King, autographed by the author. It contains a certificate of authenticity pronouncing it to be a first edition."
++ "text": "This is a well-kept leather bound copy of \"Oryx and Crake\" by Margaret Atwood. Inscribed in the inner cover is a faded note wishing the owner a happy birthday."
+ },
+ {
+ "id": "fancy16",
+- "text": "This bright orange hardcover copy of \"1984\" by George Orwell has been carefully preserved, and appears to be a first or second edition judging from the publisher's information."
++ "text": "This is a perfectly preserved hardcover copy of \"The Gunslinger\" by Stephen King, autographed by the author. It contains a certificate of authenticity pronouncing it to be a first edition."
+ },
+ {
+ "id": "fancy17",
+- "text": "This is a very nice copy of \"Lady Chatterly's Lover\", probably quite expensive in the days before the apocalypse."
++ "text": "This bright orange hardcover copy of \"1984\" by George Orwell has been carefully preserved, and appears to be a first or second edition judging from the publisher's information."
+ },
+ {
+ "id": "fancy18",
+- "text": "This is a high quality early edition hardcover copy of \"The Handmaid's Tale\" by Margaret Atwood, signed by the author."
++ "text": "This is a very nice copy of \"Lady Chatterly's Lover\", probably quite expensive in the days before the apocalypse."
+ },
+ {
+ "id": "fancy19",
+- "text": "This ancient and worn book looks to be an 18th or early 19th century handwritten copy of \"Don Quixote\". In the days of book traders it would have been worth an absolute fortune. Now it's either a priceless piece of history, some light reading before bed, or excellent kindling."
++ "text": "This is a high quality early edition hardcover copy of \"The Handmaid's Tale\" by Margaret Atwood, signed by the author."
+ },
+ {
+ "id": "fancy20",
++ "text": "This ancient and worn book looks to be an 18th or early 19th century handwritten copy of \"Don Quixote\". In the days of book traders it would have been worth an absolute fortune. Now it's either a priceless piece of history, some light reading before bed, or excellent kindling."
++ },
++ {
++ "id": "fancy21",
+ "text": "This is a first edition copy of Terry Pratchett's \"The Colour of Magic\". In the inner cover is a handwritten note that reads \"To Chris, thanks for believing I could do it. Best regards, Terry.\""
+ }
+ ],
++ "weight": "400 g",
++ "volume": "750 ml",
+ "price": "4550 cent",
++ "price_postapoc": "50 cent",
++ "material": [ "paper" ],
+ "looks_like": "tall_tales",
+- "fun": 3
++ "color": "light_blue",
++ "symbol": "?",
++ "intelligence": 7,
++ "time": "28 m",
++ "chapters": 40,
++ "fun": 4
+ },
+ {
+ "id": "sa_cryptology_key",
diff --git a/revert-03_generic-nv.patch b/revert-03_generic-nv.patch
new file mode 100644
index 0000000..64f491b
--- /dev/null
+++ b/revert-03_generic-nv.patch
@@ -0,0 +1,365 @@
+--- a/data/json/mutations/mutations.json
++++ b/data/json/mutations/mutations.json
+@@ -152,7 +152,7 @@
+ "description": "You heal faster when sleeping and will even recover a small amount of HP when not sleeping.",
+ "starting_trait": true,
+ "types": [ "HEALING" ],
+- "changes_to": [ "FASTHEALER2", "REGEN_LIZ" ],
++ "changes_to": [ "FASTHEALER2" ],
+ "category": [ "MEDICAL" ],
+ "healing_awake": 0.2,
+ "healing_resting": 0.5,
+@@ -213,7 +213,7 @@
+ "starting_trait": true,
+ "changes_to": [ "NIGHTVISION2" ],
+ "cancels": [ "ELFA_NV", "ELFA_FNV", "FEL_NV", "URSINE_EYE" ],
+- "category": [ "BIRD", "CATTLE", "INSECT" ],
++ "category": [ "BIRD", "CATTLE", "INSECT", "URSINE" ],
+ "active": true,
+ "starts_active": true,
+ "night_vision_range": 2
+@@ -692,7 +692,7 @@
+ "description": "Without glasses, your seeing radius is severely reduced! However, you are guaranteed to start with a pair of glasses.",
+ "starting_trait": true,
+ "cancels": [ "URSINE_EYE", "EAGLEEYED", "HYPEROPIC" ],
+- "category": [ "BEAST", "TROGLOBITE" ]
++ "category": [ "BEAST", "TROGLOBITE", "URSINE" ]
+ },
+ {
+ "type": "mutation",
+@@ -1238,7 +1238,7 @@
+ "prereqs": [ "NIGHTVISION" ],
+ "changes_to": [ "NIGHTVISION3" ],
+ "cancels": [ "ELFA_NV", "ELFA_FNV", "FEL_NV", "URSINE_EYE" ],
+- "category": [ "FISH", "BEAST", "INSECT", "RAT", "CHIMERA", "LUPINE", "MOUSE" ],
++ "category": [ "FISH", "BEAST", "INSECT", "RAT", "CHIMERA", "LUPINE", "MOUSE", "FELINE", "URSINE" ],
+ "active": true,
+ "starts_active": true,
+ "night_vision_range": 4.5
+@@ -1252,7 +1252,8 @@
+ "prereqs": [ "NIGHTVISION2" ],
+ "leads_to": [ "INFRARED" ],
+ "cancels": [ "ELFA_NV", "ELFA_FNV", "FEL_NV", "URSINE_EYE" ],
+- "category": [ "FISH", "TROGLOBITE", "SPIDER" ],
++ "threshreq": [ "THRESH_FISH", "THRESH_TROGLOBITE", "THRESH_SPIDER", "THRESH_INSECT", "THRESH_ELFA", "THRESH_CEPHALOPOD" ],
++ "category": [ "FISH", "TROGLOBITE", "SPIDER", "INSECT", "ELFA", "CEPHALOPOD" ],
+ "active": true,
+ "starts_active": true,
+ "night_vision_range": 10
+@@ -1265,62 +1266,22 @@
+ "visibility": 8,
+ "ugliness": 5,
+ "description": "Your eyes still bulge, yet your pupils look different somehow. Water doesn't seem to cause any trouble at all, though.",
+- "leads_to": [ "CEPH_VISION" ],
++ "leads_to": [ "NIGHTVISION3" ],
+ "cancels": [ "BIRD_EYE", "LIZ_EYE", "FEL_EYE", "URSINE_EYE", "COMPOUND_EYES", "ELFAEYES" ],
+ "category": [ "CEPHALOPOD" ]
+ },
+- {
+- "type": "mutation",
+- "id": "CEPH_VISION",
+- "name": { "str": "Cephalopod Vision" },
+- "points": 3,
+- "description": "Your brain has caught up with your eyes. You can see much better in the dark, but sunlight seems much brighter now. Activate to toggle NV-visible areas on or off.",
+- "prereqs": [ "CEPH_EYES" ],
+- "cancels": [ "LIZ_IR", "FEL_NV", "NIGHTVISION", "NIGHTVISION2", "NIGHTVISION3", "ELFA_NV", "ELFA_FNV" ],
+- "category": [ "CEPHALOPOD" ],
+- "active": true,
+- "starts_active": true,
+- "night_vision_range": 10
+- },
+ {
+ "type": "mutation",
+ "id": "ELFAEYES",
+ "name": { "str": "Fey Eyes" },
+ "points": 1,
+ "description": "Your eyes have turned… green. It's tough to tell the exact shade as it seems to shift. The effect is… pleasant.",
+- "leads_to": [ "ELFA_NV" ],
+ "valid": false,
+ "cancels": [ "BIRD_EYE", "LIZ_EYE", "FEL_EYE", "URSINE_EYE", "COMPOUND_EYES" ],
++ "leads_to": [ "NIGHTVISION2" ],
+ "category": [ "ELFA" ],
+ "social_modifiers": { "lie": 5, "persuade": 5, "intimidate": -5 }
+ },
+- {
+- "type": "mutation",
+- "id": "ELFA_NV",
+- "name": { "str": "Fey Vision" },
+- "points": 3,
+- "description": "The shadows don't seem as dark now. Activate to toggle NV-visible areas on or off.",
+- "prereqs": [ "ELFAEYES" ],
+- "changes_to": [ "ELFA_FNV" ],
+- "cancels": [ "LIZ_IR", "FEL_NV", "NIGHTVISION", "NIGHTVISION2", "NIGHTVISION3" ],
+- "category": [ "ELFA" ],
+- "active": true,
+- "starts_active": true,
+- "night_vision_range": 4.5
+- },
+- {
+- "type": "mutation",
+- "id": "ELFA_FNV",
+- "name": { "str": "Fey Nightsight" },
+- "points": 5,
+- "description": "You have great low-light vision now, though that doesn't allow you to perform fine tasks such as crafting and reading in darkness. Activate to toggle NV-visible areas on or off.",
+- "prereqs": [ "ELFA_NV" ],
+- "cancels": [ "LIZ_IR", "FEL_NV", "NIGHTVISION", "NIGHTVISION2", "NIGHTVISION3" ],
+- "category": [ "ELFA" ],
+- "active": true,
+- "starts_active": true,
+- "night_vision_range": 10
+- },
+ {
+ "type": "mutation",
+ "id": "FEL_EYE",
+@@ -1330,46 +1291,10 @@
+ "ugliness": 1,
+ "description": "Your eyes have mutated, now having a slitted pupil and glittering in light, much like those of cats. This is visually striking, but it isn't helping you see at night.",
+ "social_modifiers": { "lie": 2, "persuade": 2 },
+- "leads_to": [ "FEL_NV" ],
++ "prereqs": [ "NIGHTVISION" ],
+ "cancels": [ "ELFAEYES", "LIZ_EYE", "BIRD_EYE", "URSINE_EYE", "COMPOUND_EYES" ],
+ "category": [ "FELINE", "BEAST" ]
+ },
+- {
+- "type": "mutation",
+- "id": "FEL_NV",
+- "name": { "str": "Feline Vision" },
+- "points": 4,
+- "description": "Your optic nerves and brain caught up with your eyes. Now you can see pretty well at night. Activate to toggle NV-visible areas on or off.",
+- "prereqs": [ "FEL_EYE" ],
+- "cancels": [ "ELFA_NV", "ELFA_FNV", "LIZ_IR", "NIGHTVISION", "NIGHTVISION2", "NIGHTVISION3" ],
+- "category": [ "FELINE" ],
+- "active": true,
+- "starts_active": true,
+- "night_vision_range": 4.5
+- },
+- {
+- "type": "mutation",
+- "id": "URSINE_EYE",
+- "name": { "str": "Ursine Vision" },
+- "points": 1,
+- "description": "Your visual processing has shifted: though you can see better in the dark, you're nearsighted in the light. Maybe glasses would help. Activate to toggle NV-visible areas on or off.",
+- "cancels": [
+- "ELFAEYES",
+- "LIZ_EYE",
+- "BIRD_EYE",
+- "FEL_EYE",
+- "COMPOUND_EYES",
+- "NIGHTVISION",
+- "NIGHTVISION2",
+- "NIGHTVISION3",
+- "MYOPIC",
+- "HYPEROPIC"
+- ],
+- "category": [ "URSINE" ],
+- "active": true,
+- "starts_active": true,
+- "night_vision_range": 4.5
+- },
+ {
+ "type": "mutation",
+ "id": "BIRD_EYE",
+@@ -1378,7 +1303,7 @@
+ "visibility": 1,
+ "description": "Your vision has become particularly acute: you suspect you could pick out zombies much farther away. Perception +4.",
+ "cancels": [ "ELFAEYES", "FEL_EYE", "LIZ_EYE", "URSINE_EYE", "COMPOUND_EYES" ],
+- "prereqs": [ "PER_UP" ],
++ "prereqs": [ "PER_UP_2" ],
+ "threshreq": [ "THRESH_BIRD" ],
+ "category": [ "BIRD" ],
+ "passive_mods": { "per_mod": 4 }
+@@ -1391,7 +1316,8 @@
+ "description": "Your eyes have mutated to pick up radiation in the infrared spectrum.",
+ "prereqs": [ "NIGHTVISION3" ],
+ "cancels": [ "LIZ_IR" ],
+- "category": [ "INSECT", "TROGLOBITE", "SPIDER" ]
++ "category": [ "INSECT", "TROGLOBITE", "SPIDER" ],
++ "threshreq": [ "THRESH_INSECT", "THRESH_TROGLOBITE", "THRESH_SPIDER" ]
+ },
+ {
+ "type": "mutation",
+@@ -1425,7 +1351,7 @@
+ "types": [ "HEALING" ],
+ "prereqs": [ "FASTHEALER" ],
+ "changes_to": [ "REGEN" ],
+- "category": [ "PLANT" ],
++ "category": [ "PLANT", "LIZARD" ],
+ "healing_awake": 0.66,
+ "healing_resting": 0.5,
+ "mending_modifier": 4.0
+@@ -1452,7 +1378,7 @@
+ "purifiable": false,
+ "description": "Your broken limbs mend themselves without significant difficulty.",
+ "cancels": [ "ROT1", "ROT2", "ROT3" ],
+- "prereqs": [ "FASTHEALER" ],
++ "prereqs": [ "FASTHEALER2" ],
+ "threshreq": [ "THRESH_LIZARD" ],
+ "category": [ "LIZARD" ],
+ "mending_modifier": 20.0
+@@ -1790,7 +1716,7 @@
+ "points": 0,
+ "visibility": 4,
+ "ugliness": 1,
+- "bodytemp_modifiers": [ 300, 800 ],
++ "bodytemp_modifiers": [ 250, 800 ],
+ "bodytemp_sleep": 250,
+ "description": "You shan't need to migrate south with your layer of down. It's even better with no apes around to kill you for it!",
+ "types": [ "SKIN" ],
+@@ -1820,7 +1746,7 @@
+ "points": 1,
+ "visibility": 10,
+ "ugliness": 3,
+- "bodytemp_modifiers": [ 750, 1500 ],
++ "bodytemp_modifiers": [ 250, 1200 ],
+ "bodytemp_sleep": 500,
+ "description": "Thick black fur has grown to cover your entire body, providing a marginal protection against bashing attacks, and considerable protection from cold.",
+ "types": [ "SKIN" ],
+@@ -1836,7 +1762,7 @@
+ "points": 2,
+ "visibility": 10,
+ "ugliness": 3,
+- "bodytemp_modifiers": [ 750, 1500 ],
++ "bodytemp_modifiers": [ 250, 1200 ],
+ "bodytemp_sleep": 500,
+ "description": "Your fur has grown out and thickened, providing noticeable protection from bashing attacks as well as considerable insulation.",
+ "types": [ "SKIN" ],
+@@ -1851,7 +1777,7 @@
+ "points": 1,
+ "visibility": 10,
+ "ugliness": 3,
+- "bodytemp_modifiers": [ 750, 1500 ],
++ "bodytemp_modifiers": [ 250, 1200 ],
+ "bodytemp_sleep": 500,
+ "description": "Dense gray fur has grown to cover your entire body, providing a marginal protection against bashing attacks, and considerable protection from cold.",
+ "types": [ "SKIN" ],
+@@ -1866,7 +1792,7 @@
+ "points": 0,
+ "visibility": 10,
+ "ugliness": 3,
+- "bodytemp_modifiers": [ 500, 1000 ],
++ "bodytemp_modifiers": [ 250, 1000 ],
+ "bodytemp_sleep": 300,
+ "description": "You've grown sleek brown fur, providing some protection from cold.",
+ "types": [ "SKIN" ],
+@@ -2651,6 +2577,7 @@
+ "description": "Your eyes are compound, like those of an insect. This increases your Perception by 2 so long as you aren't wearing eyewear.",
+ "cancels": [ "ELFAEYES", "FEL_EYE", "URSINE_EYE", "BIRD_EYE", "LIZ_EYE" ],
+ "prereqs": [ "EYEBULGE" ],
++ "leads_to": [ "NIGHTVISION2" ],
+ "category": [ "INSECT" ]
+ },
+ {
+@@ -4294,7 +4221,8 @@
+ "description": "You're a real head-turner. Some people will react well to your appearance, and most people have an easier time trusting you.",
+ "cancels": [ "UGLY", "DEFORMED", "DEFORMED2", "DEFORMED3" ],
+ "prereqs": [ "PRETTY" ],
+- "changes_to": [ "BEAUTIFUL2" ]
++ "changes_to": [ "BEAUTIFUL2" ],
++ "category": [ "FELINE", "LUPINE" ]
+ },
+ {
+ "type": "mutation",
+@@ -4963,7 +4891,8 @@
+ "points": -3,
+ "description": "Your body's ability to digest meat is severely hampered. Eating meat has a good chance of making you vomit it back up; even if you manage to keep it down, its nutritional value is greatly reduced.",
+ "cancels": [ "CARNIVORE", "SAPROVORE", "ANTIFRUIT", "MEATARIAN" ],
+- "leads_to": [ "RUMINANT" ]
++ "leads_to": [ "RUMINANT" ],
++ "category": [ "CATTLE" ]
+ },
+ {
+ "type": "mutation",
+@@ -5515,7 +5444,7 @@
+ "points": -1,
+ "visibility": 10,
+ "ugliness": 3,
+- "bodytemp_modifiers": [ 500, 750 ],
++ "bodytemp_modifiers": [ 250, 750 ],
+ "bodytemp_sleep": 200,
+ "mixed_effect": true,
+ "description": "Your protective shell has grown large enough to accommodate--if need be--your whole body. Activate to pull your head and limbs into your shell, trading mobility and vision for warmth and shelter.",
+
+--- a/data/json/obsoletion/mutations.json
++++ b/data/json/obsoletion/mutations.json
+@@ -174,5 +174,80 @@
+ "points": -4,
+ "description": "Spending any amount of time in familiar places makes you miserable. Must. Keep. Moving.",
+ "valid": false
++ },
++ {
++ "type": "mutation",
++ "id": "ELFA_NV",
++ "name": { "str": "Fey Vision" },
++ "points": 3,
++ "description": "The shadows don't seem as dark now. Activate to toggle NV-visible areas on or off.",
++ "prereqs": [ "ELFAEYES" ],
++ "changes_to": [ "ELFA_FNV" ],
++ "cancels": [ "LIZ_IR", "FEL_NV", "NIGHTVISION", "NIGHTVISION2", "NIGHTVISION3" ],
++ "active": true,
++ "starts_active": true,
++ "valid": false,
++ "night_vision_range": 4.5
++ },
++ {
++ "type": "mutation",
++ "id": "ELFA_FNV",
++ "name": { "str": "Fey Nightsight" },
++ "points": 5,
++ "description": "You have great low-light vision now, though that doesn't allow you to perform fine tasks such as crafting and reading in darkness. Activate to toggle NV-visible areas on or off.",
++ "prereqs": [ "ELFA_NV" ],
++ "cancels": [ "LIZ_IR", "FEL_NV", "NIGHTVISION", "NIGHTVISION2", "NIGHTVISION3" ],
++ "active": true,
++ "starts_active": true,
++ "valid": false,
++ "night_vision_range": 10
++ },
++ {
++ "type": "mutation",
++ "id": "FEL_NV",
++ "name": { "str": "Feline Vision" },
++ "points": 4,
++ "description": "Your optic nerves and brain caught up with your eyes. Now you can see pretty well at night. Activate to toggle NV-visible areas on or off.",
++ "prereqs": [ "FEL_EYE" ],
++ "cancels": [ "ELFA_NV", "ELFA_FNV", "LIZ_IR", "NIGHTVISION", "NIGHTVISION2", "NIGHTVISION3" ],
++ "active": true,
++ "starts_active": true,
++ "valid": false,
++ "night_vision_range": 4.5
++ },
++ {
++ "type": "mutation",
++ "id": "CEPH_VISION",
++ "name": { "str": "Cephalopod Vision" },
++ "points": 3,
++ "description": "Your brain has caught up with your eyes. You can see much better in the dark, but sunlight seems much brighter now. Activate to toggle NV-visible areas on or off.",
++ "cancels": [ "LIZ_IR", "FEL_NV", "NIGHTVISION", "NIGHTVISION2", "NIGHTVISION3", "ELFA_NV", "ELFA_FNV" ],
++ "active": true,
++ "starts_active": true,
++ "valid": false,
++ "night_vision_range": 10
++ },
++ {
++ "type": "mutation",
++ "id": "URSINE_EYE",
++ "name": { "str": "Ursine Vision" },
++ "points": 1,
++ "description": "Your visual processing has shifted: though you can see better in the dark, you're nearsighted in the light. Maybe glasses would help. Activate to toggle NV-visible areas on or off.",
++ "cancels": [
++ "ELFAEYES",
++ "LIZ_EYE",
++ "BIRD_EYE",
++ "FEL_EYE",
++ "COMPOUND_EYES",
++ "NIGHTVISION",
++ "NIGHTVISION2",
++ "NIGHTVISION3",
++ "MYOPIC",
++ "HYPEROPIC"
++ ],
++ "valid": false,
++ "active": true,
++ "starts_active": true,
++ "night_vision_range": 4.5
+ },
+ {
+ "type": "mutation",
diff --git a/revert-04_telescopic-lenses.patch b/revert-04_telescopic-lenses.patch
new file mode 100644
index 0000000..6a31edb
--- /dev/null
+++ b/revert-04_telescopic-lenses.patch
@@ -0,0 +1,53 @@
+--- a/data/json/bionics.json
++++ b/data/json/bionics.json
+@@ -394,32 +394,10 @@
+ {
+ "id": "bio_eye_optic",
+ "type": "bionic",
+- "name": { "str": "Telescopic Eyes" },
+- "description": "Much of the material in your inner eye has been surgically removed and replaced with an array of high-powered, auto-focusing lenses. They function as integrated binoculars, letting you see much farther than before, and any vision problems you might have had are now gone.",
++ "name": { "str": "Telescopic Lenses" },
++ "description": "The lenses in your eyes have been surgically removed and replaced with an array of high-powered, auto-focusing lenses. They function as integrated binoculars, letting you see much farther than before, and any mundane vision problems you might have had are now gone.",
+ "occupied_bodyparts": [ [ "eyes", 2 ] ],
+- "canceled_mutations": [
+- "HYPEROPIC",
+- "MYOPIC",
+- "URSINE_EYE",
+- "NIGHTVISION3",
+- "NIGHTVISION2",
+- "NIGHTVISION",
+- "BIRD_EYE",
+- "COMPOUND_EYES",
+- "LIZ_IR",
+- "EAGLEEYED",
+- "CEPH_VISION",
+- "CEPH_EYES",
+- "ELFA_FNV",
+- "ELFA_NV",
+- "ELFAEYES",
+- "FEL_NV",
+- "FEL_EYE",
+- "INFRARED",
+- "LIZ_EYE",
+- "EYEBULGE",
+- "SEESLEEP"
+- ]
++ "canceled_mutations": [ "HYPEROPIC", "MYOPIC" ]
+ },
+ {
+ "id": "bio_face_mask",
+
+--- a/data/json/items/bionics.json
++++ b/data/json/items/bionics.json
+@@ -339,9 +339,9 @@
+ "id": "bio_eye_optic",
+ "copy-from": "bionic_general",
+ "type": "BIONIC_ITEM",
+- "name": { "str": "Telescopic Eyes CBM" },
++ "name": { "str": "Telescopic Lenses CBM" },
+ "looks_like": "bio_int_enhancer",
+- "description": "An array of high-powered, auto-focusing lenses that replaces much of the material in the inner eye. This fixes any vision problems and allows for an increased vision range akin to binoculars.",
++ "description": "An array of high-powered, auto-focusing lenses that replaces your natural lenses. This fixes any mundane vision problems and allows for an increased vision range akin to binoculars. Once installed they will be impossible to remove, having replaced part of your eyes.",
+ "price": "5 kUSD",
+ "weight": "100 g",
+ "difficulty": 5
diff --git a/revert-06_Obsolete-useless-hub01-basement-1457.patch b/revert-06_Obsolete-useless-hub01-basement-1457.patch
new file mode 100644
index 0000000..a214370
--- /dev/null
+++ b/revert-06_Obsolete-useless-hub01-basement-1457.patch
@@ -0,0 +1,1151 @@
+From 8c5a757dd08a7b8222a12f13972c00f551456259 Mon Sep 17 00:00:00 2001
+From: HoneyButterToast <103519677+HoneyButterToast@users.noreply.github.com>
+Date: Tue, 3 May 2022 05:48:08 +0200
+Subject: [PATCH 04/10] Obsolete useless hub01 basement (#1457)
+
+* Obsolete useless hub01 basement
+
+* turn off the elevator control
+
+* Obsolete NPC that doesn't spawn anymore
+
+* obsolete NPC that doesn't spawn
+---
+ data/json/mapgen/robofachq_static.json | 519 +-----------------
+ data/json/obsoletion/map.json | 519 ++++++++++++++++++
+ .../npc.json} | 0
+ .../overmap/overmap_special/specials.json | 50 --
+ 4 files changed, 520 insertions(+), 568 deletions(-)
+ create mode 100644 data/json/obsoletion/map.json
+ rename data/json/{npcs/robofac/NPC_Ulysses_Rourke.json => obsoletion/npc.json} (100%)
+
+diff --git a/data/json/mapgen/robofachq_static.json b/data/json/mapgen/robofachq_static.json
+index 93e999c36a..74d3c55ee5 100644
+--- a/data/json/mapgen/robofachq_static.json
++++ b/data/json/mapgen/robofachq_static.json
+@@ -98,7 +98,7 @@
+ "-": "t_wall_metal",
+ "G": "t_card_robofac",
+ "e": "t_elevator",
+- "E": "t_elevator_control",
++ "E": "t_elevator_control_off",
+ "Y": "t_utility_light",
+ "I": "t_intercom"
+ },
+@@ -109,522 +109,5 @@
+ },
+ "place_npcs": [ { "class": "robofac_intercom", "x": 46, "y": 17 } ]
+ }
+- },
+- {
+- "type": "mapgen",
+- "om_terrain": [
+- [ "robofachq_exe_a0", "robofachq_exe_a1", "robofachq_exe_a2", "robofachq_exe_a3" ],
+- [ "robofachq_exe_b0", "robofachq_exe_b1", "robofachq_exe_b2", "robofachq_exe_b3" ]
+- ],
+- "method": "json",
+- "object": {
+- "fill_ter": "t_thconc_floor",
+- "rows": [
+- "############################################| |############################################",
+- "########|||||||||||||||||||||||||#|||||||||||||22|||############################################",
+- "########|k ht|A h ^|#|lll|lllll| YY |############################################",
+- "########|i k k htth ht| Cd6ddC |#|bYb|bYbYb|T YY T|########||||||||############################",
+- "########|k o k htth ht| CCCCCC |#|b b|b b b|| YY ||######||=A6666A=||##########################",
+- "########| W ^|^ h ^|#|l l|l l l| YY |######|,=Y Y=,|##########################",
+- "########|FFFF| htth ?||||[[||||||l l|l l l|T YY T|######|,= htth =,|##########################",
+- "########|||||| htth ?||^^ ^^|| |||22||||||||||,= htth =,|##########################",
+- "########|ffff| 2 YY 2Y bbb bbbb| |L | i|,= htth =,|##########################",
+- "########| |^??t t??^| ,, ||||||||||||| |LY2 Y;|,= htth =,|##########################",
+- "###||||||hd ||||||||||| ,, 2 r r r| d( Y b|||||2||,= htth =,|##########################",
+- "###|;i|T|dd 2 2 (d r r r| Gd( Y b|AhQ ^|,= =,|##########################",
+- "###|@ 2Y2 | T T |G YY G(dh r| 2 Y b|ddd H|,[Y Y[,|##########################",
+- "###|||| |||||||||||||||||||22|||||||||||||||| ^| h ||||| |||||##########################",
+- "###|;i| |''''''''''''''''R R''''''''''''''( ^| YH|###|YY|##############################",
+- "###|@ 2Yh|''''''''''''''''R R''''''''''''''|||22|||====[=|||||22|||||||||||####################",
+- "###|||| t|''''''''''''''''R R''''''''''''''(< GY Y =,,,,,,,,|||||||||############",
+- "###|;i| h|''''''''''''''''R R''''''''''''''(> CC Y G=,,,,,,,,|^BB ^^|#|||||######",
+- "###|@ 2Y |''''''''''''''''R R'''''''|======|| CC ||(RRRRRRRR =======[=(YY CCC |||:::|######",
+- "###|||||||''''''''''''''''R R'''''''=Eeeeee2Y CC ^('''''''([( Y Y(H Cdd 5T Y|######",
+- "#########|''''''''''''''''RYYR'''''''=eeeeee2CCCC.dG('''''''R<( CCCCCCCCCC 2 C6C Y5 6|######",
+- "#########|''''''''''''''''RYYR'''''''=eeeeee2CCCC dh('''''''R>( CCCCCCCCCC 2 hCdh Y5 :|######",
+- "#########|''''''''''''''''R R'''''''=Eeeeee2Y CC ^('''''''([( Y Y( Cdd 5T Y|######",
+- "#########|''''''''''''''''R R'''''''|======|| CC ||(RRRRRRRR =======[=(YY CCC |||:::|######",
+- "#########|''''''''''''''''R R''''''''''''''(> CC Y G=,,,,,,,,|^ A ^|#|||||######",
+- "#########|''''''''''''''''R R''''''''''''''(< GY Y =,,,,,,,,||||55||||###########",
+- "#########|''''''''''''''''R R''''''''''''''|||22|||((2||||||||22|||||||||||^ ^|###########",
+- "#########|''''''''''''''''R R''''''''''''''( Y(dG L|L6dd|^YY^|::::::::| YY |###########",
+- "#########|====|====|=====||22||=======||||||| Y(dh 2 Yhd|^ ^| Y Y | htth |###########",
+- "#########| h ^|h B|h B| |A dh B|A dCCCCCCC ||||||||||||| ||[=======| htth |###########",
+- "#########|dd ^|dd B|dd B| |Bh6 ^| hdCCCCCCC 5Y |Wt| dh dh dh f| h tth |###########",
+- "#|||||||||^h Y|h Y^|h Y^| |B Y2 dCCCCCCC 5Y d d d f| htth |###########",
+- "#|iii |===[|==[=|===[=||YY|||||||||| ((((( d dh dh Y f| YY |###########",
+- "#|Y Y Y |Y ^ ^ ^ ^ Y(,,,(. dh d dY Y d d d Yf|^ ^|###########",
+- "#|2|2|2| |Y CCC Y(,,,[ dh dh dh f||||66||||###########",
+- "#|;|;|;|Y =========================t CCC (,,,[ dh d dY Yf|##||||##############",
+- "#|||||||Y [,,,,,,,,,,,,,,,,,,,,,,,=t CCC (,,,( d dh dh Y d d d f|||||||||||||########",
+- "#|;|;|;|Y =========================t cCC ((((( Y dh dh dh f|^^^^^^^^^^^|########",
+- "#|2|2|2| |YG CCC Y 5Y Y ^|########",
+- "#|Y Y Y |Y Y 5Y G Y ^|########",
+- "#|iii |====[[||=====|===[=|===[|[==||==[=||2||2|||[=======|| |||=====||||||2|||2||||########",
+- "#||||||||| ^| hd^|^ H| | |^ |f ff f| d dh dh| |Y Y^|;2Y | Y2;|########",
+- "#########|dd [ dh|h t|h h | | d |f ff f| dh d d | 2 hhhhh ^||| ||| |||########",
+- "#########| h [ hh |6dd H|ddd |6dd |hd |f ff f| Y Y| 2 ttttt ^|;2Y i|i Y2;|########",
+- "#########|dd dd|Y |h YB|Yh |Yhd |^ Y|f f| d d dh| | hhh h ^||| i|i |||########",
+- "#########|Yh h|BBBB^|^^BBB|A6^^| |BBBB|ffffff| dh d d |^^|Y h Y^|;2Y i|i Y2;|########",
+- "#########|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||########",
+- "################################################################################################"
+- ],
+- "palettes": [ "robofachq" ],
+- "terrain": {
+- ",": [ "t_shrub_rose", "t_shrub", "t_grass", "t_grass", "t_grass_tall" ],
+- "-": "t_wall_metal",
+- "'": "t_open_air",
+- "e": "t_elevator",
+- "C": "t_carpet_red",
+- "E": "t_elevator_control",
+- "Y": "t_thconc_floor_olight",
+- "#": "t_rock",
+- "6": "t_console",
+- "R": "t_railing",
+- "W": "t_water_dispenser"
+- },
+- "furniture": { ":": "f_server", "K": "f_counter", "H": "f_armchair", "L": "f_locker", "f": "f_filing_cabinet" },
+- "item": { "A": { "item": "american_flag" } },
+- "items": {
+- "F": { "item": "fridge", "chance": 80 },
+- "f": { "item": "file_room", "repeat": [ 10, 30 ] },
+- "@": { "item": "bed", "chance": 80 },
+- "r": [
+- { "item": "cop_armory", "chance": 80 },
+- { "item": "energy_weapon_armory", "chance": 33 },
+- { "item": "ammo_milspec", "chance": 40 },
+- { "item": "mags_milspec", "chance": 40 },
+- { "item": "guns_milspec", "chance": 40 }
+- ],
+- "L": [
+- { "item": "energy_weapon_armory", "chance": 33 },
+- { "item": "ammo_milspec", "chance": 40 },
+- { "item": "mags_milspec", "chance": 40 },
+- { "item": "guns_milspec", "chance": 40 }
+- ],
+- "K": { "item": "kitchen", "chance": 40 },
+- "o": { "item": "oven", "chance": 70 },
+- "d": [ { "item": "office_supplies", "chance": 70 }, { "item": "office_mess", "chance": 70, "repeat": [ 1, 3 ] } ],
+- "D": { "item": "NC_ROBOFAC_SCIENTIST_worn", "chance": 50 },
+- "B": [
+- { "item": "magazines", "chance": 75, "repeat": [ 1, 5 ] },
+- { "item": "lab_bookshelves", "chance": 55, "repeat": [ 1, 3 ] }
+- ]
+- },
+- "monster": { "T": { "monster": "mon_turret_light" } },
+- "npcs": { "G": { "class": "hub_security" }, "Q": { "class": "hub_security_head" } }
+- }
+- },
+- {
+- "type": "mapgen",
+- "om_terrain": [
+- [ "robofachq_hab_a0", "robofachq_hab_a1", "robofachq_hab_a2", "robofachq_hab_a3" ],
+- [ "robofachq_hab_b0", "robofachq_hab_b1", "robofachq_hab_b2", "robofachq_hab_b3" ]
+- ],
+- "method": "json",
+- "object": {
+- "fill_ter": "t_concrete",
+- "rows": [
+- "################################################################################################",
+- "################################||||||||||######################################################",
+- "################################|FFFF|FFF|######################################################",
+- "#############||||||||||||||||||||F F|F F||||#####||||||##||||||################################",
+- "#############|KiKKKKKiKooKKKK K|F F|F F|;Y|#####|~Y ~|##|~ Y~|################################",
+- "#############|K K YY o K|F F|F f|i |#####|| |||##||| ||################################",
+- "#############|k K iKKoK K K||2||||2|||2|||||||i 2;|##|;2 i|################################",
+- "#############| i i| Y Y Y|^^^^^|i |||##||| i|################################",
+- "#############|FFFFFFFF 2 | Y2;||||;2Y |||||############################",
+- "####|||||||||||||||||||YY|||||||||||||||||||||| ||2||||FF|||2||FFF|||||||||||||||||||||||######",
+- "####|,,,.| htth Yffff i|'''''''''''''''(Y Y|Y X X X EE|rrrrrrrrrrrrp|######",
+- "####|,,,,= htth Mi|'''''''''''''''(G CC | TT TT b CCC X X Y | p|######",
+- "####|,,,, ccccccff||||'''''''''''''''( CC | b CCC EE| c cccc p|######",
+- "####|,,,,= htth |WW|RRRRRRRRRRRRRRR| CC | TT TT b CCC X X Y | h6 p|######",
+- "####|,,,,= htth h Y CC |Y ^ ^ X X X EE|ccccYYcccc p|######",
+- "####|,,,,= htth hth Y RRRRRR CC ||=========||22||=======||||||22||||||||######",
+- "####|,,,,= ^| ,,,,,R'''R>YCC Y =,,,,,,,,|cccAYYApppppp|######",
+- "####|,,,,= htth htth htth ^|^bb^ ,,,,,R'''R<YCC Y =,,,,,,,,| A A p p P|######",
+- "####|,,,,= htth htth htth ^| ,,|======|| CC ||====[==== ========== hA A p p p|######",
+- "####|,,,,[Y =Eeeeee| CC ^=,,,,,,,=[( bb Y= ddA A p p p|######",
+- "####|,,,,=& ^MMM^ ^MMM^ Y [eeeeee[CCCC.dG=,,,,,,,= ( [ % % r|######",
+- "####|,,,,=& ^MMM^ ^MMM^ Y [eeeeee[CCCC dh=,,,,,,,=<( [ AAAA Y Y r|######",
+- "####|,,,,[Y =Eeeeee| CC ^=,,,,,,,=[( bb Y= A r|######",
+- "####|,,,,= htth htth hth h ^|G ,,|======|| CC ||====[==== ==========AAAA P P P P|######",
+- "####|,,,,= htth htth t ^|^bb^ ,,,,,R'''R<YCC Y G=,,,,,,,,|Y P P P P|######",
+- "####|,,,,= htth hth h ^| ,,,,,R'''R>YCC Y =,,,,,,,,|PPPPPPP P P P|######",
+- "####|,,,,= MM Y RRRRRR CC ||=========||22||========|||||||||||||||######",
+- "####|,,,,= MM Y CC |Y BB BB B|####################",
+- "####|,,,,= hth htth|WW|RRRRRRRRRRRRRRR| CC |htth hhh htth B|####################",
+- "####|,,,,= hth thht htth||||'''''''''''''''( CC |htth ttt ^^ htth B|####################",
+- "####|,,,,= hth thht htth|##|'''''''''''''''( CC |Y B B B|####################",
+- "#||||||||| hth YY htth|##|'''''''''''''''(Y Y|BBBBBBBBBBBBBBBBBBBBBBBB|####################",
+- "#|iii | |||||||||||||||||||||||||||||||||||22|||||||||||||||||||||||||||||||||||############",
+- "#|Y Y Y | ^|##|~Y;|~Y;|~Y;|~Y;|~Y;|~Y;|^ t ^ |~Y;|~Y;|~Y;|~Y;|~Y;|~Y;|~Y;|############",
+- "#|2|2|2| | ^|##|~ i|~ i|~ i|~ i|~ i|~ i|? a^ htth |~ i|~ i|~ i|~ i|~ i|~ i|~ i|||||||||||||",
+- "#|;|;|;|Y ^|##||2|||2|||2|||2|||2|||2||? t ^ htth ||2|||2|||2|||2|||2|||2|||2||~2 |@@ D @@|",
+- "#|||||||Y ^|##|@ D|@ D|@ D|@ D|@ D|@ D|? t a^ |@ D|@ D|@ D|@ D|@ D|@ D| D||| |D @ D|",
+- "#|;|;|;|Y|YY^|##|@ D|@ D|@ D|@ D|@ D|@ D| htth |@ D|@ D|@ D|@ D|@ D|@ D| D|~2 |@@ @ @@|",
+- "#|2|2|2| |||||||||5|||5|||5|||5|||5|||2||at a ||5|||5|||5|||5|||5|||5|||5||||2|D D|",
+- "#|Y Y Y |###|,,,=Y Y 2 S @@|",
+- "#|iii |###|,,,=Y Y 2 D|",
+- "#|||||||||###|||||5|||5|||5|||5|||5|||2||G ? t ?||5|||5|||5|||5|||5|||5|||5||||2| @@|",
+- "#############|##|@ D|@ D|@ D|@ D|@ D|@ D|^ h ? t ?|@ D|@ D|@ D|@ D|@ D|@ D|@ D|i |D D|",
+- "#############|##|@ D|@ D|@ D|@ D|@ D|@ D|t??t ^|@ D|@ D|@ D|@ D|@ D|@ D|@ D|i |@@ @ @@|",
+- "#############|##||2|||2|||2|||2|||2|||2||======[[======||2|||2|||2|||2|||2|||2|||2|| |D @ D|",
+- "#############|##|~ i|~ i|~ i|~ i|~ i|~ i|,,,,,,,,,,,,,,|~ i|~ i|~ i|~ i|~ i|~ i|~ i|2|2|@@ D @@|",
+- "#############|##|~Y;|~Y;|~Y;|~Y;|~Y;|~Y;|,,,,,,,,,,,,,,|~Y;|~Y;|~Y;|~Y;|~Y;|~Y;|~Y;|;|;|||||||||",
+- "#############|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||########"
+- ],
+- "palettes": [ "robofachq" ],
+- "terrain": {
+- ",": [ "t_shrub_rose", "t_shrub", "t_grass_tall" ],
+- "-": "t_wall_metal",
+- "'": "t_open_air",
+- "e": "t_elevator",
+- "C": "t_carpet_red",
+- "E": "t_elevator_control",
+- "Y": "t_thconc_floor_olight",
+- "#": "t_rock",
+- "6": "t_console",
+- "R": "t_railing",
+- "W": "t_water_dispenser",
+- "&": "t_machinery_electronic"
+- },
+- "furniture": {
+- "K": "f_counter",
+- "M": "f_counter",
+- "S": "f_table",
+- "A": "f_canvas_wall",
+- "%": "f_canvas_door",
+- "E": "f_ergometer",
+- "T": "f_treadmill",
+- "X": "f_exercise"
+- },
+- "sealed_item": {
+- "P": { "item": { "item": "seed_tomato" }, "furniture": "f_planter_mature" },
+- "p": { "item": { "item": "seed_wheat" }, "furniture": "f_planter_mature" }
+- },
+- "items": {
+- "S": [
+- { "item": "tools_robotics", "chance": 30, "repeat": [ 1, 3 ] },
+- { "item": "robots", "chance": 50, "repeat": [ 1, 3 ] },
+- { "item": "supplies_electronics", "chance": 50, "repeat": [ 1, 3 ] }
+- ],
+- "F": { "item": "fridge", "chance": 80, "repeat": [ 2, 6 ] },
+- "@": { "item": "bed", "chance": 80 },
+- "M": [
+- { "item": "SUS_dishes", "chance": 80, "repeat": [ 1, 3 ] },
+- { "item": "SUS_silverware", "chance": 33, "repeat": [ 1, 3 ] }
+- ],
+- "k": [
+- { "item": "kitchen", "chance": 33, "repeat": [ 1, 3 ] },
+- { "item": "SUS_knife_drawer", "chance": 40, "repeat": [ 1, 3 ] },
+- { "item": "SUS_cookware", "chance": 40, "repeat": [ 1, 3 ] }
+- ],
+- "K": { "item": "kitchen", "chance": 40 },
+- "o": { "item": "oven", "chance": 70 },
+- "d": [ { "item": "office_supplies", "chance": 70 }, { "item": "office_mess", "chance": 70, "repeat": [ 1, 3 ] } ],
+- "r": [ { "item": "tools_earthworking", "chance": 50 }, { "item": "supplies_farming", "chance": 70, "repeat": [ 1, 3 ] } ],
+- "D": { "item": "NC_ROBOFAC_SCIENTIST_worn", "chance": 50 },
+- "B": [
+- { "item": "magazines", "chance": 75, "repeat": [ 1, 5 ] },
+- { "item": "lab_bookshelves", "chance": 55, "repeat": [ 1, 3 ] }
+- ]
+- },
+- "npcs": { "G": { "class": "hub_security" } }
+- }
+- },
+- {
+- "type": "mapgen",
+- "om_terrain": [
+- [ "robofachq_res_a0", "robofachq_res_a1", "robofachq_res_a2", "robofachq_res_a3" ],
+- [ "robofachq_res_b0", "robofachq_res_b1", "robofachq_res_b2", "robofachq_res_b3" ]
+- ],
+- "method": "json",
+- "object": {
+- "fill_ter": "t_concrete",
+- "rows": [
+- "############################################| |#############################################",
+- "################################||||||||||##| |#############################################",
+- "################################|FFFF|FFF|##| |#############################################",
+- "#############||||||||||||||||||||F F|F F|||||222|||||||||||||||||||||||||||####################",
+- "#############| |^ ^| :|####################",
+- "#############| |^ ^| === === === === === :|####################",
+- "#############| |^ ^| =6= =6= =6= =6= =6= :|####################",
+- "#############| |^ ^| =2= =2= =2= =2= =2= :|####################",
+- "#############| AAAA |^ ^| :|####################",
+- "####||||||||||||||||||||||||||||YY||||||||||||222|| === === === === === :|||||||||||||||######",
+- "####|,,,.|SSSS6SSSS| h B|##|,,( (,,,,,,,,,( | =6= =6= =6= =6= =6= :|:::::::::::::|######",
+- "####|,,,,|S S|ddd B|##|,,( (,,,,,,,,,( | =2= =2= =2= =2= =2= :| :|######",
+- "####|,,,,|SSS SSSS| h B||||,,( (,,,,,,,,,( | :| 66 66 6 :|######",
+- "####|,,,,|====[====|=[===|YY|((( ((((((((((| | d d d d 2 66 66 6 :|######",
+- "####|,,,,= G Y | dh dh dh dh 2 :|######",
+- "####|,,,,= Y RRRRR ||====[==|||||||||||||||||2(||||||||||||######",
+- "####|,,,,= ||||||| (((((((( ======'''(> 2 G Y(:::::::::::::::| : : : : : |######",
+- "####|,,,,= = 666 = (''''''(^bb^ =,,,,='''(<Y Y2 Y('''''''''''''':| : : : : : |######",
+- "####|,,,,= = = (''''''( ==|======|||dd|| |===[==('''''''''''''':| Y Y Y Y|######",
+- "####|,,,,[ = hth = (''::''( d =Eeeeee| h|^ |6h ('''''''''''''':| : : : : : |######",
+- "####|,,,,= [ hth [ (''::''(Gd [eeeeee|6h |^ |6h h6(''''''MM''''''Y| 6: : : : : |######",
+- "####|,,,,= [ hth [ (''::''(hd [eeeeee|d |^ |6h h6(''''''MM''''''Y| 6: : : : : |######",
+- "####|,,,,[ = hth = (''::''( d =Eeeeee| Gh|^ |6h ('''''''''''''':| : : : : : |######",
+- "####|,,,,= = hth = (''''''( ==|======|||dd|| |===[==('''''''''''''':| Y Y Y Y|######",
+- "####|,,,,= = = (''''''(^bb^ =,,,,='''(<Y Y2 Y('''''''''''''':| : : : : : |######",
+- "####|,,,,= ======= (((((((( ======'''(> 2 G Y(:::::::::::::::| : : : : : |######",
+- "####|,,,,= RRRRRR ||=[=====|||||||||||||||||2(||||||||||||######",
+- "####|,,,,= |? [ 2 |#################",
+- "####|,,,,= |=[===|=[===|YY|((( ((((((((((|||||||? [ ( Y|#################",
+- "####|,,,,= |S S|s S||||,,( (,,,,,,,,,( ^|^ |[=======|===[|[====||||#################",
+- "####|,,,,= |S hS|S hS|##|,,( (,,,,,,,,,( hdhd|ddd | hhhh ^|h Y|Y h |####################",
+- "#||||||||| ||S6SSS|S6SSS|##|,,( (,,,,,,,,,( d6d| h | tttt 6|d6d | dd6|####################",
+- "#|iii | ^||||||||||||||||((|YY|(((((((((|[[|||| | hhhh | h | h|####################",
+- "#|Y Y Y | ^|lllll|^Y dh = dh^|Y B| |ffff|Y Y|BBBB|BBBBB|####################",
+- "#|2|2|2| | ^|l |B h6 [ d | hdhB|AAAAA||||||||||||||||||||||||||||||||||||||||||||||",
+- "#|;|;|;|Y |l ll |B d ^|||| ||2|Y d B|SSSSSSSS9S|SlllSSSS llSSSS SSS=YDSS SSS SSSll ll|",
+- "#|||||||Y ^|||||2|BY HtH| G|2|||||| hy|SY G Y= Y|",
+- "#|;|;|;|Y|YY^|S |||||||||| A Y|S SSSSS hS hS sh= |",
+- "#|2|2|2| |||||Sh SS6 SSS= y% Y|| SSSSS SS SS SS= SSS t 7966 6|",
+- "#|Y Y Y |###|S h [ Y% SSS Y2Y G [Y hSSS t 7966 6|",
+- "#|iii |###|S 2 66 A h6SS Y2Y G Y[Y 688 t Y|",
+- "#|||||||||###|||||2|========|[=====[=======|AA%AA|AAAAA||yyyyyyyyyyyyyyyyyy = 9 t &&66 6|",
+- "#############|l ll |Sh SSSS|h d| y6 y = 9 &&66 6|",
+- "#############|l l |SSSSS 6| hhdA y y =t8898888 7|",
+- "#############|l l|S hS| h hdA y y =Y 6 7|",
+- "#############|lllll|SSSSSYYll 6 llYYSSS|ddd h %Y y yY=t77 t7799988ttt777|",
+- "#############|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||",
+- "################################################################################################"
+- ],
+- "palettes": [ "robofachq" ],
+- "terrain": {
+- ",": [ "t_shrub_rose", "t_shrub", "t_grass_tall" ],
+- "-": "t_wall_metal",
+- "'": "t_open_air",
+- "e": "t_elevator",
+- "C": "t_carpet_red",
+- "E": "t_elevator_control",
+- "Y": "t_thconc_floor_olight",
+- "#": "t_rock",
+- "6": "t_console",
+- "R": "t_railing",
+- "9": "t_conveyor",
+- "7": "t_machinery_light",
+- "8": "t_machinery_heavy",
+- "&": "t_machinery_electronic"
+- },
+- "furniture": {
+- ":": "f_server",
+- "K": "f_counter",
+- "S": "f_table",
+- "A": "f_canvas_wall",
+- "%": "f_canvas_door",
+- "H": "f_armchair",
+- "M": "f_server",
+- "E": "f_ergometer",
+- "T": "f_treadmill",
+- "X": "f_exercise"
+- },
+- "items": {
+- "S": [
+- { "item": "tools_robotics", "chance": 30, "repeat": [ 1, 3 ] },
+- { "item": "robots", "chance": 50, "repeat": [ 1, 3 ] },
+- { "item": "supplies_electronics", "chance": 50, "repeat": [ 1, 3 ] }
+- ],
+- "d": [ { "item": "office_supplies", "chance": 70 }, { "item": "office_mess", "chance": 70, "repeat": [ 1, 3 ] } ],
+- "B": [
+- { "item": "magazines", "chance": 75, "repeat": [ 1, 5 ] },
+- { "item": "lab_bookshelves", "chance": 55, "repeat": [ 1, 3 ] }
+- ]
+- },
+- "npcs": { "G": { "class": "hub_security" } }
+- }
+- },
+- {
+- "type": "mapgen",
+- "om_terrain": [ [ "robofachq_sub_a0", "robofachq_sub_a1", "robofachq_sub_a2", "robofachq_sub_a3" ] ],
+- "method": "json",
+- "object": {
+- "fill_ter": "t_thconc_floor",
+- "rows": [
+- "#######################| ||||||||||||||####################################",
+- "#######################|Y Y (tt ^|####################################",
+- "#######################| bb bbb bb (th |####################################",
+- "#######################| (t |####################################",
+- "#######################|Y ^bb^ ^bbb^ ^bb Y (t ^|####################################",
+- "#######################|||||||||||||||||||||||| |||2|||####################################",
+- "##############################################||5555||tt tt|####################################",
+- "#####################################||||||||||^ ^| h h|####################################",
+- "#####################################|rrrrrrrr|^ ^| |####################################",
+- "#####################################|r r|| ||||2|||####################################",
+- "#####################################|r YY 2 (t r|####################################",
+- "#####################################|||||||||| YY (thY r|####################################",
+- "#####################################|bbbbbbbb| YY (t Y r|####################################",
+- "#####################################|Y Y2 ( r|####################################",
+- "#####################################| llllll ||2222||||2|||####################################",
+- "#####################################|2||||||2|^ Y^|####################################",
+- "#####################################| ~| |~ |^ Y^|####################################",
+- "#####################################| i| |i |^ Y^|####################################",
+- "#####################################||||||||||| ||||||||####################################",
+- "#####################################|lll 2 ^|##########################################",
+- "#####################################|^ ( YY ^|##########################################",
+- "#####################################| d ( YY ^|##########################################",
+- "#####################################|^hdh ( ^|##########################################",
+- "#####################################|||||||| ||||##########################################"
+- ],
+- "palettes": [ "robofachq" ],
+- "terrain": { "-": "t_wall_metal", "e": "t_elevator", "E": "t_elevator_control", "Y": "t_utility_light", "I": "t_intercom" },
+- "items": {
+- "l": [ { "item": "NC_ROBOFAC_FIELD_RESEARCHER_worn", "chance": 50 }, { "item": "NC_ROBOFAC_SCIENTIST_worn", "chance": 50 } ],
+- "i": { "item": "cleaning", "chance": 50 },
+- "B": [ { "item": "textbooks", "chance": 50 }, { "item": "manuals", "chance": 50 } ]
+- }
+- }
+- },
+- {
+- "type": "mapgen",
+- "om_terrain": [
+- [ "robofachq_ai_a0", "robofachq_ai_a1", "robofachq_ai_a2", "robofachq_ai_a3" ],
+- [ "robofachq_ai_b0", "robofachq_ai_b1", "robofachq_ai_b2", "robofachq_ai_b3" ]
+- ],
+- "method": "json",
+- "object": {
+- "fill_ter": "t_thconc_floor",
+- "rows": [
+- "################################################################################################",
+- "################################################################################################",
+- "################################################################################################",
+- "################################################################################################",
+- "################################################################################################",
+- "################################################################################################",
+- "################################################################################################",
+- "######################################################|||||||||||||||||||||||||||||||||||||||||#",
+- "######################################################|:YY:YY:YY:YY:YY:YY:YY:| rrrrrrrrrrr|#",
+- "######################################################|: : : : : : : :| Y|#",
+- "######################################################|: : : : : : : :| rrr rrrr |#",
+- "######################################################|: : : : : : : :| Y|#",
+- "###################################################||||: : : : : : : :| rrrrrrrrrrr|#",
+- "############################################||||||||YY|: : : : : : : :||5(((||||||||||||#",
+- "############################################| 5 5 Y2>|##########",
+- "############################################| 5 5 Y Y Y Y Y Y |||||||2|||##########",
+- "############################################| Y||||((((((((((((((((((((|6 |############",
+- "############################################| 5 (````````````````````||Y |||||||######",
+- "#####################################|||||||| |5(````````````````````6|: ::::::|######",
+- "#####################################|eeeeee d | (((((((((((``````````6|||| :|######",
+- "#####################################|eeeeee Y d | h6``````````6|: Y 6 :|######",
+- "#####################################|Eeeeee Y 6h| h6``````````6|: Y 6 :|######",
+- "#####################################|eeeeee d | (((((((((((``````````6|||| :|######",
+- "#####################################|||||||| |5(````````````````````6|: ::::::|######",
+- "########################################|>< 5 5 (````````````````````||Y |||||||######",
+- "########################################| | ||||((((((((((((((((((((|6 |############",
+- "########################################||||| 5 5 Y Y Y Y Y Y |||||||2|||##########",
+- "############################################| 5 5 Y2>|##########",
+- "############################################||||||||YY|: : : : : : : :||5(((||||||||||||#",
+- "###################################################||||: : : : : : : :| rrrrrrrrrrr|#",
+- "######################################################|: : : : : : : :| Y|#",
+- "######################################################|: : : : : : : :| rrr rrrr |#",
+- "######################################################|: : : : : : : :| Y|#",
+- "######################################################|:YY:YY:YY:YY:YY:YY:YY:| rrrrrrrrrrr|#",
+- "######################################################|||||||||||||||||||||||||||||||||||||||||#",
+- "################################################################################################",
+- "################################################################################################",
+- "################################################################################################",
+- "################################################################################################",
+- "################################################################################################",
+- "################################################################################################",
+- "################################################################################################",
+- "################################################################################################",
+- "################################################################################################",
+- "################################################################################################",
+- "################################################################################################",
+- "################################################################################################",
+- "################################################################################################"
+- ],
+- "palettes": [ "robofachq" ],
+- "terrain": {
+- "-": "t_wall_metal",
+- "e": "t_elevator",
+- "E": "t_elevator_control",
+- "Y": "t_thconc_floor_olight",
+- "#": "t_rock",
+- "6": "t_console"
+- },
+- "furniture": { ":": "f_server", "K": "f_counter" },
+- "items": { "r": [ { "item": "electronics", "chance": 75, "repeat": [ 1, 5 ] } ] }
+- }
+- },
+- {
+- "type": "mapgen",
+- "om_terrain": [
+- [ "robofachq_aiutl_a0", "robofachq_aiutl_a1", "robofachq_aiutl_a2", "robofachq_aiutl_a3" ],
+- [ "robofachq_aiutl_b0", "robofachq_aiutl_b1", "robofachq_aiutl_b2", "robofachq_aiutl_b3" ]
+- ],
+- "method": "json",
+- "object": {
+- "fill_ter": "t_thconc_floor",
+- "rows": [
+- "################################################################################################",
+- "################################################################################################",
+- "################################################################################################",
+- "################################################################################################",
+- "##############################################||||##############################################",
+- "##############################################|66|##############################################",
+- "##############################################| |##############################################",
+- "###########################|||||||||||||||||||| ||||||||||||||||||||||||||||||||||||||||||||||#",
+- "###########################|::::::::::::::::|B d ^|: : : : : : : :| :::::::::::|#",
+- "###########################| :|B Y h dh |: : : : : : : :| |#",
+- "###########################| :|B Y dd |YYYYYYYYYYYYYYYYYYYYYY| ::: :::::|#",
+- "###########################| :|B |: : : : : : : :| |#",
+- "###########################|:::::::: ||||||55||^||||: : : : : : : :| :::::::::::|#",
+- "###########################| 5 Y ||| |||||||||||||||||||||||||5(((||||||||||||#",
+- "###########################|::::::::::::| Y 5 5 2<|##########",
+- "###########################|||||||||||||||||| 5 5 Y Y Y Y Y Y |||||||2|||##########",
+- "############################################||55|||||||((((((((((((((((((((|6 |############",
+- "############################################| 5wwwwwwwwwwwwwwwwwwwwww||Y |||||||######",
+- "#####################################|||||||| |wwwwwwwwwwwwwwwwwwwwww:|: ::::::|######",
+- "#####################################|eeeeee (wwwwwwwwwwwwwwwwwwwwww:|||| :|######",
+- "#####################################|eeeeee Y (wwwwwwwwwwwwwwwwwwwwww:|: 6 :|######",
+- "#####################################|Eeeeee Y (wwwwwwwwwwwwwwwwwwwwww:|: 6 :|######",
+- "#####################################|eeeeee (wwwwwwwwwwwwwwwwwwwwww:|||| :|######",
+- "#####################################|||||||| |wwwwwwwwwwwwwwwwwwwwww:|: ::::::|######",
+- "########################################|>< 5 5wwwwwwwwwwwwwwwwwwwwww||Y |||||||######",
+- "########################################| ||55|||||||((((((((((((((((((((|6 |############",
+- "#############################|||||||||||||||| 5 5 Y Y Y Y Y Y ||2||||2|||##########",
+- "#############################|^ Y 5 5 | 2<|##########",
+- "#############################|^ Y ||| ||||||||||||||22|||||||||5(((||||||||||||#",
+- "#############################||2|2((((|(((2|||222||||||:::| : : : : : :| :::::::::::|#",
+- "#############################|i | |h B| |:::: | : : : : : :| |#",
+- "#############################|; | dd|dd B| Y 5 Y 2YYYYYYYYYYYYYYYYY:| :::: :::::|#",
+- "#############################|||| |h B| Y | | : : : : : :| |#",
+- "################################| h| ^|2||| |||2||:::| : : : : : :| :::::::::::|#",
+- "################################|2|||||||| |555||Y :|||||||||||||| |||||||||22||||||||||||||#",
+- "################################| ( | |:Y :|############| |#######| |: : : : : :|#",
+- "################################| cccc 2 2 ||2|||||||||||||||| ||||||||| |: : : : : :|#",
+- "################################| ||||| | |::::::::::::| 2 2 |#",
+- "################################| cccc | 2 2 |#",
+- "################################| 2 |||||||||||||||||#",
+- "################################| ccccccccc ||||| |||||||||||||||| |||||||||#################",
+- "################################| |###| :::::::::::::: :|######################",
+- "################################||||||||||||||###| 6 :|######################",
+- "#################################################| 6 :|######################",
+- "#################################################| :::::::::::::: :|######################",
+- "#################################################|||||||||||||||||||||||||######################",
+- "################################################################################################",
+- "################################################################################################"
+- ],
+- "palettes": [ "robofachq" ],
+- "terrain": {
+- "-": "t_wall_metal",
+- "e": "t_elevator",
+- "w": "t_water_pool_shallow",
+- "E": "t_elevator_control",
+- "Y": "t_thconc_floor_olight",
+- "#": "t_rock",
+- "6": "t_console"
+- },
+- "furniture": { ":": "f_server" },
+- "items": {
+- "B": [
+- { "item": "magazines", "chance": 75, "repeat": [ 1, 5 ] },
+- { "item": "lab_bookshelves", "chance": 55, "repeat": [ 1, 3 ] }
+- ]
+- }
+- }
+ }
+ ]
+--- a/data/json/obsoletion/map.json
++++ b/data/json/obsoletion/map.json
+@@ -1,6 +1,523 @@
+ [
+ {
+ "type": "mapgen",
++ "om_terrain": [
++ [ "robofachq_exe_a0", "robofachq_exe_a1", "robofachq_exe_a2", "robofachq_exe_a3" ],
++ [ "robofachq_exe_b0", "robofachq_exe_b1", "robofachq_exe_b2", "robofachq_exe_b3" ]
++ ],
++ "method": "json",
++ "object": {
++ "fill_ter": "t_thconc_floor",
++ "rows": [
++ "############################################| |############################################",
++ "########|||||||||||||||||||||||||#|||||||||||||22|||############################################",
++ "########|k ht|A h ^|#|lll|lllll| YY |############################################",
++ "########|i k k htth ht| Cd6ddC |#|bYb|bYbYb|T YY T|########||||||||############################",
++ "########|k o k htth ht| CCCCCC |#|b b|b b b|| YY ||######||=A6666A=||##########################",
++ "########| W ^|^ h ^|#|l l|l l l| YY |######|,=Y Y=,|##########################",
++ "########|FFFF| htth ?||||[[||||||l l|l l l|T YY T|######|,= htth =,|##########################",
++ "########|||||| htth ?||^^ ^^|| |||22||||||||||,= htth =,|##########################",
++ "########|ffff| 2 YY 2Y bbb bbbb| |L | i|,= htth =,|##########################",
++ "########| |^??t t??^| ,, ||||||||||||| |LY2 Y;|,= htth =,|##########################",
++ "###||||||hd ||||||||||| ,, 2 r r r| d( Y b|||||2||,= htth =,|##########################",
++ "###|;i|T|dd 2 2 (d r r r| Gd( Y b|AhQ ^|,= =,|##########################",
++ "###|@ 2Y2 | T T |G YY G(dh r| 2 Y b|ddd H|,[Y Y[,|##########################",
++ "###|||| |||||||||||||||||||22|||||||||||||||| ^| h ||||| |||||##########################",
++ "###|;i| |''''''''''''''''R R''''''''''''''( ^| YH|###|YY|##############################",
++ "###|@ 2Yh|''''''''''''''''R R''''''''''''''|||22|||====[=|||||22|||||||||||####################",
++ "###|||| t|''''''''''''''''R R''''''''''''''(< GY Y =,,,,,,,,|||||||||############",
++ "###|;i| h|''''''''''''''''R R''''''''''''''(> CC Y G=,,,,,,,,|^BB ^^|#|||||######",
++ "###|@ 2Y |''''''''''''''''R R'''''''|======|| CC ||(RRRRRRRR =======[=(YY CCC |||:::|######",
++ "###|||||||''''''''''''''''R R'''''''=Eeeeee2Y CC ^('''''''([( Y Y(H Cdd 5T Y|######",
++ "#########|''''''''''''''''RYYR'''''''=eeeeee2CCCC.dG('''''''R<( CCCCCCCCCC 2 C6C Y5 6|######",
++ "#########|''''''''''''''''RYYR'''''''=eeeeee2CCCC dh('''''''R>( CCCCCCCCCC 2 hCdh Y5 :|######",
++ "#########|''''''''''''''''R R'''''''=Eeeeee2Y CC ^('''''''([( Y Y( Cdd 5T Y|######",
++ "#########|''''''''''''''''R R'''''''|======|| CC ||(RRRRRRRR =======[=(YY CCC |||:::|######",
++ "#########|''''''''''''''''R R''''''''''''''(> CC Y G=,,,,,,,,|^ A ^|#|||||######",
++ "#########|''''''''''''''''R R''''''''''''''(< GY Y =,,,,,,,,||||55||||###########",
++ "#########|''''''''''''''''R R''''''''''''''|||22|||((2||||||||22|||||||||||^ ^|###########",
++ "#########|''''''''''''''''R R''''''''''''''( Y(dG L|L6dd|^YY^|::::::::| YY |###########",
++ "#########|====|====|=====||22||=======||||||| Y(dh 2 Yhd|^ ^| Y Y | htth |###########",
++ "#########| h ^|h B|h B| |A dh B|A dCCCCCCC ||||||||||||| ||[=======| htth |###########",
++ "#########|dd ^|dd B|dd B| |Bh6 ^| hdCCCCCCC 5Y |Wt| dh dh dh f| h tth |###########",
++ "#|||||||||^h Y|h Y^|h Y^| |B Y2 dCCCCCCC 5Y d d d f| htth |###########",
++ "#|iii |===[|==[=|===[=||YY|||||||||| ((((( d dh dh Y f| YY |###########",
++ "#|Y Y Y |Y ^ ^ ^ ^ Y(,,,(. dh d dY Y d d d Yf|^ ^|###########",
++ "#|2|2|2| |Y CCC Y(,,,[ dh dh dh f||||66||||###########",
++ "#|;|;|;|Y =========================t CCC (,,,[ dh d dY Yf|##||||##############",
++ "#|||||||Y [,,,,,,,,,,,,,,,,,,,,,,,=t CCC (,,,( d dh dh Y d d d f|||||||||||||########",
++ "#|;|;|;|Y =========================t cCC ((((( Y dh dh dh f|^^^^^^^^^^^|########",
++ "#|2|2|2| |YG CCC Y 5Y Y ^|########",
++ "#|Y Y Y |Y Y 5Y G Y ^|########",
++ "#|iii |====[[||=====|===[=|===[|[==||==[=||2||2|||[=======|| |||=====||||||2|||2||||########",
++ "#||||||||| ^| hd^|^ H| | |^ |f ff f| d dh dh| |Y Y^|;2Y | Y2;|########",
++ "#########|dd [ dh|h t|h h | | d |f ff f| dh d d | 2 hhhhh ^||| ||| |||########",
++ "#########| h [ hh |6dd H|ddd |6dd |hd |f ff f| Y Y| 2 ttttt ^|;2Y i|i Y2;|########",
++ "#########|dd dd|Y |h YB|Yh |Yhd |^ Y|f f| d d dh| | hhh h ^||| i|i |||########",
++ "#########|Yh h|BBBB^|^^BBB|A6^^| |BBBB|ffffff| dh d d |^^|Y h Y^|;2Y i|i Y2;|########",
++ "#########|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||########",
++ "################################################################################################"
++ ],
++ "palettes": [ "robofachq" ],
++ "terrain": {
++ ",": [ "t_shrub_rose", "t_shrub", "t_grass", "t_grass", "t_grass_tall" ],
++ "-": "t_wall_metal",
++ "'": "t_open_air",
++ "e": "t_elevator",
++ "C": "t_carpet_red",
++ "E": "t_elevator_control",
++ "Y": "t_thconc_floor_olight",
++ "#": "t_rock",
++ "6": "t_console",
++ "R": "t_railing",
++ "W": "t_water_dispenser"
++ },
++ "furniture": { ":": "f_server", "K": "f_counter", "H": "f_armchair", "L": "f_locker", "f": "f_filing_cabinet" },
++ "item": { "A": { "item": "american_flag" } },
++ "items": {
++ "F": { "item": "fridge", "chance": 80 },
++ "f": { "item": "file_room", "repeat": [ 10, 30 ] },
++ "@": { "item": "bed", "chance": 80 },
++ "r": [
++ { "item": "cop_armory", "chance": 80 },
++ { "item": "energy_weapon_armory", "chance": 33 },
++ { "item": "ammo_milspec", "chance": 40 },
++ { "item": "mags_milspec", "chance": 40 },
++ { "item": "guns_milspec", "chance": 40 }
++ ],
++ "L": [
++ { "item": "energy_weapon_armory", "chance": 33 },
++ { "item": "ammo_milspec", "chance": 40 },
++ { "item": "mags_milspec", "chance": 40 },
++ { "item": "guns_milspec", "chance": 40 }
++ ],
++ "K": { "item": "kitchen", "chance": 40 },
++ "o": { "item": "oven", "chance": 70 },
++ "d": [ { "item": "office_supplies", "chance": 70 }, { "item": "office_mess", "chance": 70, "repeat": [ 1, 3 ] } ],
++ "D": { "item": "NC_ROBOFAC_SCIENTIST_worn", "chance": 50 },
++ "B": [
++ { "item": "magazines", "chance": 75, "repeat": [ 1, 5 ] },
++ { "item": "lab_bookshelves", "chance": 55, "repeat": [ 1, 3 ] }
++ ]
++ },
++ "monster": { "T": { "monster": "mon_turret_light" } },
++ "npcs": { "G": { "class": "hub_security" }, "Q": { "class": "hub_security_head" } }
++ }
++ },
++ {
++ "type": "mapgen",
++ "om_terrain": [
++ [ "robofachq_hab_a0", "robofachq_hab_a1", "robofachq_hab_a2", "robofachq_hab_a3" ],
++ [ "robofachq_hab_b0", "robofachq_hab_b1", "robofachq_hab_b2", "robofachq_hab_b3" ]
++ ],
++ "method": "json",
++ "object": {
++ "fill_ter": "t_concrete",
++ "rows": [
++ "################################################################################################",
++ "################################||||||||||######################################################",
++ "################################|FFFF|FFF|######################################################",
++ "#############||||||||||||||||||||F F|F F||||#####||||||##||||||################################",
++ "#############|KiKKKKKiKooKKKK K|F F|F F|;Y|#####|~Y ~|##|~ Y~|################################",
++ "#############|K K YY o K|F F|F f|i |#####|| |||##||| ||################################",
++ "#############|k K iKKoK K K||2||||2|||2|||||||i 2;|##|;2 i|################################",
++ "#############| i i| Y Y Y|^^^^^|i |||##||| i|################################",
++ "#############|FFFFFFFF 2 | Y2;||||;2Y |||||############################",
++ "####|||||||||||||||||||YY|||||||||||||||||||||| ||2||||FF|||2||FFF|||||||||||||||||||||||######",
++ "####|,,,.| htth Yffff i|'''''''''''''''(Y Y|Y X X X EE|rrrrrrrrrrrrp|######",
++ "####|,,,,= htth Mi|'''''''''''''''(G CC | TT TT b CCC X X Y | p|######",
++ "####|,,,, ccccccff||||'''''''''''''''( CC | b CCC EE| c cccc p|######",
++ "####|,,,,= htth |WW|RRRRRRRRRRRRRRR| CC | TT TT b CCC X X Y | h6 p|######",
++ "####|,,,,= htth h Y CC |Y ^ ^ X X X EE|ccccYYcccc p|######",
++ "####|,,,,= htth hth Y RRRRRR CC ||=========||22||=======||||||22||||||||######",
++ "####|,,,,= ^| ,,,,,R'''R>YCC Y =,,,,,,,,|cccAYYApppppp|######",
++ "####|,,,,= htth htth htth ^|^bb^ ,,,,,R'''R<YCC Y =,,,,,,,,| A A p p P|######",
++ "####|,,,,= htth htth htth ^| ,,|======|| CC ||====[==== ========== hA A p p p|######",
++ "####|,,,,[Y =Eeeeee| CC ^=,,,,,,,=[( bb Y= ddA A p p p|######",
++ "####|,,,,=& ^MMM^ ^MMM^ Y [eeeeee[CCCC.dG=,,,,,,,= ( [ % % r|######",
++ "####|,,,,=& ^MMM^ ^MMM^ Y [eeeeee[CCCC dh=,,,,,,,=<( [ AAAA Y Y r|######",
++ "####|,,,,[Y =Eeeeee| CC ^=,,,,,,,=[( bb Y= A r|######",
++ "####|,,,,= htth htth hth h ^|G ,,|======|| CC ||====[==== ==========AAAA P P P P|######",
++ "####|,,,,= htth htth t ^|^bb^ ,,,,,R'''R<YCC Y G=,,,,,,,,|Y P P P P|######",
++ "####|,,,,= htth hth h ^| ,,,,,R'''R>YCC Y =,,,,,,,,|PPPPPPP P P P|######",
++ "####|,,,,= MM Y RRRRRR CC ||=========||22||========|||||||||||||||######",
++ "####|,,,,= MM Y CC |Y BB BB B|####################",
++ "####|,,,,= hth htth|WW|RRRRRRRRRRRRRRR| CC |htth hhh htth B|####################",
++ "####|,,,,= hth thht htth||||'''''''''''''''( CC |htth ttt ^^ htth B|####################",
++ "####|,,,,= hth thht htth|##|'''''''''''''''( CC |Y B B B|####################",
++ "#||||||||| hth YY htth|##|'''''''''''''''(Y Y|BBBBBBBBBBBBBBBBBBBBBBBB|####################",
++ "#|iii | |||||||||||||||||||||||||||||||||||22|||||||||||||||||||||||||||||||||||############",
++ "#|Y Y Y | ^|##|~Y;|~Y;|~Y;|~Y;|~Y;|~Y;|^ t ^ |~Y;|~Y;|~Y;|~Y;|~Y;|~Y;|~Y;|############",
++ "#|2|2|2| | ^|##|~ i|~ i|~ i|~ i|~ i|~ i|? a^ htth |~ i|~ i|~ i|~ i|~ i|~ i|~ i|||||||||||||",
++ "#|;|;|;|Y ^|##||2|||2|||2|||2|||2|||2||? t ^ htth ||2|||2|||2|||2|||2|||2|||2||~2 |@@ D @@|",
++ "#|||||||Y ^|##|@ D|@ D|@ D|@ D|@ D|@ D|? t a^ |@ D|@ D|@ D|@ D|@ D|@ D| D||| |D @ D|",
++ "#|;|;|;|Y|YY^|##|@ D|@ D|@ D|@ D|@ D|@ D| htth |@ D|@ D|@ D|@ D|@ D|@ D| D|~2 |@@ @ @@|",
++ "#|2|2|2| |||||||||5|||5|||5|||5|||5|||2||at a ||5|||5|||5|||5|||5|||5|||5||||2|D D|",
++ "#|Y Y Y |###|,,,=Y Y 2 S @@|",
++ "#|iii |###|,,,=Y Y 2 D|",
++ "#|||||||||###|||||5|||5|||5|||5|||5|||2||G ? t ?||5|||5|||5|||5|||5|||5|||5||||2| @@|",
++ "#############|##|@ D|@ D|@ D|@ D|@ D|@ D|^ h ? t ?|@ D|@ D|@ D|@ D|@ D|@ D|@ D|i |D D|",
++ "#############|##|@ D|@ D|@ D|@ D|@ D|@ D|t??t ^|@ D|@ D|@ D|@ D|@ D|@ D|@ D|i |@@ @ @@|",
++ "#############|##||2|||2|||2|||2|||2|||2||======[[======||2|||2|||2|||2|||2|||2|||2|| |D @ D|",
++ "#############|##|~ i|~ i|~ i|~ i|~ i|~ i|,,,,,,,,,,,,,,|~ i|~ i|~ i|~ i|~ i|~ i|~ i|2|2|@@ D @@|",
++ "#############|##|~Y;|~Y;|~Y;|~Y;|~Y;|~Y;|,,,,,,,,,,,,,,|~Y;|~Y;|~Y;|~Y;|~Y;|~Y;|~Y;|;|;|||||||||",
++ "#############|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||########"
++ ],
++ "palettes": [ "robofachq" ],
++ "terrain": {
++ ",": [ "t_shrub_rose", "t_shrub", "t_grass_tall" ],
++ "-": "t_wall_metal",
++ "'": "t_open_air",
++ "e": "t_elevator",
++ "C": "t_carpet_red",
++ "E": "t_elevator_control",
++ "Y": "t_thconc_floor_olight",
++ "#": "t_rock",
++ "6": "t_console",
++ "R": "t_railing",
++ "W": "t_water_dispenser",
++ "&": "t_machinery_electronic"
++ },
++ "furniture": {
++ "K": "f_counter",
++ "M": "f_counter",
++ "S": "f_table",
++ "A": "f_canvas_wall",
++ "%": "f_canvas_door",
++ "E": "f_ergometer",
++ "T": "f_treadmill",
++ "X": "f_exercise"
++ },
++ "sealed_item": {
++ "P": { "item": { "item": "seed_tomato" }, "furniture": "f_planter_mature" },
++ "p": { "item": { "item": "seed_wheat" }, "furniture": "f_planter_mature" }
++ },
++ "items": {
++ "S": [
++ { "item": "tools_robotics", "chance": 30, "repeat": [ 1, 3 ] },
++ { "item": "robots", "chance": 50, "repeat": [ 1, 3 ] },
++ { "item": "supplies_electronics", "chance": 50, "repeat": [ 1, 3 ] }
++ ],
++ "F": { "item": "fridge", "chance": 80, "repeat": [ 2, 6 ] },
++ "@": { "item": "bed", "chance": 80 },
++ "M": [
++ { "item": "SUS_dishes", "chance": 80, "repeat": [ 1, 3 ] },
++ { "item": "SUS_silverware", "chance": 33, "repeat": [ 1, 3 ] }
++ ],
++ "k": [
++ { "item": "kitchen", "chance": 33, "repeat": [ 1, 3 ] },
++ { "item": "SUS_knife_drawer", "chance": 40, "repeat": [ 1, 3 ] },
++ { "item": "SUS_cookware", "chance": 40, "repeat": [ 1, 3 ] }
++ ],
++ "K": { "item": "kitchen", "chance": 40 },
++ "o": { "item": "oven", "chance": 70 },
++ "d": [ { "item": "office_supplies", "chance": 70 }, { "item": "office_mess", "chance": 70, "repeat": [ 1, 3 ] } ],
++ "r": [ { "item": "tools_earthworking", "chance": 50 }, { "item": "supplies_farming", "chance": 70, "repeat": [ 1, 3 ] } ],
++ "D": { "item": "NC_ROBOFAC_SCIENTIST_worn", "chance": 50 },
++ "B": [
++ { "item": "magazines", "chance": 75, "repeat": [ 1, 5 ] },
++ { "item": "lab_bookshelves", "chance": 55, "repeat": [ 1, 3 ] }
++ ]
++ },
++ "npcs": { "G": { "class": "hub_security" } }
++ }
++ },
++ {
++ "type": "mapgen",
++ "om_terrain": [
++ [ "robofachq_res_a0", "robofachq_res_a1", "robofachq_res_a2", "robofachq_res_a3" ],
++ [ "robofachq_res_b0", "robofachq_res_b1", "robofachq_res_b2", "robofachq_res_b3" ]
++ ],
++ "method": "json",
++ "object": {
++ "fill_ter": "t_concrete",
++ "rows": [
++ "############################################| |#############################################",
++ "################################||||||||||##| |#############################################",
++ "################################|FFFF|FFF|##| |#############################################",
++ "#############||||||||||||||||||||F F|F F|||||222|||||||||||||||||||||||||||####################",
++ "#############| |^ ^| :|####################",
++ "#############| |^ ^| === === === === === :|####################",
++ "#############| |^ ^| =6= =6= =6= =6= =6= :|####################",
++ "#############| |^ ^| =2= =2= =2= =2= =2= :|####################",
++ "#############| AAAA |^ ^| :|####################",
++ "####||||||||||||||||||||||||||||YY||||||||||||222|| === === === === === :|||||||||||||||######",
++ "####|,,,.|SSSS6SSSS| h B|##|,,( (,,,,,,,,,( | =6= =6= =6= =6= =6= :|:::::::::::::|######",
++ "####|,,,,|S S|ddd B|##|,,( (,,,,,,,,,( | =2= =2= =2= =2= =2= :| :|######",
++ "####|,,,,|SSS SSSS| h B||||,,( (,,,,,,,,,( | :| 66 66 6 :|######",
++ "####|,,,,|====[====|=[===|YY|((( ((((((((((| | d d d d 2 66 66 6 :|######",
++ "####|,,,,= G Y | dh dh dh dh 2 :|######",
++ "####|,,,,= Y RRRRR ||====[==|||||||||||||||||2(||||||||||||######",
++ "####|,,,,= ||||||| (((((((( ======'''(> 2 G Y(:::::::::::::::| : : : : : |######",
++ "####|,,,,= = 666 = (''''''(^bb^ =,,,,='''(<Y Y2 Y('''''''''''''':| : : : : : |######",
++ "####|,,,,= = = (''''''( ==|======|||dd|| |===[==('''''''''''''':| Y Y Y Y|######",
++ "####|,,,,[ = hth = (''::''( d =Eeeeee| h|^ |6h ('''''''''''''':| : : : : : |######",
++ "####|,,,,= [ hth [ (''::''(Gd [eeeeee|6h |^ |6h h6(''''''MM''''''Y| 6: : : : : |######",
++ "####|,,,,= [ hth [ (''::''(hd [eeeeee|d |^ |6h h6(''''''MM''''''Y| 6: : : : : |######",
++ "####|,,,,[ = hth = (''::''( d =Eeeeee| Gh|^ |6h ('''''''''''''':| : : : : : |######",
++ "####|,,,,= = hth = (''''''( ==|======|||dd|| |===[==('''''''''''''':| Y Y Y Y|######",
++ "####|,,,,= = = (''''''(^bb^ =,,,,='''(<Y Y2 Y('''''''''''''':| : : : : : |######",
++ "####|,,,,= ======= (((((((( ======'''(> 2 G Y(:::::::::::::::| : : : : : |######",
++ "####|,,,,= RRRRRR ||=[=====|||||||||||||||||2(||||||||||||######",
++ "####|,,,,= |? [ 2 |#################",
++ "####|,,,,= |=[===|=[===|YY|((( ((((((((((|||||||? [ ( Y|#################",
++ "####|,,,,= |S S|s S||||,,( (,,,,,,,,,( ^|^ |[=======|===[|[====||||#################",
++ "####|,,,,= |S hS|S hS|##|,,( (,,,,,,,,,( hdhd|ddd | hhhh ^|h Y|Y h |####################",
++ "#||||||||| ||S6SSS|S6SSS|##|,,( (,,,,,,,,,( d6d| h | tttt 6|d6d | dd6|####################",
++ "#|iii | ^||||||||||||||||((|YY|(((((((((|[[|||| | hhhh | h | h|####################",
++ "#|Y Y Y | ^|lllll|^Y dh = dh^|Y B| |ffff|Y Y|BBBB|BBBBB|####################",
++ "#|2|2|2| | ^|l |B h6 [ d | hdhB|AAAAA||||||||||||||||||||||||||||||||||||||||||||||",
++ "#|;|;|;|Y |l ll |B d ^|||| ||2|Y d B|SSSSSSSS9S|SlllSSSS llSSSS SSS=YDSS SSS SSSll ll|",
++ "#|||||||Y ^|||||2|BY HtH| G|2|||||| hy|SY G Y= Y|",
++ "#|;|;|;|Y|YY^|S |||||||||| A Y|S SSSSS hS hS sh= |",
++ "#|2|2|2| |||||Sh SS6 SSS= y% Y|| SSSSS SS SS SS= SSS t 7966 6|",
++ "#|Y Y Y |###|S h [ Y% SSS Y2Y G [Y hSSS t 7966 6|",
++ "#|iii |###|S 2 66 A h6SS Y2Y G Y[Y 688 t Y|",
++ "#|||||||||###|||||2|========|[=====[=======|AA%AA|AAAAA||yyyyyyyyyyyyyyyyyy = 9 t &&66 6|",
++ "#############|l ll |Sh SSSS|h d| y6 y = 9 &&66 6|",
++ "#############|l l |SSSSS 6| hhdA y y =t8898888 7|",
++ "#############|l l|S hS| h hdA y y =Y 6 7|",
++ "#############|lllll|SSSSSYYll 6 llYYSSS|ddd h %Y y yY=t77 t7799988ttt777|",
++ "#############|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||",
++ "################################################################################################"
++ ],
++ "palettes": [ "robofachq" ],
++ "terrain": {
++ ",": [ "t_shrub_rose", "t_shrub", "t_grass_tall" ],
++ "-": "t_wall_metal",
++ "'": "t_open_air",
++ "e": "t_elevator",
++ "C": "t_carpet_red",
++ "E": "t_elevator_control",
++ "Y": "t_thconc_floor_olight",
++ "#": "t_rock",
++ "6": "t_console",
++ "R": "t_railing",
++ "9": "t_conveyor",
++ "7": "t_machinery_light",
++ "8": "t_machinery_heavy",
++ "&": "t_machinery_electronic"
++ },
++ "furniture": {
++ ":": "f_server",
++ "K": "f_counter",
++ "S": "f_table",
++ "A": "f_canvas_wall",
++ "%": "f_canvas_door",
++ "H": "f_armchair",
++ "M": "f_server",
++ "E": "f_ergometer",
++ "T": "f_treadmill",
++ "X": "f_exercise"
++ },
++ "items": {
++ "S": [
++ { "item": "tools_robotics", "chance": 30, "repeat": [ 1, 3 ] },
++ { "item": "robots", "chance": 50, "repeat": [ 1, 3 ] },
++ { "item": "supplies_electronics", "chance": 50, "repeat": [ 1, 3 ] }
++ ],
++ "d": [ { "item": "office_supplies", "chance": 70 }, { "item": "office_mess", "chance": 70, "repeat": [ 1, 3 ] } ],
++ "B": [
++ { "item": "magazines", "chance": 75, "repeat": [ 1, 5 ] },
++ { "item": "lab_bookshelves", "chance": 55, "repeat": [ 1, 3 ] }
++ ]
++ },
++ "npcs": { "G": { "class": "hub_security" } }
++ }
++ },
++ {
++ "type": "mapgen",
++ "om_terrain": [ [ "robofachq_sub_a0", "robofachq_sub_a1", "robofachq_sub_a2", "robofachq_sub_a3" ] ],
++ "method": "json",
++ "object": {
++ "fill_ter": "t_thconc_floor",
++ "rows": [
++ "#######################| ||||||||||||||####################################",
++ "#######################|Y Y (tt ^|####################################",
++ "#######################| bb bbb bb (th |####################################",
++ "#######################| (t |####################################",
++ "#######################|Y ^bb^ ^bbb^ ^bb Y (t ^|####################################",
++ "#######################|||||||||||||||||||||||| |||2|||####################################",
++ "##############################################||5555||tt tt|####################################",
++ "#####################################||||||||||^ ^| h h|####################################",
++ "#####################################|rrrrrrrr|^ ^| |####################################",
++ "#####################################|r r|| ||||2|||####################################",
++ "#####################################|r YY 2 (t r|####################################",
++ "#####################################|||||||||| YY (thY r|####################################",
++ "#####################################|bbbbbbbb| YY (t Y r|####################################",
++ "#####################################|Y Y2 ( r|####################################",
++ "#####################################| llllll ||2222||||2|||####################################",
++ "#####################################|2||||||2|^ Y^|####################################",
++ "#####################################| ~| |~ |^ Y^|####################################",
++ "#####################################| i| |i |^ Y^|####################################",
++ "#####################################||||||||||| ||||||||####################################",
++ "#####################################|lll 2 ^|##########################################",
++ "#####################################|^ ( YY ^|##########################################",
++ "#####################################| d ( YY ^|##########################################",
++ "#####################################|^hdh ( ^|##########################################",
++ "#####################################|||||||| ||||##########################################"
++ ],
++ "palettes": [ "robofachq" ],
++ "terrain": { "-": "t_wall_metal", "e": "t_elevator", "E": "t_elevator_control", "Y": "t_utility_light", "I": "t_intercom" },
++ "items": {
++ "l": [ { "item": "NC_ROBOFAC_FIELD_RESEARCHER_worn", "chance": 50 }, { "item": "NC_ROBOFAC_SCIENTIST_worn", "chance": 50 } ],
++ "i": { "item": "cleaning", "chance": 50 },
++ "B": [ { "item": "textbooks", "chance": 50 }, { "item": "manuals", "chance": 50 } ]
++ }
++ }
++ },
++ {
++ "type": "mapgen",
++ "om_terrain": [
++ [ "robofachq_ai_a0", "robofachq_ai_a1", "robofachq_ai_a2", "robofachq_ai_a3" ],
++ [ "robofachq_ai_b0", "robofachq_ai_b1", "robofachq_ai_b2", "robofachq_ai_b3" ]
++ ],
++ "method": "json",
++ "object": {
++ "fill_ter": "t_thconc_floor",
++ "rows": [
++ "################################################################################################",
++ "################################################################################################",
++ "################################################################################################",
++ "################################################################################################",
++ "################################################################################################",
++ "################################################################################################",
++ "################################################################################################",
++ "######################################################|||||||||||||||||||||||||||||||||||||||||#",
++ "######################################################|:YY:YY:YY:YY:YY:YY:YY:| rrrrrrrrrrr|#",
++ "######################################################|: : : : : : : :| Y|#",
++ "######################################################|: : : : : : : :| rrr rrrr |#",
++ "######################################################|: : : : : : : :| Y|#",
++ "###################################################||||: : : : : : : :| rrrrrrrrrrr|#",
++ "############################################||||||||YY|: : : : : : : :||5(((||||||||||||#",
++ "############################################| 5 5 Y2>|##########",
++ "############################################| 5 5 Y Y Y Y Y Y |||||||2|||##########",
++ "############################################| Y||||((((((((((((((((((((|6 |############",
++ "############################################| 5 (````````````````````||Y |||||||######",
++ "#####################################|||||||| |5(````````````````````6|: ::::::|######",
++ "#####################################|eeeeee d | (((((((((((``````````6|||| :|######",
++ "#####################################|eeeeee Y d | h6``````````6|: Y 6 :|######",
++ "#####################################|Eeeeee Y 6h| h6``````````6|: Y 6 :|######",
++ "#####################################|eeeeee d | (((((((((((``````````6|||| :|######",
++ "#####################################|||||||| |5(````````````````````6|: ::::::|######",
++ "########################################|>< 5 5 (````````````````````||Y |||||||######",
++ "########################################| | ||||((((((((((((((((((((|6 |############",
++ "########################################||||| 5 5 Y Y Y Y Y Y |||||||2|||##########",
++ "############################################| 5 5 Y2>|##########",
++ "############################################||||||||YY|: : : : : : : :||5(((||||||||||||#",
++ "###################################################||||: : : : : : : :| rrrrrrrrrrr|#",
++ "######################################################|: : : : : : : :| Y|#",
++ "######################################################|: : : : : : : :| rrr rrrr |#",
++ "######################################################|: : : : : : : :| Y|#",
++ "######################################################|:YY:YY:YY:YY:YY:YY:YY:| rrrrrrrrrrr|#",
++ "######################################################|||||||||||||||||||||||||||||||||||||||||#",
++ "################################################################################################",
++ "################################################################################################",
++ "################################################################################################",
++ "################################################################################################",
++ "################################################################################################",
++ "################################################################################################",
++ "################################################################################################",
++ "################################################################################################",
++ "################################################################################################",
++ "################################################################################################",
++ "################################################################################################",
++ "################################################################################################",
++ "################################################################################################"
++ ],
++ "palettes": [ "robofachq" ],
++ "terrain": {
++ "-": "t_wall_metal",
++ "e": "t_elevator",
++ "E": "t_elevator_control",
++ "Y": "t_thconc_floor_olight",
++ "#": "t_rock",
++ "6": "t_console"
++ },
++ "furniture": { ":": "f_server", "K": "f_counter" },
++ "items": { "r": [ { "item": "electronics", "chance": 75, "repeat": [ 1, 5 ] } ] }
++ }
++ },
++ {
++ "type": "mapgen",
++ "om_terrain": [
++ [ "robofachq_aiutl_a0", "robofachq_aiutl_a1", "robofachq_aiutl_a2", "robofachq_aiutl_a3" ],
++ [ "robofachq_aiutl_b0", "robofachq_aiutl_b1", "robofachq_aiutl_b2", "robofachq_aiutl_b3" ]
++ ],
++ "method": "json",
++ "object": {
++ "fill_ter": "t_thconc_floor",
++ "rows": [
++ "################################################################################################",
++ "################################################################################################",
++ "################################################################################################",
++ "################################################################################################",
++ "##############################################||||##############################################",
++ "##############################################|66|##############################################",
++ "##############################################| |##############################################",
++ "###########################|||||||||||||||||||| ||||||||||||||||||||||||||||||||||||||||||||||#",
++ "###########################|::::::::::::::::|B d ^|: : : : : : : :| :::::::::::|#",
++ "###########################| :|B Y h dh |: : : : : : : :| |#",
++ "###########################| :|B Y dd |YYYYYYYYYYYYYYYYYYYYYY| ::: :::::|#",
++ "###########################| :|B |: : : : : : : :| |#",
++ "###########################|:::::::: ||||||55||^||||: : : : : : : :| :::::::::::|#",
++ "###########################| 5 Y ||| |||||||||||||||||||||||||5(((||||||||||||#",
++ "###########################|::::::::::::| Y 5 5 2<|##########",
++ "###########################|||||||||||||||||| 5 5 Y Y Y Y Y Y |||||||2|||##########",
++ "############################################||55|||||||((((((((((((((((((((|6 |############",
++ "############################################| 5wwwwwwwwwwwwwwwwwwwwww||Y |||||||######",
++ "#####################################|||||||| |wwwwwwwwwwwwwwwwwwwwww:|: ::::::|######",
++ "#####################################|eeeeee (wwwwwwwwwwwwwwwwwwwwww:|||| :|######",
++ "#####################################|eeeeee Y (wwwwwwwwwwwwwwwwwwwwww:|: 6 :|######",
++ "#####################################|Eeeeee Y (wwwwwwwwwwwwwwwwwwwwww:|: 6 :|######",
++ "#####################################|eeeeee (wwwwwwwwwwwwwwwwwwwwww:|||| :|######",
++ "#####################################|||||||| |wwwwwwwwwwwwwwwwwwwwww:|: ::::::|######",
++ "########################################|>< 5 5wwwwwwwwwwwwwwwwwwwwww||Y |||||||######",
++ "########################################| ||55|||||||((((((((((((((((((((|6 |############",
++ "#############################|||||||||||||||| 5 5 Y Y Y Y Y Y ||2||||2|||##########",
++ "#############################|^ Y 5 5 | 2<|##########",
++ "#############################|^ Y ||| ||||||||||||||22|||||||||5(((||||||||||||#",
++ "#############################||2|2((((|(((2|||222||||||:::| : : : : : :| :::::::::::|#",
++ "#############################|i | |h B| |:::: | : : : : : :| |#",
++ "#############################|; | dd|dd B| Y 5 Y 2YYYYYYYYYYYYYYYYY:| :::: :::::|#",
++ "#############################|||| |h B| Y | | : : : : : :| |#",
++ "################################| h| ^|2||| |||2||:::| : : : : : :| :::::::::::|#",
++ "################################|2|||||||| |555||Y :|||||||||||||| |||||||||22||||||||||||||#",
++ "################################| ( | |:Y :|############| |#######| |: : : : : :|#",
++ "################################| cccc 2 2 ||2|||||||||||||||| ||||||||| |: : : : : :|#",
++ "################################| ||||| | |::::::::::::| 2 2 |#",
++ "################################| cccc | 2 2 |#",
++ "################################| 2 |||||||||||||||||#",
++ "################################| ccccccccc ||||| |||||||||||||||| |||||||||#################",
++ "################################| |###| :::::::::::::: :|######################",
++ "################################||||||||||||||###| 6 :|######################",
++ "#################################################| 6 :|######################",
++ "#################################################| :::::::::::::: :|######################",
++ "#################################################|||||||||||||||||||||||||######################",
++ "################################################################################################",
++ "################################################################################################"
++ ],
++ "palettes": [ "robofachq" ],
++ "terrain": {
++ "-": "t_wall_metal",
++ "e": "t_elevator",
++ "w": "t_water_pool_shallow",
++ "E": "t_elevator_control",
++ "Y": "t_thconc_floor_olight",
++ "#": "t_rock",
++ "6": "t_console"
++ },
++ "furniture": { ":": "f_server" },
++ "items": {
++ "B": [
++ { "item": "magazines", "chance": 75, "repeat": [ 1, 5 ] },
++ { "item": "lab_bookshelves", "chance": 55, "repeat": [ 1, 3 ] }
++ ]
++ }
++ }
++ },
++ {
++ "type": "mapgen",
+ "method": "json",
+ "nested_mapgen_id": "bunker_mech_spawn",
+ "weight": 25,
+diff --git a/data/json/npcs/robofac/NPC_Ulysses_Rourke.json b/data/json/obsoletion/npc.json
+similarity index 100%
+rename from data/json/npcs/robofac/NPC_Ulysses_Rourke.json
+rename to data/json/obsoletion/npc.json
+diff --git a/data/json/overmap/overmap_special/specials.json b/data/json/overmap/overmap_special/specials.json
+index 9d6302c72c..2c73e69a2c 100644
+--- a/data/json/overmap/overmap_special/specials.json
++++ b/data/json/overmap/overmap_special/specials.json
+@@ -4208,56 +4208,6 @@
+ { "point": [ 1, 1, 0 ], "overmap": "robofachq_surface_b1_north" },
+ { "point": [ 2, 1, 0 ], "overmap": "robofachq_surface_b2_north" },
+ { "point": [ 3, 1, 0 ], "overmap": "robofachq_surface_b3_north" },
+- { "point": [ 1, -2, -2 ], "overmap": "microlab_sub_connector_north" },
+- { "point": [ 0, -1, -2 ], "overmap": "robofachq_sub_a0_north" },
+- { "point": [ 1, -1, -2 ], "overmap": "robofachq_sub_a1_north" },
+- { "point": [ 2, -1, -2 ], "overmap": "robofachq_sub_a2_north" },
+- { "point": [ 3, -1, -2 ], "overmap": "robofachq_sub_a3_north" },
+- { "point": [ 0, 0, -2 ], "overmap": "robofachq_exe_a0_north" },
+- { "point": [ 1, 0, -2 ], "overmap": "robofachq_exe_a1_north" },
+- { "point": [ 2, 0, -2 ], "overmap": "robofachq_exe_a2_north" },
+- { "point": [ 3, 0, -2 ], "overmap": "robofachq_exe_a3_north" },
+- { "point": [ 0, 1, -2 ], "overmap": "robofachq_exe_b0_north" },
+- { "point": [ 1, 1, -2 ], "overmap": "robofachq_exe_b1_north" },
+- { "point": [ 2, 1, -2 ], "overmap": "robofachq_exe_b2_north" },
+- { "point": [ 3, 1, -2 ], "overmap": "robofachq_exe_b3_north" },
+- { "point": [ 0, 0, -3 ], "overmap": "robofachq_hab_a0_north" },
+- { "point": [ 1, 0, -3 ], "overmap": "robofachq_hab_a1_north" },
+- { "point": [ 2, 0, -3 ], "overmap": "robofachq_hab_a2_north" },
+- { "point": [ 3, 0, -3 ], "overmap": "robofachq_hab_a3_north" },
+- { "point": [ 0, 1, -3 ], "overmap": "robofachq_hab_b0_north" },
+- { "point": [ 1, 1, -3 ], "overmap": "robofachq_hab_b1_north" },
+- { "point": [ 2, 1, -3 ], "overmap": "robofachq_hab_b2_north" },
+- { "point": [ 3, 1, -3 ], "overmap": "robofachq_hab_b3_north" },
+- { "point": [ 1, -2, -4 ], "overmap": "microlab_sub_connector_north" },
+- { "point": [ 0, -1, -4 ], "overmap": "robofachq_sub_a0_north" },
+- { "point": [ 1, -1, -4 ], "overmap": "robofachq_sub_a1_north" },
+- { "point": [ 2, -1, -4 ], "overmap": "robofachq_sub_a2_north" },
+- { "point": [ 3, -1, -4 ], "overmap": "robofachq_sub_a3_north" },
+- { "point": [ 0, 0, -4 ], "overmap": "robofachq_res_a0_north" },
+- { "point": [ 1, 0, -4 ], "overmap": "robofachq_res_a1_north" },
+- { "point": [ 2, 0, -4 ], "overmap": "robofachq_res_a2_north" },
+- { "point": [ 3, 0, -4 ], "overmap": "robofachq_res_a3_north" },
+- { "point": [ 0, 1, -4 ], "overmap": "robofachq_res_b0_north" },
+- { "point": [ 1, 1, -4 ], "overmap": "robofachq_res_b1_north" },
+- { "point": [ 2, 1, -4 ], "overmap": "robofachq_res_b2_north" },
+- { "point": [ 3, 1, -4 ], "overmap": "robofachq_res_b3_north" },
+- { "point": [ 0, 0, -6 ], "overmap": "robofachq_ai_a0_north" },
+- { "point": [ 1, 0, -6 ], "overmap": "robofachq_ai_a1_north" },
+- { "point": [ 2, 0, -6 ], "overmap": "robofachq_ai_a2_north" },
+- { "point": [ 3, 0, -6 ], "overmap": "robofachq_ai_a3_north" },
+- { "point": [ 0, 1, -6 ], "overmap": "robofachq_ai_b0_north" },
+- { "point": [ 1, 1, -6 ], "overmap": "robofachq_ai_b1_north" },
+- { "point": [ 2, 1, -6 ], "overmap": "robofachq_ai_b2_north" },
+- { "point": [ 3, 1, -6 ], "overmap": "robofachq_ai_b3_north" },
+- { "point": [ 0, 0, -7 ], "overmap": "robofachq_aiutl_a0_north" },
+- { "point": [ 1, 0, -7 ], "overmap": "robofachq_aiutl_a1_north" },
+- { "point": [ 2, 0, -7 ], "overmap": "robofachq_aiutl_a2_north" },
+- { "point": [ 3, 0, -7 ], "overmap": "robofachq_aiutl_a3_north" },
+- { "point": [ 0, 1, -7 ], "overmap": "robofachq_aiutl_b0_north" },
+- { "point": [ 1, 1, -7 ], "overmap": "robofachq_aiutl_b1_north" },
+- { "point": [ 2, 1, -7 ], "overmap": "robofachq_aiutl_b2_north" },
+- { "point": [ 3, 1, -7 ], "overmap": "robofachq_aiutl_b3_north" },
+ { "point": [ 10, 2, 0 ], "overmap": "radio_tower_1_north" },
+ { "point": [ 10, 2, 1 ], "overmap": "radio_tower_roof_1_north" },
+ { "point": [ 10, 2, 2 ], "overmap": "radio_tower_even_stair_only_north" },
+--
+2.35.1
+
diff --git a/revert-07.5_Use-bismuth-in-recipes-related-ammo-fixes-2952.patch b/revert-07.5_Use-bismuth-in-recipes-related-ammo-fixes-2952.patch
new file mode 100644
index 0000000..d123347
--- /dev/null
+++ b/revert-07.5_Use-bismuth-in-recipes-related-ammo-fixes-2952.patch
@@ -0,0 +1,32 @@
+From 321411e0dca04ec7d218acc2351053ba0f63edab Mon Sep 17 00:00:00 2001
+From: Chaosvolt <chaosvolt@users.noreply.github.com>
+Date: Fri, 23 Jun 2023 01:31:18 -0500
+Subject: [PATCH] Use bismuth in recipes, related ammo fixes (#2952)
+
+---
+ data/json/items/ammo/4570.json | 10 ++++++++++
+ 5 files changed, 15 insertions(+), 15 deletions(-)
+
+diff --git a/data/json/items/ammo/4570.json b/data/json/items/ammo/4570.json
+index 048d32d35c7..fb2961ab382 100644
+--- a/data/json/items/ammo/4570.json
++++ b/data/json/items/ammo/4570.json
+@@ -46,5 +46,15 @@
+ "price_postapoc": "4 USD",
+ "flags": [ "IRREPLACEABLE_CONSUMABLE" ],
+ "relative": { "range": -8, "damage": { "damage_type": "bullet", "amount": -14, "armor_penetration": -25 }, "recoil": -900 }
++ },
++ {
++ "id": "reloaded_4570_bp",
++ "copy-from": "4570_low",
++ "type": "AMMO",
++ "name": { "str": ".45-70, black powder" },
++ "description": ".45-70 Government ammunition loaded with a 405 grain lead flat nose bullet using black powder to original specifications. Quite a bit less powerful and a lot dirtier than modern ammo, but still packs a punch. This one has been hand-loaded.",
++ "proportional": { "price": 0.6, "damage": { "damage_type": "bullet", "amount": 0.8 }, "dispersion": 1.2 },
++ "extend": { "effects": [ "RECYCLED", "MUZZLE_SMOKE", "BLACKPOWDER" ] },
++ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+ }
+ ]
+--
+2.40.1
+
diff --git a/revert-07_Remove-handload-quality-distinction-1481.patch b/revert-07_Remove-handload-quality-distinction-1481.patch
new file mode 100644
index 0000000..696bfbe
--- /dev/null
+++ b/revert-07_Remove-handload-quality-distinction-1481.patch
@@ -0,0 +1,4291 @@
+From 6f1c6c6edbb2f9f958b9585ead80e5bbb09a5a7e Mon Sep 17 00:00:00 2001
+From: KheirFerrum <102964889+KheirFerrum@users.noreply.github.com>
+Date: Tue, 3 May 2022 04:51:35 +0100
+Subject: [PATCH 06/10] Remove handload quality distinction (#1481)
+
+---
+ .../itemgroups/Weapons_Mods_Ammo/ammo.json | 118 ++--
+ data/json/items/ammo/10mm.json | 9 -
+ data/json/items/ammo/22.json | 18 -
+ data/json/items/ammo/223.json | 27 -
+ data/json/items/ammo/270win.json | 9 -
+ data/json/items/ammo/300.json | 10 -
+ data/json/items/ammo/3006.json | 27 -
+ data/json/items/ammo/300blk.json | 10 -
+ data/json/items/ammo/308.json | 27 -
+ data/json/items/ammo/32.json | 9 -
+ data/json/items/ammo/357mag.json | 14 -
+ data/json/items/ammo/357sig.json | 18 -
+ data/json/items/ammo/38.json | 18 -
+ data/json/items/ammo/380.json | 27 -
+ data/json/items/ammo/38super.json | 18 -
+ data/json/items/ammo/40.json | 18 -
+ data/json/items/ammo/410shot.json | 9 -
+ data/json/items/ammo/44.json | 18 -
+ data/json/items/ammo/45.json | 27 -
+ data/json/items/ammo/454.json | 9 -
+ data/json/items/ammo/4570.json | 40 --
+ data/json/items/ammo/45colt.json | 9 -
+ data/json/items/ammo/46.json | 10 -
+ data/json/items/ammo/460.json | 19 -
+ data/json/items/ammo/50.json | 30 -
+ data/json/items/ammo/500.json | 9 -
+ data/json/items/ammo/545x39.json | 20 -
+ data/json/items/ammo/57.json | 10 -
+ data/json/items/ammo/5x50.json | 11 -
+ data/json/items/ammo/700nx.json | 9 -
+ data/json/items/ammo/762.json | 19 -
+ data/json/items/ammo/762R.json | 9 -
+ data/json/items/ammo/762x25.json | 7 -
+ data/json/items/ammo/9mm.json | 36 -
+ data/json/items/ammo/9x18.json | 31 -
+ data/json/items/ammo/shot.json | 45 --
+ data/json/items/migration.json | 348 +++++++++-
+ data/json/obsoletion/items.json | 626 ++++++++++++++++++
+ data/json/obsoletion/recipes.json | 340 ++++++++++
+ data/json/recipes/ammo/pistol.json | 173 +++--
+ data/json/recipes/ammo/rifle.json | 111 ++--
+ data/json/recipes/ammo/shot.json | 17 +-
+ data/json/uncraft/ammo/30-06.json | 19 +-
+ data/json/uncraft/ammo/300.json | 2 +-
+ data/json/uncraft/ammo/300blk.json | 2 +-
+ data/json/uncraft/ammo/357mag.json | 8 +-
+ data/json/uncraft/ammo/357sig.json | 10 +-
+ data/json/uncraft/ammo/38.json | 10 +-
+ data/json/uncraft/ammo/380.json | 6 +-
+ data/json/uncraft/ammo/38super.json | 16 +-
+ data/json/uncraft/ammo/40.json | 2 +-
+ data/json/uncraft/ammo/44.json | 10 +-
+ data/json/uncraft/ammo/45.json | 2 +-
+ data/json/uncraft/ammo/454.json | 8 +-
+ data/json/uncraft/ammo/4570.json | 22 +-
+ data/json/uncraft/ammo/45colt.json | 2 +-
+ data/json/uncraft/ammo/460.json | 10 +-
+ data/json/uncraft/ammo/500.json | 8 +-
+ data/json/uncraft/ammo/50bmg.json | 2 +-
+ data/json/uncraft/ammo/545.json | 4 +-
+ data/json/uncraft/ammo/556.json | 4 +-
+ data/json/uncraft/ammo/5x50.json | 18 +-
+ data/json/uncraft/ammo/700nx.json | 6 +-
+ data/json/uncraft/ammo/762x39.json | 4 +-
+ data/json/uncraft/ammo/762x51.json | 5 +-
+ data/json/uncraft/ammo/762x54.json | 6 +-
+ data/json/uncraft/ammo/9mm.json | 2 +-
+ data/json/uncraft/ammo/9x18mm.json | 2 +-
+ .../Generic_Guns/recipes/recipe_obsolete.json | 580 +---------------
+ 71 files changed, 1632 insertions(+), 1517 deletions(-)
+
+diff --git a/data/json/itemgroups/Weapons_Mods_Ammo/ammo.json b/data/json/itemgroups/Weapons_Mods_Ammo/ammo.json
+index 5d03f226d2..c10de498fb 100644
+--- a/data/json/itemgroups/Weapons_Mods_Ammo/ammo.json
++++ b/data/json/itemgroups/Weapons_Mods_Ammo/ammo.json
+@@ -87,42 +87,42 @@
+ "//": "Reloaded pistol ammo balanced according to rarity.",
+ "subtype": "distribution",
+ "entries": [
+- { "item": "reloaded_10mm_fmj", "prob": 10 },
+- { "item": "reloaded_22_cphp", "prob": 20 },
+- { "item": "reloaded_22_lr", "prob": 70 },
+- { "item": "reloaded_32_acp", "prob": 50 },
+- { "item": "reloaded_38_fmj", "prob": 30 },
+- { "item": "reloaded_38_special", "prob": 80 },
+- { "item": "reloaded_38super_fmj", "prob": 40 },
+- { "item": "reloaded_357mag_fmj", "prob": 30 },
+- { "item": "reloaded_357mag_jhp", "prob": 30 },
+- { "item": "reloaded_380_JHP", "prob": 10 },
+- { "item": "reloaded_380_FMJ", "prob": 15 },
+- { "item": "reloaded_380_p", "prob": 5 },
+- { "item": "reloaded_357sig_fmj", "prob": 70 },
+- { "item": "reloaded_357sig_jhp", "prob": 70 },
+- { "item": "reloaded_40fmj", "prob": 20 },
+- { "item": "reloaded_40sw", "prob": 50 },
+- { "item": "reloaded_44magnum", "prob": 60 },
+- { "item": "reloaded_44fmj", "prob": 30 },
+- { "item": "reloaded_45_acp", "prob": 80 },
+- { "item": "reloaded_45_jhp", "prob": 100 },
+- { "item": "reloaded_45_super", "prob": 40 },
+- { "item": "reloaded_46mm", "prob": 20 },
+- { "item": "reloaded_454_Casull", "prob": 5 },
+- { "item": "reloaded_45colt_jhp", "prob": 10 },
+- { "item": "reloaded_460_fmj", "prob": 5 },
+- { "item": "reloaded_460_rowland", "prob": 5 },
+- { "item": "reloaded_500_Magnum", "prob": 5 },
+- { "item": "reloaded_57mm", "prob": 50 },
+- { "item": "reloaded_9mm", "prob": 160 },
+- { "item": "reloaded_9mmfmj", "prob": 80 },
+- { "item": "reloaded_9mmP", "prob": 80 },
+- { "item": "reloaded_9mmP2", "prob": 40 },
+- { "item": "reloaded_9x18mm", "prob": 20 },
+- { "item": "reloaded_9x18mmfmj", "prob": 10 },
+- { "item": "reloaded_9x18mmP2", "prob": 5 },
+- { "item": "reloaded_762_25", "prob": 10 }
++ { "item": "10mm_fmj", "prob": 10 },
++ { "item": "22_cphp", "prob": 20 },
++ { "item": "22_lr", "prob": 70 },
++ { "item": "32_acp", "prob": 50 },
++ { "item": "38_fmj", "prob": 30 },
++ { "item": "38_special", "prob": 80 },
++ { "item": "38super_fmj", "prob": 40 },
++ { "item": "357mag_fmj", "prob": 30 },
++ { "item": "357mag_jhp", "prob": 30 },
++ { "item": "380_JHP", "prob": 10 },
++ { "item": "380_FMJ", "prob": 15 },
++ { "item": "380_p", "prob": 5 },
++ { "item": "357sig_fmj", "prob": 70 },
++ { "item": "357sig_jhp", "prob": 70 },
++ { "item": "40fmj", "prob": 20 },
++ { "item": "40sw", "prob": 50 },
++ { "item": "44magnum", "prob": 60 },
++ { "item": "44fmj", "prob": 30 },
++ { "item": "45_acp", "prob": 80 },
++ { "item": "45_jhp", "prob": 100 },
++ { "item": "45_super", "prob": 40 },
++ { "item": "46mm", "prob": 20 },
++ { "item": "454_Casull", "prob": 5 },
++ { "item": "45colt_jhp", "prob": 10 },
++ { "item": "460_fmj", "prob": 5 },
++ { "item": "460_rowland", "prob": 5 },
++ { "item": "500_Magnum", "prob": 5 },
++ { "item": "57mm", "prob": 50 },
++ { "item": "9mm", "prob": 160 },
++ { "item": "9mmfmj", "prob": 80 },
++ { "item": "9mmP", "prob": 80 },
++ { "item": "9mmP2", "prob": 40 },
++ { "item": "9x18mm", "prob": 20 },
++ { "item": "9x18mmfmj", "prob": 10 },
++ { "item": "9x18mmP2", "prob": 5 },
++ { "item": "762_25", "prob": 10 }
+ ]
+ },
+ {
+@@ -274,25 +274,25 @@
+ "//": "Reloaded rifle ammo balanced according to rarity.",
+ "subtype": "distribution",
+ "entries": [
+- { "item": "reloaded_223", "prob": 60 },
+- { "item": "reloaded_22_cphp", "prob": 20 },
+- { "item": "reloaded_22_lr", "prob": 70 },
+- { "item": "reloaded_270win_jsp", "prob": 15 },
+- { "item": "reloaded_300_winmag", "prob": 15 },
+- { "item": "reloaded_3006", "prob": 70 },
+- { "item": "reloaded_3006fmj", "prob": 10 },
+- { "item": "reloaded_3006_incendiary", "prob": 5 },
+- { "item": "reloaded_308", "prob": 40 },
+- { "item": "reloaded_556", "prob": 10 },
+- { "item": "reloaded_556_incendiary", "prob": 5 },
+- { "item": "reloaded_4570_sp", "prob": 15 },
+- { "item": "reloaded_4570_pen", "prob": 5 },
+- { "item": "reloaded_4570_low", "prob": 15 },
+- { "item": "reloaded_762_51", "prob": 10 },
+- { "item": "reloaded_762_51_incendiary", "prob": 5 },
+- { "item": "reloaded_762_54R", "prob": 40 },
+- { "item": "reloaded_762_m43", "prob": 20 },
+- { "item": "reloaded_300blk", "prob": 10 }
++ { "item": "223", "prob": 60 },
++ { "item": "22_cphp", "prob": 20 },
++ { "item": "22_lr", "prob": 70 },
++ { "item": "270win_jsp", "prob": 15 },
++ { "item": "300_winmag", "prob": 15 },
++ { "item": "3006", "prob": 70 },
++ { "item": "3006fmj", "prob": 10 },
++ { "item": "3006_incendiary", "prob": 5 },
++ { "item": "308", "prob": 40 },
++ { "item": "556", "prob": 10 },
++ { "item": "556_incendiary", "prob": 5 },
++ { "item": "4570_sp", "prob": 15 },
++ { "item": "4570_pen", "prob": 5 },
++ { "item": "4570_low", "prob": 15 },
++ { "item": "762_51", "prob": 10 },
++ { "item": "762_51_incendiary", "prob": 5 },
++ { "item": "762_54R", "prob": 40 },
++ { "item": "762_m43", "prob": 20 },
++ { "item": "300blk", "prob": 10 }
+ ]
+ },
+ {
+@@ -380,13 +380,13 @@
+ "//": "Reloaded shotgun ammo balanced according to rarity.",
+ "subtype": "distribution",
+ "entries": [
+- { "item": "reloaded_shot_00", "prob": 200 },
+- { "item": "reloaded_shot_bird", "prob": 30 },
+- { "item": "reloaded_shot_dragon", "prob": 20 },
+- { "item": "reloaded_shot_flechette", "prob": 5 },
+- { "item": "reloaded_shot_slug", "prob": 30 },
++ { "item": "shot_00", "prob": 200 },
++ { "item": "shot_bird", "prob": 30 },
++ { "item": "shot_dragon", "prob": 20 },
++ { "item": "shot_flechette", "prob": 5 },
++ { "item": "shot_slug", "prob": 30 },
+ { "item": "shot_scrap", "prob": 80 },
+- { "item": "reloaded_410shot_000", "prob": 25 }
++ { "item": "410shot_000", "prob": 25 }
+ ]
+ },
+ {
+diff --git a/data/json/items/ammo/10mm.json b/data/json/items/ammo/10mm.json
+index 668ae34781..f86c20c8e4 100644
+--- a/data/json/items/ammo/10mm.json
++++ b/data/json/items/ammo/10mm.json
+@@ -36,14 +36,5 @@
+ },
+ "extend": { "effects": [ "RECYCLED", "BLACKPOWDER", "MUZZLE_SMOKE" ] },
+ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+- },
+- {
+- "id": "reloaded_10mm_fmj",
+- "copy-from": "10mm_fmj",
+- "type": "AMMO",
+- "name": { "str": "10mm Auto FMJ, reloaded" },
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
+- "extend": { "effects": [ "RECYCLED" ] },
+- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+ }
+ ]
+diff --git a/data/json/items/ammo/22.json b/data/json/items/ammo/22.json
+index d0d6f14aa5..268637c10b 100644
+--- a/data/json/items/ammo/22.json
++++ b/data/json/items/ammo/22.json
+@@ -69,23 +69,5 @@
+ },
+ "extend": { "effects": [ "RECYCLED", "BLACKPOWDER", "MUZZLE_SMOKE" ] },
+ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+- },
+- {
+- "id": "reloaded_22_lr",
+- "copy-from": "22_lr",
+- "type": "AMMO",
+- "name": { "str": ".22 LR, reloaded" },
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
+- "extend": { "effects": [ "RECYCLED" ] },
+- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+- },
+- {
+- "id": "reloaded_22_cphp",
+- "copy-from": "22_cphp",
+- "type": "AMMO",
+- "name": { "str": ".22 CPHP, reloaded" },
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
+- "extend": { "effects": [ "RECYCLED" ] },
+- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+ }
+ ]
+diff --git a/data/json/items/ammo/223.json b/data/json/items/ammo/223.json
+index 0920cde8c0..22c55429c5 100644
+--- a/data/json/items/ammo/223.json
++++ b/data/json/items/ammo/223.json
+@@ -84,32 +84,5 @@
+ },
+ "extend": { "effects": [ "RECYCLED", "BLACKPOWDER", "MUZZLE_SMOKE" ] },
+ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+- },
+- {
+- "id": "reloaded_223",
+- "copy-from": "223",
+- "type": "AMMO",
+- "name": { "str": ".223 Remington, reloaded" },
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
+- "extend": { "effects": [ "RECYCLED" ] },
+- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+- },
+- {
+- "id": "reloaded_556",
+- "copy-from": "556",
+- "type": "AMMO",
+- "name": { "str": "5.56 NATO, reloaded" },
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
+- "extend": { "effects": [ "RECYCLED" ] },
+- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+- },
+- {
+- "id": "reloaded_556_incendiary",
+- "copy-from": "556_incendiary",
+- "type": "AMMO",
+- "name": { "str": "5.56 NATO tracer, reloaded" },
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
+- "extend": { "effects": [ "RECYCLED" ] },
+- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+ }
+ ]
+diff --git a/data/json/items/ammo/270win.json b/data/json/items/ammo/270win.json
+index d9812da22a..bc2f5e826e 100644
+--- a/data/json/items/ammo/270win.json
++++ b/data/json/items/ammo/270win.json
+@@ -35,14 +35,5 @@
+ },
+ "extend": { "effects": [ "RECYCLED", "BLACKPOWDER", "MUZZLE_SMOKE" ] },
+ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+- },
+- {
+- "id": "reloaded_270win_jsp",
+- "copy-from": "270win_jsp",
+- "type": "AMMO",
+- "name": { "str": ".270 Winchester JSP, reloaded" },
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
+- "extend": { "effects": [ "RECYCLED" ] },
+- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+ }
+ ]
+diff --git a/data/json/items/ammo/300.json b/data/json/items/ammo/300.json
+index 6c69fe4e4d..95fcb846f5 100644
+--- a/data/json/items/ammo/300.json
++++ b/data/json/items/ammo/300.json
+@@ -35,15 +35,5 @@
+ },
+ "extend": { "effects": [ "RECYCLED", "BLACKPOWDER", "MUZZLE_SMOKE" ] },
+ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+- },
+- {
+- "id": "reloaded_300_winmag",
+- "copy-from": "300_winmag",
+- "type": "AMMO",
+- "name": { "str": ".300 Winchester Magnum, reloaded" },
+- "description": "The .300 Winchester Magnum is extremely versatile and has been adopted by many shooting disciplines. The cartridge has found use by hunters, military units, and law enforcement departments.",
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
+- "extend": { "effects": [ "RECYCLED" ] },
+- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+ }
+ ]
+diff --git a/data/json/items/ammo/3006.json b/data/json/items/ammo/3006.json
+index d8abccb9b4..222ccaad66 100644
+--- a/data/json/items/ammo/3006.json
++++ b/data/json/items/ammo/3006.json
+@@ -79,32 +79,5 @@
+ },
+ "extend": { "effects": [ "RECYCLED", "BLACKPOWDER", "MUZZLE_SMOKE" ] },
+ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+- },
+- {
+- "id": "reloaded_3006",
+- "copy-from": "3006",
+- "type": "AMMO",
+- "name": { "str": ".30-06 Springfield, reloaded" },
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
+- "extend": { "effects": [ "RECYCLED" ] },
+- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+- },
+- {
+- "id": "reloaded_3006_incendiary",
+- "copy-from": "3006_incendiary",
+- "type": "AMMO",
+- "name": { "str": ".30-06 incendiary, reloaded" },
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
+- "extend": { "effects": [ "RECYCLED" ] },
+- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+- },
+- {
+- "id": "reloaded_3006fmj",
+- "copy-from": "3006fmj",
+- "type": "AMMO",
+- "name": { "str": ".30-06 M2 AP, reloaded" },
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
+- "extend": { "effects": [ "RECYCLED" ] },
+- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+ }
+ ]
+diff --git a/data/json/items/ammo/300blk.json b/data/json/items/ammo/300blk.json
+index acf9dc62cc..bdff5be36f 100644
+--- a/data/json/items/ammo/300blk.json
++++ b/data/json/items/ammo/300blk.json
+@@ -46,15 +46,5 @@
+ },
+ "extend": { "effects": [ "RECYCLED", "BLACKPOWDER", "MUZZLE_SMOKE" ] },
+ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+- },
+- {
+- "id": "reloaded_300blk",
+- "copy-from": "300blk",
+- "type": "AMMO",
+- "name": { "str": ".300 AAC Blackout, reloaded" },
+- "description": ".300 AAC Blackout is an intermediate cartridge that achieves ballistics similar to the 7.62x39 but allows use on the AR-15 platform. The round is necked-up from the 5.56mm NATO, but feeds from a STANAG magazine. It requires a specific barrel, so will not work in a standard M4 or similar carbine.",
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
+- "extend": { "effects": [ "RECYCLED" ] },
+- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+ }
+ ]
+diff --git a/data/json/items/ammo/308.json b/data/json/items/ammo/308.json
+index 3691c8269a..8d25222a91 100644
+--- a/data/json/items/ammo/308.json
++++ b/data/json/items/ammo/308.json
+@@ -82,32 +82,5 @@
+ },
+ "extend": { "effects": [ "RECYCLED", "BLACKPOWDER", "MUZZLE_SMOKE" ] },
+ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+- },
+- {
+- "id": "reloaded_308",
+- "copy-from": "308",
+- "type": "AMMO",
+- "name": { "str": ".308 Winchester, reloaded" },
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
+- "extend": { "effects": [ "RECYCLED" ] },
+- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+- },
+- {
+- "id": "reloaded_762_51",
+- "copy-from": "762_51",
+- "type": "AMMO",
+- "name": { "str": "7.62x51mm, reloaded" },
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
+- "extend": { "effects": [ "RECYCLED" ] },
+- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+- },
+- {
+- "id": "reloaded_762_51_incendiary",
+- "copy-from": "762_51_incendiary",
+- "type": "AMMO",
+- "name": { "str": "7.62x51mm incendiary, reloaded" },
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
+- "extend": { "effects": [ "RECYCLED" ] },
+- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+ }
+ ]
+diff --git a/data/json/items/ammo/32.json b/data/json/items/ammo/32.json
+index b500f7f5b4..52e96900ea 100644
+--- a/data/json/items/ammo/32.json
++++ b/data/json/items/ammo/32.json
+@@ -36,14 +36,5 @@
+ },
+ "extend": { "effects": [ "RECYCLED", "BLACKPOWDER", "MUZZLE_SMOKE" ] },
+ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+- },
+- {
+- "id": "reloaded_32_acp",
+- "copy-from": "32_acp",
+- "type": "AMMO",
+- "name": { "str": ".32 ACP, reloaded" },
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
+- "extend": { "effects": [ "RECYCLED" ] },
+- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+ }
+ ]
+diff --git a/data/json/items/ammo/357mag.json b/data/json/items/ammo/357mag.json
+index b00d90a5d8..c5324f076e 100644
+--- a/data/json/items/ammo/357mag.json
++++ b/data/json/items/ammo/357mag.json
+@@ -58,19 +58,5 @@
+ },
+ "extend": { "effects": [ "RECYCLED", "BLACKPOWDER", "MUZZLE_SMOKE" ] },
+ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+- },
+- {
+- "id": "reloaded_357mag_fmj",
+- "copy-from": "357mag_fmj",
+- "type": "AMMO",
+- "name": { "str_sp": ".357 Magnum FMJ, reloaded" },
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1, "recoil": 0.9 }
+- },
+- {
+- "id": "reloaded_357mag_jhp",
+- "copy-from": "357mag_jhp",
+- "type": "AMMO",
+- "name": { "str_sp": ".357 Magnum JHP, reloaded" },
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1, "recoil": 0.9 }
+ }
+ ]
+diff --git a/data/json/items/ammo/357sig.json b/data/json/items/ammo/357sig.json
+index 6f2cd83e49..99473a7653 100644
+--- a/data/json/items/ammo/357sig.json
++++ b/data/json/items/ammo/357sig.json
+@@ -30,23 +30,5 @@
+ "name": { "str": ".357 SIG JHP" },
+ "description": "Jacketed hollow point .357 SIG ammunition. The .357 SIG round is a high velocity pistol cartridge, giving it a flatter trajectory than many handgun rounds.",
+ "damage": { "damage_type": "bullet", "amount": 42, "armor_penetration": 0 }
+- },
+- {
+- "id": "reloaded_357sig_fmj",
+- "copy-from": "357sig_fmj",
+- "type": "AMMO",
+- "name": { "str": ".357 SIG FMJ, reloaded" },
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
+- "extend": { "effects": [ "RECYCLED" ] },
+- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+- },
+- {
+- "id": "reloaded_357sig_jhp",
+- "copy-from": "357sig_jhp",
+- "type": "AMMO",
+- "name": { "str": ".357 SIG JHP, reloaded" },
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
+- "extend": { "effects": [ "RECYCLED" ] },
+- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+ }
+ ]
+diff --git a/data/json/items/ammo/38.json b/data/json/items/ammo/38.json
+index f4b08dfaaa..798b35db5d 100644
+--- a/data/json/items/ammo/38.json
++++ b/data/json/items/ammo/38.json
+@@ -32,24 +32,6 @@
+ "recoil": 250,
+ "effects": [ "COOKOFF" ]
+ },
+- {
+- "id": "reloaded_38_fmj",
+- "copy-from": "38_fmj",
+- "type": "AMMO",
+- "name": { "str": ".38 FMJ, reloaded" },
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
+- "extend": { "effects": [ "RECYCLED" ] },
+- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+- },
+- {
+- "id": "reloaded_38_special",
+- "copy-from": "38_special",
+- "type": "AMMO",
+- "name": { "str": ".38 Special, reloaded" },
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
+- "extend": { "effects": [ "RECYCLED" ] },
+- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+- },
+ {
+ "id": "bp_38_fmj",
+ "copy-from": "38_fmj",
+diff --git a/data/json/items/ammo/380.json b/data/json/items/ammo/380.json
+index 395772a3fa..9667b74813 100644
+--- a/data/json/items/ammo/380.json
++++ b/data/json/items/ammo/380.json
+@@ -73,32 +73,5 @@
+ },
+ "extend": { "effects": [ "RECYCLED", "BLACKPOWDER", "MUZZLE_SMOKE" ] },
+ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+- },
+- {
+- "id": "reloaded_380_FMJ",
+- "copy-from": "380_FMJ",
+- "type": "AMMO",
+- "name": { "str": ".380 ACP FMJ, reloaded" },
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
+- "extend": { "effects": [ "RECYCLED" ] },
+- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+- },
+- {
+- "id": "reloaded_380_JHP",
+- "copy-from": "380_JHP",
+- "type": "AMMO",
+- "name": { "str": ".380 ACP JHP, reloaded" },
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
+- "extend": { "effects": [ "RECYCLED" ] },
+- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+- },
+- {
+- "id": "reloaded_380_p",
+- "copy-from": "380_p",
+- "type": "AMMO",
+- "name": { "str": ".380 ACP +P, reloaded" },
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
+- "extend": { "effects": [ "RECYCLED" ] },
+- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+ }
+ ]
+diff --git a/data/json/items/ammo/38super.json b/data/json/items/ammo/38super.json
+index 06ac5f021a..2b576f3bf9 100644
+--- a/data/json/items/ammo/38super.json
++++ b/data/json/items/ammo/38super.json
+@@ -34,23 +34,5 @@
+ "count": 20,
+ "//": "Hollowpoint damage increase of 25%.",
+ "damage": { "damage_type": "bullet", "amount": 40, "armor_penetration": 0 }
+- },
+- {
+- "id": "reloaded_38super_fmj",
+- "copy-from": "38super_fmj",
+- "type": "AMMO",
+- "name": { "str": ".38 Super FMJ, reloaded" },
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
+- "extend": { "effects": [ "RECYCLED" ] },
+- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+- },
+- {
+- "id": "reloaded_38_super",
+- "copy-from": "38_super",
+- "type": "AMMO",
+- "name": { "str": ".38 Super, reloaded" },
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
+- "extend": { "effects": [ "RECYCLED" ] },
+- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+ }
+ ]
+diff --git a/data/json/items/ammo/40.json b/data/json/items/ammo/40.json
+index 8cb513d33c..227f270ad0 100644
+--- a/data/json/items/ammo/40.json
++++ b/data/json/items/ammo/40.json
+@@ -59,23 +59,5 @@
+ },
+ "extend": { "effects": [ "RECYCLED", "BLACKPOWDER", "MUZZLE_SMOKE" ] },
+ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+- },
+- {
+- "id": "reloaded_40fmj",
+- "copy-from": "40fmj",
+- "type": "AMMO",
+- "name": { "str": ".40 S&W FMJ, reloaded" },
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
+- "extend": { "effects": [ "RECYCLED" ] },
+- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+- },
+- {
+- "id": "reloaded_40sw",
+- "copy-from": "40sw",
+- "type": "AMMO",
+- "name": { "str": ".40 S&W JHP, reloaded" },
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
+- "extend": { "effects": [ "RECYCLED" ] },
+- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+ }
+ ]
+diff --git a/data/json/items/ammo/410shot.json b/data/json/items/ammo/410shot.json
+index 757b9b403a..ffb7db6072 100644
+--- a/data/json/items/ammo/410shot.json
++++ b/data/json/items/ammo/410shot.json
+@@ -21,14 +21,5 @@
+ "recoil": 1350,
+ "loudness": 90,
+ "effects": [ "COOKOFF", "SHOT" ]
+- },
+- {
+- "id": "reloaded_410shot_000",
+- "copy-from": "410shot_000",
+- "type": "AMMO",
+- "name": { "str": ".410 000 shot, reloaded" },
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
+- "extend": { "effects": [ "RECYCLED" ] },
+- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+ }
+ ]
+diff --git a/data/json/items/ammo/44.json b/data/json/items/ammo/44.json
+index 5c014350eb..1082652bf7 100644
+--- a/data/json/items/ammo/44.json
++++ b/data/json/items/ammo/44.json
+@@ -32,24 +32,6 @@
+ "recoil": 1570,
+ "effects": [ "COOKOFF" ]
+ },
+- {
+- "id": "reloaded_44fmj",
+- "copy-from": "44fmj",
+- "type": "AMMO",
+- "name": { "str": ".44 Magnum FMJ, reloaded" },
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
+- "extend": { "effects": [ "RECYCLED" ] },
+- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+- },
+- {
+- "id": "reloaded_44magnum",
+- "copy-from": "44magnum",
+- "type": "AMMO",
+- "name": { "str": ".44 Magnum, reloaded" },
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
+- "extend": { "effects": [ "RECYCLED" ] },
+- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+- },
+ {
+ "id": "bp_44magnum",
+ "copy-from": "44magnum",
+diff --git a/data/json/items/ammo/45.json b/data/json/items/ammo/45.json
+index 76d92daa6c..3c78bef870 100644
+--- a/data/json/items/ammo/45.json
++++ b/data/json/items/ammo/45.json
+@@ -71,32 +71,5 @@
+ },
+ "extend": { "effects": [ "RECYCLED", "BLACKPOWDER", "MUZZLE_SMOKE" ] },
+ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+- },
+- {
+- "id": "reloaded_45_acp",
+- "copy-from": "45_acp",
+- "type": "AMMO",
+- "name": { "str": ".45 FMJ, reloaded" },
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
+- "extend": { "effects": [ "RECYCLED" ] },
+- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+- },
+- {
+- "id": "reloaded_45_jhp",
+- "copy-from": "45_jhp",
+- "type": "AMMO",
+- "name": { "str": ".45 ACP JHP, reloaded" },
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
+- "extend": { "effects": [ "RECYCLED" ] },
+- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+- },
+- {
+- "id": "reloaded_45_super",
+- "copy-from": "45_super",
+- "type": "AMMO",
+- "name": { "str": ".45 ACP +P, reloaded" },
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
+- "extend": { "effects": [ "RECYCLED" ] },
+- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+ }
+ ]
+diff --git a/data/json/items/ammo/454.json b/data/json/items/ammo/454.json
+index d46502dbd2..ac93acc229 100644
+--- a/data/json/items/ammo/454.json
++++ b/data/json/items/ammo/454.json
+@@ -22,15 +22,6 @@
+ "recoil": 2500,
+ "effects": [ "COOKOFF" ]
+ },
+- {
+- "id": "reloaded_454_Casull",
+- "copy-from": "454_Casull",
+- "type": "AMMO",
+- "name": { "str": ".454 Casull, reloaded" },
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
+- "extend": { "effects": [ "RECYCLED" ] },
+- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+- },
+ {
+ "id": "bp_454_Casull",
+ "copy-from": "454_Casull",
+diff --git a/data/json/items/ammo/4570.json b/data/json/items/ammo/4570.json
+index 94082b3805..360afcdb1c 100644
+--- a/data/json/items/ammo/4570.json
++++ b/data/json/items/ammo/4570.json
+@@ -44,45 +44,5 @@
+ "price_postapoc": "4 USD",
+ "flags": [ "IRREPLACEABLE_CONSUMABLE" ],
+ "relative": { "range": -8, "damage": { "damage_type": "bullet", "amount": -14, "armor_penetration": -25 }, "recoil": -900 }
+- },
+- {
+- "id": "reloaded_4570_sp",
+- "copy-from": "4570_sp",
+- "type": "AMMO",
+- "name": { "str": ".45-70 SP, reloaded" },
+- "description": ".45-70 Government ammunition loaded with a 305 grain soft point round. One of the oldest cartridges still in use, it is still a favorite for large game hunting at short ranges.",
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
+- "extend": { "effects": [ "RECYCLED" ] },
+- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+- },
+- {
+- "id": "reloaded_4570_pen",
+- "copy-from": "4570_pen",
+- "type": "AMMO",
+- "name": { "str": ".45-70 +P penetrator, reloaded" },
+- "description": ".45-70 Government +P ammunition loaded with a 305 grain solid copper penetrator projectile. Designed for maximum penetration through thick hide and bone while maintaining ideal wounding characteristics.",
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
+- "extend": { "effects": [ "RECYCLED" ] },
+- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+- },
+- {
+- "id": "reloaded_4570_low",
+- "copy-from": "4570_low",
+- "type": "AMMO",
+- "name": { "str": ".45-70 LFN cowboy, reloaded" },
+- "description": ".45-70 Government ammunition loaded with a 405 grain lead flat nose bullet to original specifications for safe use in antique firearms. Quite a bit less powerful than modern ammo, but still packs a punch.",
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
+- "extend": { "effects": [ "RECYCLED" ] },
+- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+- },
+- {
+- "id": "reloaded_4570_bp",
+- "copy-from": "4570_low",
+- "type": "AMMO",
+- "name": { "str": ".45-70, black powder" },
+- "description": ".45-70 Government ammunition loaded with a 405 grain lead flat nose bullet using black powder to original specifications. Quite a bit less powerful and a lot dirtier than modern ammo, but still packs a punch.",
+- "proportional": { "price": 0.6, "damage": { "damage_type": "bullet", "amount": 0.8 }, "dispersion": 1.2 },
+- "extend": { "effects": [ "RECYCLED", "MUZZLE_SMOKE", "BLACKPOWDER" ] },
+- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+ }
+ ]
+diff --git a/data/json/items/ammo/45colt.json b/data/json/items/ammo/45colt.json
+index 713c49c5b4..99a289404c 100644
+--- a/data/json/items/ammo/45colt.json
++++ b/data/json/items/ammo/45colt.json
+@@ -23,15 +23,6 @@
+ "recoil": 600,
+ "effects": [ "COOKOFF" ]
+ },
+- {
+- "id": "reloaded_45colt_jhp",
+- "copy-from": "45colt_jhp",
+- "type": "AMMO",
+- "name": { "str": ".45 Colt JHP, reloaded" },
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
+- "extend": { "effects": [ "RECYCLED" ] },
+- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+- },
+ {
+ "id": "bp_45colt_jhp",
+ "copy-from": "45colt_jhp",
+diff --git a/data/json/items/ammo/46.json b/data/json/items/ammo/46.json
+index 477702dcdb..3a63dddaf4 100644
+--- a/data/json/items/ammo/46.json
++++ b/data/json/items/ammo/46.json
+@@ -37,15 +37,5 @@
+ },
+ "extend": { "effects": [ "RECYCLED", "BLACKPOWDER", "MUZZLE_SMOKE" ] },
+ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+- },
+- {
+- "id": "reloaded_46mm",
+- "copy-from": "46mm",
+- "type": "AMMO",
+- "name": { "str": "4.6x30mm, reloaded" },
+- "description": "4.6x30mm ammunition with 31gr copper plated lead bullets. The 4.6x30mm round was developed by H&K to compete with FN Herstal's 5.7x28mm cartridge. It has low recoil, but no usual armor penetration due to using simple lead bullets rather than proper factory-made penetrator projectiles.",
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9, "armor_penetration": 0.2 }, "dispersion": 1.1 },
+- "extend": { "effects": [ "RECYCLED" ] },
+- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+ }
+ ]
+diff --git a/data/json/items/ammo/460.json b/data/json/items/ammo/460.json
+index c21480727c..087ec1ba8f 100644
+--- a/data/json/items/ammo/460.json
++++ b/data/json/items/ammo/460.json
+@@ -44,24 +44,5 @@
+ },
+ "extend": { "effects": [ "RECYCLED", "BLACKPOWDER", "MUZZLE_SMOKE" ] },
+ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+- },
+- {
+- "id": "reloaded_460_fmj",
+- "copy-from": "460_fmj",
+- "type": "AMMO",
+- "name": { "str": ".460 Rowland FMJ, reloaded" },
+- "description": "A brass-jacketed variant of the .460 Rowland round. This increases penetration slightly at the cost of reduced damage from expansion.",
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
+- "extend": { "effects": [ "RECYCLED" ] },
+- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+- },
+- {
+- "id": "reloaded_460_rowland",
+- "copy-from": "460_rowland",
+- "type": "AMMO",
+- "name": { "str": ".460 Rowland, reloaded" },
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
+- "extend": { "effects": [ "RECYCLED" ] },
+- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+ }
+ ]
+diff --git a/data/json/items/ammo/50.json b/data/json/items/ammo/50.json
+index 928f5c94a1..058da3c560 100644
+--- a/data/json/items/ammo/50.json
++++ b/data/json/items/ammo/50.json
+@@ -65,35 +65,5 @@
+ "//": "mk 211 is estimated to be as effective as 20mm, which would have 65kJ energy, or 255 damage. ~181 damage is fair.",
+ "relative": { "damage": { "damage_type": "bullet", "amount": 50, "armor_penetration": 25 } },
+ "dispersion": 100
+- },
+- {
+- "id": "reloaded_50_incendiary",
+- "copy-from": "50_incendiary",
+- "type": "AMMO",
+- "name": { "str": ".50 BMG tracer, reloaded" },
+- "description": "A tracer variant of the powerful .50 BMG round. Tracer rounds help to keep the weapon they are fired from on target at the risk of igniting flammable substances.",
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
+- "extend": { "effects": [ "RECYCLED" ] },
+- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+- },
+- {
+- "id": "reloaded_50bmg",
+- "copy-from": "50match",
+- "type": "AMMO",
+- "name": { "str": ".50 BMG Match, reloaded" },
+- "description": ".50 BMG ammunition with lead-cored FMJ bullets. The .50 BMG is a very powerful rifle round designed for anti-aircraft use, later adapted to anti-vehicular and anti-personnel roles. Its stupendous energy and armor piercing capabilities make it one of the most deadly rounds available, offset only by its drastic recoil and noise.",
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
+- "extend": { "effects": [ "RECYCLED" ] },
+- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+- },
+- {
+- "id": "reloaded_50ss",
+- "copy-from": "50ss",
+- "type": "AMMO",
+- "name": { "str": ".50 BMG AP, reloaded" },
+- "description": "Variant of the .50 BMG round that uses a core hardened steel. Penetration is increased, but damage is reduced.",
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
+- "extend": { "effects": [ "RECYCLED" ] },
+- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+ }
+ ]
+diff --git a/data/json/items/ammo/500.json b/data/json/items/ammo/500.json
+index 1f115ef477..e13aec49f2 100644
+--- a/data/json/items/ammo/500.json
++++ b/data/json/items/ammo/500.json
+@@ -35,14 +35,5 @@
+ },
+ "extend": { "effects": [ "RECYCLED", "BLACKPOWDER", "MUZZLE_SMOKE" ] },
+ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+- },
+- {
+- "id": "reloaded_500_Magnum",
+- "copy-from": "500_Magnum",
+- "type": "AMMO",
+- "name": { "str": ".500 S&W Magnum, reloaded" },
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
+- "extend": { "effects": [ "RECYCLED" ] },
+- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+ }
+ ]
+diff --git a/data/json/items/ammo/545x39.json b/data/json/items/ammo/545x39.json
+index 67b9e40515..13b13adcf2 100644
+--- a/data/json/items/ammo/545x39.json
++++ b/data/json/items/ammo/545x39.json
+@@ -35,25 +35,5 @@
+ "color": "yellow",
+ "//": "Balanced as AP, 7/8 damage, arpen 6/7 that value.",
+ "relative": { "damage": { "damage_type": "bullet", "amount": -5, "armor_penetration": 12 } }
+- },
+- {
+- "id": "reloaded_545",
+- "copy-from": "545",
+- "type": "AMMO",
+- "name": { "str": "5.45x39mm, reloaded" },
+- "description": "The 5.45x39mm was the standard ammunition for the AK series from 1974. Its designers were inspired by the 5.56x45mm NATO cartridge.",
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
+- "extend": { "effects": [ "RECYCLED" ] },
+- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+- },
+- {
+- "id": "reloaded_545_ap",
+- "copy-from": "545_ap",
+- "type": "AMMO",
+- "name": { "str": "5.45x39mm AP, reloaded" },
+- "description": "Armor piercing 5.45x39mm ammunition with hand-reloaded bullets containing a steel penetrator. Developed in 1998 by the Russian military.",
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
+- "extend": { "effects": [ "RECYCLED" ] },
+- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+ }
+ ]
+diff --git a/data/json/items/ammo/57.json b/data/json/items/ammo/57.json
+index e9ada36514..0cde40d396 100644
+--- a/data/json/items/ammo/57.json
++++ b/data/json/items/ammo/57.json
+@@ -37,15 +37,5 @@
+ },
+ "extend": { "effects": [ "RECYCLED", "BLACKPOWDER", "MUZZLE_SMOKE" ] },
+ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+- },
+- {
+- "id": "reloaded_57mm",
+- "copy-from": "57mm",
+- "type": "AMMO",
+- "name": { "str": "5.7x28mm, reloaded" },
+- "description": "5.7x28mm ammunition with 31gr AP FMJ bullets. The 5.7x28mm cartridge was designed by FN Herstal to replace the 9x19mm round in NATO use. Although the project to replace 9x19mm Parabellum was effectively canceled the 5.7x28mm round has seen action in many conflicts and has proven to be reliable. It has very low recoil but no usual armor penetration due to using simple lead bullets rather than proper factory-made penetrator projectiles.",
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9, "armor_penetration": 0.2 }, "dispersion": 1.1 },
+- "extend": { "effects": [ "RECYCLED" ] },
+- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+ }
+ ]
+diff --git a/data/json/items/ammo/5x50.json b/data/json/items/ammo/5x50.json
+index c1a285cb91..5a8901e578 100644
+--- a/data/json/items/ammo/5x50.json
++++ b/data/json/items/ammo/5x50.json
+@@ -33,16 +33,5 @@
+ "//": "Balanced as AP, with 25% higher damage and 50% higher arpen"
+ "relative": { "range": -10, "damage": { "damage_type": "bullet", "amount": 8, "armor_penetration": 13 } },
+ "proportional": { "dispersion": 1.5, "recoil": 1.5 }
+- },
+- {
+- "id": "reloaded_5x50dart",
+- "copy-from": "5x50dart",
+- "type": "AMMO",
+- "name": { "str": "5x50mm flechette, reloaded" },
+- "price_postapoc": "12 USD",
+- "description": "Designed to defeat modern body armor, the Rivtech 5x50mm flechette round features a biodegradable sabot and a single, fin-stabilized penetrator.",
+- "effects": [ "COOKOFF", "RECYCLED" ],
+- "relative": { "range": -15, "dispersion": 40 },
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9, "armor_penetration": 0.7 }, "recoil": 0.9 }
+ }
+ ]
+diff --git a/data/json/items/ammo/700nx.json b/data/json/items/ammo/700nx.json
+index 7eb5b7e653..0c1502f592 100644
+--- a/data/json/items/ammo/700nx.json
++++ b/data/json/items/ammo/700nx.json
+@@ -21,14 +21,5 @@
+ "dispersion": 15,
+ "recoil": 12100,
+ "effects": [ "COOKOFF" ]
+- },
+- {
+- "id": "reloaded_700nx",
+- "copy-from": "700nx",
+- "type": "AMMO",
+- "name": { "str": ".700 NX, reloaded" },
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
+- "extend": { "effects": [ "RECYCLED" ] },
+- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+ }
+ ]
+diff --git a/data/json/items/ammo/762.json b/data/json/items/ammo/762.json
+index 7f770d227c..685111f200 100644
+--- a/data/json/items/ammo/762.json
++++ b/data/json/items/ammo/762.json
+@@ -32,24 +32,5 @@
+ "price": "150 cent",
+ "price_postapoc": "68 USD",
+ "relative": { "damage": { "damage_type": "bullet", "amount": 4, "armor_penetration": 2 } }
+- },
+- {
+- "id": "reloaded_762_m43",
+- "copy-from": "762_m43",
+- "type": "AMMO",
+- "name": { "str": "7.62x39mm M43, reloaded" },
+- "description": "7.62x39mm ammunition with 121.9gr bullets. Developed in WW2 by the Soviet Union the 7.62x39mm round rapidly became extremely popular all over the world. The bullet has poor wounding potential due to its stability, only beginning to yaw after 26cm.",
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
+- "extend": { "effects": [ "RECYCLED" ] },
+- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+- },
+- {
+- "id": "reloaded_762_m87",
+- "copy-from": "762_m87",
+- "type": "AMMO",
+- "name": { "str": "7.62x39mm M67, reloaded" },
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
+- "extend": { "effects": [ "RECYCLED" ] },
+- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+ }
+ ]
+diff --git a/data/json/items/ammo/762R.json b/data/json/items/ammo/762R.json
+index 805a79dc09..1d595cc200 100644
+--- a/data/json/items/ammo/762R.json
++++ b/data/json/items/ammo/762R.json
+@@ -21,14 +21,5 @@
+ "dispersion": 15,
+ "recoil": 2650,
+ "effects": [ "COOKOFF" ]
+- },
+- {
+- "id": "reloaded_762_54R",
+- "copy-from": "762_54R",
+- "type": "AMMO",
+- "name": { "str": "7.62x54mmR, reloaded" },
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
+- "extend": { "effects": [ "RECYCLED" ] },
+- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+ }
+ ]
+diff --git a/data/json/items/ammo/762x25.json b/data/json/items/ammo/762x25.json
+index 77877e86f7..2dc22bed9e 100644
+--- a/data/json/items/ammo/762x25.json
++++ b/data/json/items/ammo/762x25.json
+@@ -63,12 +63,5 @@
+ },
+ "extend": { "effects": [ "RECYCLED", "BLACKPOWDER", "MUZZLE_SMOKE" ] },
+ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+- },
+- {
+- "id": "reloaded_762_25",
+- "copy-from": "762_25hot",
+- "type": "AMMO",
+- "name": { "str": "7.62x25mm, reloaded" },
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9, "armor_penetration": 0.9 }, "dispersion": 1.1 }
+ }
+ ]
+diff --git a/data/json/items/ammo/9mm.json b/data/json/items/ammo/9mm.json
+index a48e446164..420503af41 100644
+--- a/data/json/items/ammo/9mm.json
++++ b/data/json/items/ammo/9mm.json
+@@ -85,41 +85,5 @@
+ },
+ "extend": { "effects": [ "RECYCLED", "BLACKPOWDER", "MUZZLE_SMOKE" ] },
+ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+- },
+- {
+- "id": "reloaded_9mm",
+- "copy-from": "9mm",
+- "type": "AMMO",
+- "name": { "str": "9x19mm JHP, reloaded" },
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
+- "extend": { "effects": [ "RECYCLED" ] },
+- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+- },
+- {
+- "id": "reloaded_9mmfmj",
+- "copy-from": "9mmfmj",
+- "type": "AMMO",
+- "name": { "str": "9x19mm FMJ, reloaded" },
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
+- "extend": { "effects": [ "RECYCLED" ] },
+- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+- },
+- {
+- "id": "reloaded_9mmP",
+- "copy-from": "9mmP",
+- "type": "AMMO",
+- "name": { "str": "9x19mm +P, reloaded" },
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
+- "extend": { "effects": [ "RECYCLED" ] },
+- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+- },
+- {
+- "id": "reloaded_9mmP2",
+- "copy-from": "9mmP2",
+- "type": "AMMO",
+- "name": { "str": "9x19mm +P+, reloaded" },
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
+- "extend": { "effects": [ "RECYCLED" ] },
+- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+ }
+ ]
+diff --git a/data/json/items/ammo/9x18.json b/data/json/items/ammo/9x18.json
+index 94c130a144..63b613e9ff 100644
+--- a/data/json/items/ammo/9x18.json
++++ b/data/json/items/ammo/9x18.json
+@@ -74,36 +74,5 @@
+ },
+ "extend": { "effects": [ "RECYCLED", "BLACKPOWDER", "MUZZLE_SMOKE" ] },
+ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+- },
+- {
+- "id": "reloaded_9x18mm",
+- "copy-from": "9x18mm",
+- "type": "AMMO",
+- "name": { "str": "9x18mm, reloaded" },
+- "description": "9x18 millimeter Makarov, an old Soviet pistol cartridge used mainly by the Makarov PM. As the designation implies, it is a bit shorter in case length compared to 9mm Parabellum.",
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
+- "extend": { "effects": [ "RECYCLED" ] },
+- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+- },
+- {
+- "id": "reloaded_9x18mmP2",
+- "copy-from": "9x18mmP2",
+- "type": "AMMO",
+- "name": { "str": "9x18mm +P+, reloaded" },
+- "//": "Rather than give it a military designation, this is simply handmade overpressure ammo.",
+- "description": "9x18 millimeter Makarov, an old Soviet pistol cartridge used mainly by the Makarov PM. This one has been hand-reloaded to generate higher internal pressure, boosting flight stability and damage.",
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
+- "extend": { "effects": [ "RECYCLED" ] },
+- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+- },
+- {
+- "id": "reloaded_9x18mmfmj",
+- "copy-from": "9x18mmfmj",
+- "type": "AMMO",
+- "name": { "str": "9x18mm FMJ, reloaded" },
+- "description": "9x18 millimeter Makarov, an old Soviet pistol cartridge used mainly by the Makarov PM. This brass-jacketed round increases penetration slightly, at the cost of reduced expansion.",
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
+- "extend": { "effects": [ "RECYCLED" ] },
+- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+ }
+ ]
+diff --git a/data/json/items/ammo/shot.json b/data/json/items/ammo/shot.json
+index 50f6c09d56..619ab4ab64 100644
+--- a/data/json/items/ammo/shot.json
++++ b/data/json/items/ammo/shot.json
+@@ -1,49 +1,4 @@
+ [
+- {
+- "id": "reloaded_shot_bird",
+- "copy-from": "shot_bird",
+- "type": "AMMO",
+- "name": { "str": "birdshot, reloaded" },
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
+- "extend": { "effects": [ "RECYCLED" ] },
+- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+- },
+- {
+- "id": "reloaded_shot_dragon",
+- "copy-from": "shot_dragon",
+- "type": "AMMO",
+- "name": { "str": "dragon's breath shell, reloaded" },
+- "proportional": { "price": 0.7, "damage": { "damage_type": "heat", "amount": 0.9 }, "dispersion": 1.1 },
+- "extend": { "effects": [ "RECYCLED" ] },
+- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+- },
+- {
+- "id": "reloaded_shot_00",
+- "copy-from": "shot_00",
+- "type": "AMMO",
+- "name": { "str": "00 shot, reloaded" },
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
+- "extend": { "effects": [ "RECYCLED" ] },
+- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+- },
+- {
+- "id": "reloaded_shot_flechette",
+- "copy-from": "shot_flechette",
+- "type": "AMMO",
+- "name": { "str": "flechette shell, reloaded" },
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
+- "extend": { "effects": [ "RECYCLED" ] },
+- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+- },
+- {
+- "id": "reloaded_shot_slug",
+- "copy-from": "shot_slug",
+- "type": "AMMO",
+- "name": { "str": "shotgun slug, reloaded" },
+- "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
+- "extend": { "effects": [ "RECYCLED" ] },
+- "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+- },
+ {
+ "id": "bp_shot_bird",
+ "copy-from": "shot_bird",
+diff --git a/data/json/items/migration.json b/data/json/items/migration.json
+index 13f75ba5ed..ccda62af14 100644
+--- a/data/json/obsoletion/migration.json
++++ b/data/json/obsoletion/migration.json
+@@ -387,7 +387,7 @@
+ {
+ "id": "shot_scrapslug",
+ "type": "MIGRATION",
+- "replace": "reloaded_shot_slug"
++ "replace": "shot_slug"
+ },
+ {
+ "id": "UPS_on",
+@@ -792,7 +792,7 @@
+ {
+ "id": "reloaded_10mm",
+ "type": "MIGRATION",
+- "replace": "reloaded_10mm_fmj"
++ "replace": "10mm_fmj"
+ },
+ {
+ "id": "locket",
+@@ -827,7 +827,7 @@
+ {
+ "id": "reloaded_270",
+ "type": "MIGRATION",
+- "replace": "reloaded_270win_jsp"
++ "replace": "270win_jsp"
+ },
+ {
+ "id": "afs_rolling_pin",
+@@ -1247,7 +1247,7 @@
+ {
+ "id": "reloaded_22_fmj",
+ "type": "MIGRATION",
+- "replace": "reloaded_22_cphp"
++ "replace": "22_cphp"
+ },
+ {
+ "id": "hickory_nut_unshelled",
+@@ -1320,5 +1320,345 @@
+ "id": "raw_butter",
+ "type": "MIGRATION",
+ "replace": "butter"
++ },
++ {
++ "id": "reloaded_32_acp",
++ "type": "MIGRATION",
++ "replace": "32_acp"
++ },
++ {
++ "id": "reloaded_38_fmj",
++ "type": "MIGRATION",
++ "replace": "38_fmj"
++ },
++ {
++ "id": "reloaded_38_special",
++ "type": "MIGRATION",
++ "replace": "38_special"
++ },
++ {
++ "id": "reloaded_38super_fmj",
++ "type": "MIGRATION",
++ "replace": "38super_fmj"
++ },
++ {
++ "id": "reloaded_357sig_fmj",
++ "type": "MIGRATION",
++ "replace": "357sig_fmj"
++ },
++ {
++ "id": "reloaded_357sig_jhp",
++ "type": "MIGRATION",
++ "replace": "357sig_jhp"
++ },
++ {
++ "id": "reloaded_357mag_fmj",
++ "type": "MIGRATION",
++ "replace": "357mag_fmj"
++ },
++ {
++ "id": "reloaded_357mag_jhp",
++ "type": "MIGRATION",
++ "replace": "357mag_jhp"
++ },
++ {
++ "id": "reloaded_38_super",
++ "type": "MIGRATION",
++ "replace": "38_super"
++ },
++ {
++ "id": "reloaded_40fmj",
++ "type": "MIGRATION",
++ "replace": "40fmj"
++ },
++ {
++ "id": "reloaded_40sw",
++ "type": "MIGRATION",
++ "replace": "40sw"
++ },
++ {
++ "id": "reloaded_10mm_fmj",
++ "type": "MIGRATION",
++ "replace": "10mm_fmj"
++ },
++ {
++ "id": "reloaded_44fmj",
++ "type": "MIGRATION",
++ "replace": "44fmj"
++ },
++ {
++ "id": "reloaded_44magnum",
++ "type": "MIGRATION",
++ "replace": "44magnum"
++ },
++ {
++ "id": "reloaded_45_acp",
++ "type": "MIGRATION",
++ "replace": "45_acp"
++ },
++ {
++ "id": "reloaded_45_jhp",
++ "type": "MIGRATION",
++ "replace": "45_jhp"
++ },
++ {
++ "id": "reloaded_45_super",
++ "type": "MIGRATION",
++ "replace": "45_super"
++ },
++ {
++ "id": "reloaded_454_Casull",
++ "type": "MIGRATION",
++ "replace": "454_Casull"
++ },
++ {
++ "id": "reloaded_45colt_jhp",
++ "type": "MIGRATION",
++ "replace": "45colt_jhp"
++ },
++ {
++ "id": "reloaded_46mm",
++ "type": "MIGRATION",
++ "replace": "46mm"
++ },
++ {
++ "id": "reloaded_460_fmj",
++ "type": "MIGRATION",
++ "replace": "460_fmj"
++ },
++ {
++ "id": "reloaded_460_rowland",
++ "type": "MIGRATION",
++ "replace": "460_rowland"
++ },
++ {
++ "id": "reloaded_500_Magnum",
++ "type": "MIGRATION",
++ "replace": "500_Magnum"
++ },
++ {
++ "id": "reloaded_57mm",
++ "type": "MIGRATION",
++ "replace": "57mm"
++ },
++ {
++ "id": "reloaded_762_25",
++ "type": "MIGRATION",
++ "replace": "762_25"
++ },
++ {
++ "id": "reloaded_9mm",
++ "type": "MIGRATION",
++ "replace": "9mm"
++ },
++ {
++ "id": "reloaded_9mmP",
++ "type": "MIGRATION",
++ "replace": "9mmP"
++ },
++ {
++ "id": "reloaded_9mmP2",
++ "type": "MIGRATION",
++ "replace": "9mmP2"
++ },
++ {
++ "id": "reloaded_9mmfmj",
++ "type": "MIGRATION",
++ "replace": "9mmfmj"
++ },
++ {
++ "id": "reloaded_9x18mm",
++ "type": "MIGRATION",
++ "replace": "9x18mm"
++ },
++ {
++ "id": "reloaded_9x18mmfmj",
++ "type": "MIGRATION",
++ "replace": "9x18mmfmj"
++ },
++ {
++ "id": "reloaded_9x18mmP2",
++ "type": "MIGRATION",
++ "replace": "9x18mmP2"
++ },
++ {
++ "id": "reloaded_380_JHP",
++ "type": "MIGRATION",
++ "replace": "380_JHP"
++ },
++ {
++ "id": "reloaded_380_p",
++ "type": "MIGRATION",
++ "replace": "380_p"
++ },
++ {
++ "id": "reloaded_380_FMJ",
++ "type": "MIGRATION",
++ "replace": "380_FMJ"
++ },
++ {
++ "id": "reloaded_22_cphp",
++ "type": "MIGRATION",
++ "replace": "22_cphp"
++ },
++ {
++ "id": "reloaded_22_lr",
++ "type": "MIGRATION",
++ "replace": "22_lr"
++ },
++ {
++ "id": "reloaded_223",
++ "type": "MIGRATION",
++ "replace": "223"
++ },
++ {
++ "id": "reloaded_270win_jsp",
++ "type": "MIGRATION",
++ "replace": "270win_jsp"
++ },
++ {
++ "id": "reloaded_300_winmag",
++ "type": "MIGRATION",
++ "replace": "300_winmag"
++ },
++ {
++ "id": "reloaded_3006",
++ "type": "MIGRATION",
++ "replace": "3006"
++ },
++ {
++ "id": "reloaded_3006fmj",
++ "type": "MIGRATION",
++ "replace": "3006fmj"
++ },
++ {
++ "id": "reloaded_3006_incendiary",
++ "type": "MIGRATION",
++ "replace": "3006_incendiary"
++ },
++ {
++ "id": "reloaded_308",
++ "type": "MIGRATION",
++ "replace": "308"
++ },
++ {
++ "id": "reloaded_4570_sp",
++ "type": "MIGRATION",
++ "replace": "4570_sp"
++ },
++ {
++ "id": "reloaded_4570_pen",
++ "type": "MIGRATION",
++ "replace": "4570_pen"
++ },
++ {
++ "id": "reloaded_4570_low",
++ "type": "MIGRATION",
++ "replace": "4570_low"
++ },
++ {
++ "id": "reloaded_50bmg",
++ "type": "MIGRATION",
++ "replace": "50bmg"
++ },
++ {
++ "id": "reloaded_50_incendiary",
++ "type": "MIGRATION",
++ "replace": "50_incendiary"
++ },
++ {
++ "id": "reloaded_50ss",
++ "type": "MIGRATION",
++ "replace": "50ss"
++ },
++ {
++ "id": "reloaded_545",
++ "type": "MIGRATION",
++ "replace": "545"
++ },
++ {
++ "id": "reloaded_545_ap",
++ "type": "MIGRATION",
++ "replace": "545_ap"
++ },
++ {
++ "id": "reloaded_300blk",
++ "type": "MIGRATION",
++ "replace": "300blk"
++ },
++ {
++ "id": "reloaded_556",
++ "type": "MIGRATION",
++ "replace": "556"
++ },
++ {
++ "id": "reloaded_556_incendiary",
++ "type": "MIGRATION",
++ "replace": "556_incendiary"
++ },
++ {
++ "id": "reloaded_700nx",
++ "type": "MIGRATION",
++ "replace": "700nx"
++ },
++ {
++ "id": "reloaded_762_51",
++ "type": "MIGRATION",
++ "replace": "762_51"
++ },
++ {
++ "id": "reloaded_762_51_incendiary",
++ "type": "MIGRATION",
++ "replace": "762_51_incendiary"
++ },
++ {
++ "id": "reloaded_762_54R",
++ "type": "MIGRATION",
++ "replace": "762_54R"
++ },
++ {
++ "id": "reloaded_762_m43",
++ "type": "MIGRATION",
++ "replace": "762_m43"
++ },
++ {
++ "id": "reloaded_762_m87",
++ "type": "MIGRATION",
++ "replace": "762_m87"
++ },
++ {
++ "id": "reloaded_shot_00",
++ "type": "MIGRATION",
++ "replace": "shot_00"
++ },
++ {
++ "id": "reloaded_410shot_000",
++ "type": "MIGRATION",
++ "replace": "410shot_000"
++ },
++ {
++ "id": "reloaded_shot_bird",
++ "type": "MIGRATION",
++ "replace": "shot_bird"
++ },
++ {
++ "id": "reloaded_shot_dragon",
++ "type": "MIGRATION",
++ "replace": "shot_dragon"
++ },
++ {
++ "id": "reloaded_shot_flechette",
++ "type": "MIGRATION",
++ "replace": "shot_flechette"
++ },
++ {
++ "id": "reloaded_shot_slug",
++ "type": "MIGRATION",
++ "replace": "shot_slug"
++ },
++ {
++ "id": "reloaded_5x50dart",
++ "type": "MIGRATION",
++ "replace": "5x50dart"
+ },
+ {
+ "id": "mutant_offal_cooked",
+ "type": "MIGRATION",
+diff --git a/data/json/obsoletion/items.json b/data/json/obsoletion/items.json
+index a3819132f6..b8c26c57dd 100644
+--- a/data/json/obsoletion/items.json
++++ b/data/json/obsoletion/items.json
+@@ -3707,6 +3707,632 @@
+ "transform_age": 21600,
+ "not_ready_msg": "The cream has not risen yet."
+ }
++ },
++ {
++ "id": "reloaded_5x50dart",
++ "copy-from": "5x50dart",
++ "type": "AMMO",
++ "name": { "str": "5x50mm flechette, reloaded" },
++ "price_postapoc": "12 USD",
++ "description": "Designed to defeat modern body armor, the Rivtech 5x50mm flechette round features a biodegradable sabot and a single, fin-stabilized penetrator. This one has been hand-reloaded.",
++ "effects": [ "COOKOFF", "RECYCLED" ],
++ "relative": { "range": -15, "dispersion": 40 },
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9, "armor_penetration": 0.7 }, "recoil": 0.9 }
++ },
++ {
++ "id": "reloaded_9mm",
++ "copy-from": "9mm",
++ "type": "AMMO",
++ "name": { "str": "9x19mm JHP, reloaded" },
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
++ "extend": { "effects": [ "RECYCLED" ] },
++ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
++ },
++ {
++ "id": "reloaded_9mmfmj",
++ "copy-from": "9mmfmj",
++ "type": "AMMO",
++ "name": { "str": "9x19mm FMJ, reloaded" },
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
++ "extend": { "effects": [ "RECYCLED" ] },
++ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
++ },
++ {
++ "id": "reloaded_9mmP",
++ "copy-from": "9mmP",
++ "type": "AMMO",
++ "name": { "str": "9x19mm +P, reloaded" },
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
++ "extend": { "effects": [ "RECYCLED" ] },
++ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
++ },
++ {
++ "id": "reloaded_9mmP2",
++ "copy-from": "9mmP2",
++ "type": "AMMO",
++ "name": { "str": "9x19mm +P+, reloaded" },
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
++ "extend": { "effects": [ "RECYCLED" ] },
++ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
++ },
++ {
++ "id": "reloaded_9x18mm",
++ "copy-from": "9x18mm",
++ "type": "AMMO",
++ "name": { "str": "9x18mm, reloaded" },
++ "description": "9x18 millimeter Makarov, an old Soviet pistol cartridge used mainly by the Makarov PM. As the designation implies, it is a bit shorter in case length compared to 9mm Parabellum. This one has been hand-reloaded.",
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
++ "extend": { "effects": [ "RECYCLED" ] },
++ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
++ },
++ {
++ "id": "reloaded_9x18mmP2",
++ "copy-from": "9x18mmP2",
++ "type": "AMMO",
++ "name": { "str": "9x18mm +P+, reloaded" },
++ "//": "Rather than give it a military designation, this is simply handmade overpressure ammo.",
++ "description": "9x18 millimeter Makarov, an old Soviet pistol cartridge used mainly by the Makarov PM. This one has been hand-reloaded to generate higher internal pressure, boosting flight stability and damage.",
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
++ "extend": { "effects": [ "RECYCLED" ] },
++ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
++ },
++ {
++ "id": "reloaded_9x18mmfmj",
++ "copy-from": "9x18mmfmj",
++ "type": "AMMO",
++ "name": { "str": "9x18mm FMJ, reloaded" },
++ "description": "9x18 millimeter Makarov, an old Soviet pistol cartridge used mainly by the Makarov PM. This brass-jacketed round increases penetration slightly, at the cost of reduced expansion. This one has been hand-reloaded.",
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
++ "extend": { "effects": [ "RECYCLED" ] },
++ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
++ },
++ {
++ "id": "reloaded_10mm_fmj",
++ "copy-from": "10mm_fmj",
++ "type": "AMMO",
++ "name": { "str": "10mm Auto FMJ, reloaded" },
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
++ "extend": { "effects": [ "RECYCLED" ] },
++ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
++ },
++ {
++ "id": "reloaded_22_lr",
++ "copy-from": "22_lr",
++ "type": "AMMO",
++ "name": { "str": ".22 LR, reloaded" },
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
++ "extend": { "effects": [ "RECYCLED" ] },
++ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
++ },
++ {
++ "id": "reloaded_22_cphp",
++ "copy-from": "22_cphp",
++ "type": "AMMO",
++ "name": { "str": ".22 CPHP, reloaded" },
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
++ "extend": { "effects": [ "RECYCLED" ] },
++ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
++ },
++ {
++ "id": "reloaded_32_acp",
++ "copy-from": "32_acp",
++ "type": "AMMO",
++ "name": { "str": ".32 ACP, reloaded" },
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
++ "extend": { "effects": [ "RECYCLED" ] },
++ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
++ },
++ {
++ "id": "reloaded_38_fmj",
++ "copy-from": "38_fmj",
++ "type": "AMMO",
++ "name": { "str": ".38 FMJ, reloaded" },
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
++ "extend": { "effects": [ "RECYCLED" ] },
++ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
++ },
++ {
++ "id": "reloaded_38_special",
++ "copy-from": "38_special",
++ "type": "AMMO",
++ "name": { "str": ".38 Special, reloaded" },
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
++ "extend": { "effects": [ "RECYCLED" ] },
++ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
++ },
++ {
++ "id": "reloaded_38super_fmj",
++ "copy-from": "38super_fmj",
++ "type": "AMMO",
++ "name": { "str": ".38 Super FMJ, reloaded" },
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
++ "extend": { "effects": [ "RECYCLED" ] },
++ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
++ },
++ {
++ "id": "reloaded_38_super",
++ "copy-from": "38_super",
++ "type": "AMMO",
++ "name": { "str": ".38 Super, reloaded" },
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
++ "extend": { "effects": [ "RECYCLED" ] },
++ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
++ },
++ {
++ "id": "reloaded_40fmj",
++ "copy-from": "40fmj",
++ "type": "AMMO",
++ "name": { "str": ".40 S&W FMJ, reloaded" },
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
++ "extend": { "effects": [ "RECYCLED" ] },
++ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
++ },
++ {
++ "id": "reloaded_40sw",
++ "copy-from": "40sw",
++ "type": "AMMO",
++ "name": { "str": ".40 S&W JHP, reloaded" },
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
++ "extend": { "effects": [ "RECYCLED" ] },
++ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
++ },
++ {
++ "id": "reloaded_44fmj",
++ "copy-from": "44fmj",
++ "type": "AMMO",
++ "name": { "str": ".44 Magnum FMJ, reloaded" },
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
++ "extend": { "effects": [ "RECYCLED" ] },
++ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
++ },
++ {
++ "id": "reloaded_44magnum",
++ "copy-from": "44magnum",
++ "type": "AMMO",
++ "name": { "str": ".44 Magnum, reloaded" },
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
++ "extend": { "effects": [ "RECYCLED" ] },
++ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
++ },
++ {
++ "id": "reloaded_45_acp",
++ "copy-from": "45_acp",
++ "type": "AMMO",
++ "name": { "str": ".45 FMJ, reloaded" },
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
++ "extend": { "effects": [ "RECYCLED" ] },
++ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
++ },
++ {
++ "id": "reloaded_45_jhp",
++ "copy-from": "45_jhp",
++ "type": "AMMO",
++ "name": { "str": ".45 ACP JHP, reloaded" },
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
++ "extend": { "effects": [ "RECYCLED" ] },
++ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
++ },
++ {
++ "id": "reloaded_45_super",
++ "copy-from": "45_super",
++ "type": "AMMO",
++ "name": { "str": ".45 ACP +P, reloaded" },
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
++ "extend": { "effects": [ "RECYCLED" ] },
++ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
++ },
++ {
++ "id": "reloaded_45colt_jhp",
++ "copy-from": "45colt_jhp",
++ "type": "AMMO",
++ "name": { "str": ".45 Colt JHP, reloaded" },
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
++ "extend": { "effects": [ "RECYCLED" ] },
++ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
++ },
++ {
++ "id": "reloaded_46mm",
++ "copy-from": "46mm",
++ "type": "AMMO",
++ "name": { "str": "4.6x30mm, reloaded" },
++ "description": "4.6x30mm ammunition with 31gr copper plated lead bullets. The 4.6x30mm round was developed by H&K to compete with FN Herstal's 5.7x28mm cartridge. It has low recoil, but no usual armor penetration due to using simple lead bullets rather than proper factory-made penetrator projectiles.",
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9, "armor_penetration": 0.2 }, "dispersion": 1.1 },
++ "extend": { "effects": [ "RECYCLED" ] },
++ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
++ },
++ {
++ "id": "reloaded_50_incendiary",
++ "copy-from": "50_incendiary",
++ "type": "AMMO",
++ "name": { "str": ".50 BMG tracer, reloaded" },
++ "description": "A tracer variant of the powerful .50 BMG round. Tracer rounds help to keep the weapon they are fired from on target at the risk of igniting flammable substances. This one has been hand-reloaded.",
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
++ "extend": { "effects": [ "RECYCLED" ] },
++ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
++ },
++ {
++ "id": "reloaded_50bmg",
++ "copy-from": "50match",
++ "type": "AMMO",
++ "name": { "str": ".50 BMG Match, reloaded" },
++ "description": ".50 BMG ammunition with lead-cored FMJ bullets. The .50 BMG is a very powerful rifle round designed for anti-aircraft use, later adapted to anti-vehicular and anti-personnel roles. Its stupendous energy and armor piercing capabilities make it one of the most deadly rounds available, offset only by its drastic recoil and noise.",
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
++ "extend": { "effects": [ "RECYCLED" ] },
++ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
++ },
++ {
++ "id": "reloaded_50ss",
++ "copy-from": "50ss",
++ "type": "AMMO",
++ "name": { "str": ".50 BMG AP, reloaded" },
++ "description": "Variant of the .50 BMG round that uses a core hardened steel. Penetration is increased, but damage is reduced. This one has been hand-reloaded.",
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
++ "extend": { "effects": [ "RECYCLED" ] },
++ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
++ },
++ {
++ "id": "reloaded_57mm",
++ "copy-from": "57mm",
++ "type": "AMMO",
++ "name": { "str": "5.7x28mm, reloaded" },
++ "description": "5.7x28mm ammunition with 31gr AP FMJ bullets. The 5.7x28mm cartridge was designed by FN Herstal to replace the 9x19mm round in NATO use. Although the project to replace 9x19mm Parabellum was effectively canceled the 5.7x28mm round has seen action in many conflicts and has proven to be reliable. It has very low recoil but no usual armor penetration due to using simple lead bullets rather than proper factory-made penetrator projectiles.",
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9, "armor_penetration": 0.2 }, "dispersion": 1.1 },
++ "extend": { "effects": [ "RECYCLED" ] },
++ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
++ },
++ {
++ "id": "reloaded_223",
++ "copy-from": "223",
++ "type": "AMMO",
++ "name": { "str": ".223 Remington, reloaded" },
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
++ "extend": { "effects": [ "RECYCLED" ] },
++ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
++ },
++ {
++ "id": "reloaded_556",
++ "copy-from": "556",
++ "type": "AMMO",
++ "name": { "str": "5.56 NATO, reloaded" },
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
++ "extend": { "effects": [ "RECYCLED" ] },
++ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
++ },
++ {
++ "id": "reloaded_556_incendiary",
++ "copy-from": "556_incendiary",
++ "type": "AMMO",
++ "name": { "str": "5.56 NATO tracer, reloaded" },
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
++ "extend": { "effects": [ "RECYCLED" ] },
++ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
++ },
++ {
++ "id": "reloaded_270win_jsp",
++ "copy-from": "270win_jsp",
++ "type": "AMMO",
++ "name": { "str": ".270 Winchester JSP, reloaded" },
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
++ "extend": { "effects": [ "RECYCLED" ] },
++ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
++ },
++ {
++ "id": "reloaded_300_winmag",
++ "copy-from": "300_winmag",
++ "type": "AMMO",
++ "name": { "str": ".300 Winchester Magnum, reloaded" },
++ "description": "The .300 Winchester Magnum is extremely versatile and has been adopted by many shooting disciplines. The cartridge has found use by hunters, military units, and law enforcement departments. This one has been hand-reloaded.",
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
++ "extend": { "effects": [ "RECYCLED" ] },
++ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
++ },
++ {
++ "id": "reloaded_300blk",
++ "copy-from": "300blk",
++ "type": "AMMO",
++ "name": { "str": ".300 AAC Blackout, reloaded" },
++ "description": ".300 AAC Blackout is an intermediate cartridge that achieves ballistics similar to the 7.62x39 but allows use on the AR-15 platform. The round is necked-up from the 5.56mm NATO, but feeds from a STANAG magazine. It requires a specific barrel, so will not work in a standard M4 or similar carbine. This one has been hand-reloaded.",
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
++ "extend": { "effects": [ "RECYCLED" ] },
++ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
++ },
++ {
++ "id": "reloaded_308",
++ "copy-from": "308",
++ "type": "AMMO",
++ "name": { "str": ".308 Winchester, reloaded" },
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
++ "extend": { "effects": [ "RECYCLED" ] },
++ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
++ },
++ {
++ "id": "reloaded_762_51",
++ "copy-from": "762_51",
++ "type": "AMMO",
++ "name": { "str": "7.62x51mm, reloaded" },
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
++ "extend": { "effects": [ "RECYCLED" ] },
++ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
++ },
++ {
++ "id": "reloaded_762_51_incendiary",
++ "copy-from": "762_51_incendiary",
++ "type": "AMMO",
++ "name": { "str": "7.62x51mm incendiary, reloaded" },
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
++ "extend": { "effects": [ "RECYCLED" ] },
++ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
++ },
++ {
++ "id": "reloaded_357mag_fmj",
++ "copy-from": "357mag_fmj",
++ "type": "AMMO",
++ "name": { "str_sp": ".357 Magnum FMJ, reloaded" },
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1, "recoil": 0.9 }
++ },
++ {
++ "id": "reloaded_357mag_jhp",
++ "copy-from": "357mag_jhp",
++ "type": "AMMO",
++ "name": { "str_sp": ".357 Magnum JHP, reloaded" },
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1, "recoil": 0.9 }
++ },
++ {
++ "id": "reloaded_357sig_fmj",
++ "copy-from": "357sig_fmj",
++ "type": "AMMO",
++ "name": { "str": ".357 SIG FMJ, reloaded" },
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
++ "extend": { "effects": [ "RECYCLED" ] },
++ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
++ },
++ {
++ "id": "reloaded_357sig_jhp",
++ "copy-from": "357sig_jhp",
++ "type": "AMMO",
++ "name": { "str": ".357 SIG JHP, reloaded" },
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
++ "extend": { "effects": [ "RECYCLED" ] },
++ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
++ },
++ {
++ "id": "reloaded_380_FMJ",
++ "copy-from": "380_FMJ",
++ "type": "AMMO",
++ "name": { "str": ".380 ACP FMJ, reloaded" },
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
++ "extend": { "effects": [ "RECYCLED" ] },
++ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
++ },
++ {
++ "id": "reloaded_380_JHP",
++ "copy-from": "380_JHP",
++ "type": "AMMO",
++ "name": { "str": ".380 ACP JHP, reloaded" },
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
++ "extend": { "effects": [ "RECYCLED" ] },
++ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
++ },
++ {
++ "id": "reloaded_380_p",
++ "copy-from": "380_p",
++ "type": "AMMO",
++ "name": { "str": ".380 ACP +P, reloaded" },
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
++ "extend": { "effects": [ "RECYCLED" ] },
++ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
++ },
++ {
++ "id": "reloaded_410shot_000",
++ "copy-from": "410shot_000",
++ "type": "AMMO",
++ "name": { "str": ".410 000 shot, reloaded" },
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
++ "extend": { "effects": [ "RECYCLED" ] },
++ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
++ },
++ {
++ "id": "reloaded_454_Casull",
++ "copy-from": "454_Casull",
++ "type": "AMMO",
++ "name": { "str": ".454 Casull, reloaded" },
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
++ "extend": { "effects": [ "RECYCLED" ] },
++ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
++ },
++ {
++ "id": "reloaded_460_fmj",
++ "copy-from": "460_fmj",
++ "type": "AMMO",
++ "name": { "str": ".460 Rowland FMJ, reloaded" },
++ "description": "A brass-jacketed variant of the .460 Rowland round. This increases penetration slightly at the cost of reduced damage from expansion.",
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
++ "extend": { "effects": [ "RECYCLED" ] },
++ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
++ },
++ {
++ "id": "reloaded_460_rowland",
++ "copy-from": "460_rowland",
++ "type": "AMMO",
++ "name": { "str": ".460 Rowland, reloaded" },
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
++ "extend": { "effects": [ "RECYCLED" ] },
++ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
++ },
++ {
++ "id": "reloaded_500_Magnum",
++ "copy-from": "500_Magnum",
++ "type": "AMMO",
++ "name": { "str": ".500 S&W Magnum, reloaded" },
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
++ "extend": { "effects": [ "RECYCLED" ] },
++ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
++ },
++ {
++ "id": "reloaded_545",
++ "copy-from": "545",
++ "type": "AMMO",
++ "name": { "str": "5.45x39mm, reloaded" },
++ "description": "The 5.45x39mm was the standard ammunition for the AK series from 1974. Its designers were inspired by the 5.56x45mm NATO cartridge. This one has been hand-reloaded.",
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
++ "extend": { "effects": [ "RECYCLED" ] },
++ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
++ },
++ {
++ "id": "reloaded_545_ap",
++ "copy-from": "545_ap",
++ "type": "AMMO",
++ "name": { "str": "5.45x39mm AP, reloaded" },
++ "description": "Armor piercing 5.45x39mm ammunition with hand-reloaded bullets containing a steel penetrator. Developed in 1998 by the Russian military.",
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
++ "extend": { "effects": [ "RECYCLED" ] },
++ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
++ },
++ {
++ "id": "reloaded_700nx",
++ "copy-from": "700nx",
++ "type": "AMMO",
++ "name": { "str": ".700 NX, reloaded" },
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
++ "extend": { "effects": [ "RECYCLED" ] },
++ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
++ },
++ {
++ "id": "reloaded_762_m43",
++ "copy-from": "762_m43",
++ "type": "AMMO",
++ "name": { "str": "7.62x39mm M43, reloaded" },
++ "description": "7.62x39mm ammunition with 121.9gr bullets. Developed in WW2 by the Soviet Union the 7.62x39mm round rapidly became extremely popular all over the world. The bullet has poor wounding potential due to its stability, only beginning to yaw after 26cm.",
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
++ "extend": { "effects": [ "RECYCLED" ] },
++ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
++ },
++ {
++ "id": "reloaded_762_m87",
++ "copy-from": "762_m87",
++ "type": "AMMO",
++ "name": { "str": "7.62x39mm M67, reloaded" },
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
++ "extend": { "effects": [ "RECYCLED" ] },
++ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
++ },
++ {
++ "id": "reloaded_762_54R",
++ "copy-from": "762_54R",
++ "type": "AMMO",
++ "name": { "str": "7.62x54mmR, reloaded" },
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
++ "extend": { "effects": [ "RECYCLED" ] },
++ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
++ },
++ {
++ "id": "reloaded_762_25",
++ "copy-from": "762_25hot",
++ "type": "AMMO",
++ "name": { "str": "7.62x25mm, reloaded" },
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9, "armor_penetration": 0.9 }, "dispersion": 1.1 }
++ },
++ {
++ "id": "reloaded_3006",
++ "copy-from": "3006",
++ "type": "AMMO",
++ "name": { "str": ".30-06 Springfield, reloaded" },
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
++ "extend": { "effects": [ "RECYCLED" ] },
++ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
++ },
++ {
++ "id": "reloaded_3006_incendiary",
++ "copy-from": "3006_incendiary",
++ "type": "AMMO",
++ "name": { "str": ".30-06 incendiary, reloaded" },
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
++ "extend": { "effects": [ "RECYCLED" ] },
++ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
++ },
++ {
++ "id": "reloaded_3006fmj",
++ "copy-from": "3006fmj",
++ "type": "AMMO",
++ "name": { "str": ".30-06 M2 AP, reloaded" },
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
++ "extend": { "effects": [ "RECYCLED" ] },
++ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
++ },
++ {
++ "id": "reloaded_4570_sp",
++ "copy-from": "4570_sp",
++ "type": "AMMO",
++ "name": { "str": ".45-70 SP, reloaded" },
++ "description": ".45-70 Government ammunition loaded with a 305 grain soft point round. One of the oldest cartridges still in use, it is still a favorite for large game hunting at short ranges. This one has been hand-loaded.",
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
++ "extend": { "effects": [ "RECYCLED" ] },
++ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
++ },
++ {
++ "id": "reloaded_4570_pen",
++ "copy-from": "4570_pen",
++ "type": "AMMO",
++ "name": { "str": ".45-70 +P penetrator, reloaded" },
++ "description": ".45-70 Government +P ammunition loaded with a 305 grain solid copper penetrator projectile. Designed for maximum penetration through thick hide and bone while maintaining ideal wounding characteristics. This one has been hand-loaded.",
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
++ "extend": { "effects": [ "RECYCLED" ] },
++ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
++ },
++ {
++ "id": "reloaded_4570_low",
++ "copy-from": "4570_low",
++ "type": "AMMO",
++ "name": { "str": ".45-70 LFN cowboy, reloaded" },
++ "description": ".45-70 Government ammunition loaded with a 405 grain lead flat nose bullet to original specifications for safe use in antique firearms. Quite a bit less powerful than modern ammo, but still packs a punch. This one has been hand-loaded.",
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
++ "extend": { "effects": [ "RECYCLED" ] },
++ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
++ },
++ {
++ "id": "reloaded_shot_bird",
++ "copy-from": "shot_bird",
++ "type": "AMMO",
++ "name": { "str": "birdshot, reloaded" },
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
++ "extend": { "effects": [ "RECYCLED" ] },
++ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
++ },
++ {
++ "id": "reloaded_shot_dragon",
++ "copy-from": "shot_dragon",
++ "type": "AMMO",
++ "name": { "str": "dragon's breath shell, reloaded" },
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
++ "extend": { "effects": [ "RECYCLED" ] },
++ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
++ },
++ {
++ "id": "reloaded_shot_00",
++ "copy-from": "shot_00",
++ "type": "AMMO",
++ "name": { "str": "00 shot, reloaded" },
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
++ "extend": { "effects": [ "RECYCLED" ] },
++ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
++ },
++ {
++ "id": "reloaded_shot_flechette",
++ "copy-from": "shot_flechette",
++ "type": "AMMO",
++ "name": { "str": "flechette shell, reloaded" },
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
++ "extend": { "effects": [ "RECYCLED" ] },
++ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
++ },
++ {
++ "id": "reloaded_shot_slug",
++ "copy-from": "shot_slug",
++ "type": "AMMO",
++ "name": { "str": "shotgun slug, reloaded" },
++ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
++ "extend": { "effects": [ "RECYCLED" ] },
++ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+ },
+ {
+ "id": "flu_shot",
+diff --git a/data/json/obsoletion/recipes.json b/data/json/obsoletion/recipes.json
+index 36e24fedb5..ef04e54bbe 100644
+--- a/data/json/obsoletion/recipes.json
++++ b/data/json/obsoletion/recipes.json
+@@ -2693,5 +2693,345 @@
+ "type": "recipe",
+ "result": "milk_cream",
+ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_32_acp",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_38_fmj",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_38_special",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_38super_fmj",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_357sig_fmj",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_357sig_jhp",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_357mag_fmj",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_357mag_jhp",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_38_super",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_40fmj",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_40sw",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_10mm_fmj",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_44fmj",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_44magnum",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_45_acp",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_45_jhp",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_45_super",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_454_Casull",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_45colt_jhp",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_46mm",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_460_fmj",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_460_rowland",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_500_Magnum",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_57mm",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_762_25",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_9mm",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_9mmP",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_9mmP2",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_9mmfmj",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_9x18mm",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_9x18mmfmj",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_9x18mmP2",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_380_JHP",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_380_FMJ",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_380_p",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_22_cphp",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_22_lr",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_223",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_270win_jsp",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_300_winmag",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_3006",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_3006fmj",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_3006_incendiary",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_308",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_4570_sp",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_4570_pen",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_4570_low",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_5x50dart",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_50bmg",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_50_incendiary",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_50ss",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_545",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_545_ap",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_300blk",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_556",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_556_incendiary",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_700nx",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_762_51",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_762_51_incendiary",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_762_54R",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_762_m43",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_762_m87",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_shot_00",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_410shot_000",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_shot_bird",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_shot_dragon",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_shot_flechette",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "reloaded_shot_slug",
++ "obsolete": true
+ },
+ {
+ "type": "recipe",
+diff --git a/data/json/recipes/ammo/pistol.json b/data/json/recipes/ammo/pistol.json
+index dad829873c..66c943d2d2 100644
+--- a/data/json/recipes/ammo/pistol.json
++++ b/data/json/recipes/ammo/pistol.json
+@@ -125,7 +125,7 @@
+ "charges": 1,
+ "reversible": true,
+ "using": [ [ "bullet_forming", 3 ], [ "ammo_bullet", 3 ] ],
+- "components": [ [ [ "45_casing", 1 ] ], [ [ "lgpistol_primer", 1 ] ], [ [ "chem_black_powder", 6 ] ] ]
++ "components": [ [ [ "45_casing", 1 ] ], [ [ "lgpistol_primer", 1 ] ], [ [ "chem_black_powder", 6 ] ], [ [ "copper", 2 ] ] ]
+ },
+ {
+ "result": "bp_45_jhp",
+@@ -338,7 +338,7 @@
+ "components": [ [ [ "chem_black_powder", 4 ] ], [ [ "lgpistol_primer", 1 ] ], [ [ "paper", 1 ], [ "aluminum_foil", 1 ] ] ]
+ },
+ {
+- "result": "reloaded_32_acp",
++ "result": "32_acp",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_PISTOL",
+@@ -349,12 +349,11 @@
+ "batch_time_factors": [ 60, 5 ],
+ "book_learn": [ [ "recipe_bullets", 5 ] ],
+ "charges": 1,
+- "reversible": true,
+ "using": [ [ "bullet_forming", 2 ], [ "ammo_bullet", 2 ] ],
+ "components": [ [ [ "32_casing", 1 ] ], [ [ "smpistol_primer", 1 ] ], [ [ "gunpowder", 2 ] ] ]
+ },
+ {
+- "result": "reloaded_38_fmj",
++ "result": "38_fmj",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_PISTOL",
+@@ -365,12 +364,11 @@
+ "batch_time_factors": [ 60, 5 ],
+ "book_learn": [ [ "manual_pistol", 2 ], [ "recipe_bullets", 3 ] ],
+ "charges": 1,
+- "reversible": true,
+ "using": [ [ "bullet_forming", 2 ], [ "ammo_bullet", 2 ] ],
+ "components": [ [ [ "38_casing", 1 ] ], [ [ "smpistol_primer", 1 ] ], [ [ "gunpowder", 2 ] ], [ [ "copper", 1 ] ] ]
+ },
+ {
+- "result": "reloaded_38_special",
++ "result": "38_special",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_PISTOL",
+@@ -381,12 +379,26 @@
+ "batch_time_factors": [ 60, 5 ],
+ "book_learn": [ [ "manual_pistol", 1 ], [ "recipe_bullets", 2 ] ],
+ "charges": 1,
+- "reversible": true,
+ "using": [ [ "bullet_forming", 2 ], [ "ammo_bullet", 2 ] ],
+ "components": [ [ [ "38_casing", 1 ] ], [ [ "smpistol_primer", 1 ] ], [ [ "gunpowder", 2 ] ] ]
+ },
+ {
+- "result": "reloaded_38super_fmj",
++ "result": "38_super",
++ "type": "recipe",
++ "category": "CC_AMMO",
++ "subcategory": "CSC_AMMO_PISTOL",
++ "skill_used": "fabrication",
++ "difficulty": 4,
++ "skills_required": [ "gun", 3 ],
++ "time": "2 m",
++ "batch_time_factors": [ 60, 5 ],
++ "book_learn": [ [ "manual_pistol", 3 ] ],
++ "charges": 1,
++ "using": [ [ "bullet_forming", 2 ], [ "ammo_bullet", 2 ], [ "ammo_38super", 1 ] ],
++ "components": [ [ [ "gunpowder", 3 ] ] ]
++ },
++ {
++ "result": "38super_fmj",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_PISTOL",
+@@ -397,12 +409,11 @@
+ "batch_time_factors": [ 60, 5 ],
+ "book_learn": [ [ "manual_pistol", 1 ], [ "recipe_bullets", 2 ] ],
+ "charges": 1,
+- "reversible": true,
+ "using": [ [ "bullet_forming", 2 ], [ "ammo_bullet", 2 ], [ "ammo_38super", 1 ] ],
+- "components": [ [ [ "gunpowder", 3 ] ] ]
++ "components": [ [ [ "gunpowder", 3 ] ], [ [ "copper", 1 ] ] ]
+ },
+ {
+- "result": "reloaded_357sig_fmj",
++ "result": "357sig_fmj",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_PISTOL",
+@@ -413,12 +424,11 @@
+ "batch_time_factors": [ 60, 5 ],
+ "book_learn": [ [ "manual_pistol", 3 ], [ "recipe_bullets", 4 ] ],
+ "charges": 1,
+- "reversible": true,
+ "using": [ [ "bullet_forming", 2 ], [ "ammo_bullet", 2 ], [ "ammo_357sig", 1 ] ],
+ "components": [ [ [ "gunpowder", 5 ] ], [ [ "copper", 1 ] ] ]
+ },
+ {
+- "result": "reloaded_357sig_jhp",
++ "result": "357sig_jhp",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_PISTOL",
+@@ -429,12 +439,11 @@
+ "batch_time_factors": [ 60, 5 ],
+ "book_learn": [ [ "manual_pistol", 3 ], [ "recipe_bullets", 4 ] ],
+ "charges": 1,
+- "reversible": true,
+ "using": [ [ "bullet_forming", 2 ], [ "ammo_bullet", 2 ], [ "ammo_357sig", 1 ] ],
+ "components": [ [ [ "gunpowder", 5 ] ] ]
+ },
+ {
+- "result": "reloaded_357mag_fmj",
++ "result": "357mag_fmj",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_PISTOL",
+@@ -445,12 +454,11 @@
+ "batch_time_factors": [ 60, 5 ],
+ "book_learn": [ [ "manual_pistol", 3 ], [ "recipe_bullets", 4 ] ],
+ "charges": 1,
+- "reversible": true,
+ "using": [ [ "bullet_forming", 2 ], [ "ammo_bullet", 2 ], [ "ammo_357mag", 1 ] ],
+- "components": [ [ [ "gunpowder", 5 ] ] ]
++ "components": [ [ [ "gunpowder", 5 ] ], [ [ "copper", 1 ] ] ]
+ },
+ {
+- "result": "reloaded_357mag_jhp",
++ "result": "357mag_jhp",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_PISTOL",
+@@ -461,7 +469,6 @@
+ "batch_time_factors": [ 60, 5 ],
+ "book_learn": [ [ "manual_pistol", 3 ], [ "recipe_bullets", 4 ] ],
+ "charges": 1,
+- "reversible": true,
+ "using": [ [ "bullet_forming", 2 ], [ "ammo_bullet", 2 ], [ "ammo_357mag", 1 ] ],
+ "components": [ [ [ "gunpowder", 5 ] ] ]
+ },
+@@ -479,7 +486,7 @@
+ "charges": 1,
+ "reversible": true,
+ "using": [ [ "bullet_forming", 2 ], [ "ammo_bullet", 2 ], [ "ammo_357mag", 1 ] ],
+- "components": [ [ [ "chem_black_powder", 8 ] ] ]
++ "components": [ [ [ "chem_black_powder", 8 ] ], [ [ "copper", 1 ] ] ]
+ },
+ {
+ "result": "bp_357mag_jhp",
+@@ -514,23 +521,7 @@
+ "components": [ [ [ "38_casing", 1 ] ], [ [ "smpistol_primer", 1 ] ], [ [ "chem_black_powder", 3 ] ] ]
+ },
+ {
+- "result": "reloaded_38_super",
+- "type": "recipe",
+- "category": "CC_AMMO",
+- "subcategory": "CSC_AMMO_PISTOL",
+- "skill_used": "fabrication",
+- "difficulty": 4,
+- "skills_required": [ "gun", 3 ],
+- "time": "2 m",
+- "batch_time_factors": [ 60, 5 ],
+- "book_learn": [ [ "manual_pistol", 3 ] ],
+- "charges": 1,
+- "reversible": true,
+- "using": [ [ "bullet_forming", 2 ], [ "ammo_bullet", 2 ] ],
+- "components": [ [ [ "38_casing", 1 ] ], [ [ "smpistol_primer", 1 ] ], [ [ "gunpowder", 3 ] ] ]
+- },
+- {
+- "result": "reloaded_40fmj",
++ "result": "40fmj",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_PISTOL",
+@@ -541,12 +532,11 @@
+ "batch_time_factors": [ 60, 5 ],
+ "book_learn": [ [ "manual_pistol", 3 ], [ "recipe_bullets", 4 ] ],
+ "charges": 1,
+- "reversible": true,
+ "using": [ [ "bullet_forming", 2 ], [ "ammo_bullet", 2 ] ],
+ "components": [ [ [ "40_casing", 1 ] ], [ [ "smpistol_primer", 1 ] ], [ [ "gunpowder", 4 ] ], [ [ "copper", 1 ] ] ]
+ },
+ {
+- "result": "reloaded_40sw",
++ "result": "40sw",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_PISTOL",
+@@ -557,12 +547,11 @@
+ "batch_time_factors": [ 60, 5 ],
+ "book_learn": [ [ "manual_pistol", 2 ], [ "recipe_bullets", 3 ] ],
+ "charges": 1,
+- "reversible": true,
+ "using": [ [ "bullet_forming", 2 ], [ "ammo_bullet", 2 ] ],
+ "components": [ [ [ "40_casing", 1 ] ], [ [ "smpistol_primer", 1 ] ], [ [ "gunpowder", 4 ] ] ]
+ },
+ {
+- "result": "reloaded_10mm_fmj",
++ "result": "10mm_fmj",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_PISTOL",
+@@ -573,7 +562,6 @@
+ "batch_time_factors": [ 60, 5 ],
+ "book_learn": [ [ "manual_pistol", 3 ], [ "recipe_bullets", 4 ] ],
+ "charges": 1,
+- "reversible": true,
+ "using": [ [ "bullet_forming", 2 ], [ "ammo_bullet", 2 ], [ "ammo_10mm", 1 ] ],
+ "components": [ [ [ "gunpowder", 5 ] ] ]
+ },
+@@ -594,7 +582,7 @@
+ "components": [ [ [ "chem_black_powder", 8 ] ] ]
+ },
+ {
+- "result": "reloaded_44fmj",
++ "result": "44fmj",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_PISTOL",
+@@ -605,12 +593,11 @@
+ "batch_time_factors": [ 60, 5 ],
+ "book_learn": [ [ "recipe_bullets", 3 ], [ "manual_pistol", 4 ] ],
+ "charges": 1,
+- "reversible": true,
+ "using": [ [ "bullet_forming", 5 ], [ "ammo_bullet", 4 ] ],
+ "components": [ [ [ "44_casing", 1 ] ], [ [ "lgpistol_primer", 1 ] ], [ [ "gunpowder", 6 ] ], [ [ "copper", 2 ] ] ]
+ },
+ {
+- "result": "reloaded_44magnum",
++ "result": "44magnum",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_PISTOL",
+@@ -621,7 +608,6 @@
+ "batch_time_factors": [ 60, 5 ],
+ "book_learn": [ [ "recipe_bullets", 3 ], [ "manual_pistol", 4 ] ],
+ "charges": 1,
+- "reversible": true,
+ "using": [ [ "bullet_forming", 5 ], [ "ammo_bullet", 5 ] ],
+ "components": [ [ [ "44_casing", 1 ] ], [ [ "lgpistol_primer", 1 ] ], [ [ "gunpowder", 6 ] ] ]
+ },
+@@ -642,7 +628,7 @@
+ "components": [ [ [ "44_casing", 1 ] ], [ [ "lgpistol_primer", 1 ] ], [ [ "chem_black_powder", 9 ] ] ]
+ },
+ {
+- "result": "reloaded_45_acp",
++ "result": "45_acp",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_PISTOL",
+@@ -653,12 +639,11 @@
+ "batch_time_factors": [ 60, 5 ],
+ "book_learn": [ [ "manual_pistol", 3 ], [ "manual_smg", 3 ], [ "recipe_bullets", 4 ] ],
+ "charges": 1,
+- "reversible": true,
+ "using": [ [ "bullet_forming", 3 ], [ "ammo_bullet", 3 ] ],
+- "components": [ [ [ "45_casing", 1 ] ], [ [ "lgpistol_primer", 1 ] ], [ [ "gunpowder", 4 ] ] ]
++ "components": [ [ [ "45_casing", 1 ] ], [ [ "lgpistol_primer", 1 ] ], [ [ "gunpowder", 4 ] ], [ [ "copper", 2 ] ] ]
+ },
+ {
+- "result": "reloaded_45_jhp",
++ "result": "45_jhp",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_PISTOL",
+@@ -669,12 +654,11 @@
+ "batch_time_factors": [ 60, 5 ],
+ "book_learn": [ [ "manual_pistol", 2 ], [ "manual_smg", 2 ], [ "recipe_bullets", 3 ] ],
+ "charges": 1,
+- "reversible": true,
+ "using": [ [ "bullet_forming", 3 ], [ "ammo_bullet", 3 ] ],
+ "components": [ [ [ "45_casing", 1 ] ], [ [ "lgpistol_primer", 1 ] ], [ [ "gunpowder", 4 ] ] ]
+ },
+ {
+- "result": "reloaded_45_super",
++ "result": "45_super",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_PISTOL",
+@@ -685,12 +669,11 @@
+ "batch_time_factors": [ 60, 5 ],
+ "book_learn": [ [ "manual_pistol", 4 ], [ "manual_smg", 4 ] ],
+ "charges": 1,
+- "reversible": true,
+ "using": [ [ "bullet_forming", 3 ], [ "ammo_bullet", 3 ] ],
+ "components": [ [ [ "45_casing", 1 ] ], [ [ "lgpistol_primer", 1 ] ], [ [ "gunpowder", 5 ] ] ]
+ },
+ {
+- "result": "reloaded_454_Casull",
++ "result": "454_Casull",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_PISTOL",
+@@ -701,7 +684,6 @@
+ "batch_time_factors": [ 60, 5 ],
+ "book_learn": [ [ "recipe_bullets", 6 ], [ "manual_pistol", 7 ] ],
+ "charges": 1,
+- "reversible": true,
+ "using": [ [ "bullet_forming", 5 ], [ "ammo_bullet", 4 ] ],
+ "components": [ [ [ "454_casing", 1 ] ], [ [ "smrifle_primer", 1 ] ], [ [ "gunpowder", 6 ] ], [ [ "copper", 2 ] ] ]
+ },
+@@ -722,7 +704,7 @@
+ "components": [ [ [ "454_casing", 1 ] ], [ [ "smrifle_primer", 1 ] ], [ [ "chem_black_powder", 9 ] ], [ [ "copper", 2 ] ] ]
+ },
+ {
+- "result": "reloaded_45colt_jhp",
++ "result": "45colt_jhp",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_PISTOL",
+@@ -733,7 +715,6 @@
+ "batch_time_factors": [ 60, 5 ],
+ "book_learn": [ [ "recipe_bullets", 3 ], [ "manual_pistol", 4 ] ],
+ "charges": 1,
+- "reversible": true,
+ "using": [ [ "bullet_forming", 3 ], [ "ammo_bullet", 4 ], [ "ammo_45colt", 1 ] ],
+ "components": [ [ [ "gunpowder", 4 ] ] ]
+ },
+@@ -754,7 +735,7 @@
+ "components": [ [ [ "chem_black_powder", 5 ] ] ]
+ },
+ {
+- "result": "reloaded_46mm",
++ "result": "46mm",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_PISTOL",
+@@ -765,12 +746,11 @@
+ "batch_time_factors": [ 60, 5 ],
+ "book_learn": [ [ "recipe_bullets", 3 ], [ "mag_rifle", 4 ] ],
+ "charges": 1,
+- "reversible": true,
+ "using": [ [ "bullet_forming", 2 ], [ "ammo_bullet", 2 ] ],
+ "components": [ [ [ "46mm_casing", 1 ] ], [ [ "smpistol_primer", 1 ] ], [ [ "gunpowder", 4 ] ] ]
+ },
+ {
+- "result": "reloaded_460_fmj",
++ "result": "460_fmj",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_PISTOL",
+@@ -781,12 +761,11 @@
+ "batch_time_factors": [ 60, 5 ],
+ "book_learn": [ [ "recipe_bullets", 3 ], [ "manual_pistol", 4 ] ],
+ "charges": 1,
+- "reversible": true,
+ "using": [ [ "bullet_forming", 3 ], [ "ammo_bullet", 3 ] ],
+ "components": [ [ [ "460_casing", 1 ] ], [ [ "lgpistol_primer", 1 ] ], [ [ "gunpowder", 6 ] ], [ [ "copper", 2 ] ] ]
+ },
+ {
+- "result": "reloaded_460_rowland",
++ "result": "460_rowland",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_PISTOL",
+@@ -797,12 +776,11 @@
+ "batch_time_factors": [ 60, 5 ],
+ "book_learn": [ [ "recipe_bullets", 3 ], [ "manual_pistol", 4 ] ],
+ "charges": 1,
+- "reversible": true,
+ "using": [ [ "bullet_forming", 3 ], [ "ammo_bullet", 3 ] ],
+ "components": [ [ [ "460_casing", 1 ] ], [ [ "lgpistol_primer", 1 ] ], [ [ "gunpowder", 6 ] ] ]
+ },
+ {
+- "result": "reloaded_500_Magnum",
++ "result": "500_Magnum",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_PISTOL",
+@@ -813,12 +791,11 @@
+ "batch_time_factors": [ 60, 5 ],
+ "book_learn": [ [ "recipe_bullets", 7 ], [ "manual_pistol", 8 ] ],
+ "charges": 1,
+- "reversible": true,
+ "using": [ [ "bullet_forming", 6 ], [ "ammo_bullet", 5 ] ],
+ "components": [ [ [ "500_casing", 1 ] ], [ [ "lgrifle_primer", 1 ] ], [ [ "gunpowder", 8 ] ], [ [ "copper", 2 ] ] ]
+ },
+ {
+- "result": "reloaded_57mm",
++ "result": "57mm",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_PISTOL",
+@@ -829,12 +806,11 @@
+ "batch_time_factors": [ 60, 5 ],
+ "book_learn": [ [ "recipe_bullets", 3 ], [ "mag_rifle", 4 ] ],
+ "charges": 1,
+- "reversible": true,
+ "using": [ [ "bullet_forming", 2 ], [ "ammo_bullet", 2 ] ],
+ "components": [ [ [ "57mm_casing", 1 ] ], [ [ "smrifle_primer", 1 ] ], [ [ "gunpowder", 4 ] ] ]
+ },
+ {
+- "result": "reloaded_762_25",
++ "result": "762_25",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_PISTOL",
+@@ -845,12 +821,41 @@
+ "batch_time_factors": [ 60, 5 ],
+ "book_learn": [ [ "recipe_bullets", 3 ], [ "manual_pistol", 3 ] ],
+ "charges": 1,
+- "reversible": true,
+ "using": [ [ "bullet_forming", 2 ], [ "ammo_bullet", 2 ], [ "ammo_762_25", 1 ] ],
+ "components": [ [ [ "gunpowder", 4 ] ] ]
+ },
+ {
+- "result": "reloaded_9mm",
++ "result": "762_25hot",
++ "type": "recipe",
++ "category": "CC_AMMO",
++ "subcategory": "CSC_AMMO_PISTOL",
++ "skill_used": "fabrication",
++ "difficulty": 5,
++ "skills_required": [ "gun", 4 ],
++ "time": "2 m",
++ "batch_time_factors": [ 60, 5 ],
++ "book_learn": [ [ "recipe_bullets", 3 ], [ "manual_pistol", 3 ] ],
++ "charges": 1,
++ "using": [ [ "bullet_forming", 2 ], [ "ammo_bullet", 2 ], [ "ammo_762_25", 1 ] ],
++ "components": [ [ [ "gunpowder", 5 ] ] ]
++ },
++ {
++ "result": "762_25typeP",
++ "type": "recipe",
++ "category": "CC_AMMO",
++ "subcategory": "CSC_AMMO_PISTOL",
++ "skill_used": "fabrication",
++ "difficulty": 5,
++ "skills_required": [ "gun", 4 ],
++ "time": "2 m",
++ "batch_time_factors": [ 60, 5 ],
++ "book_learn": [ [ "recipe_bullets", 3 ], [ "manual_pistol", 3 ] ],
++ "charges": 1,
++ "using": [ [ "bullet_forming", 2 ], [ "ammo_bullet", 2 ], [ "ammo_762_25", 1 ] ],
++ "components": [ [ [ "gunpowder", 5 ] ] ]
++ },
++ {
++ "result": "9mm",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_PISTOL",
+@@ -861,12 +866,11 @@
+ "batch_time_factors": [ 60, 5 ],
+ "book_learn": [ [ "manual_pistol", 1 ], [ "manual_smg", 1 ], [ "recipe_bullets", 2 ] ],
+ "charges": 1,
+- "reversible": true,
+ "using": [ [ "bullet_forming", 2 ], [ "ammo_bullet", 2 ], [ "ammo_9mm", 1 ] ],
+ "components": [ [ [ "gunpowder", 3 ] ] ]
+ },
+ {
+- "result": "reloaded_9mmP",
++ "result": "9mmP",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_PISTOL",
+@@ -877,12 +881,11 @@
+ "batch_time_factors": [ 60, 5 ],
+ "book_learn": [ [ "manual_pistol", 3 ], [ "manual_smg", 3 ], [ "recipe_bullets", 4 ] ],
+ "charges": 1,
+- "reversible": true,
+ "using": [ [ "bullet_forming", 2 ], [ "ammo_bullet", 2 ], [ "ammo_9mm", 1 ] ],
+ "components": [ [ [ "gunpowder", 4 ] ] ]
+ },
+ {
+- "result": "reloaded_9mmP2",
++ "result": "9mmP2",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_PISTOL",
+@@ -893,12 +896,11 @@
+ "batch_time_factors": [ 60, 5 ],
+ "book_learn": [ [ "manual_pistol", 4 ], [ "manual_smg", 4 ] ],
+ "charges": 1,
+- "reversible": true,
+ "using": [ [ "bullet_forming", 2 ], [ "ammo_bullet", 2 ], [ "ammo_9mm", 1 ] ],
+ "components": [ [ [ "gunpowder", 5 ] ] ]
+ },
+ {
+- "result": "reloaded_9mmfmj",
++ "result": "9mmfmj",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_PISTOL",
+@@ -909,12 +911,11 @@
+ "batch_time_factors": [ 60, 5 ],
+ "book_learn": [ [ "manual_pistol", 2 ], [ "manual_smg", 2 ], [ "recipe_bullets", 3 ] ],
+ "charges": 1,
+- "reversible": true,
+ "using": [ [ "bullet_forming", 2 ], [ "ammo_bullet", 2 ], [ "ammo_9mm", 1 ] ],
+ "components": [ [ [ "gunpowder", 3 ] ], [ [ "copper", 1 ] ] ]
+ },
+ {
+- "result": "reloaded_9x18mm",
++ "result": "9x18mm",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_PISTOL",
+@@ -925,12 +926,11 @@
+ "batch_time_factors": [ 60, 5 ],
+ "book_learn": [ [ "recipe_bullets", 1 ], [ "manual_pistol", 2 ] ],
+ "charges": 1,
+- "reversible": true,
+ "using": [ [ "bullet_forming", 2 ], [ "ammo_bullet", 2 ] ],
+ "components": [ [ [ "9x18mm_casing", 1 ] ], [ [ "smpistol_primer", 1 ] ], [ [ "gunpowder", 3 ] ] ]
+ },
+ {
+- "result": "reloaded_9x18mmfmj",
++ "result": "9x18mmfmj",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_PISTOL",
+@@ -941,12 +941,11 @@
+ "batch_time_factors": [ 60, 5 ],
+ "book_learn": [ [ "recipe_bullets", 3 ], [ "manual_pistol", 4 ] ],
+ "charges": 1,
+- "reversible": true,
+ "using": [ [ "bullet_forming", 2 ], [ "ammo_bullet", 2 ] ],
+ "components": [ [ [ "9x18mm_casing", 1 ] ], [ [ "smpistol_primer", 1 ] ], [ [ "gunpowder", 3 ] ], [ [ "copper", 1 ] ] ]
+ },
+ {
+- "result": "reloaded_9x18mmP2",
++ "result": "9x18mmP2",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_PISTOL",
+@@ -957,12 +956,11 @@
+ "batch_time_factors": [ 60, 5 ],
+ "book_learn": [ [ "recipe_bullets", 3 ], [ "manual_pistol", 4 ] ],
+ "charges": 1,
+- "reversible": true,
+ "using": [ [ "bullet_forming", 2 ], [ "ammo_bullet", 2 ] ],
+ "components": [ [ [ "9x18mm_casing", 1 ] ], [ [ "smpistol_primer", 1 ] ], [ [ "gunpowder", 5 ] ] ]
+ },
+ {
+- "result": "reloaded_380_JHP",
++ "result": "380_JHP",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_PISTOL",
+@@ -973,12 +971,11 @@
+ "batch_time_factors": [ 60, 5 ],
+ "book_learn": [ [ "manual_pistol", 1 ], [ "manual_smg", 1 ], [ "recipe_bullets", 2 ] ],
+ "charges": 1,
+- "reversible": true,
+ "using": [ [ "bullet_forming", 2 ], [ "ammo_bullet", 2 ], [ "ammo_380", 1 ] ],
+ "components": [ [ [ "gunpowder", 2 ] ] ]
+ },
+ {
+- "result": "reloaded_380_p",
++ "result": "380_p",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_PISTOL",
+@@ -989,12 +986,11 @@
+ "batch_time_factors": [ 60, 5 ],
+ "book_learn": [ [ "manual_pistol", 3 ], [ "manual_smg", 3 ], [ "recipe_bullets", 4 ] ],
+ "charges": 1,
+- "reversible": true,
+ "using": [ [ "bullet_forming", 2 ], [ "ammo_bullet", 2 ], [ "ammo_380", 1 ] ],
+ "components": [ [ [ "gunpowder", 3 ] ] ]
+ },
+ {
+- "result": "reloaded_380_FMJ",
++ "result": "380_FMJ",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_PISTOL",
+@@ -1005,7 +1001,6 @@
+ "batch_time_factors": [ 60, 5 ],
+ "book_learn": [ [ "manual_pistol", 2 ], [ "manual_smg", 2 ], [ "recipe_bullets", 3 ] ],
+ "charges": 1,
+- "reversible": true,
+ "using": [ [ "bullet_forming", 2 ], [ "ammo_bullet", 2 ], [ "ammo_380", 1 ] ],
+ "components": [ [ [ "gunpowder", 2 ] ], [ [ "copper", 1 ] ] ]
+ }
+diff --git a/data/json/recipes/ammo/rifle.json b/data/json/recipes/ammo/rifle.json
+index 84d930b02d..c1d954073c 100644
+--- a/data/json/recipes/ammo/rifle.json
++++ b/data/json/recipes/ammo/rifle.json
+@@ -34,7 +34,7 @@
+ "components": [ [ [ "chem_black_powder", 5 ] ], [ [ "paper", 1 ] ] ]
+ },
+ {
+- "result": "reloaded_22_cphp",
++ "result": "22_cphp",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_RIFLE",
+@@ -45,12 +45,11 @@
+ "batch_time_factors": [ 60, 5 ],
+ "book_learn": [ [ "recipe_bullets", 1 ], [ "manual_pistol", 2 ] ],
+ "charges": 1,
+- "reversible": true,
+ "using": [ [ "bullet_forming", 3 ], [ "ammo_bullet", 2 ] ],
+ "components": [ [ [ "22_casing_new", 1 ] ], [ [ "gunpowder", 2 ] ], [ [ "copper", 1 ] ] ]
+ },
+ {
+- "result": "reloaded_22_lr",
++ "result": "22_lr",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_RIFLE",
+@@ -61,7 +60,6 @@
+ "batch_time_factors": [ 60, 5 ],
+ "book_learn": [ [ "recipe_bullets", 1 ], [ "manual_pistol", 2 ] ],
+ "charges": 1,
+- "reversible": true,
+ "using": [ [ "bullet_forming", 2 ], [ "ammo_bullet", 2 ] ],
+ "components": [ [ [ "22_casing_new", 1 ] ], [ [ "gunpowder", 2 ] ] ]
+ },
+@@ -98,7 +96,7 @@
+ "components": [ [ [ "22_casing_new", 1 ] ], [ [ "chem_black_powder", 3 ] ] ]
+ },
+ {
+- "result": "reloaded_223",
++ "result": "223",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_RIFLE",
+@@ -109,7 +107,6 @@
+ "batch_time_factors": [ 60, 5 ],
+ "book_learn": [ [ "recipe_bullets", 1 ], [ "mag_rifle", 2 ] ],
+ "charges": 1,
+- "reversible": true,
+ "using": [ [ "bullet_forming", 4 ], [ "ammo_bullet", 3 ] ],
+ "components": [ [ [ "223_casing", 1 ] ], [ [ "smrifle_primer", 1 ] ], [ [ "gunpowder", 4 ] ], [ [ "copper", 1 ] ] ]
+ },
+@@ -130,7 +127,7 @@
+ "components": [ [ [ "223_casing", 1 ] ], [ [ "smrifle_primer", 1 ] ], [ [ "chem_black_powder", 6 ] ], [ [ "copper", 1 ] ] ]
+ },
+ {
+- "result": "reloaded_270win_jsp",
++ "result": "270win_jsp",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_RIFLE",
+@@ -141,7 +138,6 @@
+ "batch_time_factors": [ 60, 5 ],
+ "book_learn": [ [ "recipe_bullets", 1 ], [ "mag_rifle", 3 ] ],
+ "charges": 1,
+- "reversible": true,
+ "using": [ [ "bullet_forming", 8 ], [ "ammo_bullet", 5 ], [ "ammo_270win", 1 ] ],
+ "components": [ [ [ "gunpowder", 10 ] ], [ [ "copper", 3 ] ] ]
+ },
+@@ -162,7 +158,7 @@
+ "components": [ [ [ "chem_black_powder", 15 ] ], [ [ "copper", 3 ] ] ]
+ },
+ {
+- "result": "reloaded_300_winmag",
++ "result": "300_winmag",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_RIFLE",
+@@ -173,7 +169,6 @@
+ "batch_time_factors": [ 60, 5 ],
+ "book_learn": [ [ "recipe_bullets", 4 ], [ "mag_rifle", 5 ] ],
+ "charges": 1,
+- "reversible": true,
+ "using": [ [ "bullet_forming", 12 ], [ "ammo_bullet", 8 ] ],
+ "components": [ [ [ "300_casing", 1 ] ], [ [ "lgrifle_primer", 1 ] ], [ [ "gunpowder", 16 ] ], [ [ "copper", 4 ] ] ]
+ },
+@@ -194,7 +189,7 @@
+ "components": [ [ [ "300_casing", 1 ] ], [ [ "lgrifle_primer", 1 ] ], [ [ "chem_black_powder", 24 ] ], [ [ "copper", 4 ] ] ]
+ },
+ {
+- "result": "reloaded_3006",
++ "result": "3006",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_RIFLE",
+@@ -205,12 +200,11 @@
+ "batch_time_factors": [ 60, 5 ],
+ "book_learn": [ [ "recipe_bullets", 3 ], [ "mag_rifle", 4 ] ],
+ "charges": 1,
+- "reversible": true,
+ "using": [ [ "bullet_forming", 12 ], [ "ammo_bullet", 8 ] ],
+ "components": [ [ [ "3006_casing", 1 ] ], [ [ "lgrifle_primer", 1 ] ], [ [ "gunpowder", 12 ] ], [ [ "copper", 4 ] ] ]
+ },
+ {
+- "result": "reloaded_3006fmj",
++ "result": "3006fmj",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_RIFLE",
+@@ -221,12 +215,11 @@
+ "batch_time_factors": [ 60, 5 ],
+ "book_learn": [ [ "recipe_bullets", 3 ], [ "mag_rifle", 4 ] ],
+ "charges": 1,
+- "reversible": true,
+ "using": [ [ "bullet_forming", 12 ], [ "ammo_bullet", 8 ] ],
+ "components": [ [ [ "3006_casing", 1 ] ], [ [ "lgrifle_primer", 1 ] ], [ [ "gunpowder", 12 ] ], [ [ "copper", 4 ] ] ]
+ },
+ {
+- "result": "reloaded_3006_incendiary",
++ "result": "3006_incendiary",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_RIFLE",
+@@ -237,7 +230,6 @@
+ "batch_time_factors": [ 60, 5 ],
+ "book_learn": [ [ "recipe_bullets", 2 ] ],
+ "charges": 1,
+- "reversible": true,
+ "using": [ [ "bullet_forming", 12 ], [ "ammo_bullet", 8 ] ],
+ "components": [
+ [ [ "3006_casing", 1 ] ],
+@@ -302,7 +294,7 @@
+ ]
+ },
+ {
+- "result": "reloaded_308",
++ "result": "308",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_RIFLE",
+@@ -313,7 +305,6 @@
+ "batch_time_factors": [ 60, 5 ],
+ "book_learn": [ [ "recipe_bullets", 2 ], [ "mag_rifle", 4 ] ],
+ "charges": 1,
+- "reversible": true,
+ "using": [ [ "bullet_forming", 9 ], [ "ammo_bullet", 6 ] ],
+ "components": [
+ [ [ "308_casing", 1 ], [ "762_51_casing", 1 ] ],
+@@ -344,7 +335,7 @@
+ ]
+ },
+ {
+- "result": "reloaded_4570_sp",
++ "result": "4570_sp",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_RIFLE",
+@@ -356,16 +347,10 @@
+ "book_learn": [ [ "recipe_bullets", 2 ], [ "mag_rifle", 4 ] ],
+ "charges": 1,
+ "using": [ [ "bullet_forming", 15 ], [ "ammo_bullet", 8 ] ],
+- "components": [
+- [ [ "4570_casing", 1 ] ],
+- [ [ "lgrifle_primer", 1 ] ],
+- [ [ "gunpowder", 15 ] ],
+- [ [ "lead", 5 ] ],
+- [ [ "copper", 2 ] ]
+- ]
++ "components": [ [ [ "4570_casing", 1 ] ], [ [ "lgrifle_primer", 1 ] ], [ [ "gunpowder", 15 ] ], [ [ "copper", 2 ] ] ]
+ },
+ {
+- "result": "reloaded_4570_pen",
++ "result": "4570_pen",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_RIFLE",
+@@ -380,7 +365,7 @@
+ "components": [ [ [ "4570_casing", 1 ] ], [ [ "lgrifle_primer", 1 ] ], [ [ "gunpowder", 17 ] ], [ [ "copper", 7 ] ] ]
+ },
+ {
+- "result": "reloaded_4570_low",
++ "result": "4570_low",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_RIFLE",
+@@ -406,7 +391,7 @@
+ ]
+ },
+ {
+- "result": "reloaded_5x50dart",
++ "result": "5x50dart",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_RIFLE",
+@@ -433,7 +418,29 @@
+ ]
+ },
+ {
+- "result": "reloaded_50bmg",
++ "result": "5x50heavy",
++ "type": "recipe",
++ "category": "CC_AMMO",
++ "subcategory": "CSC_AMMO_RIFLE",
++ "skill_used": "fabrication",
++ "difficulty": 6,
++ "skills_required": [ "gun", 5 ],
++ "time": "2 m",
++ "batch_time_factors": [ 60, 5 ],
++ "book_learn": [ [ "recipe_caseless", 4 ] ],
++ "charges": 8,
++ "using": [ [ "bullet_forming", 16 ], [ "ammo_bullet", 24 ] ],
++ "tools": [ [ [ "mold_plastic", -1 ] ] ],
++ "components": [
++ [ [ "5x50_hull", 8 ] ],
++ [ [ "plastic_chunk", 1 ] ],
++ [ [ "smrifle_primer", 8 ] ],
++ [ [ "gunpowder", 32 ] ],
++ [ [ "scrap", 8 ] ]
++ ]
++ },
++ {
++ "result": "50bmg",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_RIFLE",
+@@ -444,12 +451,11 @@
+ "batch_time_factors": [ 60, 5 ],
+ "book_learn": [ [ "recipe_bullets", 6 ] ],
+ "charges": 1,
+- "reversible": true,
+ "using": [ [ "bullet_forming", 18 ], [ "ammo_bullet", 12 ] ],
+ "components": [ [ [ "50_casing", 1 ] ], [ [ "lgrifle_primer", 1 ] ], [ [ "gunpowder", 30 ] ], [ [ "copper", 6 ] ] ]
+ },
+ {
+- "result": "reloaded_50_incendiary",
++ "result": "50_incendiary",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_RIFLE",
+@@ -460,7 +466,6 @@
+ "batch_time_factors": [ 60, 5 ],
+ "book_learn": [ [ "recipe_bullets", 8 ] ],
+ "charges": 1,
+- "reversible": true,
+ "using": [ [ "bullet_forming", 21 ], [ "ammo_bullet", 15 ] ],
+ "components": [
+ [ [ "50_casing", 1 ] ],
+@@ -471,7 +476,7 @@
+ ]
+ },
+ {
+- "result": "reloaded_50ss",
++ "result": "50ss",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_RIFLE",
+@@ -482,7 +487,6 @@
+ "batch_time_factors": [ 60, 5 ],
+ "book_learn": [ [ "recipe_bullets", 7 ] ],
+ "charges": 1,
+- "reversible": true,
+ "using": [ [ "bullet_forming", 21 ] ],
+ "components": [
+ [ [ "50_casing", 1 ] ],
+@@ -493,7 +497,7 @@
+ ]
+ },
+ {
+- "result": "reloaded_545",
++ "result": "545",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_RIFLE",
+@@ -504,12 +508,11 @@
+ "batch_time_factors": [ 60, 5 ],
+ "book_learn": [ [ "recipe_bullets", 2 ], [ "mag_rifle", 3 ] ],
+ "charges": 1,
+- "reversible": true,
+ "using": [ [ "bullet_forming", 4 ], [ "ammo_bullet", 3 ] ],
+ "components": [ [ [ "545_casing", 1 ] ], [ [ "smrifle_primer", 1 ] ], [ [ "gunpowder", 5 ] ], [ [ "copper", 1 ] ] ]
+ },
+ {
+- "result": "reloaded_545_ap",
++ "result": "545_ap",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_RIFLE",
+@@ -520,12 +523,11 @@
+ "batch_time_factors": [ 60, 5 ],
+ "book_learn": [ [ "recipe_bullets", 2 ], [ "mag_rifle", 3 ] ],
+ "charges": 1,
+- "reversible": true,
+ "using": [ [ "bullet_forming", 4 ], [ "ammo_bullet", 3 ] ],
+ "components": [ [ [ "545_casing", 1 ] ], [ [ "smrifle_primer", 1 ] ], [ [ "gunpowder", 6 ] ], [ [ "copper", 1 ] ] ]
+ },
+ {
+- "result": "reloaded_300blk",
++ "result": "300blk",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_RIFLE",
+@@ -536,7 +538,6 @@
+ "batch_time_factors": [ 60, 5 ],
+ "book_learn": [ [ "recipe_bullets", 3 ], [ "mag_rifle", 4 ] ],
+ "charges": 1,
+- "reversible": true,
+ "using": [ [ "bullet_forming", 4 ], [ "ammo_bullet", 5 ], [ "ammo_300blk", 1 ] ],
+ "components": [ [ [ "gunpowder", 4 ] ], [ [ "copper", 2 ] ] ]
+ },
+@@ -557,7 +558,7 @@
+ "components": [ [ [ "chem_black_powder", 6 ] ], [ [ "copper", 2 ] ] ]
+ },
+ {
+- "result": "reloaded_556",
++ "result": "556",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_RIFLE",
+@@ -568,12 +569,11 @@
+ "batch_time_factors": [ 60, 5 ],
+ "book_learn": [ [ "recipe_bullets", 3 ], [ "mag_rifle", 4 ] ],
+ "charges": 1,
+- "reversible": true,
+ "using": [ [ "bullet_forming", 4 ], [ "ammo_bullet", 3 ] ],
+ "components": [ [ [ "223_casing", 1 ] ], [ [ "smrifle_primer", 1 ] ], [ [ "gunpowder", 6 ] ], [ [ "copper", 1 ] ] ]
+ },
+ {
+- "result": "reloaded_556_incendiary",
++ "result": "556_incendiary",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_RIFLE",
+@@ -584,7 +584,6 @@
+ "batch_time_factors": [ 60, 5 ],
+ "book_learn": [ [ "recipe_bullets", 5 ] ],
+ "charges": 1,
+- "reversible": true,
+ "using": [ [ "bullet_forming", 4 ], [ "ammo_bullet", 3 ] ],
+ "components": [
+ [ [ "223_casing", 1 ] ],
+@@ -633,7 +632,7 @@
+ ]
+ },
+ {
+- "result": "reloaded_700nx",
++ "result": "700nx",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_RIFLE",
+@@ -644,12 +643,11 @@
+ "batch_time_factors": [ 60, 5 ],
+ "book_learn": [ [ "recipe_bullets", 7 ] ],
+ "charges": 1,
+- "reversible": true,
+ "using": [ [ "bullet_forming", 15 ], [ "ammo_bullet", 10 ] ],
+ "components": [ [ [ "700nx_casing", 1 ] ], [ [ "lgrifle_primer", 1 ] ], [ [ "gunpowder", 30 ] ], [ [ "copper", 5 ] ] ]
+ },
+ {
+- "result": "reloaded_762_51",
++ "result": "762_51",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_RIFLE",
+@@ -660,7 +658,6 @@
+ "batch_time_factors": [ 60, 5 ],
+ "book_learn": [ [ "recipe_bullets", 2 ], [ "mag_rifle", 4 ] ],
+ "charges": 1,
+- "reversible": true,
+ "using": [ [ "bullet_forming", 9 ], [ "ammo_bullet", 6 ] ],
+ "components": [
+ [ [ "308_casing", 1 ], [ "762_51_casing", 1 ] ],
+@@ -670,7 +667,7 @@
+ ]
+ },
+ {
+- "result": "reloaded_762_51_incendiary",
++ "result": "762_51_incendiary",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_RIFLE",
+@@ -681,7 +678,6 @@
+ "batch_time_factors": [ 60, 5 ],
+ "book_learn": [ [ "recipe_bullets", 5 ] ],
+ "charges": 1,
+- "reversible": true,
+ "using": [ [ "bullet_forming", 9 ], [ "ammo_bullet", 6 ] ],
+ "components": [
+ [ [ "308_casing", 1 ], [ "762_51_casing", 1 ] ],
+@@ -735,7 +731,7 @@
+ ]
+ },
+ {
+- "result": "reloaded_762_54R",
++ "result": "762_54R",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_RIFLE",
+@@ -746,12 +742,11 @@
+ "batch_time_factors": [ 60, 5 ],
+ "book_learn": [ [ "recipe_bullets", 3 ], [ "mag_rifle", 4 ] ],
+ "charges": 1,
+- "reversible": true,
+ "using": [ [ "bullet_forming", 10 ], [ "ammo_bullet", 7 ] ],
+ "components": [ [ [ "762R_casing", 1 ] ], [ [ "lgrifle_primer", 1 ] ], [ [ "gunpowder", 10 ] ], [ [ "copper", 3 ] ] ]
+ },
+ {
+- "result": "reloaded_762_m43",
++ "result": "762_m43",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_RIFLE",
+@@ -762,12 +757,11 @@
+ "batch_time_factors": [ 60, 5 ],
+ "book_learn": [ [ "recipe_bullets", 2 ], [ "mag_rifle", 3 ] ],
+ "charges": 1,
+- "reversible": true,
+ "using": [ [ "bullet_forming", 5 ], [ "ammo_bullet", 4 ] ],
+ "components": [ [ [ "762_casing", 1 ] ], [ [ "lgrifle_primer", 1 ] ], [ [ "gunpowder", 8 ] ], [ [ "copper", 1 ] ] ]
+ },
+ {
+- "result": "reloaded_762_m87",
++ "result": "762_m87",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_RIFLE",
+@@ -778,7 +772,6 @@
+ "batch_time_factors": [ 60, 5 ],
+ "book_learn": [ [ "recipe_bullets", 3 ], [ "mag_rifle", 4 ] ],
+ "charges": 1,
+- "reversible": true,
+ "using": [ [ "bullet_forming", 5 ], [ "ammo_bullet", 4 ] ],
+ "components": [ [ [ "762_casing", 1 ] ], [ [ "lgrifle_primer", 1 ] ], [ [ "gunpowder", 8 ] ], [ [ "copper", 1 ] ] ]
+ }
+diff --git a/data/json/recipes/ammo/shot.json b/data/json/recipes/ammo/shot.json
+index 76d1d3f6b4..3cd7313750 100644
+--- a/data/json/recipes/ammo/shot.json
++++ b/data/json/recipes/ammo/shot.json
+@@ -317,7 +317,7 @@
+ ]
+ },
+ {
+- "result": "reloaded_shot_00",
++ "result": "shot_00",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_SHOT",
+@@ -328,12 +328,11 @@
+ "batch_time_factors": [ 60, 5 ],
+ "book_learn": [ [ "recipe_bullets", 2 ], [ "manual_shotgun", 2 ] ],
+ "charges": 1,
+- "reversible": true,
+ "using": [ [ "shot_forming", 1 ], [ "ammo_bullet", 10 ], [ "ammo_shot", 1 ] ],
+ "components": [ [ [ "gunpowder", 6 ] ] ]
+ },
+ {
+- "result": "reloaded_410shot_000",
++ "result": "410shot_000",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_SHOT",
+@@ -344,12 +343,11 @@
+ "batch_time_factors": [ 60, 5 ],
+ "book_learn": [ [ "recipe_bullets", 2 ], [ "manual_shotgun", 2 ] ],
+ "charges": 1,
+- "reversible": true,
+ "using": [ [ "shot_forming", 1 ], [ "ammo_bullet", 5 ], [ "ammo_410shot", 1 ] ],
+ "components": [ [ [ "gunpowder", 5 ] ] ]
+ },
+ {
+- "result": "reloaded_shot_bird",
++ "result": "shot_bird",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_SHOT",
+@@ -360,12 +358,11 @@
+ "batch_time_factors": [ 60, 5 ],
+ "book_learn": [ [ "recipe_bullets", 1 ], [ "manual_shotgun", 1 ] ],
+ "charges": 1,
+- "reversible": true,
+ "using": [ [ "shot_forming", 1 ], [ "ammo_bullet", 10 ], [ "ammo_shot", 1 ] ],
+ "components": [ [ [ "gunpowder", 3 ] ] ]
+ },
+ {
+- "result": "reloaded_shot_dragon",
++ "result": "shot_dragon",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_SHOT",
+@@ -381,7 +378,7 @@
+ "components": [ [ [ "gunpowder", 3 ] ], [ [ "magnesium", 5 ] ] ]
+ },
+ {
+- "result": "reloaded_shot_flechette",
++ "result": "shot_flechette",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_SHOT",
+@@ -392,13 +389,12 @@
+ "batch_time_factors": [ 60, 5 ],
+ "book_learn": [ [ "recipe_bullets", 4 ], [ "manual_shotgun", 4 ] ],
+ "charges": 1,
+- "reversible": true,
+ "using": [ [ "ammo_shot", 1 ] ],
+ "tools": [ [ [ "press", -1 ], [ "press_dowel", -1 ] ] ],
+ "components": [ [ [ "gunpowder", 6 ] ], [ [ "combatnail", 10 ] ] ]
+ },
+ {
+- "result": "reloaded_shot_slug",
++ "result": "shot_slug",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_SHOT",
+@@ -409,7 +405,6 @@
+ "batch_time_factors": [ 60, 5 ],
+ "book_learn": [ [ "recipe_bullets", 3 ], [ "manual_shotgun", 3 ] ],
+ "charges": 1,
+- "reversible": true,
+ "using": [ [ "shot_forming", 1 ], [ "ammo_bullet", 20 ], [ "ammo_shot", 1 ] ],
+ "components": [ [ [ "gunpowder", 6 ] ] ]
+ },
+diff --git a/data/mods/Generic_Guns/recipes/recipe_obsolete.json b/data/mods/Generic_Guns/recipes/recipe_obsolete.json
+index 3146c0a01c..e4e3796a10 100644
+--- a/data/mods/Generic_Guns/recipes/recipe_obsolete.json
++++ b/data/mods/Generic_Guns/recipes/recipe_obsolete.json
+@@ -404,581 +404,6 @@
+ "result": "40x53mm_flechette_m169",
+ "obsolete": true
+ },
+- {
+- "type": "recipe",
+- "result": "460_casing",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "380_casing",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "300blk_casing",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "bp_9mm",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "bp_9mmfmj",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "bp_40sw",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "bp_32_acp",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "bp_38_fmj",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "bp_45_acp",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "bp_45_jhp",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "bp_46mm",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "bp_460_fmj",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "bp_460_rowland",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "bp_500_Magnum",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "bp_762_25",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "bp_9x18mm",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "bp_9x18mmfmj",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "bp_380_JHP",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "bp_380_FMJ",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "bp_57mm",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "36navy",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "44army",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "reloaded_32_acp",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "reloaded_38_fmj",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "reloaded_38_special",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "reloaded_38super_fmj",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "reloaded_357sig_fmj",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "reloaded_357sig_jhp",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "reloaded_357mag_fmj",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "reloaded_357mag_jhp",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "bp_357mag_fmj",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "bp_357mag_jhp",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "bp_38_special",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "reloaded_38_super",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "reloaded_40fmj",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "reloaded_40sw",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "reloaded_10mm_fmj",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "bp_10mm_fmj",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "reloaded_44fmj",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "reloaded_44magnum",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "bp_44magnum",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "bp_44fmj",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "reloaded_45_acp",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "reloaded_45_jhp",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "reloaded_45_super",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "reloaded_454_Casull",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "bp_454_Casull",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "reloaded_45colt_jhp",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "reloaded_46mm",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "reloaded_460_fmj",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "reloaded_460_rowland",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "reloaded_500_Magnum",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "reloaded_57mm",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "reloaded_762_25",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "reloaded_9mm",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "reloaded_9mmP",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "reloaded_9mmP2",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "reloaded_9mmfmj",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "reloaded_9x18mm",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "reloaded_9x18mmfmj",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "reloaded_9x18mmP2",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "reloaded_380_JHP",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "reloaded_380_p",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "reloaded_380_FMJ",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "reloaded_22_fmj",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "reloaded_22_lr",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "bp_22_fmj",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "bp_22_lr",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "reloaded_223",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "bp_223",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "reloaded_270win_jsp",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "bp_270win_jsp",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "reloaded_300_winmag",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "bp_300_winmag",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "reloaded_3006",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "reloaded_3006fmj",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "reloaded_3006_incendiary",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "bp_3006",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "bp_3006fmj",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "bp_3006_incendiary",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "reloaded_308",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "bp_308",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "reloaded_4570_sp",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "reloaded_4570_pen",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "reloaded_4570_low",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "reloaded_4570_bp",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "reloaded_5x50dart",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "reloaded_50bmg",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "reloaded_50_incendiary",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "reloaded_50ss",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "reloaded_545",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "reloaded_545_ap",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "reloaded_300blk",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "bp_300blk",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "reloaded_556",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "reloaded_556_incendiary",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "bp_556",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "bp_556_incendiary",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "reloaded_700nx",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "reloaded_762_51",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "reloaded_762_51_incendiary",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "bp_762_51",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "bp_762_51_incendiary",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "reloaded_762_54R",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "reloaded_762_m43",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "reloaded_762_m87",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "40x46mm_buckshot_m118",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "40x46mm_buckshot_m199",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "40x46mm_slug_m118",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "40x46mm_slug_m199",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "40x46mm_flechette_m118",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "40x46mm_flechette_m199",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "40x53mm_buckshot_m169",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "40x53mm_slug_m169",
+- "obsolete": true
+- },
+- {
+- "type": "recipe",
+- "result": "40x53mm_flechette_m169",
+- "obsolete": true
+- },
+ {
+ "type": "recipe",
+ "result": "shot_paper_00",
+@@ -1304,6 +729,11 @@
+ "result": "bp_44magnum",
+ "obsolete": true
+ },
++ {
++ "type": "recipe",
++ "result": "bp_44fmj",
++ "obsolete": true
++ },
+ {
+ "type": "recipe",
+ "result": "reloaded_45_acp",
+--
+2.35.1
+
diff --git a/revert-09_undo-yet-more-ammo-balancing.patch b/revert-09_undo-yet-more-ammo-balancing.patch
new file mode 100644
index 0000000..01dd4e1
--- /dev/null
+++ b/revert-09_undo-yet-more-ammo-balancing.patch
@@ -0,0 +1,308 @@
+From 30517b3811fa707a3dcfb0849efb0cfd4977c98d Mon Sep 17 00:00:00 2001
+From: Chaosvolt <chaosvolt@users.noreply.github.com>
+Date: Mon, 12 Dec 2022 08:08:09 -0600
+Subject: [PATCH 148/177] Ammo rebalance project, part 7 (#2121)
+
+* [WIP] Ammo rebalance project, part 7
+
+* Typofix
+
+Doi
+
+* Update 40x46mm, casing description stuff
+
+* And do 40x53mm
+
+* Obsolete/migrate redundant 8mm ammo
+
+* Re-add comment that got ate by merge conflict fix
+
+* Updates per feedback
+---
+ .../itemgroups/Weapons_Mods_Ammo/ammo.json | 1 -
+ data/json/itemgroups/military.json | 4 +-
+ data/json/items/ammo/40x46mm.json | 57 ++++++++-----------
+ data/json/items/ammo/40x53mm.json | 29 +++-------
+ data/json/items/ammo/8x40mm.json | 23 ++++----
+ data/json/items/migration.json | 15 +++++
+ data/json/obsoletion/recipes.json | 10 ++++
+ data/json/professions.json | 4 +-
+ data/json/recipes/ammo/shot.json | 4 +-
+ .../Generic_Guns/ammo/gg_ammo_migration.json | 3 -
+ .../Generic_Guns/recipes/recipe_obsolete.json | 7 +--
+ data/mods/No_Rivtech_Guns/modinfo.json | 1 -
+ .../more_classes_scenarios/cs_classes.json | 6 +-
+ doc/GAME_BALANCE.md | 6 +-
+ 22 files changed, 110 insertions(+), 108 deletions(-)
+
+diff --git a/data/json/itemgroups/Weapons_Mods_Ammo/ammo.json b/data/json/itemgroups/Weapons_Mods_Ammo/ammo.json
+index c10de498fb4..63682ca9ef1 100644
+--- a/data/json/itemgroups/Weapons_Mods_Ammo/ammo.json
++++ b/data/json/itemgroups/Weapons_Mods_Ammo/ammo.json
+@@ -246,7 +246,6 @@
+ { "item": "762_51_incendiary", "prob": 10 },
+ { "item": "762_51", "prob": 40 },
+ { "item": "8mm_caseless", "prob": 30 },
+- { "item": "8mm_fmj", "prob": 30 },
+ { "item": "8mm_hvp", "prob": 10 },
+ { "item": "8mm_inc", "prob": 20 },
+ { "item": "8mm_jhp", "prob": 10 },
+diff --git a/data/json/itemgroups/military.json b/data/json/itemgroups/military.json
+index 67766ba566a..8f564eb87aa 100644
+--- a/data/json/itemgroups/military.json
++++ b/data/json/itemgroups/military.json
+@@ -226,7 +226,7 @@
+ { "item": "8mm_caseless", "prob": 2 },
+ { "item": "rm99_pistol", "prob": 1 },
+ { "item": "8mm_jhp", "prob": 2 },
+- { "item": "8mm_fmj", "prob": 2 },
++ { "item": "8mm_hvp", "prob": 2 },
+ { "item": "laser_rifle", "prob": 1 },
+ { "item": "rm103a_pistol", "prob": 1 },
+ { "item": "laser_sight", "prob": 15 },
+@@ -388,7 +388,7 @@
+ { "item": "50_mk211", "prob": 1 },
+ { "item": "50ss", "prob": 8 },
+ { "item": "50_incendiary", "prob": 8 },
+- { "item": "8mm_fmj", "prob": 6 },
++ { "item": "8mm_jhp", "prob": 6 },
+ { "item": "8mm_inc", "prob": 6 },
+ { "item": "8mm_caseless", "prob": 6 },
+ { "item": "m202_flash", "prob": 15 },
+diff --git a/data/json/items/ammo/40x46mm.json b/data/json/items/ammo/40x46mm.json
+index 530278fd5d8..352b67d154c 100644
+--- a/data/json/items/ammo/40x46mm.json
++++ b/data/json/items/ammo/40x46mm.json
+@@ -69,19 +69,6 @@
+ "casing": "40x46mm_m118_casing",
+ "extend": { "effects": [ "SHOT" ] }
+ },
+- {
+- "id": "40x46mm_buckshot_m199",
+- "copy-from": "40x46mm_grenade",
+- "type": "AMMO",
+- "name": { "str": "40x46mm buckshot" },
+- "description": "An improvised 40x46mm buckshot load somewhat resembling M576.",
+- "weight": "120 g",
+- "range": 10,
+- "damage": { "damage_type": "bullet", "amount": 90, "armor_penetration": 4 },
+- "recoil": 1000,
+- "casing": "40x46mm_m199_casing",
+- "extend": { "effects": [ "SHOT" ] }
+- },
+ {
+ "id": "40x46mm_slug_m118",
+ "copy-from": "40x46mm_grenade",
+diff --git a/data/json/items/ammo/40x53mm.json b/data/json/items/ammo/40x53mm.json
+index 4541de0dab2..aeb0d2e732e 100644
+--- a/data/json/items/ammo/40x53mm.json
++++ b/data/json/items/ammo/40x53mm.json
+@@ -60,17 +61,4 @@
+ "recoil": 1200,
+ "casing": "40x53mm_m169_casing"
+- },
+- {
+- "id": "40x53mm_flechette_m169",
+- "copy-from": "40x53mm_grenade",
+- "type": "AMMO",
+- "name": { "str": "40x53mm flechette" },
+- "description": "An improvised 40x53mm flechette load containing 100 steel darts.",
+- "weight": "340 g",
+- "range": 10,
+- "damage": { "damage_type": "bullet", "amount": 85, "armor_penetration": 6 },
+- "recoil": 1200,
+- "casing": "40x53mm_m169_casing",
+- "extend": { "effects": [ "SHOT" ] }
+ }
+ ]
+diff --git a/data/json/items/ammo/8x40mm.json b/data/json/items/ammo/8x40mm.json
+index 25d9b16a37b..8ca62a1bfb3 100644
+--- a/data/json/items/ammo/8x40mm.json
++++ b/data/json/items/ammo/8x40mm.json
+@@ -39,14 +39,6 @@
+ "dispersion": 1.2,
+ "recoil": 0.5
+ },
+- {
+- "id": "8mm_fmj",
+- "copy-from": "8mm_caseless",
+- "type": "AMMO",
+- "name": { "str": "8x40mm FMJ" },
+- "description": "8x40mm caseless rounds, full metal jacket. Military grade ammunition for Rivtech firearms. Being caseless rounds, these cannot be disassembled or reloaded.",
+- "relative": { "damage": { "damage_type": "bullet", "amount": -5, "armor_penetration": 10 } }
+- },
+ {
+ "id": "8mm_hvp",
+ "copy-from": "8mm_caseless",
+diff --git a/data/json/items/migration.json b/data/json/items/migration.json
+index ed67da394f0..31158a8187c 100644
+--- a/data/json/obsoletion/migration.json
++++ b/data/json/obsoletion/migration.json
+@@ -1740,6 +1740,21 @@
+ "id": "rubber_armor_horse",
+ "type": "MIGRATION",
+ "replace": "rubber_armor_medium_quadruped"
++ },
++ {
++ "id": "40x46mm_buckshot_m199",
++ "type": "MIGRATION",
++ "replace": "40x46mm_m576"
++ },
++ {
++ "id": "40x53mm_flechette_m169",
++ "type": "MIGRATION",
++ "replace": "40x53mm_m1001"
++ },
++ {
++ "id": "8mm_fmj",
++ "type": "MIGRATION",
++ "replace": "8mm_caseless"
+ },
+ {
+ "id": "chem_zinc_powder",
+diff --git a/data/json/obsoletion/recipes.json b/data/json/obsoletion/recipes.json
+index c0c56cead36..8e1335380e2 100644
+--- a/data/json/obsoletion/recipes.json
++++ b/data/json/obsoletion/recipes.json
+@@ -3147,5 +3147,15 @@
+ "type": "recipe",
+ "result": "rubber_armor_horse_from_scratch",
+ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "40x46mm_buckshot_m199",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "40x53mm_flechette_m169",
++ "obsolete": true
+ },
+ {
+ "type": "recipe",
+diff --git a/data/json/professions.json b/data/json/professions.json
+index cd30799fa83..f84f94b6d33 100644
+--- a/data/json/professions.json
++++ b/data/json/professions.json
+@@ -45,8 +45,8 @@
+ "subtype": "collection",
+ "id": "army_mags_rm11b",
+ "entries": [
+- { "item": "8x40_10_mag", "ammo-item": "8mm_fmj", "charges": 10 },
+- { "item": "8x40_10_mag", "ammo-item": "8mm_fmj", "charges": 10 }
++ { "item": "8x40_10_mag", "ammo-item": "8mm_caseless", "charges": 10 },
++ { "item": "8x40_10_mag", "ammo-item": "8mm_caseless", "charges": 10 }
+ ]
+ },
+ {
+diff --git a/data/json/recipes/ammo/shot.json b/data/json/recipes/ammo/shot.json
+index 80a7881ea64..27b7bb17832 100644
+--- a/data/json/recipes/ammo/shot.json
++++ b/data/json/recipes/ammo/shot.json
+@@ -149,7 +149,7 @@
+ ]
+ },
+ {
+- "result": "40x53mm_flechette_m169",
++ "result": "40x53mm_m1001",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_SHOT",
+@@ -197,7 +197,7 @@
+ ]
+ },
+ {
+- "result": "40x46mm_buckshot_m199",
++ "result": "40x46mm_m576",
+ "type": "recipe",
+ "category": "CC_AMMO",
+ "subcategory": "CSC_AMMO_SHOT",
+diff --git a/data/mods/Generic_Guns/ammo/gg_ammo_migration.json b/data/mods/Generic_Guns/ammo/gg_ammo_migration.json
+index 675f5ba932d..8e61d596190 100644
+--- a/data/mods/Generic_Guns/ammo/gg_ammo_migration.json
++++ b/data/mods/Generic_Guns/ammo/gg_ammo_migration.json
+@@ -147,7 +147,6 @@
+ "556_incendiary",
+ "762_m43",
+ "8mm_caseless",
+- "8mm_fmj",
+ "8mm_hvp",
+ "8mm_inc",
+ "reloaded_556",
+@@ -260,11 +259,9 @@
+ "id": [
+ "40x46mm_m576",
+ "40x46mm_buckshot_m118",
+- "40x46mm_buckshot_m199",
+ "40x46mm_flechette_m118",
+ "40x46mm_flechette_m199",
+ "40x53mm_m1001",
+- "40x53mm_flechette_m169",
+ "40x53mm_buckshot_m169"
+ ],
+ "type": "MIGRATION",
+diff --git a/data/mods/Generic_Guns/recipes/recipe_obsolete.json b/data/mods/Generic_Guns/recipes/recipe_obsolete.json
+index e4e3796a108..8653252ae1d 100644
+--- a/data/mods/Generic_Guns/recipes/recipe_obsolete.json
++++ b/data/mods/Generic_Guns/recipes/recipe_obsolete.json
+@@ -366,7 +366,7 @@
+ },
+ {
+ "type": "recipe",
+- "result": "40x46mm_buckshot_m199",
++ "result": "40x46mm_m576",
+ "obsolete": true
+ },
+ {
+@@ -399,11 +399,6 @@
+ "result": "40x53mm_slug_m169",
+ "obsolete": true
+ },
+- {
+- "type": "recipe",
+- "result": "40x53mm_flechette_m169",
+- "obsolete": true
+- },
+ {
+ "type": "recipe",
+ "result": "shot_paper_00",
+diff --git a/data/mods/No_Rivtech_Guns/modinfo.json b/data/mods/No_Rivtech_Guns/modinfo.json
+index 716658fe996..983a1d1d2e4 100644
+--- a/data/mods/No_Rivtech_Guns/modinfo.json
++++ b/data/mods/No_Rivtech_Guns/modinfo.json
+@@ -14,7 +14,6 @@
+ "items": [
+ "8mm_caseless",
+ "8mm_bootleg",
+- "8mm_fmj",
+ "8mm_jhp",
+ "8mm_inc",
+ "5x50dart",
+diff --git a/data/mods/more_classes_scenarios/cs_classes.json b/data/mods/more_classes_scenarios/cs_classes.json
+index d10e81bd771..95a92381547 100644
+--- a/data/mods/more_classes_scenarios/cs_classes.json
++++ b/data/mods/more_classes_scenarios/cs_classes.json
+@@ -4,8 +4,8 @@
+ "subtype": "collection",
+ "id": "army_mags_rm2000",
+ "entries": [
+- { "item": "8x40_10_mag", "ammo-item": "8mm_fmj", "charges": 10 },
+- { "item": "8x40_10_mag", "ammo-item": "8mm_fmj", "charges": 10 }
++ { "item": "8x40_10_mag", "ammo-item": "8mm_caseless", "charges": 10 },
++ { "item": "8x40_10_mag", "ammo-item": "8mm_caseless", "charges": 10 }
+ ]
+ },
+ {
+@@ -53,7 +53,7 @@
+ { "item": "kukri", "container-item": "sheath" },
+ {
+ "item": "rm2000_smg",
+- "ammo-item": "8mm_fmj",
++ "ammo-item": "8mm_caseless",
+ "charges": 25,
+ "contents-item": [ "shoulder_strap", "suppressor", "holo_sight" ]
+ },
+--
+2.39.0
+
diff --git a/revert-11_Obsoletion-and-removal-of-useless-bathroom-fluff-247.patch b/revert-11_Obsoletion-and-removal-of-useless-bathroom-fluff-247.patch
new file mode 100644
index 0000000..5867ada
--- /dev/null
+++ b/revert-11_Obsoletion-and-removal-of-useless-bathroom-fluff-247.patch
@@ -0,0 +1,515 @@
+From 8ef2a855d0338e35aa1d9fbbda641315dc53f8db Mon Sep 17 00:00:00 2001
+From: Viss Valdyr <33199510+Lamandus@users.noreply.github.com>
+Date: Sat, 25 Mar 2023 14:24:02 +0100
+Subject: [PATCH] Obsoletion and removal of useless bathroom fluff (#2471)
+
+---
+ .../Clothing_Gear/gear_civilian.json | 1 -
+ .../Locations_MapExtras/locations.json | 4 +-
+ .../locations_commercial.json | 1 -
+ .../Locations_MapExtras/mall_item_groups.json | 1 -
+ .../Locations_MapExtras/mansion.json | 10 +-
+ data/json/itemgroups/SUS/domestic.json | 12 +-
+ .../json/itemgroups/collections_domestic.json | 6 +-
+ data/json/itemgroups/supplies.json | 8 +-
+ data/json/items/generic/bathroom_house.json | 126 ------------------
+ data/json/obsoletion/items.json | 126 ++++++++++++++++++
+ data/json/uncraft/generic.json | 8 --
+ 11 files changed, 133 insertions(+), 170 deletions(-)
+
+diff --git a/data/json/itemgroups/Clothing_Gear/gear_civilian.json b/data/json/itemgroups/Clothing_Gear/gear_civilian.json
+index 6c93a36b829..a7a9744e8e1 100644
+--- a/data/json/itemgroups/Clothing_Gear/gear_civilian.json
++++ b/data/json/itemgroups/Clothing_Gear/gear_civilian.json
+@@ -218,7 +218,6 @@
+ [ "elec_hairtrimmer", 15 ],
+ [ "razor_blade", 5 ],
+ [ "razor_shaving", 5 ],
+- [ "toothbrush_plain", 10 ],
+ [ "string_floss", 10 ],
+ [ "kilt", 5 ],
+ [ "hobo_stove", 1 ],
+diff --git a/data/json/itemgroups/Locations_MapExtras/locations.json b/data/json/itemgroups/Locations_MapExtras/locations.json
+index 2dfb60740ef..b1bfc7941a4 100644
+--- a/data/json/itemgroups/Locations_MapExtras/locations.json
++++ b/data/json/itemgroups/Locations_MapExtras/locations.json
+@@ -1158,9 +1158,7 @@
+ [ "toolbox", 5 ],
+ [ "apron_leather", 10 ],
+ [ "bio_infolink", 10 ],
+- [ "chem_aluminium_sulphate", 20 ],
+- [ "plunger_toilet", 10 ],
+- [ "plunger_futuristic", 5 ]
++ [ "chem_aluminium_sulphate", 20 ]
+ ]
+ },
+ {
+diff --git a/data/json/itemgroups/Locations_MapExtras/locations_commercial.json b/data/json/itemgroups/Locations_MapExtras/locations_commercial.json
+index 85fb9960d3c..07550e43c95 100644
+--- a/data/json/itemgroups/Locations_MapExtras/locations_commercial.json
++++ b/data/json/itemgroups/Locations_MapExtras/locations_commercial.json
+@@ -82,7 +82,6 @@
+ "items": [
+ [ "rope_6", 20 ],
+ [ "string_36", 25 ],
+- [ "toilet_paper", 10 ],
+ [ "handflare", 15 ],
+ [ "duct_tape", 25 ],
+ [ "flashlight", 25 ],
+diff --git a/data/json/itemgroups/Locations_MapExtras/mall_item_groups.json b/data/json/itemgroups/Locations_MapExtras/mall_item_groups.json
+index 261ede3a3f8..0841f79f760 100644
+--- a/data/json/itemgroups/Locations_MapExtras/mall_item_groups.json
++++ b/data/json/itemgroups/Locations_MapExtras/mall_item_groups.json
+@@ -281,7 +281,6 @@
+ [ "shavingkit", 20 ],
+ [ "elec_hairtrimmer", 20 ],
+ [ "razor_shaving", 20 ],
+- [ "curler_hair", 30 ],
+ [ "hair_dryer", 40 ],
+ [ "curling_iron", 40 ],
+ [ "comb_pocket", 10 ],
+diff --git a/data/json/itemgroups/Locations_MapExtras/mansion.json b/data/json/itemgroups/Locations_MapExtras/mansion.json
+index 56d45fb47d7..7dcb828df02 100644
+--- a/data/json/itemgroups/Locations_MapExtras/mansion.json
++++ b/data/json/itemgroups/Locations_MapExtras/mansion.json
+@@ -956,7 +956,6 @@
+ [ "38_casing", 20 ],
+ [ "45_casing", 20 ],
+ [ "bone_tainted", 1 ],
+- [ "toothbrush_plain", 10 ],
+ { "group": "corpse_mansion", "prob": 1 }
+ ]
+ },
+@@ -1122,10 +1121,7 @@
+ [ "oxy_powder", 5 ],
+ [ "fungicide", 5 ],
+ [ "insecticide", 5 ],
+- { "item": "charcoal", "prob": 5, "container-item": "bag_canvas" },
+- [ "toilet_paper", 30 ],
+- [ "plunger_toilet", 10 ],
+- [ "plunger_futuristic", 25 ]
++ { "item": "charcoal", "prob": 5, "container-item": "bag_canvas" }
+ ]
+ },
+ {
+@@ -1273,9 +1269,7 @@
+ { "group": "harddrugs", "prob": 5 },
+ [ "hairbrush", 30 ],
+ [ "comb_pocket", 15 ],
+- [ "curler_hair", 10 ],
+- [ "curling_iron", 15 ],
+- [ "brush_toilet", 15 ]
++ [ "curling_iron", 15 ]
+ ]
+ },
+ {
+diff --git a/data/json/itemgroups/SUS/domestic.json b/data/json/itemgroups/SUS/domestic.json
+index c431b052f2b..88574cb4111 100644
+--- a/data/json/itemgroups/SUS/domestic.json
++++ b/data/json/itemgroups/SUS/domestic.json
+@@ -343,7 +343,6 @@
+ { "item": "comb_pocket", "count": [ 1, 2 ], "prob": 75 },
+ { "item": "scissors", "count": [ 1, 2 ], "prob": 60 },
+ { "item": "hair_dryer", "prob": 60 },
+- { "collection": [ { "item": "curling_iron", "count": [ 1, 2 ] }, { "item": "curler_hair" } ], "prob": 25 },
+ { "item": "elec_hairtrimmer", "prob": 30 }
+ ]
+ },
+@@ -353,15 +352,7 @@
+ "//": "SUS item groups are collections that contain a reasonable realistic distribution of items that might spawn in a given storage furniture.",
+ "//2": "This group is for things you often find stored on or next to a toilet.",
+ "subtype": "collection",
+- "entries": [
+- {
+- "distribution": [ { "item": "plunger_toilet", "prob": 90 }, { "item": "plunger_futuristic", "prob": 10 } ],
+- "prob": 90
+- },
+- { "item": "brush_toilet", "prob": 75 },
+- { "item": "toilet_paper", "prob": 95 },
+- { "item": "bathroom_scale", "prob": 50 }
+- ]
++ "entries": [ { "item": "bathroom_scale", "prob": 50 } ]
+ },
+ {
+ "id": "SUS_bathroom_cabinet",
+@@ -384,7 +375,6 @@
+ { "item": "mirror", "prob": 25 },
+ { "item": "sponge", "count": [ 1, 3 ], "prob": 75 },
+ { "collection": [ { "item": "candle", "count": [ 1, 2 ] }, { "item": "matches" } ], "prob": 20 },
+- { "item": "toilet_paper", "prob": 80 },
+ { "item": "towel", "count": [ 1, 2 ], "prob": 75 }
+ ]
+ },
+diff --git a/data/json/itemgroups/collections_domestic.json b/data/json/itemgroups/collections_domestic.json
+index 63285818678..87f0178aafd 100644
+--- a/data/json/itemgroups/collections_domestic.json
++++ b/data/json/itemgroups/collections_domestic.json
+@@ -230,7 +230,6 @@
+ { "group": "mansion_guns", "prob": 3 },
+ { "group": "harddrugs", "prob": 1 },
+ [ "joint", 1 ],
+- [ "curler_hair", 10 ],
+ [ "hairbrush", 5 ]
+ ]
+ },
+@@ -989,10 +988,7 @@
+ { "item": "insecticide", "prob": 2 },
+ { "item": "soap", "prob": 80 },
+ { "item": "detergent", "prob": 80 },
+- { "item": "chem_hydrogen_peroxide", "prob": 20 },
+- { "item": "plunger_toilet", "prob": 30 },
+- { "item": "plunger_futuristic", "prob": 15 },
+- { "item": "toilet_paper", "prob": 10 }
++ { "item": "chem_hydrogen_peroxide", "prob": 20 }
+ ]
+ },
+ {
+diff --git a/data/json/itemgroups/supplies.json b/data/json/itemgroups/supplies.json
+index 0327c507ba9..0748fa9b951 100644
+--- a/data/json/itemgroups/supplies.json
++++ b/data/json/itemgroups/supplies.json
+@@ -122,9 +122,7 @@
+ [ "pump_complex", 5 ],
+ [ "well_pump", 5 ],
+ [ "plastic_sheet", 20 ],
+- [ "recharge_station", 20 ],
+- [ "plunger_toilet", 75 ],
+- [ "plunger_futuristic", 25 ]
++ [ "recharge_station", 20 ]
+ ]
+ },
+ {
+@@ -144,9 +142,7 @@
+ [ "jerrycan", 10 ],
+ [ "pump_complex", 10 ],
+ [ "well_pump", 10 ],
+- { "item": "scrap_copper", "prob": 15, "count": [ 1, 10 ] },
+- { "item": "plunger_toilet", "prob": 90, "count": [ 1, 2 ] },
+- [ "plunger_futuristic", 50 ]
++ { "item": "scrap_copper", "prob": 15, "count": [ 1, 10 ] }
+ ]
+ },
+ {
+diff --git a/data/json/items/generic/bathroom_house.json b/data/json/items/generic/bathroom_house.json
+index dba9eb592f6..2b4b7874c51 100644
+--- a/data/json/items/generic/bathroom_house.json
++++ b/data/json/items/generic/bathroom_house.json
+@@ -14,14 +14,6 @@
+ "bashing": 1,
+ "to_hit": -1
+ },
+- {
+- "id": "soap_holder",
+- "name": { "str": "soap dish", "str_pl": "soap dishes" },
+- "type": "GENERIC",
+- "description": "A shallow dish for holding a bar of soap. It has ridges to help drain water away from the dish. Not the most exciting of items.",
+- "symbol": "-",
+- "copy-from": "base_toiletries"
+- },
+ {
+ "id": "razor_shaving",
+ "name": { "str": "shaving razor" },
+@@ -36,36 +28,6 @@
+ "material": [ "plastic", "steel" ],
+ "cutting": 2
+ },
+- {
+- "id": "toothbrush_plain",
+- "name": { "str": "toothbrush", "str_pl": "toothbrushes" },
+- "type": "GENERIC",
+- "description": "A plastic brush with soft bristles for cleaning your teeth.",
+- "symbol": "/",
+- "copy-from": "base_toiletries",
+- "snippet_category": [
+- {
+- "id": "tbrush1",
+- "text": "A plastic brush with soft bristles for cleaning your teeth. It has a cheap, blocky handle and is likely meant to be disposable."
+- },
+- {
+- "id": "tbrush2",
+- "text": "A combination toothbrush and gum massager. It has an ergonomic silicone grip. Luxurious!"
+- },
+- {
+- "id": "tbrush3",
+- "text": "A plastic brush with soft bristles for cleaning your teeth. The blue and white pattern on the handle implies cleanliness."
+- },
+- {
+- "id": "tbrush4",
+- "text": "A short toothbrush designed for children. It has a wide-eyed cartoon pony on the handle."
+- },
+- {
+- "id": "tbrush5",
+- "text": "A short toothbrush designed for children. It has a grinning red racecar on the handle."
+- }
+- ]
+- },
+ {
+ "id": "hairbrush",
+ "name": { "str": "hairbrush", "str_pl": "hairbrushes" },
+@@ -80,17 +42,6 @@
+ { "id": "hbrush4", "text": "A tacky kid's hairbrush. The cartoon whale on the handle seems friendly enough." }
+ ]
+ },
+- {
+- "id": "curler_hair",
+- "name": { "str": "hair curler" },
+- "type": "GENERIC",
+- "description": "A soft plastic cylinder you can wrap a lock of your hair around to curl it.",
+- "copy-from": "base_toiletries",
+- "symbol": ",",
+- "weight": "20 g",
+- "volume": "25 ml",
+- "container": "box_small"
+- },
+ {
+ "id": "string_floss",
+ "name": { "str": "dental floss", "str_pl": "rolls of dental floss" },
+@@ -117,68 +68,6 @@
+ { "id": "pcomb4", "text": "A comb which folds on a hinge, in case you want to look like a greaser." }
+ ]
+ },
+- {
+- "id": "plunger_toilet",
+- "name": { "str": "toilet plunger" },
+- "type": "GENERIC",
+- "description": "A rubber-tipped tool for unclogging pipes, or a club for an immature survivor.",
+- "symbol": "p",
+- "color": "red",
+- "price": "8 USD",
+- "price_postapoc": "10 cent",
+- "weight": "590 g",
+- "volume": "2100 ml",
+- "//": "the volume is pretty bulky, but this is an old fashioned model.",
+- "material": [ "wood", "rubber" ],
+- "bashing": 5,
+- "to_hit": -1
+- },
+- {
+- "id": "plunger_futuristic",
+- "name": { "str": "professional plunger" },
+- "type": "GENERIC",
+- "description": "This hollow plastic toilet plunger's bell compresses like an accordion. It is efficient at its intended purpose, and complete rubbish as a weapon.",
+- "symbol": "p",
+- "color": "black",
+- "price": "1590 cent",
+- "price_postapoc": "10 cent",
+- "weight": "680 g",
+- "volume": "2400 ml",
+- "material": "plastic",
+- "bashing": 2,
+- "to_hit": -1
+- },
+- {
+- "id": "toilet_paper",
+- "name": { "str": "toilet paper", "str_pl": "rolls of toilet paper" },
+- "type": "GENERIC",
+- "description": "A luxurious remnant of civilization.",
+- "symbol": "~",
+- "color": "white",
+- "container": "box_medium",
+- "price": "89 cent",
+- "price_postapoc": "180 cent",
+- "volume": "250 ml",
+- "weight": "227 g",
+- "material": "paper",
+- "to_hit": -2,
+- "snippet_category": [
+- {
+- "id": "tpaper1",
+- "text": "Imagine the thinnest, most disposable paper you could possibly make. Now imagine something thinner than that."
+- },
+- {
+- "id": "tpaper2",
+- "text": "This roll of toilet paper is two-ply and quilted, for vandalizing houses more comfortably than ever."
+- },
+- { "id": "tpaper3", "text": "This brand of toilet paper is designed to dissolve completely in water!" },
+- { "id": "tpaper4", "text": "Images of your least favorite politician are printed on each individual sheet." },
+- {
+- "id": "tpaper5",
+- "text": "A luxurious remnant of civilization. The splinters of unprocessed wood visible in this one make it seem less luxurious, though."
+- }
+- ]
+- },
+ {
+ "id": "hair_dryer",
+ "name": { "str": "hair dryer" },
+@@ -208,20 +97,5 @@
+ "material": [ "ceramic", "steel" ],
+ "bashing": 3,
+ "to_hit": 1
+- },
+- {
+- "id": "brush_toilet",
+- "name": { "str": "toilet brush", "str_pl": "toilet brushes" },
+- "type": "GENERIC",
+- "description": "Zombies cannot be intimidated or humiliated, so this stiff brush is only useful for scouring toilet bowls.",
+- "symbol": "p",
+- "color": "white",
+- "price": "17 USD",
+- "price_postapoc": "0 cent",
+- "volume": "500 ml",
+- "weight": "160 g",
+- "material": [ "steel", "plastic" ],
+- "bashing": 3,
+- "to_hit": 1
+ }
+ ]
+diff --git a/data/json/obsoletion/items.json b/data/json/obsoletion/items.json
+index f2a8063e7ef..e0a1a36ce29 100644
+--- a/data/json/obsoletion/items.json
++++ b/data/json/obsoletion/items.json
+@@ -4354,6 +4354,132 @@
+ "cutting": 3,
+ "to_hit": -3,
+ "flags": [ "STAB", "SHEATH_KNIFE", "CONDUCTIVE" ]
++ },
++ {
++ "id": "soap_holder",
++ "name": { "str": "soap dish", "str_pl": "soap dishes" },
++ "type": "GENERIC",
++ "description": "A shallow dish for holding a bar of soap. It has ridges to help drain water away from the dish. Not the most exciting of items.",
++ "symbol": "-",
++ "copy-from": "base_toiletries"
++ },
++ {
++ "id": "toothbrush_plain",
++ "name": { "str": "toothbrush", "str_pl": "toothbrushes" },
++ "type": "GENERIC",
++ "description": "A plastic brush with soft bristles for cleaning your teeth.",
++ "symbol": "/",
++ "copy-from": "base_toiletries",
++ "snippet_category": [
++ {
++ "id": "tbrush1",
++ "text": "A plastic brush with soft bristles for cleaning your teeth. It has a cheap, blocky handle and is likely meant to be disposable."
++ },
++ {
++ "id": "tbrush2",
++ "text": "A combination toothbrush and gum massager. It has an ergonomic silicone grip. Luxurious!"
++ },
++ {
++ "id": "tbrush3",
++ "text": "A plastic brush with soft bristles for cleaning your teeth. The blue and white pattern on the handle implies cleanliness."
++ },
++ {
++ "id": "tbrush4",
++ "text": "A short toothbrush designed for children. It has a wide-eyed cartoon pony on the handle."
++ },
++ {
++ "id": "tbrush5",
++ "text": "A short toothbrush designed for children. It has a grinning red racecar on the handle."
++ }
++ ]
++ },
++ {
++ "id": "curler_hair",
++ "name": { "str": "hair curler" },
++ "type": "GENERIC",
++ "description": "A soft plastic cylinder you can wrap a lock of your hair around to curl it.",
++ "copy-from": "base_toiletries",
++ "symbol": ",",
++ "weight": "20 g",
++ "volume": "25 ml",
++ "container": "box_small"
++ },
++ {
++ "id": "plunger_toilet",
++ "name": { "str": "toilet plunger" },
++ "type": "GENERIC",
++ "description": "A rubber-tipped tool for unclogging pipes, or a club for an immature survivor.",
++ "symbol": "p",
++ "color": "red",
++ "price": "8 USD",
++ "price_postapoc": "10 cent",
++ "weight": "590 g",
++ "volume": "2100 ml",
++ "//": "the volume is pretty bulky, but this is an old fashioned model.",
++ "material": [ "wood", "rubber" ],
++ "bashing": 5,
++ "to_hit": -1
++ },
++ {
++ "id": "plunger_futuristic",
++ "name": { "str": "professional plunger" },
++ "type": "GENERIC",
++ "description": "This hollow plastic toilet plunger's bell compresses like an accordion. It is efficient at its intended purpose, and complete rubbish as a weapon.",
++ "symbol": "p",
++ "color": "black",
++ "price": "1590 cent",
++ "price_postapoc": "10 cent",
++ "weight": "680 g",
++ "volume": "2400 ml",
++ "material": "plastic",
++ "bashing": 2,
++ "to_hit": -1
++ },
++ {
++ "id": "toilet_paper",
++ "name": { "str": "toilet paper", "str_pl": "rolls of toilet paper" },
++ "type": "GENERIC",
++ "description": "A luxurious remnant of civilization.",
++ "symbol": "~",
++ "color": "white",
++ "container": "box_medium",
++ "price": "89 cent",
++ "price_postapoc": "180 cent",
++ "volume": "250 ml",
++ "weight": "227 g",
++ "material": "paper",
++ "to_hit": -2,
++ "snippet_category": [
++ {
++ "id": "tpaper1",
++ "text": "Imagine the thinnest, most disposable paper you could possibly make. Now imagine something thinner than that."
++ },
++ {
++ "id": "tpaper2",
++ "text": "This roll of toilet paper is two-ply and quilted, for vandalizing houses more comfortably than ever."
++ },
++ { "id": "tpaper3", "text": "This brand of toilet paper is designed to dissolve completely in water!" },
++ { "id": "tpaper4", "text": "Images of your least favorite politician are printed on each individual sheet." },
++ {
++ "id": "tpaper5",
++ "text": "A luxurious remnant of civilization. The splinters of unprocessed wood visible in this one make it seem less luxurious, though."
++ }
++ ]
++ },
++ {
++ "id": "brush_toilet",
++ "name": { "str": "toilet brush", "str_pl": "toilet brushes" },
++ "type": "GENERIC",
++ "description": "Zombies cannot be intimidated or humiliated, so this stiff brush is only useful for scouring toilet bowls.",
++ "symbol": "p",
++ "color": "white",
++ "price": "17 USD",
++ "price_postapoc": "0 cent",
++ "volume": "500 ml",
++ "weight": "160 g",
++ "material": [ "steel", "plastic" ],
++ "bashing": 3,
++ "to_hit": 1
+ },
+ {
+ "id": "lycra_patch",
+diff --git a/data/json/uncraft/generic.json b/data/json/uncraft/generic.json
+index 30a4c1b1ace..ceacdc75895 100644
+--- a/data/json/uncraft/generic.json
++++ b/data/json/uncraft/generic.json
+@@ -3961,14 +3961,6 @@
+ "//": "just unspool the floss, no need to make a big production out of it.",
+ "components": [ [ [ "plastic_chunk", 1 ] ], [ [ "thread", 25 ] ] ]
+ },
+- {
+- "result": "plunger_toilet",
+- "type": "uncraft",
+- "skill_used": "fabrication",
+- "time": "6 s",
+- "qualities": [ { "id": "CUT", "level": 1 } ],
+- "components": [ [ [ "plastic_chunk", 2 ] ], [ [ "splinter", 3 ] ] ]
+- },
+ {
+ "result": "stopcock",
+ "type": "uncraft",
+--
+2.39.2
+
diff --git a/revert-12_fix-i18n-metric-bullets-part-1-rename-.223-5.56x45mm.patch b/revert-12_fix-i18n-metric-bullets-part-1-rename-.223-5.56x45mm.patch
new file mode 100644
index 0000000..705719a
--- /dev/null
+++ b/revert-12_fix-i18n-metric-bullets-part-1-rename-.223-5.56x45mm.patch
@@ -0,0 +1,291 @@
+From 413fd9596300b354af1c75186631b85956fde57c Mon Sep 17 00:00:00 2001
+From: scarf <greenscarf005@gmail.com>
+Date: Sat, 29 Apr 2023 11:19:43 +0900
+Subject: [PATCH 01/31] fix(i18n): metric bullets part 1: rename `.223` ->
+ `5.56x45mm` (#2691)
+
+* refactor: fully specify milimetre for 5.56x45mm
+
+* refactor: change display name of `.223` to `5.56x45mm`
+
+* refactor: `.223` to `5.56x45mm`
+
+* refactor: make metric diameter primary
+---
+ data/help/texts.json | 2 +-
+ data/json/items/ammo/223.json | 14 +++++++-------
+ data/json/items/ammo_types.json | 3 ++-
+ data/json/items/generic/ammolink.json | 2 +-
+ data/json/items/generic/casing.json | 4 ++--
+ data/json/items/gun/223.json | 8 ++++----
+ data/json/items/magazine/223.json | 12 ++++++------
+ data/json/obsoletion/items.json | 12 ++++++------
+ 9 files changed, 30 insertions(+), 29 deletions(-)
+
+diff --git a/data/help/texts.json b/data/help/texts.json
+index e8599a549fb..a155169f812 100644
+--- a/data/help/texts.json
++++ b/data/help/texts.json
+@@ -316,7 +316,7 @@
+ "Q: Why can't I carry anything?\nA: At the start of the game you only have the space in your pockets. A good first goal of many survivors is to find a backpack or pouch to store things in.",
+ "Q: Help! I started a fire and now my house is burning down!\nA: Fires will spread to nearby flammable tiles if they are able. Lighting a fire in a set-up brazier, stove, wood stove, stone fireplace, pit, or even in a kitchen stove will stop it from spreading. Fire extinguishers can put out fires that get out of control. You can put out a fire in the fireplace by examining it.",
+ "Q: I'm cold and can't sleep at night!\nA: Gather some clothes and put them in the place you use to sleep in. Being hungry, thirsty, wet, or injured can also make you feel the cold more, so try to avoid these effects before you go to sleep. Pillows and some other appliances will help you sleep, and the quality of your sleeping spot is also very important.",
+- "Q: There are too many calibers and guns. It confuses me - I don't usually understand what is compatible with what.\nA: Try to remember few usual calibers: \n9x19 (or simply 9mm) - fits most basic pistols (Glock, for example) and SMGs, quite easy to find and gets job done versus usual zombies;\n 00 buckshot - for most shotguns. Very powerful against unarmored target at closer ranges;\n .223 (5.56) - for rifles. Good long range option.\n .308 (7.62) - for even more powerful rifles. Also good long range option.\n It should be enough in the beginning. Or even just grab any shotgun, fill it with buckshot and give them hell!",
++ "Q: There are too many calibers and guns. It confuses me - I don't usually understand what is compatible with what.\nA: Try to remember few usual calibers: \n9x19mm (or simply 9mm) - fits most basic pistols (Glock, for example) and SMGs, quite easy to find and gets job done versus usual zombies;\n 00 buckshot - for most shotguns. Very powerful against unarmored target at closer ranges;\n 5.56mm (.223) - for rifles. Good long range option.\n 7.62mm (.308) - for even more powerful rifles. Also good long range option.\n It should be enough in the beginning. Or even just grab any shotgun, fill it with buckshot and give them hell!",
+ "Q: I have a question that's not addressed here. How can I get an answer?\nA: Check the wiki, or ask the helpful people on the forum or at the chat channels. Links are provided in MOTD in the main menu."
+ ]
+ }
+diff --git a/data/json/items/ammo/223.json b/data/json/items/ammo/223.json
+index beaea0d4e9f..254058920f2 100644
+--- a/data/json/items/ammo/223.json
++++ b/data/json/items/ammo/223.json
+@@ -2,8 +2,8 @@
+ {
+ "id": "223",
+ "type": "AMMO",
+- "name": { "str": ".223 Remington" },
+- "description": ".223 Remington ammunition with 36gr JHP bullets. The .223 round has been very popular with civilian shooters for almost a century, finding use in a wide variety of weapons. It generates lower pressure than 5.56 NATO leading to slightly decreased accuracy and recoil.",
++ "name": { "str": "5.56x45mm '.223 Remington'" },
++ "description": ".223 Remington ammunition with 36gr JHP bullets. The .223 round has been very popular with civilian shooters for almost a century, finding use in a wide variety of weapons. It generates lower pressure than 5.56x45mm NATO leading to slightly decreased accuracy and recoil.",
+ "weight": "12 g",
+ "volume": "250 ml",
+ "price": "280 cent",
+@@ -27,7 +27,7 @@
+ "id": "556",
+ "copy-from": "223",
+ "type": "AMMO",
+- "name": { "str": "5.56 NATO M855A1" },
++ "name": { "str": "5.56x45mm NATO M855A1" },
+ "description": "5.56x45mm ammunition with a 62gr FMJ bullet containing a steel penetrator. Its light weight, high accuracy, and manageable recoil lead to widespread use in the 20th century and it remains popular among militaries and civilians.",
+ "price": "290 cent",
+ "price_postapoc": "9 USD",
+@@ -41,7 +41,7 @@
+ "id": "556_incendiary",
+ "copy-from": "556",
+ "type": "AMMO",
+- "name": { "str": "5.56 NATO tracer" },
++ "name": { "str": "5.56x45mm NATO tracer" },
+ "description": "This ammunition is a one-in-five mix of M855A1 and M856 tracer rounds to help keep the weapon they are fired from on target.",
+ "extend": { "effects": [ "INCENDIARY" ] }
+ },
+@@ -49,7 +49,7 @@
+ "id": "bp_223",
+ "copy-from": "223",
+ "type": "AMMO",
+- "name": { "str": ".223 Remington, black powder" },
++ "name": { "str": "5.56x45mm '.223 Remington', black powder" },
+ "proportional": {
+ "price": 0.3,
+ "damage": { "damage_type": "bullet", "amount": 0.57, "armor_penetration": 0.5 },
+@@ -63,7 +63,7 @@
+ "id": "bp_556",
+ "copy-from": "556",
+ "type": "AMMO",
+- "name": { "str": "5.56 NATO, black powder" },
++ "name": { "str": "5.56x45mm NATO, black powder" },
+ "proportional": {
+ "price": 0.3,
+ "damage": { "damage_type": "bullet", "amount": 0.57, "armor_penetration": 0.5 },
+@@ -77,7 +77,7 @@
+ "id": "bp_556_incendiary",
+ "copy-from": "556_incendiary",
+ "type": "AMMO",
+- "name": { "str": "5.56 NATO tracer, black powder" },
++ "name": { "str": "5.56x45mm NATO tracer, black powder" },
+ "proportional": {
+ "price": 0.3,
+ "damage": { "damage_type": "bullet", "amount": 0.57, "armor_penetration": 0.5 },
+diff --git a/data/json/items/ammo_types.json b/data/json/items/ammo_types.json
+index 62583254eb9..06cbf7f7e8a 100644
+--- a/data/json/items/ammo_types.json
++++ b/data/json/items/ammo_types.json
+@@ -212,7 +212,8 @@
+ {
+ "type": "ammunition_type",
+ "id": "223",
+- "name": ".223",
++ "//": "This is a 5.56x45mm round, but it's called 223 because legacy migration reasons.",
++ "name": "5.56x45mm",
+ "default": "556"
+ },
+ {
+diff --git a/data/json/items/generic/ammolink.json b/data/json/items/generic/ammolink.json
+index 2f23920986f..b7108aedbbd 100644
+--- a/data/json/items/generic/ammolink.json
++++ b/data/json/items/generic/ammolink.json
+@@ -17,7 +17,7 @@
+ "id": "ammolink223",
+ "copy-from": "ammolink",
+ "type": "GENERIC",
+- "name": { "str": ".223 ammo belt linkage" },
++ "name": { "str": "5.56x45mm ammo belt linkage" },
+ "use_action": { "type": "ammobelt", "belt": "belt223" }
+ },
+ {
+diff --git a/data/json/items/generic/casing.json b/data/json/items/generic/casing.json
+index f486ad3126a..133ceb06528 100644
+--- a/data/json/items/generic/casing.json
++++ b/data/json/items/generic/casing.json
+@@ -14,8 +14,8 @@
+ "id": "223_casing",
+ "copy-from": "casing",
+ "type": "GENERIC",
+- "name": { "str": ".223 casing" },
+- "description": "An empty casing from a .223 round.",
++ "name": { "str": "5.56x45mm casing" },
++ "description": "An empty casing from a 5.56x45mm round.",
+ "weight": "5 g",
+ "volume": "5ml"
+ },
+diff --git a/data/json/items/gun/223.json b/data/json/items/gun/223.json
+index d197c2cade4..5b754865152 100644
+--- a/data/json/items/gun/223.json
++++ b/data/json/items/gun/223.json
+@@ -4,7 +4,7 @@
+ "copy-from": "rifle_auto",
+ "type": "GUN",
+ "name": { "str": "Remington ACR" },
+- "description": "This carbine was developed for military use in the early 21st century. It is damaging and accurate, though its rate of fire is a bit slower than competing .223 carbines.",
++ "description": "This carbine was developed for military use in the early 21st century. It is damaging and accurate, though its rate of fire is a bit slower than competing 5.56x45mm carbines.",
+ "weight": "3590 g",
+ "volume": "2 L",
+ "price": "2343 USD",
+@@ -179,7 +179,7 @@
+ "copy-from": "rifle_auto",
+ "type": "GUN",
+ "name": { "str": "H&K G36" },
+- "description": "Designed as a replacement for the early H&K G3 battle rifle, the G36 is more accurate, and uses the much-lighter .223 round, allowing for a higher ammo capacity.",
++ "description": "Designed as a replacement for the early H&K G3 battle rifle, the G36 is more accurate, and uses the much-lighter 5.56x45mm round, allowing for a higher ammo capacity.",
+ "weight": "3630 g",
+ "volume": "2500 ml",
+ "barrel_length": "250 ml",
+@@ -396,7 +396,7 @@
+ "id": "rifle_223",
+ "copy-from": "rifle_home_made",
+ "type": "GUN",
+- "name": { "str": "pipe rifle: .223", "str_pl": "pipe rifles: .223" },
++ "name": { "str": "pipe rifle: 5.56x45mm", "str_pl": "pipe rifles: 5.56x45mm" },
+ "description": "A home-made rifle. It is simply a pipe attached to a stock, with a hammer to strike the single round it holds.",
+ "weight": "4080 g",
+ "volume": "3 L",
+@@ -447,7 +447,7 @@
+ "copy-from": "rifle_auto",
+ "type": "GUN",
+ "name": { "str": "FN SCAR-L" },
+- "description": "A highly accurate and modular assault rifle specially designed for the United States Special Operations Command. The 'L' in its name stands for light, as it uses the lightweight .223 round.",
++ "description": "A highly accurate and modular assault rifle specially designed for the United States Special Operations Command. The 'L' in its name stands for light, as it uses the lightweight 5.56x45mm round.",
+ "weight": "3300 g",
+ "volume": "2250 ml",
+ "barrel_length": "250 ml",
+diff --git a/data/json/items/magazine/223.json b/data/json/items/magazine/223.json
+index 74ffa8b8ba1..11ac7ac14b1 100644
+--- a/data/json/items/magazine/223.json
++++ b/data/json/items/magazine/223.json
+@@ -33,7 +33,7 @@
+ "id": "ruger5",
+ "looks_like": "stanag30",
+ "type": "MAGAZINE",
+- "name": { "str": "Ruger .223 5-round magazine" },
++ "name": { "str": "Ruger 5.56x45mm 5-round magazine" },
+ "description": "A compact 5-round box magazine used with the Ruger Mini-14 rifle.",
+ "weight": "60 g",
+ "volume": "250 ml",
+@@ -70,7 +70,7 @@
+ "copy-from": "stanag10",
+ "looks_like": "stanag30",
+ "type": "MAGAZINE",
+- "name": { "str": "Ruger .223 10-round magazine" },
++ "name": { "str": "Ruger 5.56x45mm 10-round magazine" },
+ "description": "A compact 10-round box magazine used with the Ruger Mini-14 rifle.",
+ "ammo_type": "223"
+ },
+@@ -79,7 +79,7 @@
+ "copy-from": "stanag20",
+ "looks_like": "stanag30",
+ "type": "MAGAZINE",
+- "name": { "str": "Ruger .223 20-round magazine" },
++ "name": { "str": "Ruger 5.56x45mm 20-round magazine" },
+ "description": "A 20-round box magazine used with the Ruger Mini-14 rifle.",
+ "ammo_type": "223"
+ },
+@@ -87,7 +87,7 @@
+ "id": "ruger30",
+ "looks_like": "stanag30",
+ "type": "MAGAZINE",
+- "name": { "str": "Ruger .223 30-round magazine" },
++ "name": { "str": "Ruger 5.56x45mm 30-round magazine" },
+ "description": "A high-capacity box magazine for use with the Ruger Mini-14 rifle.",
+ "weight": "360 g",
+ "volume": "500 ml",
+@@ -106,7 +106,7 @@
+ "copy-from": "stanag90",
+ "looks_like": "stanag30",
+ "type": "MAGAZINE",
+- "name": { "str": "Ruger .223 90-round snail drum magazine" },
++ "name": { "str": "Ruger 5.56x45mm 90-round snail drum magazine" },
+ "description": "A bulky 90-round snail drum magazine for use with the Ruger Mini-14 rifle.",
+ "ammo_type": "223"
+ },
+@@ -115,7 +115,7 @@
+ "copy-from": "stanag100drum",
+ "looks_like": "stanag30",
+ "type": "MAGAZINE",
+- "name": { "str": "Ruger .223 100-round double drum magazine" },
++ "name": { "str": "Ruger 5.56x45mm 100-round double drum magazine" },
+ "description": "A bulky 100-round double drum magazine for use with the Ruger Mini-14 rifle.",
+ "ammo_type": "223"
+ },
+diff --git a/data/json/obsoletion/items.json b/data/json/obsoletion/items.json
+index 4355e98444f..f90219f33a8 100644
+--- a/data/json/obsoletion/items.json
++++ b/data/json/obsoletion/items.json
+@@ -195,8 +195,8 @@
+ {
+ "id": "retool_223",
+ "type": "GUNMOD",
+- "name": { "str": ".223 caliber conversion kit" },
+- "description": "This kit is used to convert a shotgun, 5.45x39mm, 7.62x39mm, .30-06, or .308 rifle to the popular, accurate, and lighter .223 caliber. The conversion results in slight reductions to both accuracy and ammo capacity.",
++ "name": { "str": "5.56x45mm caliber conversion kit" },
++ "description": "This kit is used to convert a shotgun, 5.45x39mm, 7.62x39mm, .30-06, or .308 rifle to the popular, accurate, and lighter 5.56x45mm caliber. The conversion results in slight reductions to both accuracy and ammo capacity.",
+ "weight": "114 g",
+ "volume": "500 ml",
+ "integral_volume": 0,
+@@ -1662,7 +1662,7 @@
+ "looks_like": "sw_619",
+ "type": "GUN",
+ "name": { "str": "L2037 Backup" },
+- "description": "The logical extension of Leadworks' autorevolver series, this massive 'sidearm' fires 5.56 NATO to share ammo with a soldier's rifle. The muzzle flash and report of this 5-shot revolver are incredible, producing ballistics similar to .357 Magnum. Similar to other Leadworks products it doesn't accept third-party modifications.",
++ "description": "The logical extension of Leadworks' autorevolver series, this massive 'sidearm' fires 5.56x45mm NATO to share ammo with a soldier's rifle. The muzzle flash and report of this 5-shot revolver are incredible, producing ballistics similar to .357 Magnum. Similar to other Leadworks products it doesn't accept third-party modifications.",
+ "weight": "2370 g",
+ "volume": "750 ml",
+ "price": "2670 USD",
+@@ -3971,7 +3971,7 @@
+ "id": "reloaded_223",
+ "copy-from": "223",
+ "type": "AMMO",
+- "name": { "str": ".223 Remington, reloaded" },
++ "name": { "str": "5.56x45mm '.223 Remington', reloaded" },
+ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
+ "extend": { "effects": [ "RECYCLED" ] },
+ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+@@ -3980,7 +3980,7 @@
+ "id": "reloaded_556",
+ "copy-from": "556",
+ "type": "AMMO",
+- "name": { "str": "5.56 NATO, reloaded" },
++ "name": { "str": "5.56x45mm NATO, reloaded" },
+ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
+ "extend": { "effects": [ "RECYCLED" ] },
+ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+@@ -3989,7 +3989,7 @@
+ "id": "reloaded_556_incendiary",
+ "copy-from": "556_incendiary",
+ "type": "AMMO",
+- "name": { "str": "5.56 NATO tracer, reloaded" },
++ "name": { "str": "5.56x45mm NATO tracer, reloaded" },
+ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
+ "extend": { "effects": [ "RECYCLED" ] },
+ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+--
+2.40.0
+
diff --git a/revert-13_fix-i18n-metric-bullets-part-2-rename-.308-7.62x51mm.patch b/revert-13_fix-i18n-metric-bullets-part-2-rename-.308-7.62x51mm.patch
new file mode 100644
index 0000000..1b48c17
--- /dev/null
+++ b/revert-13_fix-i18n-metric-bullets-part-2-rename-.308-7.62x51mm.patch
@@ -0,0 +1,228 @@
+From 4aceff1708412b5778d89a44d0ad178c064c04e6 Mon Sep 17 00:00:00 2001
+From: scarf <greenscarf005@gmail.com>
+Date: Sat, 29 Apr 2023 13:21:19 +0900
+Subject: [PATCH 03/31] fix(i18n): metric bullets part 2: rename `.308` ->
+ `7.62x51mm` (#2724)
+
+* refactor: `7.62` -> `7.62x51mm`
+
+since there's many 7.62mm calibre rounds with different lengths.
+
+* refactor: `.308`-> `7.62x51mm`
+---
+ data/help/texts.json | 2 +-
+ data/json/items/ammo/308.json | 10 +++++-----
+ data/json/items/ammo_types.json | 2 +-
+ data/json/items/generic/ammolink.json | 2 +-
+ data/json/items/generic/casing.json | 4 ++--
+ data/json/items/gun/308.json | 8 ++++----
+ data/json/monsters/turrets.json | 2 +-
+ data/json/obsoletion/items.json | 8 ++++----
+ data/json/requirements/ammo.json | 4 ++--
+ data/mods/Salvaged_Robots/monsters.json | 2 +-
+ doc/GAME_BALANCE.md | 4 ++--
+ tests/ranged_burst_balance_test.cpp | 8 ++++----
+ 23 files changed, 49 insertions(+), 49 deletions(-)
+
+diff --git a/data/help/texts.json b/data/help/texts.json
+index a155169f812..45f26483c03 100644
+--- a/data/help/texts.json
++++ b/data/help/texts.json
+@@ -316,7 +316,7 @@
+ "Q: Why can't I carry anything?\nA: At the start of the game you only have the space in your pockets. A good first goal of many survivors is to find a backpack or pouch to store things in.",
+ "Q: Help! I started a fire and now my house is burning down!\nA: Fires will spread to nearby flammable tiles if they are able. Lighting a fire in a set-up brazier, stove, wood stove, stone fireplace, pit, or even in a kitchen stove will stop it from spreading. Fire extinguishers can put out fires that get out of control. You can put out a fire in the fireplace by examining it.",
+ "Q: I'm cold and can't sleep at night!\nA: Gather some clothes and put them in the place you use to sleep in. Being hungry, thirsty, wet, or injured can also make you feel the cold more, so try to avoid these effects before you go to sleep. Pillows and some other appliances will help you sleep, and the quality of your sleeping spot is also very important.",
+- "Q: There are too many calibers and guns. It confuses me - I don't usually understand what is compatible with what.\nA: Try to remember few usual calibers: \n9x19mm (or simply 9mm) - fits most basic pistols (Glock, for example) and SMGs, quite easy to find and gets job done versus usual zombies;\n 00 buckshot - for most shotguns. Very powerful against unarmored target at closer ranges;\n 5.56mm (.223) - for rifles. Good long range option.\n 7.62mm (.308) - for even more powerful rifles. Also good long range option.\n It should be enough in the beginning. Or even just grab any shotgun, fill it with buckshot and give them hell!",
++ "Q: There are too many calibers and guns. It confuses me - I don't usually understand what is compatible with what.\nA: Try to remember few usual calibers: \n9x19mm (or simply 9mm) - fits most basic pistols (Glock, for example) and SMGs, quite easy to find and gets job done versus usual zombies;\n 00 buckshot - for most shotguns. Very powerful against unarmored target at closer ranges;\n 5.56x45mm (.223) - for rifles. Good long range option.\n 7.62x51mm (.308) - for even more powerful rifles. Also good long range option.\n It should be enough in the beginning. Or even just grab any shotgun, fill it with buckshot and give them hell!",
+ "Q: I have a question that's not addressed here. How can I get an answer?\nA: Check the wiki, or ask the helpful people on the forum or at the chat channels. Links are provided in MOTD in the main menu."
+ ]
+ }
+diff --git a/data/json/items/ammo/308.json b/data/json/items/ammo/308.json
+index 52e9c588eda..c8832a73794 100644
+--- a/data/json/items/ammo/308.json
++++ b/data/json/items/ammo/308.json
+@@ -2,7 +2,7 @@
+ {
+ "id": "308",
+ "type": "AMMO",
+- "name": { "str": ".308 Winchester" },
++ "name": { "str": "7.62x51mm '.308 Winchester'" },
+ "description": ".308 Winchester ammunition with 168gr hollow point bullets. The .308 round is one of the most popular hunting cartridges in the world due to its accuracy and power.",
+ "weight": "18 g",
+ "volume": "250 ml",
+@@ -46,7 +46,7 @@
+ "id": "bp_308",
+ "copy-from": "308",
+ "type": "AMMO",
+- "name": { "str": ".308 Winchester, black powder" },
++ "name": { "str": "7.62x51mm '.308 Winchester', black powder" },
+ "proportional": {
+ "price": 0.3,
+ "damage": { "damage_type": "bullet", "amount": 0.76, "armor_penetration": 0.5 },
+diff --git a/data/json/items/ammo_types.json b/data/json/items/ammo_types.json
+index 06cbf7f7e8a..19c14a9397d 100644
+--- a/data/json/items/ammo_types.json
++++ b/data/json/items/ammo_types.json
+@@ -231,7 +231,7 @@
+ {
+ "type": "ammunition_type",
+ "id": "308",
+- "name": ".308",
++ "name": "7.62x51mm",
+ "default": "762_51"
+ },
+ {
+diff --git a/data/json/items/generic/ammolink.json b/data/json/items/generic/ammolink.json
+index b7108aedbbd..4635d1a3bf4 100644
+--- a/data/json/items/generic/ammolink.json
++++ b/data/json/items/generic/ammolink.json
+@@ -24,7 +24,7 @@
+ "id": "ammolink308",
+ "copy-from": "ammolink",
+ "type": "GENERIC",
+- "name": { "str": ".308 ammo belt linkage" },
++ "name": { "str": "7.62x51mm ammo belt linkage" },
+ "use_action": { "type": "ammobelt", "belt": "belt308" }
+ },
+ {
+diff --git a/data/json/items/generic/casing.json b/data/json/items/generic/casing.json
+index 133ceb06528..1643fd856e7 100644
+--- a/data/json/items/generic/casing.json
++++ b/data/json/items/generic/casing.json
+@@ -78,8 +78,8 @@
+ "copy-from": "casing",
+ "looks_like": "223_casing",
+ "type": "GENERIC",
+- "name": { "str": ".308 casing" },
+- "description": "An empty casing from a .308 round.",
++ "name": { "str": "7.62x51mm '.308 Winchester' casing" },
++ "description": "An empty casing from a 7.62x51mm '.308 Winchester' round.",
+ "weight": "6 g",
+ "volume": "9ml"
+ },
+diff --git a/data/json/items/gun/308.json b/data/json/items/gun/308.json
+index 0bc0eecb631..30c25837e42 100644
+--- a/data/json/items/gun/308.json
++++ b/data/json/items/gun/308.json
+@@ -206,8 +206,8 @@
+ "copy-from": "rifle_manual",
+ "type": "GUN",
+ "name": { "str": "handmade heavy carbine" },
+- "//": "It's amongst the smallest of the .308 firearms, and a scrap weapon as well. This means a short handmade barrel, and considerable loss of energy.",
+- "description": "A homemade lever-action magazine-fed smoothbore rifle. While still a primitive pipe and 2x4 design, some minor improvements have been made, such as being able to accept G3 compatible magazines, and chambering the more powerful .308 rounds.",
++ "//": "It's amongst the smallest of the 7.62x51mm(.308) firearms, and a scrap weapon as well. This means a short handmade barrel, and considerable loss of energy.",
++ "description": "A homemade lever-action magazine-fed smoothbore rifle. While still a primitive pipe and 2x4 design, some minor improvements have been made, such as being able to accept G3 compatible magazines, and chambering the more powerful 7.62x51mm (.308) rounds.",
+ "weight": "2311 g",
+ "volume": "2 L",
+ "price": "100 USD",
+@@ -243,7 +243,7 @@
+ "copy-from": "rifle_manual",
+ "type": "GUN",
+ "name": { "str_sp": "Savage 111F" },
+- "description": "A very accurate rifle chambered for the powerful .308 round. Its very low ammo capacity is offset by its accuracy and near-complete lack of recoil.",
++ "description": "A very accurate rifle chambered for the powerful 7.62x51mm (.308) round. Its very low ammo capacity is offset by its accuracy and near-complete lack of recoil.",
+ "weight": "2993 g",
+ "volume": "3 L",
+ "price": "530 USD",
+@@ -264,7 +264,7 @@
+ "copy-from": "scar_l",
+ "type": "GUN",
+ "name": { "str_sp": "FN SCAR-H" },
+- "description": "A highly accurate and modular battle rifle specially designed for the United States Special Operations Command. The 'H' in its name stands for heavy, as it uses the powerful .308 round.",
++ "description": "A highly accurate and modular battle rifle specially designed for the United States Special Operations Command. The 'H' in its name stands for heavy, as it uses the powerful 7.62x51mm (.308) round.",
+ "weight": "3640 g",
+ "ascii_picture": "scar-H",
+ "ammo": "308",
+diff --git a/data/json/monsters/turrets.json b/data/json/monsters/turrets.json
+index df9783c632d..396a7007c88 100644
+--- a/data/json/monsters/turrets.json
++++ b/data/json/monsters/turrets.json
+@@ -254,7 +254,7 @@
+ "id": "mon_turret_longrange",
+ "type": "MONSTER",
+ "name": { "str": "longrange milspec turret" },
+- "description": "The General Atomics TX-7 Sniper, an automated milspec turret equipped with a 7.62mm gun. Designed as a counter-sniper turret to cover the vulnerability of TX-5 Sentinel to sniper fire. Its advanced target recognition system and 7.62mm gun allows it to engage targets protected by modern body armor at very long range.",
++ "description": "The General Atomics TX-7 Sniper, an automated milspec turret equipped with a 7.62x51mm gun. Designed as a counter-sniper turret to cover the vulnerability of TX-5 Sentinel to sniper fire. Its advanced target recognition system and 7.62x51mm gun allows it to engage targets protected by modern body armor at very long range.",
+ "default_faction": "military",
+ "species": [ "ROBOT" ],
+ "looks_like": "mon_turret_bmg",
+diff --git a/data/json/obsoletion/items.json b/data/json/obsoletion/items.json
+index f90219f33a8..1b029a72e13 100644
+--- a/data/json/obsoletion/items.json
++++ b/data/json/obsoletion/items.json
+@@ -196,7 +196,7 @@
+ "id": "retool_223",
+ "type": "GUNMOD",
+ "name": { "str": "5.56x45mm caliber conversion kit" },
+- "description": "This kit is used to convert a shotgun, 5.45x39mm, 7.62x39mm, .30-06, or .308 rifle to the popular, accurate, and lighter 5.56x45mm caliber. The conversion results in slight reductions to both accuracy and ammo capacity.",
++ "description": "This kit is used to convert a shotgun, 5.45x39mm, 7.62x39mm, .30-06, or 7.62x51mm rifle to the popular, accurate, and lighter 5.56x45mm caliber. The conversion results in slight reductions to both accuracy and ammo capacity.",
+ "weight": "114 g",
+ "volume": "500 ml",
+ "integral_volume": 0,
+@@ -215,8 +215,8 @@
+ {
+ "id": "retool_308",
+ "type": "GUNMOD",
+- "name": { "str": ".308 caliber conversion kit" },
+- "description": "This kit is used to convert a shotgun or 7.62x39mm, .223 or .30-06 rifle to the popular and powerful .308 caliber. The conversion results in reduced ammo capacity and a slight reduction to accuracy.",
++ "name": { "str": "7.62x51mm caliber conversion kit" },
++ "description": "This kit is used to convert a shotgun or 7.62x39mm, .223 or .30-06 rifle to the popular and powerful 7.62x51mm caliber. The conversion results in reduced ammo capacity and a slight reduction to accuracy.",
+ "weight": "114 g",
+ "volume": "500 ml",
+ "integral_volume": 0,
+@@ -4027,7 +4027,7 @@
+ "id": "reloaded_308",
+ "copy-from": "308",
+ "type": "AMMO",
+- "name": { "str": ".308 Winchester, reloaded" },
++ "name": { "str": "7.62x51mm '.308 Winchester', reloaded" },
+ "proportional": { "price": 0.7, "damage": { "damage_type": "bullet", "amount": 0.9 }, "dispersion": 1.1 },
+ "extend": { "effects": [ "RECYCLED" ] },
+ "delete": { "effects": [ "NEVER_MISFIRES" ], "flags": [ "IRREPLACEABLE_CONSUMABLE" ] }
+diff --git a/data/json/requirements/ammo.json b/data/json/requirements/ammo.json
+index add42666055..7b1a6d112fa 100644
+--- a/data/json/requirements/ammo.json
++++ b/data/json/requirements/ammo.json
+@@ -97,7 +97,7 @@
+ {
+ "id": "223_casehead",
+ "type": "requirement",
+- "//": "References needed for boltfaces and magazines using .223 or derivatives",
++ "//": "References needed for boltfaces and magazines using 5.56x45mm (.223) or derivatives",
+ "tools": [
+ [
+ [ "300blk_casing", -1 ],
+@@ -121,7 +121,7 @@
+ {
+ "id": "308_casehead",
+ "type": "requirement",
+- "//": "References needed for boltfaces and magazines using .308 or derivatives",
++ "//": "References needed for boltfaces and magazines using 7.62x51mm (.308) or derivatives",
+ "tools": [
+ [
+ [ "308_casing", -1 ],
+diff --git a/tests/ranged_burst_balance_test.cpp b/tests/ranged_burst_balance_test.cpp
+index ec61fad0613..de55646f92d 100644
+--- a/tests/ranged_burst_balance_test.cpp
++++ b/tests/ranged_burst_balance_test.cpp
+@@ -61,13 +61,13 @@ TEST_CASE( "unskilled_burst_no_mods", "[ranged] [balance]" )
+ check_burst_penalty( shooter, "american_180", 0 );
+ // 9mm SMG - should be manageable
+ check_burst_penalty( shooter, "calico", 60 );
+- // .223 machine gun - should have lower penalty than a rifle of the same caliber
++ // 5.56x45mm machine gun - should have lower penalty than a rifle of the same caliber
+ check_burst_penalty( shooter, "m249", 250 );
+- // .223 rifle
++ // 5.56x45mm rifle
+ check_burst_penalty( shooter, "m4a1", 600 );
+- // 7.62 rifle
++ // 7.62x39mm rifle
+ check_burst_penalty( shooter, "ak47", 700 );
+- // .50 machine gun - heaviest expected burst fire
++ // 12.7mm '.50 BMG' machine gun - heaviest expected burst fire
+ check_burst_penalty( shooter, "m2browning", 800 );
+ }
+
+--
+2.40.0
+
diff --git a/revert-15_Fix-mutant-scenarios-adding-an-obsoleted-trait-2929.patch b/revert-15_Fix-mutant-scenarios-adding-an-obsoleted-trait-2929.patch
new file mode 100644
index 0000000..4a65221
--- /dev/null
+++ b/revert-15_Fix-mutant-scenarios-adding-an-obsoleted-trait-2929.patch
@@ -0,0 +1,34 @@
+From f25e3e13491872cef28f7bcf245c4b3f0c5dc5f5 Mon Sep 17 00:00:00 2001
+From: Chaosvolt <chaosvolt@users.noreply.github.com>
+Date: Sun, 4 Jun 2023 12:30:28 -0500
+Subject: [PATCH] Fix mutant scenarios adding an obsoleted trait (#2929)
+
+---
+ data/json/scenarios.json | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/data/json/scenarios.json b/data/json/scenarios.json
+index 4b0a90da8b1..20c82aba2d4 100644
+--- a/data/json/scenarios.json
++++ b/data/json/scenarios.json
+@@ -250,7 +250,7 @@
+ "allowed_locs": [ "sloc_lab_random", "sloc_lab_escape_cells", "sloc_lab_finale", "sloc_ice_lab_stairs", "sloc_ice_lab_finale" ],
+ "traits": [
+ "ELFAEYES",
+- "URSINE_EYE",
++ "NIGHTVISION2",
+ "FANGS",
+ "GILLS",
+ "SPINES",
+@@ -489,7 +489,7 @@
+ ],
+ "traits": [
+ "ELFAEYES",
+- "URSINE_EYE",
++ "NIGHTVISION2",
+ "FANGS",
+ "GILLS",
+ "SPINES",
+--
+2.40.1
+
diff --git a/revert-18-Simplify-broken-limb-mending-3054.patch b/revert-18-Simplify-broken-limb-mending-3054.patch
new file mode 100644
index 0000000..70c1259
--- /dev/null
+++ b/revert-18-Simplify-broken-limb-mending-3054.patch
@@ -0,0 +1,821 @@
+From d8aa6d9696fbce4339edfccf96df85ae438a8fad Mon Sep 17 00:00:00 2001
+From: Coolthulhu <Coolthulhu@gmail.com>
+Date: Thu, 21 Sep 2023 15:58:59 +0200
+Subject: [PATCH] Simplify broken limb mending (#3054)
+
+* Rework broken limbs and mending
+
+* Redesign mending_modifier: 1.0 is same as splint
+
+* Update comments
+
+* Update disabled effect description
+
+---------
+
+Co-authored-by: Olanti <olanti-p@yandex.ru>
+---
+ data/json/effects.json | 14 +---
+ data/json/mutations/mutations.json | 33 ++++-----
+ data/json/obsoletion/effects.json | 4 +
+ src/bionics.cpp | 24 ------
+ src/character.cpp | 66 +++++++++--------
+ src/character.h | 6 +-
+ src/creature.cpp | 4 +-
+ src/iexamine.cpp | 15 ++--
+ src/iuse_actor.cpp | 12 ---
+ src/mutation.h | 6 +-
+ src/mutation_data.cpp | 2 +-
+ src/npc.cpp | 3 +-
+ src/panels.cpp | 45 ++++++-----
+ src/player_hardcoded_effects.cpp | 7 +-
+ src/suffer.cpp | 115 -----------------------------
+ tests/player_helpers.cpp | 3 +
+ 16 files changed, 96 insertions(+), 263 deletions(-)
+
+diff --git a/data/json/effects.json b/data/json/effects.json
+index 394bfb1a915..969cafe5046 100644
+--- a/data/json/effects.json
++++ b/data/json/effects.json
+@@ -1802,23 +1802,11 @@
+ "max_duration": "1 s",
+ "rating": "bad"
+ },
+- {
+- "type": "effect_type",
+- "id": "mending",
+- "name": [ "Started recovery", "Recovering", "Mostly recovered" ],
+- "desc": [ "This damaged limb is slowly regaining its functions." ],
+- "//": "Duration is 10 days, but the actual time taken is probabilistic.",
+- "max_duration": "10 d",
+- "int_dur_factor": "60 h",
+- "max_intensity": 3,
+- "rating": "good",
+- "permanent": true
+- },
+ {
+ "type": "effect_type",
+ "id": "disabled",
+ "name": [ { "ctxt": "physically", "str": "Disabled" } ],
+- "desc": [ "This limb is damaged beyond use and may require a splint to recover." ],
++ "desc": [ "This limb is damaged beyond use and must fully heal to recover. Using a splint may speed up the process." ],
+ "//": "This sounds weird. We need <bp_affected> tag or something",
+ "apply_message": "Your limb breaks!",
+ "remove_message": "The broken limb has mended.",
+diff --git a/data/json/mutations/mutations.json b/data/json/mutations/mutations.json
+index 1fe217b8559..333a471d30e 100644
+--- a/data/json/mutations/mutations.json
++++ b/data/json/mutations/mutations.json
+@@ -155,7 +155,7 @@
+ "category": [ "MEDICAL" ],
+ "healing_awake": 0.2,
+ "healing_resting": 0.5,
+- "mending_modifier": 2.0
++ "mending_modifier": 0.5
+ },
+ {
+ "type": "mutation",
+@@ -722,37 +722,34 @@
+ "id": "SLOWHEALER",
+ "name": { "str": "Slow Healer" },
+ "points": -2,
+- "description": "Your wounds heal a little slower than most. Your HP whilst asleep, as well as your broken limbs, heal at 75% of the regular rate.",
++ "description": "Your wounds heal a little slower than most. Your HP whilst asleep heals at 75% of the regular rate.",
+ "starting_trait": true,
+ "types": [ "HEALING" ],
+- "healing_resting": -0.25,
+- "mending_modifier": 0.5
++ "healing_resting": -0.25
+ },
+ {
+ "type": "mutation",
+ "id": "SLOWHEALER2",
+ "name": { "str": "Poor Healer" },
+ "points": -4,
+- "description": "Your health recovery is severely impaired. Your HP whilst asleep, as well as your broken limbs, heal at 33% of the regular rate.",
++ "description": "Your health recovery is severely impaired. Your HP whilst asleep heals at 33% of the regular rate.",
+ "starting_trait": true,
+ "valid": false,
+ "purifiable": false,
+ "types": [ "HEALING" ],
+- "healing_resting": -0.66,
+- "mending_modifier": 0.33
++ "healing_resting": -0.66
+ },
+ {
+ "type": "mutation",
+ "id": "SLOWHEALER3",
+ "name": { "str": "Imperceptive Healer" },
+ "points": -8,
+- "description": "Wounds are incredibly dangerous to you, as they barely heal at all. Your HP whilst asleep, as well as your broken limbs, heal at 10% of the regular rate.",
++ "description": "Wounds are incredibly dangerous to you, as they barely heal at all. Your HP whilst asleep heals at 10% of the regular rate.",
+ "starting_trait": true,
+ "valid": false,
+ "purifiable": false,
+ "types": [ "HEALING" ],
+- "healing_resting": -0.9,
+- "mending_modifier": 0.1
++ "healing_resting": -0.9
+ },
+ {
+ "type": "mutation",
+@@ -1377,34 +1374,34 @@
+ "category": [ "PLANT", "LIZARD" ],
+ "healing_awake": 0.66,
+ "healing_resting": 0.5,
+- "mending_modifier": 4
++ "mending_modifier": 0.5
+ },
+ {
+ "type": "mutation",
+ "id": "REGEN",
+ "name": { "str": "Regeneration" },
+ "points": 6,
+- "description": "Your flesh regenerates from wounds incredibly quickly. You heal 150% faster whilst asleep and 200% faster whilst awake. Your broken limbs also heal 16 times faster than usual.",
++ "description": "Your flesh regenerates from wounds incredibly quickly. You heal 150% faster whilst asleep and 200% faster whilst awake. You do not require splints to heal broken limbs.",
+ "types": [ "HEALING" ],
+ "prereqs": [ "FASTHEALER2" ],
+ "category": [ "SLIME", "TROGLOBITE" ],
+ "healing_awake": 2,
+ "healing_resting": 1.5,
+- "mending_modifier": 16
++ "mending_modifier": 1
+ },
+ {
+ "type": "mutation",
+ "id": "REGEN_LIZ",
+ "name": { "str": "Reptilian Healing" },
+- "points": 5,
++ "//": "Not worth a point, barely more than flavor.",
++ "points": 0,
+ "valid": false,
+ "purifiable": false,
+- "description": "Your broken limbs mend themselves without significant difficulty. You do not require splints and broken limbs heal 20 times faster than usual.",
+- "cancels": [ "ROT1", "ROT2", "ROT3" ],
+- "prereqs": [ "FASTHEALER2" ],
++ "description": "Your broken limbs mend themselves without significant difficulty. You do not require splints.",
++ "prereqs": [ "FASTHEALER" ],
+ "threshreq": [ "THRESH_LIZARD" ],
+ "category": [ "LIZARD" ],
+- "mending_modifier": 20
++ "mending_modifier": 1
+ },
+ {
+ "type": "mutation",
+diff --git a/data/json/obsoletion/effects.json b/data/json/obsoletion/effects.json
+index 38c218728cd..bb666566f6b 100644
+--- a/data/json/obsoletion/effects.json
++++ b/data/json/obsoletion/effects.json
+@@ -60,5 +60,9 @@
+ {
+ "type": "effect_type",
+ "id": "took_anticonvulsant_visible"
++ },
++ {
++ "type": "effect_type",
++ "id": "mending"
+ }
+ ]
+diff --git a/src/bionics.cpp b/src/bionics.cpp
+index 78827e780d7..bb2b2bd73e7 100644
+--- a/src/bionics.cpp
++++ b/src/bionics.cpp
+@@ -101,7 +101,6 @@ static const efftype_id effect_fungus( "fungus" );
+ static const efftype_id effect_hallu( "hallu" );
+ static const efftype_id effect_heating_bionic( "heating_bionic" );
+ static const efftype_id effect_iodine( "iodine" );
+-static const efftype_id effect_mending( "mending" );
+ static const efftype_id effect_meth( "meth" );
+ static const efftype_id effect_narcosis( "narcosis" );
+ static const efftype_id effect_operating( "operating" );
+@@ -190,7 +189,6 @@
+ static const trait_id trait_PROF_AUTODOC( "PROF_AUTODOC" );
+ static const trait_id trait_PROF_MED( "PROF_MED" );
+ static const trait_id trait_PYROMANIA( "PYROMANIA" );
+-static const trait_id trait_REGEN_LIZ( "REGEN_LIZ" );
+ static const trait_id trait_THRESH_MEDICAL( "THRESH_MEDICAL" );
+
+ static const flag_id flag_BIONIC_GUN( "BIONIC_GUN" );
+@@ -1675,18 +1673,6 @@ void Character::process_bionic( bionic &bio )
+ }
+ if( calendar::once_every( 2_minutes ) ) {
+ std::vector<bodypart_id> damaged_hp_parts;
+- std::vector<effect *> mending_list;
+-
+- for( const bodypart_id &bp : get_all_body_parts( true ) ) {
+- const int hp_cur = get_part_hp_cur( bp );
+- if( !is_limb_broken( bp ) && hp_cur < get_part_hp_max( bp ) ) {
+- damaged_hp_parts.push_back( bp );
+- } else if( has_effect( effect_mending, bp.id() ) &&
+- ( has_trait( trait_REGEN_LIZ ) || worn_with_flag( flag_SPLINT, bp ) ) ) {
+- effect *e = &get_effect( effect_mending, bp->token );
+- mending_list.push_back( e );
+- }
+- }
+ if( !damaged_hp_parts.empty() ) {
+ // Essential parts are considered 10 HP lower than non-essential parts for the purpose of determining priority.
+ // I'd use the essential_value, but it's tied up in the heal_actor class of iuse_actor.
+@@ -1703,16 +1689,6 @@ void Character::process_bionic( bionic &bio )
+ mod_stored_kcal( -bio.info().kcal_trigger );
+ }
+ }
+- if( !mending_list.empty() ) {
+- for( effect *e : mending_list ) {
+- if( !can_use_bionic() ) {
+- return;
+- }
+- e->mod_duration( e->get_max_duration() / 100 );
+- mod_power_level( -bio.info().power_trigger );
+- mod_stored_kcal( -bio.info().kcal_trigger );
+- }
+- }
+ }
+ }
+ } else if( bio.id == bio_painkiller ) {
+diff --git a/src/character.cpp b/src/character.cpp
+index 6cb10461791..761e0785f44 100644
+--- a/src/character.cpp
++++ b/src/character.cpp
+@@ -140,6 +140,7 @@ static const efftype_id effect_cough_suppress( "cough_suppress" );
+ static const efftype_id effect_crushed( "crushed" );
+ static const efftype_id effect_darkness( "darkness" );
+ static const efftype_id effect_deaf( "deaf" );
++static const efftype_id effect_disabled( "disabled" );
+ static const efftype_id effect_disinfected( "disinfected" );
+ static const efftype_id effect_downed( "downed" );
+ static const efftype_id effect_drunk( "drunk" );
+@@ -167,7 +168,6 @@ static const efftype_id effect_lying_down( "lying_down" );
+ static const efftype_id effect_melatonin_supplements( "melatonin" );
+ static const efftype_id effect_meth( "meth" );
+ static const efftype_id effect_masked_scent( "masked_scent" );
+-static const efftype_id effect_mending( "mending" );
+ static const efftype_id effect_narcosis( "narcosis" );
+ static const efftype_id effect_nausea( "nausea" );
+ static const efftype_id effect_no_sight( "no_sight" );
+@@ -287,7 +287,6 @@ static const trait_id trait_INFRARED( "INFRARED" );
+ static const trait_id trait_LEG_TENT_BRACE( "LEG_TENT_BRACE" );
+ static const trait_id trait_LIGHT_BONES( "LIGHT_BONES" );
+ static const trait_id trait_LIZ_IR( "LIZ_IR" );
+-static const trait_id trait_REGEN_LIZ( "REGEN_LIZ" );
+ static const trait_id trait_M_DEPENDENT( "M_DEPENDENT" );
+ static const trait_id trait_M_IMMUNE( "M_IMMUNE" );
+ static const trait_id trait_M_SKIN2( "M_SKIN2" );
+@@ -1257,14 +1256,15 @@ int Character::get_working_leg_count() const
+
+ bool Character::is_limb_disabled( const bodypart_id &limb ) const
+ {
+- return get_part_hp_cur( limb ) <= get_part_hp_max( limb ) * .125;
++ return is_limb_broken( limb ) ||
++ ( get_part_hp_cur( limb ) <= get_part_hp_max( limb ) * 0.125 );
+ }
+
+ // this is the source of truth on if a limb is broken so all code to determine
+ // if a limb is broken should point here to make any future changes to breaking easier
+ bool Character::is_limb_broken( const bodypart_id &limb ) const
+ {
+- return get_part_hp_cur( limb ) <= 0;
++ return has_effect( effect_disabled, limb.id() );
+ }
+
+ bool Character::can_run()
+@@ -4580,8 +4580,17 @@ void Character::regen( int rate_multiplier )
+
+ float rest = rest_quality();
+ float heal_rate = healing_rate( rest ) * to_turns<int>( 5_minutes );
++ const float broken_regen_mod = clamp( mutation_value( "mending_modifier" ), 0.25f, 1.0f );
+ if( heal_rate > 0.0f ) {
+- healall( roll_remainder( rate_multiplier * heal_rate ) );
++ const int base_heal = roll_remainder( rate_multiplier * heal_rate );
++ const int broken_heal = roll_remainder( base_heal * broken_regen_mod );
++
++ for( const bodypart_id &bp : get_all_body_parts() ) {
++ const bool is_broken = is_limb_broken( bp ) &&
++ !worn_with_flag( flag_SPLINT, bp );
++ heal( bp, is_broken ? broken_heal : base_heal );
++ mod_part_healed_total( bp, is_broken ? broken_heal : base_heal );
++ }
+ } else if( heal_rate < 0.0f ) {
+ int rot_rate = roll_remainder( rate_multiplier * -heal_rate );
+ // Has to be in loop because some effects depend on rounding
+@@ -4595,9 +4604,13 @@ void Character::regen( int rate_multiplier )
+ const bodypart_id &bp = convert_bp( hp_to_bp( static_cast<hp_part>( i ) ) ).id();
+ float healing = healing_rate_medicine( rest, bp ) * to_turns<int>( 5_minutes );
+
+- int healing_apply = roll_remainder( healing );
++ const bool is_broken = is_limb_broken( bp ) &&
++ !worn_with_flag( flag_SPLINT, bp );
++ const int healing_apply = roll_remainder( is_broken ? healing *broken_regen_mod : healing );
++
+ healed_bp( i, healing_apply );
+ heal( bp, healing_apply );
++
+ if( damage_bandaged[i] > 0 ) {
+ damage_bandaged[i] -= healing_apply;
+ if( damage_bandaged[i] <= 0 ) {
+@@ -4707,9 +4720,6 @@ void Character::update_body( const time_point &from, const time_point &to )
+ check_needs_extremes();
+ update_needs( five_mins );
+ regen( five_mins );
+- // Note: mend ticks once per 5 minutes, but wants rate in TURNS, not 5 minute intervals
+- // TODO: change @ref med to take time_duration
+- mend( five_mins * to_turns<int>( 5_minutes ) );
+ }
+ if( ticks_between( from, to, 24_hours ) > 0 ) {
+ enforce_minimum_healing();
+@@ -5800,15 +5810,11 @@ hp_part Character::body_window( const std::string &menu_header,
+ const nc_color all_state_col = limb_color( bp, true, true, true );
+ // Broken means no HP can be restored, it requires surgical attention.
+ const bool limb_is_broken = is_limb_broken( bp );
+- const bool limb_is_mending = limb_is_broken &&
+- ( worn_with_flag( flag_SPLINT, bp ) || has_trait( trait_REGEN_LIZ ) );
+
+ if( show_all ) {
+ e.allowed = true;
+ } else if( has_curable_effect ) {
+ e.allowed = true;
+- } else if( limb_is_broken ) {
+- e.allowed = false;
+ } else if( current_hp < maximal_hp && ( e.bonus != 0 || bandage_power > 0.0f ||
+ disinfectant_power > 0.0f ) ) {
+ e.allowed = true;
+@@ -5837,21 +5843,21 @@ hp_part Character::body_window( const std::string &menu_header,
+
+ const auto &aligned_name = std::string( max_bp_name_len - utf8_width( e.name ), ' ' ) + e.name;
+ std::string hp_str;
+- if( limb_is_mending ) {
+- desc += colorize( _( "It is broken but has been set and just needs time to heal." ),
++ if( limb_is_broken ) {
++ const nc_color color = worn_with_flag( flag_SPLINT, bp ) ||
++ ( mutation_value( "mending_modifier" ) >= 1.0f ) ?
++ c_blue :
++ c_light_red;
++ desc += colorize( _( "It is broken and must heal fully before it becomes functional again." ),
+ c_blue ) + "\n";
+- const auto &eff = get_effect( effect_mending, bp_token );
+- const int mend_perc = eff.is_null() ? 0.0 : 100 * eff.get_duration() / eff.get_max_duration();
++ const int mend_perc = 100 * current_hp / maximal_hp;
+
+ if( precise ) {
+- hp_str = colorize( string_format( "=%2d%%=", mend_perc ), c_blue );
++ hp_str = colorize( string_format( "=%2d%%=", mend_perc ), color );
+ } else {
+ const int num = mend_perc / 20;
+- hp_str = colorize( std::string( num, '#' ) + std::string( 5 - num, '=' ), c_blue );
++ hp_str = colorize( std::string( num, '#' ) + std::string( 5 - num, '=' ), color );
+ }
+- } else if( limb_is_broken ) {
+- desc += colorize( _( "It is broken. It needs a splint or surgical attention." ), c_red ) + "\n";
+- hp_str = "==%==";
+ } else if( precise ) {
+ hp_str = string_format( "%d", current_hp );
+ } else {
+@@ -8431,10 +8437,5 @@ void Character::apply_damage( Creature *source, bodypart_id hurt, int dam,
+ put_into_vehicle_or_drop( *this, item_drop_reason::tumbling, remove_primary_weapon() );
+ }
+- if( has_effect( effect_mending, part_to_damage->token ) ) {
+- effect &e = get_effect( effect_mending, part_to_damage->token );
+- float remove_mend = dam / 20.0f;
+- e.mod_duration( -e.get_max_duration() * remove_mend );
+- }
+
+ if( dam > get_painkiller() ) {
+ on_hurt( source );
+@@ -8646,10 +8647,13 @@ int Character::reduce_healing_effect( const efftype_id &eff_id, int remove_med,
+
+ void Character::heal( const bodypart_id &healed, int dam )
+ {
+- if( !is_limb_broken( healed ) ) {
+- int effective_heal = std::min( dam, get_part_hp_max( healed ) - get_part_hp_cur( healed ) );
+- mod_part_hp_cur( healed, effective_heal );
+- g->events().send<event_type::character_heals_damage>( getID(), effective_heal );
++ const int max_hp = get_part_hp_max( healed );
++ const int cur_hp = get_part_hp_cur( healed );
++ const int effective_heal = std::min( dam, max_hp - cur_hp );
++ mod_part_hp_cur( healed, effective_heal );
++ g->events().send<event_type::character_heals_damage>( getID(), effective_heal );
++ if( cur_hp + dam >= max_hp ) {
++ remove_effect( effect_disabled, healed.id() );
+ }
+ }
+
+diff --git a/src/character.h b/src/character.h
+index c3ff9d3f7eb..a84bf824865 100644
+--- a/src/character.h
++++ b/src/character.h
+@@ -742,10 +742,8 @@ class Character : public Creature, public visitable<Character>
+ int get_working_arm_count() const;
+ /** Returns the number of functioning legs */
+ int get_working_leg_count() const;
+- /** Returns true if the limb is disabled(12.5% or less hp)*/
++ /** Returns true if the limb is disabled (12.5% or less hp, or broken)*/
+ bool is_limb_disabled( const bodypart_id &limb ) const;
+- /** Returns true if the limb is hindered(40% or less hp) */
+- bool is_limb_hindered( hp_part limb ) const;
+ /** Returns true if the limb is broken */
+ bool is_limb_broken( const bodypart_id &limb ) const;
+ /** source of truth of whether a Character can run */
+@@ -2063,8 +2061,6 @@ class Character : public Creature, public visitable<Character>
+ void suffer();
+ /** Handles mitigation and application of radiation */
+ bool irradiate( float rads, bool bypass = false );
+- /** Handles the chance for broken limbs to spontaneously heal to 1 HP */
+- void mend( int rate_multiplier );
+
+ /** Creates an auditory hallucination */
+ void sound_hallu();
+diff --git a/src/creature.cpp b/src/creature.cpp
+index 0d69db54329..d1c48950682 100644
+--- a/src/creature.cpp
++++ b/src/creature.cpp
+@@ -1652,14 +1652,14 @@ void Creature::mod_part_healed_total( const bodypart_id &id, int mod )
+ void Creature::set_all_parts_hp_cur( const int set )
+ {
+ for( std::pair<const bodypart_str_id, bodypart> &elem : body ) {
+- elem.second.set_hp_cur( set );
++ set_part_hp_cur( elem.first, set );
+ }
+ }
+
+ void Creature::set_all_parts_hp_to_max()
+ {
+ for( std::pair<const bodypart_str_id, bodypart> &elem : body ) {
+- elem.second.set_hp_to_max();
++ set_part_hp_cur( elem.first, get_part_hp_max( elem.first ) );
+ }
+ }
+
+diff --git a/src/iexamine.cpp b/src/iexamine.cpp
+index cb1af8fb5a7..5295e4bf0ca 100644
+--- a/src/iexamine.cpp
++++ b/src/iexamine.cpp
+@@ -123,7 +123,6 @@ static const efftype_id effect_bleed( "bleed" );
+ static const efftype_id effect_disinfected( "disinfected" );
+ static const efftype_id effect_earphones( "earphones" );
+ static const efftype_id effect_infected( "infected" );
+-static const efftype_id effect_mending( "mending" );
+ static const efftype_id effect_pblue( "pblue" );
+ static const efftype_id effect_pkill2( "pkill2" );
+ static const efftype_id effect_sleep( "sleep" );
+@@ -5081,11 +5080,7 @@ void iexamine::autodoc( player &p, const tripoint &examp )
+ for( int i = 0; i < num_hp_parts; i++ ) {
+ const bodypart_id &part = convert_bp( player::hp_to_bp( static_cast<hp_part>( i ) ) ).id();
+ const bool broken = patient.is_limb_broken( part );
+- effect &existing_effect = patient.get_effect( effect_mending, part->token );
+- // Skip part if not broken or already healed 50%
+- if( !broken || ( !existing_effect.is_null() &&
+- existing_effect.get_duration() >
+- existing_effect.get_max_duration() - 5_days - 1_turns ) ) {
++ if( !broken ) {
+ continue;
+ }
+ broken_limbs_count++;
+@@ -5116,9 +5111,11 @@ void iexamine::autodoc( player &p, const tripoint &examp )
+ patient.add_msg_player_or_npc( m_good, _( "The machine rapidly sets and splints your broken %s." ),
+ _( "The machine rapidly sets and splints <npcname>'s broken %s." ),
+ body_part_name( part ) );
+- patient.add_effect( effect_mending, 0_turns, part->token );
+- effect &mending_effect = patient.get_effect( effect_mending, part->token );
+- mending_effect.set_duration( mending_effect.get_max_duration() - 5_days );
++ // TODO: Prevent exploits with hp draining stuff?
++ int heal_amt = patient.get_part_hp_max( part ) / 2 - patient.get_part_hp_cur( part );
++ if( heal_amt > 0 ) {
++ patient.heal( part, heal_amt );
++ }
+ }
+ }
+ if( broken_limbs_count == 0 ) {
+diff --git a/src/iuse_actor.cpp b/src/iuse_actor.cpp
+index a0d6e66b7dc..4a0eb9befdb 100644
+--- a/src/iuse_actor.cpp
++++ b/src/iuse_actor.cpp
+@@ -3903,18 +3903,6 @@ static hp_part pick_part_to_heal(
+ return healed_part;
+ }
+
+- if( patient.is_limb_broken( bp ) ) {
+- if( healed_part == hp_arm_l || healed_part == hp_arm_r ) {
+- add_msg( m_info, _( "That arm is broken. It needs surgical attention or a splint." ) );
+- } else if( healed_part == hp_leg_l || healed_part == hp_leg_r ) {
+- add_msg( m_info, _( "That leg is broken. It needs surgical attention or a splint." ) );
+- } else {
+- add_msg( m_info, "That body part is bugged. It needs developer's attention." );
+- }
+-
+- continue;
+- }
+-
+ if( force || patient.get_part_hp_cur( bp ) < patient.get_part_hp_max( bp ) ) {
+ return healed_part;
+ }
+diff --git a/src/mutation.h b/src/mutation.h
+index 8e82983e2d7..8fe226d47b5 100644
+--- a/src/mutation.h
++++ b/src/mutation.h
+@@ -115,8 +115,10 @@ struct mutation_branch {
+ // Healing per turn
+ float healing_awake = 0.0f;
+ float healing_resting = 0.0f;
+- // Limb mending bonus
+- float mending_modifier = 1.0f;
++ // Multiplier on regen of broken limbs.
++ // Base regen of broken limbs is 25% and 25% the low cap.
++ // Capped at 1.0, which makes broken limbs regen at same rate as unbroken.
++ float mending_modifier = 0.0f;
+ // Bonus HP multiplier. That is, 1.0 doubles hp, -0.5 halves it.
+ float hp_modifier = 0.0f;
+ // Second HP modifier that stacks with first but is otherwise identical.
+diff --git a/src/mutation_data.cpp b/src/mutation_data.cpp
+index 9c95b97873e..a070de723d8 100644
+--- a/src/mutation_data.cpp
++++ b/src/mutation_data.cpp
+@@ -377,7 +377,7 @@ void mutation_branch::load( const JsonObject &jo, const std::string & )
+ optional( jo, was_loaded, "pain_recovery", pain_recovery, 0.0f );
+ optional( jo, was_loaded, "healing_awake", healing_awake, 0.0f );
+ optional( jo, was_loaded, "healing_resting", healing_resting, 0.0f );
+- optional( jo, was_loaded, "mending_modifier", mending_modifier, 1.0f );
++ optional( jo, was_loaded, "mending_modifier", mending_modifier, 0.0f );
+ optional( jo, was_loaded, "hp_modifier", hp_modifier, 0.0f );
+ optional( jo, was_loaded, "hp_modifier_secondary", hp_modifier_secondary, 0.0f );
+ optional( jo, was_loaded, "hp_adjustment", hp_adjustment, 0.0f );
+diff --git a/src/npc.cpp b/src/npc.cpp
+index 36b63dd2bb4..9c31869540d 100644
+--- a/src/npc.cpp
++++ b/src/npc.cpp
+@@ -84,7 +84,6 @@ static const efftype_id effect_contacts( "contacts" );
+ static const efftype_id effect_drunk( "drunk" );
+ static const efftype_id effect_feral_killed_recently( "feral_killed_recently" );
+ static const efftype_id effect_infection( "infection" );
+-static const efftype_id effect_mending( "mending" );
+ static const efftype_id effect_npc_flee_player( "npc_flee_player" );
+ static const efftype_id effect_npc_suspend( "npc_suspend" );
+ static const efftype_id effect_pkill_l( "pkill_l" );
+@@ -1073,7 +1072,8 @@ bool npc::wear_if_wanted( const item &it, std::string &reason )
+ for( int i = 0; i < num_hp_parts; i++ ) {
+ hp_part hpp = static_cast<hp_part>( i );
+ body_part bp = player::hp_to_bp( hpp );
+- if( is_limb_broken( convert_bp( bp ) ) && !has_effect( effect_mending, bp ) &&
++ if( is_limb_broken( convert_bp( bp ).id() ) &&
++ !worn_with_flag( flag_SPLINT, convert_bp( bp ).id() ) &&
+ it->covers( convert_bp( bp ).id() ) ) {
+ reason = _( "Thanks, I'll wear that now." );
+ return wear_item( std::move( it ), false );
+diff --git a/src/panels.cpp b/src/panels.cpp
+index 41983b82ae5..9c8ae1701bc 100644
+--- a/src/panels.cpp
++++ b/src/panels.cpp
+@@ -61,7 +61,6 @@
+ #include "vpart_position.h"
+ #include "weather.h"
+
+-static const trait_id trait_REGEN_LIZ( "REGEN_LIZ" );
+ static const trait_id trait_SELFAWARE( "SELFAWARE" );
+ static const trait_id trait_THRESH_FELINE( "THRESH_FELINE" );
+ static const trait_id trait_THRESH_BIRD( "THRESH_BIRD" );
+@@ -771,36 +770,36 @@ static void draw_limb_health( avatar &u, const catacurses::window &w, int limb_i
+ wprintz( w, color, sym );
+ }
+ };
++
+ const bodypart_id bp = convert_bp( avatar::hp_to_bp( static_cast<hp_part>( limb_index ) ) ).id();
++ const int hp_cur = u.get_part_hp_cur( bp );
++ const int hp_max = u.get_part_hp_max( bp );
++
++ std::optional<nc_color> color_override;
++
+ if( u.is_limb_broken( bp.id() ) && ( limb_index >= hp_arm_l &&
+ limb_index <= hp_leg_r ) ) {
+ //Limb is broken
+- std::string limb = "~~%~~";
+- nc_color color = c_light_red;
+-
+- if( u.worn_with_flag( json_flag_SPLINT, bp ) || u.has_trait( trait_REGEN_LIZ ) ) {
+- static const efftype_id effect_mending( "mending" );
+- const auto &eff = u.get_effect( effect_mending, bp->token );
+- const int mend_perc = eff.is_null() ? 0.0 : 100 * eff.get_duration() / eff.get_max_duration();
++ const int mend_perc = 100 * hp_cur / hp_max;
++ bool splinted = u.worn_with_flag( json_flag_SPLINT, bp ) ||
++ ( u.mutation_value( "mending_modifier" ) >= 1.0f );
++ nc_color color = splinted ? c_blue : c_dark_gray;
+
+- if( is_self_aware || u.has_effect( effect_got_checked ) ) {
+- limb = string_format( "=%2d%%=", mend_perc );
+- color = c_blue;
+- } else {
+- const int num = mend_perc / 20;
+- print_symbol_num( w, num, "#", c_blue );
+- print_symbol_num( w, 5 - num, "=", c_blue );
+- return;
+- }
++ if( is_self_aware || u.has_effect( effect_got_checked ) ) {
++ color_override = color;
++ } else {
++ const int num = mend_perc / 20;
++ print_symbol_num( w, num, "#", color );
++ print_symbol_num( w, 5 - num, "=", color );
++ return;
+ }
+-
+- wprintz( w, color, limb );
+- return;
+ }
+
+- const int hp_cur = u.get_part_hp_cur( bp );
+- const int hp_max = u.get_part_hp_max( bp );
++
+ std::pair<std::string, nc_color> hp = get_hp_bar( hp_cur, hp_max );
++ if( color_override ) {
++ hp.second = *color_override;
++ }
+
+ if( is_self_aware || u.has_effect( effect_got_checked ) ) {
+ wprintz( w, hp.second, "%3d ", hp_cur );
+diff --git a/src/player_hardcoded_effects.cpp b/src/player_hardcoded_effects.cpp
+index 2f74c64ccf4..88d7f83de8e 100644
+--- a/src/player_hardcoded_effects.cpp
++++ b/src/player_hardcoded_effects.cpp
+@@ -73,7 +73,6 @@ static const efftype_id effect_hallu( "hallu" );
+ static const efftype_id effect_hot( "hot" );
+ static const efftype_id effect_infected( "infected" );
+ static const efftype_id effect_lying_down( "lying_down" );
+-static const efftype_id effect_mending( "mending" );
+ static const efftype_id effect_mutating( "mutating" );
+ static const efftype_id effect_nausea( "nausea" );
+ static const efftype_id effect_narcosis( "narcosis" );
+@@ -1292,12 +1291,8 @@ void Character::hardcoded_effects( effect &it )
+ }
+ }
+ }
+- } else if( id == effect_mending ) {
+- if( !is_limb_broken( convert_bp( bp ) ) ) {
+- it.set_duration( 0_turns );
+- }
+ } else if( id == effect_disabled ) {
+- if( !is_limb_broken( convert_bp( bp ) ) ) {
++ if( get_part_hp_cur( convert_bp( bp ) ) >= get_part_hp_max( convert_bp( bp ) ) ) {
+ remove_effect( effect_disabled );
+ }
+ } else if( id == effect_panacea ) {
+diff --git a/src/suffer.cpp b/src/suffer.cpp
+index f752944f22b..acc6a8dc50e 100644
+--- a/src/suffer.cpp
++++ b/src/suffer.cpp
+@@ -95,7 +95,6 @@ static const efftype_id effect_glowy_led( "glowy_led" );
+ static const efftype_id effect_hallu( "hallu" );
+ static const efftype_id effect_iodine( "iodine" );
+ static const efftype_id effect_masked_scent( "masked_scent" );
+-static const efftype_id effect_mending( "mending" );
+ static const efftype_id effect_meth( "meth" );
+ static const efftype_id effect_narcosis( "narcosis" );
+ static const efftype_id effect_nausea( "nausea" );
+@@ -143,7 +142,6 @@ static const trait_id trait_RADIOACTIVE1( "RADIOACTIVE1" );
+ static const trait_id trait_RADIOACTIVE2( "RADIOACTIVE2" );
+ static const trait_id trait_RADIOACTIVE3( "RADIOACTIVE3" );
+ static const trait_id trait_RADIOGENIC( "RADIOGENIC" );
+-static const trait_id trait_REGEN_LIZ( "REGEN_LIZ" );
+ static const trait_id trait_ROOTS3( "ROOTS3" );
+ static const trait_id trait_SCHIZOPHRENIC( "SCHIZOPHRENIC" );
+ static const trait_id trait_SHARKTEETH( "SHARKTEETH" );
+@@ -174,16 +172,6 @@ static const std::string flag_RAD_RESIST( "RAD_RESIST" );
+ static const std::string flag_SPLINT( "SPLINT" );
+ static const std::string flag_SUN_GLASSES( "SUN_GLASSES" );
+
+-static float addiction_scaling( float at_min, float at_max, float add_lvl )
+-{
+- // Not addicted
+- if( add_lvl < MIN_ADDICTION_LEVEL ) {
+- return 1.0f;
+- }
+-
+- return lerp( at_min, at_max, ( add_lvl - MIN_ADDICTION_LEVEL ) / MAX_ADDICTION_LEVEL );
+-}
+-
+ void Character::suffer_water_damage( const mutation_branch &mdata )
+ {
+ for( const std::pair<const bodypart_str_id, bodypart> &elem : get_body() ) {
+@@ -1669,109 +1657,6 @@ bool Character::irradiate( float rads, bool bypass )
+ return false;
+ }
+
+-void Character::mend( int rate_multiplier )
+-{
+- // Wearing splints can slowly mend a broken limb back to 1 hp.
+- bool any_broken = false;
+- for( const bodypart_id &bp : get_all_body_parts() ) {
+- if( is_limb_broken( bp ) ) {
+- any_broken = true;
+- break;
+- }
+- }
+-
+- if( !any_broken ) {
+- return;
+- }
+-
+- double healing_factor = 1.0;
+- // Studies have shown that alcohol and tobacco use delay fracture healing time
+- // Being under effect is 50% slowdown
+- // Being addicted but not under effect scales from 25% slowdown to 75% slowdown
+- // The improvement from being intoxicated over withdrawal is intended
+- if( has_effect( effect_cig ) ) {
+- healing_factor *= 0.5;
+- } else {
+- healing_factor *= addiction_scaling( 0.25f, 0.75f, addiction_level( add_type::CIG ) );
+- }
+-
+- if( has_effect( effect_drunk ) ) {
+- healing_factor *= 0.5;
+- } else {
+- healing_factor *= addiction_scaling( 0.25f, 0.75f, addiction_level( add_type::ALCOHOL ) );
+- }
+-
+- if( get_rad() > 0 && !has_trait( trait_RADIOGENIC ) ) {
+- healing_factor *= clamp( ( 1000.0f - get_rad() ) / 1000.0f, 0.0f, 1.0f );
+- }
+-
+- // Bed rest speeds up mending
+- if( has_effect( effect_sleep ) ) {
+- healing_factor *= 4.0;
+- } else if( get_fatigue() > fatigue_levels::dead_tired ) {
+- // but being dead tired does not...
+- healing_factor *= 0.75;
+- } else {
+- // If not dead tired, resting without sleep also helps
+- healing_factor *= 1.0f + rest_quality();
+- }
+-
+- // Being healthy helps.
+- healing_factor *= 1.0f + get_healthy() / 200.0f;
+-
+- // Very hungry starts lowering the chance
+- // square rooting the value makes the numbers drop off faster when below 1
+- healing_factor *= std::sqrt( static_cast<float>( get_stored_kcal() ) / static_cast<float>
+- ( max_stored_kcal() ) );
+- // Similar for thirst - starts at very thirsty, drops to 0 at parched
+- healing_factor *= 1.0f - clamp( 1.0f * ( get_thirst() - thirst_levels::very_thirsty ) /
+- +thirst_levels::parched, 0.0f, 1.0f );
+-
+- // Mutagenic healing factor!
+- bool needs_splint = true;
+-
+- healing_factor *= mutation_value( "mending_modifier" );
+-
+- if( has_trait( trait_REGEN_LIZ ) ) {
+- needs_splint = false;
+- }
+-
+- add_msg( m_debug, "Limb mend healing factor: %.2f", healing_factor );
+- if( healing_factor <= 0.0f ) {
+- // The section below assumes positive healing rate
+- return;
+- }
+-
+- for( const bodypart_id &bp : get_all_body_parts() ) {
+- const bool broken = is_limb_broken( bp );
+- if( !broken ) {
+- continue;
+- }
+-
+- if( needs_splint && !worn_with_flag( flag_SPLINT, bp ) ) {
+- continue;
+- }
+-
+- const time_duration dur_inc = 1_turns * roll_remainder( rate_multiplier * healing_factor );
+- auto &eff = get_effect( effect_mending, bp->token );
+- if( eff.is_null() ) {
+- add_effect( effect_mending, dur_inc, bp->token );
+- continue;
+- }
+-
+- eff.set_duration( eff.get_duration() + dur_inc );
+-
+- if( eff.get_duration() >= eff.get_max_duration() ) {
+- set_part_hp_cur( bp, 1 );
+- remove_effect( effect_mending, bp->token );
+- g->events().send<event_type::broken_bone_mends>( getID(), bp->token );
+- //~ %s is bodypart
+- add_msg_if_player( m_good, _( "Your %s has started to mend!" ),
+- body_part_name( bp ) );
+- }
+- }
+-}
+-
+ void Character::sound_hallu()
+ {
+ // Random 'dangerous' sound from a random direction
+diff --git a/tests/player_helpers.cpp b/tests/player_helpers.cpp
+index fc95f1696d8..307b9a8834f 100644
+--- a/tests/player_helpers.cpp
++++ b/tests/player_helpers.cpp
+@@ -98,6 +98,9 @@ void clear_character( player &dummy, bool debug_storage )
+ dummy.set_stamina( dummy.get_stamina_max() );
+ dummy.set_movement_mode( CMM_WALK );
+
++ // Set HP to max here and also later, for disabled/broken limbs
++ dummy.set_all_parts_hp_to_max();
++
+ // Make sure we don't carry around weird effects.
+ dummy.clear_effects(); // mark effects for removal
+ dummy.process_effects(); // actually remove them
+--
+2.42.0
+
diff --git a/revert-19_Fix-Repair-Nanobots-3308.patch b/revert-19_Fix-Repair-Nanobots-3308.patch
new file mode 100644
index 0000000..040af83
--- /dev/null
+++ b/revert-19_Fix-Repair-Nanobots-3308.patch
@@ -0,0 +1,36 @@
+From 88924caafa4534a8c6a3d0f4bf84913a85ef3361 Mon Sep 17 00:00:00 2001
+From: KheirFerrum <102964889+KheirFerrum@users.noreply.github.com>
+Date: Fri, 29 Sep 2023 15:02:13 +0100
+Subject: [PATCH] Fix Repair Nanobots (#3308)
+
+* Add back code that marks limbs for healing.
+
+* style(autofix.ci): automated formatting
+
+---------
+
+Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
+---
+ src/bionics.cpp | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/src/bionics.cpp b/src/bionics.cpp
+index 6c7586bbfc1..1884f75e6f8 100644
+--- a/src/bionics.cpp
++++ b/src/bionics.cpp
+@@ -1673,6 +1673,12 @@ void Character::process_bionic( bionic &bio )
+ }
+ if( calendar::once_every( 2_minutes ) ) {
+ std::vector<bodypart_id> damaged_hp_parts;
++ for( const bodypart_id &bp : get_all_body_parts( true ) ) {
++ const int hp_cur = get_part_hp_cur( bp );
++ if( !is_limb_broken( bp ) && hp_cur < get_part_hp_max( bp ) ) {
++ damaged_hp_parts.push_back( bp );
++ }
++ }
+ if( !damaged_hp_parts.empty() ) {
+ // Essential parts are considered 10 HP lower than non-essential parts for the purpose of determining priority.
+ // I'd use the essential_value, but it's tied up in the heal_actor class of iuse_actor.
+--
+2.42.0
+
diff --git a/revert-20_Fix-tidy-warnings-3310.patch b/revert-20_Fix-tidy-warnings-3310.patch
new file mode 100644
index 0000000..e026533
--- /dev/null
+++ b/revert-20_Fix-tidy-warnings-3310.patch
@@ -0,0 +1,30 @@
+From 1fbcf35677e9cd33a9f6952fcd81c14cdf1b753d Mon Sep 17 00:00:00 2001
+From: Olanti <olanti-p@yandex.ru>
+Date: Sat, 30 Sep 2023 08:43:54 +0300
+Subject: [PATCH] Fix tidy warnings (#3310)
+
+---
+ src/suffer.cpp | 3 ---
+
+diff --git a/src/suffer.cpp b/src/suffer.cpp
+index 97786373598..390016d1aa5 100644
+--- a/src/suffer.cpp
++++ b/src/suffer.cpp
+@@ -82,13 +82,11 @@ static const efftype_id effect_asthma( "asthma" );
+ static const efftype_id effect_attention( "attention" );
+ static const efftype_id effect_bleed( "bleed" );
+ static const efftype_id effect_blind( "blind" );
+-static const efftype_id effect_cig( "cig" );
+ static const efftype_id effect_cough_aggravated_asthma( "cough_aggravated_asthma" );
+ static const efftype_id effect_datura( "datura" );
+ static const efftype_id effect_deaf( "deaf" );
+ static const efftype_id effect_disabled( "disabled" );
+ static const efftype_id effect_downed( "downed" );
+-static const efftype_id effect_drunk( "drunk" );
+ static const efftype_id effect_feral_killed_recently( "feral_killed_recently" );
+ static const efftype_id effect_formication( "formication" );
+ static const efftype_id effect_glowy_led( "glowy_led" );
+
+--
+2.42.0
+
diff --git a/revert-21_fix-Erased-the-npc-Alonso-from-history-the-game-3582.patch b/revert-21_fix-Erased-the-npc-Alonso-from-history-the-game-3582.patch
new file mode 100644
index 0000000..d8974c6
--- /dev/null
+++ b/revert-21_fix-Erased-the-npc-Alonso-from-history-the-game-3582.patch
@@ -0,0 +1,225 @@
+From d0bdffe94a1222aa26e9d6c2952e80f2b760278c Mon Sep 17 00:00:00 2001
+From: AniDemi <60388907+AniDemi@users.noreply.github.com>
+Date: Tue, 7 Nov 2023 02:03:29 +0100
+Subject: [PATCH 063/318] fix: Erased the npc Alonso from history (the game)
+ (#3582)
+
+* Rewrite the records, alonso never existed
+
+* Obsolete npc dialogue
+
+* style(autofix.ci): automated formatting
+
+---------
+
+Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
+---
+ .../mapgen/refugee_center/refugee_center.json | 1 -
+ .../surface_refugees/NPC_Jenny_Forcette.json | 4 +-
+ data/json/obsoletion/npc.json | 58 +++++++++++++++++++
+ .../npc_dialogue.json} | 58 -------------------
+ .../npc_dialogue.json} | 0
+ data/mods/DinoMod/snippets/grave_labels.json | 3 +-
+ data/mods/No_Hope/Mapgen/refugee_center.json | 1 -
+ 7 files changed, 61 insertions(+), 64 deletions(-)
+ rename data/json/{npcs/refugee_center/surface_refugees/NPC_Alonso_Lautrec.json => obsoletion/npc_dialogue.json} (78%)
+ rename data/mods/DinoMod/{NPC/NPC_Alonso_Lautrec.json => obsolete/npc_dialogue.json} (100%)
+
+diff --git a/data/json/mapgen/refugee_center/refugee_center.json b/data/json/mapgen/refugee_center/refugee_center.json
+index fbcc14991b9..ded6de4059c 100644
+--- a/data/json/mapgen/refugee_center/refugee_center.json
++++ b/data/json/mapgen/refugee_center/refugee_center.json
+@@ -137,7 +137,6 @@
+ { "class": "refugee_AleeshaSeward", "x": 35, "y": 7 },
+ { "class": "refugee_PabloNunez", "x": 35, "y": 12 },
+ { "class": "refugee_DanaNunez", "x": 35, "y": 13 },
+- { "class": "refugee_AlonsoLautrec", "x": 40, "y": 23 },
+ { "class": "refugee_MangalpreetSingh", "x": 40, "y": 5 },
+ { "class": "refugee_MandeepSingh", "x": 41, "y": 5 },
+ { "class": "refugee_GuneetSingh", "x": 43, "y": 4 },
+diff --git a/data/json/npcs/refugee_center/surface_refugees/NPC_Jenny_Forcette.json b/data/json/npcs/refugee_center/surface_refugees/NPC_Jenny_Forcette.json
+index 45ddbb7bbbf..cb5b65dd1ef 100644
+--- a/data/json/npcs/refugee_center/surface_refugees/NPC_Jenny_Forcette.json
++++ b/data/json/npcs/refugee_center/surface_refugees/NPC_Jenny_Forcette.json
+@@ -324,8 +324,8 @@
+ "id": "TALK_REFUGEE_JENNY_Refugees2_Others",
+ "dynamic_line": {
+ "days_since_cataclysm": 80,
+- "yes": "Vanessa… I'm doing my best, I really am, but we just do not get along. One of these days one of us is probably going to brain the other with a tire iron, and I'm just grateful I spend more time around the tire irons. Uyen and Rhyzaea are both excellent people, and I genuinely like them, but I can't stand this ongoing political bullshit they've got going on. Alonso is just a… he's… there's no polite word for what he is. A lot of the others are fine with it, and okay, sure, I guess. John is a walking stereotype, but he's a great poker buddy. I admit I kinda like him.",
+- "no": "Vanessa… well, she's nice, I guess. I gotta say, she kinda drives me nuts, but we're in this together so I try not to be too harsh. Uyen and Rhyzaea both seem to want to run the show here, but I try to stay out of those politics and just focus on building stuff. I don't see much good coming of it. Alonso is fine, he's clearly interested in me, and also in every other single person here. Not my thing, in a group this small. John is a walking stereotype, I imagine there must be more depth to him, but I haven't seen it yet."
++ "yes": "Vanessa… I'm doing my best, I really am, but we just do not get along. One of these days one of us is probably going to brain the other with a tire iron, and I'm just grateful I spend more time around the tire irons. Uyen and Rhyzaea are both excellent people, and I genuinely like them, but I can't stand this ongoing political bullshit they've got going on. John is a walking stereotype, but he's a great poker buddy. I admit I kinda like him.",
++ "no": "Vanessa… well, she's nice, I guess. I gotta say, she kinda drives me nuts, but we're in this together so I try not to be too harsh. Uyen and Rhyzaea both seem to want to run the show here, but I try to stay out of those politics and just focus on building stuff. I don't see much good coming of it. John is a walking stereotype, I imagine there must be more depth to him, but I haven't seen it yet."
+ },
+ "responses": [
+ { "text": "What was it you said earlier?", "topic": "TALK_NONE" },
+diff --git a/data/json/obsoletion/npc.json b/data/json/obsoletion/npc.json
+index 7f067301878..b8560dd46fc 100644
+--- a/data/json/obsoletion/npc.json
++++ b/data/json/obsoletion/npc.json
+@@ -78,5 +78,63 @@
+ { "item": "5x50_100_mag", "count": 2, "charges": 100, "ammo-item": "5x50heavy" },
+ { "item": "5x50heavy", "count": 8 }
+ ]
++ },
++ {
++ "type": "npc",
++ "id": "refugee_AlonsoLautrec",
++ "name_unique": "Alonso Lautrec",
++ "gender": "male",
++ "name_suffix": "refugee",
++ "class": "NC_REFUGEE_Alonso",
++ "attitude": 0,
++ "mission": 7,
++ "chat": "TALK_DONE",
++ "faction": "free_merchants"
++ },
++ {
++ "type": "npc_class",
++ "id": "NC_REFUGEE_Alonso",
++ "name": { "str": "Refugee" },
++ "job_description": "I'm just trying to survive.",
++ "common": false,
++ "//": "Alonso wants to be the town bicycle, but isn't getting as much interest as he'd hoped. He'll trade a morale bonus for condoms.",
++ "bonus_str": { "rng": [ -2, 1 ] },
++ "bonus_dex": { "rng": [ -2, 4 ] },
++ "bonus_int": { "rng": [ -2, 2 ] },
++ "bonus_per": { "rng": [ -2, 2 ] },
++ "worn_override": "REFUGEE_Alonso_worn",
++ "carry_override": "REFUGEE_Alonso_carried",
++ "weapon_override": "REFUGEE_Alonso_wield",
++ "traits": [ { "trait": "PRETTY" }, { "group": "Appearance_demographics" } ],
++ "skills": [
++ { "skill": "ALL", "level": { "mul": [ { "one_in": 3 }, { "sum": [ { "dice": [ 2, 2 ] }, { "rng": [ 0, -5 ] } ] } ] } },
++ { "skill": "barter", "bonus": { "rng": [ 0, 1 ] } }
++ ]
++ },
++ {
++ "type": "item_group",
++ "id": "REFUGEE_Alonso_worn",
++ "subtype": "collection",
++ "entries": [
++ { "item": "boxer_briefs" },
++ { "item": "socks" },
++ { "item": "tshirt" },
++ { "item": "pants_leather" },
++ { "item": "jacket_leather" },
++ { "item": "fancy_sunglasses" },
++ { "item": "dress_shoes" }
++ ]
++ },
++ {
++ "type": "item_group",
++ "id": "REFUGEE_Alonso_carried",
++ "subtype": "collection",
++ "entries": [ { "item": "mag_porn" }, { "item": "vibrator" }, { "item": "condom" } ]
++ },
++ {
++ "type": "item_group",
++ "id": "REFUGEE_Alonso_wield",
++ "subtype": "collection",
++ "entries": [ { "item": "cudgel" } ]
+ }
+ ]
+diff --git a/data/json/npcs/refugee_center/surface_refugees/NPC_Alonso_Lautrec.json b/data/json/obsoletion/npc_dialogue.json
+similarity index 78%
+rename from data/json/npcs/refugee_center/surface_refugees/NPC_Alonso_Lautrec.json
+rename to data/json/obsoletion/npc_dialogue.json
+index 136c879b117..459467b71a9 100644
+--- a/data/json/npcs/refugee_center/surface_refugees/NPC_Alonso_Lautrec.json
++++ b/data/json/obsoletion/npc_dialogue.json
+@@ -1,62 +1,4 @@
+ [
+- {
+- "type": "npc",
+- "id": "refugee_AlonsoLautrec",
+- "name_unique": "Alonso Lautrec",
+- "gender": "male",
+- "name_suffix": "refugee",
+- "class": "NC_REFUGEE_Alonso",
+- "attitude": 0,
+- "mission": 7,
+- "chat": "TALK_REFUGEE_Alonso_1",
+- "faction": "free_merchants"
+- },
+- {
+- "type": "npc_class",
+- "id": "NC_REFUGEE_Alonso",
+- "name": { "str": "Refugee" },
+- "job_description": "I'm just trying to survive.",
+- "common": false,
+- "//": "Alonso wants to be the town bicycle, but isn't getting as much interest as he'd hoped. He'll trade a morale bonus for condoms.",
+- "bonus_str": { "rng": [ -2, 1 ] },
+- "bonus_dex": { "rng": [ -2, 4 ] },
+- "bonus_int": { "rng": [ -2, 2 ] },
+- "bonus_per": { "rng": [ -2, 2 ] },
+- "worn_override": "REFUGEE_Alonso_worn",
+- "carry_override": "REFUGEE_Alonso_carried",
+- "weapon_override": "REFUGEE_Alonso_wield",
+- "traits": [ { "trait": "PRETTY" }, { "group": "Appearance_demographics" } ],
+- "skills": [
+- { "skill": "ALL", "level": { "mul": [ { "one_in": 3 }, { "sum": [ { "dice": [ 2, 2 ] }, { "rng": [ 0, -5 ] } ] } ] } },
+- { "skill": "barter", "bonus": { "rng": [ 0, 1 ] } }
+- ]
+- },
+- {
+- "type": "item_group",
+- "id": "REFUGEE_Alonso_worn",
+- "subtype": "collection",
+- "entries": [
+- { "item": "boxer_briefs" },
+- { "item": "socks" },
+- { "item": "tshirt" },
+- { "item": "pants_leather" },
+- { "item": "jacket_leather" },
+- { "item": "fancy_sunglasses" },
+- { "item": "dress_shoes" }
+- ]
+- },
+- {
+- "type": "item_group",
+- "id": "REFUGEE_Alonso_carried",
+- "subtype": "collection",
+- "entries": [ { "item": "mag_porn" }, { "item": "vibrator" }, { "item": "condom" } ]
+- },
+- {
+- "type": "item_group",
+- "id": "REFUGEE_Alonso_wield",
+- "subtype": "collection",
+- "entries": [ { "item": "cudgel" } ]
+- },
+ {
+ "type": "talk_topic",
+ "//": "common talk responses",
+diff --git a/data/mods/DinoMod/NPC/NPC_Alonso_Lautrec.json b/data/mods/DinoMod/obsolete/npc_dialogue.json
+similarity index 100%
+rename from data/mods/DinoMod/NPC/NPC_Alonso_Lautrec.json
+rename to data/mods/DinoMod/obsolete/npc_dialogue.json
+diff --git a/data/mods/DinoMod/snippets/grave_labels.json b/data/mods/DinoMod/snippets/grave_labels.json
+index 72fdc095b39..c40d3bdb567 100644
+--- a/data/mods/DinoMod/snippets/grave_labels.json
++++ b/data/mods/DinoMod/snippets/grave_labels.json
+@@ -14,8 +14,7 @@
+ "Life did not find a way.",
+ "The greatest dinosaur expert of our times. Crushed to death by an apatosaurus.",
+ "Fool hid in a cardboard box from a deinonychus, shouting Dino Dave! Didn't work.",
+- "Here lies a dinosaur, don't know what kind. Hated shovels.",
+- "Alonso did not know her, but she was beautiful and majestic and she deserved the proper burial. Alonso will remember this dinosaur for some of the time."
++ "Here lies a dinosaur, don't know what kind. Hated shovels."
+ ]
+ }
+ ]
+diff --git a/data/mods/No_Hope/Mapgen/refugee_center.json b/data/mods/No_Hope/Mapgen/refugee_center.json
+index 30f4a0e7374..d848a2ef941 100644
+--- a/data/mods/No_Hope/Mapgen/refugee_center.json
++++ b/data/mods/No_Hope/Mapgen/refugee_center.json
+@@ -137,7 +137,6 @@
+ { "class": "refugee_AleeshaSeward", "x": 35, "y": 7 },
+ { "class": "refugee_PabloNunez", "x": 35, "y": 12 },
+ { "class": "refugee_DanaNunez", "x": 35, "y": 13 },
+- { "class": "refugee_AlonsoLautrec", "x": 40, "y": 23 },
+ { "class": "refugee_MangalpreetSingh", "x": 40, "y": 5 },
+ { "class": "refugee_MandeepSingh", "x": 41, "y": 5 },
+ { "class": "refugee_GuneetSingh", "x": 43, "y": 4 },
+--
+2.42.0
+
diff --git a/revert-22_feat-content-Biodiesel-Fuel-for-Gasoline-Engines-371.patch b/revert-22_feat-content-Biodiesel-Fuel-for-Gasoline-Engines-371.patch
new file mode 100644
index 0000000..9a0d32b
--- /dev/null
+++ b/revert-22_feat-content-Biodiesel-Fuel-for-Gasoline-Engines-371.patch
@@ -0,0 +1,39 @@
+From 1de404eef929a870584e71ea7cc8cf7c50a05963 Mon Sep 17 00:00:00 2001
+From: Chorus System <ohinchy@gmail.com>
+Date: Sat, 18 Nov 2023 19:06:26 -0500
+Subject: [PATCH 139/318] feat(content): Biodiesel Fuel for Gasoline Engines
+ (#3716)
+
+* Added alcohol fuels to engine
+
+Made gasoline and JP8 engines capable of using ethanol, methanol, and denatured alcohol as fuel.
+
+* style(autofix.ci): automated formatting
+
+* Replace ethanol with biodiesel
+
+* style(autofix.ci): automated formatting
+
+---------
+
+Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
+---
+ data/json/vehicleparts/combustion.json | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/data/json/vehicleparts/combustion.json b/data/json/vehicleparts/combustion.json
+index 2ecedc733b5..8d2d492f47c 100644
+--- a/data/json/vehicleparts/combustion.json
++++ b/data/json/vehicleparts/combustion.json
+@@ -31,7 +31,7 @@
+ "copy-from": "engine_combustion",
+ "type": "vehicle_part",
+ "fuel_type": "gasoline",
+- "fuel_options": [ "gasoline", "avgas", "chem_ethanol" ],
++ "fuel_options": [ "gasoline", "avgas", "biodiesel" ],
+ "//2": "TODO: remove when injectors are implemented",
+ "m2c": 60,
+ "//": "30% energy efficiency",
+--
+2.42.0
+
diff --git a/revert-23_fix-balance-no-more-EXP-gain-when-a-skill-is-maxed-o.patch b/revert-23_fix-balance-no-more-EXP-gain-when-a-skill-is-maxed-o.patch
new file mode 100644
index 0000000..b40bc5e
--- /dev/null
+++ b/revert-23_fix-balance-no-more-EXP-gain-when-a-skill-is-maxed-o.patch
@@ -0,0 +1,48 @@
+From d437a5a6e57cb27bca6685cd88186fd97c372ef8 Mon Sep 17 00:00:00 2001
+From: Chaosvolt <chaosvolt@users.noreply.github.com>
+Date: Thu, 23 Nov 2023 16:31:11 -0600
+Subject: [PATCH 154/318] fix(balance): no more EXP gain when a skill is maxed
+ out (#3720)
+
+---
+ src/character.cpp | 2 +-
+ src/skill.cpp | 3 ++-
+ 2 files changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/src/character.cpp b/src/character.cpp
+index 6d8d9335c9c..707cce4f12d 100644
+--- a/src/character.cpp
++++ b/src/character.cpp
+@@ -3920,7 +3920,7 @@ void Character::practice( const skill_id &id, int amount, int cap, bool suppress
+
+ if( !level.can_train() && !in_sleep_state() ) {
+ // If leveling is disabled, don't train, don't drain focus, don't print anything
+- // Leaving as a skill method rather than global for possible future skill cap setting
++ // This also checks if your skill level is maxed out at the cap of 10.
+ return;
+ }
+
+diff --git a/src/skill.cpp b/src/skill.cpp
+index 8964c80487f..5404cb204b1 100644
+--- a/src/skill.cpp
++++ b/src/skill.cpp
+@@ -9,6 +9,7 @@
+
+ #include "cata_utility.h"
+ #include "debug.h"
++#include "game_constants.h"
+ #include "item.h"
+ #include "json.h"
+ #include "options.h"
+@@ -310,7 +311,7 @@ void SkillLevel::readBook( int minimumGain, int maximumGain, int maximumLevel )
+
+ bool SkillLevel::can_train() const
+ {
+- return get_option<float>( "SKILL_TRAINING_SPEED" ) > 0.0;
++ return ( get_option<float>( "SKILL_TRAINING_SPEED" ) > 0.0 && _level < MAX_SKILL );
+ }
+
+ const SkillLevel &SkillLevelMap::get_skill_level_object( const skill_id &ident ) const
+--
+2.42.0
+
diff --git a/revert-24_fix-repair-nanobots-not-working-at-all-on-broken-lim.patch b/revert-24_fix-repair-nanobots-not-working-at-all-on-broken-lim.patch
new file mode 100644
index 0000000..c1de272
--- /dev/null
+++ b/revert-24_fix-repair-nanobots-not-working-at-all-on-broken-lim.patch
@@ -0,0 +1,214 @@
+From 5da2793a2a464a997b19c9b156cdb6baaaacb081 Mon Sep 17 00:00:00 2001
+From: scarf <greenscarf005@gmail.com>
+Date: Wed, 6 Dec 2023 11:35:40 +0900
+Subject: [PATCH 213/318] fix: repair nanobots not working at all on broken
+ limbs (#3787)
+
+fix: make nanobot work regardless of splint
+---
+ data/json/bionics.json | 2 +-
+ data/json/items/bionics.json | 2 +-
+ src/bionics.cpp | 47 ++++++++++++++++++++----------------
+ src/character.cpp | 11 +++------
+ src/regen.cpp | 35 +++++++++++++++++++++++++++
+ src/regen.h | 18 ++++++++++++++
+ 6 files changed, 85 insertions(+), 30 deletions(-)
+ create mode 100644 src/regen.cpp
+ create mode 100644 src/regen.h
+
+diff --git a/data/json/bionics.json b/data/json/bionics.json
+index 2e4b121ce7f..824be5bad23 100644
+--- a/data/json/bionics.json
++++ b/data/json/bionics.json
+@@ -661,7 +661,7 @@
+ "id": "bio_nanobots",
+ "type": "bionic",
+ "name": { "str": "Repair Nanobots" },
+- "description": "Inside your body is a fleet of tiny dormant robots. While activated they will reduce the intensity of one bleed effect every 30 seconds, and heal all injured body parts by 1 HP (or broken limbs by 1%) every 2 minutes if you have 3 kJ bionic power and 5 kcal per body part. Broken limbs must still be splinted (unless you have specific mutations) to benefit. If you don't have enough, they will prioritize based on the resources you have.",
++ "description": "Inside your body is a fleet of tiny dormant robots. While activated they will reduce the intensity of one bleed effect every 30 seconds, and heal all injured body parts by 1 HP (or broken limbs by 1%) every 2 minutes if you have 3 kJ bionic power and 5 kcal per body part. If you don't have enough, they will prioritize based on the resources you have.",
+ "occupied_bodyparts": [ [ "torso", 10 ] ],
+ "flags": [ "BIONIC_TOGGLED", "BIONIC_NPC_USABLE", "BIONIC_SLEEP_FRIENDLY" ],
+ "act_cost": "300 J",
+diff --git a/data/json/items/bionics.json b/data/json/items/bionics.json
+index 8e06717899b..5a5c9e5a037 100644
+--- a/data/json/items/bionics.json
++++ b/data/json/items/bionics.json
+@@ -610,7 +610,7 @@
+ "type": "BIONIC_ITEM",
+ "name": { "str": "Repair Nanobots CBM" },
+ "looks_like": "bio_int_enhancer",
+- "description": "A fleet of tiny dormant robots. While activated they will reduce the intensity of one bleed effect every 30 seconds, and heal all injured body parts by 1 HP (or broken limbs by 1%) every 2 minutes if you have 3 kJ bionic power and 5 kcal per body part. Broken limbs must still be splinted (unless you have specific mutations) to benefit. If you don't have enough, they will prioritize based on the resources you have.",
++ "description": "A fleet of tiny dormant robots. While activated they will reduce the intensity of one bleed effect every 30 seconds, and heal all injured body parts by 1 HP (or broken limbs by 1%) every 2 minutes if you have 3 kJ bionic power and 5 kcal per body part. If you don't have enough, they will prioritize based on the resources you have.",
+ "price": "9500 USD",
+ "weight": "200 g",
+ "difficulty": 6
+diff --git a/src/bionics.cpp b/src/bionics.cpp
+index 63d72584731..28e79490d37 100644
+--- a/src/bionics.cpp
++++ b/src/bionics.cpp
+@@ -68,6 +68,7 @@
+ #include "point.h"
+ #include "projectile.h"
+ #include "requirements.h"
++#include "regen.h"
+ #include "rng.h"
+ #include "sounds.h"
+ #include "string_formatter.h"
+@@ -1662,28 +1663,32 @@ void Character::process_bionic( bionic &bio )
+ }
+ }
+ if( calendar::once_every( 2_minutes ) ) {
+- std::vector<bodypart_id> damaged_hp_parts;
+- for( const bodypart_id &bp : get_all_body_parts( true ) ) {
+- const int hp_cur = get_part_hp_cur( bp );
+- if( !is_limb_broken( bp ) && hp_cur < get_part_hp_max( bp ) ) {
+- damaged_hp_parts.push_back( bp );
+- }
+- }
+- if( !damaged_hp_parts.empty() ) {
+- // Essential parts are considered 10 HP lower than non-essential parts for the purpose of determining priority.
+- // I'd use the essential_value, but it's tied up in the heal_actor class of iuse_actor.
+- std::sort( damaged_hp_parts.begin(), damaged_hp_parts.end(),
+- [this]( const bodypart_id & a, const bodypart_id & b ) {
+- return ( get_part_hp_cur( a ) - a->essential * 10 ) < ( get_part_hp_cur( b ) - b->essential * 10 );
+- } );
+- for( bodypart_id &bpid : damaged_hp_parts ) {
+- if( !can_use_bionic() ) {
+- return;
+- }
+- heal( bpid, 1 );
+- mod_power_level( -bio.info().power_trigger );
+- mod_stored_kcal( -bio.info().kcal_trigger );
++ // Essential parts are considered 10 HP lower than non-essential parts for the purpose of determining priority.
++ // I'd use the essential_value, but it's tied up in the heal_actor class of iuse_actor.
++ const auto effective_hp = [this]( const bodypart_id & bp ) -> int {
++ return get_part_hp_cur( bp ) - bp->essential * 10;
++ };
++ const auto should_heal = [this]( const bodypart_id & bp ) -> bool {
++ return get_part_hp_cur( bp ) < get_part_hp_max( bp );
++ };
++ const auto sort_by = [effective_hp]( const bodypart_id & a, const bodypart_id & b ) -> bool {
++ return effective_hp( a ) < effective_hp( b );
++ };
++ const auto damaged_parts = [this, should_heal, sort_by]() {
++ const auto xs = get_all_body_parts( true );
++ auto ys = std::vector<bodypart_id> {};
++ std::copy_if( xs.begin(), xs.end(), std::back_inserter( ys ), should_heal );
++ std::sort( ys.begin(), ys.end(), sort_by );
++ return ys;
++ };
++
++ for( bodypart_id &bp : damaged_parts() ) {
++ if( !can_use_bionic() ) {
++ return;
+ }
++ heal_adjusted( *this, bp, 1 );
++ mod_power_level( -bio.info().power_trigger );
++ mod_stored_kcal( -bio.info().kcal_trigger );
+ }
+ }
+ }
+diff --git a/src/character.cpp b/src/character.cpp
+index 9b6c15ce40c..25be749aa56 100644
+--- a/src/character.cpp
++++ b/src/character.cpp
+@@ -1,5 +1,4 @@
+ #include "character.h"
+-#include "bodypart.h"
+ #include "character_encumbrance.h"
+
+ #include <algorithm>
+@@ -82,6 +81,7 @@
+ #include "profession.h"
+ #include "recipe_dictionary.h"
+ #include "ret_val.h"
++#include "regen.h"
+ #include "rng.h"
+ #include "scent_map.h"
+ #include "skill.h"
+@@ -5068,14 +5068,11 @@ void Character::regen( int rate_multiplier )
+ float heal_rate = healing_rate( rest ) * to_turns<int>( 5_minutes );
+ const float broken_regen_mod = clamp( mutation_value( "mending_modifier" ), 0.25f, 1.0f );
+ if( heal_rate > 0.0f ) {
+- const int base_heal = roll_remainder( rate_multiplier * heal_rate );
+- const int broken_heal = roll_remainder( base_heal * broken_regen_mod );
++ const int heal = roll_remainder( rate_multiplier * heal_rate );
+
+ for( const bodypart_id &bp : get_all_body_parts() ) {
+- const bool is_broken = is_limb_broken( bp ) &&
+- !worn_with_flag( flag_SPLINT, bp );
+- heal( bp, is_broken ? broken_heal : base_heal );
+- mod_part_healed_total( bp, is_broken ? broken_heal : base_heal );
++ const int actually_healed = heal_adjusted( *this, bp, heal );
++ mod_part_healed_total( bp, actually_healed );
+ }
+ } else if( heal_rate < 0.0f ) {
+ int rot_rate = roll_remainder( rate_multiplier * -heal_rate );
+diff --git a/src/regen.cpp b/src/regen.cpp
+new file mode 100644
+index 00000000000..f8446c4243d
+--- /dev/null
++++ b/src/regen.cpp
+@@ -0,0 +1,35 @@
++#include "regen.h"
++#include "character.h"
++#include "rng.h"
++
++const flag_id flag_SPLINT( "SPLINT" );
++
++namespace
++{
++
++/// Limb is broken without splint
++auto has_broken_limb_penalty( const Character &c, const bodypart_id &bp ) -> bool
++{
++ return c.is_limb_broken( bp )
++ && !c.worn_with_flag( flag_SPLINT, bp );
++}
++
++/// Broken limbs without splint heal slower up to 25%
++auto mending_modifier( const Character &c ) -> float
++{
++ return clamp( c.mutation_value( "mending_modifier" ), 0.25f, 1.0f );
++}
++
++} // namespace
++
++auto heal_adjusted( Character &c, const bodypart_id &bp, const int heal ) -> int
++{
++ const float broken_regen_mod = mending_modifier( c );
++ const int broken_heal = roll_remainder( heal * broken_regen_mod );
++ const bool is_broken = has_broken_limb_penalty( c, bp );
++ const int actual_heal = is_broken ? broken_heal : heal;
++
++ c.heal( bp, actual_heal );
++
++ return actual_heal;
++}
+diff --git a/src/regen.h b/src/regen.h
+new file mode 100644
+index 00000000000..671a8a0e75d
+--- /dev/null
++++ b/src/regen.h
+@@ -0,0 +1,18 @@
++#pragma once
++#ifndef CATA_SRC_REGEN_H
++#define CATA_SRC_REGEN_H
++
++#include "type_id.h"
++
++class Character;
++
++/// like heal, but actually takes account of
++/// - whether limb suffers from being broken without splint
++/// - `mending_modifier`
++///
++/// @return actually healed amount. used for `mod_part_healed_total`
++///
++/// TODO: merge into `Character::heal`?
++auto heal_adjusted( Character &c, const bodypart_id &bp, const int heal ) -> int;
++
++#endif // CATA_SRC_REGEN_H
+--
+2.42.0
+
diff --git a/revert-26_fix-npc-splints-and-clean-up-iterator-errors-3592.patch b/revert-26_fix-npc-splints-and-clean-up-iterator-errors-3592.patch
new file mode 100644
index 0000000..f302dc8
--- /dev/null
+++ b/revert-26_fix-npc-splints-and-clean-up-iterator-errors-3592.patch
@@ -0,0 +1,67 @@
+From 17831b78d407a5abfc9389b35202b807ce5df8c4 Mon Sep 17 00:00:00 2001
+From: joveeater <joveasarus@gmail.com>
+Date: Wed, 8 Nov 2023 00:18:59 +0000
+Subject: [PATCH 065/318] fix: npc splints and clean up iterator errors (#3592)
+
+* Fix splints and clean up iterator errors
+
+* style(autofix.ci): automated formatting
+
+---------
+
+Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
+---
+ src/item.cpp | 1 +
+ src/npcmove.cpp | 13 ++++++++++++-
+ 3 files changed, 13 insertions(+), 8 deletions(-)
+
+diff --git a/src/item.cpp b/src/item.cpp
+index 3674560e548..d772312c36a 100644
+--- a/src/item.cpp
++++ b/src/item.cpp
+@@ -483,6 +483,7 @@ item &item::operator=( const item &source )
+ invlet = source.invlet;
+ active = source.active;
+ activated_by = source.activated_by;
++ is_favorite = source.is_favorite;
+
+ contents.clear_items();
+
+diff --git a/src/npcmove.cpp b/src/npcmove.cpp
+index c3470703e8a..3a0cd430288 100644
+--- a/src/npcmove.cpp
++++ b/src/npcmove.cpp
+@@ -4736,6 +4736,7 @@ bool npc::adjust_worn()
+ return false;
+ };
+
++ item *splint = nullptr;
+ for( auto &elem : worn ) {
+ if( !elem->has_flag( flag_SPLINT ) ) {
+ continue;
+@@ -4744,11 +4745,21 @@ bool npc::adjust_worn()
+ if( !covers_broken( *elem, elem->get_side() ) ) {
+ const bool needs_change = covers_broken( *elem, opposite_side( elem->get_side() ) );
+ // Try to change side (if it makes sense), or take off.
+- if( ( needs_change && change_side( *elem ) ) || takeoff( *elem ) ) {
++ if( needs_change && change_side( *elem ) ) {
+ return true;
+ }
++
++ if( can_takeoff( *elem ).success() ) {
++ splint = elem;
++ break;
++ }
++
+ }
+ }
++ if( splint ) {
++ takeoff( *splint );
++ return true;
++ }
+
+ return false;
+ }
+--
+2.42.0
+
diff --git a/revert-27_fix-NPCs-keep-their-splints-on-3589.patch b/revert-27_fix-NPCs-keep-their-splints-on-3589.patch
new file mode 100644
index 0000000..3bf0731
--- /dev/null
+++ b/revert-27_fix-NPCs-keep-their-splints-on-3589.patch
@@ -0,0 +1,30 @@
+From a3aaf76f252bc45f1e3b4da3fbf43e9208aefcb6 Mon Sep 17 00:00:00 2001
+From: KheirFerrum <102964889+KheirFerrum@users.noreply.github.com>
+Date: Wed, 8 Nov 2023 00:19:01 +0000
+Subject: [PATCH 066/318] fix: NPCs keep their splints on (#3589)
+
+* Use is_limb_broken like a normal function.
+
+* Update npcmove.cpp
+---
+ src/npcmove.cpp | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/src/npcmove.cpp b/src/npcmove.cpp
+index 3a0cd430288..2db92b4c253 100644
+--- a/src/npcmove.cpp
++++ b/src/npcmove.cpp
+@@ -4728,8 +4728,8 @@ bool npc::adjust_worn()
+ }
+ const auto covers_broken = [this]( const item & it, side s ) {
+ const body_part_set covered = it.get_covered_body_parts( s );
+- for( const std::pair<const bodypart_str_id, bodypart> &elem : get_body() ) {
+- if( elem.second.get_hp_cur() <= 0 && covered.test( elem.first ) ) {
++ for( const bodypart_str_id &bp_id : covered ) {
++ if( is_limb_broken( bp_id ) && covered.test( bp_id ) ) {
+ return true;
+ }
+ }
+--
+2.42.0
+
diff --git a/revert-28_feat-content-semi-plausible-smokeless-gunpowder-reci.patch b/revert-28_feat-content-semi-plausible-smokeless-gunpowder-reci.patch
new file mode 100644
index 0000000..f0e3aa0
--- /dev/null
+++ b/revert-28_feat-content-semi-plausible-smokeless-gunpowder-reci.patch
@@ -0,0 +1,62 @@
+From 49e4e2b3257d90ffc66b4e8fa2e7666b1440b751 Mon Sep 17 00:00:00 2001
+From: YeOldeMiller <36291373+YeOldeMiller@users.noreply.github.com>
+Date: Thu, 26 Oct 2023 03:22:35 +0300
+Subject: [PATCH 015/318] feat(content): semi-plausible smokeless gunpowder
+ recipe (#3503)
+
+* Introduce a semi-plausible smokeless gunpowder recipe
+
+* style(autofix.ci): automated formatting
+
+* Define id_suffix for gunpowder recipe, add ether to components
+
+* Remove obsolete gunpowder recipe from Craftable Gun Pack mod
+
+* Revert "Define id_suffix for gunpowder recipe"
+
+* Reapply ether addition for gunpowder recipe
+
+---------
+
+Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
+---
+ data/json/recipes/ammo/components.json | 23 ++++++++++++++++++++++
+ 2 files changed, 23 insertions(+), 21 deletions(-)
+
+diff --git a/data/json/recipes/ammo/components.json b/data/json/recipes/ammo/components.json
+index 3a29dfb5156..7610be60b25 100644
+--- a/data/json/recipes/ammo/components.json
++++ b/data/json/recipes/ammo/components.json
+@@ -44,6 +44,29 @@
+ "tools": [ [ [ "hotplate", 5 ], [ "toolset", 5 ] ] ],
+ "components": [ [ [ "oxy_powder", 5 ] ], [ [ "lye_powder", 5 ] ], [ [ "charcoal", 1 ], [ "coal_lump", 1 ] ] ]
+ },
++ {
++ "type": "recipe",
++ "result": "gunpowder",
++ "category": "CC_AMMO",
++ "subcategory": "CSC_AMMO_COMPONENTS",
++ "skill_used": "cooking",
++ "skills_required": [ "fabrication", 6 ],
++ "difficulty": 8,
++ "time": "2 h 40 m",
++ "charges": 200,
++ "book_learn": [ [ "textbook_anarch", 7 ], [ "adv_chemistry", 8 ], [ "textbook_chemistry", 8 ] ],
++ "batch_time_factors": [ 50, 3 ],
++ "qualities": [ { "id": "CHEM", "level": 3 } ],
++ "tools": [ [ [ "surface_heat", 250, "LIST" ] ], [ [ "pastaextruder", -1 ] ] ],
++ "components": [
++ [ [ "cotton_ball", 5 ] ],
++ [ [ "chem_nitric_acid", 3 ] ],
++ [ [ "acid", 3 ], [ "chem_sulphuric_acid", 2 ] ],
++ [ [ "ether", 125 ] ],
++ [ [ "water", 9 ], [ "water_clean", 9 ] ],
++ [ [ "edible_tallow_lard", 2, "LIST" ], [ "tallow_tainted", 2 ], [ "cooking_oil", 16 ], [ "cooking_oil2", 16 ] ]
++ ]
++ },
+ {
+ "type": "recipe",
+ "result": "exploding_arrow_warhead",
+--
+2.42.0
+
diff --git a/revert-30_feat-content-weapon-mount-obsoletion-part-1-4179.patch b/revert-30_feat-content-weapon-mount-obsoletion-part-1-4179.patch
new file mode 100644
index 0000000..fdc3225
--- /dev/null
+++ b/revert-30_feat-content-weapon-mount-obsoletion-part-1-4179.patch
@@ -0,0 +1,1957 @@
+From 0aca66e98ed0dc699179a24760160768146e2304 Mon Sep 17 00:00:00 2001
+From: Chorus System <ohinchy@gmail.com>
+Date: Mon, 5 Feb 2024 11:32:43 -0500
+Subject: [PATCH 094/231] feat(content): weapon mount obsoletion, part 1
+ (#4179)
+
+* Mount-ed Combat
+
+Removed all basegame weapon mount mod slots, replacing them with the corresponding mod slots of that type.
+
+* Mod mounts
+
+Removed weapon mount mod locations from modded weapons, replacing them with corresponding weapon mod locations.
+
+* style(autofix.ci): automated formatting
+
+* Obsoleted mount weapon mods
+
+* Changed ranged burst balance test
+
+Modified ranged burst balance test via RoyalFox's recommendation.
+
+---------
+
+Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
+Co-authored-by: Chaosvolt <chaosvolt@users.noreply.github.com>
+---
+ data/json/items/classes/gun.json | 65 +++----
+ data/json/items/classes/range.json | 2 +-
+ data/json/items/gun/20x66mm.json | 2 +-
+ data/json/items/gun/22.json | 6 +-
+ data/json/items/gun/223.json | 18 +-
+ data/json/items/gun/3006.json | 6 +-
+ data/json/items/gun/308.json | 16 +-
+ data/json/items/gun/38.json | 19 +-
+ data/json/items/gun/40.json | 2 +-
+ data/json/items/gun/40x46mm.json | 20 +-
+ data/json/items/gun/40x53mm.json | 4 +-
+ data/json/items/gun/410shot.json | 10 +-
+ data/json/items/gun/44.json | 4 +-
+ data/json/items/gun/44paper.json | 4 +-
+ data/json/items/gun/454.json | 4 +-
+ data/json/items/gun/4570.json | 16 +-
+ data/json/items/gun/45colt.json | 6 +-
+ data/json/items/gun/50.json | 8 +-
+ data/json/items/gun/500.json | 8 +-
+ data/json/items/gun/66mm.json | 9 +-
+ data/json/items/gun/762.json | 20 +-
+ data/json/items/gun/762x25.json | 2 +-
+ data/json/items/gun/84x246mm.json | 4 +-
+ data/json/items/gun/9mm.json | 28 +--
+ data/json/items/gun/atgm.json | 2 +-
+ data/json/items/gun/blunderbuss.json | 9 +-
+ data/json/items/gun/combination.json | 2 +-
+ data/json/items/gun/flammable.json | 8 +-
+ data/json/items/gun/flintlock.json | 23 +--
+ data/json/items/gun/misc.json | 2 +-
+ data/json/items/gun/nail.json | 2 +-
+ data/json/items/gun/paintball.json | 9 +-
+ data/json/items/gun/rpg.json | 4 +-
+ data/json/items/gun/shot.json | 122 ++++++------
+ data/json/items/gun/shotpaper.json | 8 +-
+ data/json/items/gun/signal_flare.json | 9 +-
+ data/json/items/gun/ups.json | 10 +-
+ data/json/items/ranged/crossbows.json | 9 +-
+ data/json/items/ranged/pneumatic.json | 6 +-
+ data/json/items/ranged/spearguns.json | 4 +-
+ data/json/not_really_obsolete.json | 4 +-
+ data/json/obsoletion/items.json | 24 +--
+ .../{items/gunmod => obsoletion}/mount.json | 0
+ data/json/obsoletion/recipes.json | 35 ++++
+ data/json/recipes/weapon/mods.json | 182 ------------------
+ data/mods/Aftershock/items/obsolete.json | 4 +-
+ data/mods/Aftershock/items/weapons.json | 10 +-
+ data/mods/Generic_Guns/firearms/obsolete.json | 8 +-
+ .../Magiclysm/items/enchanted_ranged.json | 6 +-
+ data/mods/No_Hope/Items/guns.json | 43 ++---
+ tests/ranged_burst_balance_test.cpp | 2 +-
+ 51 files changed, 306 insertions(+), 524 deletions(-)
+ rename data/json/{items/gunmod => obsoletion}/mount.json (100%)
+
+diff --git a/data/json/items/classes/gun.json b/data/json/items/classes/gun.json
+index d010aa2dee0..8ec6c586c89 100644
+--- a/data/json/items/classes/gun.json
++++ b/data/json/items/classes/gun.json
+@@ -93,10 +93,10 @@
+ [ "grip", 1 ],
+ [ "mechanism", 2 ],
+ [ "muzzle", 1 ],
+- [ "rail mount", 1 ],
+- [ "sights mount", 1 ],
+- [ "stock mount", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "rail", 1 ],
++ [ "sights", 1 ],
++ [ "stock", 1 ],
++ [ "underbarrel", 1 ]
+ ]
+ },
+ {
+@@ -129,9 +129,9 @@
+ [ "grip", 1 ],
+ [ "mechanism", 4 ],
+ [ "sights", 1 ],
+- [ "stock mount", 1 ],
+- [ "rail mount", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "stock", 1 ],
++ [ "rail", 1 ],
++ [ "underbarrel", 1 ]
+ ]
+ },
+ {
+@@ -145,15 +145,7 @@
+ "delete": { "flags": [ "NEVER_JAMS" ] },
+ "//": "Slower reloads, no unloading. Base, unskilled person should take 1.5 seconds per chamber. No underbarrel mods, that's where the ram goes.",
+ "faults": [ "fault_gun_blackpowder", "fault_gun_dirt" ],
+- "valid_mod_locations": [
+- [ "accessories", 2 ],
+- [ "barrel", 1 ],
+- [ "bore", 1 ],
+- [ "grip", 1 ],
+- [ "stock mount", 1 ],
+- [ "rail mount", 1 ],
+- [ "sights mount", 1 ]
+- ]
++ "valid_mod_locations": [ [ "accessories", 2 ], [ "barrel", 1 ], [ "bore", 1 ], [ "grip", 1 ], [ "stock", 1 ], [ "rail", 1 ], [ "sights", 1 ] ]
+ },
+ {
+ "abstract": "pistol_energy",
+@@ -188,14 +180,7 @@
+ "flags": [ "RELOAD_ONE", "STR_RELOAD", "WATERPROOF_GUN", "UNDERWATER_GUN", "NEVER_JAMS", "NON_FOULING", "NEEDS_NO_LUBE" ],
+ "dispersion": 120,
+ "reload": 600,
+- "valid_mod_locations": [
+- [ "accessories", 2 ],
+- [ "grip", 1 ],
+- [ "sights", 1 ],
+- [ "stock", 1 ],
+- [ "rail mount", 1 ],
+- [ "underbarrel mount", 1 ]
+- ],
++ "valid_mod_locations": [ [ "accessories", 2 ], [ "grip", 1 ], [ "sights", 1 ], [ "stock", 1 ], [ "rail", 1 ], [ "underbarrel", 1 ] ],
+ "faults": [ ]
+ },
+ {
+@@ -271,10 +256,10 @@
+ [ "muzzle", 1 ],
+ [ "sling", 1 ],
+ [ "stock", 1 ],
+- [ "grip mount", 1 ],
+- [ "rail mount", 1 ],
+- [ "sights mount", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "grip", 1 ],
++ [ "rail", 1 ],
++ [ "sights", 1 ],
++ [ "underbarrel", 1 ]
+ ],
+ "faults": [ "fault_gun_blackpowder", "fault_gun_dirt" ],
+ "flags": [ "RELOAD_EJECT" ]
+@@ -340,8 +325,8 @@
+ [ "sights", 1 ],
+ [ "sling", 1 ],
+ [ "stock", 1 ],
+- [ "rail mount", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "rail", 1 ],
++ [ "underbarrel", 1 ]
+ ],
+ "faults": [ ]
+ },
+@@ -356,7 +341,7 @@
+ "flags": [ "NEVER_JAMS", "NON_FOULING", "NEEDS_NO_LUBE" ],
+ "dispersion": 350,
+ "reload": 600,
+- "valid_mod_locations": [ [ "accessories", 3 ], [ "sling", 1 ], [ "grip", 1 ], [ "mechanism", 4 ], [ "stock", 1 ], [ "rail mount", 1 ] ],
++ "valid_mod_locations": [ [ "accessories", 3 ], [ "sling", 1 ], [ "grip", 1 ], [ "mechanism", 4 ], [ "stock", 1 ], [ "rail", 1 ] ],
+ "faults": [ ]
+ },
+ {
+@@ -375,14 +360,14 @@
+ [ "barrel", 1 ],
+ [ "bore", 1 ],
+ [ "brass catcher", 1 ],
+- [ "grip mount", 1 ],
++ [ "grip", 1 ],
+ [ "mechanism", 4 ],
+ [ "muzzle", 1 ],
+- [ "rail mount", 1 ],
+- [ "sights mount", 1 ],
++ [ "rail", 1 ],
++ [ "sights", 1 ],
+ [ "sling", 1 ],
+ [ "stock", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "underbarrel", 1 ]
+ ]
+ },
+ {
+@@ -415,15 +400,15 @@
+ [ "barrel", 1 ],
+ [ "bore", 1 ],
+ [ "brass catcher", 1 ],
+- [ "grip mount", 1 ],
++ [ "grip", 1 ],
+ [ "mechanism", 4 ],
+ [ "muzzle", 1 ],
+ [ "loading port", 1 ],
+- [ "rail mount", 1 ],
+- [ "sights mount", 1 ],
++ [ "rail", 1 ],
++ [ "sights", 1 ],
+ [ "sling", 1 ],
+ [ "stock", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "underbarrel", 1 ]
+ ]
+ },
+ {
+@@ -475,7 +460,7 @@
+ "dispersion": 300,
+ "reload": 400,
+ "handling": 60,
+- "valid_mod_locations": [ [ "brass catcher", 1 ], [ "sling", 1 ], [ "rail mount", 1 ], [ "sights mount", 1 ] ],
++ "valid_mod_locations": [ [ "brass catcher", 1 ], [ "sling", 1 ], [ "rail", 1 ], [ "sights", 1 ] ],
+ "flags": [ "MOUNTED_GUN" ],
+ "faults": [ "fault_gun_blackpowder", "fault_gun_dirt" ]
+ },
+diff --git a/data/json/items/classes/range.json b/data/json/items/classes/range.json
+index 0909d41652c..e887e7e5e73 100644
+--- a/data/json/items/classes/range.json
++++ b/data/json/items/classes/range.json
+@@ -77,7 +77,7 @@
+ "name": { "str": "base slingshot" },
+ "skill": "archery",
+ "ammo": "pebble",
+- "valid_mod_locations": [ [ "grip mount", 1 ], [ "underbarrel mount", 1 ] ],
++ "valid_mod_locations": [ [ "grip", 1 ], [ "underbarrel", 1 ] ],
+ "extend": { "flags": [ "BELT_CLIP" ] }
+ },
+ {
+diff --git a/data/json/items/gun/20x66mm.json b/data/json/items/gun/20x66mm.json
+index ef5f400ea73..fcd4ba7d58d 100644
+--- a/data/json/items/gun/20x66mm.json
++++ b/data/json/items/gun/20x66mm.json
+@@ -92,7 +92,7 @@
+ [ "rail", 1 ],
+ [ "sights", 1 ],
+ [ "stock", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "underbarrel", 1 ]
+ ],
+ "magazines": [ [ "20x66mm", [ "20x66_10_mag" ] ] ],
+ "flags": [ "WATERPROOF_GUN", "NEVER_JAMS" ]
+diff --git a/data/json/items/gun/22.json b/data/json/items/gun/22.json
+index 501c3df55a5..9a9f792cae7 100644
+--- a/data/json/items/gun/22.json
++++ b/data/json/items/gun/22.json
+@@ -67,9 +67,9 @@
+ [ "bore", 1 ],
+ [ "grip", 1 ],
+ [ "mechanism", 2 ],
+- [ "sights mount", 1 ],
+- [ "stock mount", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "sights", 1 ],
++ [ "stock", 1 ],
++ [ "underbarrel", 1 ]
+ ],
+ "faults": [ "fault_gun_blackpowder", "fault_gun_dirt" ],
+ "flags": [ "RELOAD_ONE", "NEVER_JAMS", "RELOAD_EJECT" ]
+diff --git a/data/json/items/gun/223.json b/data/json/items/gun/223.json
+index 848fe53ce0a..1b6d7c727d9 100644
+--- a/data/json/items/gun/223.json
++++ b/data/json/items/gun/223.json
+@@ -123,13 +123,13 @@
+ [ "barrel", 1 ],
+ [ "bore", 1 ],
+ [ "brass catcher", 1 ],
+- [ "grip mount", 1 ],
++ [ "grip", 1 ],
+ [ "mechanism", 4 ],
+ [ "magazine", 1 ],
+ [ "muzzle", 1 ],
+- [ "sights mount", 1 ],
++ [ "sights", 1 ],
+ [ "sling", 1 ],
+- [ "underbarrel mount", 1 ],
++ [ "underbarrel", 1 ],
+ [ "underbarrel", 1 ]
+ ],
+ "magazines": [ [ "223", [ "famasmag" ] ] ]
+@@ -435,10 +435,10 @@
+ [ "muzzle", 1 ],
+ [ "sights", 1 ],
+ [ "sling", 1 ],
+- [ "grip mount", 1 ],
+- [ "rail mount", 1 ],
++ [ "grip", 1 ],
++ [ "rail", 1 ],
+ [ "stock", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "underbarrel", 1 ]
+ ],
+ "magazines": [ [ "223", [ "ruger20", "ruger5", "ruger10", "ruger30", "ruger90", "ruger100", "ruger_makeshiftmag" ] ] ]
+ },
+@@ -586,9 +586,9 @@
+ [ "sling", 1 ],
+ [ "stock", 1 ],
+ [ "underbarrel", 1 ],
+- [ "grip mount", 1 ],
+- [ "rail mount", 1 ],
+- [ "sights mount", 1 ]
++ [ "grip", 1 ],
++ [ "rail", 1 ],
++ [ "sights", 1 ]
+ ],
+ "magazines": [
+ [
+diff --git a/data/json/items/gun/3006.json b/data/json/items/gun/3006.json
+index 96248a6de79..3963fd1197a 100644
+--- a/data/json/items/gun/3006.json
++++ b/data/json/items/gun/3006.json
+@@ -79,10 +79,10 @@
+ [ "muzzle", 1 ],
+ [ "sights", 1 ],
+ [ "sling", 1 ],
+- [ "grip mount", 1 ],
+- [ "rail mount", 1 ],
++ [ "grip", 1 ],
++ [ "rail", 1 ],
+ [ "stock", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "underbarrel", 1 ]
+ ],
+ "magazines": [ [ "3006", [ "3006_clip" ] ] ],
+ "flags": [ "RELOAD_ONE" ]
+diff --git a/data/json/items/gun/308.json b/data/json/items/gun/308.json
+index e32022184b3..87677a5128a 100644
+--- a/data/json/items/gun/308.json
++++ b/data/json/items/gun/308.json
+@@ -122,10 +122,10 @@
+ [ "muzzle", 1 ],
+ [ "sights", 1 ],
+ [ "sling", 1 ],
+- [ "grip mount", 1 ],
+- [ "rail mount", 1 ],
++ [ "grip", 1 ],
++ [ "rail", 1 ],
+ [ "stock", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "underbarrel", 1 ]
+ ],
+ "magazines": [ [ "308", [ "m14mag", "m14smallmag", "m14_makeshiftmag" ] ] ]
+ },
+@@ -232,9 +232,9 @@
+ [ "mechanism", 4 ],
+ [ "sights", 1 ],
+ [ "sling", 1 ],
+- [ "grip mount", 1 ],
+- [ "rail mount", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "grip", 1 ],
++ [ "rail", 1 ],
++ [ "underbarrel", 1 ]
+ ],
+ "magazines": [ [ "308", [ "g3_makeshiftmag", "g3mag", "g3bigmag" ] ] ]
+ },
+@@ -302,8 +302,8 @@
+ [ "stock", 1 ],
+ [ "mechanism", 4 ],
+ [ "sights", 1 ],
+- [ "grip mount", 1 ],
+- [ "rail mount", 1 ],
++ [ "grip", 1 ],
++ [ "rail", 1 ],
+ [ "underbarrel", 1 ]
+ ],
+ "flags": [ "RELOAD_ONE", "NEVER_JAMS" ]
+diff --git a/data/json/items/gun/38.json b/data/json/items/gun/38.json
+index e71fa7eaf06..c79c06b26b6 100644
+--- a/data/json/items/gun/38.json
++++ b/data/json/items/gun/38.json
+@@ -21,14 +21,7 @@
+ "blackpowder_tolerance": 60,
+ "clip_size": 2,
+ "reload": 200,
+- "valid_mod_locations": [
+- [ "accessories", 4 ],
+- [ "grip", 1 ],
+- [ "sights", 1 ],
+- [ "underbarrel", 1 ],
+- [ "rail mount", 1 ],
+- [ "stock mount", 1 ]
+- ],
++ "valid_mod_locations": [ [ "accessories", 4 ], [ "grip", 1 ], [ "sights", 1 ], [ "underbarrel", 1 ], [ "rail", 1 ], [ "stock", 1 ] ],
+ "delete": { "flags": "NEVER_JAMS" }
+ },
+ {
+@@ -55,9 +48,9 @@
+ [ "bore", 1 ],
+ [ "grip", 1 ],
+ [ "mechanism", 2 ],
+- [ "sights mount", 1 ],
+- [ "stock mount", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "sights", 1 ],
++ [ "stock", 1 ],
++ [ "underbarrel", 1 ]
+ ]
+ },
+ {
+@@ -121,7 +114,7 @@
+ [ "mechanism", 4 ],
+ [ "rail", 1 ],
+ [ "sights", 1 ],
+- [ "stock mount", 1 ],
++ [ "stock", 1 ],
+ [ "underbarrel", 1 ]
+ ]
+ },
+@@ -154,7 +147,7 @@
+ [ "mechanism", 4 ],
+ [ "rail", 1 ],
+ [ "sights", 1 ],
+- [ "stock mount", 1 ],
++ [ "stock", 1 ],
+ [ "underbarrel", 1 ]
+ ]
+ }
+diff --git a/data/json/items/gun/40.json b/data/json/items/gun/40.json
+index 498b7189c15..922be16a0ef 100644
+--- a/data/json/items/gun/40.json
++++ b/data/json/items/gun/40.json
+@@ -191,7 +191,7 @@
+ [ "sights", 1 ],
+ [ "stock", 1 ],
+ [ "underbarrel", 1 ],
+- [ "rail mount", 1 ]
++ [ "rail", 1 ]
+ ],
+ "flags": [ "RELOAD_ONE", "NEVER_JAMS", "RELOAD_EJECT" ],
+ "delete": { "faults": "fault_gun_chamber_spent" }
+diff --git a/data/json/items/gun/40x46mm.json b/data/json/items/gun/40x46mm.json
+index 5e5af532fca..a3e217b890b 100644
+--- a/data/json/items/gun/40x46mm.json
++++ b/data/json/items/gun/40x46mm.json
+@@ -21,10 +21,10 @@
+ [ "barrel", 1 ],
+ [ "sights", 1 ],
+ [ "sling", 1 ],
+- [ "grip mount", 1 ],
+- [ "rail mount", 1 ],
+- [ "stock mount", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "grip", 1 ],
++ [ "rail", 1 ],
++ [ "stock", 1 ],
++ [ "underbarrel", 1 ]
+ ]
+ },
+ {
+@@ -68,10 +68,10 @@
+ [ "barrel", 1 ],
+ [ "sights", 1 ],
+ [ "sling", 1 ],
+- [ "grip mount", 1 ],
+- [ "rail mount", 1 ],
++ [ "grip", 1 ],
++ [ "rail", 1 ],
+ [ "stock", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "underbarrel", 1 ]
+ ]
+ },
+ {
+@@ -95,10 +95,10 @@
+ [ "barrel", 1 ],
+ [ "sights", 1 ],
+ [ "sling", 1 ],
+- [ "grip mount", 1 ],
+- [ "rail mount", 1 ],
++ [ "grip", 1 ],
++ [ "rail", 1 ],
+ [ "stock", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "underbarrel", 1 ]
+ ]
+ },
+ {
+diff --git a/data/json/items/gun/40x53mm.json b/data/json/items/gun/40x53mm.json
+index ffe7978e13b..0ed451e6df0 100644
+--- a/data/json/items/gun/40x53mm.json
++++ b/data/json/items/gun/40x53mm.json
+@@ -24,8 +24,8 @@
+ [ "brass catcher", 1 ],
+ [ "sights", 1 ],
+ [ "sling", 1 ],
+- [ "rail mount", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "rail", 1 ],
++ [ "underbarrel", 1 ]
+ ],
+ "modes": [ [ "DEFAULT", "semi", 1, "NPC_AVOID" ], [ "AUTO", "auto", 2, "NPC_AVOID" ] ],
+ "magazines": [ [ "40x53mm", [ "belt40mm" ] ] ],
+diff --git a/data/json/items/gun/410shot.json b/data/json/items/gun/410shot.json
+index f485eb15c46..8e4bdec9554 100644
+--- a/data/json/items/gun/410shot.json
++++ b/data/json/items/gun/410shot.json
+@@ -41,12 +41,12 @@
+ [ "bore", 1 ],
+ [ "muzzle", 1 ],
+ [ "mechanism", 1 ],
+- [ "sights mount", 1 ],
++ [ "sights", 1 ],
+ [ "sling", 1 ],
+- [ "stock mount", 1 ],
+- [ "grip mount", 1 ],
+- [ "rail mount", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "stock", 1 ],
++ [ "grip", 1 ],
++ [ "rail", 1 ],
++ [ "underbarrel", 1 ]
+ ],
+ "extend": { "flags": [ "NEVER_JAMS" ] }
+ }
+diff --git a/data/json/items/gun/44.json b/data/json/items/gun/44.json
+index cc4deed8ff4..d2b4d1c3f21 100644
+--- a/data/json/items/gun/44.json
++++ b/data/json/items/gun/44.json
+@@ -62,8 +62,8 @@
+ [ "sights", 1 ],
+ [ "sling", 1 ],
+ [ "stock", 1 ],
+- [ "rail mount", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "rail", 1 ],
++ [ "underbarrel", 1 ]
+ ]
+ },
+ {
+diff --git a/data/json/items/gun/44paper.json b/data/json/items/gun/44paper.json
+index e3fdcabb226..483e2eecb4d 100644
+--- a/data/json/items/gun/44paper.json
++++ b/data/json/items/gun/44paper.json
+@@ -41,8 +41,8 @@
+ [ "grip", 1 ],
+ [ "stock", 1 ],
+ [ "underbarrel", 1 ],
+- [ "rail mount", 1 ],
+- [ "sights mount", 1 ]
++ [ "rail", 1 ],
++ [ "sights", 1 ]
+ ],
+ "built_in_mods": [ "lemat_revolver_shotgun" ]
+ }
+diff --git a/data/json/items/gun/454.json b/data/json/items/gun/454.json
+index 9b134a715b8..b35e2aa131e 100644
+--- a/data/json/items/gun/454.json
++++ b/data/json/items/gun/454.json
+@@ -24,8 +24,8 @@
+ [ "mechanism", 4 ],
+ [ "rail", 1 ],
+ [ "sights", 1 ],
+- [ "stock mount", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "stock", 1 ],
++ [ "underbarrel", 1 ]
+ ]
+ },
+ {
+diff --git a/data/json/items/gun/4570.json b/data/json/items/gun/4570.json
+index 62036e1bc6e..c54a6612423 100644
+--- a/data/json/items/gun/4570.json
++++ b/data/json/items/gun/4570.json
+@@ -23,9 +23,9 @@
+ [ "muzzle", 1 ],
+ [ "sights", 1 ],
+ [ "sling", 1 ],
+- [ "rail mount", 1 ],
++ [ "rail", 1 ],
+ [ "stock", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "underbarrel", 1 ]
+ ],
+ "flags": [ "RELOAD_ONE" ]
+ },
+@@ -53,9 +53,9 @@
+ [ "grip", 1 ],
+ [ "mechanism", 4 ],
+ [ "sights", 1 ],
+- [ "rail mount", 1 ],
+- [ "stock mount", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "rail", 1 ],
++ [ "stock", 1 ],
++ [ "underbarrel", 1 ]
+ ]
+ },
+ {
+@@ -85,9 +85,9 @@
+ [ "muzzle", 1 ],
+ [ "sights", 1 ],
+ [ "sling", 1 ],
+- [ "rail mount", 1 ],
++ [ "rail", 1 ],
+ [ "stock", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "underbarrel", 1 ]
+ ]
+ },
+ {
+@@ -107,7 +107,7 @@
+ "ammo": "4570",
+ "dispersion": 400,
+ "blackpowder_tolerance": 80,
+- "valid_mod_locations": [ [ "brass catcher", 1 ], [ "rail mount", 1 ], [ "sights", 1 ] ],
++ "valid_mod_locations": [ [ "brass catcher", 1 ], [ "rail", 1 ], [ "sights", 1 ] ],
+ "modes": [ [ "DEFAULT", "single", 1 ], [ "AUTO", "burst", 3 ] ],
+ "//": "If speedloaders get fixed to allow topping off a partially-loaded gun, adding the more common Bruce feed (40 round feed tray topped off with 20-round blocks) would be an option.",
+ "magazines": [ [ "4570", [ "gatlingdrum240" ] ] ],
+diff --git a/data/json/items/gun/45colt.json b/data/json/items/gun/45colt.json
+index db54e498372..e6a2b6a6250 100644
+--- a/data/json/items/gun/45colt.json
++++ b/data/json/items/gun/45colt.json
+@@ -23,9 +23,9 @@
+ [ "bore", 1 ],
+ [ "grip", 1 ],
+ [ "mechanism", 2 ],
+- [ "sights mount", 1 ],
+- [ "stock mount", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "sights", 1 ],
++ [ "stock", 1 ],
++ [ "underbarrel", 1 ]
+ ]
+ },
+ {
+diff --git a/data/json/items/gun/50.json b/data/json/items/gun/50.json
+index 0920cb6f218..dad0ca0fa82 100644
+--- a/data/json/items/gun/50.json
++++ b/data/json/items/gun/50.json
+@@ -46,8 +46,8 @@
+ [ "sling", 1 ],
+ [ "mechanism", 4 ],
+ [ "muzzle", 1 ],
+- [ "rail mount", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "rail", 1 ],
++ [ "underbarrel", 1 ]
+ ],
+ "magazines": [ [ "50", [ "belt50" ] ] ],
+ "flags": [ "MOUNTED_GUN" ]
+@@ -84,8 +84,8 @@
+ [ "sling", 1 ],
+ [ "stock", 1 ],
+ [ "grip", 1 ],
+- [ "rail mount", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "rail", 1 ],
++ [ "underbarrel", 1 ]
+ ],
+ "magazines": [ ],
+ "clip_size": 1,
+diff --git a/data/json/items/gun/500.json b/data/json/items/gun/500.json
+index 0954d54fb7a..58f0ed4665f 100644
+--- a/data/json/items/gun/500.json
++++ b/data/json/items/gun/500.json
+@@ -27,8 +27,8 @@
+ [ "sights", 1 ],
+ [ "sling", 1 ],
+ [ "stock", 1 ],
+- [ "rail mount", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "rail", 1 ],
++ [ "underbarrel", 1 ]
+ ]
+ },
+ {
+@@ -56,8 +56,8 @@
+ [ "mechanism", 4 ],
+ [ "rail", 1 ],
+ [ "sights", 1 ],
+- [ "stock mount", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "stock", 1 ],
++ [ "underbarrel", 1 ]
+ ]
+ }
+ ]
+diff --git a/data/json/items/gun/66mm.json b/data/json/items/gun/66mm.json
+index dd89b475912..effed9c7242 100644
+--- a/data/json/items/gun/66mm.json
++++ b/data/json/items/gun/66mm.json
+@@ -43,13 +43,6 @@
+ "durability": 9,
+ "clip_size": 1,
+ "reload": 150,
+- "valid_mod_locations": [
+- [ "accessories", 1 ],
+- [ "sling", 1 ],
+- [ "grip mount", 1 ],
+- [ "rail mount", 1 ],
+- [ "sights mount", 1 ],
+- [ "underbarrel mount", 1 ]
+- ]
++ "valid_mod_locations": [ [ "accessories", 1 ], [ "sling", 1 ], [ "grip", 1 ], [ "rail", 1 ], [ "sights", 1 ], [ "underbarrel", 1 ] ]
+ }
+ ]
+diff --git a/data/json/items/gun/762.json b/data/json/items/gun/762.json
+index a21d1e6d8fa..2b516169168 100644
+--- a/data/json/items/gun/762.json
++++ b/data/json/items/gun/762.json
+@@ -24,11 +24,11 @@
+ [ "grip", 1 ],
+ [ "mechanism", 4 ],
+ [ "muzzle", 1 ],
+- [ "rail mount", 1 ],
+- [ "sights mount", 1 ],
++ [ "rail", 1 ],
++ [ "sights", 1 ],
+ [ "sling", 1 ],
+ [ "stock", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "underbarrel", 1 ]
+ ],
+ "magazines": [ [ "762", [ "akmag30", "akmag10", "akmag20", "akmag40", "akdrum75" ] ] ]
+ },
+@@ -100,11 +100,11 @@
+ [ "grip", 1 ],
+ [ "mechanism", 4 ],
+ [ "muzzle", 1 ],
+- [ "rail mount", 1 ],
+- [ "sights mount", 1 ],
++ [ "rail", 1 ],
++ [ "sights", 1 ],
+ [ "sling", 1 ],
+ [ "stock", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "underbarrel", 1 ]
+ ],
+ "magazines": [ [ "762", [ "akmag30", "akmag10", "akmag20", "akmag40", "akdrum75" ] ] ]
+ },
+@@ -134,11 +134,11 @@
+ [ "grip", 1 ],
+ [ "mechanism", 4 ],
+ [ "muzzle", 1 ],
+- [ "rail mount", 1 ],
+- [ "sights mount", 1 ],
++ [ "rail", 1 ],
++ [ "sights", 1 ],
+ [ "sling", 1 ],
+- [ "stock mount", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "stock", 1 ],
++ [ "underbarrel", 1 ]
+ ],
+ "magazines": [ [ "762", [ "akmag30", "akmag10", "akmag20", "akmag40", "akdrum75" ] ] ]
+ }
+diff --git a/data/json/items/gun/762x25.json b/data/json/items/gun/762x25.json
+index 397d57e9a93..2a34af4ea9e 100644
+--- a/data/json/items/gun/762x25.json
++++ b/data/json/items/gun/762x25.json
+@@ -30,7 +30,7 @@
+ [ "sling", 1 ],
+ [ "stock", 1 ],
+ [ "underbarrel", 1 ],
+- [ "rail mount", 1 ]
++ [ "rail", 1 ]
+ ],
+ "magazines": [ [ "762x25", [ "ppshmag", "ppshdrum" ] ] ]
+ },
+diff --git a/data/json/items/gun/84x246mm.json b/data/json/items/gun/84x246mm.json
+index 29c8d5d810f..a3b1bcbbd97 100644
+--- a/data/json/items/gun/84x246mm.json
++++ b/data/json/items/gun/84x246mm.json
+@@ -25,8 +25,8 @@
+ [ "grip", 1 ],
+ [ "mechanism", 4 ],
+ [ "sights", 1 ],
+- [ "rail mount", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "rail", 1 ],
++ [ "underbarrel", 1 ]
+ ]
+ },
+ {
+diff --git a/data/json/items/gun/9mm.json b/data/json/items/gun/9mm.json
+index a3db7b059ac..dea9a3429f9 100644
+--- a/data/json/items/gun/9mm.json
++++ b/data/json/items/gun/9mm.json
+@@ -117,9 +117,9 @@
+ [ "grip", 1 ],
+ [ "mechanism", 4 ],
+ [ "muzzle", 1 ],
+- [ "rail mount", 1 ],
+- [ "sights mount", 1 ],
+- [ "underbarrel mount", 1 ],
++ [ "rail", 1 ],
++ [ "sights", 1 ],
++ [ "underbarrel", 1 ],
+ [ "sling", 1 ],
+ [ "stock", 1 ]
+ ],
+@@ -142,9 +142,9 @@
+ [ "brass catcher", 1 ],
+ [ "grip", 1 ],
+ [ "mechanism", 4 ],
+- [ "rail mount", 1 ],
+- [ "sights mount", 1 ],
+- [ "underbarrel mount", 1 ],
++ [ "rail", 1 ],
++ [ "sights", 1 ],
++ [ "underbarrel", 1 ],
+ [ "sling", 1 ],
+ [ "stock", 1 ]
+ ],
+@@ -173,8 +173,8 @@
+ [ "grip", 1 ],
+ [ "mechanism", 4 ],
+ [ "muzzle", 1 ],
+- [ "rail mount", 1 ],
+- [ "sights mount", 1 ],
++ [ "rail", 1 ],
++ [ "sights", 1 ],
+ [ "underbarrel", 1 ],
+ [ "sling", 1 ],
+ [ "stock", 1 ]
+@@ -199,9 +199,9 @@
+ [ "grip", 1 ],
+ [ "mechanism", 4 ],
+ [ "muzzle", 1 ],
+- [ "rail mount", 1 ],
++ [ "rail", 1 ],
+ [ "sights", 1 ],
+- [ "underbarrel mount", 1 ],
++ [ "underbarrel", 1 ],
+ [ "sling", 1 ],
+ [ "stock", 1 ]
+ ],
+@@ -385,10 +385,10 @@
+ [ "muzzle", 1 ],
+ [ "sling", 1 ],
+ [ "stock", 1 ],
+- [ "grip mount", 1 ],
+- [ "rail mount", 1 ],
+- [ "sights mount", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "grip", 1 ],
++ [ "rail", 1 ],
++ [ "sights", 1 ],
++ [ "underbarrel", 1 ]
+ ],
+ "magazines": [ [ "9mm", [ "stenmag", "survivor9mm_mag" ] ] ]
+ },
+diff --git a/data/json/items/gun/atgm.json b/data/json/items/gun/atgm.json
+index d08f2aa7a30..706e60049c6 100644
+--- a/data/json/items/gun/atgm.json
++++ b/data/json/items/gun/atgm.json
+@@ -19,7 +19,7 @@
+ "clip_size": 1,
+ "reload": 600,
+ "loudness": 200,
+- "valid_mod_locations": [ [ "sling", 1 ], [ "rail mount", 1 ], [ "sights mount", 1 ], [ "underbarrel mount", 1 ] ],
++ "valid_mod_locations": [ [ "sling", 1 ], [ "rail", 1 ], [ "sights", 1 ], [ "underbarrel", 1 ] ],
+ "extend": { "flags": [ "RELOAD_EJECT", "MOUNTED_GUN" ] }
+ }
+ ]
+diff --git a/data/json/items/gun/blunderbuss.json b/data/json/items/gun/blunderbuss.json
+index 9b95f5f0763..f123f83524e 100644
+--- a/data/json/items/gun/blunderbuss.json
++++ b/data/json/items/gun/blunderbuss.json
+@@ -19,14 +19,7 @@
+ "clip_size": 1,
+ "reload": 300,
+ "barrel_length": "500 ml",
+- "valid_mod_locations": [
+- [ "sling", 1 ],
+- [ "stock", 1 ],
+- [ "grip mount", 1 ],
+- [ "rail mount", 1 ],
+- [ "sights mount", 1 ],
+- [ "underbarrel mount", 1 ]
+- ],
++ "valid_mod_locations": [ [ "sling", 1 ], [ "stock", 1 ], [ "grip", 1 ], [ "rail", 1 ], [ "sights", 1 ], [ "underbarrel", 1 ] ],
+ "faults": [ ]
+ }
+ ]
+diff --git a/data/json/items/gun/combination.json b/data/json/items/gun/combination.json
+index 3287be03365..22e6bf7fa5f 100644
+--- a/data/json/items/gun/combination.json
++++ b/data/json/items/gun/combination.json
+@@ -28,7 +28,7 @@
+ [ "sling", 1 ],
+ [ "stock", 1 ],
+ [ "underbarrel", 1 ],
+- [ "rail mount", 1 ]
++ [ "rail", 1 ]
+ ]
+ },
+ {
+diff --git a/data/json/items/gun/flammable.json b/data/json/items/gun/flammable.json
+index 9068ff03e6b..3ba14725f14 100644
+--- a/data/json/items/gun/flammable.json
++++ b/data/json/items/gun/flammable.json
+@@ -17,10 +17,10 @@
+ [ "accessories", 1 ],
+ [ "grip", 1 ],
+ [ "sling", 1 ],
+- [ "rail mount", 1 ],
+- [ "stock mount", 1 ],
+- [ "sights mount", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "rail", 1 ],
++ [ "stock", 1 ],
++ [ "sights", 1 ],
++ [ "underbarrel", 1 ]
+ ],
+ "magazines": [ [ "flammable", [ "pressurized_tank" ] ] ]
+ },
+diff --git a/data/json/items/gun/flintlock.json b/data/json/items/gun/flintlock.json
+index de0bc8717f9..90b94fd59ae 100644
+--- a/data/json/items/gun/flintlock.json
++++ b/data/json/items/gun/flintlock.json
+@@ -9,11 +9,11 @@
+ "valid_mod_locations": [
+ [ "accessories", 1 ],
+ [ "sling", 1 ],
+- [ "grip mount", 1 ],
+- [ "rail mount", 1 ],
+- [ "sights mount", 1 ],
++ [ "grip", 1 ],
++ [ "rail", 1 ],
++ [ "sights", 1 ],
+ [ "stock", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "underbarrel", 1 ]
+ ],
+ "volume": "2250 ml",
+ "weight": "3600 g",
+@@ -55,14 +55,7 @@
+ "blackpowder_tolerance": 96,
+ "clip_size": 1,
+ "reload": 600,
+- "valid_mod_locations": [
+- [ "accessories", 1 ],
+- [ "grip mount", 1 ],
+- [ "rail mount", 1 ],
+- [ "sights mount", 1 ],
+- [ "stock mount", 1 ],
+- [ "underbarrel mount", 1 ]
+- ],
++ "valid_mod_locations": [ [ "accessories", 1 ], [ "grip", 1 ], [ "rail", 1 ], [ "sights", 1 ], [ "stock", 1 ], [ "underbarrel", 1 ] ],
+ "flags": [ "NEVER_JAMS" ]
+ },
+ {
+@@ -91,9 +84,9 @@
+ [ "accessories", 1 ],
+ [ "sling", 1 ],
+ [ "underbarrel", 1 ],
+- [ "grip mount", 1 ],
+- [ "rail mount", 1 ],
+- [ "sights mount", 1 ],
++ [ "grip", 1 ],
++ [ "rail", 1 ],
++ [ "sights", 1 ],
+ [ "stock", 1 ]
+ ],
+ "extend": { "flags": [ "DURABLE_MELEE" ] }
+diff --git a/data/json/items/gun/misc.json b/data/json/items/gun/misc.json
+index 54884ef07a8..ec4d43f9286 100644
+--- a/data/json/items/gun/misc.json
++++ b/data/json/items/gun/misc.json
+@@ -19,7 +19,7 @@
+ "clip_size": 1,
+ "reload": 800,
+ "loudness": 200,
+- "valid_mod_locations": [ [ "sling", 1 ], [ "grip mount", 1 ], [ "rail mount", 1 ], [ "sights mount", 1 ], [ "underbarrel mount", 1 ] ]
++ "valid_mod_locations": [ [ "sling", 1 ], [ "grip", 1 ], [ "rail", 1 ], [ "sights", 1 ], [ "underbarrel", 1 ] ]
+ },
+ {
+ "id": "watercannon",
+diff --git a/data/json/items/gun/nail.json b/data/json/items/gun/nail.json
+index bedf605cf5b..6df29b41a28 100644
+--- a/data/json/items/gun/nail.json
++++ b/data/json/items/gun/nail.json
+@@ -18,6 +18,6 @@
+ "loudness": 5,
+ "clip_size": 20,
+ "reload": 50,
+- "valid_mod_locations": [ [ "grip mount", 1 ], [ "rail mount", 1 ], [ "sights mount", 1 ], [ "stock mount", 1 ], [ "underbarrel mount", 1 ] ]
++ "valid_mod_locations": [ [ "grip", 1 ], [ "rail", 1 ], [ "sights", 1 ], [ "stock", 1 ], [ "underbarrel", 1 ] ]
+ }
+ ]
+diff --git a/data/json/items/gun/paintball.json b/data/json/items/gun/paintball.json
+index 6eea43e32fe..f1e584dc959 100644
+--- a/data/json/items/gun/paintball.json
++++ b/data/json/items/gun/paintball.json
+@@ -23,13 +23,6 @@
+ "durability": 7,
+ "clip_size": 50,
+ "reload": 50,
+- "valid_mod_locations": [
+- [ "sling", 1 ],
+- [ "grip mount", 1 ],
+- [ "rail mount", 1 ],
+- [ "sights mount", 1 ],
+- [ "stock mount", 1 ],
+- [ "underbarrel mount", 1 ]
+- ]
++ "valid_mod_locations": [ [ "sling", 1 ], [ "grip", 1 ], [ "rail", 1 ], [ "sights", 1 ], [ "stock", 1 ], [ "underbarrel", 1 ] ]
+ }
+ ]
+diff --git a/data/json/items/gun/rpg.json b/data/json/items/gun/rpg.json
+index 44e881691c8..3ffb55be6e7 100644
+--- a/data/json/items/gun/rpg.json
++++ b/data/json/items/gun/rpg.json
+@@ -24,8 +24,8 @@
+ [ "mechanism", 4 ],
+ [ "sights", 1 ],
+ [ "sling", 1 ],
+- [ "rail mount", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "rail", 1 ],
++ [ "underbarrel", 1 ]
+ ]
+ }
+ ]
+diff --git a/data/json/items/gun/shot.json b/data/json/items/gun/shot.json
+index d170049a3b3..a599c10aae7 100644
+--- a/data/json/items/gun/shot.json
++++ b/data/json/items/gun/shot.json
+@@ -24,11 +24,11 @@
+ "valid_mod_locations": [
+ [ "accessories", 1 ],
+ [ "grip", 1 ],
+- [ "stock mount", 1 ],
++ [ "stock", 1 ],
+ [ "mechanism", 4 ],
+- [ "sights mount", 1 ],
+- [ "rail mount", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "sights", 1 ],
++ [ "rail", 1 ],
++ [ "underbarrel", 1 ]
+ ]
+ },
+ {
+@@ -50,7 +50,7 @@
+ "burst": 6,
+ "reload": 200,
+ "handling": 30,
+- "valid_mod_locations": [ [ "accessories", 4 ], [ "sights", 1 ], [ "rail mount", 1 ] ],
++ "valid_mod_locations": [ [ "accessories", 4 ], [ "sights", 1 ], [ "rail", 1 ] ],
+ "magazines": [ [ "shot", [ "shotbelt_20" ] ] ],
+ "flags": [ "MOUNTED_GUN" ]
+ },
+@@ -96,10 +96,10 @@
+ [ "barrel", 1 ],
+ [ "bore", 1 ],
+ [ "brass catcher", 1 ],
+- [ "grip mount", 1 ],
++ [ "grip", 1 ],
+ [ "mechanism", 4 ],
+ [ "muzzle", 1 ],
+- [ "rail mount", 1 ],
++ [ "rail", 1 ],
+ [ "sights", 1 ],
+ [ "sling", 1 ],
+ [ "underbarrel", 2 ]
+@@ -128,10 +128,10 @@
+ [ "barrel", 1 ],
+ [ "bore", 1 ],
+ [ "brass catcher", 1 ],
+- [ "grip mount", 1 ],
++ [ "grip", 1 ],
+ [ "mechanism", 4 ],
+ [ "muzzle", 1 ],
+- [ "rail mount", 1 ],
++ [ "rail", 1 ],
+ [ "sights", 1 ],
+ [ "sling", 1 ],
+ [ "underbarrel", 2 ]
+@@ -157,11 +157,11 @@
+ [ "mechanism", 4 ],
+ [ "sling", 1 ],
+ [ "barrel", 1 ],
+- [ "rail mount", 1 ],
++ [ "rail", 1 ],
+ [ "loading port", 1 ],
+ [ "brass catcher", 1 ],
+ [ "sights", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "underbarrel", 1 ]
+ ],
+ "flags": [ "RELOAD_ONE", "NEEDS_UNFOLD" ]
+ },
+@@ -236,14 +236,14 @@
+ [ "accessories", 2 ],
+ [ "sling", 1 ],
+ [ "barrel", 1 ],
+- [ "grip mount", 1 ],
++ [ "grip", 1 ],
+ [ "stock", 1 ],
+- [ "rail mount", 1 ],
++ [ "rail", 1 ],
+ [ "loading port", 1 ],
+ [ "brass catcher", 1 ],
+ [ "mechanism", 4 ],
+ [ "sights", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "underbarrel", 1 ]
+ ],
+ "extend": { "flags": [ "RELOAD_ONE" ] }
+ },
+@@ -261,12 +261,12 @@
+ "valid_mod_locations": [
+ [ "accessories", 2 ],
+ [ "sling", 1 ],
+- [ "stock mount", 1 ],
++ [ "stock", 1 ],
+ [ "barrel", 1 ],
+- [ "grip mount", 1 ],
+- [ "rail mount", 1 ],
+- [ "sights mount", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "grip", 1 ],
++ [ "rail", 1 ],
++ [ "sights", 1 ],
++ [ "underbarrel", 1 ]
+ ],
+ "extend": { "flags": [ "RELOAD_ONE" ] }
+ },
+@@ -291,13 +291,13 @@
+ "valid_mod_locations": [
+ [ "accessories", 2 ],
+ [ "sling", 1 ],
+- [ "stock mount", 1 ],
++ [ "stock", 1 ],
+ [ "barrel", 1 ],
+ [ "muzzle", 1 ],
+- [ "grip mount", 1 ],
+- [ "rail mount", 1 ],
+- [ "sights mount", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "grip", 1 ],
++ [ "rail", 1 ],
++ [ "sights", 1 ],
++ [ "underbarrel", 1 ]
+ ],
+ "flags": [ "NEVER_JAMS", "RELOAD_EJECT" ]
+ },
+@@ -347,11 +347,11 @@
+ [ "grip", 1 ],
+ [ "loading port", 1 ],
+ [ "mechanism", 4 ],
+- [ "rail mount", 1 ],
++ [ "rail", 1 ],
+ [ "sights", 1 ],
+ [ "sling", 1 ],
+ [ "stock", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "underbarrel", 1 ]
+ ]
+ },
+ {
+@@ -394,10 +394,10 @@
+ [ "barrel", 1 ],
+ [ "stock", 1 ],
+ [ "mechanism", 4 ],
+- [ "rail mount", 1 ],
++ [ "rail", 1 ],
+ [ "loading port", 1 ],
+- [ "sights mount", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "sights", 1 ],
++ [ "underbarrel", 1 ]
+ ],
+ "extend": { "flags": [ "RELOAD_ONE" ] }
+ },
+@@ -423,10 +423,10 @@
+ [ "sling", 1 ],
+ [ "stock", 1 ],
+ [ "barrel", 1 ],
+- [ "grip mount", 1 ],
+- [ "rail mount", 1 ],
+- [ "sights mount", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "grip", 1 ],
++ [ "rail", 1 ],
++ [ "sights", 1 ],
++ [ "underbarrel", 1 ]
+ ],
+ "flags": [ "RELOAD_ONE", "RELOAD_EJECT", "NEVER_JAMS" ]
+ },
+@@ -452,10 +452,10 @@
+ [ "mechanism", 4 ],
+ [ "barrel", 1 ],
+ [ "brass catcher", 1 ],
+- [ "grip mount", 1 ],
+- [ "rail mount", 1 ],
+- [ "sights mount", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "grip", 1 ],
++ [ "rail", 1 ],
++ [ "sights", 1 ],
++ [ "underbarrel", 1 ]
+ ],
+ "magazines": [ [ "shot", [ "saiga10mag", "saiga30mag" ] ] ]
+ },
+@@ -496,12 +496,12 @@
+ [ "bore", 1 ],
+ [ "muzzle", 1 ],
+ [ "mechanism", 1 ],
+- [ "sights mount", 1 ],
++ [ "sights", 1 ],
+ [ "sling", 1 ],
+ [ "stock", 1 ],
+- [ "grip mount", 1 ],
+- [ "rail mount", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "grip", 1 ],
++ [ "rail", 1 ],
++ [ "underbarrel", 1 ]
+ ],
+ "extend": { "flags": [ "NEVER_JAMS" ] }
+ },
+@@ -533,11 +533,11 @@
+ [ "brass catcher", 1 ],
+ [ "grip", 1 ],
+ [ "mechanism", 4 ],
+- [ "rail mount", 1 ],
+- [ "sights mount", 1 ],
++ [ "rail", 1 ],
++ [ "sights", 1 ],
+ [ "sling", 1 ],
+ [ "stock", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "underbarrel", 1 ]
+ ],
+ "flags": [ "RELOAD_ONE", "RELOAD_EJECT", "NEVER_JAMS" ]
+ },
+@@ -562,14 +562,14 @@
+ [ "accessories", 4 ],
+ [ "bore", 1 ],
+ [ "brass catcher", 1 ],
+- [ "grip mount", 1 ],
++ [ "grip", 1 ],
+ [ "mechanism", 2 ],
+ [ "muzzle", 1 ],
+- [ "rail mount", 1 ],
+- [ "sights mount", 1 ],
++ [ "rail", 1 ],
++ [ "sights", 1 ],
+ [ "sling", 1 ],
+ [ "stock", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "underbarrel", 1 ]
+ ],
+ "flags": [ "RELOAD_ONE" ]
+ },
+@@ -595,11 +595,11 @@
+ [ "accessories", 2 ],
+ [ "bore", 1 ],
+ [ "brass catcher", 1 ],
+- [ "grip mount", 1 ],
++ [ "grip", 1 ],
+ [ "mechanism", 4 ],
+ [ "muzzle", 1 ],
+ [ "underbarrel", 2 ],
+- [ "rail mount", 1 ],
++ [ "rail", 1 ],
+ [ "sights", 1 ],
+ [ "sling", 1 ]
+ ],
+@@ -628,9 +628,9 @@
+ [ "muzzle", 1 ],
+ [ "grip", 1 ],
+ [ "brass catcher", 1 ],
+- [ "rail mount", 1 ],
+- [ "sights mount", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "rail", 1 ],
++ [ "sights", 1 ],
++ [ "underbarrel", 1 ]
+ ],
+ "modes": [ [ "DEFAULT", "semi", 1 ], [ "AUTO", "auto", 5 ] ],
+ "magazines": [ [ "shot", [ "USAS10mag", "USAS20mag" ] ] ]
+@@ -657,14 +657,14 @@
+ "modes": [ [ "DEFAULT", "single", 1 ] ],
+ "valid_mod_locations": [
+ [ "accessories", 2 ],
+- [ "stock mount", 1 ],
++ [ "stock", 1 ],
+ [ "mechanism", 2 ],
+ [ "barrel", 1 ],
+- [ "grip mount", 1 ],
++ [ "grip", 1 ],
+ [ "brass catcher", 1 ],
+- [ "rail mount", 1 ],
+- [ "sights mount", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "rail", 1 ],
++ [ "sights", 1 ],
++ [ "underbarrel", 1 ]
+ ],
+ "flags": [ "RELOAD_ONE" ]
+ },
+@@ -694,9 +694,9 @@
+ [ "muzzle", 1 ],
+ [ "sling", 1 ],
+ [ "brass catcher", 1 ],
+- [ "grip mount", 1 ],
+- [ "rail mount", 1 ],
+- [ "sights mount", 1 ],
++ [ "grip", 1 ],
++ [ "rail", 1 ],
++ [ "sights", 1 ],
+ [ "underbarrel", 1 ]
+ ],
+ "default_mods": [ "sword_bayonet" ],
+diff --git a/data/json/items/gun/shotpaper.json b/data/json/items/gun/shotpaper.json
+index f5cf170037f..27105ff1bfa 100644
+--- a/data/json/items/gun/shotpaper.json
++++ b/data/json/items/gun/shotpaper.json
+@@ -22,12 +22,12 @@
+ [ "accessories", 2 ],
+ [ "barrel", 1 ],
+ [ "muzzle", 1 ],
+- [ "sights mount", 1 ],
++ [ "sights", 1 ],
+ [ "sling", 1 ],
+ [ "stock", 1 ],
+- [ "grip mount", 1 ],
+- [ "rail mount", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "grip", 1 ],
++ [ "rail", 1 ],
++ [ "underbarrel", 1 ]
+ ],
+ "flags": [ "NEVER_JAMS" ]
+ }
+diff --git a/data/json/items/gun/signal_flare.json b/data/json/items/gun/signal_flare.json
+index b359f251261..9592711086c 100644
+--- a/data/json/items/gun/signal_flare.json
++++ b/data/json/items/gun/signal_flare.json
+@@ -17,14 +17,7 @@
+ "durability": 7,
+ "loudness": 40,
+ "clip_size": 1,
+- "valid_mod_locations": [
+- [ "accessories", 4 ],
+- [ "grip", 1 ],
+- [ "stock", 1 ],
+- [ "rail mount", 1 ],
+- [ "sights mount", 1 ],
+- [ "underbarrel mount", 1 ]
+- ],
++ "valid_mod_locations": [ [ "accessories", 4 ], [ "grip", 1 ], [ "stock", 1 ], [ "rail", 1 ], [ "sights", 1 ], [ "underbarrel", 1 ] ],
+ "extend": { "flags": [ "WATERPROOF_GUN", "PYROMANIAC_WEAPON" ] },
+ "faults": [ ]
+ }
+diff --git a/data/json/items/gun/ups.json b/data/json/items/gun/ups.json
+index c291ad20b75..f0936360820 100644
+--- a/data/json/items/gun/ups.json
++++ b/data/json/items/gun/ups.json
+@@ -122,11 +122,11 @@
+ [ "emitter", 1 ],
+ [ "lens", 1 ],
+ [ "sling", 1 ],
+- [ "grip mount", 1 ],
+- [ "rail mount", 1 ],
+- [ "sights mount", 1 ],
+- [ "stock mount", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "grip", 1 ],
++ [ "rail", 1 ],
++ [ "sights", 1 ],
++ [ "stock", 1 ],
++ [ "underbarrel", 1 ]
+ ],
+ "ammo_effects": [ "LASER", "INCENDIARY" ]
+ },
+diff --git a/data/json/items/ranged/crossbows.json b/data/json/items/ranged/crossbows.json
+index 30df24032c4..7626ebfa1f0 100644
+--- a/data/json/items/ranged/crossbows.json
++++ b/data/json/items/ranged/crossbows.json
+@@ -338,14 +338,7 @@
+ "dispersion": 375,
+ "durability": 6,
+ "reload": 800,
+- "valid_mod_locations": [
+- [ "accessories", 4 ],
+- [ "dampening", 1 ],
+- [ "rail mount", 1 ],
+- [ "sights mount", 1 ],
+- [ "underbarrel mount", 1 ],
+- [ "mechanism", 1 ]
+- ]
++ "valid_mod_locations": [ [ "accessories", 4 ], [ "dampening", 1 ], [ "rail", 1 ], [ "sights", 1 ], [ "underbarrel", 1 ], [ "mechanism", 1 ] ]
+ },
+ {
+ "id": "compositecrossbow",
+diff --git a/data/json/items/ranged/pneumatic.json b/data/json/items/ranged/pneumatic.json
+index 3249c93783c..1bbe5f657af 100644
+--- a/data/json/items/ranged/pneumatic.json
++++ b/data/json/items/ranged/pneumatic.json
+@@ -27,9 +27,9 @@
+ [ "sights", 1 ],
+ [ "sling", 1 ],
+ [ "stock", 1 ],
+- [ "grip mount", 1 ],
+- [ "rail mount", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "grip", 1 ],
++ [ "rail", 1 ],
++ [ "underbarrel", 1 ]
+ ]
+ },
+ {
+diff --git a/data/json/items/ranged/spearguns.json b/data/json/items/ranged/spearguns.json
+index a1d95fbe962..13fe8e90d0c 100644
+--- a/data/json/items/ranged/spearguns.json
++++ b/data/json/items/ranged/spearguns.json
+@@ -94,8 +94,8 @@
+ [ "sights", 1 ],
+ [ "sling", 1 ],
+ [ "stock", 1 ],
+- [ "rail mount", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "rail", 1 ],
++ [ "underbarrel", 1 ]
+ ]
+ },
+ {
+diff --git a/data/json/not_really_obsolete.json b/data/json/not_really_obsolete.json
+index b745c6c2840..aa615cfaf2e 100644
+--- a/data/json/not_really_obsolete.json
++++ b/data/json/not_really_obsolete.json
+@@ -148,8 +148,8 @@
+ [ "sights", 1 ],
+ [ "sling", 1 ],
+ [ "stock", 1 ],
+- [ "rail mount", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "rail", 1 ],
++ [ "underbarrel", 1 ]
+ ],
+ "ammo_effects": [ "PLASMA", "EXPLOSIVE", "FLAME" ]
+ },
+diff --git a/data/json/obsoletion/items.json b/data/json/obsoletion/items.json
+index 74d09d98e1c..95c7d704106 100644
+--- a/data/json/obsoletion/items.json
++++ b/data/json/obsoletion/items.json
+@@ -386,7 +386,7 @@
+ "range": -2,
+ "dispersion": 300,
+ "clip_size": 100,
+- "valid_mod_locations": [ [ "sling", 1 ], [ "stock", 1 ], [ "rail mount", 1 ] ],
++ "valid_mod_locations": [ [ "sling", 1 ], [ "stock", 1 ], [ "rail", 1 ] ],
+ "relative": { "reload": 4 }
+ },
+ {
+@@ -461,7 +461,7 @@
+ [ "rail", 1 ],
+ [ "sights", 1 ],
+ [ "stock", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "underbarrel", 1 ]
+ ],
+ "ammo_effects": [ "LASER", "INCENDIARY" ],
+ "flags": [ "NO_UNLOAD" ]
+@@ -1246,9 +1246,9 @@
+ [ "muzzle", 1 ],
+ [ "sights", 1 ],
+ [ "sling", 1 ],
+- [ "rail mount", 1 ],
+- [ "stock mount", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "rail", 1 ],
++ [ "stock", 1 ],
++ [ "underbarrel", 1 ]
+ ],
+ "blackpowder_tolerance": 60,
+ "relative": { "durability": -3 },
+@@ -1915,8 +1915,8 @@
+ [ "sights", 1 ],
+ [ "sling", 1 ],
+ [ "stock", 1 ],
+- [ "rail mount", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "rail", 1 ],
++ [ "underbarrel", 1 ]
+ ]
+ },
+ {
+@@ -1943,7 +1943,7 @@
+ "durability": 7,
+ "clip_size": 1,
+ "reload": 800,
+- "valid_mod_locations": [ [ "sling", 1 ], [ "grip mount", 1 ], [ "rail mount", 1 ], [ "sights mount", 1 ], [ "underbarrel mount", 1 ] ]
++ "valid_mod_locations": [ [ "sling", 1 ], [ "grip", 1 ], [ "rail", 1 ], [ "sights", 1 ], [ "underbarrel", 1 ] ]
+ },
+ {
+ "id": "coilgun",
+@@ -1974,8 +1974,8 @@
+ [ "sights", 1 ],
+ [ "sling", 1 ],
+ [ "stock", 1 ],
+- [ "rail mount", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "rail", 1 ],
++ [ "underbarrel", 1 ]
+ ],
+ "magazines": [ [ "nail", [ "nailmag" ] ] ]
+ },
+@@ -1999,8 +1999,8 @@
+ [ "sights", 1 ],
+ [ "sling", 1 ],
+ [ "stock", 1 ],
+- [ "rail mount", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "rail", 1 ],
++ [ "underbarrel", 1 ]
+ ],
+ "magazines": [ [ "nail", [ "nailmag" ] ] ],
+ "relative": { "weight": 1000, "volume": 6, "range": 3, "ranged_damage": { "damage_type": "stab", "amount": 4 } },
+diff --git a/data/json/items/gunmod/mount.json b/data/json/obsoletion/mount.json
+similarity index 100%
+rename from data/json/items/gunmod/mount.json
+rename to data/json/obsoletion/mount.json
+diff --git a/data/json/obsoletion/recipes.json b/data/json/obsoletion/recipes.json
+index 9bd16374c34..ae6d33169e4 100644
+--- a/data/json/obsoletion/recipes.json
++++ b/data/json/obsoletion/recipes.json
+@@ -3239,6 +3239,41 @@
+ "result": "linuxtshirtuncraft",
+ "obsolete": true
+ },
++ {
++ "type": "recipe",
++ "result": "grip_mount",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "stock_mount",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "underbarrel_mount",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "rail_mount",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "sights_mount_pistol",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "sights_mount_launcher",
++ "obsolete": true
++ },
++ {
++ "type": "recipe",
++ "result": "sights_mount",
++ "obsolete": true
++ },
+ {
+ "type": "recipe",
+ "result": "welder_crude",
+diff --git a/data/json/recipes/weapon/mods.json b/data/json/recipes/weapon/mods.json
+index 1ac272e0e65..059185de546 100644
+--- a/data/json/recipes/weapon/mods.json
++++ b/data/json/recipes/weapon/mods.json
+@@ -738,188 +738,6 @@
+ "tools": [ [ [ "large_repairkit", 25 ], [ "small_repairkit", 45 ] ] ],
+ "components": [ [ [ "offset_sights", 1 ] ], [ [ "scrap", 1 ] ], [ [ "plastic_chunk", 1 ] ] ]
+ },
+- {
+- "result": "sights_mount",
+- "type": "recipe",
+- "category": "CC_WEAPON",
+- "subcategory": "CSC_WEAPON_MODS",
+- "skill_used": "fabrication",
+- "difficulty": 3,
+- "skills_required": [ [ "gun", 4 ] ],
+- "time": "30 m",
+- "book_learn": [
+- [ "mag_guns", 4 ],
+- [ "mag_pistol", 4 ],
+- [ "mag_shotgun", 4 ],
+- [ "mag_smg", 4 ],
+- [ "mag_rifle", 4 ],
+- [ "manual_gun", 4 ],
+- [ "manual_pistol", 4 ],
+- [ "manual_shotgun", 4 ],
+- [ "manual_smg", 4 ],
+- [ "manual_rifle", 4 ]
+- ],
+- "using": [ [ "soldering_standard", 15 ] ],
+- "qualities": [ { "id": "HAMMER_FINE", "level": 1 }, { "id": "SAW_M_FINE", "level": 1 } ],
+- "tools": [ [ [ "large_repairkit", 10 ], [ "small_repairkit", 30 ] ] ],
+- "components": [ [ [ "scrap", 1 ] ], [ [ "plastic_chunk", 1 ] ] ]
+- },
+- {
+- "result": "sights_mount_launcher",
+- "type": "recipe",
+- "category": "CC_WEAPON",
+- "subcategory": "CSC_WEAPON_MODS",
+- "skill_used": "fabrication",
+- "difficulty": 3,
+- "skills_required": [ [ "gun", 4 ] ],
+- "time": "30 m",
+- "book_learn": [
+- [ "mag_guns", 4 ],
+- [ "mag_pistol", 4 ],
+- [ "mag_shotgun", 4 ],
+- [ "mag_smg", 4 ],
+- [ "mag_rifle", 4 ],
+- [ "manual_gun", 4 ],
+- [ "manual_pistol", 4 ],
+- [ "manual_shotgun", 4 ],
+- [ "manual_smg", 4 ],
+- [ "manual_rifle", 4 ]
+- ],
+- "using": [ [ "soldering_standard", 15 ] ],
+- "qualities": [ { "id": "HAMMER_FINE", "level": 1 }, { "id": "SAW_M_FINE", "level": 1 } ],
+- "tools": [ [ [ "large_repairkit", 10 ], [ "small_repairkit", 30 ] ] ],
+- "components": [ [ [ "scrap", 1 ] ], [ [ "plastic_chunk", 1 ] ] ]
+- },
+- {
+- "result": "sights_mount_pistol",
+- "type": "recipe",
+- "category": "CC_WEAPON",
+- "subcategory": "CSC_WEAPON_MODS",
+- "skill_used": "fabrication",
+- "difficulty": 3,
+- "skills_required": [ [ "gun", 4 ] ],
+- "time": "30 m",
+- "book_learn": [
+- [ "mag_guns", 4 ],
+- [ "mag_pistol", 4 ],
+- [ "mag_shotgun", 4 ],
+- [ "mag_smg", 4 ],
+- [ "mag_rifle", 4 ],
+- [ "manual_gun", 4 ],
+- [ "manual_pistol", 4 ],
+- [ "manual_shotgun", 4 ],
+- [ "manual_smg", 4 ],
+- [ "manual_rifle", 4 ]
+- ],
+- "using": [ [ "soldering_standard", 15 ] ],
+- "qualities": [ { "id": "HAMMER_FINE", "level": 1 }, { "id": "SAW_M_FINE", "level": 1 } ],
+- "tools": [ [ [ "large_repairkit", 10 ], [ "small_repairkit", 30 ] ] ],
+- "components": [ [ [ "scrap", 1 ] ], [ [ "plastic_chunk", 1 ] ] ]
+- },
+- {
+- "result": "rail_mount",
+- "type": "recipe",
+- "category": "CC_WEAPON",
+- "subcategory": "CSC_WEAPON_MODS",
+- "skill_used": "fabrication",
+- "difficulty": 3,
+- "skills_required": [ [ "gun", 4 ] ],
+- "time": "30 m",
+- "book_learn": [
+- [ "mag_guns", 4 ],
+- [ "mag_pistol", 4 ],
+- [ "mag_shotgun", 4 ],
+- [ "mag_smg", 4 ],
+- [ "mag_rifle", 4 ],
+- [ "manual_gun", 4 ],
+- [ "manual_pistol", 4 ],
+- [ "manual_shotgun", 4 ],
+- [ "manual_smg", 4 ],
+- [ "manual_rifle", 4 ]
+- ],
+- "using": [ [ "soldering_standard", 15 ] ],
+- "qualities": [ { "id": "HAMMER_FINE", "level": 1 }, { "id": "SAW_M_FINE", "level": 1 } ],
+- "tools": [ [ [ "large_repairkit", 10 ], [ "small_repairkit", 30 ] ] ],
+- "components": [ [ [ "scrap", 1 ] ], [ [ "plastic_chunk", 1 ] ] ]
+- },
+- {
+- "result": "underbarrel_mount",
+- "type": "recipe",
+- "category": "CC_WEAPON",
+- "subcategory": "CSC_WEAPON_MODS",
+- "skill_used": "fabrication",
+- "difficulty": 3,
+- "skills_required": [ [ "gun", 4 ] ],
+- "time": "30 m",
+- "book_learn": [
+- [ "mag_guns", 4 ],
+- [ "mag_pistol", 4 ],
+- [ "mag_shotgun", 4 ],
+- [ "mag_smg", 4 ],
+- [ "mag_rifle", 4 ],
+- [ "manual_gun", 4 ],
+- [ "manual_pistol", 4 ],
+- [ "manual_shotgun", 4 ],
+- [ "manual_smg", 4 ],
+- [ "manual_rifle", 4 ]
+- ],
+- "using": [ [ "soldering_standard", 15 ] ],
+- "qualities": [ { "id": "HAMMER_FINE", "level": 1 }, { "id": "SAW_M_FINE", "level": 1 } ],
+- "tools": [ [ [ "large_repairkit", 10 ], [ "small_repairkit", 30 ] ] ],
+- "components": [ [ [ "scrap", 1 ] ], [ [ "plastic_chunk", 1 ] ] ]
+- },
+- {
+- "result": "stock_mount",
+- "type": "recipe",
+- "category": "CC_WEAPON",
+- "subcategory": "CSC_WEAPON_MODS",
+- "skill_used": "fabrication",
+- "difficulty": 3,
+- "skills_required": [ [ "gun", 5 ] ],
+- "time": "30 m",
+- "book_learn": [
+- [ "mag_guns", 4 ],
+- [ "mag_pistol", 4 ],
+- [ "mag_shotgun", 4 ],
+- [ "mag_smg", 4 ],
+- [ "mag_rifle", 4 ],
+- [ "manual_gun", 4 ],
+- [ "manual_pistol", 4 ],
+- [ "manual_shotgun", 4 ],
+- [ "manual_smg", 4 ],
+- [ "manual_rifle", 4 ]
+- ],
+- "using": [ [ "soldering_standard", 15 ] ],
+- "qualities": [ { "id": "HAMMER_FINE", "level": 1 }, { "id": "SAW_M_FINE", "level": 1 } ],
+- "tools": [ [ [ "large_repairkit", 10 ], [ "small_repairkit", 30 ] ] ],
+- "components": [ [ [ "scrap", 3 ] ] ]
+- },
+- {
+- "result": "grip_mount",
+- "type": "recipe",
+- "category": "CC_WEAPON",
+- "subcategory": "CSC_WEAPON_MODS",
+- "skill_used": "fabrication",
+- "difficulty": 3,
+- "skills_required": [ [ "gun", 5 ] ],
+- "time": "30 m",
+- "book_learn": [
+- [ "mag_guns", 4 ],
+- [ "mag_pistol", 4 ],
+- [ "mag_shotgun", 4 ],
+- [ "mag_smg", 4 ],
+- [ "mag_rifle", 4 ],
+- [ "manual_gun", 4 ],
+- [ "manual_pistol", 4 ],
+- [ "manual_shotgun", 4 ],
+- [ "manual_smg", 4 ],
+- [ "manual_rifle", 4 ]
+- ],
+- "using": [ [ "soldering_standard", 15 ] ],
+- "qualities": [ { "id": "HAMMER_FINE", "level": 1 }, { "id": "SAW_M_FINE", "level": 1 } ],
+- "tools": [ [ [ "large_repairkit", 10 ], [ "small_repairkit", 30 ] ] ],
+- "components": [ [ [ "scrap", 1 ] ], [ [ "plastic_chunk", 3 ] ] ]
+- },
+ {
+ "type": "recipe",
+ "result": "tele_sight",
+diff --git a/data/mods/Aftershock/items/obsolete.json b/data/mods/Aftershock/items/obsolete.json
+index 17f2bb22534..f6806ad84f2 100644
+--- a/data/mods/Aftershock/items/obsolete.json
++++ b/data/mods/Aftershock/items/obsolete.json
+@@ -356,8 +356,8 @@
+ [ "sling", 1 ],
+ [ "stock", 1 ],
+ [ "sights", 1 ],
+- [ "rail mount", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "rail", 1 ],
++ [ "underbarrel", 1 ]
+ ],
+ "ammo_effects": [ "TRAIL" ]
+ }
+diff --git a/data/mods/Aftershock/items/weapons.json b/data/mods/Aftershock/items/weapons.json
+index 77652ecf40d..be8ba0b5b91 100644
+--- a/data/mods/Aftershock/items/weapons.json
++++ b/data/mods/Aftershock/items/weapons.json
+@@ -250,11 +250,11 @@
+ [ "emitter", 1 ],
+ [ "lens", 1 ],
+ [ "sling", 1 ],
+- [ "grip mount", 1 ],
+- [ "rail mount", 1 ],
+- [ "sights mount", 1 ],
+- [ "stock mount", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "grip", 1 ],
++ [ "rail", 1 ],
++ [ "sights", 1 ],
++ [ "stock", 1 ],
++ [ "underbarrel", 1 ]
+ ],
+ "ammo_effects": [ "LASER", "INCENDIARY" ],
+ "flags": [ "NO_UNLOAD", "NON_FOULING", "NEEDS_NO_LUBE" ]
+diff --git a/data/mods/Generic_Guns/firearms/obsolete.json b/data/mods/Generic_Guns/firearms/obsolete.json
+index fcf88b10709..5345ecfa464 100644
+--- a/data/mods/Generic_Guns/firearms/obsolete.json
++++ b/data/mods/Generic_Guns/firearms/obsolete.json
+@@ -32,10 +32,10 @@
+ [ "muzzle", 1 ],
+ [ "sling", 1 ],
+ [ "stock", 1 ],
+- [ "grip mount", 1 ],
+- [ "rail mount", 1 ],
+- [ "sights mount", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "grip", 1 ],
++ [ "rail", 1 ],
++ [ "sights", 1 ],
++ [ "underbarrel", 1 ]
+ ],
+ "magazines": [
+ [ "ammo_pistol", [ "pistol_magnum_mag", "pistol_magnum_mag_hc" ] ],
+diff --git a/data/mods/Magiclysm/items/enchanted_ranged.json b/data/mods/Magiclysm/items/enchanted_ranged.json
+index 3701be94ecf..c5f2bcc1bee 100644
+--- a/data/mods/Magiclysm/items/enchanted_ranged.json
++++ b/data/mods/Magiclysm/items/enchanted_ranged.json
+@@ -51,10 +51,10 @@
+ [ "mechanism", 1 ],
+ [ "barrel", 1 ],
+ [ "grip", 1 ],
+- [ "rail mount", 1 ],
++ [ "rail", 1 ],
+ [ "sights", 1 ],
+- [ "stock mount", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "stock", 1 ],
++ [ "underbarrel", 1 ]
+ ],
+ "flags": [ "RELOAD_ONE", "NEVER_JAMS", "RELOAD_EJECT" ]
+ },
+diff --git a/data/mods/No_Hope/Items/guns.json b/data/mods/No_Hope/Items/guns.json
+index 67194e3f282..fe93f821dec 100644
+--- a/data/mods/No_Hope/Items/guns.json
++++ b/data/mods/No_Hope/Items/guns.json
+@@ -28,11 +28,11 @@
+ [ "emitter", 1 ],
+ [ "lens", 1 ],
+ [ "sling", 1 ],
+- [ "grip mount", 1 ],
+- [ "rail mount", 1 ],
+- [ "sights mount", 1 ],
+- [ "stock mount", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "grip", 1 ],
++ [ "rail", 1 ],
++ [ "sights", 1 ],
++ [ "stock", 1 ],
++ [ "underbarrel", 1 ]
+ ],
+ "ammo_effects": [ "LASER", "INCENDIARY" ],
+ "flags": [ "NO_UNLOAD", "NON_FOULING", "NEEDS_NO_LUBE" ]
+@@ -88,8 +88,8 @@
+ [ "sights", 1 ],
+ [ "sling", 1 ],
+ [ "stock", 1 ],
+- [ "rail mount", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "rail", 1 ],
++ [ "underbarrel", 1 ]
+ ],
+ "ammo_effects": [ "PLASMA", "EXPLOSIVE", "FLAME" ],
+ "flags": [ "USE_UPS", "NO_UNLOAD", "PYROMANIAC_WEAPON", "NEVER_JAMS" ]
+@@ -140,14 +140,7 @@
+ "blackpowder_tolerance": 56,
+ "clip_size": 6,
+ "built_in_mods": [ "lead_holo_sight", "lead_laser_sight" ],
+- "valid_mod_locations": [
+- [ "accessories", 2 ],
+- [ "sights", 1 ],
+- [ "underbarrel", 1 ],
+- [ "grip mount", 1 ],
+- [ "rail mount", 1 ],
+- [ "stock mount", 1 ]
+- ]
++ "valid_mod_locations": [ [ "accessories", 2 ], [ "sights", 1 ], [ "underbarrel", 1 ], [ "grip", 1 ], [ "rail", 1 ], [ "stock", 1 ] ]
+ },
+ {
+ "id": "l_long_45",
+@@ -182,9 +175,9 @@
+ [ "sling", 1 ],
+ [ "underbarrel", 1 ],
+ [ "muzzle", 1 ],
+- [ "grip mount", 1 ],
+- [ "rail mount", 1 ],
+- [ "stock mount", 1 ]
++ [ "grip", 1 ],
++ [ "rail", 1 ],
++ [ "stock", 1 ]
+ ],
+ "faults": [ "fault_gun_blackpowder", "fault_gun_dirt" ],
+ "flags": [ "RELOAD_ONE" ]
+@@ -238,9 +231,9 @@
+ [ "sights", 1 ],
+ [ "underbarrel", 1 ],
+ [ "muzzle", 1 ],
+- [ "grip mount", 1 ],
+- [ "rail mount", 1 ],
+- [ "stock mount", 1 ]
++ [ "grip", 1 ],
++ [ "rail", 1 ],
++ [ "stock", 1 ]
+ ],
+ "flags": [ "DURABLE_MELEE" ]
+ },
+@@ -487,8 +480,8 @@
+ [ "sights", 1 ],
+ [ "sling", 1 ],
+ [ "stock", 1 ],
+- [ "rail mount", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "rail", 1 ],
++ [ "underbarrel", 1 ]
+ ]
+ },
+ {
+@@ -526,8 +519,8 @@
+ [ "sights", 1 ],
+ [ "sling", 1 ],
+ [ "stock", 1 ],
+- [ "rail mount", 1 ],
+- [ "underbarrel mount", 1 ]
++ [ "rail", 1 ],
++ [ "underbarrel", 1 ]
+ ]
+ },
+ {
+diff --git a/tests/ranged_burst_balance_test.cpp b/tests/ranged_burst_balance_test.cpp
+index d6f787ba11e..44e261799ce 100644
+--- a/tests/ranged_burst_balance_test.cpp
++++ b/tests/ranged_burst_balance_test.cpp
+@@ -102,7 +102,7 @@ TEST_CASE( "average_burst_bipod", "[ranged] [balance]" )
+ standard_npc shooter( "Shooter", shooter_pos, {}, 5, 10, 8, 8, 8 );
+ check_burst_penalty( shooter, "m249", {}, 40, true );
+ check_burst_penalty( shooter, "m240", {}, 90, true );
+- check_burst_penalty( shooter, "m2browning", {"underbarrel_mount", "bipod"}, 160, true );
++ check_burst_penalty( shooter, "m2browning", {"bipod"}, 160, true );
+ check_burst_penalty( shooter, "m1918", {"bipod"}, 160, true );
+ }
+
+--
+2.43.0
+
diff --git a/revert-31_restore-vague-nether-healing.patch b/revert-31_restore-vague-nether-healing.patch
new file mode 100644
index 0000000..e7b03cf
--- /dev/null
+++ b/revert-31_restore-vague-nether-healing.patch
@@ -0,0 +1,51 @@
+
+---
+ src/monster.cpp | 34 +++---
+ 13 files changed, 184 insertions(+), 44 deletions(-)
+
+diff --git a/src/monster.cpp b/src/monster.cpp
+index 665d82321e8..c8c7d4d1c2b 100644
+--- a/src/monster.cpp
++++ b/src/monster.cpp
+@@ -2819,25 +2825,23 @@ void monster::process_effects_internal()
+ regeneration_amount = 0;
+ }
+ const int healed_amount = heal( round( regeneration_amount ) );
+- if( healed_amount > 0 && one_in( 2 ) && g->u.sees( *this ) ) {
+- add_msg( m_debug, ( "Regen: %s" ), healed_amount );
+- std::string healing_format_string;
+- if( healed_amount >= 50 ) {
+- healing_format_string = _( "The %s is visibly regenerating!" );
+- } else if( healed_amount >= 10 ) {
+- healing_format_string = _( "The %s seems a little healthier." );
+- } else {
+- healing_format_string = _( "The %s is healing slowly." );
+- }
+- add_msg( m_warning, healing_format_string, name() );
++ if( healed_amount > 0 && g->u.sees( *this ) ) {
++ add_msg( m_warning, _( "The %1$s regenerates %2$s damage." ), name(), healed_amount );
+ }
+
+ if( type->regenerates_in_dark ) {
+ const float light = g->m.ambient_light_at( pos() );
+- // Magic number 10000 was chosen so that a floodlight prevents regeneration in a range of 20 tiles
+- if( heal( static_cast<int>( 50.0 * std::exp( - light * light / 10000 ) ) > 0 && one_in( 2 ) &&
+- g->u.sees( *this ) ) ) {
+- add_msg( m_warning, _( "The %s uses the darkness to regenerate." ), name() );
++ add_msg( m_debug, _( "%1$s local light level: %2$s" ), name(), light );
++ // Requires standing in a properly dark tile, scales as it gets darker
++ if( light < 11.0f && one_in( 2 ) && hp < type->hp ) {
++ // Regen will max out at 50 at 6.0 light (barely able to craft), or top off to max HP
++ int dark_regen_amount = std::min( static_cast<int>( 110.0f - ( light * 10.0f ) ), type->hp - hp );
++ dark_regen_amount = std::min( dark_regen_amount, 50 );
++ heal( round( dark_regen_amount ) );
++ if( dark_regen_amount > 0 && g->u.sees( *this ) ) {
++ add_msg( m_warning, _( "The %1$s uses the darkness to regenerate %2$s damage." ), name(),
++ dark_regen_amount );
++ }
+ }
+ }
+
+--
+2.43.0
+
diff --git a/0.F_backport-radio-can-use-ups.patch b/src-01_radio-can-use-ups.patch
index ee146e5..d75e8dc 100644
--- a/0.F_backport-radio-can-use-ups.patch
+++ b/src-01_radio-can-use-ups.patch
@@ -1,14 +1,6 @@
--- a/src/iuse.cpp
+++ b/src/iuse.cpp
-@@ -289,6 +289,7 @@
- static const std::string flag_HEATS_FOOD( "HEATS_FOOD" );
- static const std::string flag_PLANT( "PLANT" );
- static const std::string flag_PLOWABLE( "PLOWABLE" );
-+static const std::string flag_USE_UPS( "USE_UPS" );
-
- // how many characters per turn of radio
- static constexpr int RADIO_PER_TURN = 25;
-@@ -2162,7 +2163,8 @@
+@@ -2205,7 +2206,8 @@
}
} else { // Activated
int ch = 1;
@@ -18,7 +10,7 @@
ch = uilist( _( "Radio:" ), {
_( "Scan" ), _( "Turn off" )
} );
-@@ -4082,7 +4084,8 @@
+@@ -4074,7 +4076,8 @@
if( t ) { // Effects while simply on
} else {
@@ -26,9 +18,9 @@
+ if( !it->units_sufficient( *p ) || !( it->has_flag( flag_USE_UPS ) &&
+ p->has_enough_charges( *it, false ) ) ) {
p->add_msg_if_player( m_info, _( "Your tactical tonfa is out of power." ) );
- it->convert( "shocktonfa_off" ).active = false;
- } else {
-@@ -4107,7 +4110,8 @@
+ it->convert( itype_shocktonfa_off );
+ it->active = false;
+@@ -4099,7 +4102,8 @@
int iuse::mp3( player *p, item *it, bool, const tripoint & )
{
// TODO: avoid item id hardcoding to make this function usable for pure json-defined devices.
@@ -36,9 +28,9 @@
+ if( !it->units_sufficient( *p ) || !( it->has_flag( flag_USE_UPS ) &&
+ p->has_enough_charges( *it, false ) ) ) {
p->add_msg_if_player( m_info, _( "The device's batteries are dead." ) );
- } else if( p->has_active_item( "mp3_on" ) || p->has_active_item( "smartphone_music" ) ||
- p->has_active_item( "afs_atomic_smartphone_music" ) ||
-@@ -6367,9 +6371,12 @@
+ } else if( p->has_active_item( itype_mp3_on ) || p->has_active_item( itype_smartphone_music ) ||
+ p->has_active_item( itype_afs_atomic_smartphone_music ) ||
+@@ -6366,9 +6370,12 @@
int iuse::einktabletpc( player *p, item *it, bool t, const tripoint &pos )
{
if( t ) {
diff --git a/jc_ammo-loudness-ap-times-2.patch b/src-02_ammo-loudness-ap-times-2.patch
index 3def080..3def080 100644
--- a/jc_ammo-loudness-ap-times-2.patch
+++ b/src-02_ammo-loudness-ap-times-2.patch
diff --git a/src-03_allow-bio-firestarter-on-smoker.patch b/src-03_allow-bio-firestarter-on-smoker.patch
new file mode 100644
index 0000000..5210727
--- /dev/null
+++ b/src-03_allow-bio-firestarter-on-smoker.patch
@@ -0,0 +1,40 @@
+--- a/src/iexamine.cpp
++++ b/src/iexamine.cpp
+@@ -2476,7 +2476,10 @@
+ return;
+ }
+
+- if( !p.has_charges( itype_fire, 1 ) ) {
++ const bool has_bionic_firestarter = p.has_bionic( bio_lighter ) &&
++ p.enough_power_for( bio_lighter );
++
++ if( !has_bionic_firestarter && !p.has_charges( itype_fire, 1 ) ) {
+ add_msg( _( "This kiln is ready to be fired, but you have no fire source." ) );
+ return;
+ } else {
+@@ -4950,10 +4953,21 @@
+ return;
+ }
+
+- p.use_charges( itype_fire, 1 );
+- for( auto &it : here.i_at( examp ) ) {
+- if( it->has_flag( flag_SMOKABLE ) ) {
+- it->set_flag( flag_PROCESSING );
++ const bool has_bionic_firestarter = p.has_bionic( bio_lighter ) &&
++ p.enough_power_for( bio_lighter );
++
++ if( has_bionic_firestarter ) {
++ for( auto &it : here.i_at( examp ) ) {
++ if( it->has_flag( flag_SMOKABLE ) ) {
++ it->set_flag( flag_PROCESSING );
++ }
++ }
++ } else {
++ p.use_charges( itype_fire, 1 );
++ for( auto &it : here.i_at( examp ) ) {
++ if( it->has_flag( flag_SMOKABLE ) ) {
++ it->set_flag( flag_PROCESSING );
++ }
+ }
+ }
+ here.furn_set( examp, next_smoker_type );
diff --git a/jc_stop-non-faction-npc-sleep-depirvation.patch b/src-04_stop-non-faction-npc-sleep-depirvation.patch
index fb8941c..fb8941c 100644
--- a/jc_stop-non-faction-npc-sleep-depirvation.patch
+++ b/src-04_stop-non-faction-npc-sleep-depirvation.patch
diff --git a/jc_stop-non-faction-npc-malnourishment.patch b/src-05_stop-non-faction-npc-malnourishment.patch
index 33781d7..096a5a8 100644
--- a/jc_stop-non-faction-npc-malnourishment.patch
+++ b/src-05_stop-non-faction-npc-malnourishment.patch
@@ -1,8 +1,8 @@
--- a/src/npcmove.cpp
+++ b/src/npcmove.cpp
@@ -116,6 +116,14 @@
- static const efftype_id effect_onfire( "onfire" );
- static const efftype_id effect_stunned( "stunned" );
+ static const itype_id itype_oxygen_tank( "oxygen_tank" );
+ static const itype_id itype_UPS( "UPS" );
+const vitamin_id vitamin_calcium( "calcium" );
+const vitamin_id vitamin_iron( "iron" );
@@ -15,11 +15,10 @@
static constexpr float NPC_DANGER_VERY_LOW = 5.0f;
static constexpr float NPC_DANGER_MAX = 150.0f;
static constexpr float MAX_FLOAT = 5000000000.0f;
-@@ -3856,6 +3864,14 @@
+@@ -3856,6 +3864,13 @@
// TODO: Remove this and let player "exploit" hungry NPCs
set_hunger( 0 );
set_thirst( 0 );
-+ set_stored_kcal( get_healthy_kcal() );
+ vitamin_set( vitamin_calcium, 0 );
+ vitamin_set( vitamin_iron, 0 );
+ vitamin_set( vitamin_vitA, 0 );
@@ -28,5 +27,5 @@
+ vitamin_set( vitamin_mutant_toxin, 0 );
+ vitamin_set( vitamin_bad_food, 0 );
}
- return false;
- }
+ } else {
+ for( const auto &food_item : inv_food ) {
diff --git a/jc_stop-sleeping-on-tables.patch b/src-06_stop-sleeping-on-tables.patch
index d60e950..eb3dc41 100644
--- a/jc_stop-sleeping-on-tables.patch
+++ b/src-06_stop-sleeping-on-tables.patch
@@ -1,6 +1,6 @@
---- a/src/character.cpp
-+++ b/src/character.cpp
-@@ -5328,20 +5328,24 @@
+--- a/src/character_functions.cpp
++++ b/src/character_functions.cpp
+@@ -215,20 +215,24 @@
}
}
// Not in a vehicle, start checking furniture/terrain/traps at this point in decreasing order
@@ -28,7 +28,7 @@
- comfort += 0 + trap_at_pos.comfort;
} else {
// Not a comfortable sleeping spot
- comfort -= g->m.move_cost( p );
+ comfort -= here.move_cost( p );
--- a/src/mapdata.h
+++ b/src/mapdata.h
@@ -407,7 +407,7 @@
diff --git a/src-07_allow-hacker-laptop.patch b/src-07_allow-hacker-laptop.patch
new file mode 100644
index 0000000..07f44ba
--- /dev/null
+++ b/src-07_allow-hacker-laptop.patch
@@ -0,0 +1,29 @@
+--- a/src/game.cpp
++++ b/src/game.cpp
+@@ -224,6 +224,7 @@
+
+ static const itype_id itype_battery( "battery" );
+ static const itype_id itype_grapnel( "grapnel" );
++static const itype_id itype_hackerlaptop( "hacker_laptop" );
+ static const itype_id itype_holybook_bible1( "holybook_bible1" );
+ static const itype_id itype_holybook_bible2( "holybook_bible2" );
+ static const itype_id itype_holybook_bible3( "holybook_bible3" );
+@@ -2501,7 +2502,8 @@
+ remoteveh_cache_time = calendar::turn;
+ std::stringstream remote_veh_string( u.get_value( "remote_controlling_vehicle" ) );
+ if( remote_veh_string.str().empty() ||
+- ( !u.has_active_bionic( bio_remote ) && !u.has_active_item( itype_remotevehcontrol ) ) ) {
++ ( !u.has_active_bionic( bio_remote ) && !u.has_active_item( itype_remotevehcontrol )
++ && !u.has_active_item( itype_hackerlaptop ) ) ) {
+ remoteveh_cache = nullptr;
+ } else {
+ tripoint vp;
+@@ -2521,7 +2523,7 @@
+ remoteveh_cache_time = calendar::turn;
+ remoteveh_cache = veh;
+ if( veh != nullptr && !u.has_active_bionic( bio_remote ) &&
+- !u.has_active_item( itype_remotevehcontrol ) ) {
++ !u.has_active_item( itype_remotevehcontrol ) && !u.has_active_item( itype_hackerlaptop ) ) {
+ debugmsg( "Tried to set remote vehicle without bio_remote or remotevehcontrol" );
+ veh = nullptr;
+ }
diff --git a/src-08_more-military-base-overmap.patch b/src-08_more-military-base-overmap.patch
new file mode 100644
index 0000000..f2bc3cb
--- /dev/null
+++ b/src-08_more-military-base-overmap.patch
@@ -0,0 +1,257 @@
+--- a/data/json/overmap/overmap_terrain/overmap_terrain_military.json
++++ b/data/json/overmap/overmap_terrain/overmap_terrain_military.json
+@@ -251,14 +251,10 @@
+ "mil_base_6b",
+ "mil_base_7b",
+ "mil_base_8b",
+- "mil_base_1c",
+ "mil_base_2c",
+ "mil_base_3c",
+ "mil_base_8c",
+ "mil_base_1d",
+- "mil_base_5d",
+- "mil_base_6d",
+- "mil_base_7d",
+ "mil_base_8d",
+ "mil_base_1e",
+ "mil_base_1f",
+@@ -267,17 +263,13 @@
+ "mil_base_2h",
+ "mil_base_1i",
+ "mil_base_2i",
+- "mil_base_1j",
+ "mil_base_2j",
+- "mil_base_3j",
+ "mil_base_8j",
+ "mil_base_1k",
+ "mil_base_2k",
+ "mil_base_3k",
+ "mil_base_4k",
+- "mil_base_5k",
+ "mil_base_6k",
+- "mil_base_7k",
+ "mil_base_8k"
+ ],
+ "copy-from": "generic_military_base",
+@@ -287,6 +279,22 @@
+ },
+ {
+ "type": "overmap_terrain",
++ "id": [ "mil_base_1c", "mil_base_1j", "mil_base_3j", "mil_base_5k", "mil_base_6k", "mil_base_7k" ],
++ "copy-from": "generic_military_base",
++ "name": "military base - storage containers",
++ "sym": "#",
++ "color": "yellow"
++ },
++ {
++ "type": "overmap_terrain",
++ "id": [ "mil_base_1c1", "mil_base_1j1", "mil_base_3j1", "mil_base_5k1", "mil_base_6k1", "mil_base_7k1" ],
++ "copy-from": "generic_military_base",
++ "name": "military base - storage container roofs",
++ "sym": "#",
++ "color": "yellow"
++ },
++ {
++ "type": "overmap_terrain",
+ "id": [ "mil_base_5a", "mil_base_6a", "mil_base_7a" ],
+ "copy-from": "generic_military_base",
+ "name": "parking lot",
+@@ -322,70 +330,99 @@
+ "mil_base_3e",
+ "mil_base_5c1",
+ "mil_base_5c",
++ "mil_base_5d1",
++ "mil_base_5d",
+ "mil_base_6c1",
+ "mil_base_6c",
++ "mil_base_6d1",
++ "mil_base_6d",
+ "mil_base_7c1",
+- "mil_base_7c"
++ "mil_base_7c",
++ "mil_base_7d1",
++ "mil_base_7d"
+ ],
+ "copy-from": "generic_military_base",
+- "name": "military base - barracks"
++ "name": "military base - barracks",
++ "color": "light_green"
++ },
++ {
++ "type": "overmap_terrain",
++ "id": [
++ "mil_base_1b1",
++ "mil_base_3b1",
++ "mil_base_5b1",
++ "mil_base_8b1",
++ "mil_base_1g1",
++ "mil_base_8g1",
++ "mil_base_1k1",
++ "mil_base_4k1",
++ "mil_base_8k1"
++ ],
++ "copy-from": "generic_military_base",
++ "name": "military base - watch tower",
++ "sym": "T"
+ },
+ {
+ "type": "overmap_terrain",
+ "id": [ "mil_base_2f1", "mil_base_2f", "mil_base_3f1", "mil_base_3f" ],
+ "copy-from": "generic_military_base",
+- "name": "military base - mess hall"
++ "name": "military base - mess hall",
++ "sym": ">",
++ "color": "pink"
+ },
+ {
+ "type": "overmap_terrain",
+ "id": [ "mil_base_2g1", "mil_base_2g", "mil_base_3g1", "mil_base_3g" ],
+ "copy-from": "generic_military_base",
+- "name": "military base - warehouse"
++ "name": "military base - warehouse",
++ "sym": "w",
++ "color": "light_blue"
+ },
+ {
+ "type": "overmap_terrain",
+ "id": [ "mil_base_3h1", "mil_base_3h" ],
+ "copy-from": "generic_military_base",
+- "name": "military base - communications center"
++ "name": "military base - communications center",
++ "sym": "L",
++ "color": "light_gray"
+ },
+ {
+ "type": "overmap_terrain",
+- "id": [ "mil_base_5e1", "mil_base_5e" ],
++ "id": [ "mil_base_5e1", "mil_base_5e", "mil_base_6e1", "mil_base_6e" ],
+ "copy-from": "generic_military_base",
+- "name": "military base - armory"
++ "name": "military base - armory",
++ "sym": "v"
+ },
+ {
+ "type": "overmap_terrain",
+- "id": [
+- "mil_base_6e1",
+- "mil_base_6e",
+- "mil_base_7e1",
+- "mil_base_7e",
+- "mil_base_8e1",
+- "mil_base_8e",
+- "mil_base_7f1",
+- "mil_base_7f"
+- ],
++ "id": [ "mil_base_7e1", "mil_base_7e", "mil_base_8e1", "mil_base_8e", "mil_base_7f1", "mil_base_7f" ],
+ "copy-from": "generic_military_base",
+- "name": "military base - motor pool"
++ "name": "military base - motor pool",
++ "sym": "O",
++ "color": "white"
+ },
+ {
+ "type": "overmap_terrain",
+ "id": [ "mil_base_5g1", "mil_base_5g" ],
+ "copy-from": "generic_military_base",
+- "name": "military base - command center"
++ "name": "military base - command center",
++ "sym": "<",
++ "color": "light_gray"
+ },
+ {
+ "type": "overmap_terrain",
+ "id": [ "mil_base_5h1", "mil_base_5h", "mil_base_5i1", "mil_base_5i", "mil_base_6i1", "mil_base_6i" ],
+ "copy-from": "generic_military_base",
+- "name": "military base - infirmary"
++ "name": "military base - infirmary",
++ "sym": "+"
+ },
+ {
+ "type": "overmap_terrain",
+ "id": "mil_base_8i",
+ "copy-from": "generic_military_base",
+- "name": "military base - fuel depot"
++ "name": "military base - fuel depot",
++ "sym": "<",
++ "color": "light_blue"
+ },
+ {
+ "type": "overmap_terrain",
+@@ -416,7 +453,7 @@
+ "type": "overmap_terrain",
+ "id": "mil_base_7i",
+ "copy-from": "generic_military_base",
+- "name": "military helipad",
++ "name": "military base - helipad",
+ "sym": "H"
+ },
+ {
+@@ -465,16 +502,11 @@
+ "type": "overmap_terrain",
+ "id": [
+ "mil_base_1a1",
+- "mil_base_1b1",
+- "mil_base_1c1",
+ "mil_base_1d1",
+ "mil_base_1e1",
+ "mil_base_1f1",
+- "mil_base_1g1",
+ "mil_base_1h1",
+ "mil_base_1i1",
+- "mil_base_1j1",
+- "mil_base_1k1",
+ "mil_base_2a1",
+ "mil_base_2b1",
+ "mil_base_2c1",
+@@ -483,9 +515,7 @@
+ "mil_base_2j1",
+ "mil_base_2k1",
+ "mil_base_3a1",
+- "mil_base_3b1",
+ "mil_base_3c1",
+- "mil_base_3j1",
+ "mil_base_3k1",
+ "mil_base_4a1",
+ "mil_base_4b1",
+@@ -497,16 +527,11 @@
+ "mil_base_4h1",
+ "mil_base_4i1",
+ "mil_base_4j1",
+- "mil_base_4k1",
+ "mil_base_5a1",
+- "mil_base_5b1",
+- "mil_base_5d1",
+ "mil_base_5f1",
+ "mil_base_5j1",
+- "mil_base_5k1",
+ "mil_base_6a1",
+ "mil_base_6b1",
+- "mil_base_6d1",
+ "mil_base_6f1",
+ "mil_base_6g1",
+ "mil_base_6h1",
+@@ -514,22 +539,17 @@
+ "mil_base_6k1",
+ "mil_base_7a1",
+ "mil_base_7b1",
+- "mil_base_7d1",
+ "mil_base_7g1",
+ "mil_base_7h1",
+ "mil_base_7i1",
+ "mil_base_7j1",
+- "mil_base_7k1",
+ "mil_base_8a1",
+- "mil_base_8b1",
+ "mil_base_8c1",
+ "mil_base_8d1",
+ "mil_base_8f1",
+- "mil_base_8g1",
+ "mil_base_8h1",
+- "mil_base_8j1",
+- "mil_base_8k1",
+- "mil_base_8i1"
++ "mil_base_8i1",
++ "mil_base_8j1"
+ ],
+ "copy-from": "generic_military_base",
+ "name": "open air",
diff --git a/src-09_npc-eat-from-further-camp.patch b/src-09_npc-eat-from-further-camp.patch
new file mode 100644
index 0000000..ed1442d
--- /dev/null
+++ b/src-09_npc-eat-from-further-camp.patch
@@ -0,0 +1,11 @@
+--- a/src/npcmove.cpp
++++ b/src/npcmove.cpp
+@@ -3817,7 +3817,7 @@
+ Character &player_character = get_player_character();
+ cata::optional<basecamp *> potential_bc;
+ for( const tripoint_abs_omt &camp_pos : player_character.camps ) {
+- if( rl_dist( camp_pos, global_omt_location() ) < 3 ) {
++ if( rl_dist( camp_pos, global_omt_location() ) < 6 ) {
+ potential_bc = overmap_buffer.find_camp( camp_pos.xy() );
+ if( potential_bc ) {
+ break;
diff --git a/src-10_reduced-kcal-during-sleep.patch b/src-10_reduced-kcal-during-sleep.patch
new file mode 100644
index 0000000..20d83f2
--- /dev/null
+++ b/src-10_reduced-kcal-during-sleep.patch
@@ -0,0 +1,13 @@
+--- a/src/character.cpp
++++ b/src/character.cpp
+@@ -4806,6 +4806,10 @@
+ // Multiplied by 2 to account for legacy (bugged to always apply)
+ // bonus for sleeping over 2 hours
+ rates.recovery = 2.0f * ( 1.0f + mutation_value( fatigue_regen_modifier ) );
++ if( !is_hibernating() ) {
++ rates.hunger *= 0.5f;
++ rates.thirst *= 0.5f;
++ }
+ if( is_hibernating() ) {
+ // Hunger and thirst advance *much* more slowly whilst we hibernate.
+ // This will slow calories consumption enough to go through the 7 days of hibernation
diff --git a/src-11_fix-tacoma-farmfield.patch b/src-11_fix-tacoma-farmfield.patch
new file mode 100644
index 0000000..3a3e0ac
--- /dev/null
+++ b/src-11_fix-tacoma-farmfield.patch
@@ -0,0 +1,32 @@
+--- a/src/mission_companion.cpp
++++ b/src/mission_companion.cpp
+@@ -940,12 +940,12 @@
+ void talk_function::field_build_1( npc &p )
+ {
+ Character &player_character = get_player_character();
+- if( player_character.cash < 100000 ) {
++ if( g->u.cash < 100000 ) {
+ popup( _( "I'm sorry, you don't have enough money." ) );
+ return;
+ }
+ p.set_mutation( trait_NPC_CONSTRUCTION_LEV_1 );
+- player_character.cash += -100000;
++ g->u.cash += -100000;
+ const tripoint_abs_omt site =
+ overmap_buffer.find_closest( player_character.global_omt_location(), "ranch_camp_63", 20,
+ false );
+@@ -966,12 +966,12 @@
+ void talk_function::field_build_2( npc &p )
+ {
+ Character &player_character = get_player_character();
+- if( player_character.cash < 550000 ) {
++ if( g->u.cash < 550000 ) {
+ popup( _( "I'm sorry, you don't have enough money." ) );
+ return;
+ }
+ p.set_mutation( trait_NPC_CONSTRUCTION_LEV_2 );
+- player_character.cash += -550000;
++ g->u.cash += -550000;
+ const tripoint_abs_omt site =
+ overmap_buffer.find_closest( player_character.global_omt_location(), "ranch_camp_63", 20,
+ false );
diff --git a/src-12_lower-lockpicking-experience.patch b/src-12_lower-lockpicking-experience.patch
new file mode 100644
index 0000000..375731c
--- /dev/null
+++ b/src-12_lower-lockpicking-experience.patch
@@ -0,0 +1,16 @@
+--- a/src/activity_actor.cpp
++++ b/src/activity_actor.cpp
+@@ -1174,10 +1174,11 @@
+ }
+
+ if( !perfect ) {
++ who.practice( skill_mechanics, 6, 12 );
++ } else {
+ // You don't gain much skill since the item does all the hard work for you
+- xp_gain += std::pow( 2, who.get_skill_level( skill_mechanics ) ) + 1;
++ who.practice( skill_mechanics, 3, 12 );
+ }
+- who.practice( skill_mechanics, xp_gain );
+
+ if( !perfect && g->m.has_flag( "ALARMED", target ) && ( lock_roll + dice( 1, 30 ) ) > pick_roll ) {
+ sounds::sound( who.pos(), 40, sounds::sound_t::alarm, _( "an alarm sound!" ),
diff --git a/src-13_searchlights-with-plut-gen-furn.patch b/src-13_searchlights-with-plut-gen-furn.patch
new file mode 100644
index 0000000..d18ec30
--- /dev/null
+++ b/src-13_searchlights-with-plut-gen-furn.patch
@@ -0,0 +1,12 @@
+--- a/src/monattack.cpp
++++ b/src/monattack.cpp
+@@ -3552,7 +3552,8 @@
+ for( int x = zposx - 24; x < zposx + 24; x++ ) {
+ for( int y = zposy - 24; y < zposy + 24; y++ ) {
+ tripoint dest( x, y, z->posz() );
+- if( g->m.ter( dest ) == ter_str_id( "t_plut_generator" ) ) {
++ if( ( g->m.ter( dest ) == ter_str_id( "t_plut_generator" ) ) ||
++ ( g->m.furn( dest ) == furn_str_id( "f_grid_plut_generator" ) ) ) {
+ generator_ok = true;
+ }
+ }
diff --git a/src-14_fix-npc_melee-calculations.patch b/src-14_fix-npc_melee-calculations.patch
new file mode 100644
index 0000000..ea98989
--- /dev/null
+++ b/src-14_fix-npc_melee-calculations.patch
@@ -0,0 +1,11 @@
+--- a/src/npcmove.cpp
++++ b/src/npcmove.cpp
+@@ -1409,7 +1409,7 @@
+ return npc_reload;
+ }
+
+- if( dist == 1 && same_z ) {
++ if( dist <= 1 && same_z ) {
+ add_msg( m_debug, "%s is trying a melee attack", disp_name() );
+ return npc_melee;
+ }
diff --git a/src-15_slow-down-fungal-blossoms.patch b/src-15_slow-down-fungal-blossoms.patch
new file mode 100644
index 0000000..b3c3832
--- /dev/null
+++ b/src-15_slow-down-fungal-blossoms.patch
@@ -0,0 +1,20 @@
+--- a/src/fungal_effects.cpp
++++ b/src/fungal_effects.cpp
+@@ -167,7 +167,7 @@
+ } else if( m.has_flag( flag_YOUNG, p ) ) {
+ if( x_in_y( growth * 10, 500 ) ) {
+ if( m.get_field_intensity( p, fd_fungal_haze ) != 0 ) {
+- if( x_in_y( growth * 10, 800 ) ) { // young trees are vulnerable
++ if( x_in_y( growth * 10, 1600 ) ) { // young trees are vulnerable
+ m.ter_set( p, t_fungus );
+ if( gm.place_critter_at( mon_fungal_blossom, p ) && gm.u.sees( p ) ) {
+ add_msg( m_warning, _( "The young tree blooms forth into a fungal blossom!" ) );
+@@ -183,7 +183,7 @@
+ } else if( m.has_flag( flag_TREE, p ) ) {
+ if( one_in( 10 ) ) {
+ if( m.get_field_intensity( p, fd_fungal_haze ) != 0 ) {
+- if( x_in_y( growth * 10, 100 ) ) {
++ if( x_in_y( growth * 10, 2000 ) ) {
+ m.ter_set( p, t_fungus );
+ if( gm.place_critter_at( mon_fungal_blossom, p ) && gm.u.sees( p ) ) {
+ add_msg( m_warning, _( "The tree blooms forth into a fungal blossom!" ) );
diff --git a/src-20_fix-default-mods.patch b/src-20_fix-default-mods.patch
new file mode 100644
index 0000000..035e125
--- /dev/null
+++ b/src-20_fix-default-mods.patch
@@ -0,0 +1,26 @@
+--- a/data/mods/default.json
++++ b/data/mods/default.json
+@@ -1,8 +1,18 @@
+ [
+- "bn",
+- "no_npc_food",
+- "novitamins",
++ "bn",
+ "No_Rail_Stations",
+- "no_reviving_zombies",
+- "limit_fungal_growth"
++ "bn_restore_crows_turrets",
++ "martial_arts_update",
++ "bn_restore_removed_traits",
++ "bn_revert_handgun_damage_buff",
++ "armor_rebalance",
++ "recipe_fixes",
++ "faction_camp_recipe_expansion",
++ "packed_at4",
++ "caseless_crafting",
++ "grenade_crafting",
++ "survivorheadgear_crafting",
++ "hk_loadout",
++ "m26_mass",
++ "restore_reactor_core_expansion"
+ ]
diff --git a/0012-fix-doors-for-npcs.patch b/terrain-02_fix-doors-for-npcs.patch
index 54f1f47..54f1f47 100644
--- a/0012-fix-doors-for-npcs.patch
+++ b/terrain-02_fix-doors-for-npcs.patch
diff --git a/0004-tacoma-clinic-add-missing-floor.patch b/terrain-03_tacoma-clinic-add-missing-floor.patch
index 9accf88..9accf88 100644
--- a/0004-tacoma-clinic-add-missing-floor.patch
+++ b/terrain-03_tacoma-clinic-add-missing-floor.patch
diff --git a/0005-lumbermill-gasoline-not-spilled.patch b/terrain-04_lumbermill-gasoline-not-spilled.patch
index 05e63ac..05e63ac 100644
--- a/0005-lumbermill-gasoline-not-spilled.patch
+++ b/terrain-04_lumbermill-gasoline-not-spilled.patch
diff --git a/0018-rehide-redacted.patch b/terrain-07_rehide-redacted.patch
index 6dacdbf..6dacdbf 100644
--- a/0018-rehide-redacted.patch
+++ b/terrain-07_rehide-redacted.patch
diff --git a/0.F_backport-make-firestation-shelter-wells-npc-drinkable.patch b/terrain-09_make-firestation-shelter-wells-npc-drinkable.patch
index 8eac7f0..8eac7f0 100644
--- a/0.F_backport-make-firestation-shelter-wells-npc-drinkable.patch
+++ b/terrain-09_make-firestation-shelter-wells-npc-drinkable.patch
diff --git a/terrain-10_fix-milbase_minefield.patch b/terrain-10_fix-milbase_minefield.patch
new file mode 100644
index 0000000..30bad9f
--- /dev/null
+++ b/terrain-10_fix-milbase_minefield.patch
@@ -0,0 +1,11 @@
+--- a/data/json/overmap/overmap_special/specials.json
++++ b/data/json/overmap/overmap_special/specials.json
+@@ -6858,7 +6858,7 @@
+ { "point": [ 1, -1, 0 ], "overmap": "mil_base_minefield_n_north" },
+ { "point": [ 2, -1, 0 ], "overmap": "mil_base_minefield_end_north" },
+ { "point": [ 3, -1, 0 ], "overmap": "mil_base_road_entrance_north" },
+- { "point": [ 4, -1, 0 ], "overmap": "mil_base_minefield_end_south" },
++ { "point": [ 4, -1, 0 ], "overmap": "mil_base_minefield_end_west" },
+ { "point": [ 5, -1, 0 ], "overmap": "mil_base_minefield_n_north" },
+ { "point": [ 6, -1, 0 ], "overmap": "mil_base_minefield_n_north" },
+ { "point": [ 7, -1, 0 ], "overmap": "mil_base_minefield_n_north" },
diff --git a/terrain-11_clean-up-map-extras.patch b/terrain-11_clean-up-map-extras.patch
new file mode 100644
index 0000000..fbee684
--- /dev/null
+++ b/terrain-11_clean-up-map-extras.patch
@@ -0,0 +1,138 @@
+--- a/data/json/overmap/map_extras.json
++++ b/data/json/overmap/map_extras.json
+@@ -129,7 +129,7 @@
+ {
+ "id": "mx_portal",
+ "type": "map_extra",
+- "name": "Portal",
++ "name": "Shimmering Portal",
+ "description": "A portal is here.",
+ "generator": { "generator_method": "map_extra_function", "generator_id": "mx_portal" },
+ "sym": "P",
+@@ -139,7 +139,7 @@
+ {
+ "id": "mx_portal_in",
+ "type": "map_extra",
+- "name": "Portal",
++ "name": "Tear in Reality",
+ "description": "A portal is here.",
+ "generator": { "generator_method": "map_extra_function", "generator_id": "mx_portal_in" },
+ "sym": "P",
+@@ -239,16 +239,22 @@
+ {
+ "id": "mx_trees",
+ "type": "map_extra",
+- "name": "Stand of trees",
++ "name": "Copse of trees",
+ "description": "A copse of trees.",
+- "generator": { "generator_method": "update_mapgen", "generator_id": "mx_trees_map" }
++ "generator": { "generator_method": "update_mapgen", "generator_id": "mx_trees_map" },
++ "sym": "t",
++ "color": "light_green",
++ "autonote": true
+ },
+ {
+ "id": "mx_grass",
+ "type": "map_extra",
+ "name": "Tall grass",
+ "description": "A meadow of tall grass.",
+- "generator": { "generator_method": "update_mapgen", "generator_id": "mx_grass_map" }
++ "generator": { "generator_method": "update_mapgen", "generator_id": "mx_grass_map" },
++ "sym": "g",
++ "color": "light_green",
++ "autonote": true
+ },
+ {
+ "id": "mx_fallen_shed",
+@@ -256,7 +262,7 @@
+ "name": "Derelict shed",
+ "description": "A collapsed shed.",
+ "generator": { "generator_method": "update_mapgen", "generator_id": "mx_fallen_shed_map" },
+- "sym": "N",
++ "sym": "s",
+ "color": "brown",
+ "autonote": true
+ },
+@@ -295,7 +302,9 @@
+ "name": "Burned Ground",
+ "description": "This area has been burned down.",
+ "generator": { "generator_method": "map_extra_function", "generator_id": "mx_burned_ground" },
+- "sym": "."
++ "sym": ".",
++ "color": "white",
++ "autonote": true
+ },
+ {
+ "id": "mx_point_burned_ground",
+@@ -303,7 +312,9 @@
+ "name": "Burned Ground",
+ "description": "This area has been burned down.",
+ "generator": { "generator_method": "map_extra_function", "generator_id": "mx_point_burned_ground" },
+- "sym": "."
++ "sym": ".",
++ "color": "white",
++ "autonote": true
+ },
+ {
+ "id": "mx_marloss_pilgrimage",
+@@ -321,21 +332,29 @@
+ "name": "Casings",
+ "description": "A shootout happened here.",
+ "generator": { "generator_method": "map_extra_function", "generator_id": "mx_casings" },
+- "sym": "C"
++ "sym": "C",
++ "color": "white",
++ "autonote": true
+ },
+ {
+ "id": "mx_looters",
+ "type": "map_extra",
+ "name": "Looters",
+ "description": "Some looters are gathering everything not nailed down.",
+- "generator": { "generator_method": "map_extra_function", "generator_id": "mx_looters" }
++ "generator": { "generator_method": "map_extra_function", "generator_id": "mx_looters" },
++ "sym": "L",
++ "color": "red",
++ "autonote": true
+ },
+ {
+ "id": "mx_corpses",
+ "type": "map_extra",
+ "name": "Corpses",
+ "description": "Some unfortunates from the billions lost in the Cataclysm.",
+- "generator": { "generator_method": "map_extra_function", "generator_id": "mx_corpses" }
++ "generator": { "generator_method": "map_extra_function", "generator_id": "mx_corpses" },
++ "sym": "c",
++ "color": "light_red",
++ "autonote": true
+ },
+ {
+ "id": "mx_nest_wasp",
+@@ -362,7 +381,10 @@
+ "type": "map_extra",
+ "name": "Prison Bus",
+ "description": "A prison bus.",
+- "generator": { "generator_method": "update_mapgen", "generator_id": "mx_prison_bus" }
++ "generator": { "generator_method": "update_mapgen", "generator_id": "mx_prison_bus" },
++ "sym": "P",
++ "color": "blue",
++ "autonote": true
+ },
+ {
+ "id": "mx_mass_grave",
+@@ -377,9 +399,12 @@
+ {
+ "id": "mx_grave",
+ "type": "map_extra",
+- "name": "Grave",
+- "description": "A grave.",
+- "generator": { "generator_method": "map_extra_function", "generator_id": "mx_grave" }
++ "name": "Solitary Grave",
++ "description": "A solitary grave.",
++ "generator": { "generator_method": "map_extra_function", "generator_id": "mx_grave" },
++ "sym": "c",
++ "color": "white",
++ "autonote": true
+ },
+ {
+ "id": "mx_sewer_round",
diff --git a/terrain-13_fix-mapgen-palettes.patch b/terrain-13_fix-mapgen-palettes.patch
new file mode 100644
index 0000000..5fb3187
--- /dev/null
+++ b/terrain-13_fix-mapgen-palettes.patch
@@ -0,0 +1,256 @@
+--- a/data/json/mapgen/lab/lab_floorplans.json
++++ b/data/json/mapgen/lab/lab_floorplans.json
+@@ -119,7 +119,7 @@
+ "...|...|r......|X.....X|",
+ "...|...|.......|---W---|",
+ "LLL|LLL|.......| |",
+- "...C..........l| |",
++ "...K..........l| |",
+ "..............l| |",
+ "...............+ |",
+ "...............| |",
+@@ -148,7 +148,7 @@
+ "F": "t_chainfence_h",
+ "f": "t_chainfence_v",
+ "H": "t_chaingate_c",
+- "C": "t_gates_control_concrete_lab"
++ "K": "t_gates_control_concrete_lab"
+ },
+ "mapping": { "r": { "items": [ { "item": "hardware", "chance": 10 }, { "item": "robots", "chance": 10 } ] } },
+ "place_nested": [
+@@ -238,10 +238,10 @@
+ "..c|c..c|c....c|c..c|c..",
+ "..---..---....---..---..",
+ "........................",
+- "...C....C......C....C...",
++ "...K....K......K....K...",
+ "........................",
+ "........................",
+- "...C....C......C....C...",
++ "...K....K......K....K...",
+ "........................",
+ "..---..---.....|---+---|",
+ "..c|c..c|c.....| |",
+@@ -254,11 +254,11 @@
+ "rrr.....!.....l|-------|"
+ ],
+ "palettes": [ "lab_palette", "lab_loot_research" ],
+- "furniture": { "f": "f_null", "C": "f_centrifuge" },
++ "furniture": { "f": "f_null", "K": "f_centrifuge" },
+ "terrain": {
+ "?": [ "t_concrete_wall", "t_concrete_wall", "t_door_glass_frosted_lab_c" ],
+ "!": [ "t_thconc_floor", "t_thconc_floor", "t_console_broken", "t_generator_broken" ],
+- "C": "t_thconc_floor"
++ "K": "t_thconc_floor"
+ },
+ "mapping": {
+ "c": { "items": [ { "item": "chem_lab", "chance": 10 }, { "item": "tools_science", "chance": 10 } ] },
+@@ -401,7 +401,7 @@
+ "...| |---+---|..",
+ "...| |..........",
+ "...|---------|..........",
+- "...| |C|cccxc...hh",
++ "...| |K|cccxc...hh",
+ "l..| | +...hc...tt",
+ "l..| |f|....c...hh",
+ "l..? |--cc.cc.....",
+@@ -415,8 +415,8 @@
+ ],
+ "palettes": [ "lab_palette", "lab_loot_home_office" ],
+ "terrain": { "?": [ "t_concrete_wall", "t_concrete_wall", "t_door_glass_frosted_lab_c" ] },
+- "furniture": { "^": "f_indoor_plant", "C": "f_cupboard" },
+- "mapping": { "C": { "items": [ { "item": "kitchen", "chance": 40 } ] }, "t": { "items": [ { "item": "snacks", "chance": 10 } ] } },
++ "furniture": { "^": "f_indoor_plant", "K": "f_cupboard" },
++ "mapping": { "K": { "items": [ { "item": "kitchen", "chance": 40 } ] }, "t": { "items": [ { "item": "snacks", "chance": 10 } ] } },
+ "place_nested": [
+ { "chunks": [ "lab_spawn_9x9_wall_nw" ], "x": 3, "y": 2 },
+ { "chunks": [ "lab_spawn_7x7_crossdoors" ], "x": 14, "y": 3 },
+@@ -437,7 +437,7 @@
+ ".......L...............l",
+ ".......L...............l",
+ ".......L....----?----..l",
+- "-------|C...| |..l",
++ "-------|K...| |..l",
+ ".......L....| |..l",
+ ".......L....| |..l",
+ ".......L....+ |..l",
+@@ -465,7 +465,7 @@
+ "F": "t_chainfence_h",
+ "f": "t_chainfence_v",
+ "H": "t_chaingate_c",
+- "C": "t_gates_control_concrete_lab",
++ "K": "t_gates_control_concrete_lab",
+ "?": [ "t_concrete_wall", "t_concrete_wall", "t_door_glass_frosted_lab_c" ]
+ },
+ "mapping": {
+@@ -509,7 +509,7 @@
+ "rows": [
+ "..cccccc.|...|,,,|..|,,,",
+ "c........|...|,,,|.6|,,,",
+- "c..Ccxc..|...|,,,g..g,,,",
++ "c..Kcxc..|...|,,,g..g,,,",
+ "c........g...|,,,g..g,,,",
+ "c........g...|,,,L..L,,,",
+ "......llS|...|---|..|---",
+@@ -533,10 +533,10 @@
+ "........................"
+ ],
+ "palettes": [ "lab_palette", "lab_loot_research" ],
+- "furniture": { "?": "f_autodoc", "/": "f_autodoc_couch", "C": "f_centrifuge" },
++ "furniture": { "?": "f_autodoc", "/": "f_autodoc_couch", "K": "f_centrifuge" },
+ "terrain": {
+ ",": "t_floor_blue",
+- "C": "t_floor_blue",
++ "K": "t_floor_blue",
+ "?": "t_floor_blue",
+ "/": "t_floor_blue",
+ "7": "t_console",
+@@ -593,7 +593,7 @@
+ "bb...+.......| |",
+ "bb...+.......| |",
+ "...ht|.......| |",
+- "-----|..C6...+ |",
++ "-----|..K6...+ |",
+ "....l|.......| |",
+ "bb...+.......| |",
+ "bb...+.......| |",
+@@ -606,7 +606,7 @@
+ "bb...+.......| |",
+ "bb...+.......| |",
+ "...ht|.......| |",
+- "-----|..Cx...? |",
++ "-----|..Kx...? |",
+ "...ht|.......| |",
+ "bb...+.......| |",
+ "bb...+.......| |",
+@@ -615,12 +615,12 @@
+ ],
+ "palettes": [ "lab_palette" ],
+ "terrain": {
+- "C": "t_floor",
++ "K": "t_floor",
+ "?": [ "t_concrete_wall", "t_concrete_wall", "t_door_glass_frosted_lab_c" ],
+ "7": "t_floor",
+ "8": "t_floor"
+ },
+- "furniture": { "7": "f_autodoc", "8": "f_autodoc_couch", "C": "f_centrifuge" },
++ "furniture": { "7": "f_autodoc", "8": "f_autodoc_couch", "K": "f_centrifuge" },
+ "items": {
+ "b": { "item": "hospital_bed", "chance": 33 },
+ "l": { "item": "surgery", "chance": 50 },
+@@ -661,7 +661,7 @@
+ "fill_ter": "t_thconc_floor",
+ "rows": [
+ ",,,,,|..|.....|.........",
+- ",,,,,|7.|.....|..cxcC...",
++ ",,,,,|7.|.....|..cxcK...",
+ ",,,,,g..g.....g.......l.",
+ ",,,,,g..g.....g.......l.",
+ ",,,,,L..g.....|.......S.",
+@@ -686,8 +686,8 @@
+ "........................"
+ ],
+ "palettes": [ "lab_palette" ],
+- "furniture": { "C": "f_centrifuge" },
+- "terrain": { "C": "t_floor_blue", "7": "t_console", ",": "t_floor_blue" },
++ "furniture": { "K": "f_centrifuge" },
++ "terrain": { "K": "t_floor_blue", "7": "t_console", ",": "t_floor_blue" },
+ "mapping": {
+ "c": { "items": [ { "item": "office", "chance": 30 }, { "item": "tools_science", "chance": 15 } ] },
+ "l": { "items": [ { "item": "science", "chance": 60 } ] }
+@@ -746,7 +746,7 @@
+ ".......L.........G......",
+ ".......L.........|..ddd.",
+ ".......L.........g..dh..",
+- "-------|C........g......",
++ "-------|K........g......",
+ ".......L.........g......",
+ ".......L.........|dh....",
+ ".......L.........|dxd.^.",
+@@ -762,7 +762,7 @@
+ "P": "t_generator_broken",
+ "S": "t_sewage_pump",
+ "p": "t_sewage_pipe",
+- "C": "t_gates_control_concrete_lab",
++ "K": "t_gates_control_concrete_lab",
+ "g": "t_wall_glass",
+ "G": "t_door_glass_lab_c"
+ },
+@@ -826,21 +826,21 @@
+ "...htth..g....gWWWWWWWl|",
+ "...htth..g....gWWWcWWWl|",
+ ".........G....LWWWcWWWW|",
+- ".........g....gWWWCWWWW|",
++ ".........g....gWWWKWWWW|",
+ "...htth..g....gWWWcWWWW|",
+ "...htth..g....gWWWWWWhd|",
+ "........^|....|rrrWWdxd|",
+ ".........|....|---------"
+ ],
+ "palettes": [ "lab_palette", "lab_loot_home_office" ],
+- "furniture": { "^": "f_indoor_plant", "C": "f_centrifuge" },
++ "furniture": { "^": "f_indoor_plant", "K": "f_centrifuge" },
+ "terrain": {
+ "E": "t_elevator",
+ "e": "t_elevator_control_off",
+ "w": "t_water_sh",
+ "W": "t_water_dp",
+ "=": "t_door_lab_c",
+- "C": "t_thconc_floor"
++ "K": "t_thconc_floor"
+ },
+ "mapping": { "t": { "items": [ { "item": "vending_food_items", "chance": 20 } ] } },
+ "place_loot": [
+@@ -920,20 +920,20 @@
+ "TS| F +`````+ F |ST|",
+ "--|V F w`hth`w F V|--|",
+ "rr--| -w---w- |--rr|",
+- "-+|s| CSC|CSC |s|+-|",
+- " | C|C | x|",
++ "-+|s| KSK|KSK |s|+-|",
++ " | K|K | x|",
+ " t + O|O + t|",
+ "bb |hh ḟ|ḟ hh| bb|",
+- "bb ]|tt C|C tt|] bb|",
++ "bb ]|tt K|K tt|] bb|",
+ "--------+-----+--------|",
+ "........................",
+ "........................",
+ "--------+-----+--------|",
+- "bb ]|tt C|C tt|] bb|",
++ "bb ]|tt K|K tt|] bb|",
+ "bb |hh ḟ|ḟ hh| bb|",
+ " t + O|O + t|",
+- " | C|C | |",
+- "-+|s| CSC|CSC |s|+-|",
++ " | K|K | |",
++ "-+|s| KSK|KSK |s|+-|",
+ "rr--| -w---w- |--rr|",
+ "--|V F w`hth`w F V|--|",
+ "TS| F +`````+ F |ST|",
+@@ -941,13 +941,13 @@
+ "BB|FFFt |`````| tFFF|BB|"
+ ],
+ "palettes": [ "lab_palette", "lab_loot_home_office" ],
+- "furniture": { "F": "f_sofa", "B": "f_bathtub", "C": "f_counter", "O": "f_oven", "V": "f_table" },
++ "furniture": { "F": "f_sofa", "B": "f_bathtub", "K": "f_counter", "O": "f_oven", "V": "f_table" },
+ "terrain": { "w": "t_window_domestic", "`": "t_grass", "+": "t_door_lab_c" },
+ "mapping": {
+ "t": { "items": [ { "item": "livingroom", "chance": 20 } ] },
+ "F": { "items": [ { "item": "livingroom", "chance": 5 } ] },
+ "ḟ": { "items": [ { "item": "fridge", "chance": 80 } ] },
+- "C": { "items": [ { "item": "kitchen", "chance": 40 } ] },
++ "K": { "items": [ { "item": "kitchen", "chance": 40 } ] },
+ "O": { "items": [ { "item": "oven", "chance": 70 } ] },
+ "r": {
+ "items": [
+--- a/data/json/mapgen_palettes/fema.json
++++ b/data/json/mapgen_palettes/fema.json
+@@ -26,6 +26,7 @@
+ "g": "t_wall_glass",
+ "I": "t_column",
+ "i": "t_sidewalk",
++ "N": [ [ "t_region_groundcover", 10 ], [ "t_region_groundcover_barren", 3 ] ],
+ "P": "t_water_pump",
+ "s": "t_floor",
+ "w": [ "t_window_domestic", "t_curtains", "t_curtains" ],
diff --git a/0021-foldable-bottle-is-container.patch b/tools-01_foldable-bottle-is-container.patch
index 95b3d0f..95b3d0f 100644
--- a/0021-foldable-bottle-is-container.patch
+++ b/tools-01_foldable-bottle-is-container.patch
diff --git a/tools-03_shears-use-light-battery.patch b/tools-03_shears-use-light-battery.patch
new file mode 100644
index 0000000..d6da6bf
--- /dev/null
+++ b/tools-03_shears-use-light-battery.patch
@@ -0,0 +1,28 @@
+--- a/data/json/items/tool/pets.json
++++ b/data/json/items/tool/pets.json
+@@ -68,9 +68,22 @@
+ "color": "dark_gray",
+ "qualities": [ [ "SHEAR", 3 ] ],
+ "ammo": "battery",
+- "initial_charges": 100,
+- "max_charges": 100,
+- "charges_per_use": 25
++ "charges_per_use": 25,
++ "magazines": [
++ [
++ "battery",
++ [
++ "light_minus_battery_cell",
++ "light_battery_cell",
++ "light_plus_battery_cell",
++ "light_atomic_battery_cell",
++ "light_minus_atomic_battery_cell",
++ "light_minus_disposable_cell",
++ "light_disposable_cell"
++ ]
++ ]
++ ],
++ "magazine_well": "250 ml"
+ },
+ {
+ "id": "horse_tack",
diff --git a/vampirism.patch b/vampirism.patch
new file mode 100644
index 0000000..4fbef1e
--- /dev/null
+++ b/vampirism.patch
@@ -0,0 +1,823 @@
+--- a/src/activity_handlers.cpp
++++ b/src/activity_handlers.cpp
+@@ -238,6 +238,7 @@3
+ static const species_id HUMAN( "HUMAN" );
+ static const species_id ZOMBIE( "ZOMBIE" );
+
++static const trait_flag_str_id trait_flag_VAMPIRE( "VAMPIRE" );
+ static const trait_flag_str_id trait_flag_CANNIBAL( "CANNIBAL" );
+ static const trait_flag_str_id trait_flag_PSYCHOPATH( "PSYCHOPATH" );
+ static const trait_flag_str_id trait_flag_SAPIOVORE( "SAPIOVORE" );
+@@ -667,7 +667,8 @@
+ !corpse.in_species( ZOMBIE ) );
+ if( is_human && !( u.has_trait_flag( trait_flag_CANNIBAL ) ||
+ u.has_trait_flag( trait_flag_PSYCHOPATH ) ||
+- u.has_trait_flag( trait_flag_SAPIOVORE ) ) ) {
++ u.has_trait_flag( trait_flag_SAPIOVORE ) ||
++ u.has_trait_flag( trait_flag_VAMPIRE ) ) ) {
+ need_confirm( _( "Would you dare desecrate the mortal remains of a fellow human being?" ),
+ butcherable_rating::warn_cannibalism );
+ }
+
+--- a/src/character.cpp
++++ b/src/character.cpp
+@@ -311,6 +311,9 @@
+ static const trait_id trait_TOUGH_FEET( "TOUGH_FEET" );
+ static const trait_id trait_TRANSPIRATION( "TRANSPIRATION" );
+ static const trait_id trait_URSINE_EYE( "URSINE_EYE" );
++static const trait_id trait_VAMP_HEARING( "VAMP_HEARING" );
++static const trait_id trait_VAMP_HUNGER( "VAMP_HUNGER" );
++static const trait_id trait_VAMP_SKIN( "VAMP_SKIN" );
+ static const trait_id trait_VISCOUS( "VISCOUS" );
+ static const trait_id trait_WATERSLEEP( "WATERSLEEP" );
+ static const trait_id trait_WEBBED( "WEBBED" );
+@@ -4631,6 +4631,7 @@
+ const bool npc_no_food = is_npc() && get_option<bool>( "NO_NPC_FOOD" );
+ const bool foodless = debug_ls || npc_no_food;
+ const bool mouse = has_trait( trait_NO_THIRST );
++ const bool vamp = has_trait( trait_VAMP_HUNGER );
+ const bool mycus = has_trait( trait_M_DEPENDENT );
+ const float kcal_per_time = bmr() / ( 12.0f * 24.0f );
+ const int five_mins = ticks_between( from, to, 5_minutes );
+@@ -4661,7 +4661,7 @@
+
+ // Mycus and Metabolic Rehydration makes thirst unnecessary
+ // since water is not limited by intake but by absorption, we can just set thirst to zero
+- if( mycus || mouse ) {
++ if( mycus || mouse || vamp ) {
+ set_thirst( 0 );
+ }
+ }
+@@ -4861,15 +4861,17 @@
+ void Character::check_needs_extremes()
+ {
+ // Check if we've overdosed... in any deadly way.
+- if( get_stim() > 250 ) {
++ if( ( get_stim() > 250 ) && !( has_trait( trait_VAMP_SKIN ) ) ) {
+ add_msg_if_player( m_bad, _( "You have a sudden heart attack!" ) );
+ g->events().send<event_type::dies_from_drug_overdose>( getID(), efftype_id() );
+ set_part_hp_cur( bodypart_id( "torso" ), 0 );
+- } else if( get_stim() < -200 || get_painkiller() > 240 ) {
++ } else if( ( get_stim() < -200 || get_painkiller() > 240 ) && !( has_trait( trait_VAMP_SKIN ) ) ) {
+ add_msg_if_player( m_bad, _( "Your breathing stops completely." ) );
+ g->events().send<event_type::dies_from_drug_overdose>( getID(), efftype_id() );
+ set_part_hp_cur( bodypart_id( "torso" ), 0 );
+- } else if( has_effect( effect_jetinjector ) && get_effect_dur( effect_jetinjector ) > 40_minutes ) {
++ } else if( ( has_effect( effect_jetinjector ) &&
++ get_effect_dur( effect_jetinjector ) > 40_minutes ) &&
++ !( has_trait( trait_VAMP_SKIN ) ) ) {
+ if( !( has_trait( trait_NOPAIN ) ) ) {
+ add_msg_if_player( m_bad, _( "Your heart spasms painfully and stops." ) );
+ } else {
+@@ -4879,7 +4879,7 @@
+ }
+ g->events().send<event_type::dies_from_drug_overdose>( getID(), effect_jetinjector );
+ set_part_hp_cur( bodypart_id( "torso" ), 0 );
+- } else if( get_effect_int( effect_drunk ) > 4 ) {
++ } else if( ( get_effect_int( effect_drunk ) > 4 ) && !( has_trait( trait_VAMP_SKIN ) ) ) {
+ add_msg_if_player( m_bad, _( "Your breathing slows down to a stop." ) );
+ g->events().send<event_type::dies_from_drug_overdose>( getID(), effect_drunk );
+ set_part_hp_cur( bodypart_id( "torso" ), 0 );
+@@ -4985,7 +4988,7 @@
+
+ void Character::update_bodytemp( const map &m, const weather_manager &weather )
+ {
+- if( has_trait( trait_DEBUG_NOTEMP ) ) {
++ if( has_trait( trait_DEBUG_NOTEMP ) || has_trait( trait_VAMP_SKIN ) ) {
+ temp_cur.fill( BODYTEMP_NORM );
+ temp_conv.fill( BODYTEMP_NORM );
+ return;
+@@ -6629,6 +6629,7 @@
+ } else if( eff == effect_deaf ) {
+ return worn_with_flag( flag_DEAF ) || worn_with_flag( flag_PARTIAL_DEAF ) ||
+ has_bionic( bio_ears ) ||
++ has_trait( trait_VAMP_HEARING ) ||
+ is_wearing( itype_rm13_armor_on );
+ } else if( eff == effect_corroding ) {
+ return is_immune_damage( DT_ACID ) || has_trait( trait_SLIMY ) || has_trait( trait_VISCOUS );
+
+--- a/src/character.h
++++ b/src/character.h
+@@ -162,6 +162,8 @@
+ allergy_weak,
+ // Cannibalism (unless psycho/cannibal)
+ cannibalism,
++ // Vampirism (unless psycho/cannibal)
++ vampirism,
+ // Rotten or not rotten enough (for saprophages)
+ rotten,
+ // Can provoke vomiting if you already feel nauseous.
+
+--- a/src/consumption.cpp
++++ b/src/consumption.cpp
+@@ -108,8 +108,10 @@
+ static const trait_id trait_THRESH_LUPINE( "THRESH_LUPINE" );
+ static const trait_id trait_THRESH_PLANT( "THRESH_PLANT" );
+ static const trait_id trait_THRESH_URSINE( "THRESH_URSINE" );
++static const trait_id trait_VAMP_HUNGER( "VAMP_HUNGER" );
+ static const trait_id trait_VEGETARIAN( "VEGETARIAN" );
+ static const trait_id trait_WATERSLEEP( "WATERSLEEP" );
+
+ static const trait_flag_str_id trait_flag_CANNIBAL( "CANNIBAL" );
++static const trait_flag_str_id trait_flag_VAMPIRE( "VAMPIRE" );
+
+@@ -126,6 +126,15 @@
+ flag_id( "ALLERGEN_WHEAT" ), flag_id( "ALLERGEN_NUT" )
+ }};
+
++static const std::array<flag_id, 12> vamp_blacklist {{
++ flag_id( "ALLERGEN_VEGGY" ), flag_id( "ALLERGEN_FRUIT" ),
++ flag_id( "ALLERGEN_WHEAT" ), flag_id( "ALLERGEN_NUT" ),
++ flag_id( "ALLERGEN_MEAT" ), flag_id( "ALLERGEN_EGG" ),
++ flag_id( "ALLERGEN_JUNK" ), flag_id( "ALLERGEN_MILK" ),
++ flag_id( "ALLERGEN_HONEY" ), flag_id( "ALLERGEN_FOODSTUFF" ),
++ flag_id( "ALLERGEN_ALCOHOL" ), flag_id( "ALLERGEN_WATER" )
++ }};
++
+ static const std::array<flag_id, 2> herbivore_blacklist {{
+ flag_id( "ALLERGEN_MEAT" ), flag_id( "ALLERGEN_EGG" )
+ }};
+@@ -712,6 +712,12 @@
+ _( "Eww. Inedible plant stuff!" ) );
+ }
+
++ if( has_trait_flag( trait_flag_VAMPIRE ) && food.has_any_flag( vamp_blacklist ) &&
++ !food.has_flag( flag_VAMPIRISM_OK ) ) {
++ return ret_val<edible_rating>::make_failure( edible_rating::inedible_mutation,
++ _( "Bleh. This isn't blood!" ) );
++ }
++
+ if( ( has_trait( trait_HERBIVORE ) || has_trait( trait_RUMINANT ) ) &&
+ food.has_any_flag( herbivore_blacklist ) ) {
+ // Like non-cannibal, but more strict!
+@@ -744,8 +744,15 @@
+ }
+ }
+
++ if( food.has_flag( flag_VAMPIRISM ) && ( !has_trait_flag( trait_flag_VAMPIRE ) &&
++ !has_trait_flag( trait_flag_CANNIBAL ) ) ) {
++ add_consequence( _( "The thought of drinking human blood makes you feel sick." ),
++ edible_rating::vampirism );
++ }
++
+ const bool carnivore = has_trait( trait_CARNIVORE );
+- if( food.has_flag( flag_CANNIBALISM ) && !has_trait_flag( trait_flag_CANNIBAL ) ) {
++ if( ( food.has_flag( flag_CANNIBALISM ) && !food.has_flag( flag_VAMPIRISM ) ) &&
++ !has_trait_flag( trait_flag_CANNIBAL ) ) {
+ add_consequence( _( "The thought of eating human flesh makes you feel sick." ),
+ edible_rating::cannibalism );
+ }
+@@ -1084,7 +1091,28 @@
+ }
+ }
+
+- if( food.has_flag( flag_CANNIBALISM ) ) {
++ if( food.has_flag( flag_VAMPIRISM ) ) {
++ const bool vamp = has_trait( trait_VAMP_HUNGER );
++ const bool cannibal = has_trait( trait_CANNIBAL );
++ const bool psycho = has_trait( trait_PSYCHOPATH );
++ const bool sapiovore = has_trait( trait_SAPIOVORE );
++ if( !vamp && !cannibal && !psycho && !sapiovore ) {
++ add_msg_if_player( m_bad, _( "You feel horrible for drinking the blood of a person." ) );
++ add_morale( MORALE_CANNIBAL, -60, -400, 60_minutes, 30_minutes );
++ } else if( vamp ) {
++ add_msg_if_player( m_good, _( "You relish drinking the human blood." ) );
++ add_morale( MORALE_VAMPIRE, 30, 300 );
++ } else if( cannibal ) {
++ add_msg_if_player( m_good, _( "You indulge your shameful hunger." ) );
++ add_morale( MORALE_CANNIBAL, 20, 200 );
++ } else if( psycho || sapiovore ) {
++ // Nothing - doesn't care enough to print a message
++ } else {
++ add_msg_if_player( m_bad, _( "You found a bug drinking human blood." ) );
++ }
++ }
++
++ if( food.has_flag( flag_CANNIBALISM ) && !food.has_flag( flag_VAMPIRISM ) ) {
+ const bool cannibal = has_trait( trait_CANNIBAL );
+ const bool psycho = has_trait( trait_PSYCHOPATH );
+ const bool sapiovore = has_trait( trait_SAPIOVORE );
+@@ -1123,6 +1161,11 @@
+ add_msg_if_player( m_bad, _( "Yuck! How can anybody eat this stuff?" ) );
+ add_morale( allergy, -75, -400, 30_minutes, 24_minutes );
+ }
++ if( allergy != MORALE_NULL && has_trait( trait_VAMP_HUNGER ) ) {
++ add_msg_if_player( m_bad, _( "I can't stomach anything but blood!" ) );
++ add_morale( allergy, -75, -400, 30_minutes, 24_minutes );
++ vomit();
++ }
+ if( food.has_flag( flag_ALLERGEN_JUNK ) ) {
+ if( has_trait( trait_PROJUNK ) ) {
+ add_msg_if_player( m_good, _( "Mmm, junk food." ) );
+
+--- a/src/flag.cpp
++++ b/src/flag.cpp
+@@ -15,13 +15,17 @@
+ const flag_id flag_ACT_IN_FIRE( "ACT_IN_FIRE" );
+ const flag_id flag_ACT_ON_RANGED_HIT( "ACT_ON_RANGED_HIT" );
+ const flag_id flag_ALARMCLOCK( "ALARMCLOCK" );
++const flag_id flag_ALLERGEN_ALCOHOL( "ALLERGEN_ALCOHOL" );
+ const flag_id flag_ALLERGEN_EGG( "ALLERGEN_EGG" );
++const flag_id flag_ALLERGEN_FOODSTUFF( "ALLERGEN_FOODSTUFF" );
+ const flag_id flag_ALLERGEN_FRUIT( "ALLERGEN_FRUIT" );
++const flag_id flag_ALLERGEN_HONEY( "ALLERGEN_HONEY" );
+ const flag_id flag_ALLERGEN_JUNK( "ALLERGEN_JUNK" );
+ const flag_id flag_ALLERGEN_MEAT( "ALLERGEN_MEAT" );
+ const flag_id flag_ALLERGEN_MILK( "ALLERGEN_MILK" );
+ const flag_id flag_ALLERGEN_NUT( "ALLERGEN_NUT" );
+ const flag_id flag_ALLERGEN_VEGGY( "ALLERGEN_VEGGY" );
++const flag_id flag_ALLERGEN_WATER( "ALLERGEN_WATER" );
+ const flag_id flag_ALLERGEN_WHEAT( "ALLERGEN_WHEAT" );
+ const flag_id flag_ALLERGEN_WOOL( "ALLERGEN_WOOL" );
+ const flag_id flag_ALLOWS_NATURAL_ATTACKS( "ALLOWS_NATURAL_ATTACKS" );
+@@ -326,6 +330,8 @@
+ const flag_id flag_USE_UPS( "USE_UPS" );
+ const flag_id flag_VARSIZE( "VARSIZE" );
+ const flag_id flag_VEHICLE( "VEHICLE" );
++const flag_id flag_VAMPIRISM( "VAMPIRISM" );
++const flag_id flag_VAMPIRISM_OK( "VAMPIRISM_OK" );
+ const flag_id flag_VERY_COLD( "VERY_COLD" );
+ const flag_id flag_WAIST( "WAIST" );
+ const flag_id flag_WATCH( "WATCH" );
+
+--- a/src/flag.h
++++ b/src/flag.h
+@@ -17,13 +17,17 @@
+ extern const flag_id flag_ACT_IN_FIRE;
+ extern const flag_id flag_ACT_ON_RANGED_HIT;
+ extern const flag_id flag_ALARMCLOCK;
++extern const flag_id flag_ALLERGEN_ALCOHOL;
+ extern const flag_id flag_ALLERGEN_EGG;
++extern const flag_id flag_ALLERGEN_FOODSTUFF;
+ extern const flag_id flag_ALLERGEN_FRUIT;
++extern const flag_id flag_ALLERGEN_HONEY;
+ extern const flag_id flag_ALLERGEN_JUNK;
+ extern const flag_id flag_ALLERGEN_MEAT;
+ extern const flag_id flag_ALLERGEN_MILK;
+ extern const flag_id flag_ALLERGEN_NUT;
+ extern const flag_id flag_ALLERGEN_VEGGY;
++extern const flag_id flag_ALLERGEN_WATER;
+ extern const flag_id flag_ALLERGEN_WHEAT;
+ extern const flag_id flag_ALLERGEN_WOOL;
+ extern const flag_id flag_ALLOWS_NATURAL_ATTACKS;
+@@ -327,6 +331,8 @@
+ extern const flag_id flag_USE_PLAYER_ENERGY;
+ extern const flag_id flag_USE_UPS;
+ extern const flag_id flag_VARSIZE;
++extern const flag_id flag_VAMPIRISM;
++extern const flag_id flag_VAMPIRISM_OK;
+ extern const flag_id flag_VERY_COLD;
+ extern const flag_id flag_VEHICLE;
+ extern const flag_id flag_WAIST;
+
+--- a/src/game.cpp
++++ b/src/game.cpp
+@@ -1040,8 +1040,9 @@
+ int iInfoLine = 0;
+
+ if( u.has_amount( itype_holybook_bible1, 1 ) || u.has_amount( itype_holybook_bible2, 1 ) ||
+- u.has_amount( itype_holybook_bible3, 1 ) ) {
+- if( !( u.has_trait( trait_id( "CANNIBAL" ) ) || u.has_trait( trait_id( "PSYCHOPATH" ) ) ) ) {
++ u.has_amount( itype_holybook_bible3, 1 ) || u.has_trait( trait_id( "THRESH_REAL_VAMP" ) ) ) {
++ if( !( u.has_trait( trait_id( "CANNIBAL" ) ) || u.has_trait( trait_id( "PSYCHOPATH" ) ) ||
++ u.has_trait( trait_id( "THRESH_REAL_VAMP" ) ) ) ) {
+ vRip.emplace_back( " _______ ___" );
+ vRip.emplace_back( " < `/ |" );
+ vRip.emplace_back( " > _ _ (" );
+
+--- a/src/item.cpp
++++ b/src/item.cpp
+@@ -148,6 +148,7 @@
+ static const species_id ROBOT( "ROBOT" );
+
+ static const trait_flag_str_id trait_flag_CANNIBAL( "CANNIBAL" );
++static const trait_flag_str_id trait_flag_VAMPIRE( "VAMPIRE" );
+
+ static const bionic_id bio_digestion( "bio_digestion" );
+
+@@ -1720,18 +1722,34 @@
+ _( "* This food will cause an <bad>allergic reaction</bad>." ) );
+ }
+
++ if( food_item->has_flag( flag_VAMPIRISM ) &&
++ parts->test( iteminfo_parts::FOOD_VAMPIRISM ) ) {
++ if( you.has_trait_flag( trait_flag_VAMPIRE ) ) {
++ info.emplace_back( "DESCRIPTION",
++ _( "* This food contains <good>human blood</good>." ) );
++ } else if( you.has_trait_flag( trait_flag_CANNIBAL ) ) {
++ info.emplace_back( "DESCRIPTION",
++ _( "* This food contains <good>human flesh</good>." ) );
++ } else {
++ info.emplace_back( "DESCRIPTION",
++ _( "* This food contains <bad>human flesh</bad>." ) );
++ }
++ }
++
+ if( food_item->has_flag( flag_CANNIBALISM ) &&
++ !food_item->has_flag( flag_VAMPIRISM ) &&
+ parts->test( iteminfo_parts::FOOD_CANNIBALISM ) ) {
+- if( !you.has_trait_flag( trait_flag_CANNIBAL ) ) {
++ if( !you.has_trait_flag( trait_flag_CANNIBAL ) && !you.has_trait_flag( trait_flag_VAMPIRE ) ) {
+ info.emplace_back( "DESCRIPTION",
+- _( "* This food contains <bad>human flesh</bad>." ) );
++ _( "* This food contains <good>human flesh</good>." ) );
+ } else {
+ info.emplace_back( "DESCRIPTION",
+- _( "* This food contains <good>human flesh</good>." ) );
++ _( "* This food contains <bad>human flesh</bad>." ) );
+ }
+ }
+
+- if( food_item->is_tainted() && parts->test( iteminfo_parts::FOOD_CANNIBALISM ) ) {
++ if( food_item->is_tainted() && ( parts->test( iteminfo_parts::FOOD_CANNIBALISM ) ||
++ parts->test( iteminfo_parts::FOOD_VAMPIRISM ) ) ) {
+ info.emplace_back( "DESCRIPTION",
+ _( "* This food is <bad>tainted</bad> and will poison you." ) );
+ }
+@@ -4041,6 +4059,7 @@
+ case edible_rating::allergy:
+ case edible_rating::allergy_weak:
+ case edible_rating::cannibalism:
++ case edible_rating::vampirism:
+ ret = c_red;
+ break;
+ case edible_rating::rotten:
+
+--- a/src/item_factory.cpp
++++ b/src/item_factory.cpp
+@@ -2470,6 +2470,7 @@
+ // First allergens:
+ // An item is an allergen even if it has trace amounts of allergenic material
+ std::make_pair( material_id( "hflesh" ), flag_CANNIBALISM ),
++ std::make_pair( material_id( "blood" ), flag_VAMPIRISM ),
+
+ std::make_pair( material_id( "hflesh" ), flag_ALLERGEN_MEAT ),
+ std::make_pair( material_id( "iflesh" ), flag_ALLERGEN_MEAT ),
+@@ -2484,10 +2485,16 @@
+ std::make_pair( material_id( "mushroom" ), flag_ALLERGEN_VEGGY ),
+ std::make_pair( material_id( "milk" ), flag_ALLERGEN_MILK ),
+ std::make_pair( material_id( "egg" ), flag_ALLERGEN_EGG ),
++ std::make_pair( material_id( "alcohol" ), flag_ALLERGEN_ALCOHOL ),
++ std::make_pair( material_id( "foodplace_foodstuff" ), flag_ALLERGEN_FOODSTUFF ),
++ std::make_pair( material_id( "water" ), flag_ALLERGEN_WATER ),
++ std::make_pair( material_id( "honey" ), flag_ALLERGEN_HONEY ),
+ std::make_pair( material_id( "junk" ), flag_ALLERGEN_JUNK ),
+ // Not food, but we can keep it here
+ std::make_pair( material_id( "wool" ), flag_ALLERGEN_WOOL ),
+ // Now "made of". Those flags should not be passed
++ std::make_pair( material_id( "blood" ), flag_VAMPIRISM_OK ),
++ std::make_pair( material_id( "blood" ), flag_CARNIVORE_OK ),
+ std::make_pair( material_id( "flesh" ), flag_CARNIVORE_OK ),
+ std::make_pair( material_id( "hflesh" ), flag_CARNIVORE_OK ),
+ std::make_pair( material_id( "iflesh" ), flag_CARNIVORE_OK ),
+
+--- a/src/iteminfo_query.h
++++ b/src/iteminfo_query.h
+@@ -36,6 +36,7 @@
+ FOOD_VITAMINS,
+ FOOD_VIT_EFFECTS,
+ FOOD_CANNIBALISM,
++ FOOD_VAMPIRISM,
+ FOOD_TAINT,
+ FOOD_POISON,
+ FOOD_HALLUCINOGENIC,
+
+--- a/src/map_field.cpp
++++ b/src/map_field.cpp
+@@ -91,6 +91,7 @@
+ static const trait_id trait_M_SKIN3( "M_SKIN3" );
+ static const trait_id trait_THRESH_MARLOSS( "THRESH_MARLOSS" );
+ static const trait_id trait_THRESH_MYCUS( "THRESH_MYCUS" );
++static const trait_id trait_VAMP_SKIN( "VAMP_SKIN" );
+ static const trait_id trait_WEB_WALKER( "WEB_WALKER" );
+
+ void map::create_burnproducts( const tripoint &p, const item &fuel, const units::mass &burned_mass )
+@@ -1405,7 +1405,8 @@
+ if( ( cur.get_field_intensity() > 1 || !one_in( 3 ) ) && ( !inside || one_in( 3 ) ) ) {
+ u.add_env_effect( effect_teargas, bp_mouth, 5, 20_seconds );
+ }
+- if( cur.get_field_intensity() > 1 && ( !inside || one_in( 3 ) ) ) {
++ if( !( u.has_trait( trait_VAMP_SKIN ) ) && cur.get_field_intensity() > 1 && ( !inside ||
++ one_in( 3 ) ) ) {
+ u.add_env_effect( effect_blind, bp_eyes, cur.get_field_intensity() * 2, 10_seconds );
+ }
+ }
+@@ -1539,7 +1539,7 @@
+ // The gas won't harm you inside a vehicle.
+ if( !inside ) {
+ // Full body suits protect you from the effects of the gas.
+- if( !( u.worn_with_flag( STATIC( flag_id( "GAS_PROOF" ) ) ) &&
++ if( !( u.has_trait( trait_VAMP_SKIN ) ) && !( u.worn_with_flag( STATIC( flag_id( "GAS_PROOF" ) ) ) &&
+ u.get_env_resist( bodypart_id( "mouth" ) ) >= 15 &&
+ u.get_env_resist( bodypart_id( "eyes" ) ) >= 15 ) ) {
+ const int intensity = cur.get_field_intensity();
+
+--- a/src/memorial_logger.cpp
++++ b/src/memorial_logger.cpp
+@@ -79,6 +79,7 @@
+ static const trap_str_id tr_snake( "tr_snake" );
+ static const trap_str_id tr_glass_pit( "tr_glass_pit" );
+
++static const trait_id trait_THRESH_REAL_VAMP( "THRESH_REAL_VAMP" );
+ static const trait_id trait_CANNIBAL( "CANNIBAL" );
+ static const trait_id trait_PSYCHOPATH( "PSYCHOPATH" );
+ static const trait_id trait_SAPIOVORE( "SAPIOVORE" );
+@@ -488,6 +488,7 @@
+ character_id ch = e.get<character_id>( "killer" );
+ if( ch == g->u.getID() ) {
+ std::string name = e.get<cata_variant_type::string>( "victim_name" );
++ bool vampire = g->u.has_trait( trait_THRESH_REAL_VAMP );
+ bool cannibal = g->u.has_trait( trait_CANNIBAL );
+ bool psycho = g->u.has_trait( trait_PSYCHOPATH );
+ if( g->u.has_trait( trait_SAPIOVORE ) ) {
+@@ -512,6 +512,10 @@
+ add( pgettext( "memorial_male", "Killed an innocent, %s." ),
+ pgettext( "memorial_female", "Killed an innocent, %s." ),
+ name );
++ } else if( vampire ) {
++ add( pgettext( "memorial_male", "Killed an innocent human, %s." ),
++ pgettext( "memorial_female", "Killed an innocent human, %s." ),
++ name );
+ } else {
+ add( pgettext( "memorial_male",
+ "Killed an innocent person, %s, in cold blood and "
+
+--- a/src/morale_types.cpp
++++ b/src/morale_types.cpp
+@@ -36,6 +36,7 @@
+ const morale_type MORALE_CRAVING_MARLOSS( "morale_craving_marloss" );
+ const morale_type MORALE_FOOD_BAD( "morale_food_bad" );
+ const morale_type MORALE_CANNIBAL( "morale_cannibal" );
++const morale_type MORALE_VAMPIRE( "morale_vampire" );
+ const morale_type MORALE_VEGETARIAN( "morale_vegetarian" );
+ const morale_type MORALE_MEATARIAN( "morale_meatarian" );
+ const morale_type MORALE_ANTIFRUIT( "morale_antifruit" );
+
+--- a/src/morale_types.h
++++ b/src/morale_types.h
+@@ -62,6 +62,7 @@
+ extern const morale_type MORALE_CRAVING_MARLOSS;
+ extern const morale_type MORALE_FOOD_BAD;
+ extern const morale_type MORALE_CANNIBAL;
++extern const morale_type MORALE_VAMPIRE;
+ extern const morale_type MORALE_VEGETARIAN;
+ extern const morale_type MORALE_MEATARIAN;
+ extern const morale_type MORALE_ANTIFRUIT;
+
+--- a/src/mutation.cpp
++++ b/src/mutation.cpp
+@@ -80,6 +80,7 @@
+ static const trait_id trait_STR_ALPHA( "STR_ALPHA" );
+ static const trait_id trait_THRESH_MARLOSS( "THRESH_MARLOSS" );
+ static const trait_id trait_THRESH_MYCUS( "THRESH_MYCUS" );
++static const trait_id trait_VAMP_SKIN( "VAMP_SKIN" );
+ static const trait_id trait_TREE_COMMUNION( "TREE_COMMUNION" );
+ static const trait_id trait_VOMITOUS( "VOMITOUS" );
+ static const trait_id trait_WEB_WEAVER( "WEB_WEAVER" );
+@@ -860,6 +860,11 @@
+ if( !mutagen ) {
+ return;
+ }
++ if( has_trait( trait_VAMP_SKIN ) ) {
++ add_msg_if_player( m_good, _( "Your Vampire blood quickly destroys the mutagenic contagion." ) );
++ remove_effect( effect_accumulated_mutagen );
++ return;
++ }
+ float mut_power = to_turns<float>( mutagen.get_duration() ) / to_turns<float>
+ ( mutagen.get_int_dur_factor() );
+ add_msg_if_player( m_debug, "Mutation accumulation: %.1f", mut_power );
+@@ -904,6 +904,10 @@
+ {
+ bool force_bad = one_in( 3 );
+ bool force_good = false;
++ if( has_trait( trait_VAMP_SKIN ) ) {
++ add_msg_if_player( m_good, _( "Your Vampire blood quickly destroys the mutagenic contagion." ) );
++ return;
++ }
+ if( has_trait( trait_ROBUST ) && force_bad ) {
+ // Robust Genetics gives you a 33% chance for a good mutation,
+ // instead of the 33% chance of a bad one.
+
+--- a/src/npc.cpp
++++ b/src/npc.cpp
+@@ -118,6 +118,7 @@
+ static const trait_id trait_SAPIOVORE( "SAPIOVORE" );
+ static const trait_id trait_SCHIZOPHRENIC( "SCHIZOPHRENIC" );
+ static const trait_id trait_TERRIFYING( "TERRIFYING" );
++static const trait_id trait_THRESH_REAL_VAMP( "THRESH_REAL_VAMP" );
+
+ class monfaction;
+
+@@ -2492,12 +2492,15 @@
+ }
+
+ if( get_killer() == &g->u && ( !guaranteed_hostile() || hit_by_player ) ) {
++ bool vampire = g->u.has_trait( trait_THRESH_REAL_VAMP );
+ bool cannibal = g->u.has_trait( trait_CANNIBAL );
+ bool psycho = g->u.has_trait( trait_PSYCHOPATH ) || g->u.has_trait( trait_KILLER );
+ if( g->u.has_trait( trait_SAPIOVORE ) || psycho ) {
+ // No morale penalty
+ } else if( cannibal ) {
+ g->u.add_morale( MORALE_KILLED_INNOCENT, -5, 0, 2_days, 3_hours );
++ } else if( vampire ) {
++ g->u.add_morale( MORALE_KILLED_INNOCENT, -5, 0, 2_days, 3_hours );
+ } else {
+ g->u.add_morale( MORALE_KILLED_INNOCENT, -100, 0, 2_days, 3_hours );
+ }
+
+--- a/src/player_hardcoded_effects.cpp
++++ b/src/player_hardcoded_effects.cpp
+@@ -105,6 +105,8 @@
+ static const trait_id trait_SEESLEEP( "SEESLEEP" );
+ static const trait_id trait_SCHIZOPHRENIC( "SCHIZOPHRENIC" );
+ static const trait_id trait_THRESH_MYCUS( "THRESH_MYCUS" );
++static const trait_id trait_THRESH_REAL_VAMP( "THRESH_REAL_VAMP" );
++static const trait_id trait_VAMP_SKIN( "VAMP_SKIN" );
+ static const trait_id trait_WATERSLEEP( "WATERSLEEP" );
+
+ static void eff_fun_onfire( player &u, effect &it )
+@@ -841,7 +841,9 @@
+ }
+
+ if( dur > 1800_minutes && one_in( 300 * 512 ) ) {
+- if( !has_trait( trait_NOPAIN ) ) {
++ if( has_trait( trait_VAMP_SKIN ) ) {
++ return;
++ } else if( !has_trait( trait_NOPAIN ) ) {
+ add_msg_if_player( m_bad,
+ _( "Your heart spasms painfully and stops, dragging you back to reality as you die." ) );
+ } else {
+
+--- a/src/suffer.cpp
++++ b/src/suffer.cpp
+@@ -153,6 +153,8 @@
+ static const trait_id trait_TROGLO2( "TROGLO2" );
+ static const trait_id trait_TROGLO3( "TROGLO3" );
+ static const trait_id trait_UNSTABLE( "UNSTABLE" );
++static const trait_id trait_VAMP_CURSE( "VAMP_CURSE" );
++static const trait_id trait_VAMP_SKIN( "VAMP_SKIN" );
+ static const trait_id trait_VOMITOUS( "VOMITOUS" );
+ static const trait_id trait_WEB_SPINNER( "WEB_SPINNER" );
+ static const trait_id trait_WEB_WEAVER( "WEB_WEAVER" );
+@@ -251,7 +251,8 @@
+ if( has_trait( trait_DEBUG_STAMINA ) ) {
+ return;
+ }
+- if( !has_trait( trait_GILLS ) && !has_trait( trait_GILLS_CEPH ) ) {
++ if( !has_trait( trait_GILLS ) && !has_trait( trait_GILLS_CEPH ) &&
++ !has_trait( trait_VAMP_SKIN ) ) {
+ oxygen--;
+ }
+ if( oxygen < 12 && worn_with_flag( flag_REBREATHER ) ) {
+@@ -751,7 +751,8 @@
+ return;
+ }
+
+- if( has_trait( trait_ALBINO ) || has_effect( effect_datura ) || has_trait( trait_SUNBURN ) ) {
++ if( has_trait( trait_ALBINO ) || has_effect( effect_datura ) || has_trait( trait_SUNBURN ) ||
++ has_trait( trait_VAMP_CURSE ) ) {
+ suffer_from_sunburn();
+ }
+
+@@ -778,6 +778,13 @@
+ mod_int_bonus( -4 );
+ mod_per_bonus( -4 );
+ }
++ if( has_trait( trait_VAMP_CURSE ) ) {
++ mod_str_bonus( -4 );
++ mod_dex_bonus( -4 );
++ add_miss_reason( _( "You can't tolerate the sunlight!" ), 4 );
++ mod_int_bonus( -4 );
++ mod_per_bonus( -4 );
++ }
+ }
+
+ std::map<bodypart_id, float> Character::bodypart_exposure()
+@@ -816,7 +816,8 @@
+
+ void Character::suffer_from_sunburn()
+ {
+- if( !has_trait( trait_ALBINO ) && !has_effect( effect_datura ) && !has_trait( trait_SUNBURN ) ) {
++ if( !has_trait( trait_ALBINO ) && !has_effect( effect_datura ) && !has_trait( trait_SUNBURN ) &&
++ !has_trait( trait_VAMP_CURSE ) ) {
+ return;
+ }
+
+@@ -834,6 +834,12 @@
+ return;
+ }
+ sunlight_effect = _( "The sunlight burns" );
++ } else if( has_trait( trait_VAMP_CURSE ) ) {
++ // Sunburn effects occur about 10 times per minute
++ if( !one_turn_in( 6_seconds ) ) {
++ return;
++ }
++ sunlight_effect = _( "The sunlight sears" );
+ }
+
+ // Sunglasses can keep the sun off the eyes.
+@@ -917,7 +917,7 @@
+ }
+
+ // Solar Sensitivity (SUNBURN) trait causes injury to exposed parts
+- if( has_trait( trait_SUNBURN ) ) {
++ if( has_trait( trait_SUNBURN ) || has_trait( trait_VAMP_CURSE ) ) {
+ mod_pain( 1 );
+ // Check exposure of all body parts
+ for( const std::pair<const bodypart_id, float> &bp_exp : bp_exposure ) {
+@@ -1663,7 +1664,7 @@
+
+ healing_factor *= mutation_value( "mending_modifier" );
+
+- if( has_trait( trait_REGEN_LIZ ) ) {
++ if( has_trait( trait_REGEN_LIZ ) || has_trait( trait_VAMP_SKIN ) ) {
+ needs_splint = false;
+ }
+
+
+--- a/data/json/field_type.json
++++ b/data/json/field_type.json
+@@ -299,7 +299,7 @@
+ "dirty_transparency_cache": true,
+ "percent_spread": 10,
+ "outdoor_age_speedup": "0 turns",
+- "immunity_data": { "body_part_env_resistance": [ [ "mouth", 7 ] ] },
++ "immunity_data": { "body_part_env_resistance": [ [ "mouth", 7 ] ], "traits": [ "VAMP_SKIN" ] },
+ "priority": 8,
+ "half_life": "2 minutes",
+ "phase": "gas",
+@@ -385,7 +385,7 @@
+ "outdoor_age_speedup": "3 minutes",
+ "dirty_transparency_cache": true,
+ "has_fume": true,
+- "immunity_data": { "body_part_env_resistance": [ [ "mouth", 15 ] ] },
++ "immunity_data": { "body_part_env_resistance": [ [ "mouth", 15 ] ], "traits": [ "VAMP_SKIN" ] },
+ "priority": 8,
+ "half_life": "10 minutes",
+ "phase": "gas",
+@@ -414,7 +414,7 @@
+ "outdoor_age_speedup": "0 turns",
+ "dirty_transparency_cache": true,
+ "has_fume": true,
+- "immunity_data": { "body_part_env_resistance": [ [ "mouth", 15 ] ] },
++ "immunity_data": { "body_part_env_resistance": [ [ "mouth", 15 ], [ "eyes", 15 ] ], "traits": [ "VAMP_SKIN" ] },
+ "priority": 8,
+ "half_life": "5 minutes",
+ "phase": "gas",
+@@ -460,7 +460,7 @@
+ "wandering_field": "fd_toxic_gas",
+ "gas_absorption_factor": 15,
+ "dirty_transparency_cache": true,
+- "immunity_data": { "body_part_env_resistance": [ [ "mouth", 15 ] ] },
++ "immunity_data": { "body_part_env_resistance": [ [ "mouth", 15 ] ], "traits": [ "VAMP_SKIN" ] },
+ "phase": "gas",
+ "display_items": false,
+ "display_field": true,
+@@ -577,7 +577,7 @@
+ "outdoor_age_speedup": "3 minutes",
+ "dirty_transparency_cache": true,
+ "has_fume": true,
+- "immunity_data": { "body_part_env_resistance": [ [ "mouth", 15 ] ] },
++ "immunity_data": { "body_part_env_resistance": [ [ "mouth", 15 ] ], "traits": [ "VAMP_SKIN" ] },
+ "priority": 8,
+ "half_life": "10 minutes",
+ "phase": "gas",
+@@ -956,7 +956,7 @@
+ "outdoor_age_speedup": "5 minutes",
+ "dirty_transparency_cache": true,
+ "has_fume": true,
+- "immunity_data": { "body_part_env_resistance": [ [ "mouth", 15 ] ] },
++ "immunity_data": { "body_part_env_resistance": [ [ "mouth", 15 ] ], "traits": [ "VAMP_SKIN" ] },
+ "priority": 8,
+ "half_life": "50 minutes",
+ "phase": "gas",
+@@ -978,7 +978,7 @@
+ "outdoor_age_speedup": "1 minutes",
+ "dirty_transparency_cache": true,
+ "has_fume": true,
+- "immunity_data": { "body_part_env_resistance": [ [ "mouth", 15 ] ] },
++ "immunity_data": { "body_part_env_resistance": [ [ "mouth", 15 ] ], "traits": [ "VAMP_SKIN" ] },
+ "priority": 8,
+ "half_life": "15 minutes",
+ "phase": "gas",
+@@ -1225,7 +1225,7 @@
+ "outdoor_age_speedup": "3 minutes",
+ "dirty_transparency_cache": true,
+ "has_fume": true,
+- "immunity_data": { "body_part_env_resistance": [ [ "mouth", 15 ] ] },
++ "immunity_data": { "body_part_env_resistance": [ [ "mouth", 15 ] ], "traits": [ "VAMP_SKIN" ] },
+ "priority": -1,
+ "half_life": "10 minutes",
+ "phase": "gas"
+@@ -1245,7 +1245,7 @@
+ "outdoor_age_speedup": "1 minutes",
+ "dirty_transparency_cache": true,
+ "has_fume": true,
+- "immunity_data": { "body_part_env_resistance": [ [ "mouth", 15 ] ] },
++ "immunity_data": { "body_part_env_resistance": [ [ "mouth", 15 ] ], "traits": [ "VAMP_SKIN" ] },
+ "priority": 8,
+ "half_life": "30 minutes",
+ "phase": "gas",
+@@ -1267,7 +1267,7 @@
+ "outdoor_age_speedup": "1 minutes",
+ "dirty_transparency_cache": true,
+ "has_fume": true,
+- "immunity_data": { "body_part_env_resistance": [ [ "mouth", 15 ] ] },
++ "immunity_data": { "body_part_env_resistance": [ [ "mouth", 15 ] ], "traits": [ "VAMP_SKIN" ] },
+ "priority": 8,
+ "half_life": "30 minutes",
+ "phase": "gas",
+
+--- a/data/json/flags.json
++++ b/data/json/flags.json
+@@ -1117,6 +1117,26 @@
+ "context": [ "COMESTIBLE" ]
+ },
+ {
++ "id": "ALLERGEN_HONEY",
++ "type": "json_flag",
++ "context": [ "COMESTIBLE" ]
++ },
++ {
++ "id": "ALLERGEN_ALCOHOL",
++ "type": "json_flag",
++ "context": [ "COMESTIBLE" ]
++ },
++ {
++ "id": "ALLERGEN_FOODSTUFF",
++ "type": "json_flag",
++ "context": [ "COMESTIBLE" ]
++ },
++ {
++ "id": "ALLERGEN_WATER",
++ "type": "json_flag",
++ "context": [ "COMESTIBLE" ]
++ },
++ {
+ "id": "ALLERGEN_JUNK",
+ "type": "json_flag",
+ "context": [ "COMESTIBLE" ]
+@@ -1197,6 +1197,16 @@
+ "context": [ ]
+ },
+ {
++ "id": "VAMPIRISM",
++ "type": "json_flag",
++ "context": [ ]
++ },
++ {
++ "id": "VAMPIRISM_OK",
++ "type": "json_flag",
++ "context": [ ]
++ },
++ {
+ "id": "CASING",
+ "type": "json_flag",
+ "context": [ ]
+
+--- a/data/json/flags_mutation.json
++++ b/data/json/flags_mutation.json
+@@ -128,5 +132,9 @@
+ {
+ "id": "UNARMED_BONUS",
+ "type": "mutation_flag"
++ },
++ {
++ "id": "VAMPIRE",
++ "type": "mutation_flag"
+ }
+ ]
+--- a/data/json/morale_types.json
++++ b/data/json/morale_types.json
+@@ -125,6 +125,11 @@
+ "text": "Ate Human Flesh"
+ },
+ {
++ "id": "morale_vampire",
++ "type": "morale_type",
++ "text": "Drank Human Blood"
++ },
++ {
+ "id": "morale_vegetarian",
+ "type": "morale_type",
+ "text": "Ate Meat"
+
+--- a/data/json/mutations/mutation_ordering.json
++++ b/data/json/mutations/mutation_ordering.json
+@@ -73,6 +73,7 @@
+ "TROGLO2",
+ "TROGLO3",
+ "URSINE_FUR",
++ "VAMP_SKIN",
+ "VISCOUS"
+ ],
+ "order": 1500
+@@ -180,7 +181,7 @@
+ { "id": [ "FLOWERS" ], "order": 5000 },
+ { "id": [ "ELFA_EARS", "FELINE_EARS", "LUPINE_EARS", "URSINE_EARS" ], "order": 5500 },
+ { "id": [ "ANTENNAE", "ANTLERS", "CURVED_HORNS", "HORNS", "POINTED_HORNS" ], "order": 6000 },
+- { "id": [ "COMPOUND_EYES", "ELFAEYES", "FEL_EYE", "LIZ_EYE" ], "order": 6500 },
++ { "id": [ "COMPOUND_EYES", "ELFAEYES", "FEL_EYE", "LIZ_EYE", "REAL_VAMP_EYES" ], "order": 6500 },
+ {
+ "id": [
+ "BEAK",
diff --git a/0014-portable-generator-engine.patch b/vehicles-01_portable-generator-engine.patch
index 70e1c2d..70e1c2d 100644
--- a/0014-portable-generator-engine.patch
+++ b/vehicles-01_portable-generator-engine.patch
diff --git a/vehicles-02_fix-fbi-car-name.patch b/vehicles-02_fix-fbi-car-name.patch
new file mode 100644
index 0000000..00dd303
--- /dev/null
+++ b/vehicles-02_fix-fbi-car-name.patch
@@ -0,0 +1,11 @@
+--- a/data/json/vehicles/emergency.json
++++ b/data/json/vehicles/emergency.json
+@@ -167,7 +167,7 @@
+ {
+ "id": "car_fbi",
+ "type": "vehicle",
+- "name": "FBI, Emergency",
++ "name": "FBI Car",
+ "blueprint": [
+ [ "o-++-o" ],
+ [ "+=##'|" ],
diff --git a/vehicles-03_black-box-can-be-installed.patch b/vehicles-03_black-box-can-be-installed.patch
new file mode 100644
index 0000000..aef147b
--- /dev/null
+++ b/vehicles-03_black-box-can-be-installed.patch
@@ -0,0 +1,14 @@
+--- a/data/json/vehicleparts/vehicle_parts.json
++++ b/data/json/vehicleparts/vehicle_parts.json
+@@ -637,7 +637,10 @@
+ "broken_color": "dark_gray",
+ "flags": [ "NO_REPAIR" ],
+ "requirements": {
+- "install": { "skills": [ [ "mechanics", 2 ] ], "qualities": [ { "id": "SCREW", "level": 3 }, { "id": "WRENCH", "level": 3 } ] },
++ "install": {
++ "skills": [ [ "mechanics", 2 ] ],
++ "qualities": [ { "id": "SCREW_FINE", "level": 1 }, { "id": "WRENCH_FINE", "level": 1 } ]
++ },
+ "removal": { "skills": [ [ "mechanics", 2 ] ], "using": [ [ "vehicle_screw", 1 ] ] }
+ },
+ "breaks_into": [
diff --git a/weapon-02_Fix-usp45-load-order.patch b/weapon-02_Fix-usp45-load-order.patch
new file mode 100644
index 0000000..0469e75
--- /dev/null
+++ b/weapon-02_Fix-usp45-load-order.patch
@@ -0,0 +1,30 @@
+--- a/data/json/items/gun/45.json
++++ b/data/json/items/gun/45.json
+@@ -206,14 +206,24 @@
+ },
+ {
+ "id": "usp_45",
+- "copy-from": "usp_9mm",
++ "copy-from": "pistol_base",
+ "type": "GUN",
+ "name": { "str": "USP .45" },
++ "description": "A popular pistol, widely used among law enforcement. Extensively tested for durability, it has been found to stay accurate even after being subjected to extreme abuse.",
+ "weight": "930 g",
+- "ammo": "45",
++ "volume": "500 ml",
++ "price": "680 USD",
+ "price_postapoc": "25 USD",
+- "ranged_damage": { "damage_type": "bullet", "amount": 0 },
++ "to_hit": -2,
++ "material": [ "steel", "plastic" ],
++ "color": "dark_gray",
++ "ammo": "45",
++ "dispersion": 400,
++ "durability": 9,
++ "blackpowder_tolerance": 48,
++ "min_cycle_recoil": 450,
+ "built_in_mods": [ "match_trigger" ],
++ "magazine_well": "250 ml",
+ "magazines": [ [ "45", [ "usp45mag" ] ] ]
+ },
+ {