diff --git a/.github/vcpkg_triplets/x64-windows-static.cmake b/.github/vcpkg_triplets/x64-windows-static.cmake
new file mode 100644
index 0000000000000..66655f1877714
--- /dev/null
+++ b/.github/vcpkg_triplets/x64-windows-static.cmake
@@ -0,0 +1,5 @@
+set(VCPKG_TARGET_ARCHITECTURE x64)
+set(VCPKG_CRT_LINKAGE static)
+set(VCPKG_LIBRARY_LINKAGE static)
+
+set(VCPKG_BUILD_TYPE release)
diff --git a/.github/vcpkg_triplets/x64-windows.cmake b/.github/vcpkg_triplets/x64-windows.cmake
new file mode 100644
index 0000000000000..1ae9006118fb3
--- /dev/null
+++ b/.github/vcpkg_triplets/x64-windows.cmake
@@ -0,0 +1,5 @@
+set(VCPKG_TARGET_ARCHITECTURE x64)
+set(VCPKG_CRT_LINKAGE dynamic)
+set(VCPKG_LIBRARY_LINKAGE dynamic)
+
+set(VCPKG_BUILD_TYPE release)
diff --git a/.github/workflows/msvc-full-features.yml b/.github/workflows/msvc-full-features.yml
new file mode 100644
index 0000000000000..6758ca01ed785
--- /dev/null
+++ b/.github/workflows/msvc-full-features.yml
@@ -0,0 +1,91 @@
+name: Cataclysm Windows build
+
+on:
+ push:
+ branches:
+ - master
+ paths-ignore:
+ - 'android/**'
+ - 'build-data/osx/**'
+ - 'doc/**'
+ - 'doxygen_doc/**'
+ - 'lgtm/**'
+ - 'msvc-object_creator/**'
+ - 'tools/**'
+ - 'utilities/**'
+ pull_request:
+ branches:
+ - master
+ paths-ignore:
+ - 'android/**'
+ - 'build-data/osx/**'
+ - 'doc/**'
+ - 'doxygen_doc/**'
+ - 'lgtm/**'
+ - 'msvc-object_creator/**'
+ - 'tools/**'
+ - 'utilities/**'
+
+env:
+ # There's not enough disk space to build both release and debug versions of
+ # our dependencies, so we hack the triplet file to build only release versions
+ # Have to use github.workspace because runner namespace isn't available yet.
+ VCPKG_OVERLAY_TRIPLETS: ${{ github.workspace }}\.github\vcpkg_triplets
+
+jobs:
+ build_catatclysm:
+ name: Build
+ runs-on: windows-2019
+
+ steps:
+ - name: checkout repository
+ uses: actions/checkout@v2
+ with:
+ fetch-depth: 1
+
+ - name: Add msbuild to PATH
+ uses: microsoft/setup-msbuild@v1.0.2
+
+ - name: Restore artifacts, or run vcpkg, build and cache artifacts
+ uses: lukka/run-vcpkg@main
+ id: runvcpkg
+ with:
+ additionalCachedPaths: '${{ runner.workspace }}/Cataclysm-DDA/msvc-full-features/vcpkg_installed'
+ appendedCacheKey: ${{ hashFiles( 'msvc-full-features/vcpkg.json', '.github/vcpkg_triplets/**' ) }}
+ setupOnly: true
+ vcpkgDirectory: '${{ runner.workspace }}/b/vcpkg'
+ # We have to use at least this version of vcpkg to include fixes for yasm-tool's
+ # availability only as an x86 host tool. Keep it in sync with the builtin-baseline
+ # field in vcpkg.json. Caching happens as a post-action which runs at the end of
+ # the whole workflow, after vcpkg install happens during msbuild run.
+ vcpkgGitCommitId: '49b67d9cb856424ff69f10e7721aec5299624268'
+
+ - name: Integrate vcpkg
+ run: |
+ vcpkg integrate install
+
+ - name: Build
+ run: |
+ cd msvc-full-features
+ msbuild -m -p:Configuration=Release -p:Platform=x64 -target:Cataclysm-vcpkg-static Cataclysm-vcpkg-static.sln
+
+ - name: Dump logs if build failed
+ if: failure()
+ run: |
+ echo =================================================
+ Get-ChildItem "${{ runner.workspace }}/Cataclysm-DDA/msvc-full-features/vcpkg_installed" -Recurse
+ echo =================================================
+ Get-ChildItem "${{ runner.workspace }}/b/vcpkg/buildtrees" |
+ Foreach-Object {
+ Get-ChildItem $_.FullName -Filter *.log |
+ Foreach-Object {
+ echo =================================================
+ echo $_.FullName
+ echo =================================================
+ type $_.FullName
+ }
+ }
+
+ - name: Clean
+ run: |
+ Get-ChildItem -Path Cataclysm-lib-vcpkg-static-Release-x64.* | Foreach-Object { rm $_.FullName }
diff --git a/.github/workflows/object_creator.yml b/.github/workflows/object_creator.yml
new file mode 100644
index 0000000000000..13d76ff5f919f
--- /dev/null
+++ b/.github/workflows/object_creator.yml
@@ -0,0 +1,91 @@
+name: ObjectCreator Windows build
+
+on:
+ push:
+ branches:
+ - master
+ paths-ignore:
+ - 'android/**'
+ - 'build-data/osx/**'
+ - 'doc/**'
+ - 'doxygen_doc/**'
+ - 'lgtm/**'
+ - 'tools/**'
+ - 'utilities/**'
+ pull_request:
+ branches:
+ - master
+ paths-ignore:
+ - 'android/**'
+ - 'build-data/osx/**'
+ - 'doc/**'
+ - 'doxygen_doc/**'
+ - 'lgtm/**'
+ - 'tools/**'
+ - 'utilities/**'
+
+env:
+ # There's not enough disk space to build both release and debug versions of
+ # our dependencies, so we hack the triplet file to build only release versions
+ # Have to use github.workspace because runner namespace isn't available yet.
+ VCPKG_OVERLAY_TRIPLETS: ${{ github.workspace }}\.github\vcpkg_triplets
+
+jobs:
+ build_object_creator:
+ name: Build
+ runs-on: windows-2019
+
+ steps:
+ - name: checkout repository
+ uses: actions/checkout@v2
+ with:
+ fetch-depth: 1
+
+ - name: Add msbuild to PATH
+ uses: microsoft/setup-msbuild@v1.0.2
+
+ - name: Restore artifacts, or run vcpkg, build and cache artifacts
+ uses: lukka/run-vcpkg@main
+ id: runvcpkg
+ with:
+ additionalCachedPaths: '${{ runner.workspace }}/Cataclysm-DDA/msvc-full-features/vcpkg_installed;${{ runner.workspace }}/Cataclysm-DDA/msvc-object_creator/vcpkg_installed'
+ appendedCacheKey: ${{ hashFiles( '$msvc-full-features/vcpkg.json', 'msvc-object_creator/vcpkg.json', '.github/vcpkg_triplets/**' ) }}
+ setupOnly: true
+ vcpkgDirectory: '${{ runner.workspace }}/b/vcpkg'
+ # We have to use at least this version of vcpkg to include fixes for yasm-tool's
+ # availability only as an x86 host tool. Keep it in sync with the builtin-baseline
+ # field in vcpkg.json. Caching happens as a post-action which runs at the end of
+ # the whole workflow, after vcpkg install happens during msbuild run.
+ vcpkgGitCommitId: '49b67d9cb856424ff69f10e7721aec5299624268'
+
+ - name: Integrate vcpkg
+ run: |
+ vcpkg integrate install
+
+ - name: Build
+ run: |
+ cd msvc-object_creator
+ msbuild -m -p:Configuration=Release -p:Platform=x64 ObjectCreator-vcpkg-static.sln
+
+ - name: Dump logs if build failed
+ if: failure()
+ run: |
+ echo =================================================
+ Get-ChildItem "${{ runner.workspace }}/Cataclysm-DDA/msvc-full-features/vcpkg_installed" -Recurse
+ echo =================================================
+ Get-ChildItem "${{ runner.workspace }}/Cataclysm-DDA/msvc-object_creator/vcpkg_installed" -Recurse
+ echo =================================================
+ Get-ChildItem "${{ runner.workspace }}/b/vcpkg/buildtrees" |
+ Foreach-Object {
+ Get-ChildItem $_.FullName -Filter *.log |
+ Foreach-Object {
+ echo =================================================
+ echo $_.FullName
+ echo =================================================
+ type $_.FullName
+ }
+ }
+
+ - name: Clean
+ run: |
+ Get-ChildItem -Path Cataclysm-lib-vcpkg-static-Release-x64.*,ObjectCreator-vcpkg-static-Release-x64.* | Foreach-Object { rm $_.FullName }
diff --git a/data/json/effects.json b/data/json/effects.json
index 2317b34640263..6bfe495a9d7d5 100644
--- a/data/json/effects.json
+++ b/data/json/effects.json
@@ -632,6 +632,7 @@
"int_add_val": 1,
"int_decay_step": -1,
"int_decay_tick": 90,
+ "int_decay_remove": true,
"resist_traits": [ "ELFA_NV" ],
"base_mods": { "per_mod": [ -3, 0 ] },
"scaling_mods": { "per_mod": [ -2, -1 ] }
diff --git a/data/json/items/ammo/nail.json b/data/json/items/ammo/nail.json
index a0b82e271a860..9aea0f4238931 100644
--- a/data/json/items/ammo/nail.json
+++ b/data/json/items/ammo/nail.json
@@ -34,6 +34,6 @@
"range": 3,
"damage": { "damage_type": "bullet", "amount": 3, "armor_penetration": 1 },
"dispersion": 180,
- "effects": [ "NON_FOULING" ]
+ "effects": [ "NON_FOULING", "HURT_WHEN_WIELDED" ]
}
]
diff --git a/data/json/items/comestibles/carnivore.json b/data/json/items/comestibles/carnivore.json
index a524d63a527ac..091de3a93c7b3 100644
--- a/data/json/items/comestibles/carnivore.json
+++ b/data/json/items/comestibles/carnivore.json
@@ -307,6 +307,46 @@
"fun": 0,
"flags": [ "EATEN_HOT", "NUTRIENT_OVERRIDE", "BAD_TASTE" ]
},
+ {
+ "type": "COMESTIBLE",
+ "id": "meat_mutant_tainted",
+ "copy-from": "mutant_meat",
+ "name": { "str": "chunk of tainted mutant meat", "str_pl": "chunks of tainted mutant meat" },
+ "color": "magenta",
+ "snippet_category": "tainted_mutant_meat_desc",
+ "looks_like": "meat",
+ "cooks_like": "meat_mutant_tainted_cooked",
+ "spoils_in": "4 hours",
+ "use_action": [ "POISON" ],
+ "price": 0,
+ "price_postapoc": 5,
+ "fun": -15,
+ "flags": [ "TRADER_AVOID", "SMOKABLE", "BAD_TASTE", "RAW" ],
+ "smoking_result": "meat_mutant_tainted_smoked"
+ },
+ {
+ "type": "COMESTIBLE",
+ "id": "meat_mutant_tainted_cooked",
+ "copy-from": "meat_mutant_tainted",
+ "name": { "str": "cooked tainted mutant meat" },
+ "snippet_category": "cooked_tainted_mutant_meat_desc",
+ "looks_like": "meat_cooked",
+ "parasites": 0,
+ "proportional": { "price_postapoc": 1.5, "fun": 0.7 },
+ "extend": { "flags": [ "EATEN_HOT" ] },
+ "delete": { "flags": [ "RAW" ] }
+ },
+ {
+ "type": "COMESTIBLE",
+ "id": "meat_mutant_tainted_smoked",
+ "copy-from": "meat_mutant_tainted_cooked",
+ "name": { "str": "smoked tainted mutant meat" },
+ "description": "Rotten mutatant meat that has been heavily smoked for preservation.",
+ "spoils_in": "24 days",
+ "quench": -1,
+ "proportional": { "price_postapoc": 1.8, "fun": 0.7 },
+ "extend": { "flags": [ "EATEN_HOT", "SMOKED" ] }
+ },
{
"type": "COMESTIBLE",
"comestible_type": "FOOD",
diff --git a/data/json/items/comestibles/other.json b/data/json/items/comestibles/other.json
index 318752030b61a..850cdf8fa21f2 100644
--- a/data/json/items/comestibles/other.json
+++ b/data/json/items/comestibles/other.json
@@ -454,6 +454,7 @@
},
{
"type": "COMESTIBLE",
+ "comestible_type": "FOOD",
"id": "soybean",
"name": { "str_sp": "soybeans" },
"volume": "250 ml",
@@ -474,6 +475,7 @@
},
{
"type": "COMESTIBLE",
+ "comestible_type": "FOOD",
"id": "raw_edamame",
"name": { "str": "raw edamame" },
"volume": "250 ml",
diff --git a/data/json/items/fluff.json b/data/json/items/fluff.json
index c8727f1f60ebb..a4ef05e53707f 100644
--- a/data/json/items/fluff.json
+++ b/data/json/items/fluff.json
@@ -268,7 +268,7 @@
"sided": true,
"material_thickness": 2,
"flags": [ "OVERSIZE", "BELTED", "RESTRICT_HANDS", "WATER_FRIENDLY" ],
- "armor": [ { "coverage": 10, "covers": [ "arm_l", "arm_r", "hand_l", "hand_r" ] } ]
+ "armor": [ { "encumbrance": 45, "coverage": 10, "covers": [ "arm_l", "arm_r", "hand_l", "hand_r" ] } ]
},
{
"type": "GENERIC",
diff --git a/data/json/items/generic.json b/data/json/items/generic.json
index 3a64d86c0085b..62fd50b18fa36 100644
--- a/data/json/items/generic.json
+++ b/data/json/items/generic.json
@@ -732,6 +732,7 @@
"material": [ "steel" ],
"weight": "302 g",
"volume": "500 ml",
+ "flags": [ "HURT_WHEN_WIELDED" ],
"to_hit": -2
},
{
@@ -2873,6 +2874,7 @@
"stack_size": 50,
"material": [ "steel" ],
"symbol": ".",
+ "flags": [ "HURT_WHEN_WIELDED" ],
"color": "white",
"ammo_type": "components"
},
diff --git a/data/json/items/tool_armor.json b/data/json/items/tool_armor.json
index 31820952354e5..a16e499ae83ee 100644
--- a/data/json/items/tool_armor.json
+++ b/data/json/items/tool_armor.json
@@ -1241,6 +1241,7 @@
"to_hit": 1,
"material": [ "plastic" ],
"symbol": "[",
+ "looks_like": "mask_dust",
"color": "light_gray",
"warmth": 10,
"material_thickness": 2,
diff --git a/data/json/mapgen/exodii/exo_safehouse.json b/data/json/mapgen/exodii/exo_safehouse.json
new file mode 100644
index 0000000000000..10e2c55d271cf
--- /dev/null
+++ b/data/json/mapgen/exodii/exo_safehouse.json
@@ -0,0 +1,144 @@
+[
+ {
+ "om_terrain": "exo_safehouse_stone_0",
+ "//": "A medieval stone barn from the exodii's most recently visited world, converted to a safehouse for their scouts to hole up in, and transported to our world during the portal storms.",
+ "type": "mapgen",
+ "weight": 100,
+ "method": "json",
+ "object": {
+ "rows": [
+ " ......... ",
+ " ....,,,,,,,.... ",
+ " ....,,,,,,,,,,,,,.. ",
+ " ..,,,,,,;;;;;,,,,,.. ",
+ " .,,,;;;;;;;;;;;;;,,.. ",
+ " ..,,;x;;;;;;;;;x;,,,.. ",
+ " .,,;x###########x;,,.. ",
+ "..,,;;#|ccc|ccc|#;;,,,..",
+ ".,,,;;#_3____{{g#;;;,,..",
+ ".,,;;;#_|__|{{||#;;;,,..",
+ ".,,;;;#<---I----#;;;,,..",
+ ".,,;;;#|------1|#;;;,,..",
+ ".,,;;;#C--------#;;;,,..",
+ ".,,;;;#C-----3--#;;;,,..",
+ ".,,;;;#C--------#;;;,,..",
+ "..,,;;#||-----||#;;;,,..",
+ "..,,;;#1-------1#;;,,,..",
+ " .,,;x####MMM####x;,,.. ",
+ " .,,;;x;;;;;;;;;x;,,,.. ",
+ " ..,,;x;;;;;;;;;x;,,,.. ",
+ " ..,,xxxxx;;xxxx;,,.. ",
+ " ...,,,,,,,,,,,,,,... ",
+ " ....,,,,,,,,.... ",
+ " .......... "
+ ],
+ "fill_ter": "t_dirtfloor",
+ "palettes": [ "exodii_stone_palette" ],
+ "place_monster": [
+ {
+ "monster": "mon_exodii_quad",
+ "x": [ 10, 11 ],
+ "y": [ 19, 22 ],
+ "pack_size": [ 1, 3 ],
+ "spawn_data": {
+ "patrol": [
+ { "x": 1, "y": 22 },
+ { "x": 1, "y": 1 },
+ { "x": 22, "y": 1 },
+ { "x": 22, "y": 22 },
+ { "x": 11, "y": 22 },
+ { "x": 12, "y": 20 }
+ ]
+ }
+ },
+ {
+ "monster": "mon_exodii_quad",
+ "x": 11,
+ "y": 12,
+ "spawn_data": { "patrol": [ { "x": 12, "y": 16 }, { "x": 7, "y": 10 }, { "x": 12, "y": 13 }, { "x": 8, "y": 12 } ] }
+ },
+ {
+ "monster": "mon_exodii_worker",
+ "x": 7,
+ "y": 8,
+ "spawn_data": { "patrol": [ { "x": 14, "y": 8 }, { "x": 7, "y": 8 } ] }
+ }
+ ],
+ "furniture": { "Y": "f_scrap_antenna", "I": "f_exodii_lamp" }
+ }
+ },
+ {
+ "om_terrain": "exo_safehouse_stone_1",
+ "type": "mapgen",
+ "weight": 100,
+ "method": "json",
+ "object": {
+ "fill_ter": "t_junk_floor",
+ "rows": [
+ "vvvvvvvvvvvvvvvvvvvvvvvv",
+ "vvvvvvvvvvvvvvvvvvvvvvvv",
+ "vvvvvvvvvvvvvvvvvvvvvvvv",
+ "vvvvvvvvvvvvvvvvvvvvvvvv",
+ "vvvvvvvvvvvvvvvvvvvvvvvv",
+ "vvvvvvvvvvvvvvvvvvvvvvvv",
+ "vvvvvv###########vvvvvvv",
+ "vvvvvv#<{{{I{{{g#vvvvvvv",
+ "vvvvvv#'''''{'''#vvvvvvv",
+ "vvvvvv#'|1'|{1|C#vvvvvvv",
+ "vvvvvv#>vvvvvvvv#vvvvvvv",
+ "vvvvvv#vvvvvvvvv#vvvvvvv",
+ "vvvvvv#vvvvvvvvv#vvvvvvv",
+ "vvvvvv#vvvvvvvvv#vvvvvvv",
+ "vvvvvv#vvvvvvvvv#vvvvvvv",
+ "vvvvvv#vvvvvvvvv#vvvvvvv",
+ "vvvvvv#vvvvvvvvv#vvvvvvv",
+ "vvvvvv###########vvvvvvv",
+ "vvvvvvvvvvvvvvvvvvvvvvvv",
+ "vvvvvvvvvvvvvvvvvvvvvvvv",
+ "vvvvvvvvvvvvvvvvvvvvvvvv",
+ "vvvvvvvvvvvvvvvvvvvvvvvv",
+ "vvvvvvvvvvvvvvvvvvvvvvvv",
+ "vvvvvvvvvvvvvvvvvvvvvvvv"
+ ],
+ "palettes": [ "exodii_stone_palette" ],
+ "furniture": { "I": "f_exodii_charger_cheap" }
+ }
+ },
+ {
+ "om_terrain": "exo_safehouse_stone_2",
+ "type": "mapgen",
+ "weight": 100,
+ "method": "json",
+ "object": {
+ "fill_ter": "t_tile_flat_roof",
+ "rows": [
+ "vvvvvvvvvvvvvvvvvvvvvvvv",
+ "vvvvvvvvvvvvvvvvvvvvvvvv",
+ "vvvvvvvvvvvvvvvvvvvvvvvv",
+ "vvvvvvvvvvvvvvvvvvvvvvvv",
+ "vvvvvvvvvvvvvvvvvvvvvvvv",
+ "vvvvvvvvvvvvvvvvvvvvvvvv",
+ "vvvvvv^^^^^^^^^^^vvvvvvv",
+ "vvvvvv^>{Y^^^^^^^vvvvvvv",
+ "vvvvvv^^{^^^^^^^^vvvvvvv",
+ "vvvvvv^^{^^^^^^^^vvvvvvv",
+ "vvvvvv^^{^^^^^^^^vvvvvvv",
+ "vvvvvv^^{^^^^^^^^vvvvvvv",
+ "vvvvvv^^{^^^^^^^^vvvvvvv",
+ "vvvvvv^^{^^^^^^^^vvvvvvv",
+ "vvvvvv^^{^^^^^^^^vvvvvvv",
+ "vvvvvv^^{^^^^^^^^vvvvvvv",
+ "vvvvvv^^I^^^^^^^^vvvvvvv",
+ "vvvvvv^^^^^^^^^^^vvvvvvv",
+ "vvvvvvvvvvvvvvvvvvvvvvvv",
+ "vvvvvvvvvvvvvvvvvvvvvvvv",
+ "vvvvvvvvvvvvvvvvvvvvvvvv",
+ "vvvvvvvvvvvvvvvvvvvvvvvv",
+ "vvvvvvvvvvvvvvvvvvvvvvvv",
+ "vvvvvvvvvvvvvvvvvvvvvvvv"
+ ],
+ "palettes": [ "exodii_stone_palette" ],
+ "furniture": { "Y": "f_exodii_portal_tower", "I": "f_exodii_scanner" }
+ }
+ }
+]
diff --git a/data/json/mapgen_palettes/exodii/medieval.json b/data/json/mapgen_palettes/exodii/medieval.json
new file mode 100644
index 0000000000000..f54de31aa8ccf
--- /dev/null
+++ b/data/json/mapgen_palettes/exodii/medieval.json
@@ -0,0 +1,45 @@
+[
+ {
+ "type": "palette",
+ "id": "exodii_stone_palette",
+ "//": "For medieval buildings the exodii have repurposed.",
+ "terrain": {
+ " ": [ [ "t_region_groundcover", 500 ], "t_region_tree" ],
+ ".": "t_glassed_sand",
+ ",": [ [ "t_glassed_sand", 3 ], "t_sandmound", "t_sand" ],
+ ";": "t_sand",
+ "#": "t_drystone_wall",
+ "_": "t_dirtfloor",
+ "-": "t_dirt",
+ "2": "t_dirt",
+ "5": "t_dirt",
+ "'": "t_junk_floor",
+ "<": "t_ladder_up",
+ ">": "t_ladder_down",
+ "^": "t_tile_flat_roof",
+ "|": "t_junk_wall",
+ "M": "t_door_metal_c",
+ "v": "t_open_air",
+ "x": "t_drystone_wall_half",
+ "4": "t_sand"
+ },
+ "monster": {
+ "1": { "monster": "mon_exodii_turret" },
+ "2": { "monster": "mon_exodii_turret" },
+ "3": { "monster": "mon_exodii_worker" },
+ "5": { "monster": "mon_exodii_worker" }
+ },
+ "furniture": {
+ "c": [ "f_metal_crate_r", "f_metal_crate_c" ],
+ "C": [ "f_metal_crate_r", "f_metal_crate_c" ],
+ "g": "f_capacitor",
+ "{": "f_ground_cable",
+ ".": [ [ "f_null", 2000 ], [ "f_rubble_rock", 100 ] ],
+ ",": [ [ "f_null", 2000 ], [ "f_rubble_rock", 100 ], [ "f_boulder_small", 12 ], "f_boulder_medium" ]
+ },
+ "items": {
+ "c": [ { "item": "SUS_exodii_storage_medvalue", "chance": 50 } ],
+ "C": [ { "item": "SUS_exodii_storage_highvalue", "chance": 50 } ]
+ }
+ }
+]
diff --git a/data/json/monster_factions.json b/data/json/monster_factions.json
index 0cfc4c7699ee7..76a163e7980da 100644
--- a/data/json/monster_factions.json
+++ b/data/json/monster_factions.json
@@ -433,7 +433,8 @@
{
"type": "MONSTER_FACTION",
"name": "fungus",
- "neutral": [ "bot", "fish" ]
+ "neutral": [ "bot", "fish" ],
+ "hate": "triffid"
},
{
"type": "MONSTER_FACTION",
@@ -479,7 +480,8 @@
{
"type": "MONSTER_FACTION",
"name": "triffid",
- "base_faction": "plant"
+ "base_faction": "plant",
+ "hate": "fungus"
},
{
"type": "MONSTER_FACTION",
diff --git a/data/json/overmap/overmap_special/alien.json b/data/json/overmap/overmap_special/alien.json
new file mode 100644
index 0000000000000..14d9c73887d7f
--- /dev/null
+++ b/data/json/overmap/overmap_special/alien.json
@@ -0,0 +1,17 @@
+[
+ {
+ "type": "overmap_special",
+ "id": "Out-of-place Stone Barn",
+ "//": "Exodii safehouse built in a medieval stone barn",
+ "overmaps": [
+ { "point": [ 0, 0, 0 ], "overmap": "exo_safehouse_stone_0_north" },
+ { "point": [ 0, 0, 1 ], "overmap": "exo_safehouse_stone_1_north" },
+ { "point": [ 0, 0, 2 ], "overmap": "exo_safehouse_stone_2_north" }
+ ],
+ "locations": [ "forest_without_trail", "land", "wilderness" ],
+ "city_distance": [ 0, 30 ],
+ "city_sizes": [ 0, 16 ],
+ "occurrences": [ 0, 1 ],
+ "flags": [ "EXODII", "CBM" ]
+ }
+]
diff --git a/data/json/overmap/overmap_terrain/overmap_terrain_alien.json b/data/json/overmap/overmap_terrain/overmap_terrain_alien.json
index e5178718e09d2..851f53ace44d0 100644
--- a/data/json/overmap/overmap_terrain/overmap_terrain_alien.json
+++ b/data/json/overmap/overmap_terrain/overmap_terrain_alien.json
@@ -1,4 +1,31 @@
[
+ {
+ "type": "overmap_terrain",
+ "id": "exo_safehouse_stone_0",
+ "name": "unusual stone barn",
+ "sym": "^",
+ "color": "brown",
+ "see_cost": 2,
+ "flags": [ "KNOWN_UP" ]
+ },
+ {
+ "type": "overmap_terrain",
+ "id": "exo_safehouse_stone_1",
+ "name": "unusual stone barn",
+ "sym": "^",
+ "color": "brown",
+ "see_cost": 2,
+ "flags": [ "KNOWN_UP", "KNOWN_DOWN" ]
+ },
+ {
+ "type": "overmap_terrain",
+ "id": "exo_safehouse_stone_2",
+ "name": "unusual stone barn roof",
+ "sym": "^",
+ "color": "brown",
+ "see_cost": 2,
+ "flags": [ "KNOWN_DOWN" ]
+ },
{
"type": "overmap_terrain",
"id": [ "slimepit_bottom", "slimepit_top" ],
diff --git a/data/json/recipes/practice/fabrication.json b/data/json/recipes/practice/fabrication.json
index c9d53179588f2..4a04b714d75a0 100644
--- a/data/json/recipes/practice/fabrication.json
+++ b/data/json/recipes/practice/fabrication.json
@@ -21,5 +21,41 @@
],
"autolearn": [ [ "fabrication", 2 ] ],
"book_learn": [ [ "recipe_arrows", 1 ] ]
+ },
+ {
+ "id": "prac_carving",
+ "type": "practice",
+ "activity_level": "LIGHT_EXERCISE",
+ "category": "CC_PRACTICE",
+ "subcategory": "CSC_PRACTICE_FABRICATION",
+ "name": "carving",
+ "description": "Practice carving different forms and shapes in a piece of wood.",
+ "skill_used": "fabrication",
+ "practice_data": { "min_difficulty": 0, "max_difficulty": 1, "skill_limit": 2 },
+ "proficiencies": [ { "proficiency": "prof_carving", "fail_multiplier": 1, "time_multiplier": 1 } ],
+ "time": "1 h",
+ "qualities": [ { "id": "CUT", "level": 1 } ],
+ "//": "One could use other wooden items to practice carving, but the stick and plank are the most easily adquired.",
+ "components": [ [ [ "stick", 1 ], [ "2x4", 1 ] ] ],
+ "byproducts": [ [ "splinter", 5 ] ],
+ "autolearn": [ [ "fabrication", 0 ] ]
+ },
+ {
+ "id": "prac_carpentry_basic",
+ "type": "practice",
+ "activity_level": "LIGHT_EXERCISE",
+ "category": "CC_PRACTICE",
+ "subcategory": "CSC_PRACTICE_FABRICATION",
+ "name": "basic carpentry",
+ "description": "Practice basic carpentry by cutting, shaping and uniting some planks or sticks with nails.",
+ "skill_used": "fabrication",
+ "practice_data": { "min_difficulty": 0, "max_difficulty": 1, "skill_limit": 2 },
+ "proficiencies": [ { "proficiency": "prof_carpentry_basic", "fail_multiplier": 1, "time_multiplier": 1 } ],
+ "time": "1 h",
+ "qualities": [ { "id": "HAMMER", "level": 1 }, { "id": "CUT", "level": 1 } ],
+ "//": "You destroy the wood with your practice, and the nails are now unusable.",
+ "components": [ [ [ "stick", 4 ], [ "2x4", 2 ] ], [ [ "nail", 20 ] ] ],
+ "byproducts": [ [ "splinter", 15 ] ],
+ "autolearn": [ [ "fabrication", 0 ] ]
}
]
diff --git a/data/json/recipes/recipe_food.json b/data/json/recipes/recipe_food.json
index 9f114184f8c23..0d8022b61c68d 100644
--- a/data/json/recipes/recipe_food.json
+++ b/data/json/recipes/recipe_food.json
@@ -262,6 +262,18 @@
"proficiencies": [ { "proficiency": "prof_food_prep" } ],
"components": [ [ [ "mutant_meat", 1 ] ] ]
},
+ {
+ "type": "recipe",
+ "copy-from": "mutant_meat_cooked",
+ "result": "meat_mutant_tainted_cooked",
+ "components": [ [ [ "meat_mutant_tainted", 1 ] ] ]
+ },
+ {
+ "type": "recipe",
+ "result": "meat_mutant_tainted_smoked",
+ "copy-from": "meat_smoked",
+ "components": [ [ [ "meat_mutant_tainted", 1 ] ] ]
+ },
{
"type": "recipe",
"activity_level": "NO_EXERCISE",
diff --git a/data/json/snippets/mutant_anatomy.json b/data/json/snippets/mutant_anatomy.json
index 23849977383a9..ea89111284cb9 100644
--- a/data/json/snippets/mutant_anatomy.json
+++ b/data/json/snippets/mutant_anatomy.json
@@ -43,6 +43,50 @@
}
]
},
+ {
+ "type": "snippet",
+ "category": "tainted_mutant_meat_desc",
+ "text": [
+ {
+ "id": "tainted_mutant_meat_1",
+ "text": "Poisonous meat from a heavily mutated animal. It has an unsettling loose and spongy texture and a putrid smell. There are strange tangles and formations in it that don't appear natural at all: bits of bone and hair crusted up inside the muscle, as if trying to form another organism. You'd have to be truly desperate to try eating this."
+ },
+ {
+ "id": "tainted_mutant_meat_2",
+ "text": "Poisonous meat from a heavily mutated animal. Although it came from muscle tissue, it has a curious swirling grain pattern, and at the center of each grain is a knot of hard, cartilaginous tissue. Its smell is nauseating."
+ },
+ {
+ "id": "tainted_mutant_meat_3",
+ "text": "Poisonous meat from a heavily mutated animal. This is from muscle, but in the fascial tissue between the muscles, thick spiny hairs have grown. Foul-smelling, cream-colored fluid gushes out whenever a hair pulls loose."
+ },
+ {
+ "id": "tainted_mutant_meat_4",
+ "text": "Poisonous meat from a heavily mutated animal. Although this came from muscle, it has a thick cordlike texture and smells like leather and bread mold."
+ }
+ ]
+ },
+ {
+ "type": "snippet",
+ "category": "cooked_tainted_mutant_meat_desc",
+ "text": [
+ {
+ "id": "cooked_tainted_mutant_meat_1",
+ "text": "This is a cooked chunk of meat from a mutated animal. It has an unsettling, spongy texture, but otherwise tastes… mostly normal. Hopefully you won't vomit while eating this…"
+ },
+ {
+ "id": "cooked_tainted_mutant_meat_2",
+ "text": "This is a cooked chunk of meat from a mutated animal. You thought you'd cleared out all the gross parts, but while cooking, a fluid-filled sac inside burst and covered it in some kind of foul-smelling thick grease."
+ },
+ {
+ "id": "cooked_tainted_mutant_meat_3",
+ "text": "This is a cooked chunk of meat from a mutated animal. The surface is peppered with divots from the pieces you had to dig out to make it seem edible."
+ },
+ {
+ "id": "cooked_tainted_mutant_meat_4",
+ "text": "This is a cooked chunk of meat from a mutated animal. Heat caused the muscles to twist and move as if they were alive, and now it has writhed itself into a dense knot."
+ }
+ ]
+ },
{
"type": "snippet",
"category": "mutant_brain_desc",
diff --git a/data/mods/Magiclysm/harvest.json b/data/mods/Magiclysm/harvest.json
index 521c367564aff..c17cb3260eec5 100644
--- a/data/mods/Magiclysm/harvest.json
+++ b/data/mods/Magiclysm/harvest.json
@@ -346,5 +346,19 @@
{ "drop": "sinew", "type": "bone", "mass_ratio": 0.00035 },
{ "drop": "bone_demihuman", "type": "bone", "mass_ratio": 0.1 }
]
+ },
+ {
+ "id": "zombie_owlbear",
+ "//": "identical to owlbear except ",
+ "type": "harvest",
+ "entries": [
+ { "drop": "meat_mutant_tainted", "type": "flesh", "mass_ratio": 0.32 },
+ { "drop": "owlbear_stone", "scale_num": [ 1, 1 ], "max": 1, "type": "offal" },
+ { "drop": "bone_tainted", "type": "bone", "mass_ratio": 0.15 },
+ { "drop": "raw_tainted_fur", "type": "skin", "mass_ratio": 0.015 },
+ { "drop": "fat_tainted", "type": "flesh", "mass_ratio": 0.07 },
+ { "drop": "feather", "type": "skin", "mass_ratio": 0.005 },
+ { "drop": "adrenal_gland_large", "type": "bionic", "max": 2 }
+ ]
}
]
diff --git a/data/mods/Magiclysm/monstergroups.json b/data/mods/Magiclysm/monstergroups.json
index 28f5d2b3cbbc5..e897a2dded748 100644
--- a/data/mods/Magiclysm/monstergroups.json
+++ b/data/mods/Magiclysm/monstergroups.json
@@ -25,10 +25,17 @@
"cost_multiplier": 5,
"conditions": [ "NIGHT" ],
"pack_size": [ 2, 4 ],
- "starts": 1500
+ "starts": 750
},
+ { "monster": "mon_were_zolf", "freq": 4, "cost_multiplier": 5, "pack_size": [ 1, 2 ], "starts": 800 },
+ { "monster": "mon_winter_wolf", "freq": 4, "cost_multiplier": 5, "pack_size": [ 1, 3 ], "starts": 750 },
{ "monster": "mon_irongolem", "freq": 2, "cost_multiplier": 8 },
- { "monster": "mon_demon_spiderling", "freq": 15, "cost_multiplier": 5, "pack_size": [ 3, 7 ] }
+ { "monster": "mon_demon_spiderling", "freq": 15, "cost_multiplier": 5, "pack_size": [ 3, 7 ] },
+ { "monster": "mon_owlbear_zombie", "freq": 7, "cost_multiplier": 10 },
+ { "monster": "mon_owlbear_zombie_brute", "freq": 1, "cost_multiplier": 15 },
+ { "monster": "mon_troll_zombie", "freq": 3, "cost_multiplier": 13 },
+ { "monster": "mon_yulecat_zombie", "freq": 3, "cost_multiplier": 12 },
+ { "monster": "mon_yulecat_zombie_brute", "freq": 1, "cost_multiplier": 25 }
]
},
{
@@ -54,7 +61,10 @@
"monsters": [
{ "monster": "mon_owlbear", "freq": 100, "cost_multiplier": 10, "pack_size": [ 2, 4 ] },
{ "monster": "mon_shrieker", "freq": 10, "cost_multiplier": 1 },
- { "monster": "mon_lemure", "freq": 5, "cost_multiplier": 2, "pack_size": [ 1, 4 ] }
+ { "monster": "mon_lemure", "freq": 5, "cost_multiplier": 2, "pack_size": [ 1, 4 ] },
+ { "monster": "mon_owlbear_zombie", "freq": 40, "cost_multiplier": 10, "pack_size": [ 2, 4 ] },
+ { "monster": "mon_owlbear_zombie_brute", "freq": 5, "cost_multiplier": 20, "pack_size": [ 1, 2 ] },
+ { "monster": "mon_yulecat_zombie_brute", "freq": 5, "cost_multiplier": 30 }
]
},
{
diff --git a/data/mods/Magiclysm/monsters/holiday_magiclysm.json b/data/mods/Magiclysm/monsters/holiday_magiclysm.json
index 45427ba3050e1..d7b97db8ee30c 100644
--- a/data/mods/Magiclysm/monsters/holiday_magiclysm.json
+++ b/data/mods/Magiclysm/monsters/holiday_magiclysm.json
@@ -31,7 +31,8 @@
"baby_flags": [ "WINTER" ],
"special_attacks": [ { "type": "bite", "cooldown": 10 }, [ "GRAB", 8 ], [ "scratch", 6 ] ],
"anger_triggers": [ "PLAYER_NEAR_BABY" ],
- "flags": [ "SEES", "HEARS", "SMELLS", "KEENNOSE", "PATH_AVOID_DANGER_1", "WARM", "GRABS" ]
+ "flags": [ "SEES", "HEARS", "SMELLS", "KEENNOSE", "PATH_AVOID_DANGER_1", "WARM", "GRABS" ],
+ "zombify_into": "mon_yulecat_zombie"
},
{
"id": "mon_yulecat_cub",
diff --git a/data/mods/Magiclysm/monsters/monsters.json b/data/mods/Magiclysm/monsters/monsters.json
index 3342b6ab27a08..c9995ff249e81 100644
--- a/data/mods/Magiclysm/monsters/monsters.json
+++ b/data/mods/Magiclysm/monsters/monsters.json
@@ -30,7 +30,8 @@
"reproduction": { "baby_egg": "egg_owlbear_rock", "baby_count": 1, "baby_timer": 20 },
"baby_flags": [ "SPRING", "SUMMER", "AUTUMN", "WINTER" ],
"special_attacks": [ { "type": "bite", "cooldown": 10 }, [ "GRAB", 7 ], [ "scratch", 7 ] ],
- "flags": [ "SEES", "HEARS", "SMELLS", "KEENNOSE", "PATH_AVOID_DANGER_1", "WARM", "GRABS", "SWARMS" ]
+ "flags": [ "SEES", "HEARS", "SMELLS", "KEENNOSE", "PATH_AVOID_DANGER_1", "WARM", "GRABS", "SWARMS" ],
+ "zombify_into": "mon_owlbear_zombie"
},
{
"id": "mon_black_pudding",
@@ -311,7 +312,8 @@
"harvest": "human_large_leather",
"special_attacks": [ { "type": "bite", "cooldown": 30 }, [ "GRAB", 15 ], [ "scratch", 15 ], [ "slam", 10 ], [ "SMASH", 30 ] ],
"regenerates": 1,
- "flags": [ "SEES", "SMELLS", "KEENNOSE", "PATH_AVOID_DANGER_1", "WARM", "GRABS", "FLAMMABLE" ]
+ "flags": [ "SEES", "SMELLS", "KEENNOSE", "PATH_AVOID_DANGER_1", "WARM", "GRABS", "FLAMMABLE" ],
+ "zombify_into": "mon_troll_zombie"
},
{
"id": "mon_stirge",
diff --git a/data/mods/Magiclysm/monsters/zombified_monsters.json b/data/mods/Magiclysm/monsters/zombified_monsters.json
index c3b1583b25673..055dfff189b57 100644
--- a/data/mods/Magiclysm/monsters/zombified_monsters.json
+++ b/data/mods/Magiclysm/monsters/zombified_monsters.json
@@ -61,5 +61,161 @@
"vision_night": 12,
"harvest": "orc",
"flags": [ "SEES", "HEARS", "SMELLS", "STUMBLES", "WARM", "BASHES", "GROUP_BASH", "POISON", "NO_BREATHE", "REVIVES", "FILTHY" ]
+ },
+ {
+ "type": "MONSTER",
+ "id": "mon_owlbear_zombie",
+ "name": "Zowlbear",
+ "description": "This horrible mutant monster has been zombified. Though it looks weaker than its living counterpart, you feel much more hostility from its black oily eyes.",
+ "default_faction": "zombie",
+ "bodytype": "bear",
+ "species": [ "MAGICAL_BEAST", "ZOMBIE" ],
+ "volume": "435000 ml",
+ "weight": "420 kg",
+ "looks_like": "mon_owlbear",
+ "hp": 220,
+ "speed": 105,
+ "material": [ "flesh" ],
+ "symbol": "W",
+ "color": "green",
+ "aggression": 100,
+ "morale": 100,
+ "melee_skill": 4,
+ "melee_dice": 4,
+ "melee_dice_sides": 6,
+ "melee_cut": 6,
+ "dodge": 1,
+ "armor_bash": 5,
+ "armor_cut": 2,
+ "armor_bullet": 2,
+ "vision_night": 13,
+ "path_settings": { "max_dist": 12 },
+ "harvest": "zombie_owlbear",
+ "special_attacks": [ { "type": "bite", "cooldown": 10 }, [ "GRAB", 7 ], [ "scratch", 7 ] ],
+ "flags": [
+ "SEES",
+ "HEARS",
+ "SMELLS",
+ "KEENNOSE",
+ "PATH_AVOID_DANGER_1",
+ "WARM",
+ "GRABS",
+ "SWARMS",
+ "STUMBLES",
+ "BASHES",
+ "POISON",
+ "NO_BREATHE",
+ "REVIVES"
+ ],
+ "upgrades": { "half_life": 60, "into": "mon_owlbear_zombie_brute" }
+ },
+ {
+ "type": "MONSTER",
+ "id": "mon_owlbear_zombie_brute",
+ "copy-from": "mon_owlbear_zombie",
+ "name": "Zowlbear Predator",
+ "description": "An once zombified owlbear, now faster and much bigger in size. Its thick skin protects the monster from harm, a sharp beak capable of rending through metal and a fury in its eyes warns you to stay away.",
+ "upgrades": false,
+ "path_settings": { "max_dist": 0 },
+ "proportional": { "volume": 1.15, "weight": 1.2 },
+ "relative": {
+ "hp": 80,
+ "speed": 35,
+ "melee_skill": 2,
+ "melee_dice": 1,
+ "melee_dice_sides": 2,
+ "melee_cut": 4,
+ "dodge": 3,
+ "armor_bash": 3,
+ "armor_cut": 3,
+ "armor_bullet": 2,
+ "vision_night": 19
+ },
+ "delete": { "flags": [ "PATH_AVOID_DANGER_1" ] },
+ "extend": { "special_attacks": [ [ "SMASH", 20 ] ] }
+ },
+ {
+ "type": "MONSTER",
+ "id": "mon_troll_zombie",
+ "copy-from": "mon_troll",
+ "name": "Undying",
+ "description": "An enourmous humanoid monster with a yellowish-green skin. Trolls are renowned for their thick hides and natural regenerative ability. After death, its pus filled body seems to have much grown stronger, it looks at you ferociously with hunger in its eyes.",
+ "default_faction": "zombie",
+ "harvest": "zombie",
+ "relative": {
+ "hp": 40,
+ "speed": -25,
+ "melee_skill": -2,
+ "melee_dice": 2,
+ "melee_dice_sides": -1,
+ "melee_cut": -2,
+ "armor_bash": 2,
+ "armor_cut": 2,
+ "armor_bullet": 1,
+ "vision_day": -13,
+ "vision_night": 3,
+ "regenerates": 3
+ },
+ "proportional": { "volume": 1.05, "weight": 1.07 },
+ "extend": { "species": [ "ZOMBIE" ], "flags": [ "BASHES", "POISON", "NO_BREATHE", "REVIVES" ] },
+ "delete": { "flags": [ "PATH_AVOID_DANGER_1" ] }
+ },
+ {
+ "type": "MONSTER",
+ "id": "mon_yulecat_zombie",
+ "name": "Zombified Yule Cat",
+ "description": "A magical beast from Icelandic folklore, known for their catlike appearance and their hobby of eating Workshop Elves. It creeply stumbles on its 4 legs with its squirming uneven body after meeting demise and being reborn just to eat you.",
+ "looks_like": "mon_yulecat",
+ "default_faction": "zombie",
+ "species": [ "MAGICAL_BEAST", "ZOMBIE" ],
+ "symbol": "Y",
+ "color": "white",
+ "material": [ "flesh" ],
+ "bodytype": "lion",
+ "weight": "763 kg",
+ "volume": "195 L",
+ "aggression": 100,
+ "morale": 100,
+ "hp": 215,
+ "speed": 124,
+ "melee_skill": 3,
+ "melee_dice": 5,
+ "melee_dice_sides": 7,
+ "melee_cut": 2,
+ "dodge": 3,
+ "armor_bash": 4,
+ "armor_cut": 1,
+ "armor_bullet": 4,
+ "vision_day": 30,
+ "vision_night": 10,
+ "path_settings": { "max_dist": 3, "avoid_traps": false, "avoid_sharp": false },
+ "harvest": "zombie_fur",
+ "special_attacks": [ { "type": "bite", "cooldown": 10 }, [ "GRAB", 8 ], [ "scratch", 6 ] ],
+ "flags": [ "SEES", "HEARS", "SMELLS", "KEENNOSE", "WARM", "GRABS", "STUMBLES", "BASHES", "POISON", "NO_BREATHE", "REVIVES" ],
+ "upgrades": { "half_life": 5, "into": "mon_yulecat_zombie_brute" }
+ },
+ {
+ "type": "MONSTER",
+ "id": "mon_yulecat_zombie_brute",
+ "copy-from": "mon_yulecat_zombie",
+ "name": "Tod Cat",
+ "description": "Once used to its decomposed body, this nightmarish cat with thick teeth and razorshap claws seems to be looking around for things to \"play\" with. Though its head is of a feline, it grins at you sadisticly with a glint in its cold demonic eyes.",
+ "path_settings": { "max_dist": 17 },
+ "relative": {
+ "hp": 65,
+ "speed": 49,
+ "melee_skill": 5,
+ "melee_dice": 1,
+ "melee_dice_sides": 1,
+ "melee_cut": -2,
+ "armor_bash": 2,
+ "armor_cut": 1,
+ "armor_bullet": -2,
+ "vision_day": -22,
+ "vision_night": 20,
+ "regenerates": 3
+ },
+ "proportional": { "volume": 1.01, "weight": 0.95 },
+ "extend": { "flags": [ "PATH_AVOID_DANGER_1" ], "special_attacks": [ { "type": "leap", "cooldown": 7, "max_range": 2 } ] }
}
]
diff --git a/data/mods/No_Fungi/modinfo.json b/data/mods/No_Fungi/modinfo.json
index 3110518edd062..27278fadfc272 100644
--- a/data/mods/No_Fungi/modinfo.json
+++ b/data/mods/No_Fungi/modinfo.json
@@ -6,7 +6,8 @@
"authors": [ "Chaosvolt" ],
"description": "Removes fungal monsters and regions from the game.",
"category": "monster_exclude",
- "dependencies": [ "dda" ]
+ "dependencies": [ "dda" ],
+ "obsolete": true
},
{
"type": "MONSTER_BLACKLIST",
diff --git a/data/mods/No_Hope/Mapgen/house21.json b/data/mods/No_Hope/Mapgen/house21.json
index f8ff714d173ad..279b631f586f2 100644
--- a/data/mods/No_Hope/Mapgen/house21.json
+++ b/data/mods/No_Hope/Mapgen/house21.json
@@ -112,7 +112,6 @@
},
"furniture": { "D": "f_dumpster", "P": "f_mailbox", "{": "f_dumpster" },
"place_item": [
- { "chance": 20, "item": "toolbox", "x": 14, "y": 10 },
{ "chance": 30, "item": "glass_sheet", "x": 5, "y": 18 },
{ "chance": 30, "item": "glass_sheet", "x": 6, "y": 18 },
{ "chance": 30, "item": "101_carpentry", "x": 8, "y": 7 },
@@ -122,6 +121,7 @@
{ "chance": 30, "item": "glass_sheet", "x": 7, "y": 19 }
],
"place_items": [
+ { "chance": 20, "item": "tools_toolbox", "x": 14, "y": 10 },
{ "chance": 30, "item": "building_rubble", "x": 4, "y": 10 },
{ "chance": 30, "item": "building_rubble", "x": [ 13, 14 ], "y": 4 },
{ "chance": 30, "item": "building_rubble", "x": [ 12, 13 ], "y": 3 },
diff --git a/data/mods/No_Hope/Mapgen/private_resort.json b/data/mods/No_Hope/Mapgen/private_resort.json
index 0cc1a9e9465b0..a7396ac56a7c1 100644
--- a/data/mods/No_Hope/Mapgen/private_resort.json
+++ b/data/mods/No_Hope/Mapgen/private_resort.json
@@ -1169,7 +1169,7 @@
"***WWWWWWWWWWWWWWWWWW***"
],
"palettes": [ "p_resort_palette_basement" ],
- "place_item": [ { "item": "toolbox", "repeat": 1, "x": 8, "y": 11 } ],
+ "place_loot": [ { "group": "tools_toolbox", "repeat": 1, "x": 8, "y": 11 } ],
"items": {
"S": { "item": "preserved_food", "chance": 50, "repeat": [ 0, 3 ] },
"f": { "item": "butcher_raw_meat", "chance": 50, "repeat": [ 0, 6 ] }
diff --git a/data/mods/No_Hope/item_groups.json b/data/mods/No_Hope/item_groups.json
index dea6a160cc552..9b7f6705a4922 100644
--- a/data/mods/No_Hope/item_groups.json
+++ b/data/mods/No_Hope/item_groups.json
@@ -133,5 +133,52 @@
{ "group": "newspaper", "prob": 10 },
[ "handflare_dead", 3 ]
]
+ },
+ {
+ "type": "item_group",
+ "id": "chickenbot",
+ "items": [
+ [ "robot_controls", 5 ],
+ [ "ai_module", 5 ],
+ [ "sensor_module", 5 ],
+ [ "memory_module", 5 ],
+ [ "pathfinding_module", 5 ],
+ [ "identification_module", 5 ],
+ [ "reverse_jointed_legs", 40 ],
+ [ "chickenbot_chassis", 40 ],
+ [ "targeting_module", 5 ],
+ [ "gun_module", 30 ],
+ [ "mark19", 5 ],
+ [ "tazer", 5 ],
+ [ "m249", 5 ],
+ [ "storage_battery", 5 ],
+ [ "plut_cell", 5 ],
+ [ "mil_plate", 2 ]
+ ]
+ },
+ {
+ "type": "item_group",
+ "id": "tankbot",
+ "items": [
+ [ "tazer", 3 ],
+ { "item": "flamethrower", "prob": 1, "charges-min": 0, "charges-max": 3000 },
+ [ "556", 8 ],
+ [ "alloy_plate", 10 ],
+ [ "kevlar_plate", 10 ],
+ [ "ceramic_armor", 10 ],
+ [ "hard_plate", 30 ],
+ [ "robot_controls", 5 ]
+ ]
+ },
+ {
+ "type": "item_group",
+ "id": "tripod",
+ "items": [
+ { "item": "flamethrower", "prob": 1, "charges-min": 0, "charges-max": 3000 },
+ [ "kevlar_plate", 10 ],
+ [ "ceramic_armor", 15 ],
+ [ "alloy_plate", 10 ],
+ [ "robot_controls", 3 ]
+ ]
}
]
diff --git a/data/mods/No_Hope/items.json b/data/mods/No_Hope/items.json
new file mode 100644
index 0000000000000..505e5a009a7fa
--- /dev/null
+++ b/data/mods/No_Hope/items.json
@@ -0,0 +1,264 @@
+[
+ {
+ "id": "schematics_chickenbot",
+ "type": "BOOK",
+ "name": { "str_sp": "chicken walker schematics" },
+ "description": "Bearing the logo of Northrop, those are assembly plans, design specs, and technical drawings for the chicken walker. Most of this is useless to you, but you could use the assembly plans to re-assemble the robot from salvaged parts.",
+ "copy-from": "schematics_generic"
+ },
+ {
+ "id": "schematics_tankbot",
+ "type": "BOOK",
+ "name": { "str_sp": "tank drone schematics" },
+ "description": "Bearing the logo of Northrop, those are assembly plans, design specs, and technical drawings for the tank drone. Most of this is useless to you, but you could use the assembly plans to re-assemble the robot from salvaged parts.",
+ "copy-from": "schematics_generic"
+ },
+ {
+ "id": "schematics_tripod",
+ "type": "BOOK",
+ "name": { "str_sp": "tripod schematics" },
+ "description": "Bearing the logo of Honda, those are assembly plans, design specs, and technical drawings for the tripod. Most of this is useless to you, but you could use the assembly plans to re-assemble the robot from salvaged parts.",
+ "copy-from": "schematics_generic"
+ },
+ {
+ "id": "bot_chickenbot",
+ "type": "TOOL",
+ "name": { "str": "inactive chicken walker" },
+ "description": "This is an inactive chicken walker. Using this item involves placing it on the ground, loading the unit with the factory-loaded 5.56 rounds and 40mm cartridge grenades in your inventory (if you wish to divide your ammunition, set aside whatever ammunition you do NOT want to give the robot) and turning it on. If reprogrammed and rewired successfully the chicken walker will then identify you as a friendly, roam around or follow you, and attack all enemies with a built-in firearm and grenade launcher.",
+ "weight": "120000 g",
+ "volume": "92500 ml",
+ "price": 50000000,
+ "to_hit": -3,
+ "bashing": 8,
+ "material": [ "steel" ],
+ "symbol": ";",
+ "color": "light_green",
+ "use_action": {
+ "type": "place_monster",
+ "monster_id": "mon_chickenbot",
+ "friendly_msg": "The chicken walker rises to its feet, sways away from you and begins surveying the area.",
+ "hostile_msg": "The chicken walker whirrs and aims directly at you. Take cover!",
+ "//": "Milspec, but was deployed in active service implying a reliable IFF",
+ "difficulty": 9,
+ "moves": 250,
+ "skills": [ "electronics", "computer" ]
+ }
+ },
+ {
+ "id": "bot_tankbot",
+ "looks_like": "broken_tankbot",
+ "type": "TOOL",
+ "name": { "str": "inactive tank drone" },
+ "description": "This is an inactive Beagle Mini-Tank UGV. Using this item involves placing it on the ground, loading the unit with the factory-loaded 5.56 rounds and 40mm cartridge grenades in your inventory (if you wish to divide your ammunition, set aside whatever ammunition you do NOT want to give the robot) and turning it on. If reprogrammed and rewired successfully the tank drone will then identify you as a friendly, roam around or follow you, and attack all enemies with a built-in firearm and grenade launcher.",
+ "weight": "200000 g",
+ "//": "cheating a bit with the volume due to lack of proper vehicle storage options",
+ "volume": "250 L",
+ "price": 100000000,
+ "to_hit": -3,
+ "bashing": 8,
+ "material": [ "steel" ],
+ "symbol": ";",
+ "color": "light_green",
+ "use_action": {
+ "type": "place_monster",
+ "monster_id": "mon_tankbot",
+ "friendly_msg": "The tank drone rolls out and begins acquiring targets.",
+ "hostile_msg": "The tank drone swivels its turret and aims directly at you. Don your brown pants!",
+ "//": "Milspec, clearly designed with little concern for collateral damage. What did you expect of a robo-tank?",
+ "difficulty": 10,
+ "moves": 500,
+ "skills": [ "electronics", "computer" ]
+ }
+ },
+ {
+ "type": "GENERIC",
+ "id": "broken_chickenbot",
+ "looks_like": "broken_tripod",
+ "symbol": ",",
+ "color": "green",
+ "name": { "str": "broken chickenbot" },
+ "category": "other",
+ "description": "A broken chicken walker. Still looks intimidating despite being permanently inoperative, possibly due to the sheer size and mass. Could be gutted for parts.",
+ "price": 1000,
+ "material": [ "steel", "plastic" ],
+ "weight": "1023850 g",
+ "volume": "1100 L",
+ "bashing": 20,
+ "cutting": 15,
+ "to_hit": -3,
+ "use_action": {
+ "type": "place_monster",
+ "monster_id": "mon_chickenbot",
+ "friendly_msg": "The chicken bot rolls out and begins acquiring targets.",
+ "hostile_msg": "The chicken bot swivels its turret and aims directly at you. Don your brown pants!",
+ "//": "Milspec, clearly designed with little concern for collateral damage. What did you expect of a chicken walker?",
+ "difficulty": 10,
+ "moves": 500,
+ "skills": [ "electronics", "computer" ]
+ }
+ },
+ {
+ "id": "bot_tripod",
+ "looks_like": "broken_tripod",
+ "type": "TOOL",
+ "name": { "str": "inactive tripod" },
+ "description": "This is an inactive Honda Regnal. Using this item involves placing it on the ground, wondering how it fuels its flamethrower and turning it on. If reprogrammed and rewired successfully the tribot will then identify you as an ally, roam around or follow you, and impale hostiles with its spiked cable weapons.",
+ "weight": "120000 g",
+ "volume": "92500 ml",
+ "price": 100000000,
+ "to_hit": -3,
+ "bashing": 8,
+ "material": [ "steel" ],
+ "symbol": ";",
+ "color": "light_green",
+ "use_action": {
+ "type": "place_monster",
+ "monster_id": "mon_tripod",
+ "friendly_msg": "The tribot rises to its feet and scans the area for contaminants.",
+ "hostile_msg": "The tribot glowers down at you and ignites its flamethrower. Turns out you hate the smell of napalm.",
+ "//": "No observed open deployment, likely a prototype or secret project",
+ "difficulty": 15,
+ "moves": 500,
+ "skills": [ "electronics", "computer" ]
+ }
+ },
+ {
+ "type": "GENERIC",
+ "id": "broken_tripod",
+ "symbol": ",",
+ "color": "green",
+ "name": { "str": "broken tribot" },
+ "category": "other",
+ "description": "A broken tribot. Now that its legs lie broken and immobile, the world seems a little less threatening. Could be gutted for parts.",
+ "price": 1000,
+ "material": [ "steel", "plastic" ],
+ "weight": "430000 g",
+ "volume": "187500 ml",
+ "bashing": 10,
+ "cutting": 6,
+ "to_hit": -2,
+ "flags": [ "TRADER_AVOID", "NO_REPAIR" ]
+ },
+ {
+ "type": "GENERIC",
+ "id": "broken_tankbot",
+ "symbol": ",",
+ "color": "green",
+ "name": { "str": "broken tank drone" },
+ "category": "other",
+ "description": "A broken tank drone. Still looks intimidating despite being permanently inoperative, possibly due to the sheer size and mass. Could be gutted for parts.",
+ "price": 1000,
+ "material": [ "steel", "plastic" ],
+ "weight": "1223850 g",
+ "volume": "875 L",
+ "bashing": 20,
+ "cutting": 15,
+ "to_hit": -3,
+ "flags": [ "TRADER_AVOID", "NO_REPAIR" ]
+ },
+ {
+ "type": "GENERIC",
+ "id": "tripod_chassis",
+ "name": { "str_sp": "tripod chassis" },
+ "description": "What's left when you remove all moving parts and electronics. It's the skeleton and armor of the tripod.",
+ "symbol": "c",
+ "color": "light_gray",
+ "weight": "40000 g",
+ "volume": "70000 ml",
+ "price": 200000,
+ "material": [ "steel" ],
+ "category": "spare_parts"
+ },
+ {
+ "type": "GENERIC",
+ "id": "chickenbot_chassis",
+ "name": { "str_sp": "chicken walker chassis" },
+ "description": "What's left when you remove all moving parts and electronics. It's the skeleton and armor of the chicken walker.",
+ "symbol": "c",
+ "color": "light_gray",
+ "weight": "60000 g",
+ "volume": "80000 ml",
+ "price": 300000,
+ "material": [ "steel" ],
+ "category": "spare_parts"
+ },
+ {
+ "type": "GENERIC",
+ "id": "tankbot_chassis",
+ "name": { "str_sp": "Beagle chassis" },
+ "description": "What's left when you remove all moving parts and electronics. It's the skeleton and armor of the Beagle tank.",
+ "symbol": "c",
+ "color": "light_gray",
+ "weight": "150000 g",
+ "volume": "575000 ml",
+ "price": 1000000,
+ "material": [ "steel" ],
+ "category": "spare_parts"
+ },
+ {
+ "id": "TANK",
+ "looks_like": "m79",
+ "type": "GUN",
+ "symbol": "(",
+ "color": "green",
+ "name": { "str_sp": "Tankbot Main Gun" },
+ "description": "The 120mm cannon from a tankbot. If you have this, you'd best be debugging!",
+ "price": 99999999,
+ "material": [ "steel" ],
+ "skill": "launcher",
+ "ammo": [ "120mm" ],
+ "weight": "2500 g",
+ "volume": "2500 ml",
+ "bashing": 6,
+ "to_hit": -3,
+ "dispersion": 60,
+ "durability": 9,
+ "clip_size": 1,
+ "loudness": 300,
+ "pocket_data": [ { "pocket_type": "MAGAZINE", "ammo_restriction": { "120mm": 1 } } ]
+ },
+ {
+ "type": "GENERIC",
+ "id": "spidery_legs_big",
+ "name": { "str": "set of spidery legs", "str_pl": "sets of spidery legs" },
+ "description": "A set of big pointy legs, like the ones found under a tripod.",
+ "symbol": "W",
+ "color": "light_gray",
+ "weight": "40000 g",
+ "volume": "20 L",
+ "price": 200000,
+ "material": [ "steel" ],
+ "category": "spare_parts"
+ },
+ {
+ "id": "bot_laserturret",
+ "type": "TOOL",
+ "name": { "str": "inactive laser turret" },
+ "description": "This is an inactive laser turret. Using this item involves turning it on and placing it on the ground, where it will attach itself. If reprogrammed and rewired successfully the turret will identify you as a friendly, and attack all enemies with its revolving laser cannons. It requires sunlight in order to fire.",
+ "weight": "40750 g",
+ "volume": "30 L",
+ "price": 600000,
+ "price_postapoc": 12000,
+ "to_hit": -3,
+ "bashing": 8,
+ "material": [ "steel", "plastic" ],
+ "symbol": ";",
+ "color": "white",
+ "use_action": {
+ "type": "place_monster",
+ "monster_id": "mon_laserturret",
+ "difficulty": 6,
+ "moves": 100,
+ "skills": [ "electronics", "computer" ]
+ }
+ },
+ {
+ "type": "GENERIC",
+ "id": "broken_laserturret",
+ "symbol": ",",
+ "color": "green",
+ "name": { "str": "broken laser turret" },
+ "weight": "110 kg",
+ "copy-from": "broken_turret"
+ }
+]
diff --git a/data/mods/TEST_DATA/effects.json b/data/mods/TEST_DATA/effects.json
index 0069a87d459bf..d60393de8507c 100644
--- a/data/mods/TEST_DATA/effects.json
+++ b/data/mods/TEST_DATA/effects.json
@@ -11,6 +11,7 @@
"max_duration": "1 h",
"max_intensity": 10,
"int_decay_tick": 2,
+ "int_decay_remove": true,
"base_mods": {
"str_mod": [ 1 ],
"dex_mod": [ 2 ],
diff --git a/data/mods/TEST_DATA/overmap_specials.json b/data/mods/TEST_DATA/overmap_specials.json
new file mode 100644
index 0000000000000..f0bfa1d52c54c
--- /dev/null
+++ b/data/mods/TEST_DATA/overmap_specials.json
@@ -0,0 +1,58 @@
+[
+ {
+ "type": "overmap_special",
+ "id": "test_anthill",
+ "subtype": "mutable",
+ "locations": [ "subterranean_empty" ],
+ "city_distance": [ 10, -1 ],
+ "occurrences": [ 80, 100 ],
+ "flags": [ "ANT", "UNIQUE", "CLASSIC", "WILDERNESS" ],
+ "check_for_locations": [
+ [ [ 0, 0, 0 ], [ "land" ] ],
+ [ [ 0, 0, -1 ], [ "subterranean_empty" ] ],
+ [ [ 1, 0, -1 ], [ "subterranean_empty" ] ],
+ [ [ 0, 1, -1 ], [ "subterranean_empty" ] ],
+ [ [ -1, 0, -1 ], [ "subterranean_empty" ] ],
+ [ [ 0, -1, -1 ], [ "subterranean_empty" ] ]
+ ],
+ "joins": [ "surface_to_tunnel", "tunnel_to_tunnel" ],
+ "overmaps": {
+ "surface": { "overmap": "anthill_north", "below": "surface_to_tunnel", "locations": [ "land" ] },
+ "below_entrance": {
+ "overmap": "ants_nesw",
+ "above": "surface_to_tunnel",
+ "north": "tunnel_to_tunnel",
+ "east": "tunnel_to_tunnel",
+ "south": "tunnel_to_tunnel",
+ "west": "tunnel_to_tunnel"
+ },
+ "crossroads": {
+ "overmap": "ants_nesw",
+ "north": "tunnel_to_tunnel",
+ "east": "tunnel_to_tunnel",
+ "south": "tunnel_to_tunnel",
+ "west": "tunnel_to_tunnel"
+ },
+ "tee": { "overmap": "ants_nes", "north": "tunnel_to_tunnel", "east": "tunnel_to_tunnel", "south": "tunnel_to_tunnel" },
+ "straight_tunnel": { "overmap": "ants_ns", "north": "tunnel_to_tunnel", "south": "tunnel_to_tunnel" },
+ "corner": { "overmap": "ants_ne", "north": "tunnel_to_tunnel", "east": "tunnel_to_tunnel" },
+ "dead_end": { "overmap": "ants_end_south", "north": "tunnel_to_tunnel" }
+ },
+ "root": "surface",
+ "phases": [
+ [ { "overmap": "below_entrance", "max": 1 } ],
+ [
+ { "overmap": "straight_tunnel", "max": 20 },
+ { "overmap": "corner", "max": 5 },
+ { "overmap": "tee", "max": 10 }
+ ],
+ [
+ { "overmap": "dead_end", "weight": 2000 },
+ { "overmap": "straight_tunnel", "weight": 100 },
+ { "overmap": "corner", "weight": 100 },
+ { "overmap": "tee", "weight": 10 },
+ { "overmap": "crossroads", "weight": 1 }
+ ]
+ ]
+ }
+]
diff --git a/data/mods/default.json b/data/mods/default.json
index 6271c6c613b36..e98c8dc9d745a 100644
--- a/data/mods/default.json
+++ b/data/mods/default.json
@@ -4,6 +4,6 @@
"id": "dev:default",
"name": "default",
"description": "contains all the mods recommended by the developers",
- "dependencies": [ "dda", "no_npc_food", "package_bionic_professions" ]
+ "dependencies": [ "dda", "no_npc_food", "no_fungal_growth", "package_bionic_professions" ]
}
]
diff --git a/doc/COMPILING/COMPILING-VS-VCPKG.md b/doc/COMPILING/COMPILING-VS-VCPKG.md
index 730a40de6c81b..54b1fc934e8f3 100644
--- a/doc/COMPILING/COMPILING-VS-VCPKG.md
+++ b/doc/COMPILING/COMPILING-VS-VCPKG.md
@@ -33,35 +33,6 @@ cd vcpkg
.\vcpkg integrate install
```
-4. Install a necessary pre-requisite package:
-
-#### Install YASM-tool:
-
-```cmd
-.\vcpkg --triplet x86-windows install yasm-tool yasm-tool-helper
-```
-
-5. Install the dependencies for your desired architecture.
-
-
-#### 64-bit dependencies:
-
-```cmd
-.\vcpkg --triplet x64-windows-static install sdl2 sdl2-image sdl2-mixer[libflac,mpg123,libmodplug,libvorbis] sdl2-ttf gettext
-```
-
-#### 32-bit dependencies:
-
-```cmd
-.\vcpkg --triplet x86-windows-static install sdl2 sdl2-image sdl2-mixer[libflac,mpg123,libmodplug,libvorbis] sdl2-ttf gettext
-```
-
-#### upgrade all dependencies:
-
-```cmd
-.\vcpkg upgrade
-```
-
## Cloning and compilation:
1. Clone Cataclysm-DDA repository with following command line:
@@ -79,7 +50,7 @@ cd Cataclysm-DDA
This will configure Visual Studio to compile the release version, with support for Sound, Tiles, and Localization (note, however, that language files themselves are not automatically compiled; this will be done later).
-4. Start the build process by selecting either `Build > Build Solution` or `Build > Build > 1 Cataclysm-vcpkg-static`. The process may take a long period of time, so you'd better prepare a cup of coffee and some books in front of your computer :)
+4. Start the build process by selecting either `Build > Build Solution` or `Build > Build > 1 Cataclysm-vcpkg-static`. The process may take a long period of time, so you'd better prepare a cup of coffee and some books in front of your computer :) The first build of each architecture will also download and install dependencies through vcpkg, which can take an especially long time.
5. If you need localization support, execute the bash script `lang/compile_mo.sh` inside Git Bash GUI just like on a UNIX-like system. This will compile the language files that were not automatically compiled in step 2 above.
diff --git a/doc/EFFECTS_JSON.md b/doc/EFFECTS_JSON.md
index 0860f8e847f29..09ecc69044cf2 100644
--- a/doc/EFFECTS_JSON.md
+++ b/doc/EFFECTS_JSON.md
@@ -235,7 +235,7 @@ Intensities are used to control effect effects, names, and descriptions. They ar
"int_decay_step": -2, - Int, default -1, intensity levels removed every decay tick
"int_decay_tick": 10 - Int, seconds between intensity decay (no decay at the default of 0)
- "int_decay_remove": true - Bool, default true, removes the intensity if decay would decrease it to zero
+ "int_decay_remove": true - Bool, default false, removes the intensity if decay would decrease it to zero
or
"int_dur_factor": 700
```
diff --git a/msvc-full-features/Cataclysm-common.props b/msvc-full-features/Cataclysm-common.props
index 0bbd1df8e3ad3..a9a279ee284fe 100644
--- a/msvc-full-features/Cataclysm-common.props
+++ b/msvc-full-features/Cataclysm-common.props
@@ -7,6 +7,9 @@
$(MSBuildThisFileDirectory)..\
$(SolutionDir)$(ProjectName)\$(Configuration)\$(Platform)\
+
+ --clean-after-build
+
Level1
diff --git a/msvc-full-features/Cataclysm-lib-vcpkg-static.vcxproj b/msvc-full-features/Cataclysm-lib-vcpkg-static.vcxproj
index e37e834a2f336..36ba9f2fd8884 100644
--- a/msvc-full-features/Cataclysm-lib-vcpkg-static.vcxproj
+++ b/msvc-full-features/Cataclysm-lib-vcpkg-static.vcxproj
@@ -33,8 +33,8 @@
true
true
true
- x86-windows
- x64-windows
+ x86-windows-static
+ x64-windows-static
$(Configuration)
diff --git a/msvc-full-features/Cataclysm-test-vcpkg-static.vcxproj b/msvc-full-features/Cataclysm-test-vcpkg-static.vcxproj
index a4f9feef51f62..59c79d81a2841 100644
--- a/msvc-full-features/Cataclysm-test-vcpkg-static.vcxproj
+++ b/msvc-full-features/Cataclysm-test-vcpkg-static.vcxproj
@@ -33,8 +33,8 @@
false
true
true
- x86-windows
- x64-windows
+ x86-windows-static
+ x64-windows-static
$(Configuration)
diff --git a/msvc-full-features/Cataclysm-vcpkg-static.vcxproj b/msvc-full-features/Cataclysm-vcpkg-static.vcxproj
index bd0dd4a506962..f98e74873964e 100644
--- a/msvc-full-features/Cataclysm-vcpkg-static.vcxproj
+++ b/msvc-full-features/Cataclysm-vcpkg-static.vcxproj
@@ -33,8 +33,8 @@
false
true
true
- x86-windows
- x64-windows
+ x86-windows-static
+ x64-windows-static
$(Configuration)
diff --git a/msvc-full-features/JsonFormatter-lib-vcpkg-static.vcxproj b/msvc-full-features/JsonFormatter-lib-vcpkg-static.vcxproj
index 5201f5fee95d3..be41ffcb476a1 100644
--- a/msvc-full-features/JsonFormatter-lib-vcpkg-static.vcxproj
+++ b/msvc-full-features/JsonFormatter-lib-vcpkg-static.vcxproj
@@ -33,8 +33,8 @@
false
true
true
- x86-windows
- x64-windows
+ x86-windows-static
+ x64-windows-static
$(Configuration)
diff --git a/msvc-full-features/JsonFormatter-vcpkg-static.vcxproj b/msvc-full-features/JsonFormatter-vcpkg-static.vcxproj
index 284def1dbe416..701cb1c8650c1 100644
--- a/msvc-full-features/JsonFormatter-vcpkg-static.vcxproj
+++ b/msvc-full-features/JsonFormatter-vcpkg-static.vcxproj
@@ -33,8 +33,8 @@
false
true
true
- x86-windows
- x64-windows
+ x86-windows-static
+ x64-windows-static
$(Configuration)
diff --git a/msvc-full-features/vcpkg.json b/msvc-full-features/vcpkg.json
index 7f3b25de574bc..5f77f8a645bc5 100644
--- a/msvc-full-features/vcpkg.json
+++ b/msvc-full-features/vcpkg.json
@@ -10,5 +10,6 @@
},
"sdl2-ttf",
"gettext"
- ]
+ ],
+ "builtin-baseline": "49b67d9cb856424ff69f10e7721aec5299624268"
}
diff --git a/msvc-object_creator/ObjectCreator-vcpkg-static.vcxproj b/msvc-object_creator/ObjectCreator-vcpkg-static.vcxproj
index 12fcb1637ecdf..91103c8eff31b 100644
--- a/msvc-object_creator/ObjectCreator-vcpkg-static.vcxproj
+++ b/msvc-object_creator/ObjectCreator-vcpkg-static.vcxproj
@@ -33,8 +33,8 @@
true
true
true
- x86-windows
- x64-windows
+ x86-windows-static
+ x64-windows-static
$(Configuration)
@@ -74,7 +74,6 @@
Console
- Netapi32.lib;userenv.lib;Ws2_32.lib;Wtsapi32.lib;Dwmapi.lib;Qt5Core.lib;Qt5Gui.lib;Qt5Widgets.lib;qwindows.lib;%(AdditionalDependencies)
@@ -84,6 +83,9 @@
_DEBUG;%(PreprocessorDefinitions)
MultiThreadedDebug
+
+ Netapi32.lib;userenv.lib;Ws2_32.lib;Wtsapi32.lib;Dwmapi.lib;Qt5Cored.lib;Qt5Guid.lib;Qt5Widgetsd.lib;%(AdditionalDependencies)
+
@@ -97,9 +99,23 @@
true
true
+ Netapi32.lib;userenv.lib;Ws2_32.lib;Wtsapi32.lib;Dwmapi.lib;Qt5Core.lib;Qt5Gui.lib;Qt5Widgets.lib;qwindows.lib;%(AdditionalDependencies)
+
+
+
+
+ WIN32;%(PreprocessorDefinitions)
+
+
+ .\vcpkg_installed\x86-windows-static\debug\plugins\platforms;%(AdditionalLibraryDirectories)
+
+
+
+
+ .\vcpkg_installed\x64-windows-static\debug\plugins\platforms;%(AdditionalLibraryDirectories)
-
+
WIN32;%(PreprocessorDefinitions)
@@ -107,7 +123,7 @@
.\vcpkg_installed\x86-windows-static\plugins\platforms;%(AdditionalLibraryDirectories)
-
+
.\vcpkg_installed\x64-windows-static\plugins\platforms;%(AdditionalLibraryDirectories)
diff --git a/msvc-object_creator/vcpkg.json b/msvc-object_creator/vcpkg.json
index 03a1e75919863..b467582a5d1b0 100644
--- a/msvc-object_creator/vcpkg.json
+++ b/msvc-object_creator/vcpkg.json
@@ -11,5 +11,6 @@
"sdl2-ttf",
"gettext",
"qt5-base"
- ]
+ ],
+ "builtin-baseline": "49b67d9cb856424ff69f10e7721aec5299624268"
}
diff --git a/src/action.cpp b/src/action.cpp
index 6fd3421c0165a..4e4c622ec1712 100644
--- a/src/action.cpp
+++ b/src/action.cpp
@@ -732,9 +732,9 @@ action_id handle_action_menu()
if( !player_character.controlling_vehicle ) {
action_weightings[ACTION_CYCLE_MOVE] = 400;
}
- const item *weapon = player_character.get_wielded_item();
+ const item &weapon = player_character.get_wielded_item();
// Only prioritize fire weapon options if we're wielding a ranged weapon.
- if( weapon->is_gun() || weapon->has_flag( flag_REACH_ATTACK ) ) {
+ if( weapon.is_gun() || weapon.has_flag( flag_REACH_ATTACK ) ) {
action_weightings[ACTION_FIRE] = 350;
}
}
diff --git a/src/activity_actor.cpp b/src/activity_actor.cpp
index 7430c30826715..bc3a972fc2ed2 100644
--- a/src/activity_actor.cpp
+++ b/src/activity_actor.cpp
@@ -297,8 +297,8 @@ item *aim_activity_actor::get_weapon()
} else {
// Check for lost gun (e.g. yanked by zombie technician)
// TODO: check that this is the same gun that was used to start aiming
- item *weapon = get_player_character().get_wielded_item();
- return weapon->is_null() ? nullptr : weapon;
+ item &weapon = get_player_character().get_wielded_item();
+ return weapon.is_null() ? nullptr : &weapon;
}
}
@@ -3873,7 +3873,7 @@ void reload_activity_actor::finish( player_activity &act, Character &who )
reloadable_name );
if( who.has_wield_conflicts( reloadable ) ) {
reload_query.addentry( 1, wield_check, 'w',
- _( "Dispose of %s and wield %s" ), who.get_wielded_item()->display_name(),
+ _( "Dispose of %s and wield %s" ), who.get_wielded_item().display_name(),
reloadable_name );
} else {
reload_query.addentry( 1, wield_check, 'w', _( "Wield %s" ), reloadable_name );
diff --git a/src/activity_handlers.cpp b/src/activity_handlers.cpp
index d87edb4cd2b5d..a48ba24322e37 100644
--- a/src/activity_handlers.cpp
+++ b/src/activity_handlers.cpp
@@ -1808,19 +1808,19 @@ void activity_handlers::pulp_do_turn( player_activity *act, Character *you )
map &here = get_map();
const tripoint &pos = here.getlocal( act->placement );
- const item *weapon = you->get_wielded_item();
+ const item &weapon = you->get_wielded_item();
// Stabbing weapons are a lot less effective at pulping
- const int cut_power = std::max( weapon->damage_melee( damage_type::CUT ),
- weapon->damage_melee( damage_type::STAB ) / 2 );
+ const int cut_power = std::max( weapon.damage_melee( damage_type::CUT ),
+ weapon.damage_melee( damage_type::STAB ) / 2 );
///\EFFECT_STR increases pulping power, with diminishing returns
- float pulp_power = std::sqrt( ( you->str_cur + weapon->damage_melee( damage_type::BASH ) ) *
+ float pulp_power = std::sqrt( ( you->str_cur + weapon.damage_melee( damage_type::BASH ) ) *
( cut_power + 1.0f ) );
- float pulp_effort = you->str_cur + weapon->damage_melee( damage_type::BASH );
+ float pulp_effort = you->str_cur + weapon.damage_melee( damage_type::BASH );
// Multiplier to get the chance right + some bonus for survival skill
pulp_power *= 40 + you->get_skill_level( skill_survival ) * 5;
- const int mess_radius = weapon->has_flag( flag_MESSY ) ? 2 : 1;
+ const int mess_radius = weapon.has_flag( flag_MESSY ) ? 2 : 1;
int moves = 0;
// use this to collect how many corpse are pulped
diff --git a/src/advanced_inv_pane.cpp b/src/advanced_inv_pane.cpp
index ac2627bb098c8..fe5b399dcdbb4 100644
--- a/src/advanced_inv_pane.cpp
+++ b/src/advanced_inv_pane.cpp
@@ -146,11 +146,11 @@ std::vector avatar::get_AIM_inventory( const advanced_inv
}
}
}
- item *weapon = get_wielded_item();
- if( weapon->is_container() ) {
+ item &weapon = get_wielded_item();
+ if( weapon.is_container() ) {
for( const std::vector &it_stack : item_list_to_stack(
- item_location( *this, weapon ),
- weapon->all_items_top( item_pocket::pocket_type::CONTAINER ) ) ) {
+ item_location( *this, &weapon ),
+ weapon.all_items_top( item_pocket::pocket_type::CONTAINER ) ) ) {
advanced_inv_listitem adv_it( it_stack, item_index++, square.id, false );
if( !pane.is_filtered( *adv_it.items.front() ) ) {
square.volume += adv_it.volume;
@@ -181,9 +181,9 @@ void advanced_inventory_pane::add_items_from_area( advanced_inv_area &square,
square.volume = 0_ml;
square.weight = 0_gram;
- item *weapon = u.get_wielded_item();
- if( !weapon->is_null() ) {
- advanced_inv_listitem it( item_location( u, weapon ), 0, 1, square.id, false );
+ item &weapon = u.get_wielded_item();
+ if( !weapon.is_null() ) {
+ advanced_inv_listitem it( item_location( u, &weapon ), 0, 1, square.id, false );
if( !is_filtered( *it.items.front() ) ) {
square.volume += it.volume;
square.weight += it.weight;
diff --git a/src/avatar.cpp b/src/avatar.cpp
index 381ba081179b2..d29bf8ebd9a68 100644
--- a/src/avatar.cpp
+++ b/src/avatar.cpp
@@ -1329,8 +1329,8 @@ bool avatar::wield( item &target, const int obtain_cost )
return true;
}
- item *weapon = get_wielded_item();
- if( weapon->has_item( target ) ) {
+ item &weapon = get_wielded_item();
+ if( weapon.has_item( target ) ) {
add_msg( m_info, _( "You need to put the bag away before trying to wield something from it." ) );
return false;
}
@@ -1339,7 +1339,7 @@ bool avatar::wield( item &target, const int obtain_cost )
return false;
}
- bool combine_stacks = target.can_combine( *weapon );
+ bool combine_stacks = target.can_combine( weapon );
if( !combine_stacks && !unwield() ) {
return false;
}
@@ -1366,28 +1366,28 @@ bool avatar::wield( item &target, const int obtain_cost )
if( has_item( target ) ) {
item removed = i_rem( &target );
if( combine_stacks ) {
- weapon->combine( removed );
+ weapon.combine( removed );
} else {
set_wielded_item( removed );
}
} else {
if( combine_stacks ) {
- weapon->combine( target );
+ weapon.combine( target );
} else {
set_wielded_item( target );
}
}
- last_item = weapon->typeId();
+ last_item = weapon.typeId();
recoil = MAX_RECOIL;
- weapon->on_wield( *this );
+ weapon.on_wield( *this );
get_event_bus().send( getID(), last_item );
- inv->update_invlet( *weapon );
- inv->update_cache_with_item( *weapon );
+ inv->update_invlet( weapon );
+ inv->update_cache_with_item( weapon );
return true;
}
diff --git a/src/avatar_action.cpp b/src/avatar_action.cpp
index ad124ae309f88..8cf26d28dba44 100644
--- a/src/avatar_action.cpp
+++ b/src/avatar_action.cpp
@@ -155,7 +155,7 @@ bool avatar_action::move( avatar &you, map &m, const tripoint &d )
}
// If any leg broken without crutches and not already on the ground topple over
- if( ( you.get_working_leg_count() < 2 && !you.get_wielded_item()->has_flag( flag_CRUTCHES ) ) &&
+ if( ( you.get_working_leg_count() < 2 && !you.get_wielded_item().has_flag( flag_CRUTCHES ) ) &&
!you.is_prone() ) {
you.set_movement_mode( move_mode_id( "prone" ) );
you.add_msg_if_player( m_bad,
@@ -187,20 +187,20 @@ bool avatar_action::move( avatar &you, map &m, const tripoint &d )
via_ramp = true;
}
- item *weapon = you.get_wielded_item();
+ item &weapon = you.get_wielded_item();
if( m.has_flag( ter_furn_flag::TFLAG_MINEABLE, dest_loc ) && g->mostseen == 0 &&
get_option( "AUTO_FEATURES" ) && get_option( "AUTO_MINING" ) &&
!m.veh_at( dest_loc ) && !you.is_underwater() && !you.has_effect( effect_stunned ) &&
!is_riding && !you.has_effect( effect_incorporeal ) ) {
- if( weapon->has_flag( flag_DIG_TOOL ) ) {
- if( weapon->type->can_use( "JACKHAMMER" ) &&
- weapon->ammo_sufficient( &you ) ) {
- you.invoke_item( weapon, "JACKHAMMER", dest_loc );
+ if( weapon.has_flag( flag_DIG_TOOL ) ) {
+ if( weapon.type->can_use( "JACKHAMMER" ) &&
+ weapon.ammo_sufficient( &you ) ) {
+ you.invoke_item( &weapon, "JACKHAMMER", dest_loc );
// don't move into the tile until done mining
you.defer_move( dest_loc );
return true;
- } else if( weapon->type->can_use( "PICKAXE" ) ) {
- you.invoke_item( weapon, "PICKAXE", dest_loc );
+ } else if( weapon.type->can_use( "PICKAXE" ) ) {
+ you.invoke_item( &weapon, "PICKAXE", dest_loc );
// don't move into the tile until done mining
you.defer_move( dest_loc );
return true;
@@ -667,8 +667,8 @@ static float rate_critter( const Creature &c )
void avatar_action::autoattack( avatar &you, map &m )
{
- const item *weapon = you.get_wielded_item();
- int reach = weapon->reach_range( you );
+ const item &weapon = you.get_wielded_item();
+ int reach = weapon.reach_range( you );
std::vector critters = you.get_targetable_creatures( reach, true );
critters.erase( std::remove_if( critters.begin(), critters.end(), [&you,
reach]( const Creature * c ) {
@@ -794,18 +794,18 @@ static bool can_fire_turret( avatar &you, const map &m, const turret_data &turre
void avatar_action::fire_wielded_weapon( avatar &you )
{
- const item *weapon = you.get_wielded_item();
- if( weapon->is_gunmod() ) {
+ const item &weapon = you.get_wielded_item();
+ if( weapon.is_gunmod() ) {
add_msg( m_info,
_( "The %s must be attached to a gun, it can not be fired separately." ),
- weapon->tname() );
+ weapon.tname() );
return;
- } else if( !weapon->is_gun() ) {
+ } else if( !weapon.is_gun() ) {
return;
- } else if( weapon->ammo_data() &&
- !weapon->ammo_types().count( weapon->loaded_ammo().ammo_type() ) ) {
+ } else if( weapon.ammo_data() &&
+ !weapon.ammo_types().count( weapon.loaded_ammo().ammo_type() ) ) {
add_msg( m_info, _( "The %s can't be fired while loaded with incompatible ammunition %s" ),
- weapon->tname(), weapon->ammo_current()->nname( 1 ) );
+ weapon.tname(), weapon.ammo_current()->nname( 1 ) );
return;
}
@@ -849,7 +849,7 @@ void avatar_action::mend( avatar &you, item_location loc )
if( !loc ) {
if( you.is_armed() ) {
- loc = item_location( you, you.get_wielded_item() );
+ loc = item_location( you, &you.get_wielded_item() );
} else {
add_msg( m_info, _( "You're not wielding anything." ) );
return;
@@ -1027,8 +1027,8 @@ void avatar_action::plthrow( avatar &you, item_location loc,
g->temp_exit_fullscreen();
- item *weapon = you.get_wielded_item();
- target_handler::trajectory trajectory = target_handler::mode_throw( you, *weapon,
+ item &weapon = you.get_wielded_item();
+ target_handler::trajectory trajectory = target_handler::mode_throw( you, weapon,
blind_throw_from_pos.has_value() );
// If we previously shifted our position, put ourselves back now that we've picked our target.
@@ -1040,8 +1040,8 @@ void avatar_action::plthrow( avatar &you, item_location loc,
return;
}
- if( weapon->count_by_charges() && weapon->charges > 1 ) {
- weapon->mod_charges( -1 );
+ if( weapon.count_by_charges() && weapon.charges > 1 ) {
+ weapon.mod_charges( -1 );
thrown.charges = 1;
} else {
you.remove_weapon();
diff --git a/src/bionics.cpp b/src/bionics.cpp
index 97e7dd724bd24..b98a0a55708f4 100644
--- a/src/bionics.cpp
+++ b/src/bionics.cpp
@@ -583,7 +583,7 @@ void npc::check_or_use_weapon_cbm( const bionic_id &cbm_id )
}
bionic &bio = ( *my_bionics )[index];
- item *weapon = get_wielded_item();
+ item &weapon = get_wielded_item();
if( bio.info().has_flag( json_flag_BIONIC_GUN ) ) {
if( !bio.has_weapon() ) {
debugmsg( "NPC tried to activate gun bionic \"%s\" without fake_weapon",
@@ -598,19 +598,19 @@ void npc::check_or_use_weapon_cbm( const bionic_id &cbm_id )
return;
}
- int ammo_count = weapon->ammo_remaining( this );
- const int ups_drain = weapon->get_gun_ups_drain();
+ int ammo_count = weapon.ammo_remaining( this );
+ const int ups_drain = weapon.get_gun_ups_drain();
if( ups_drain > 0 ) {
ammo_count = ammo_count / ups_drain;
}
const int cbm_ammo = free_power / bio.info().power_activate;
- if( weapon_value( *weapon, ammo_count ) < weapon_value( cbm_weapon, cbm_ammo ) ) {
- real_weapon = *weapon;
+ if( weapon_value( weapon, ammo_count ) < weapon_value( cbm_weapon, cbm_ammo ) ) {
+ real_weapon = weapon;
set_wielded_item( cbm_weapon );
cbm_weapon_index = index;
}
- } else if( bio.info().has_flag( json_flag_BIONIC_WEAPON ) && !weapon->has_flag( flag_NO_UNWIELD ) &&
+ } else if( bio.info().has_flag( json_flag_BIONIC_WEAPON ) && !weapon.has_flag( flag_NO_UNWIELD ) &&
free_power > bio.info().power_activate ) {
if( !bio.has_weapon() ) {
@@ -620,7 +620,7 @@ void npc::check_or_use_weapon_cbm( const bionic_id &cbm_id )
}
if( is_armed() ) {
- stow_item( *weapon );
+ stow_item( weapon );
}
add_msg_if_player_sees( pos(), m_info, _( "%s activates their %s." ),
disp_name(), bio.info().name );
@@ -640,7 +640,7 @@ void npc::check_or_use_weapon_cbm( const bionic_id &cbm_id )
bool Character::activate_bionic( int b, bool eff_only, bool *close_bionics_ui )
{
- item *weapon = get_wielded_item();
+ item &weapon = get_wielded_item();
bionic &bio = ( *my_bionics )[b];
const bool mounted = is_mounted();
if( bio.incapacitated_time > 0_turns ) {
@@ -650,9 +650,9 @@ bool Character::activate_bionic( int b, bool eff_only, bool *close_bionics_ui )
}
// Special compatibility code for people who updated saves with their claws out
- if( ( weapon->typeId().str() == bio_claws_weapon.str() &&
+ if( ( weapon.typeId().str() == bio_claws_weapon.str() &&
bio.id == bio_claws_weapon ) ||
- ( weapon->typeId().str() == bio_blade_weapon.str() &&
+ ( weapon.typeId().str() == bio_blade_weapon.str() &&
bio.id == bio_blade_weapon ) ) {
return deactivate_bionic( b );
}
@@ -728,7 +728,7 @@ bool Character::activate_bionic( int b, bool eff_only, bool *close_bionics_ui )
return false;
}
- if( weapon->has_flag( flag_NO_UNWIELD ) ) {
+ if( weapon.has_flag( flag_NO_UNWIELD ) ) {
cata::optional active_bio_weapon_index = active_bionic_weapon_index();
if( active_bio_weapon_index && deactivate_bionic( *active_bio_weapon_index, eff_only ) ) {
// restore state and try again
@@ -738,15 +738,15 @@ bool Character::activate_bionic( int b, bool eff_only, bool *close_bionics_ui )
return activate_bionic( b, eff_only, close_bionics_ui );
}
- add_msg_if_player( m_info, _( "Deactivate your %s first!" ), weapon->tname() );
+ add_msg_if_player( m_info, _( "Deactivate your %s first!" ), weapon.tname() );
refund_power();
bio.powered = false;
return false;
}
- if( !weapon->is_null() ) {
- const std::string query = string_format( _( "Stop wielding %s?" ), weapon->tname() );
- if( !dispose_item( item_location( *this, weapon ), query ) ) {
+ if( !weapon.is_null() ) {
+ const std::string query = string_format( _( "Stop wielding %s?" ), weapon.tname() );
+ if( !dispose_item( item_location( *this, &weapon ), query ) ) {
refund_power();
bio.powered = false;
return false;
@@ -756,7 +756,7 @@ bool Character::activate_bionic( int b, bool eff_only, bool *close_bionics_ui )
add_msg_activate();
set_wielded_item( bio.get_weapon() );
- get_wielded_item()->invlet = '#';
+ get_wielded_item().invlet = '#';
//if( bio.ammo_count > 0 ) {
// weapon.ammo_set( bio.ammo_loaded, bio.ammo_count );
// avatar_action::fire_wielded_weapon( player_character );
@@ -1215,7 +1215,7 @@ bool Character::deactivate_bionic( int b, bool eff_only )
bio.powered = false;
add_msg_if_player( m_neutral, _( "You deactivate your %s." ), bio.info().name );
}
- const item &w_weapon = *get_wielded_item();
+ const item &w_weapon = get_wielded_item();
// Deactivation effects go here
if( bio.info().has_flag( json_flag_BIONIC_WEAPON ) && !bio.info().fake_weapon.is_empty() ) {
if( w_weapon.typeId() == bio.info().fake_weapon ) {
@@ -1227,7 +1227,7 @@ bool Character::deactivate_bionic( int b, bool eff_only )
add_msg_if_npc( m_info, _( " withdraws her %s." ), w_weapon.tname() );
}
}
- bio.set_weapon( *get_wielded_item() );
+ bio.set_weapon( get_wielded_item() );
set_wielded_item( item() );
}
} else if( bio.id == bio_cqb ) {
diff --git a/src/character.cpp b/src/character.cpp
index c889c2295d653..582421c22aa4a 100644
--- a/src/character.cpp
+++ b/src/character.cpp
@@ -527,9 +527,9 @@ const item &Character::get_wielded_item() const
return weapon;
}
-item *Character::get_wielded_item()
+item &Character::get_wielded_item()
{
- return &weapon;
+ return weapon;
}
void Character::set_wielded_item( const item &to_wield )
@@ -1283,14 +1283,14 @@ bool Character::is_mounted() const
void Character::forced_dismount()
{
- item *weapon = get_wielded_item();
+ item &weapon = get_wielded_item();
remove_effect( effect_riding );
bool mech = false;
if( mounted_creature ) {
auto *mon = mounted_creature.get();
if( mon->has_flag( MF_RIDEABLE_MECH ) && !mon->type->mech_weapon.is_empty() ) {
mech = true;
- remove_item( *weapon );
+ remove_item( weapon );
}
mon->mounted_player_id = character_id();
mon->remove_effect( effect_ridden );
@@ -1395,13 +1395,13 @@ void Character::dismount()
add_msg( m_warning, _( "You cannot dismount there!" ) );
return;
}
- item *weapon = get_wielded_item();
+ item &weapon = get_wielded_item();
remove_effect( effect_riding );
monster *critter = mounted_creature.get();
critter->mounted_player_id = character_id();
if( critter->has_flag( MF_RIDEABLE_MECH ) && !critter->type->mech_weapon.is_empty() &&
- weapon->typeId() == critter->type->mech_weapon ) {
- remove_item( *weapon );
+ weapon.typeId() == critter->type->mech_weapon ) {
+ remove_item( weapon );
}
avatar &player_character = get_avatar();
if( is_avatar() && player_character.get_grab_type() != object_type::NONE ) {
@@ -1455,10 +1455,10 @@ void Character::on_dodge( Creature *source, float difficulty )
// Each avoided hit consumes an available dodge
// When no more available we are likely to fail player::dodge_roll
dodges_left--;
- const item *weapon = get_wielded_item();
+ const item &weapon = get_wielded_item();
// dodging throws of our aim unless we are either skilled at dodging or using a small weapon
- if( is_armed() && weapon->is_gun() ) {
- recoil += std::max( weapon->volume() / 250_ml - get_skill_level( skill_dodge ), 0 ) * rng( 0, 100 );
+ if( is_armed() && weapon.is_gun() ) {
+ recoil += std::max( weapon.volume() / 250_ml - get_skill_level( skill_dodge ), 0 ) * rng( 0, 100 );
recoil = std::min( MAX_RECOIL, recoil );
}
diff --git a/src/character.h b/src/character.h
index 016c3847c3fa8..4f0538af92a17 100644
--- a/src/character.h
+++ b/src/character.h
@@ -2232,7 +2232,7 @@ class Character : public Creature, public visitable
item weapon;
public:
const item &get_wielded_item() const;
- item *get_wielded_item();
+ item &get_wielded_item();
void set_wielded_item( const item &to_wield );
int scent = 0;
diff --git a/src/crafting.cpp b/src/crafting.cpp
index 17132add328e1..40d5ba953e9eb 100644
--- a/src/crafting.cpp
+++ b/src/crafting.cpp
@@ -640,14 +640,14 @@ static void set_components( std::list- &components, const std::list
- &
static cata::optional wield_craft( Character &p, item &craft )
{
- item *weapon = p.get_wielded_item();
+ item &weapon = p.get_wielded_item();
if( p.wield( craft ) ) {
- if( weapon->invlet ) {
- p.add_msg_if_player( m_info, _( "Wielding %c - %s" ), weapon->invlet, weapon->display_name() );
+ if( weapon.invlet ) {
+ p.add_msg_if_player( m_info, _( "Wielding %c - %s" ), weapon.invlet, weapon.display_name() );
} else {
- p.add_msg_if_player( m_info, _( "Wielding - %s" ), weapon->display_name() );
+ p.add_msg_if_player( m_info, _( "Wielding - %s" ), weapon.display_name() );
}
- return item_location( p, weapon );
+ return item_location( p, &weapon );
}
return cata::nullopt;
}
@@ -788,8 +788,8 @@ static item_location place_craft_or_disassembly(
amenu.text = string_format( pgettext( "in progress craft", "What to do with the %s?" ),
craft.display_name() );
- amenu.addentry( WIELD_CRAFT, ch.can_unwield( *ch.get_wielded_item() ).success(),
- '1', _( "Dispose of your wielded %s and start working." ), ch.get_wielded_item()->tname() );
+ amenu.addentry( WIELD_CRAFT, ch.can_unwield( ch.get_wielded_item() ).success(),
+ '1', _( "Dispose of your wielded %s and start working." ), ch.get_wielded_item().tname() );
amenu.addentry( DROP_CRAFT, true, '2', _( "Put it down and start working." ) );
const bool can_stash = ch.can_pickVolume( craft ) &&
ch.can_pickWeight( craft, !get_option( "DANGEROUS_PICKUPS" ) );
@@ -1719,7 +1719,7 @@ static void empty_buckets( Character &p )
{
// First grab (remove) all items that are non-empty buckets and not wielded
auto buckets = p.remove_items_with( [&p]( const item & it ) {
- return it.is_bucket_nonempty() && &it != p.get_wielded_item();
+ return it.is_bucket_nonempty() && &it != &p.get_wielded_item();
}, INT_MAX );
for( auto &it : buckets ) {
for( const item *in : it.all_items_top() ) {
diff --git a/src/debug_menu.cpp b/src/debug_menu.cpp
index c14d5d1d641a8..96a5da7d874c4 100644
--- a/src/debug_menu.cpp
+++ b/src/debug_menu.cpp
@@ -1345,7 +1345,7 @@ static void character_edit_menu()
} else if( !to_wear.is_null() ) {
you.set_wielded_item( to_wear );
get_event_bus().send( you.getID(),
- you.get_wielded_item()->typeId() );
+ you.get_wielded_item().typeId() );
}
}
break;
diff --git a/src/do_turn.cpp b/src/do_turn.cpp
index a88b6b354cb4d..1d2e77f00c813 100644
--- a/src/do_turn.cpp
+++ b/src/do_turn.cpp
@@ -37,7 +37,6 @@ static const activity_id ACT_OPERATION( "ACT_OPERATION" );
static const activity_id ACT_AUTODRIVE( "ACT_AUTODRIVE" );
static const efftype_id effect_controlled( "controlled" );
-static const efftype_id effect_downed( "downed" );
static const efftype_id effect_npc_suspend( "npc_suspend" );
static const efftype_id effect_ridden( "ridden" );
static const efftype_id effect_sleep( "sleep" );
@@ -46,7 +45,6 @@ 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" );
-static const trait_id trait_LEG_TENT_BRACE( "LEG_TENT_BRACE" );
static const trait_id trait_HAS_NEMESIS( "HAS_NEMESIS" );
#if defined(__ANDROID__)
@@ -353,219 +351,6 @@ bool cleanup_at_end()
return true;
}
-// TODO: abstract out the location checking code
-// TODO: refactor so zombies can follow up and down stairs instead of this mess
-void update_stair_monsters()
-{
- // Search for the stairs closest to the player.
- std::vector stairx;
- std::vector stairy;
- std::vector stairdist;
-
- map &m = get_map();
- const bool from_below = g->monstairz < m.get_abs_sub().z;
-
- if( g->coming_to_stairs.empty() ) {
- return;
- }
-
- if( m.has_zlevels() ) {
- debugmsg( "%d monsters coming to stairs on a map with z-levels",
- g->coming_to_stairs.size() );
- g->coming_to_stairs.clear();
- }
-
- avatar &u = get_avatar();
- for( const tripoint &dest : m.points_on_zlevel( u.posz() ) ) {
- if( ( from_below && m.has_flag( ter_furn_flag::TFLAG_GOES_DOWN, dest ) ) ||
- ( !from_below && m.has_flag( ter_furn_flag::TFLAG_GOES_UP, dest ) ) ) {
- stairx.push_back( dest.x );
- stairy.push_back( dest.y );
- stairdist.push_back( rl_dist( dest, u.pos() ) );
- }
- }
- if( stairdist.empty() ) {
- return; // Found no stairs?
- }
-
- // Find closest stairs.
- size_t si = 0;
- for( size_t i = 0; i < stairdist.size(); i++ ) {
- if( stairdist[i] < stairdist[si] ) {
- si = i;
- }
- }
-
- // Find up to 4 stairs for distance stairdist[si] +1
- std::vector nearest;
- nearest.push_back( si );
- for( size_t i = 0; i < stairdist.size() && nearest.size() < 4; i++ ) {
- if( ( i != si ) && ( stairdist[i] <= stairdist[si] + 1 ) ) {
- nearest.push_back( i );
- }
- }
- // Randomize the stair choice
- si = random_entry_ref( nearest );
-
- creature_tracker &creatures = get_creature_tracker();
- // Attempt to spawn zombies.
- for( size_t i = 0; i < g->coming_to_stairs.size(); i++ ) {
- point mpos( stairx[si], stairy[si] );
- monster &critter = g->coming_to_stairs[i];
- const tripoint dest {
- mpos, get_map().get_abs_sub().z
- };
-
- // We might be not be visible.
- if( ( critter.posx() < 0 - ( MAPSIZE_X ) / 6 ||
- critter.posy() < 0 - ( MAPSIZE_Y ) / 6 ||
- critter.posx() > ( MAPSIZE_X * 7 ) / 6 ||
- critter.posy() > ( MAPSIZE_Y * 7 ) / 6 ) ) {
- continue;
- }
-
- critter.staircount -= 4;
- // Let the player know zombies are trying to come.
- if( u.sees( dest ) ) {
- std::string dump;
- if( critter.staircount > 4 ) {
- dump += string_format( _( "You see a %s on the stairs" ), critter.name() );
- } else {
- if( critter.staircount > 0 ) {
- dump += ( from_below ?
- //~ The is almost at the of the !
- string_format( _( "The %1$s is almost at the top of the %2$s!" ),
- critter.name(),
- m.tername( dest ) ) :
- string_format( _( "The %1$s is almost at the bottom of the %2$s!" ),
- critter.name(),
- m.tername( dest ) ) );
- }
- }
-
- add_msg( m_warning, dump );
- } else {
- sounds::sound( dest, 5, sounds::sound_t::movement,
- _( "a sound nearby from the stairs!" ), true, "misc", "stairs_movement" );
- }
-
- if( critter.staircount > 0 ) {
- continue;
- }
-
- if( g->is_empty( dest ) ) {
- critter.spawn( dest );
- critter.staircount = 0;
- g->place_critter_at( make_shared_fast( critter ), dest );
- if( u.sees( dest ) ) {
- if( !from_below ) {
- add_msg( m_warning, _( "The %1$s comes down the %2$s!" ),
- critter.name(),
- m.tername( dest ) );
- } else {
- add_msg( m_warning, _( "The %1$s comes up the %2$s!" ),
- critter.name(),
- m.tername( dest ) );
- }
- }
- g->coming_to_stairs.erase( g->coming_to_stairs.begin() + i );
- continue;
- } else if( u.pos() == dest ) {
- // Monster attempts to push player of stairs
- point push( point_north_west );
- int tries = 0;
-
- // the critter is now right on top of you and will attack unless
- // it can find a square to push you into with one of his tries.
- const int creature_push_attempts = 9;
- const int player_throw_resist_chance = 3;
-
- critter.spawn( dest );
- while( tries < creature_push_attempts ) {
- tries++;
- push.x = rng( -1, 1 );
- push.y = rng( -1, 1 );
- point ipos( mpos + push );
- tripoint pos( ipos, m.get_abs_sub().z );
- if( ( push.x != 0 || push.y != 0 ) && !creatures.creature_at( pos ) &&
- critter.can_move_to( pos ) ) {
- bool resiststhrow = ( u.is_throw_immune() ) ||
- ( u.has_trait( trait_LEG_TENT_BRACE ) );
- if( resiststhrow && one_in( player_throw_resist_chance ) ) {
- u.moves -= 25; // small charge for avoiding the push altogether
- add_msg( _( "The %s fails to push you back!" ),
- critter.name() );
- return; //judo or leg brace prevent you from getting pushed at all
- }
- // Not accounting for tentacles latching on, so..
- // Something is about to happen, lets charge half a move
- u.moves -= 50;
- if( resiststhrow && ( u.is_throw_immune() ) ) {
- //we have a judoka who isn't getting pushed but counterattacking now.
- mattack::thrown_by_judo( &critter );
- return;
- }
- std::string msg;
- ///\EFFECT_DODGE reduces chance of being downed when pushed off the stairs
- if( !( resiststhrow ) && ( u.get_dodge() + rng( 0, 3 ) < 12 ) ) {
- // dodge 12 - never get downed
- // 11.. avoid 75%; 10.. avoid 50%; 9.. avoid 25%
- u.add_effect( effect_downed, 2_turns );
- msg = _( "The %s pushed you back hard!" );
- } else {
- msg = _( "The %s pushed you back!" );
- }
- add_msg( m_warning, msg.c_str(), critter.name() );
- u.move_to( u.get_location() + push );
- return;
- }
- }
- add_msg( m_warning,
- _( "The %s tried to push you back but failed! It attacks you!" ),
- critter.name() );
- critter.melee_attack( u );
- u.moves -= 50;
- return;
- } else if( monster *const mon_ptr = creatures.creature_at( dest ) ) {
- // Monster attempts to displace a monster from the stairs
- monster &other = *mon_ptr;
- critter.spawn( dest );
-
- // the critter is now right on top of another and will push it
- // if it can find a square to push it into inside of his tries.
- const int creature_push_attempts = 9;
- const int creature_throw_resist = 4;
-
- int tries = 0;
- point push2;
- while( tries < creature_push_attempts ) {
- tries++;
- push2.x = rng( -1, 1 );
- push2.y = rng( -1, 1 );
- point ipos2( mpos + push2 );
- tripoint pos( ipos2, m.get_abs_sub().z );
- if( ( push2.x == 0 && push2.y == 0 ) || ( ( ipos2.x == u.posx() ) && ( ipos2.y == u.posy() ) ) ) {
- continue;
- }
- if( !creatures.creature_at( pos ) && other.can_move_to( pos ) ) {
- other.setpos( tripoint( ipos2, m.get_abs_sub().z ) );
- other.moves -= 50;
- std::string msg;
- if( one_in( creature_throw_resist ) ) {
- other.add_effect( effect_downed, 2_turns );
- msg = _( "The %1$s pushed the %2$s hard." );
- } else {
- msg = _( "The %1$s pushed the %2$s." );
- }
- add_msg( m_neutral, msg, critter.name(), other.name() );
- return;
- }
- }
- return;
- }
- }
-}
-
} // namespace turn_handler
void handle_key_blocking_activity()
@@ -996,7 +781,6 @@ bool do_turn()
}
}
}
- turn_handler::update_stair_monsters();
g->mon_info_update();
u.process_turn();
if( u.moves < 0 && get_option( "FORCE_REDRAW" ) ) {
diff --git a/src/editmap.cpp b/src/editmap.cpp
index b3511e2151981..c7fac0d52f1f1 100644
--- a/src/editmap.cpp
+++ b/src/editmap.cpp
@@ -661,7 +661,7 @@ void editmap::draw_main_ui_overlay()
g->draw_vpart_override( map_p, vpart_id::NULL_ID(), 0, 0_degrees, false,
point_zero );
}
- g->draw_below_override( map_p, here.has_zlevels() &&
+ g->draw_below_override( map_p,
tmpmap.ter( tmp_p ).obj().has_flag( ter_furn_flag::TFLAG_NO_FLOOR ) );
}
}
diff --git a/src/effect.cpp b/src/effect.cpp
index 358abe16ebcc8..44968b9a8a739 100644
--- a/src/effect.cpp
+++ b/src/effect.cpp
@@ -1494,7 +1494,7 @@ void load_effect_type( const JsonObject &jo )
new_etype.int_add_val = jo.get_int( "int_add_val", 0 );
new_etype.int_decay_step = jo.get_int( "int_decay_step", -1 );
new_etype.int_decay_tick = jo.get_int( "int_decay_tick", 0 );
- optional( jo, false, "int_decay_remove", new_etype.int_decay_remove, true );
+ optional( jo, false, "int_decay_remove", new_etype.int_decay_remove, false );
new_etype.load_miss_msgs( jo, "miss_messages" );
new_etype.load_decay_msgs( jo, "decay_messages" );
diff --git a/src/effect.h b/src/effect.h
index 2bd714b4cae68..ac7622016ca73 100644
--- a/src/effect.h
+++ b/src/effect.h
@@ -139,7 +139,7 @@ class effect_type
int int_decay_step = 0;
int int_decay_tick = 0 ;
time_duration int_dur_factor = 0_turns;
- bool int_decay_remove = true;
+ bool int_decay_remove = false;
std::set flags;
diff --git a/src/explosion.cpp b/src/explosion.cpp
index bc880364c0862..7cc415a388960 100644
--- a/src/explosion.cpp
+++ b/src/explosion.cpp
@@ -166,7 +166,7 @@ static void do_blast( const tripoint &p, const float power,
static const int y_offset[10] = { 0, 0, -1, 1, -1, 1, -1, 1, 0, 0 };
static const int z_offset[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, -1 };
map &here = get_map();
- const size_t max_index = here.has_zlevels() ? 10 : 8;
+ const size_t max_index = 10;
here.bash( p, fire ? power : ( 2 * power ), true, false, false );
@@ -292,13 +292,6 @@ static void do_blast( const tripoint &p, const float power,
if( force > 10.0f || x_in_y( force, 10.0f ) ) {
intensity++;
}
-
- if( !here.has_zlevels() && here.is_outside( pt ) && intensity == 2 ) {
- // In 3D mode, it would have fire fields above, which would then fall
- // and fuel the fire on this tile
- intensity++;
- }
-
here.add_field( pt, fd_fire, intensity );
}
@@ -774,13 +767,13 @@ void emp_blast( const tripoint &p )
}
// TODO: More effects?
//e-handcuffs effects
- item *weapon = player_character.get_wielded_item();
- if( weapon->typeId() == itype_e_handcuffs && weapon->charges > 0 ) {
- weapon->unset_flag( STATIC( flag_id( "NO_UNWIELD" ) ) );
- weapon->charges = 0;
- weapon->active = false;
+ item &weapon = player_character.get_wielded_item();
+ if( weapon.typeId() == itype_e_handcuffs && weapon.charges > 0 ) {
+ weapon.unset_flag( STATIC( flag_id( "NO_UNWIELD" ) ) );
+ weapon.charges = 0;
+ weapon.active = false;
add_msg( m_good, _( "The %s on your wrists spark briefly, then release your hands!" ),
- weapon->tname() );
+ weapon.tname() );
}
}
// Drain any items of their battery charge
diff --git a/src/game.cpp b/src/game.cpp
index 2d230e3f981c6..a2e454ec326ee 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -196,7 +196,6 @@ static constexpr int DANGEROUS_PROXIMITY = 5;
static const mtype_id mon_manhack( "mon_manhack" );
-static const skill_id skill_melee( "melee" );
static const skill_id skill_dodge( "dodge" );
static const skill_id skill_gun( "gun" );
static const skill_id skill_firstaid( "firstaid" );
@@ -610,7 +609,7 @@ void game::setup()
load_world_modfiles( ui );
- m = map( true );
+ m = map();
next_npc_id = character_id( 1 );
next_mission_id = 1;
@@ -632,7 +631,6 @@ void game::setup()
sounds::reset_sounds();
clear_zombies();
- coming_to_stairs.clear();
critter_tracker->clear_npcs();
faction_manager_ptr->clear();
mission::clear_all();
@@ -959,7 +957,7 @@ void game::load_npcs()
const tripoint_abs_sm sm_loc = temp->global_sm_location();
// NPCs who are out of bounds before placement would be pushed into bounds
// This can cause NPCs to teleport around, so we don't want that
- if( !map_bounds.contains( sm_loc.xy() ) || ( sm_loc.z() != abs_sub.z() && !m.has_zlevels() ) ) {
+ if( !map_bounds.contains( sm_loc.xy() ) ) {
continue;
}
@@ -1662,7 +1660,7 @@ int game::inventory_item_menu( item_location locThisItem,
std::vector vDummy;
const bool bHPR = get_auto_pickup().has_rule( &oThisItem );
- const hint_rating rate_drop_item = u.get_wielded_item()->has_flag( flag_NO_UNWIELD ) ?
+ const hint_rating rate_drop_item = u.get_wielded_item().has_flag( flag_NO_UNWIELD ) ?
hint_rating::cant :
hint_rating::good;
@@ -2274,7 +2272,7 @@ bool game::try_get_right_click_action( action_id &act, const tripoint &mouse_tar
return false;
}
- if( !u.get_wielded_item()->is_gun() ) {
+ if( !u.get_wielded_item().is_gun() ) {
add_msg( m_info, _( "You are not wielding a ranged weapon." ) );
return false;
}
@@ -3210,7 +3208,7 @@ void game::draw_critter( const Creature &critter, const tripoint ¢er )
if( !is_valid_in_w_terrain( point( mx, my ) ) ) {
return;
}
- if( critter.posz() != center.z && m.has_zlevels() ) {
+ if( critter.posz() != center.z ) {
static constexpr tripoint up_tripoint( tripoint_above );
if( critter.posz() == center.z - 1 &&
( debug_mode || u.sees( critter ) ) &&
@@ -5701,7 +5699,7 @@ void game::print_terrain_info( const tripoint &lp, const catacurses::window &w_l
mvwprintz( w_look, point( column + utf8_width( _( "Lighting: " ) ), line ), ll.second, ll.first );
// Print the terrain and any furntiure on the tile below and whether it is walkable.
- if( m.has_zlevels() && lp.z > -OVERMAP_DEPTH && !m.has_floor( lp ) ) {
+ if( lp.z > -OVERMAP_DEPTH && !m.has_floor( lp ) ) {
tripoint below( lp.xy(), lp.z - 1 );
std::string tile_below = m.tername( below );
if( m.has_furn( below ) ) {
@@ -6396,7 +6394,7 @@ look_around_result game::look_around( const bool show_window, tripoint ¢er,
{
bVMonsterLookFire = false;
// TODO: Make this `true`
- const bool allow_zlev_move = m.has_zlevels() && get_option( "FOV_3D" );
+ const bool allow_zlev_move = get_option( "FOV_3D" );
temp_exit_fullscreen();
@@ -6711,7 +6709,7 @@ look_around_result game::look_around( const bool show_window, tripoint ¢er,
} while( action != "QUIT" && action != "CONFIRM" && action != "SELECT" && action != "TRAVEL_TO" &&
action != "throw_blind" );
- if( m.has_zlevels() && center.z != old_levz ) {
+ if( center.z != old_levz ) {
m.invalidate_map_cache( old_levz );
m.build_map_cache( old_levz );
u.view_offset.z = 0;
@@ -7569,7 +7567,7 @@ game::vmenu_ret game::list_monsters( const std::vector &monster_list
} );
ui.mark_resize();
- const int max_gun_range = u.get_wielded_item()->gun_range( &u );
+ const int max_gun_range = u.get_wielded_item().gun_range( &u );
const tripoint stored_view_offset = u.view_offset;
u.view_offset = tripoint_zero;
@@ -8549,12 +8547,12 @@ void game::reload_item()
void game::reload_wielded( bool prompt )
{
- item *weapon = u.get_wielded_item();
- if( weapon->is_null() || !weapon->is_reloadable() ) {
+ item &weapon = u.get_wielded_item();
+ if( weapon.is_null() || !weapon.is_reloadable() ) {
add_msg( _( "You aren't holding something you can reload." ) );
return;
}
- item_location item_loc = item_location( u, weapon );
+ item_location item_loc = item_location( u, &weapon );
reload( item_loc, prompt );
}
@@ -8580,9 +8578,9 @@ void game::reload_weapon( bool try_everything )
return true;
}
// Second sort by affiliation with wielded gun
- const std::set compatible_magazines = this->u.get_wielded_item()->magazine_compatible();
- const bool mag_ap = this->u.get_wielded_item()->can_contain( *ap, true ).success();
- const bool mag_bp = this->u.get_wielded_item()->can_contain( *bp, true ).success();
+ const std::set compatible_magazines = this->u.get_wielded_item().magazine_compatible();
+ const bool mag_ap = this->u.get_wielded_item().can_contain( *ap, true ).success();
+ const bool mag_bp = this->u.get_wielded_item().can_contain( *bp, true ).success();
if( mag_ap != mag_bp ) {
return mag_ap;
}
@@ -8630,8 +8628,8 @@ void game::wield( item_location loc )
debugmsg( "ERROR: tried to wield null item" );
return;
}
- const item *weapon = u.get_wielded_item();
- if( weapon != &*loc && weapon->has_item( *loc ) ) {
+ const item &weapon = u.get_wielded_item();
+ if( &weapon != &*loc && weapon.has_item( *loc ) ) {
add_msg( m_info, _( "You need to put the bag away before trying to wield something from it." ) );
return;
}
@@ -8917,8 +8915,7 @@ std::vector game::get_dangerous_tile( const tripoint &dest_loc ) co
const trap &tr = m.tr_at( dest_loc );
// HACK: Hack for now, later ledge should stop being a trap
- // Note: in non-z-level mode, ledges obey different rules and so should be handled as regular traps
- if( tr == tr_ledge && m.has_zlevels() ) {
+ if( tr == tr_ledge ) {
if( !veh_dest ) {
harmful_stuff.emplace_back( tr.name() );
}
@@ -9402,7 +9399,7 @@ point game::place_player( const tripoint &dest_loc )
}
// Move the player
// Start with z-level, to make it less likely that old functions (2D ones) freak out
- if( m.has_zlevels() && dest_loc.z != m.get_abs_sub().z ) {
+ if( dest_loc.z != m.get_abs_sub().z ) {
vertical_shift( dest_loc.z );
}
@@ -9637,9 +9634,7 @@ void game::place_player_overmap( const tripoint_abs_omt &om_dest )
if( u.in_vehicle ) {
m.unboard_vehicle( u.pos() );
}
- const int minz = m.has_zlevels() ? -OVERMAP_DEPTH : m.get_abs_sub().z;
- const int maxz = m.has_zlevels() ? OVERMAP_HEIGHT : m.get_abs_sub().z;
- for( int z = minz; z <= maxz; z++ ) {
+ for( int z = -OVERMAP_DEPTH; z <= OVERMAP_HEIGHT; z++ ) {
m.clear_vehicle_list( z );
}
m.rebuild_vehicle_level_caches();
@@ -10353,8 +10348,7 @@ void game::vertical_move( int movez, bool force, bool peeking )
bool climbing = false;
int move_cost = 100;
tripoint stairs( u.posx(), u.posy(), u.posz() + movez );
- if( here.has_zlevels() && !force && movez == 1 &&
- !here.has_flag( ter_furn_flag::TFLAG_GOES_UP, u.pos() ) ) {
+ if( !force && movez == 1 && !here.has_flag( ter_furn_flag::TFLAG_GOES_UP, u.pos() ) ) {
// Climbing
if( here.has_floor_or_support( stairs ) ) {
add_msg( m_info, _( "You can't climb here - there's a ceiling above your head." ) );
@@ -10411,10 +10405,7 @@ void game::vertical_move( int movez, bool force, bool peeking )
return;
}
- // Because abs_sub will change when vertical_shift (here.has_zlevels() == true)
- // is called or when the map is loaded on new z-level (== false).
- // This caches the z-level we start the movement on (current) and the level we're want to end.
- const int z_before = m.get_abs_sub().z;
+ // TODO: Use u.posz() instead of m.abs_sub
const int z_after = m.get_abs_sub().z + movez;
if( z_after < -OVERMAP_DEPTH || z_after > OVERMAP_HEIGHT ) {
debugmsg( "Tried to move outside allowed range of z-levels" );
@@ -10433,124 +10424,25 @@ void game::vertical_move( int movez, bool force, bool peeking )
}
}
- // Check if there are monsters are using the stairs.
- bool slippedpast = false;
- if( !here.has_zlevels() && !coming_to_stairs.empty() && !force ) {
- // TODO: Allow travel if zombie couldn't reach stairs, but spawn him when we go up.
- add_msg( m_warning, _( "You try to use the stairs. Suddenly you are blocked by a %s!" ),
- coming_to_stairs[0].name() );
- // Roll.
- ///\EFFECT_DEX increases chance of moving past monsters on stairs
-
- ///\EFFECT_DODGE increases chance of moving past monsters on stairs
- int dexroll = dice( 6, u.dex_cur + u.get_skill_level( skill_dodge ) * 2 );
- ///\EFFECT_STR increases chance of moving past monsters on stairs
-
- ///\EFFECT_MELEE increases chance of moving past monsters on stairs
- int strroll = dice( 3, u.str_cur + u.get_skill_level( skill_melee ) * 1.5 );
- if( coming_to_stairs.size() > 4 ) {
- add_msg( _( "The are a lot of them on the %s!" ), here.tername( u.pos() ) );
- dexroll /= 4;
- strroll /= 2;
- } else if( coming_to_stairs.size() > 1 ) {
- add_msg( m_warning, _( "There's something else behind it!" ) );
- dexroll /= 2;
- }
-
- if( dexroll < 14 || strroll < 12 ) {
- turn_handler::update_stair_monsters();
- u.moves -= 100;
- return;
- }
-
- add_msg( _( "You manage to slip past!" ) );
- slippedpast = true;
- u.moves -= 100;
- }
-
- // Shift the map up or down
-
- std::unique_ptr