diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index e9ee9eb178160..bd3551e8c2e91 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -233,9 +233,8 @@ You can also set the tracking information at the same time as creating the branc There is a suite of tests built into the source tree at tests/ You should run the test suite after ANY change to the game source. -An ordinary invocation of ``make`` will build the test executable at tests/cata_test, and it can be invoked like any ordinary executable, or via `make check`. -With no arguments it will run the entire test suite. -With ``--help`` it will print a number of invocation options you can use to adjust its operation. +An ordinary invocation of `make` will build the test executable at tests/cata_test, and it can be invoked like any ordinary executable, or via `make check`. +Running `test/cata_test` with no arguments will run the entire test suite; running it with `--help` will print a number of invocation options you can use to adjust its operation. $ make ... compilation details ... @@ -248,6 +247,8 @@ With ``--help`` it will print a number of invocation options you can use to adju I recommend habitually invoking make like ``make YOUR BUILD OPTIONS && make check``. +If you're working with Visual Studio (and don't have `make`), see [Visual Studio-specific advice](../doc/COMPILING/COMPILING-VS-VCPKG.md#running-unit-tests). + ## In-game testing, test environment and the debug menu Whether you are implementing a new feature or whether you are fixing a bug, it is always a good practice to test your changes in-game. It can be a hard task to create the exact conditions by playing a normal game to be able to test your changes, which is why there is a debug menu. There is no default key to bring up the menu so you will need to assign one first. diff --git a/build-data/osx/dmgsettings.py b/build-data/osx/dmgsettings.py index a73626b58e798..9694f4c34100a 100644 --- a/build-data/osx/dmgsettings.py +++ b/build-data/osx/dmgsettings.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals + import biplist import os.path diff --git a/build-scripts/get_all_mods.py b/build-scripts/get_all_mods.py index 59945a36b510c..fc08087c68874 100755 --- a/build-scripts/get_all_mods.py +++ b/build-scripts/get_all_mods.py @@ -10,16 +10,18 @@ mods_to_keep = [] + def add_mods(mods): for mod in mods: - if not mod in all_mod_dependencies: + if mod not in all_mod_dependencies: # Either an invalid mod id, or blacklisted. return False for mod in mods: - if not mod in mods_to_keep: + if mod not in mods_to_keep: mods_to_keep.append(mod) return True + all_mod_dependencies = {} for info in glob.glob('data/mods/*/modinfo.json'): @@ -31,7 +33,7 @@ def add_mods(mods): all_mod_dependencies[ident] = e.get("dependencies", []) for mod in all_mod_dependencies: - if not mod in mods_to_keep: + if mod not in mods_to_keep: if add_mods(all_mod_dependencies[mod]): mods_to_keep.append(mod) diff --git a/build-scripts/lint-json.sh b/build-scripts/lint-json.sh index 0aa4bba70ca13..6a92a9d6752eb 100755 --- a/build-scripts/lint-json.sh +++ b/build-scripts/lint-json.sh @@ -1 +1 @@ -find . -name "*json" -type f -exec python -m json.tool {} >/dev/null \; +find . -name "*json" -type f -exec python3 -m json.tool {} >/dev/null \; diff --git a/data/json/achievements.json b/data/json/achievements.json index 66decd2db0948..98bd393b97f26 100644 --- a/data/json/achievements.json +++ b/data/json/achievements.json @@ -73,7 +73,7 @@ "id": "achievement_marathon", "type": "achievement", "name": "Pheidippides was a hack", - "description": "Run a marathon… plus a little bit more.", + "description": "Run a marathon… plus a little more.", "requirements": [ { "event_statistic": "num_moves_ran", "is": ">=", "target": 42196 } ] }, { @@ -298,7 +298,7 @@ "id": "achievement_lvl_10_barter", "type": "achievement", "name": "Cut-Me-Own-Throat Dibbler", - "description": "My Innuit friend, I'm selling you this ice for such a low price, that it's cutting me own throat.", + "description": "My Inuit friend, I'm selling you this ice for such a low price, that it's cutting me own throat.", "requirements": [ { "event_statistic": "num_gains_barter_level_10", "is": ">=", "target": 1 } ], "hidden_by": [ "achievement_lvl_7_barter" ] }, @@ -306,7 +306,7 @@ "id": "achievement_lvl_7_speech", "type": "achievement", "name": "Eloquent", - "description": "We're frends, aren't we?", + "description": "We're friends, aren't we?", "requirements": [ { "event_statistic": "num_gains_speech_level_7", "is": ">=", "target": 1 } ] }, { @@ -403,7 +403,7 @@ "id": "achievement_lvl_10_swimming", "type": "achievement", "name": "Michael Phelps", - "description": "Faster then Jaws.", + "description": "Faster than Jaws.", "requirements": [ { "event_statistic": "num_gains_swimming_level_10", "is": ">=", "target": 1 } ], "hidden_by": [ "achievement_lvl_7_swimming" ] }, @@ -418,7 +418,7 @@ "id": "achievement_lvl_10_fabrication", "type": "achievement", "name": "Jack of All Trades", - "description": "With a right ammount of glue, there is nothing I can't do.", + "description": "With a right amount of glue, there is nothing I can't do.", "requirements": [ { "event_statistic": "num_gains_fabrication_level_10", "is": ">=", "target": 1 } ], "hidden_by": [ "achievement_lvl_7_fabrication" ] }, @@ -448,7 +448,7 @@ "id": "achievement_lvl_10_tailor", "type": "achievement", "name": "Fashion Designer", - "description": "Male, feamale and mutant fashion alike.", + "description": "Male, female and mutant fashion alike.", "requirements": [ { "event_statistic": "num_gains_tailor_level_10", "is": ">=", "target": 1 } ], "hidden_by": [ "achievement_lvl_7_tailor" ] }, @@ -486,7 +486,7 @@ "id": "achievement_lvl_7_archery", "type": "achievement", "name": "Bull's Eye", - "description": "Better then Legolas.", + "description": "Better than Legolas.", "requirements": [ { "event_statistic": "num_gains_archery_level_7", "is": ">=", "target": 1 } ] }, { @@ -531,7 +531,7 @@ "id": "achievement_lvl_7_pistol", "type": "achievement", "name": "Small But Deadly", - "description": "Caliber doesn't count when you're on the recieving side of the barrel.", + "description": "Caliber doesn't count when you're on the receiving side of the barrel.", "requirements": [ { "event_statistic": "num_gains_pistol_level_7", "is": ">=", "target": 1 } ] }, { diff --git a/data/json/artifact/relic_procgen_data.json b/data/json/artifact/relic_procgen_data.json index b9c8593b5ea80..1d0429219a883 100644 --- a/data/json/artifact/relic_procgen_data.json +++ b/data/json/artifact/relic_procgen_data.json @@ -2,6 +2,17 @@ { "type": "relic_procgen_data", "id": "cult", + "charge_types": [ + { + "weight": 100, + "charges": { "range": [ 0, 3 ], "power": 25 }, + "charges_per_use": { "range": [ 1, 1 ], "power": 25 }, + "max_charges": { "range": [ 1, 3 ], "power": 25 }, + "recharge_type": "periodic", + "time": [ "3 h", "6 h" ] + } + ], + "active_procgen_values": [ { "weight": 100, "spell_id": "AEA_PAIN", "base_power": 50 } ], "passive_add_procgen_values": [ { "weight": 100, "min_value": -1, "max_value": 1, "type": "STRENGTH", "increment": 1, "power_per_increment": 250 }, { @@ -37,12 +48,23 @@ "power_per_increment": 200 } ], - "type_weights": [ { "weight": 100, "value": "passive_enchantment_add" } ], + "type_weights": [ { "weight": 100, "value": "passive_enchantment_add" }, { "weight": 100, "value": "active_enchantment" } ], "items": [ { "weight": 100, "item": "spoon" } ] }, { "type": "relic_procgen_data", "id": "netherum_tunnels", + "charge_types": [ + { + "weight": 100, + "charges": { "range": [ 0, 3 ], "power": 25 }, + "charges_per_use": { "range": [ 1, 1 ], "power": 25 }, + "max_charges": { "range": [ 1, 3 ], "power": 25 }, + "recharge_type": "periodic", + "time": [ "3 h", "6 h" ] + } + ], + "active_procgen_values": [ { "weight": 100, "spell_id": "AEA_PAIN", "base_power": 50 } ], "passive_add_procgen_values": [ { "weight": 100, "min_value": -1, "max_value": 1, "type": "STRENGTH", "increment": 1, "power_per_increment": 250 }, { @@ -78,12 +100,23 @@ "power_per_increment": 200 } ], - "type_weights": [ { "weight": 100, "value": "passive_enchantment_add" } ], + "type_weights": [ { "weight": 100, "value": "passive_enchantment_add" }, { "weight": 100, "value": "active_enchantment" } ], "items": [ { "weight": 100, "item": "spoon" } ] }, { "type": "relic_procgen_data", "id": "alien_reality", + "charge_types": [ + { + "weight": 100, + "charges": { "range": [ 0, 3 ], "power": 25 }, + "charges_per_use": { "range": [ 1, 1 ], "power": 25 }, + "max_charges": { "range": [ 1, 3 ], "power": 25 }, + "recharge_type": "periodic", + "time": [ "3 h", "6 h" ] + } + ], + "active_procgen_values": [ { "weight": 100, "spell_id": "AEA_PAIN", "base_power": 50 } ], "passive_add_procgen_values": [ { "weight": 100, "min_value": -1, "max_value": 1, "type": "STRENGTH", "increment": 1, "power_per_increment": 250 }, { @@ -119,7 +152,7 @@ "power_per_increment": 200 } ], - "type_weights": [ { "weight": 100, "value": "passive_enchantment_add" } ], + "type_weights": [ { "weight": 100, "value": "passive_enchantment_add" }, { "weight": 100, "value": "active_enchantment" } ], "items": [ { "weight": 100, "item": "spoon" } ] } ] diff --git a/data/json/bionics.json b/data/json/bionics.json index 33bcb1d8508ac..d14754fe09c07 100644 --- a/data/json/bionics.json +++ b/data/json/bionics.json @@ -268,7 +268,7 @@ "id": "bio_cqb", "type": "bionic", "name": { "str": "Close Quarters Battle" }, - "description": "Bionic processors and databanks, loaded with martial arts combat programs, are surgically integrated into your nervous system. Whilst active, the CQB module will improve your hand to hand combat skills, but prevents you from improving them through combat experience.", + "description": "Bionic processors and databanks, loaded with martial arts combat programs, are surgically integrated into your nervous system. Whilst active, the CQB module will improve your hand-to-hand combat skills, but prevents you from improving them through combat experience.", "occupied_bodyparts": [ [ "head", 4 ] ], "act_cost": "20 J", "react_cost": "20 J", diff --git a/data/json/construction.json b/data/json/construction.json index 98ad90a7e180e..b48fd80dd8304 100644 --- a/data/json/construction.json +++ b/data/json/construction.json @@ -3435,6 +3435,7 @@ "type": "construction", "id": "constr_splitrail_fence", "description": "Build Split Rail Fence", + "//": "Step 1: Build split rail fence", "category": "CONSTRUCT", "required_skills": [ [ "fabrication", 2 ], [ "survival", 1 ] ], "time": "30 m", @@ -3443,10 +3444,24 @@ "pre_flags": "DIGGABLE", "post_terrain": "t_splitrail_fence" }, + { + "type": "construction", + "id": "constr_splitrail_fence_from_posts", + "description": "Build Split Rail Fence", + "//": "Step 2: Build split rail fence from existing fence posts", + "category": "CONSTRUCT", + "required_skills": [ [ "fabrication", 2 ] ], + "time": "15 m", + "qualities": [ [ { "id": "HAMMER", "level": 2 } ] ], + "components": [ [ [ "2x4", 4 ] ], [ [ "nail", 20 ] ] ], + "pre_terrain": "t_fence_post", + "post_terrain": "t_splitrail_fence" + }, { "type": "construction", "id": "constr_privacy_fence", "description": "Build Privacy Fence", + "//": "Step 1: Build privacy fence", "category": "CONSTRUCT", "required_skills": [ [ "fabrication", 2 ], [ "survival", 1 ] ], "time": "30 m", @@ -3455,6 +3470,32 @@ "pre_flags": "DIGGABLE", "post_terrain": "t_privacy_fence" }, + { + "type": "construction", + "id": "constr_privacy_fence_from_posts", + "description": "Build Privacy Fence", + "//": "Step 2: Build privacy fence from existing fence posts", + "category": "CONSTRUCT", + "required_skills": [ [ "fabrication", 2 ] ], + "time": "15 m", + "qualities": [ [ { "id": "HAMMER", "level": 2 } ] ], + "components": [ [ [ "2x4", 8 ] ], [ [ "nail", 20 ] ] ], + "pre_terrain": "t_fence_post", + "post_terrain": "t_privacy_fence" + }, + { + "type": "construction", + "id": "convert_splitrail_to_privacy_fence", + "description": "Build Privacy Fence", + "//": "Convert Split Rail Fence to Privacy Fence", + "category": "CONSTRUCT", + "required_skills": [ [ "fabrication", 2 ] ], + "time": "10 m", + "qualities": [ [ { "id": "HAMMER", "level": 2 } ] ], + "components": [ [ [ "2x4", 4 ] ], [ [ "nail", 10 ] ] ], + "pre_terrain": "t_splitrail_fence", + "post_terrain": "t_privacy_fence" + }, { "type": "construction", "id": "constr_adobe_brick_wall_halfway", diff --git a/data/json/furniture_and_terrain/terrain-doors.json b/data/json/furniture_and_terrain/terrain-doors.json index a593589469adf..a4d7838ad96aa 100644 --- a/data/json/furniture_and_terrain/terrain-doors.json +++ b/data/json/furniture_and_terrain/terrain-doors.json @@ -1803,7 +1803,7 @@ "type": "terrain", "id": "t_door_boarded_damaged", "name": "boarded up damaged door", - "description": "A boarded up wooden door, except some of the planks are fractured or coming loose. Without repairs, it could be broken down easily.", + "description": "A boarded up wooden door, except that some of the planks are fractured or coming loose. Without repairs, it could be broken down easily.", "symbol": "#", "looks_like": "t_door_b", "color": "brown", diff --git a/data/json/itemgroups/Weapons_Mods_Ammo/guns.json b/data/json/itemgroups/Weapons_Mods_Ammo/guns.json index 45455317cd639..2e1878ed4120a 100644 --- a/data/json/itemgroups/Weapons_Mods_Ammo/guns.json +++ b/data/json/itemgroups/Weapons_Mods_Ammo/guns.json @@ -6,9 +6,13 @@ "items": [ { "item": "glock_17", "prob": 35, "charges-min": 0, "charges-max": 15 }, { "item": "glock_19", "prob": 50, "charges-min": 0, "charges-max": 15 }, + { "item": "glock_20", "prob": 4, "charges-min": 0, "charges-max": 15 }, { "item": "glock_22", "prob": 35, "charges-min": 0, "charges-max": 15 }, + { "item": "glock_29", "prob": 2, "charges-min": 0, "charges-max": 10 }, { "item": "glock_31", "prob": 15, "charges-min": 0, "charges-max": 15 }, + { "item": "glock_40", "prob": 2, "charges-min": 0, "charges-max": 15 }, { "item": "m1911", "prob": 50, "charges-min": 0, "charges-max": 7 }, + { "item": "m1911_10", "prob": 15, "charges-min": 0, "charges-max": 7 }, { "item": "m9", "prob": 30, "charges-min": 0, "charges-max": 15 }, { "item": "px4", "prob": 24, "charges-min": 0, "charges-max": 15 }, { "item": "px4_40", "prob": 20, "charges-min": 0, "charges-max": 14 }, @@ -19,6 +23,7 @@ { "item": "sw_619", "prob": 25, "charges-min": 0, "charges-max": 7 }, { "item": "model_10_revolver", "prob": 20, "charges-min": 0, "charges-max": 6 }, { "item": "taurus_spectrum", "prob": 15, "charges-min": 0, "charges-max": 6 }, + { "item": "p220_10", "prob": 1, "charges-min": 0, "charges-max": 8 }, { "item": "p226_357sig", "prob": 20, "charges-min": 0, "charges-max": 15 }, { "item": "p320_357sig", "prob": 10, "charges-min": 0, "charges-max": 14 }, { "item": "kp32", "prob": 10, "charges-min": 0, "charges-max": 7 }, @@ -35,7 +40,9 @@ { "item": "hptcf380", "prob": 2, "charges-min": 0, "charges-max": 10 }, { "item": "hptjcp", "prob": 1, "charges-min": 0, "charges-max": 10 }, { "item": "hptjhp", "prob": 1, "charges-min": 0, "charges-max": 9 }, + { "item": "xd_10", "prob": 3, "charges-min": 0, "charges-max": 15 }, { "item": "cz75", "prob": 18, "charges-min": 0, "charges-max": 26 }, + { "item": "witness_10", "prob": 1, "charges-min": 0, "charges-max": 14 }, { "item": "walther_ccp", "prob": 8, "charges-min": 0, "charges-max": 8 }, { "item": "walther_p22", "prob": 13, "charges-min": 0, "charges-max": 10 } ] @@ -48,8 +55,11 @@ { "item": "glock_17", "prob": 35, "charges-min": 0, "charges-max": 0 }, { "item": "glock_19", "prob": 50, "charges-min": 0, "charges-max": 0 }, { "item": "glock_22", "prob": 35, "charges-min": 0, "charges-max": 0 }, + { "item": "glock_20", "prob": 4, "charges-min": 0, "charges-max": 0 }, + { "item": "glock_40", "prob": 2, "charges-min": 0, "charges-max": 0 }, { "item": "glock_31", "prob": 15, "charges-min": 0, "charges-max": 0 }, { "item": "m1911", "prob": 50, "charges-min": 0, "charges-max": 0 }, + { "item": "m1911_10", "prob": 15, "charges-min": 0, "charges-max": 0 }, { "item": "m9", "prob": 30, "charges-min": 0, "charges-max": 0 }, { "item": "ruger_lcr_38", "prob": 10, "charges-min": 0, "charges-max": 0 }, { "item": "sig_mosquito", "prob": 15, "charges-min": 0, "charges-max": 0 }, @@ -58,6 +68,7 @@ { "item": "sw_619", "prob": 25, "charges-min": 0, "charges-max": 0 }, { "item": "model_10_revolver", "prob": 20, "charges-min": 0, "charges-max": 0 }, { "item": "taurus_spectrum", "prob": 15, "charges-min": 0, "charges-max": 0 }, + { "item": "p220_10", "prob": 1, "charges-min": 0, "charges-max": 0 }, { "item": "p226_357sig", "prob": 20, "charges-min": 0, "charges-max": 0 }, { "item": "p320_357sig", "prob": 10, "charges-min": 0, "charges-max": 0 }, { "item": "kp32", "prob": 10, "charges-min": 0, "charges-max": 0 }, @@ -75,6 +86,8 @@ { "item": "hptjcp", "prob": 1, "charges-min": 0, "charges-max": 0 }, { "item": "hptjhp", "prob": 1, "charges-min": 0, "charges-max": 0 }, { "item": "cz75", "prob": 18, "charges-min": 0, "charges-max": 0 }, + { "item": "xd_10", "prob": 3, "charges-min": 0, "charges-max": 0 }, + { "item": "witness_10", "prob": 1, "charges-min": 0, "charges-max": 0 }, { "item": "walther_ccp", "prob": 8, "charges-min": 0, "charges-max": 0 }, { "item": "walther_p22", "prob": 13, "charges-min": 0, "charges-max": 0 } ] @@ -98,6 +111,7 @@ { "item": "sw629", "prob": 40, "charges-min": 0, "charges-max": 6 }, { "item": "usp_45", "prob": 70, "charges-min": 0, "charges-max": 12 }, { "item": "usp_9mm", "prob": 120, "charges-min": 0, "charges-max": 15 }, + { "item": "TDI_10", "prob": 1, "charges-min": 0, "charges-max": 30 }, { "item": "draco", "prob": 30, "charges-min": 0, "charges-max": 30 } ] }, @@ -118,6 +132,7 @@ { "item": "sw629", "prob": 40, "charges-min": 0, "charges-max": 0 }, { "item": "usp_45", "prob": 70, "charges-min": 0, "charges-max": 0 }, { "item": "usp_9mm", "prob": 120, "charges-min": 0, "charges-max": 0 }, + { "item": "TDI_10", "prob": 1, "charges-min": 0, "charges-max": 0 }, { "item": "draco", "prob": 30, "charges-min": 0, "charges-max": 0 } ] }, @@ -243,6 +258,7 @@ "//": "Imported or otherwise very obscure SMGs.", "items": [ { "item": "ppsh", "prob": 150, "charges-min": 0, "charges-max": 35 }, + { "item": "hk_mp5_10_semi", "prob": 1, "charges-min": 0, "charges-max": 30 }, { "item": "skorpion_61", "prob": 100, "charges-min": 0, "charges-max": 20 }, { "item": "skorpion_82", "prob": 100, "charges-min": 0, "charges-max": 20 } ] diff --git a/data/json/itemgroups/Weapons_Mods_Ammo/magazines.json b/data/json/itemgroups/Weapons_Mods_Ammo/magazines.json index 1b71170921bb3..115f061bd2f58 100644 --- a/data/json/itemgroups/Weapons_Mods_Ammo/magazines.json +++ b/data/json/itemgroups/Weapons_Mods_Ammo/magazines.json @@ -118,12 +118,16 @@ [ "px4_40mag", 6 ], [ "glockmag", 33 ], [ "glock40mag", 7 ], + [ "glock_20mag", 3 ], + [ "glock_29mag", 2 ], [ "m1911mag", 25 ], + [ "m1911_10mag", 2 ], [ "mosquitomag", 10 ], [ "kpf9mag", 5 ], [ "kp3atmag", 4 ], [ "rugerlcpmag", 10 ], [ "sw22mag", 10 ], + [ "p220_10_mag", 1 ], [ "p226mag_15rd_357sig", 25 ], [ "p320mag_14rd_357sig", 10 ], [ "bhp9mag_13rd", 2 ], @@ -141,10 +145,12 @@ [ "hptcf380", 1 ], [ "hptjcp", 1 ], [ "hptjhp", 1 ], + [ "witness_mag_10", 2 ], [ "cz75mag_12rd", 9 ], [ "cz75mag_20rd", 5 ], [ "cz75mag_26rd", 2 ], [ "ccpmag", 4 ], + [ "xd_10_mag", 1 ], [ "wp22mag", 7 ] ] }, @@ -169,7 +175,8 @@ [ "90two40mag", 5 ], [ "deaglemag", 40 ], [ "fn57mag", 80 ], - [ "glockbigmag", 60 ], + [ "cz75mag_26rd", 2 ], + [ "tdi_10mm_mag", 1 ], [ "glock40bigmag", 30 ], [ "m1911bigmag", 40 ], [ "m1911mag_10rd_38super", 10 ], @@ -209,7 +216,15 @@ "type": "item_group", "id": "mags_smg_rare", "//": "Aftermarket or otherwise uncommon SMG magazines excluding milspec.", - "items": [ [ "calicomag", 15 ], [ "fnp90mag", 15 ], [ "mp5bigmag", 10 ], [ "thompson_bigmag", 5 ], [ "thompson_drum", 15 ] ] + "items": [ + [ "calicomag", 19 ], + [ "fnp90mag", 150 ], + [ "tdi_10mm_mag", 65 ], + [ "mp5bigmag", 2 ], + [ "mp5_10_mag", 1 ], + [ "thompson_bigmag", 5 ], + [ "thompson_drum", 98 ] + ] }, { "type": "item_group", diff --git a/data/json/items/armor/ammo_pouch.json b/data/json/items/armor/ammo_pouch.json index f1be0e17c975d..9d47ca4d8d880 100644 --- a/data/json/items/armor/ammo_pouch.json +++ b/data/json/items/armor/ammo_pouch.json @@ -14,7 +14,7 @@ "symbol": "[", "looks_like": "leather_pouch", "color": "brown", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 10, "encumbrance": 5, "material_thickness": 1, @@ -84,7 +84,7 @@ "symbol": "[", "looks_like": "ragpouch", "color": "dark_gray", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 20, "encumbrance": 4, "material_thickness": 2, @@ -113,7 +113,7 @@ "symbol": "[", "looks_like": "ragpouch", "color": "dark_gray", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 15, "material_thickness": 2, "pocket_data": [ @@ -141,7 +141,7 @@ "symbol": "[", "looks_like": "tool_belt", "color": "dark_gray", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 15, "material_thickness": 2, "pocket_data": [ @@ -190,7 +190,7 @@ "symbol": "[", "looks_like": "quiver", "color": "brown", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 30, "encumbrance": 10, "material_thickness": 4, @@ -252,7 +252,8 @@ "symbol": "[", "looks_like": "ragpouch", "color": "dark_gray", - "covers": [ "FOOT_EITHER" ], + "covers": [ "foot_l", "foot_r" ], + "sided": true, "coverage": 5, "encumbrance": 1, "material_thickness": 2, @@ -281,7 +282,8 @@ "symbol": "[", "looks_like": "ammo_satchel", "color": "dark_gray", - "covers": [ "LEG_EITHER" ], + "covers": [ "leg_l", "leg_r" ], + "sided": true, "coverage": 15, "material_thickness": 2, "pocket_data": [ @@ -317,7 +319,8 @@ "symbol": "[", "looks_like": "bscabbard", "color": "brown", - "covers": [ "LEG_EITHER" ], + "covers": [ "leg_l", "leg_r" ], + "sided": true, "coverage": 10, "encumbrance": 3, "material_thickness": 1, @@ -338,7 +341,8 @@ "symbol": "[", "looks_like": "quiver", "color": "light_gray", - "covers": [ "LEG_EITHER" ], + "covers": [ "leg_l", "leg_r" ], + "sided": true, "coverage": 10, "encumbrance": 10, "material_thickness": 1, @@ -359,7 +363,7 @@ "symbol": "[", "looks_like": "quiver", "color": "brown", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 15, "encumbrance": 3, "material_thickness": 1, @@ -380,7 +384,7 @@ "symbol": "[", "looks_like": "quiver_birchbark", "color": "light_gray", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 15, "encumbrance": 14, "material_thickness": 1, @@ -400,7 +404,7 @@ "material": [ "cotton" ], "symbol": "[", "color": "dark_gray", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 20, "encumbrance": 2, "material_thickness": 2, @@ -457,7 +461,7 @@ "material": [ "kevlar_layered" ], "symbol": "[", "color": "light_gray", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 85, "encumbrance": 17, "warmth": 15, diff --git a/data/json/items/armor/arms_armor.json b/data/json/items/armor/arms_armor.json index a368b61b4cdb9..dfa21d66976c9 100644 --- a/data/json/items/armor/arms_armor.json +++ b/data/json/items/armor/arms_armor.json @@ -15,7 +15,7 @@ "symbol": "[", "looks_like": "arm_splint", "color": "brown", - "covers": [ "ARMS" ], + "covers": [ "arm_l", "arm_r" ], "coverage": 75, "encumbrance": 25, "warmth": 5, @@ -38,7 +38,7 @@ "symbol": "[", "looks_like": "armguard_hard", "color": "green", - "covers": [ "ARMS" ], + "covers": [ "arm_l", "arm_r" ], "coverage": 90, "encumbrance": 10, "warmth": 10, @@ -72,7 +72,7 @@ "material": [ "plastic", "neoprene" ], "symbol": "[", "color": "dark_gray", - "covers": [ "ARMS" ], + "covers": [ "arm_l", "arm_r" ], "coverage": 80, "encumbrance": 5, "warmth": 20, @@ -95,7 +95,7 @@ "symbol": "[", "looks_like": "arm_warmers", "color": "brown", - "covers": [ "ARMS" ], + "covers": [ "arm_l", "arm_r" ], "coverage": 90, "encumbrance": 10, "warmth": 25, @@ -118,7 +118,7 @@ "symbol": "[", "looks_like": "armguard_metal", "color": "light_gray", - "covers": [ "ARMS" ], + "covers": [ "arm_l", "arm_r" ], "coverage": 95, "encumbrance": 20, "warmth": 20, @@ -140,7 +140,7 @@ "symbol": "[", "looks_like": "armguard_hard", "color": "light_gray", - "covers": [ "ARMS" ], + "covers": [ "arm_l", "arm_r" ], "coverage": 80, "encumbrance": 15, "material_thickness": 3, @@ -162,7 +162,7 @@ "symbol": "[", "looks_like": "armguard_larmor", "color": "blue", - "covers": [ "ARMS" ], + "covers": [ "arm_l", "arm_r" ], "coverage": 80, "encumbrance": 10, "warmth": 5, @@ -186,7 +186,7 @@ "symbol": "[", "looks_like": "armguard_metal", "color": "light_gray", - "covers": [ "ARMS" ], + "covers": [ "arm_l", "arm_r" ], "coverage": 80, "encumbrance": 18, "warmth": 20, @@ -208,7 +208,7 @@ "symbol": "[", "looks_like": "arm_warmers", "color": "light_red", - "covers": [ "ARMS" ], + "covers": [ "arm_l", "arm_r" ], "coverage": 70, "encumbrance": 5, "warmth": 20, @@ -231,7 +231,7 @@ "symbol": "[", "looks_like": "armguard_metal", "color": "light_red", - "covers": [ "ARMS" ], + "covers": [ "arm_l", "arm_r" ], "coverage": 95, "encumbrance": 20, "material_thickness": 4, @@ -252,7 +252,7 @@ "symbol": "[", "looks_like": "armguard_hard", "color": "dark_gray", - "covers": [ "ARMS" ], + "covers": [ "arm_l", "arm_r" ], "coverage": 30, "material_thickness": 5, "flags": [ "WATER_FRIENDLY", "BELTED" ] @@ -272,7 +272,7 @@ "symbol": "[", "looks_like": "armguard_larmor", "color": "brown", - "covers": [ "ARMS" ], + "covers": [ "arm_l", "arm_r" ], "coverage": 50, "encumbrance": 8, "warmth": 10, diff --git a/data/json/items/armor/ballistic_armor.json b/data/json/items/armor/ballistic_armor.json index 0137802d2b6fe..6903474bca130 100644 --- a/data/json/items/armor/ballistic_armor.json +++ b/data/json/items/armor/ballistic_armor.json @@ -14,7 +14,7 @@ "symbol": "[", "looks_like": "modularvest", "color": "light_gray", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 85, "encumbrance": 6, "warmth": 15, @@ -35,7 +35,7 @@ "symbol": "[", "looks_like": "modularvestceramic", "color": "light_gray", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 85, "encumbrance": 10, "warmth": 15, @@ -58,7 +58,7 @@ "symbol": "[", "looks_like": "kevlar", "color": "light_red", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 95, "encumbrance": 8, "warmth": 12, @@ -83,7 +83,7 @@ "symbol": "[", "looks_like": "dragonskin", "color": "light_red", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 25, "encumbrance": 6, "warmth": 10, diff --git a/data/json/items/armor/bandolier.json b/data/json/items/armor/bandolier.json index 98bb2f86fafa3..b5f45187dc50b 100644 --- a/data/json/items/armor/bandolier.json +++ b/data/json/items/armor/bandolier.json @@ -12,7 +12,7 @@ "symbol": "[", "looks_like": "leather_belt", "color": "dark_gray", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 10, "encumbrance": 1, "material_thickness": 1, @@ -57,7 +57,7 @@ "symbol": "[", "looks_like": "leather_belt", "color": "dark_gray", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 10, "encumbrance": 1, "material_thickness": 1, @@ -98,7 +98,7 @@ "symbol": "[", "looks_like": "leather_belt", "color": "dark_gray", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 10, "encumbrance": 2, "material_thickness": 1, @@ -118,7 +118,7 @@ "symbol": "[", "looks_like": "leather_belt", "color": "dark_gray", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 12, "encumbrance": 3, "material_thickness": 1, @@ -138,7 +138,7 @@ "symbol": "[", "looks_like": "ammo_pouch", "color": "dark_gray", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 10, "encumbrance": 2, "material_thickness": 1, @@ -163,7 +163,8 @@ "symbol": "[", "looks_like": "leather_belt", "color": "dark_gray", - "covers": [ "HAND_EITHER" ], + "covers": [ "hand_l", "hand_r" ], + "sided": true, "coverage": 5, "encumbrance": 1, "material_thickness": 1, @@ -204,7 +205,8 @@ "symbol": "[", "looks_like": "ammo_satchel", "color": "dark_gray", - "covers": [ "LEG_EITHER" ], + "covers": [ "leg_l", "leg_r" ], + "sided": true, "coverage": 10, "encumbrance": 4, "material_thickness": 1, @@ -224,7 +226,8 @@ "symbol": "[", "looks_like": "ammo_satchel", "color": "dark_gray", - "covers": [ "LEG_EITHER" ], + "covers": [ "leg_l", "leg_r" ], + "sided": true, "coverage": 10, "encumbrance": 4, "material_thickness": 1, @@ -244,7 +247,7 @@ "symbol": "[", "looks_like": "leather_belt", "color": "dark_gray", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 15, "material_thickness": 2, "pocket_data": [ diff --git a/data/json/items/armor/belts.json b/data/json/items/armor/belts.json index 8c644d0ad7604..009d0bc4a8a07 100644 --- a/data/json/items/armor/belts.json +++ b/data/json/items/armor/belts.json @@ -13,7 +13,7 @@ "symbol": "[", "looks_like": "holster", "color": "yellow", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 5, "encumbrance": 4, "pocket_data": [ @@ -41,7 +41,7 @@ "to_hit": -1, "material": [ "cotton" ], "symbol": "[", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 5, "encumbrance": 2, "material_thickness": 5, @@ -116,7 +116,7 @@ "material": [ "leather" ], "symbol": "[", "color": "brown", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 5, "material_thickness": 1, "pocket_data": [ @@ -160,7 +160,7 @@ "symbol": "[", "looks_like": "fireman_belt", "color": "brown", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "encumbrance": 6, "pocket_data": [ { @@ -188,7 +188,7 @@ "symbol": "[", "looks_like": "holster", "color": "brown", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 15, "encumbrance": 4, "material_thickness": 2, @@ -220,7 +220,7 @@ "symbol": "[", "looks_like": "holster", "color": "brown", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 20, "encumbrance": 2, "material_thickness": 2, @@ -288,7 +288,7 @@ "symbol": "[", "looks_like": "leather_belt", "color": "yellow", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "flags": [ "WAIST", "WATER_FRIENDLY" ] } ] diff --git a/data/json/items/armor/boots.json b/data/json/items/armor/boots.json index 7697bc7e892bb..0ea7fa521f8fb 100644 --- a/data/json/items/armor/boots.json +++ b/data/json/items/armor/boots.json @@ -13,7 +13,7 @@ "symbol": "[", "looks_like": "flip_flops", "color": "brown", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 40, "encumbrance": 10, "material_thickness": 2, @@ -34,7 +34,7 @@ "symbol": "[", "looks_like": "dress_shoes", "color": "dark_gray", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 90, "encumbrance": 12, "warmth": 20, @@ -57,7 +57,7 @@ "symbol": "[", "looks_like": "boots", "color": "dark_gray", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "encumbrance": 16, "flags": [ "VARSIZE", "WATERPROOF" ] }, @@ -77,7 +77,7 @@ "symbol": "[", "looks_like": "boots_steel", "color": "dark_gray", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 100, "encumbrance": 40, "warmth": 35, @@ -101,7 +101,7 @@ "symbol": "[", "looks_like": "boots_bone", "color": "green", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 95, "encumbrance": 14, "warmth": 10, @@ -137,7 +137,7 @@ "symbol": "[", "looks_like": "boots", "color": "dark_gray", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 100, "encumbrance": 25, "warmth": 25, @@ -154,7 +154,7 @@ "weight": "1220 g", "volume": "3 L", "price": 50000, - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 100, "encumbrance": 40, "warmth": 10, @@ -178,7 +178,7 @@ "material": [ "plastic", "steel" ], "symbol": "[", "color": "brown", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 15, "encumbrance": 10, "warmth": 10, @@ -202,7 +202,7 @@ "symbol": "[", "looks_like": "boots_combat", "color": "light_gray", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 100, "encumbrance": 35, "warmth": 15, @@ -225,7 +225,7 @@ "symbol": "[", "looks_like": "boots", "color": "brown", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 90, "encumbrance": 20, "warmth": 60, @@ -249,7 +249,7 @@ "symbol": "[", "looks_like": "boots_bunker", "color": "dark_gray", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 100, "encumbrance": 32, "warmth": 15, @@ -273,7 +273,7 @@ "symbol": "[", "looks_like": "boots", "color": "brown", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 95, "encumbrance": 12, "warmth": 30, @@ -297,7 +297,7 @@ "symbol": "[", "looks_like": "boots_combat", "color": "dark_gray", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 100, "encumbrance": 35, "warmth": 15, @@ -321,7 +321,7 @@ "symbol": "[", "looks_like": "boots", "color": "brown", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 95, "encumbrance": 18, "warmth": 25, @@ -345,7 +345,7 @@ "symbol": "[", "looks_like": "boots_combat", "color": "green", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 100, "encumbrance": 18, "warmth": 15, @@ -369,7 +369,7 @@ "symbol": "[", "looks_like": "boots_steel", "color": "light_gray", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 100, "encumbrance": 28, "warmth": 20, @@ -392,7 +392,7 @@ "symbol": "[", "looks_like": "boots", "color": "dark_gray", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 100, "encumbrance": 30, "warmth": 10, @@ -416,7 +416,7 @@ "symbol": "[", "looks_like": "boots_steel", "color": "light_gray", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 80, "encumbrance": 20, "warmth": 20, @@ -440,7 +440,7 @@ "symbol": "[", "looks_like": "boots_combat", "color": "brown", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 90, "encumbrance": 20, "warmth": 30, @@ -464,7 +464,7 @@ "symbol": "[", "looks_like": "boots_combat", "color": "brown", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 100, "encumbrance": 24, "warmth": 15, @@ -502,7 +502,7 @@ "symbol": "[", "looks_like": "boots_larmor", "color": "light_gray", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 90, "encumbrance": 25, "warmth": 80, @@ -526,7 +526,7 @@ "symbol": "[", "looks_like": "boots_fur", "color": "light_gray", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 100, "encumbrance": 38, "warmth": 75, @@ -550,7 +550,7 @@ "symbol": "[", "looks_like": "boots_combat", "color": "brown", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 100, "encumbrance": 38, "warmth": 15, @@ -573,7 +573,7 @@ "symbol": "[", "looks_like": "sneakers", "color": "light_gray", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 80, "encumbrance": 15, "warmth": 20, @@ -595,7 +595,7 @@ "symbol": "[", "looks_like": "dress_shoes", "color": "light_gray", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 70, "encumbrance": 12, "warmth": 15, @@ -617,7 +617,7 @@ "symbol": "[", "looks_like": "leathersandals", "color": "yellow", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 85, "encumbrance": 20, "warmth": 5, @@ -641,7 +641,7 @@ "symbol": "[", "looks_like": "sneakers", "color": "light_red", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 85, "encumbrance": 60, "warmth": 20, @@ -664,7 +664,7 @@ "symbol": "[", "looks_like": "dress_shoes", "color": "dark_gray", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 60, "encumbrance": 5, "warmth": 10, @@ -687,7 +687,7 @@ "symbol": "[", "looks_like": "sneakers", "color": "dark_gray", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 60, "encumbrance": 15, "warmth": 10, @@ -708,7 +708,7 @@ "symbol": "[", "looks_like": "sneakers", "color": "blue", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 10, "encumbrance": 35, "material_thickness": 1, @@ -729,7 +729,7 @@ "symbol": "[", "looks_like": "flip_flops", "color": "brown", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 12, "encumbrance": 30, "material_thickness": 1, @@ -749,7 +749,7 @@ "symbol": "[", "looks_like": "socks", "color": "brown", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 65, "encumbrance": 2, "warmth": 5, @@ -769,7 +769,7 @@ "symbol": "[", "looks_like": "socks_wool", "color": "brown", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 65, "encumbrance": 5, "warmth": 20, @@ -789,7 +789,7 @@ "symbol": "[", "looks_like": "socks", "color": "brown", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 65, "encumbrance": 5, "warmth": 10, @@ -809,7 +809,7 @@ "symbol": "[", "looks_like": "socks_wool", "color": "blue", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 65, "encumbrance": 5, "warmth": 15, @@ -831,7 +831,7 @@ "symbol": "[", "looks_like": "clogs", "color": "yellow", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 50, "encumbrance": 10, "warmth": 5, @@ -855,7 +855,7 @@ "symbol": "[", "looks_like": "dress_shoes", "color": "dark_gray", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 30, "encumbrance": 50, "material_thickness": 1, @@ -877,7 +877,7 @@ "symbol": "[", "looks_like": "boots_larmor", "color": "dark_gray", - "covers": [ "FEET", "LEGS" ], + "covers": [ "foot_l", "foot_r", "leg_r", "leg_l" ], "coverage": 65, "encumbrance": 20, "warmth": 20, @@ -899,7 +899,7 @@ "symbol": "[", "looks_like": "flip_flops", "color": "brown", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 20, "encumbrance": 5, "material_thickness": 1, @@ -920,7 +920,7 @@ "symbol": "[", "looks_like": "sneakers", "color": "dark_gray", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 80, "warmth": 5, "material_thickness": 1, @@ -939,7 +939,7 @@ "symbol": "[", "looks_like": "leathersandals", "color": "brown", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 50, "encumbrance": 2, "warmth": 20, @@ -961,7 +961,7 @@ "symbol": "[", "looks_like": "boots_steel", "color": "dark_gray", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 95, "encumbrance": 30, "warmth": 35, @@ -984,7 +984,7 @@ "symbol": "[", "looks_like": "rollerskates", "color": "light_gray", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 100, "encumbrance": 25, "warmth": 20, @@ -1008,7 +1008,7 @@ "symbol": "[", "looks_like": "roller_blades", "color": "brown", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 100, "encumbrance": 25, "warmth": 30, @@ -1029,7 +1029,7 @@ "symbol": "[", "looks_like": "clogs", "color": "light_gray", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 50, "encumbrance": 15, "warmth": 10, @@ -1050,7 +1050,7 @@ "symbol": "[", "looks_like": "dress_shoes", "color": "light_blue", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 80, "encumbrance": 10, "warmth": 20, @@ -1072,7 +1072,7 @@ "symbol": "[", "looks_like": "socks_wool", "color": "brown", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 30, "encumbrance": 30, "warmth": 25, @@ -1093,7 +1093,7 @@ "symbol": "[", "looks_like": "shoes_bowling", "color": "light_blue", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 80, "encumbrance": 4, "warmth": 20, @@ -1114,7 +1114,7 @@ "symbol": "[", "looks_like": "leathersandals", "color": "light_gray", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 30, "encumbrance": 14, "material_thickness": 2, @@ -1133,7 +1133,7 @@ "symbol": "[", "looks_like": "clownshoes", "color": "dark_gray", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 85, "encumbrance": 25, "warmth": 5, @@ -1156,7 +1156,7 @@ "symbol": "[", "looks_like": "boots_larmor", "color": "dark_gray", - "covers": [ "FEET", "LEGS" ], + "covers": [ "foot_l", "foot_r", "leg_r", "leg_l" ], "coverage": 80, "encumbrance": 25, "warmth": 20, @@ -1177,7 +1177,7 @@ "symbol": "[", "looks_like": "boots_rubber", "color": "dark_gray", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 100, "encumbrance": 15, "warmth": 30, @@ -1199,7 +1199,7 @@ "symbol": "[", "looks_like": "sneakers", "color": "light_blue", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 80, "encumbrance": 4, "warmth": 20, @@ -1220,7 +1220,7 @@ "symbol": "[", "looks_like": "sneakers", "color": "light_blue", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 80, "encumbrance": 4, "warmth": 20, @@ -1242,7 +1242,7 @@ "material": [ "iron", "cotton" ], "symbol": "[", "color": "light_red", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 100, "encumbrance": 20, "material_thickness": 4, @@ -1261,7 +1261,7 @@ "symbol": "[", "looks_like": "leg_warmers_xl", "color": "light_gray", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 60, "encumbrance": 7, "warmth": 40, @@ -1282,7 +1282,7 @@ "symbol": "[", "looks_like": "socks", "color": "light_gray", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 100, "encumbrance": 6, "warmth": 5, @@ -1313,7 +1313,7 @@ "symbol": "[", "looks_like": "socks_wool", "color": "white", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 100, "warmth": 5, "material_thickness": 1, @@ -1342,7 +1342,7 @@ "symbol": "[", "looks_like": "socks", "color": "light_gray", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 80, "material_thickness": 1, "flags": [ "VARSIZE", "SKINTIGHT" ] @@ -1360,7 +1360,7 @@ "symbol": "[", "looks_like": "socks", "color": "light_blue", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 70, "encumbrance": 3, "material_thickness": 1, @@ -1380,7 +1380,7 @@ "symbol": "[", "looks_like": "socks", "color": "white", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 80, "warmth": 2, "flags": [ "SKINTIGHT" ] @@ -1398,7 +1398,7 @@ "symbol": "[", "looks_like": "socks", "color": "blue", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 100, "encumbrance": 5, "warmth": 30, @@ -1428,7 +1428,7 @@ "symbol": "[", "looks_like": "leg_warmers", "color": "dark_gray", - "covers": [ "FEET", "LEGS" ], + "covers": [ "foot_l", "foot_r", "leg_r", "leg_l" ], "coverage": 75, "encumbrance": 5, "warmth": 10, @@ -1448,7 +1448,7 @@ "symbol": "[", "looks_like": "leg_warmers", "color": "dark_gray", - "covers": [ "FEET", "LEGS" ], + "covers": [ "foot_l", "foot_r", "leg_r", "leg_l" ], "coverage": 75, "encumbrance": 10, "warmth": 10, @@ -1468,7 +1468,7 @@ "symbol": "[", "looks_like": "socks", "color": "dark_gray", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 100, "warmth": 5, "material_thickness": 1, @@ -1488,7 +1488,7 @@ "symbol": "[", "looks_like": "socks", "color": "white", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 100, "warmth": 5, "material_thickness": 1, diff --git a/data/json/items/armor/cloaks.json b/data/json/items/armor/cloaks.json index 55527483c44a1..f2abbf7edc2c9 100644 --- a/data/json/items/armor/cloaks.json +++ b/data/json/items/armor/cloaks.json @@ -14,7 +14,7 @@ "symbol": "[", "looks_like": "towel", "color": "light_red", - "covers": [ "TORSO", "ARMS", "HANDS", "LEGS", "FEET" ], + "covers": [ "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ], "coverage": 60, "encumbrance": 50, "warmth": 20, @@ -37,7 +37,7 @@ "symbol": "]", "looks_like": "cloak", "color": "pink", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 50, "encumbrance": 4, "warmth": 10, @@ -58,7 +58,7 @@ "symbol": "[", "looks_like": "coat_rain", "color": "green", - "covers": [ "TORSO", "ARMS", "LEGS" ], + "covers": [ "torso", "arm_l", "arm_r", "leg_l", "leg_r" ], "coverage": 65, "encumbrance": 4, "warmth": 30, @@ -80,7 +80,7 @@ "symbol": "[", "looks_like": "cloak_leather", "color": "brown", - "covers": [ "TORSO", "ARMS", "LEGS" ], + "covers": [ "torso", "arm_l", "arm_r", "leg_l", "leg_r" ], "coverage": 65, "encumbrance": 6, "warmth": 60, @@ -102,7 +102,7 @@ "symbol": "[", "looks_like": "cloak", "color": "dark_gray", - "covers": [ "TORSO", "ARMS", "LEGS" ], + "covers": [ "torso", "arm_l", "arm_r", "leg_l", "leg_r" ], "coverage": 65, "encumbrance": 6, "warmth": 40, @@ -124,7 +124,7 @@ "symbol": "[", "looks_like": "cloak", "color": "blue", - "covers": [ "TORSO", "ARMS", "LEGS" ], + "covers": [ "torso", "arm_l", "arm_r", "leg_l", "leg_r" ], "coverage": 65, "encumbrance": 5, "warmth": 50, @@ -147,7 +147,7 @@ "symbol": "[", "looks_like": "robe", "color": "brown", - "covers": [ "TORSO", "HEAD", "ARMS", "HANDS", "LEGS" ], + "covers": [ "leg_r", "leg_l", "torso", "arm_l", "arm_r", "head", "hand_l", "hand_r" ], "coverage": 65, "encumbrance": 3, "warmth": 50, @@ -169,7 +169,7 @@ "symbol": "[", "looks_like": "cloak", "color": "light_gray", - "covers": [ "TORSO", "ARMS", "LEGS" ], + "covers": [ "torso", "arm_l", "arm_r", "leg_l", "leg_r" ], "coverage": 65, "encumbrance": 50, "warmth": 10, @@ -203,7 +203,7 @@ "msg": "The %s flickers for a moment as it becomes opaque.", "target": "optical_cloak" }, - "covers": [ "TORSO", "ARMS", "LEGS" ] + "covers": [ "torso", "arm_l", "arm_r", "leg_l", "leg_r" ] }, { "id": "poncho", @@ -219,7 +219,7 @@ "symbol": "[", "looks_like": "cloak", "color": "light_gray", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 85, "encumbrance": 5, "warmth": 35, @@ -241,7 +241,7 @@ "symbol": "[", "looks_like": "blanket", "color": "light_red", - "covers": [ "TORSO", "ARMS", "LEGS" ], + "covers": [ "torso", "arm_l", "arm_r", "leg_l", "leg_r" ], "coverage": 85, "encumbrance": 20, "warmth": 50, diff --git a/data/json/items/armor/coats.json b/data/json/items/armor/coats.json index 21dc9c7d5d3e0..c27a648b1f921 100644 --- a/data/json/items/armor/coats.json +++ b/data/json/items/armor/coats.json @@ -15,7 +15,7 @@ "symbol": "[", "looks_like": "coat_winter", "color": "yellow", - "covers": [ "TORSO", "ARMS" ], + "covers": [ "torso", "arm_l", "arm_r" ], "coverage": 100, "encumbrance": 22, "max_encumbrance": 30, @@ -45,7 +45,7 @@ "symbol": "[", "looks_like": "robe", "color": "dark_gray", - "covers": [ "LEGS", "TORSO", "ARMS" ], + "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r" ], "coverage": 90, "encumbrance": 10, "warmth": 20, @@ -66,7 +66,7 @@ "symbol": "[", "looks_like": "coat_winter", "color": "brown", - "covers": [ "TORSO", "ARMS" ], + "covers": [ "torso", "arm_l", "arm_r" ], "coverage": 95, "encumbrance": 26, "max_encumbrance": 30, @@ -89,7 +89,7 @@ "description": "A garishly-colored faux fur coat with a couple small pockets. Although not as warm as the natural fur, it gives you some of that unique flair.", "material": [ "faux_fur", "cotton" ], "color": "pink", - "covers": [ "TORSO", "ARMS" ], + "covers": [ "torso", "arm_l", "arm_r" ], "flags": [ "VARSIZE", "POCKETS", "OUTER", "SUPER_FANCY" ], "warmth": 70 }, @@ -108,7 +108,7 @@ "symbol": "[", "looks_like": "coat_fur", "color": "brown", - "covers": [ "TORSO", "ARMS" ], + "covers": [ "torso", "arm_l", "arm_r" ], "coverage": 95, "encumbrance": 30, "max_encumbrance": 35, @@ -137,7 +137,7 @@ "symbol": "[", "looks_like": "coat_winter", "color": "white", - "covers": [ "TORSO", "ARMS" ], + "covers": [ "torso", "arm_l", "arm_r" ], "coverage": 90, "encumbrance": 2, "max_encumbrance": 5, @@ -163,7 +163,7 @@ "symbol": "[", "looks_like": "coat_winter", "color": "yellow", - "covers": [ "TORSO", "ARMS" ], + "covers": [ "torso", "arm_l", "arm_r" ], "coverage": 95, "encumbrance": 7, "max_encumbrance": 15, @@ -189,7 +189,7 @@ "symbol": "[", "looks_like": "coat_rain", "color": "light_gray", - "covers": [ "TORSO", "ARMS" ], + "covers": [ "torso", "arm_l", "arm_r" ], "coverage": 95, "encumbrance": 12, "warmth": 10, @@ -212,7 +212,7 @@ "symbol": "[", "looks_like": "coat_rain", "color": "light_red", - "covers": [ "TORSO", "ARMS" ], + "covers": [ "torso", "arm_l", "arm_r" ], "coverage": 95, "encumbrance": 18, "max_encumbrance": 30, @@ -242,7 +242,7 @@ "symbol": "[", "looks_like": "trenchcoat", "color": "dark_gray", - "covers": [ "TORSO", "ARMS", "LEGS" ], + "covers": [ "torso", "arm_l", "arm_r", "leg_l", "leg_r" ], "coverage": 90, "encumbrance": 7, "max_encumbrance": 15, @@ -273,7 +273,7 @@ "symbol": "[", "looks_like": "duster_leather", "color": "brown", - "covers": [ "TORSO", "ARMS", "LEGS" ], + "covers": [ "torso", "arm_l", "arm_r", "leg_l", "leg_r" ], "coverage": 90, "encumbrance": 9, "max_encumbrance": 19, @@ -299,7 +299,7 @@ "name": { "str": "faux fur duster" }, "description": "A thick faux fur duster, falling below your knees. Has many pockets for storing things.", "material": [ "faux_fur", "cotton" ], - "covers": [ "TORSO", "ARMS", "LEGS" ], + "covers": [ "torso", "arm_l", "arm_r", "leg_l", "leg_r" ], "flags": [ "VARSIZE", "POCKETS", "OUTER", "FANCY" ], "warmth": 40 }, @@ -317,7 +317,7 @@ "symbol": "[", "looks_like": "duster", "color": "brown", - "covers": [ "TORSO", "ARMS", "LEGS" ], + "covers": [ "torso", "arm_l", "arm_r", "leg_l", "leg_r" ], "coverage": 90, "encumbrance": 8, "max_encumbrance": 17, @@ -350,7 +350,7 @@ "symbol": "[", "looks_like": "duster_leather", "color": "brown", - "covers": [ "TORSO", "ARMS", "LEGS" ], + "covers": [ "torso", "arm_l", "arm_r", "leg_l", "leg_r" ], "coverage": 85, "encumbrance": 7, "max_encumbrance": 15, @@ -382,7 +382,7 @@ "symbol": "[", "looks_like": "coat_winter", "color": "blue", - "covers": [ "TORSO", "ARMS", "LEGS" ], + "covers": [ "torso", "arm_l", "arm_r", "leg_l", "leg_r" ], "coverage": 95, "encumbrance": 11, "max_encumbrance": 23, @@ -412,7 +412,7 @@ "symbol": "[", "looks_like": "skirt", "color": "dark_gray", - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "coverage": 100, "encumbrance": 6, "warmth": 10, @@ -432,7 +432,7 @@ "symbol": "[", "looks_like": "skirt", "color": "blue", - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "coverage": 100, "encumbrance": 10, "warmth": 15, @@ -453,7 +453,7 @@ "symbol": "[", "looks_like": "coat_lab", "color": "blue", - "covers": [ "TORSO", "ARMS", "LEGS" ], + "covers": [ "torso", "arm_l", "arm_r", "leg_l", "leg_r" ], "coverage": 85, "encumbrance": 5, "max_encumbrance": 10, @@ -480,7 +480,7 @@ "symbol": "[", "looks_like": "coat_winter", "color": "green", - "covers": [ "TORSO", "ARMS" ], + "covers": [ "torso", "arm_l", "arm_r" ], "coverage": 95, "encumbrance": 7, "max_encumbrance": 15, @@ -511,7 +511,7 @@ "symbol": "[", "looks_like": "coat_lab", "color": "white", - "covers": [ "TORSO", "ARMS" ], + "covers": [ "torso", "arm_l", "arm_r" ], "coverage": 95, "encumbrance": 8, "max_encumbrance": 13, @@ -534,7 +534,7 @@ "symbol": "[", "looks_like": "jacket_leather", "color": "cyan", - "covers": [ "TORSO", "ARMS" ], + "covers": [ "torso", "arm_l", "arm_r" ], "coverage": 90, "encumbrance": 13, "max_encumbrance": 15, @@ -560,7 +560,7 @@ "symbol": "[", "looks_like": "coat_winter", "color": "light_red", - "covers": [ "TORSO", "ARMS" ], + "covers": [ "torso", "arm_l", "arm_r" ], "coverage": 90, "encumbrance": 9, "max_encumbrance": 13, @@ -586,7 +586,7 @@ "symbol": "[", "looks_like": "jacket_windbreaker", "color": "light_blue", - "covers": [ "TORSO", "ARMS" ], + "covers": [ "torso", "arm_l", "arm_r" ], "coverage": 90, "encumbrance": 9, "max_encumbrance": 11, @@ -618,7 +618,7 @@ "symbol": "[", "looks_like": "jacket_windbreaker", "color": "dark_gray", - "covers": [ "TORSO", "ARMS" ], + "covers": [ "torso", "arm_l", "arm_r" ], "coverage": 90, "encumbrance": 10, "max_encumbrance": 15, @@ -646,7 +646,7 @@ "symbol": "[", "looks_like": "jacket_leather", "color": "red", - "covers": [ "TORSO", "ARMS" ], + "covers": [ "torso", "arm_l", "arm_r" ], "coverage": 90, "encumbrance": 15, "max_encumbrance": 20, @@ -674,7 +674,7 @@ "symbol": "[", "looks_like": "jacket_windbreaker", "color": "blue", - "covers": [ "TORSO", "ARMS" ], + "covers": [ "torso", "arm_l", "arm_r" ], "coverage": 90, "encumbrance": 4, "max_encumbrance": 8, @@ -700,7 +700,7 @@ "symbol": "[", "looks_like": "jacket_light", "color": "cyan", - "covers": [ "TORSO", "ARMS" ], + "covers": [ "torso", "arm_l", "arm_r" ], "coverage": 90, "encumbrance": 6, "max_encumbrance": 12, @@ -728,7 +728,7 @@ "symbol": "[", "looks_like": "robe", "color": "white", - "covers": [ "ARMS", "LEGS", "TORSO" ], + "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r" ], "coverage": 95, "encumbrance": 10, "warmth": 10, @@ -749,7 +749,7 @@ "symbol": "[", "looks_like": "judo_gi", "color": "white", - "covers": [ "ARMS", "LEGS", "TORSO" ], + "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r" ], "coverage": 80, "warmth": 5, "material_thickness": 2, @@ -770,7 +770,7 @@ "symbol": "[", "looks_like": "robe", "color": "white", - "covers": [ "LEGS", "TORSO", "ARMS" ], + "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r" ], "coverage": 100, "encumbrance": 17, "warmth": 23, @@ -791,7 +791,7 @@ "symbol": "[", "looks_like": "judo_gi", "color": "white", - "covers": [ "ARMS", "TORSO" ], + "covers": [ "torso", "arm_l", "arm_r" ], "coverage": 80, "warmth": 5, "material_thickness": 2, @@ -811,7 +811,7 @@ "symbol": "[", "looks_like": "robe", "color": "white", - "covers": [ "LEGS", "TORSO", "ARMS" ], + "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r" ], "coverage": 90, "encumbrance": 2, "max_encumbrance": 5, @@ -837,7 +837,7 @@ "symbol": "[", "looks_like": "kimono", "color": "blue", - "covers": [ "LEGS", "TORSO", "ARMS" ], + "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r" ], "coverage": 80, "encumbrance": 1, "max_encumbrance": 3, @@ -863,7 +863,7 @@ "symbol": "[", "looks_like": "house_coat", "color": "black", - "covers": [ "TORSO", "ARMS" ], + "covers": [ "torso", "arm_l", "arm_r" ], "coverage": 60, "encumbrance": 3, "warmth": 10, @@ -885,7 +885,7 @@ "symbol": "[", "looks_like": "robe", "color": "white", - "covers": [ "LEGS", "TORSO", "ARMS" ], + "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r" ], "coverage": 80, "encumbrance": 10, "warmth": 17, @@ -906,7 +906,7 @@ "symbol": "[", "looks_like": "coat_winter", "color": "blue", - "covers": [ "TORSO", "ARMS" ], + "covers": [ "torso", "arm_l", "arm_r" ], "coverage": 85, "encumbrance": 10, "max_encumbrance": 20, @@ -936,7 +936,7 @@ "symbol": "[", "looks_like": "cloak", "color": "brown", - "covers": [ "LEGS", "TORSO", "ARMS" ], + "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r" ], "coverage": 80, "encumbrance": 8, "max_encumbrance": 17, @@ -966,7 +966,7 @@ "symbol": "[", "looks_like": "coat_winter", "color": "light_blue", - "covers": [ "TORSO", "ARMS" ], + "covers": [ "torso", "arm_l", "arm_r" ], "coverage": 95, "encumbrance": 15, "max_encumbrance": 22, @@ -997,7 +997,7 @@ "symbol": "[", "looks_like": "duster", "color": "dark_gray", - "covers": [ "TORSO", "LEGS" ], + "covers": [ "torso", "leg_l", "leg_r" ], "coverage": 90, "encumbrance": 7, "max_encumbrance": 15, @@ -1029,7 +1029,7 @@ "symbol": "[", "looks_like": "duster_fur", "color": "brown", - "covers": [ "TORSO", "LEGS" ], + "covers": [ "torso", "leg_l", "leg_r" ], "coverage": 90, "encumbrance": 9, "max_encumbrance": 19, @@ -1054,7 +1054,7 @@ "name": { "str": "sleeveless faux fur duster" }, "description": "A thick, sleeveless faux fur duster, falling below your knees. Has many pockets for storing things.", "material": [ "faux_fur", "cotton" ], - "covers": [ "TORSO", "LEGS" ], + "covers": [ "torso", "leg_l", "leg_r" ], "flags": [ "VARSIZE", "POCKETS", "OUTER", "FANCY" ], "warmth": 40 }, @@ -1073,7 +1073,7 @@ "symbol": "[", "looks_like": "duster_leather", "color": "brown", - "covers": [ "TORSO", "LEGS" ], + "covers": [ "torso", "leg_l", "leg_r" ], "coverage": 90, "encumbrance": 8, "max_encumbrance": 17, @@ -1107,7 +1107,7 @@ "symbol": "[", "looks_like": "duster_survivor", "color": "brown", - "covers": [ "TORSO", "LEGS" ], + "covers": [ "torso", "leg_l", "leg_r" ], "coverage": 85, "encumbrance": 7, "max_encumbrance": 15, @@ -1140,7 +1140,7 @@ "symbol": "[", "looks_like": "sleeveless_duster", "color": "dark_gray", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 90, "encumbrance": 7, "max_encumbrance": 15, @@ -1172,7 +1172,7 @@ "symbol": "[", "looks_like": "sleeveless_duster_fur", "color": "brown", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 90, "encumbrance": 9, "max_encumbrance": 19, @@ -1197,7 +1197,7 @@ "name": { "str": "sleeveless faux fur trenchcoat" }, "description": "A thick faux fur trenchcoat without sleeves. Has plenty of storage space, and looks pretty good.", "material": [ "faux_fur", "cotton" ], - "covers": [ "TORSO" ], + "covers": [ "torso" ], "flags": [ "VARSIZE", "POCKETS", "OUTER", "FANCY" ], "warmth": 40 }, @@ -1216,7 +1216,7 @@ "symbol": "[", "looks_like": "sleeveless_duster_leather", "color": "brown", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 90, "encumbrance": 8, "max_encumbrance": 17, @@ -1250,7 +1250,7 @@ "symbol": "[", "looks_like": "sleeveless_duster_survivor", "color": "brown", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 85, "encumbrance": 7, "max_encumbrance": 15, @@ -1282,7 +1282,7 @@ "symbol": "[", "looks_like": "vest_leather", "color": "dark_gray", - "covers": [ "LEGS", "TORSO" ], + "covers": [ "torso", "leg_l", "leg_r" ], "coverage": 65, "encumbrance": 3, "warmth": 2, @@ -1304,7 +1304,7 @@ "symbol": "[", "looks_like": "robe", "color": "white", - "covers": [ "LEGS", "TORSO", "ARMS" ], + "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r" ], "coverage": 90, "encumbrance": 7, "warmth": 20, @@ -1325,7 +1325,7 @@ "symbol": "[", "looks_like": "coat_winter", "color": "dark_gray", - "covers": [ "TORSO", "ARMS" ], + "covers": [ "torso", "arm_l", "arm_r" ], "coverage": 90, "encumbrance": 7, "max_encumbrance": 15, @@ -1356,7 +1356,7 @@ "symbol": "[", "looks_like": "trenchcoat_leather", "color": "brown", - "covers": [ "TORSO", "ARMS" ], + "covers": [ "torso", "arm_l", "arm_r" ], "coverage": 90, "encumbrance": 9, "max_encumbrance": 19, @@ -1381,7 +1381,7 @@ "name": { "str": "faux fur trenchcoat" }, "description": "A thick faux fur trenchcoat, lined with pockets. Great for storage, and makes you the talk of the town.", "material": [ "faux_fur", "cotton" ], - "covers": [ "TORSO", "ARMS" ], + "covers": [ "torso", "arm_l", "arm_r" ], "flags": [ "VARSIZE", "POCKETS", "OUTER", "FANCY" ], "warmth": 40 }, @@ -1399,7 +1399,7 @@ "symbol": "[", "looks_like": "trenchcoat", "color": "brown", - "covers": [ "TORSO", "ARMS" ], + "covers": [ "torso", "arm_l", "arm_r" ], "coverage": 90, "encumbrance": 8, "max_encumbrance": 17, @@ -1432,7 +1432,7 @@ "symbol": "[", "looks_like": "trenchcoat", "color": "brown", - "covers": [ "TORSO", "ARMS" ], + "covers": [ "torso", "arm_l", "arm_r" ], "coverage": 85, "encumbrance": 7, "max_encumbrance": 15, @@ -1464,7 +1464,7 @@ "symbol": "[", "looks_like": "sweatshirt", "color": "dark_gray", - "covers": [ "LEGS", "TORSO", "ARMS" ], + "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r" ], "coverage": 75, "encumbrance": 3, "warmth": 2, @@ -1484,7 +1484,7 @@ "symbol": "[", "looks_like": "tunic", "color": "light_red", - "covers": [ "TORSO", "LEGS" ], + "covers": [ "torso", "leg_l", "leg_r" ], "coverage": 65, "encumbrance": 5, "warmth": 15, @@ -1506,7 +1506,7 @@ "symbol": "[", "looks_like": "suit", "color": "dark_gray", - "covers": [ "LEGS", "TORSO", "ARMS" ], + "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r" ], "coverage": 95, "encumbrance": 13, "max_encumbrance": 17, @@ -1534,7 +1534,7 @@ "symbol": "[", "looks_like": "blazer", "color": "light_gray", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 60, "encumbrance": 2, "max_encumbrance": 5, @@ -1562,7 +1562,7 @@ "symbol": "[", "looks_like": "coat_winter", "color": "white", - "covers": [ "TORSO", "ARMS" ], + "covers": [ "torso", "arm_l", "arm_r" ], "coverage": 95, "encumbrance": 10, "max_encumbrance": 20, diff --git a/data/json/items/armor/eyewear.json b/data/json/items/armor/eyewear.json index 785b6d6ce12ac..8fa6490ec6a31 100644 --- a/data/json/items/armor/eyewear.json +++ b/data/json/items/armor/eyewear.json @@ -14,7 +14,7 @@ "symbol": "[", "looks_like": "sunglasses", "color": "light_gray", - "covers": [ "EYES" ], + "covers": [ "eyes" ], "coverage": 80, "encumbrance": 10, "material_thickness": 1, @@ -37,7 +37,7 @@ "symbol": "[", "looks_like": "sunglasses", "color": "dark_gray", - "covers": [ "EYES" ], + "covers": [ "eyes" ], "coverage": 95, "encumbrance": 1, "material_thickness": 1, @@ -60,7 +60,7 @@ "symbol": "[", "looks_like": "sunglasses", "color": "dark_gray", - "covers": [ "EYES" ], + "covers": [ "eyes" ], "coverage": 90, "encumbrance": 1, "material_thickness": 1, @@ -84,7 +84,7 @@ "symbol": "[", "looks_like": "glasses_safety", "color": "dark_gray", - "covers": [ "EYES" ], + "covers": [ "eyes" ], "coverage": 100, "encumbrance": 5, "warmth": 5, @@ -108,7 +108,7 @@ "symbol": "[", "looks_like": "glasses_eye", "color": "cyan", - "covers": [ "EYES" ], + "covers": [ "eyes" ], "coverage": 75, "material_thickness": 1, "environmental_protection": 1, @@ -130,7 +130,7 @@ "symbol": "[", "looks_like": "sunglasses", "color": "cyan", - "covers": [ "EYES" ], + "covers": [ "eyes" ], "coverage": 75, "material_thickness": 1, "environmental_protection": 1, @@ -152,7 +152,7 @@ "symbol": "[", "looks_like": "glasses_eye", "color": "cyan", - "covers": [ "EYES" ], + "covers": [ "eyes" ], "coverage": 20, "material_thickness": 1, "environmental_protection": 1, @@ -173,7 +173,7 @@ "symbol": "[", "looks_like": "glasses_eye", "color": "cyan", - "covers": [ "EYES" ], + "covers": [ "eyes" ], "coverage": 75, "material_thickness": 1, "environmental_protection": 1, @@ -195,7 +195,7 @@ "symbol": "[", "looks_like": "glasses_eye", "color": "light_gray", - "covers": [ "EYES" ], + "covers": [ "eyes" ], "coverage": 95, "encumbrance": 5, "warmth": 5, @@ -218,7 +218,7 @@ "symbol": "[", "looks_like": "sunglasses", "color": "dark_gray", - "covers": [ "EYES" ], + "covers": [ "eyes" ], "coverage": 100, "encumbrance": 15, "warmth": 50, @@ -242,7 +242,7 @@ "symbol": "[", "looks_like": "glasses_safety", "color": "dark_gray", - "covers": [ "EYES" ], + "covers": [ "eyes" ], "coverage": 100, "encumbrance": 60, "warmth": 10, @@ -266,7 +266,7 @@ "symbol": "[", "looks_like": "sunglasses", "color": "light_gray", - "covers": [ "EYES" ], + "covers": [ "eyes" ], "coverage": 90, "encumbrance": 9, "warmth": 5, @@ -289,7 +289,7 @@ "symbol": "[", "looks_like": "glasses_eye", "color": "dark_gray", - "covers": [ "EYES" ], + "covers": [ "eyes" ], "coverage": 85, "encumbrance": 1, "material_thickness": 1, @@ -311,7 +311,7 @@ "symbol": "[", "looks_like": "glasses_bal", "color": "dark_gray", - "covers": [ "EYES" ], + "covers": [ "eyes" ], "coverage": 100, "encumbrance": 20, "warmth": 5, diff --git a/data/json/items/armor/gloves.json b/data/json/items/armor/gloves.json index 397370e8abaca..a3e1700412b40 100644 --- a/data/json/items/armor/gloves.json +++ b/data/json/items/armor/gloves.json @@ -14,7 +14,7 @@ "symbol": "[", "looks_like": "gloves_leather", "color": "white", - "covers": [ "HANDS" ], + "covers": [ "hand_l", "hand_r" ], "coverage": 100, "encumbrance": 10, "warmth": 30, @@ -37,7 +37,7 @@ "symbol": "[", "looks_like": "gloves_leather", "color": "red", - "covers": [ "HANDS" ], + "covers": [ "hand_l", "hand_r" ], "coverage": 100, "encumbrance": 70, "warmth": 20, @@ -59,7 +59,7 @@ "material": [ "iron", "cotton" ], "symbol": "[", "color": "light_red", - "covers": [ "HANDS" ], + "covers": [ "hand_l", "hand_r" ], "coverage": 100, "encumbrance": 30, "material_thickness": 4, @@ -81,7 +81,7 @@ "symbol": "[", "looks_like": "gloves_leather", "color": "dark_gray", - "covers": [ "HANDS" ], + "covers": [ "hand_l", "hand_r" ], "coverage": 100, "encumbrance": 50, "warmth": 25, @@ -105,7 +105,7 @@ "symbol": "[", "looks_like": "gauntlets_larmor", "color": "green", - "covers": [ "HANDS" ], + "covers": [ "hand_l", "hand_r" ], "coverage": 95, "encumbrance": 12, "warmth": 20, @@ -139,7 +139,7 @@ "material": [ "leather", "cotton" ], "symbol": "[", "color": "white", - "covers": [ "HAND_R" ], + "covers": [ "hand_r" ], "encumbrance": 4, "coverage": 100, "warmth": 15, @@ -161,7 +161,7 @@ "material": [ "leather", "cotton" ], "symbol": "[", "color": "white", - "covers": [ "HAND_L" ], + "covers": [ "hand_l" ], "encumbrance": 4, "coverage": 100, "warmth": 15, @@ -185,7 +185,7 @@ "symbol": "[", "looks_like": "gloves_leather", "color": "brown", - "covers": [ "HANDS" ], + "covers": [ "hand_l", "hand_r" ], "coverage": 60, "encumbrance": 4, "warmth": 15, @@ -207,7 +207,7 @@ "symbol": "[", "looks_like": "gloves_wraps", "color": "light_blue", - "covers": [ "HANDS" ], + "covers": [ "hand_l", "hand_r" ], "coverage": 70, "encumbrance": 7, "material_thickness": 1, @@ -227,7 +227,7 @@ "symbol": "[", "looks_like": "gloves_light", "color": "dark_gray", - "covers": [ "HANDS" ], + "covers": [ "hand_l", "hand_r" ], "coverage": 50, "warmth": 10, "material_thickness": 1, @@ -248,7 +248,7 @@ "symbol": "[", "looks_like": "gloves_fingerless", "color": "dark_gray", - "covers": [ "HANDS" ], + "covers": [ "hand_l", "hand_r" ], "coverage": 50, "encumbrance": 3, "warmth": 5, @@ -270,7 +270,7 @@ "symbol": "[", "looks_like": "fire_gauntlets", "color": "light_gray", - "covers": [ "HANDS" ], + "covers": [ "hand_l", "hand_r" ], "coverage": 100, "encumbrance": 30, "warmth": 15, @@ -292,7 +292,7 @@ "symbol": "[", "looks_like": "fire_gauntlets", "color": "brown", - "covers": [ "HANDS" ], + "covers": [ "hand_l", "hand_r" ], "coverage": 95, "encumbrance": 30, "warmth": 70, @@ -313,7 +313,7 @@ "symbol": "[", "looks_like": "fire_gauntlets", "color": "dark_gray", - "covers": [ "HANDS" ], + "covers": [ "hand_l", "hand_r" ], "coverage": 100, "encumbrance": 30, "warmth": 15, @@ -336,7 +336,7 @@ "symbol": "[", "looks_like": "gloves_leather", "color": "white", - "covers": [ "HAND_R" ], + "covers": [ "hand_r" ], "coverage": 95, "warmth": 20, "material_thickness": 2, @@ -356,7 +356,7 @@ "symbol": "[", "looks_like": "gloves_light", "color": "dark_gray", - "covers": [ "HANDS" ], + "covers": [ "hand_l", "hand_r" ], "coverage": 95, "encumbrance": 10, "warmth": 25, @@ -378,7 +378,7 @@ "symbol": "[", "looks_like": "gloves_leather", "color": "light_blue", - "covers": [ "HANDS" ], + "covers": [ "hand_l", "hand_r" ], "coverage": 95, "encumbrance": 2, "warmth": 20, @@ -399,7 +399,7 @@ "symbol": "[", "looks_like": "gloves_light", "color": "light_gray", - "covers": [ "HANDS" ], + "covers": [ "hand_l", "hand_r" ], "coverage": 95, "encumbrance": 1, "warmth": 15, @@ -421,7 +421,7 @@ "symbol": "[", "looks_like": "gloves_survivor", "color": "green", - "covers": [ "HANDS" ], + "covers": [ "hand_l", "hand_r" ], "coverage": 100, "encumbrance": 10, "warmth": 15, @@ -444,7 +444,7 @@ "material": [ "kevlar_layered", "cotton" ], "symbol": "[", "color": "green", - "covers": [ "HANDS" ], + "covers": [ "hand_l", "hand_r" ], "coverage": 85, "encumbrance": 8, "warmth": 12, @@ -467,7 +467,7 @@ "symbol": "[", "looks_like": "gloves_light", "color": "white", - "covers": [ "HANDS" ], + "covers": [ "hand_l", "hand_r" ], "coverage": 90, "encumbrance": 1, "material_thickness": 1, @@ -490,7 +490,7 @@ "symbol": "[", "looks_like": "fire_gauntlets", "color": "light_gray", - "covers": [ "HANDS" ], + "covers": [ "hand_l", "hand_r" ], "coverage": 100, "encumbrance": 20, "warmth": 20, @@ -513,7 +513,7 @@ "symbol": "[", "looks_like": "gloves_light", "color": "yellow", - "covers": [ "HANDS" ], + "covers": [ "hand_l", "hand_r" ], "coverage": 100, "encumbrance": 40, "warmth": 10, @@ -536,7 +536,7 @@ "symbol": "[", "looks_like": "fire_gauntlets", "color": "brown", - "covers": [ "HANDS" ], + "covers": [ "hand_l", "hand_r" ], "coverage": 100, "encumbrance": 20, "warmth": 15, @@ -560,7 +560,7 @@ "symbol": "[", "looks_like": "fire_gauntlets", "color": "dark_gray", - "covers": [ "HANDS" ], + "covers": [ "hand_l", "hand_r" ], "coverage": 100, "encumbrance": 13, "warmth": 20, @@ -583,7 +583,7 @@ "symbol": "[", "looks_like": "gloves_leather", "color": "light_blue", - "covers": [ "HANDS" ], + "covers": [ "hand_l", "hand_r" ], "coverage": 100, "encumbrance": 40, "warmth": 70, @@ -603,7 +603,7 @@ "symbol": "[", "looks_like": "gloves_winter", "color": "blue", - "covers": [ "HANDS" ], + "covers": [ "hand_l", "hand_r" ], "coverage": 95, "encumbrance": 20, "warmth": 60, @@ -623,7 +623,7 @@ "symbol": "[", "looks_like": "gloves_leather", "color": "brown", - "covers": [ "HANDS" ], + "covers": [ "hand_l", "hand_r" ], "coverage": 95, "encumbrance": 20, "warmth": 25, @@ -646,7 +646,7 @@ "symbol": "[", "looks_like": "gloves_work", "color": "light_gray", - "covers": [ "HANDS" ], + "covers": [ "hand_l", "hand_r" ], "coverage": 95, "encumbrance": 40, "warmth": 10, @@ -668,7 +668,7 @@ "symbol": "[", "looks_like": "gloves_light", "color": "white", - "covers": [ "HANDS" ], + "covers": [ "hand_l", "hand_r" ], "coverage": 50, "warmth": 5, "material_thickness": 1, @@ -688,7 +688,7 @@ "symbol": "[", "looks_like": "gloves_wraps", "color": "white", - "covers": [ "HANDS" ], + "covers": [ "hand_l", "hand_r" ], "coverage": 50, "encumbrance": 5, "warmth": 20, @@ -709,7 +709,7 @@ "symbol": "[", "looks_like": "gloves_wraps", "color": "white", - "covers": [ "HANDS" ], + "covers": [ "hand_l", "hand_r" ], "coverage": 50, "encumbrance": 5, "warmth": 10, @@ -730,7 +730,7 @@ "symbol": "[", "looks_like": "gloves_wraps", "color": "blue", - "covers": [ "HANDS" ], + "covers": [ "hand_l", "hand_r" ], "coverage": 50, "encumbrance": 2, "warmth": 15, @@ -752,7 +752,7 @@ "symbol": "[", "looks_like": "gloves_winter", "color": "light_gray", - "covers": [ "HANDS" ], + "covers": [ "hand_l", "hand_r" ], "coverage": 100, "encumbrance": 37, "warmth": 75, @@ -775,7 +775,7 @@ "symbol": "[", "looks_like": "gloves_survivor", "color": "brown", - "covers": [ "HANDS" ], + "covers": [ "hand_l", "hand_r" ], "coverage": 100, "encumbrance": 30, "warmth": 15, @@ -798,7 +798,7 @@ "symbol": "[", "looks_like": "gloves_light", "color": "light_blue", - "covers": [ "HANDS", "ARMS" ], + "covers": [ "arm_l", "arm_r", "hand_l", "hand_r" ], "coverage": 60, "warmth": 30, "material_thickness": 2, @@ -818,7 +818,7 @@ "symbol": "[", "looks_like": "gloves_wool", "color": "blue", - "covers": [ "HANDS" ], + "covers": [ "hand_l", "hand_r" ], "coverage": 100, "encumbrance": 80, "warmth": 70, @@ -839,7 +839,7 @@ "symbol": "[", "looks_like": "gloves_light", "color": "light_gray", - "covers": [ "HANDS" ], + "covers": [ "hand_l", "hand_r" ], "coverage": 100, "encumbrance": 6, "warmth": 5, @@ -860,7 +860,7 @@ "symbol": "[", "looks_like": "mittens", "color": "white", - "covers": [ "HANDS" ], + "covers": [ "hand_l", "hand_r" ], "coverage": 40, "warmth": 5, "material_thickness": 1, @@ -879,7 +879,7 @@ "symbol": "[", "looks_like": "arm_warmers", "color": "dark_gray", - "covers": [ "HANDS", "ARMS" ], + "covers": [ "arm_l", "arm_r", "hand_l", "hand_r" ], "coverage": 75, "encumbrance": 10, "warmth": 10, @@ -901,7 +901,7 @@ "symbol": "[", "looks_like": "fire_gauntlets", "color": "white", - "covers": [ "HANDS" ], + "covers": [ "hand_l", "hand_r" ], "coverage": 100, "encumbrance": 20, "warmth": 50, @@ -922,7 +922,7 @@ "symbol": "[", "looks_like": "gloves_light", "color": "dark_gray", - "covers": [ "HANDS" ], + "covers": [ "hand_l", "hand_r" ], "coverage": 90, "encumbrance": 5, "warmth": 20, @@ -938,7 +938,7 @@ "weight": "800 g", "volume": "1500 ml", "price": 70000, - "covers": [ "HANDS" ], + "covers": [ "hand_l", "hand_r" ], "coverage": 100, "encumbrance": 20, "warmth": 40, @@ -964,7 +964,7 @@ "symbol": "[", "looks_like": "gloves_leather", "color": "light_gray", - "covers": [ "HANDS" ], + "covers": [ "hand_l", "hand_r" ], "coverage": 100, "encumbrance": 5, "warmth": 5, diff --git a/data/json/items/armor/hats.json b/data/json/items/armor/hats.json index b599d6a9dd362..4d9e8118f118a 100644 --- a/data/json/items/armor/hats.json +++ b/data/json/items/armor/hats.json @@ -13,7 +13,7 @@ "symbol": "[", "looks_like": "cowboy_hat", "color": "brown", - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 50, "encumbrance": 20, "warmth": 8, @@ -35,7 +35,7 @@ "symbol": "[", "looks_like": "hat_cotton", "color": "dark_gray", - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 40, "warmth": 10, "material_thickness": 1, @@ -54,7 +54,7 @@ "symbol": "[", "looks_like": "beret", "color": "dark_gray", - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 40, "warmth": 15, "material_thickness": 2, @@ -74,7 +74,7 @@ "symbol": "[", "looks_like": "hat_cotton", "color": "dark_gray", - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 50, "encumbrance": 15, "warmth": 5, @@ -95,7 +95,7 @@ "symbol": "[", "looks_like": "bowhat", "color": "brown", - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 50, "encumbrance": 10, "warmth": 7, @@ -117,7 +117,7 @@ "weight": "733 g", "volume": "1500 ml", "encumbrance": 5, - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 15, "material_thickness": 1, "pocket_data": [ { "max_contains_volume": "500 ml", "max_contains_weight": "1 kg", "watertight": true, "rigid": true } ], @@ -137,7 +137,7 @@ "symbol": "[", "looks_like": "bowhat", "color": "dark_gray", - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 60, "encumbrance": 10, "warmth": 4, @@ -156,7 +156,7 @@ "symbol": "[", "looks_like": "cowboy_hat", "color": "dark_gray", - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 65, "encumbrance": 10, "warmth": 10, @@ -179,7 +179,7 @@ "symbol": "[", "looks_like": "hat_cotton", "color": "dark_gray", - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 50, "encumbrance": 10, "warmth": 5, @@ -201,7 +201,7 @@ "symbol": "[", "looks_like": "hat_cotton", "color": "white", - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 75, "encumbrance": 15, "warmth": 5, @@ -221,7 +221,7 @@ "symbol": "[", "looks_like": "hat_ball", "color": "dark_gray", - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 65, "warmth": 20, "material_thickness": 1, @@ -240,7 +240,7 @@ "symbol": "[", "looks_like": "hat_knit", "color": "brown", - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 95, "encumbrance": 10, "warmth": 70, @@ -254,7 +254,7 @@ "name": { "str": "faux fur hat" }, "description": "A stylish hat made of faux fur. Like real fur, but without the suffering, if the tag is to be believed. Very warm.", "material": [ "faux_fur", "cotton" ], - "covers": [ "HEAD" ], + "covers": [ "head" ], "flags": [ "FANCY" ], "warmth": 60 }, @@ -272,7 +272,7 @@ "symbol": "[", "looks_like": "hat_ball", "color": "yellow", - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 80, "encumbrance": 15, "warmth": 5, @@ -295,7 +295,7 @@ "symbol": "[", "looks_like": "hat_hard", "color": "yellow", - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 80, "encumbrance": 13, "warmth": 6, @@ -316,7 +316,7 @@ "symbol": "[", "looks_like": "hat_ball", "color": "light_red", - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 85, "encumbrance": 10, "warmth": 50, @@ -337,7 +337,7 @@ "symbol": "[", "looks_like": "hat_cotton", "color": "dark_gray", - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 65, "warmth": 40, "material_thickness": 2, @@ -357,7 +357,7 @@ "symbol": "[", "looks_like": "hat_ball", "color": "dark_gray", - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 50, "warmth": 30, "material_thickness": 2, @@ -376,7 +376,7 @@ "symbol": "[", "looks_like": "hat_cotton", "color": "dark_gray", - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 5, "encumbrance": 17, "warmth": 5, @@ -398,7 +398,7 @@ "symbol": "[", "looks_like": "cowboy_hat", "color": "light_red", - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 50, "encumbrance": 20, "warmth": 2, @@ -420,7 +420,7 @@ "symbol": "[", "looks_like": "hat_cotton", "color": "blue", - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 40, "warmth": 3, "material_thickness": 1, @@ -440,7 +440,7 @@ "symbol": "[", "looks_like": "hat_cotton", "color": "white", - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 50, "encumbrance": 10, "warmth": 6, @@ -461,7 +461,7 @@ "symbol": "[", "looks_like": "hat_cotton", "color": "white", - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 25, "encumbrance": 10, "warmth": 10, @@ -482,7 +482,7 @@ "symbol": "[", "looks_like": "bowhat", "color": "dark_gray", - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 50, "encumbrance": 15, "warmth": 5, @@ -504,7 +504,7 @@ "symbol": "[", "looks_like": "hat_ball", "color": "blue", - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 60, "encumbrance": 10, "warmth": 10, @@ -525,7 +525,7 @@ "symbol": "[", "looks_like": "cowboy_hat", "color": "dark_gray", - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 40, "warmth": 2, "material_thickness": 1, @@ -546,7 +546,7 @@ "symbol": "[", "looks_like": "hat_cotton", "color": "yellow", - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 90, "flags": [ "PSYSHIELD_PARTIAL", "SKINTIGHT", "TRADER_AVOID" ] }, @@ -565,7 +565,7 @@ "symbol": "[", "looks_like": "porkpie", "color": "dark_gray", - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 50, "encumbrance": 20, "warmth": 5, @@ -586,7 +586,7 @@ "symbol": "[", "looks_like": "bowhat", "color": "brown", - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 50, "encumbrance": 10, "warmth": 7, @@ -609,7 +609,7 @@ "symbol": "[", "looks_like": "hat_cotton", "color": "white", - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 50, "encumbrance": 5, "warmth": 10, @@ -631,7 +631,7 @@ "symbol": "[", "looks_like": "hat_ball", "color": "dark_gray", - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 40, "encumbrance": 10, "warmth": 5, diff --git a/data/json/items/armor/helmets.json b/data/json/items/armor/helmets.json index ec6225eff7409..0f97698e4e03c 100644 --- a/data/json/items/armor/helmets.json +++ b/data/json/items/armor/helmets.json @@ -14,7 +14,7 @@ "symbol": "[", "looks_like": "helmet_plate", "color": "light_gray", - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 55, "encumbrance": 50, "warmth": 5, @@ -37,7 +37,7 @@ "symbol": "[", "looks_like": "balclava", "color": "red", - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 75, "encumbrance": 20, "warmth": 10, @@ -62,7 +62,7 @@ "symbol": "[", "looks_like": "hat_hard", "color": "green", - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 85, "encumbrance": 20, "warmth": 20, @@ -115,7 +115,7 @@ "symbol": "[", "looks_like": "tac_fullhelmet", "color": "dark_gray", - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 95, "encumbrance": 15, "warmth": 10, @@ -140,7 +140,7 @@ "symbol": "[", "looks_like": "cowboy_hat", "color": "yellow", - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 75, "encumbrance": 40, "warmth": 15, @@ -165,7 +165,7 @@ "symbol": "[", "looks_like": "hat_hard", "color": "blue", - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 95, "encumbrance": 20, "warmth": 15, @@ -213,7 +213,7 @@ "symbol": "[", "looks_like": "hat_hard", "color": "dark_gray", - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 75, "encumbrance": 15, "warmth": 15, @@ -260,7 +260,7 @@ "symbol": "[", "looks_like": "helmet_barbute", "color": "brown", - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 90, "encumbrance": 20, "warmth": 35, @@ -366,7 +366,7 @@ "symbol": "[", "looks_like": "hat_hard", "color": "brown", - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 85, "encumbrance": 20, "warmth": 10, @@ -386,7 +386,7 @@ "material": [ "leather", "bone" ], "symbol": "[", "color": "dark_gray", - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 85, "encumbrance": 26, "material_thickness": 3, @@ -408,7 +408,7 @@ "symbol": "[", "looks_like": "balclava", "color": "green", - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 100, "warmth": 30, "material_thickness": 2, @@ -605,7 +605,7 @@ "symbol": "[", "looks_like": "helmet_bike", "color": "dark_gray", - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 65, "encumbrance": 20, "warmth": 10, @@ -630,7 +630,7 @@ "symbol": "[", "looks_like": "helmet_plate", "color": "dark_gray", - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 70, "encumbrance": 20, "warmth": 15, @@ -677,7 +677,7 @@ "symbol": "[", "looks_like": "pot_helmet", "color": "light_gray", - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 55, "encumbrance": 50, "warmth": 5, diff --git a/data/json/items/armor/holster.json b/data/json/items/armor/holster.json index 842700fbbd2bb..49b4eb86287f4 100644 --- a/data/json/items/armor/holster.json +++ b/data/json/items/armor/holster.json @@ -12,7 +12,7 @@ "symbol": "[", "looks_like": "quiver_large", "color": "light_gray", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 5, "encumbrance": 5, "material_thickness": 1, @@ -43,7 +43,8 @@ "symbol": "[", "looks_like": "holster", "color": "brown", - "covers": [ "FOOT_EITHER" ], + "covers": [ "foot_l", "foot_r" ], + "sided": true, "coverage": 5, "encumbrance": 3, "max_encumbrance": 4, @@ -74,7 +75,7 @@ "symbol": "[", "looks_like": "slingpack", "color": "green", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 5, "encumbrance": 3, "max_encumbrance": 7, @@ -106,7 +107,8 @@ "symbol": "[", "looks_like": "sheath", "color": "light_gray", - "covers": [ "LEG_EITHER" ], + "covers": [ "leg_l", "leg_r" ], + "sided": true, "coverage": 5, "encumbrance": 5, "material_thickness": 1, @@ -157,7 +159,7 @@ "price": 3000, "price_postapoc": 500, "material": [ "lycra" ], - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "encumbrance": 1, "pocket_data": [ { @@ -186,7 +188,7 @@ "symbol": "[", "looks_like": "tacvest", "color": "green", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 20, "encumbrance": 1, "max_encumbrance": 2, @@ -218,7 +220,8 @@ "symbol": "[", "looks_like": "quiver_large", "color": "light_gray", - "covers": [ "LEG_EITHER" ], + "covers": [ "leg_l", "leg_r" ], + "sided": true, "coverage": 10, "encumbrance": 2, "material_thickness": 1, diff --git a/data/json/items/armor/hoods.json b/data/json/items/armor/hoods.json index 9aa7c0c177e15..ed2b562d4bf1c 100644 --- a/data/json/items/armor/hoods.json +++ b/data/json/items/armor/hoods.json @@ -37,7 +37,7 @@ "symbol": "[", "looks_like": "balclava", "color": "light_red", - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 95, "encumbrance": 10, "material_thickness": 4, @@ -59,7 +59,7 @@ "symbol": "[", "looks_like": "hood_survivor", "color": "light_gray", - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 100, "encumbrance": 30, "warmth": 15, @@ -83,7 +83,7 @@ "symbol": "[", "looks_like": "hood_survivor", "color": "green", - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 100, "encumbrance": 15, "warmth": 10, @@ -104,7 +104,7 @@ "symbol": "[", "looks_like": "hat_cotton", "color": "yellow", - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 100, "warmth": 10, "material_thickness": 1, @@ -127,7 +127,7 @@ "symbol": "[", "looks_like": "hood_rain", "color": "brown", - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 100, "encumbrance": 25, "warmth": 15, @@ -152,7 +152,7 @@ "symbol": "[", "looks_like": "hood_survivor", "color": "light_gray", - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 100, "encumbrance": 37, "warmth": 75, @@ -176,7 +176,7 @@ "symbol": "[", "looks_like": "hood_survivor", "color": "brown", - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 100, "encumbrance": 40, "warmth": 15, @@ -199,7 +199,7 @@ "symbol": "[", "looks_like": "hood_rain", "color": "light_gray", - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 100, "encumbrance": 6, "warmth": 5, diff --git a/data/json/items/armor/jewelry.json b/data/json/items/armor/jewelry.json index b2d855c81c885..d739cae61009c 100644 --- a/data/json/items/armor/jewelry.json +++ b/data/json/items/armor/jewelry.json @@ -90,7 +90,7 @@ "symbol": "[", "looks_like": "gold_dental_grill", "color": "yellow", - "covers": [ "MOUTH" ], + "covers": [ "mouth" ], "encumbrance": 10, "flags": [ "SUPER_FANCY", "SKINTIGHT" ] }, @@ -109,7 +109,7 @@ "symbol": "[", "looks_like": "gold_dental_grill", "color": "red", - "covers": [ "MOUTH" ], + "covers": [ "mouth" ], "encumbrance": 10, "flags": [ "FANCY", "SKINTIGHT" ] }, @@ -235,7 +235,8 @@ "symbol": "[", "looks_like": "gold_watch", "color": "light_gray", - "covers": [ "HAND_EITHER" ], + "covers": [ "hand_l", "hand_r" ], + "sided": true, "coverage": 5, "use_action": [ "WEATHER_TOOL" ], "flags": [ "WATCH", "ALARMCLOCK", "WATER_FRIENDLY", "THERMOMETER", "BELTED", "ALLOWS_NATURAL_ATTACKS", "OVERSIZE" ] @@ -766,7 +767,7 @@ "material": [ "gold" ], "symbol": "[", "color": "yellow", - "covers": [ "MOUTH" ], + "covers": [ "mouth" ], "flags": [ "FANCY", "SKINTIGHT" ] }, { @@ -867,7 +868,8 @@ "material": [ "steel", "gold" ], "symbol": "[", "color": "yellow", - "covers": [ "HAND_EITHER" ], + "covers": [ "hand_l", "hand_r" ], + "sided": true, "coverage": 5, "flags": [ "WATCH", "FANCY", "BELTED", "FRAGILE", "ALLOWS_NATURAL_ATTACKS", "OVERSIZE" ] }, @@ -897,7 +899,8 @@ "material": [ "steel", "silver" ], "symbol": "[", "color": "light_gray", - "covers": [ "HAND_EITHER" ], + "covers": [ "hand_l", "hand_r" ], + "sided": true, "coverage": 10, "flags": [ "WATCH", "FANCY", "BELTED", "FRAGILE", "ALLOWS_NATURAL_ATTACKS", "WATER_FRIENDLY", "OVERSIZE" ] }, @@ -943,7 +946,8 @@ "material": [ "gold", "silver" ], "symbol": "[", "color": "yellow", - "covers": [ "HAND_EITHER" ], + "covers": [ "hand_l", "hand_r" ], + "sided": true, "coverage": 10, "flags": [ "WATCH", "SUPER_FANCY", "BELTED", "FRAGILE", "ALLOWS_NATURAL_ATTACKS", "WATER_FRIENDLY", "OVERSIZE" ] }, @@ -1033,7 +1037,8 @@ "material": [ "platinum" ], "symbol": "[", "color": "white", - "covers": [ "HAND_EITHER" ], + "covers": [ "hand_l", "hand_r" ], + "sided": true, "coverage": 5, "flags": [ "WATCH", "SUPER_FANCY", "BELTED", "FRAGILE", "ALLOWS_NATURAL_ATTACKS", "OVERSIZE" ] }, @@ -1065,7 +1070,7 @@ "material": [ "platinum", "silver" ], "symbol": "[", "color": "white", - "covers": [ "MOUTH" ], + "covers": [ "mouth" ], "flags": [ "SUPER_FANCY", "SKINTIGHT" ] }, { @@ -1296,7 +1301,8 @@ "ascii_picture": "wristwatch", "symbol": "[", "color": "dark_gray", - "covers": [ "HAND_EITHER" ], + "covers": [ "hand_l", "hand_r" ], + "sided": true, "coverage": 5, "flags": [ "WATCH", "ALARMCLOCK", "BELTED", "FRAGILE", "ALLOWS_NATURAL_ATTACKS", "WATER_FRIENDLY", "OVERSIZE" ] }, diff --git a/data/json/items/armor/legs_armor.json b/data/json/items/armor/legs_armor.json index c9f029c885480..2a52397d8f303 100644 --- a/data/json/items/armor/legs_armor.json +++ b/data/json/items/armor/legs_armor.json @@ -15,7 +15,7 @@ "symbol": "[", "looks_like": "leg_splint", "color": "brown", - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "coverage": 75, "encumbrance": 25, "warmth": 5, @@ -39,7 +39,7 @@ "symbol": "[", "looks_like": "pants_cargo", "color": "dark_gray", - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "coverage": 100, "encumbrance": 24, "max_encumbrance": 30, @@ -70,7 +70,7 @@ "symbol": "[", "looks_like": "legguard_hard", "color": "light_red", - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "coverage": 95, "encumbrance": 20, "material_thickness": 4, @@ -90,7 +90,7 @@ "symbol": "[", "looks_like": "pants_leather", "color": "dark_gray", - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "coverage": 65, "encumbrance": 3, "warmth": 10, @@ -122,7 +122,7 @@ "symbol": "[", "looks_like": "pants", "color": "white", - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "coverage": 95, "encumbrance": 13, "max_encumbrance": 15, @@ -149,7 +149,7 @@ "symbol": "[", "looks_like": "legguard_hard", "color": "dark_gray", - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "coverage": 30, "material_thickness": 5, "flags": [ "WATER_FRIENDLY", "BELTED" ] @@ -169,7 +169,7 @@ "symbol": "[", "looks_like": "legguard_lightplate", "color": "yellow", - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "coverage": 70, "encumbrance": 10, "warmth": 15, @@ -191,7 +191,7 @@ "symbol": "[", "looks_like": "leg_warmers", "color": "dark_gray", - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "coverage": 75, "encumbrance": 10, "warmth": 20, @@ -214,7 +214,7 @@ "symbol": "[", "looks_like": "legguard_hard", "color": "light_gray", - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "coverage": 95, "encumbrance": 20, "warmth": 20, @@ -236,7 +236,7 @@ "symbol": "[", "looks_like": "legguard_lightplate", "color": "light_gray", - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "coverage": 70, "encumbrance": 6, "warmth": 10, @@ -257,7 +257,7 @@ "symbol": "[", "looks_like": "legguard_hard", "color": "blue", - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "coverage": 80, "encumbrance": 10, "warmth": 5, @@ -281,7 +281,7 @@ "symbol": "[", "looks_like": "legguard_metal", "color": "light_gray", - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "coverage": 80, "encumbrance": 18, "warmth": 20, @@ -302,7 +302,7 @@ "symbol": "[", "looks_like": "pants_survivor", "color": "green", - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "coverage": 95, "encumbrance": 8, "max_encumbrance": 16, @@ -333,7 +333,7 @@ "symbol": "[", "looks_like": "pants_leather", "color": "dark_gray", - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "coverage": 100, "encumbrance": 20, "warmth": 35, @@ -355,7 +355,7 @@ "symbol": "[", "looks_like": "pants_army", "color": "green", - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "coverage": 100, "encumbrance": 10, "max_encumbrance": 20, @@ -384,7 +384,7 @@ "weight": "6400 g", "volume": "12 L", "price": 200000, - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "coverage": 100, "encumbrance": 80, "warmth": 65, @@ -404,7 +404,7 @@ "weight": "3000 g", "volume": "12 L", "price": 200000, - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "coverage": 100, "encumbrance": 40, "warmth": 40, diff --git a/data/json/items/armor/legs_clothes.json b/data/json/items/armor/legs_clothes.json index 7689d96a2c831..3e9ed28a7fc44 100644 --- a/data/json/items/armor/legs_clothes.json +++ b/data/json/items/armor/legs_clothes.json @@ -14,7 +14,7 @@ "symbol": "[", "looks_like": "shorts", "color": "cyan", - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "coverage": 50, "pocket_data": [ { "pocket_type": "CONTAINER", "max_contains_volume": "500 ml", "max_contains_weight": "1 kg", "moves": 80 }, @@ -38,7 +38,7 @@ "symbol": "[", "looks_like": "pants", "color": "brown", - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "coverage": 80, "encumbrance": 8, "warmth": 10, @@ -59,7 +59,7 @@ "symbol": "[", "looks_like": "pants_ski", "color": "green", - "covers": [ "TORSO", "LEGS", "FEET" ], + "covers": [ "leg_l", "leg_r", "torso", "foot_l", "foot_r" ], "coverage": 100, "encumbrance": 19, "max_encumbrance": 25, @@ -87,7 +87,7 @@ "symbol": "[", "looks_like": "boxer_briefs", "color": "light_red", - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "coverage": 15, "material_thickness": 1, "flags": [ "VARSIZE", "WATER_FRIENDLY", "SKINTIGHT" ] @@ -105,7 +105,7 @@ "symbol": "[", "looks_like": "hot_pants_leather", "color": "brown", - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "coverage": 15, "warmth": 10, "material_thickness": 1, @@ -124,7 +124,7 @@ "symbol": "[", "looks_like": "hot_pants", "color": "dark_gray", - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "coverage": 15, "warmth": 5, "material_thickness": 1, @@ -144,7 +144,7 @@ "symbol": "[", "looks_like": "pants", "color": "blue", - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "coverage": 95, "encumbrance": 12, "max_encumbrance": 16, @@ -173,7 +173,7 @@ "symbol": "[", "looks_like": "jeans", "color": "red", - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "coverage": 95, "encumbrance": 12, "max_encumbrance": 16, @@ -200,7 +200,7 @@ "symbol": "[", "looks_like": "skirt", "color": "dark_gray", - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "coverage": 50, "pocket_data": [ { "pocket_type": "CONTAINER", "max_contains_volume": "250 ml", "max_contains_weight": "1 kg", "moves": 80 } ], "warmth": 20, @@ -220,7 +220,7 @@ "symbol": "[", "looks_like": "kilt", "color": "dark_gray", - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "coverage": 50, "pocket_data": [ { "pocket_type": "CONTAINER", "max_contains_volume": "250 ml", "max_contains_weight": "1 kg", "moves": 80 } ], "warmth": 10, @@ -240,7 +240,7 @@ "symbol": "[", "looks_like": "leg_warmers", "color": "dark_gray", - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "coverage": 100, "warmth": 20, "material_thickness": 1, @@ -259,7 +259,7 @@ "symbol": "[", "looks_like": "briefs", "color": "brown", - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "coverage": 5, "material_thickness": 1, "flags": [ "VARSIZE", "SKINTIGHT", "OVERSIZE" ] @@ -277,7 +277,7 @@ "symbol": "[", "looks_like": "loincloth_leather", "color": "brown", - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "coverage": 5, "warmth": 5, "material_thickness": 1, @@ -296,7 +296,7 @@ "symbol": "[", "looks_like": "loincloth", "color": "brown", - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "coverage": 5, "material_thickness": 2, "flags": [ "VARSIZE", "SKINTIGHT", "OVERSIZE" ] @@ -314,7 +314,7 @@ "symbol": "[", "looks_like": "loincloth", "color": "blue", - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "coverage": 5, "warmth": 5, "material_thickness": 1, @@ -334,7 +334,7 @@ "symbol": "[", "looks_like": "skirt", "color": "pink", - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "coverage": 7, "material_thickness": 1, "flags": [ "VARSIZE", "FANCY" ] @@ -354,7 +354,7 @@ "symbol": "[", "looks_like": "jeans", "color": "brown", - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "coverage": 95, "encumbrance": 7, "max_encumbrance": 11, @@ -382,7 +382,7 @@ "symbol": "[", "looks_like": "pants_cargo", "color": "green", - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "coverage": 95, "encumbrance": 9, "max_encumbrance": 18, @@ -411,7 +411,7 @@ "symbol": "[", "looks_like": "pants", "color": "light_gray", - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "coverage": 95, "encumbrance": 8, "max_encumbrance": 16, @@ -443,7 +443,7 @@ "symbol": "[", "looks_like": "pants", "color": "dark_gray", - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "coverage": 95, "encumbrance": 2, "max_encumbrance": 5, @@ -471,7 +471,7 @@ "symbol": "[", "looks_like": "pants", "color": "brown", - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "coverage": 95, "encumbrance": 16, "max_encumbrance": 20, @@ -494,7 +494,7 @@ "name": { "str_sp": "faux fur pants" }, "description": "A pair of long cotton pants lined with warm imitation fur.", "material": [ "faux_fur", "cotton" ], - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "warmth": 70 }, { @@ -511,7 +511,7 @@ "symbol": "[", "looks_like": "pants", "color": "dark_gray", - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "coverage": 95, "encumbrance": 15, "max_encumbrance": 17, @@ -538,7 +538,7 @@ "symbol": "[", "looks_like": "pants", "color": "blue", - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "coverage": 95, "encumbrance": 6, "max_encumbrance": 10, @@ -568,7 +568,7 @@ "symbol": "[", "looks_like": "shorts_cargo", "color": "blue", - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "coverage": 40, "pocket_data": [ { "pocket_type": "CONTAINER", "max_contains_volume": "500 ml", "max_contains_weight": "1 kg", "moves": 80 }, @@ -594,7 +594,7 @@ "symbol": "[", "looks_like": "boxer_shorts", "color": "brown", - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "coverage": 40, "encumbrance": 2, "max_encumbrance": 5, @@ -622,7 +622,7 @@ "symbol": "[", "looks_like": "shorts", "color": "light_gray", - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "coverage": 40, "encumbrance": 2, "max_encumbrance": 5, @@ -652,7 +652,7 @@ "symbol": "[", "looks_like": "shorts", "color": "light_blue", - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "coverage": 40, "encumbrance": 1, "max_encumbrance": 2, @@ -678,7 +678,7 @@ "symbol": "[", "looks_like": "kilt", "color": "dark_gray", - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "coverage": 50, "pocket_data": [ { "pocket_type": "CONTAINER", "max_contains_volume": "250 ml", "max_contains_weight": "1 kg", "moves": 80 } ], "warmth": 5, @@ -699,7 +699,7 @@ "symbol": "[", "looks_like": "skirt", "color": "brown", - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "coverage": 35, "encumbrance": 10, "warmth": 10, @@ -721,7 +721,7 @@ "symbol": "[", "looks_like": "pants_checkered", "color": "white", - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "coverage": 95, "encumbrance": 2, "max_encumbrance": 5, @@ -750,7 +750,7 @@ "symbol": "[", "looks_like": "pants", "color": "light_gray", - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "coverage": 95, "encumbrance": 2, "max_encumbrance": 5, @@ -782,7 +782,7 @@ "symbol": "[", "looks_like": "pants_army", "color": "white", - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "coverage": 95, "encumbrance": 11, "max_encumbrance": 22, @@ -814,7 +814,7 @@ "symbol": "[", "looks_like": "pants", "color": "white", - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "coverage": 80, "warmth": 5, "material_thickness": 2, diff --git a/data/json/items/armor/masks.json b/data/json/items/armor/masks.json index 72291c89f0410..4b5ae39b0a948 100644 --- a/data/json/items/armor/masks.json +++ b/data/json/items/armor/masks.json @@ -12,7 +12,7 @@ "symbol": "[", "looks_like": "hat_cotton", "color": "dark_gray", - "covers": [ "HEAD", "MOUTH" ], + "covers": [ "head", "mouth" ], "coverage": 95, "encumbrance": 5, "warmth": 30, @@ -42,7 +42,7 @@ "symbol": "[", "looks_like": "scarf", "color": "blue", - "covers": [ "MOUTH" ], + "covers": [ "mouth" ], "coverage": 95, "encumbrance": 1, "warmth": 5, @@ -64,7 +64,7 @@ "symbol": "[", "looks_like": "balclava", "color": "dark_gray", - "covers": [ "HEAD", "EYES", "MOUTH" ], + "covers": [ "head", "eyes", "mouth" ], "coverage": 100, "encumbrance": 30, "warmth": 30, @@ -130,7 +130,7 @@ "symbol": "[", "looks_like": "glasses_bal", "color": "dark_gray", - "covers": [ "MOUTH", "EYES" ], + "covers": [ "eyes", "mouth" ], "coverage": 95, "encumbrance": 20, "warmth": 10, @@ -153,7 +153,7 @@ "symbol": "[", "looks_like": "scarf", "color": "white", - "covers": [ "MOUTH" ], + "covers": [ "mouth" ], "coverage": 100, "encumbrance": 8, "warmth": 5, @@ -175,7 +175,7 @@ "symbol": "[", "looks_like": "mask_hockey", "color": "white", - "covers": [ "MOUTH", "EYES" ], + "covers": [ "eyes", "mouth" ], "coverage": 95, "encumbrance": 10, "warmth": 5, @@ -200,7 +200,7 @@ "symbol": "[", "looks_like": "glasses_safety", "color": "white", - "covers": [ "MOUTH", "EYES" ], + "covers": [ "eyes", "mouth" ], "coverage": 95, "encumbrance": 20, "warmth": 5, @@ -222,7 +222,7 @@ "symbol": "[", "looks_like": "scarf", "color": "white", - "covers": [ "MOUTH", "HEAD" ], + "covers": [ "head", "mouth" ], "coverage": 90, "encumbrance": 8, "warmth": 10, diff --git a/data/json/items/armor/misc.json b/data/json/items/armor/misc.json index 6b51228ebd058..7f70d154dcabd 100644 --- a/data/json/items/armor/misc.json +++ b/data/json/items/armor/misc.json @@ -13,7 +13,7 @@ "material": [ "cotton" ], "symbol": "[", "color": "pink", - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 60, "encumbrance": 5, "warmth": 20, @@ -48,7 +48,7 @@ "symbol": "[", "looks_like": "hat_cotton", "color": "yellow", - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 30, "encumbrance": 20, "material_thickness": 2, @@ -67,7 +67,7 @@ "symbol": "[", "looks_like": "crown_golden", "color": "yellow", - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 30, "encumbrance": 20, "material_thickness": 2, @@ -88,7 +88,7 @@ "material": [ "plastic" ], "symbol": "[", "color": "yellow", - "covers": [ "MOUTH" ], + "covers": [ "mouth" ], "coverage": 50, "material_thickness": 1, "flags": [ "VARSIZE", "STURDY", "WATER_FRIENDLY", "SKINTIGHT", "POWERARMOR_COMPATIBLE" ] @@ -121,7 +121,7 @@ "symbol": "(", "looks_like": "duffelbag", "color": "light_red", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 10, "encumbrance": 20, "material_thickness": 4, @@ -142,7 +142,7 @@ "symbol": "[", "looks_like": "sleeping_bag", "color": "brown", - "covers": [ "TORSO", "HEAD", "MOUTH", "ARMS", "HANDS", "LEGS", "FEET" ], + "covers": [ "torso", "head", "mouth", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ], "coverage": 100, "encumbrance": 80, "warmth": 100, @@ -170,7 +170,7 @@ "symbol": "(", "looks_like": "sleeping_bag_roll", "color": "brown", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 10, "encumbrance": 20, "material_thickness": 5, @@ -239,7 +239,7 @@ "symbol": "[", "looks_like": "scarf", "color": "white", - "covers": [ "MOUTH", "EYES" ], + "covers": [ "eyes", "mouth" ], "coverage": 100, "encumbrance": 5, "material_thickness": 1, @@ -260,7 +260,7 @@ "symbol": "[", "looks_like": "blanket", "color": "light_blue", - "covers": [ "TORSO", "ARMS", "HANDS", "LEGS", "FEET" ], + "covers": [ "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ], "coverage": 90, "encumbrance": 30, "warmth": 10, diff --git a/data/json/items/armor/pets_horse_armor.json b/data/json/items/armor/pets_horse_armor.json index 3ca9c3af1d99e..76200b0dd52e2 100644 --- a/data/json/items/armor/pets_horse_armor.json +++ b/data/json/items/armor/pets_horse_armor.json @@ -156,7 +156,7 @@ "symbol": "[", "looks_like": "dump_pouch", "color": "green", - "covers": [ "HANDS" ], + "covers": [ "hand_l", "hand_r" ], "coverage": 50, "encumbrance": 30, "warmth": 10, diff --git a/data/json/items/armor/power_armor.json b/data/json/items/armor/power_armor.json index 7761042298c02..629d89ff8e99d 100644 --- a/data/json/items/armor/power_armor.json +++ b/data/json/items/armor/power_armor.json @@ -16,7 +16,7 @@ "symbol": "[", "looks_like": "power_armor_basic", "color": "light_gray", - "covers": [ "TORSO", "ARMS", "HANDS", "LEGS", "FEET" ], + "covers": [ "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ], "coverage": 95, "encumbrance": 40, "pocket_data": [ @@ -49,7 +49,7 @@ "symbol": "[", "looks_like": "power_armor_helmet_basic", "color": "light_gray", - "covers": [ "HEAD", "EYES", "MOUTH" ], + "covers": [ "head", "eyes", "mouth" ], "coverage": 95, "encumbrance": 40, "warmth": 50, @@ -74,7 +74,7 @@ "symbol": "[", "looks_like": "depowered_armor", "color": "light_gray", - "covers": [ "TORSO", "ARMS", "HANDS", "LEGS", "FEET" ], + "covers": [ "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ], "coverage": 100, "encumbrance": 50, "pocket_data": [ @@ -106,7 +106,7 @@ "power_draw": 4000000, "revert_to": "power_armor_basic", "use_action": { "type": "transform", "menu_text": "Turn off", "msg": "The %s armor disengages.", "target": "power_armor_basic" }, - "covers": [ "TORSO", "ARMS", "HANDS", "LEGS", "FEET" ] + "covers": [ "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ] }, { "id": "power_armor_frame", @@ -156,7 +156,7 @@ "symbol": "[", "looks_like": "power_armor_basic", "color": "dark_gray", - "covers": [ "TORSO", "ARMS", "HANDS", "LEGS", "FEET" ], + "covers": [ "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ], "coverage": 100, "encumbrance": 60, "pocket_data": [ @@ -188,7 +188,7 @@ "power_draw": 4000000, "revert_to": "power_armor_heavy", "use_action": { "type": "transform", "menu_text": "Turn off", "msg": "The %s armor disengages.", "target": "power_armor_heavy" }, - "covers": [ "TORSO", "ARMS", "HANDS", "LEGS", "FEET" ] + "covers": [ "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ] }, { "id": "power_armor_helmet_basic", @@ -206,7 +206,7 @@ "symbol": "[", "looks_like": "depowered_helmet", "color": "light_gray", - "covers": [ "HEAD", "EYES", "MOUTH" ], + "covers": [ "head", "eyes", "mouth" ], "coverage": 100, "encumbrance": 50, "warmth": 90, @@ -232,7 +232,7 @@ "symbol": "[", "looks_like": "power_armor_helmet_basic", "color": "dark_gray", - "covers": [ "HEAD", "EYES", "MOUTH" ], + "covers": [ "head", "eyes", "mouth" ], "coverage": 100, "encumbrance": 60, "warmth": 60, @@ -258,7 +258,7 @@ "symbol": "[", "looks_like": "power_armor_helmet_basic", "color": "dark_gray", - "covers": [ "HEAD", "EYES", "MOUTH" ], + "covers": [ "head", "eyes", "mouth" ], "coverage": 100, "encumbrance": 40, "warmth": 60, @@ -284,7 +284,7 @@ "symbol": "[", "looks_like": "depowered_armor", "color": "dark_gray", - "covers": [ "TORSO", "ARMS", "HANDS", "LEGS", "FEET" ], + "covers": [ "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ], "coverage": 100, "encumbrance": 40, "pocket_data": [ @@ -316,6 +316,6 @@ "power_draw": 4000000, "revert_to": "power_armor_light", "use_action": { "type": "transform", "menu_text": "Turn off", "msg": "The %s armor disengages.", "target": "power_armor_light" }, - "covers": [ "TORSO", "ARMS", "HANDS", "LEGS", "FEET" ] + "covers": [ "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ] } ] diff --git a/data/json/items/armor/scarfs.json b/data/json/items/armor/scarfs.json index 9a6a85c0aef11..7ff1f4665e9c8 100644 --- a/data/json/items/armor/scarfs.json +++ b/data/json/items/armor/scarfs.json @@ -13,7 +13,7 @@ "symbol": "[", "looks_like": "scarf", "color": "white", - "covers": [ "MOUTH" ], + "covers": [ "mouth" ], "coverage": 70, "encumbrance": 20, "warmth": 40, @@ -35,7 +35,7 @@ "symbol": "[", "looks_like": "scarf", "color": "yellow", - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 70, "encumbrance": 4, "warmth": 7, @@ -56,7 +56,7 @@ "symbol": "[", "looks_like": "scarf", "color": "white", - "covers": [ "MOUTH" ], + "covers": [ "mouth" ], "coverage": 85, "encumbrance": 10, "warmth": 30, @@ -72,6 +72,6 @@ "name": { "str": "cyan scarf" }, "description": "A simple cloth scarf worn by Marloss Voices. Wherever the Voices go, long sought peace soon follows, for better or for worse.", "color": "cyan", - "covers": [ "MOUTH" ] + "covers": [ "mouth" ] } ] diff --git a/data/json/items/armor/sheath.json b/data/json/items/armor/sheath.json index 8c3ed8067ba69..e687e92a35b1d 100644 --- a/data/json/items/armor/sheath.json +++ b/data/json/items/armor/sheath.json @@ -12,7 +12,7 @@ "symbol": "[", "looks_like": "sheath", "color": "brown", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 5, "encumbrance": 2, "material_thickness": 1, @@ -43,7 +43,7 @@ "symbol": "[", "looks_like": "sheath", "color": "brown", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 10, "encumbrance": 3, "material_thickness": 1, @@ -74,7 +74,8 @@ "symbol": "[", "looks_like": "sheath", "color": "brown", - "covers": [ "FOOT_EITHER" ], + "covers": [ "foot_l", "foot_r" ], + "sided": true, "coverage": 5, "encumbrance": 3, "material_thickness": 1, @@ -105,7 +106,7 @@ "symbol": "[", "looks_like": "baldric", "color": "brown", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 10, "encumbrance": 3, "material_thickness": 1, @@ -136,7 +137,8 @@ "symbol": "[", "looks_like": "holster", "color": "brown", - "covers": [ "LEG_EITHER" ], + "covers": [ "leg_l", "leg_r" ], + "sided": true, "coverage": 15, "encumbrance": 3, "material_thickness": 1, @@ -165,7 +167,8 @@ "symbol": "|", "looks_like": "scabbard", "color": "brown", - "covers": [ "LEG_EITHER" ], + "covers": [ "leg_l", "leg_r" ], + "sided": true, "coverage": 5, "material_thickness": 1, "pocket_data": [ @@ -195,7 +198,7 @@ "symbol": "[", "looks_like": "bscabbard", "color": "brown", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 5, "encumbrance": 4, "material_thickness": 1, diff --git a/data/json/items/armor/storage.json b/data/json/items/armor/storage.json index d7964bdbb4315..f394de971c107 100644 --- a/data/json/items/armor/storage.json +++ b/data/json/items/armor/storage.json @@ -12,7 +12,7 @@ "symbol": "[", "looks_like": "ragpouch", "color": "green", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 30, "encumbrance": 2, "max_encumbrance": 25, @@ -42,7 +42,7 @@ "symbol": "[", "looks_like": "backpack", "color": "brown", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 50, "encumbrance": 10, "max_encumbrance": 40, @@ -115,7 +115,7 @@ "symbol": "[", "looks_like": "backpack", "color": "green", - "covers": [ "TORSO", "LEGS" ], + "covers": [ "torso", "leg_l", "leg_r" ], "coverage": 75, "encumbrance": 20, "max_encumbrance": 60, @@ -146,7 +146,7 @@ "symbol": "[", "looks_like": "backpack", "color": "brown", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 30, "encumbrance": 4, "max_encumbrance": 26, @@ -176,7 +176,7 @@ "symbol": "[", "looks_like": "backpack", "color": "green", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 50, "encumbrance": 10, "max_encumbrance": 55, @@ -233,7 +233,7 @@ "symbol": ")", "looks_like": "plastic_shopping_bag", "color": "light_gray", - "covers": [ "ARMS", "HANDS" ], + "covers": [ "arm_l", "arm_r", "hand_l", "hand_r" ], "coverage": 5, "encumbrance": 50, "pocket_data": [ @@ -262,7 +262,7 @@ "symbol": "[", "looks_like": "rucksack", "color": "black", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 50, "encumbrance": 16, "max_encumbrance": 65, @@ -319,7 +319,8 @@ "symbol": "[", "looks_like": "plastic_shopping_bag", "color": "light_gray", - "covers": [ "ARM_EITHER", "HAND_EITHER" ], + "covers": [ "arm_l", "arm_r", "hand_l", "hand_r" ], + "sided": true, "coverage": 4, "encumbrance": 30, "max_encumbrance": 35, @@ -350,7 +351,7 @@ "moves": 300 } ], - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 40, "encumbrance": 20, "warmth": 5, @@ -375,7 +376,8 @@ "symbol": "[", "looks_like": "plastic_shopping_bag", "color": "light_gray", - "covers": [ "ARM_EITHER", "HAND_EITHER" ], + "covers": [ "arm_l", "arm_r", "hand_l", "hand_r" ], + "sided": true, "coverage": 10, "encumbrance": 30, "pocket_data": [ @@ -407,7 +409,8 @@ "symbol": "&", "looks_like": "briefcase", "color": "dark_gray", - "covers": [ "ARM_EITHER", "HAND_EITHER" ], + "covers": [ "arm_l", "arm_r", "hand_l", "hand_r" ], + "sided": true, "coverage": 10, "encumbrance": 30, "pocket_data": [ @@ -438,7 +441,7 @@ "price": 5500, "price_postapoc": 500, "material": [ "cotton", "plastic" ], - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 50, "material_thickness": 1, "encumbrance": 2, @@ -470,7 +473,7 @@ "symbol": "[", "looks_like": "backpack", "color": "yellow", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 40, "encumbrance": 2, "max_encumbrance": 30, @@ -499,7 +502,7 @@ "symbol": "[", "looks_like": "rucksack", "color": "green", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 50, "encumbrance": 5, "max_encumbrance": 35, @@ -532,7 +535,7 @@ "symbol": "[", "looks_like": "holster", "color": "dark_gray", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 10, "encumbrance": 1, "max_encumbrance": 3, @@ -564,7 +567,7 @@ "symbol": "[", "looks_like": "holster", "color": "green", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 10, "encumbrance": 1, "max_encumbrance": 3, @@ -595,7 +598,7 @@ "symbol": "[", "looks_like": "quiver_large", "color": "green", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 35, "encumbrance": 30, "max_encumbrance": 35, @@ -633,7 +636,8 @@ "color": "pink", "proportional": { "weight": 6.0, "volume": 6.0, "price": 6.0, "quench": 6.0, "calories": 6.0, "healthy": 6.0, "fun": 6.0 }, "armor_data": { - "covers": [ "ARM_EITHER", "HAND_EITHER" ], + "covers": [ "arm_l", "arm_r", "hand_l", "hand_r" ], + "sided": true, "coverage": 5, "encumbrance": 10, "max_encumbrance": 100, @@ -663,7 +667,8 @@ "price_postapoc": 10, "proportional": { "weight": 6.0, "volume": 6.0, "price": 6.0, "quench": 6.0, "calories": 6.0, "healthy": 6.0, "fun": 6.0 }, "armor_data": { - "covers": [ "ARM_EITHER", "HAND_EITHER" ], + "covers": [ "arm_l", "arm_r", "hand_l", "hand_r" ], + "sided": true, "coverage": 5, "encumbrance": 10, "max_encumbrance": 100, @@ -718,7 +723,7 @@ "symbol": "[", "looks_like": "backpack", "color": "green", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 40, "encumbrance": 30, "warmth": 5, @@ -749,7 +754,7 @@ "symbol": "[", "looks_like": "holster", "color": "brown", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 15, "encumbrance": 1, "max_encumbrance": 3, @@ -777,7 +782,7 @@ "material": [ "cotton" ], "symbol": "[", "color": "dark_gray", - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "coverage": 20, "encumbrance": 2, "max_encumbrance": 5, @@ -815,7 +820,7 @@ "symbol": "[", "looks_like": "ragpouch", "color": "light_gray", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 30, "encumbrance": 2, "max_encumbrance": 9, @@ -846,7 +851,7 @@ "symbol": "[", "looks_like": "ragpouch", "color": "light_gray", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 40, "encumbrance": 4, "max_encumbrance": 15, @@ -881,7 +886,7 @@ "symbol": "[", "looks_like": "purse", "color": "green", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 30, "encumbrance": 8, "max_encumbrance": 12, @@ -912,7 +917,7 @@ "symbol": "[", "looks_like": "backpack", "color": "green", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 35, "encumbrance": 5, "max_encumbrance": 20, @@ -967,7 +972,7 @@ "symbol": "[", "looks_like": "backpack", "color": "blue", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 40, "encumbrance": 35, "pocket_data": [ @@ -999,7 +1004,8 @@ "material": [ "plastic" ], "symbol": "[", "color": "white", - "covers": [ "ARM_EITHER", "HAND_EITHER" ], + "covers": [ "arm_l", "arm_r", "hand_l", "hand_r" ], + "sided": true, "coverage": 4, "encumbrance": 1, "max_encumbrance": 60, @@ -1023,7 +1029,7 @@ "symbol": "[", "looks_like": "ragpouch", "color": "dark_gray", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 10, "encumbrance": 2, "max_encumbrance": 7, @@ -1053,7 +1059,7 @@ "material": [ "cotton" ], "symbol": "[", "color": "light_gray", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 15, "encumbrance": 5, "max_encumbrance": 10, @@ -1083,7 +1089,7 @@ "symbol": "[", "looks_like": "backpack", "color": "green", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 40, "encumbrance": 10, "max_encumbrance": 50, @@ -1140,7 +1146,7 @@ "symbol": "[", "looks_like": "backpack", "color": "green", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 20, "encumbrance": 1, "max_encumbrance": 6, @@ -1174,7 +1180,7 @@ "symbol": "[", "looks_like": "purse", "color": "green", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 30, "encumbrance": 2, "max_encumbrance": 9, @@ -1206,7 +1212,8 @@ "symbol": "[", "looks_like": "plastic_shopping_bag", "color": "light_gray", - "covers": [ "ARM_EITHER", "HAND_EITHER" ], + "covers": [ "arm_l", "arm_r", "hand_l", "hand_r" ], + "sided": true, "coverage": 4, "encumbrance": 30, "pocket_data": [ @@ -1237,7 +1244,8 @@ "symbol": "[", "looks_like": "suitcase_m", "color": "red", - "covers": [ "ARM_EITHER", "HAND_EITHER", "LEG_EITHER" ], + "covers": [ "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r" ], + "sided": true, "coverage": 5, "encumbrance": 70, "pocket_data": [ @@ -1267,7 +1275,8 @@ "symbol": "[", "looks_like": "briefcase", "color": "blue", - "covers": [ "ARM_EITHER", "HAND_EITHER", "LEG_EITHER" ], + "covers": [ "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r" ], + "sided": true, "coverage": 5, "encumbrance": 50, "pocket_data": [ @@ -1296,7 +1305,7 @@ "symbol": "[", "looks_like": "rucksack", "color": "dark_gray", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 40, "encumbrance": 8, "max_encumbrance": 30, @@ -1327,7 +1336,7 @@ "symbol": "[", "looks_like": "backpack", "color": "brown", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 30, "encumbrance": 3, "max_encumbrance": 24, @@ -1358,7 +1367,7 @@ "symbol": "[", "looks_like": "rucksack", "color": "dark_gray", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 40, "encumbrance": 3, "max_encumbrance": 28, @@ -1389,7 +1398,7 @@ "symbol": "[", "looks_like": "backpack", "color": "brown", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 30, "encumbrance": 3, "max_encumbrance": 12, @@ -1421,7 +1430,8 @@ "symbol": "[", "looks_like": "duffelbag", "color": "brown", - "covers": [ "ARM_EITHER", "HAND_EITHER" ], + "covers": [ "arm_l", "arm_r", "hand_l", "hand_r" ], + "sided": true, "coverage": 5, "encumbrance": 4, "max_encumbrance": 100, @@ -1450,7 +1460,7 @@ "symbol": "[", "looks_like": "backpack", "color": "yellow", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 40, "encumbrance": 3, "max_encumbrance": 25, @@ -1506,7 +1516,7 @@ "symbol": "[", "looks_like": "tank_top", "color": "light_gray", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 60, "encumbrance": 2, "max_encumbrance": 5, diff --git a/data/json/items/armor/suits_clothes.json b/data/json/items/armor/suits_clothes.json index 2423eed14a1d7..aa604a3d3d2b8 100644 --- a/data/json/items/armor/suits_clothes.json +++ b/data/json/items/armor/suits_clothes.json @@ -14,7 +14,7 @@ "symbol": "[", "looks_like": "armor_larmor", "color": "dark_gray", - "covers": [ "LEGS", "TORSO", "ARMS" ], + "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r" ], "coverage": 75, "encumbrance": 20, "warmth": 30, @@ -37,7 +37,7 @@ "symbol": "[", "looks_like": "touring_suit", "color": "pink", - "covers": [ "LEGS", "TORSO", "ARMS" ], + "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r" ], "coverage": 90, "encumbrance": 17, "max_encumbrance": 30, @@ -65,7 +65,7 @@ "symbol": "[", "looks_like": "wolfsuit", "color": "light_green", - "covers": [ "LEGS", "TORSO", "ARMS", "HANDS", "HEAD", "FEET", "MOUTH", "EYES" ], + "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r", "hand_l", "hand_r", "head", "foot_l", "foot_r", "mouth", "eyes" ], "coverage": 100, "encumbrance": 26, "max_encumbrance": 30, @@ -89,7 +89,7 @@ "symbol": "[", "looks_like": "touring_suit", "color": "yellow", - "covers": [ "LEGS", "ARMS", "TORSO" ], + "covers": [ "leg_l", "leg_r", "arm_l", "arm_r", "torso" ], "coverage": 95, "encumbrance": 1, "max_encumbrance": 2, @@ -117,7 +117,7 @@ "symbol": "[", "looks_like": "jumpsuit", "color": "yellow", - "covers": [ "LEGS", "ARMS", "TORSO" ], + "covers": [ "leg_l", "leg_r", "arm_l", "arm_r", "torso" ], "coverage": 95, "encumbrance": 1, "max_encumbrance": 2, @@ -156,7 +156,7 @@ "symbol": "[", "looks_like": "jumpsuit", "color": "yellow", - "covers": [ "LEGS", "ARMS", "TORSO" ], + "covers": [ "leg_l", "leg_r", "arm_l", "arm_r", "torso" ], "coverage": 95, "encumbrance": 3, "max_encumbrance": 7, @@ -181,7 +181,7 @@ "symbol": "[", "looks_like": "jumpsuit", "color": "light_gray", - "covers": [ "TORSO", "ARMS", "LEGS" ], + "covers": [ "torso", "arm_l", "arm_r", "leg_l", "leg_r" ], "coverage": 95, "encumbrance": 3, "warmth": 35, @@ -202,7 +202,7 @@ "symbol": "[", "looks_like": "dinosuit", "color": "light_gray", - "covers": [ "LEGS", "TORSO", "ARMS", "HANDS", "HEAD", "FEET", "MOUTH", "EYES" ], + "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r", "hand_l", "hand_r", "head", "foot_l", "foot_r", "mouth", "eyes" ], "coverage": 100, "encumbrance": 26, "max_encumbrance": 30, @@ -229,7 +229,7 @@ "symbol": "[", "looks_like": "touring_suit", "color": "dark_gray", - "covers": [ "TORSO", "HEAD", "ARMS", "LEGS", "FEET" ], + "covers": [ "torso", "head", "arm_l", "arm_r", "leg_l", "leg_r", "foot_l", "foot_r" ], "coverage": 95, "encumbrance": 20, "warmth": 50, @@ -248,7 +248,7 @@ "material": [ "lycra" ], "symbol": "[", "color": "dark_gray", - "covers": [ "HEAD", "MOUTH", "EYES", "TORSO", "ARMS", "HANDS", "LEGS", "FEET" ], + "covers": [ "head", "mouth", "eyes", "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ], "coverage": 100, "warmth": 20, "material_thickness": 1, diff --git a/data/json/items/armor/suits_protection.json b/data/json/items/armor/suits_protection.json index bbdb71035f115..ff537f7292bdb 100644 --- a/data/json/items/armor/suits_protection.json +++ b/data/json/items/armor/suits_protection.json @@ -13,7 +13,7 @@ "symbol": "[", "looks_like": "hazmat_suit", "color": "light_red", - "covers": [ "LEGS", "TORSO", "ARMS" ], + "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r" ], "coverage": 100, "encumbrance": 10, "max_encumbrance": 20, @@ -42,7 +42,7 @@ "symbol": "[", "looks_like": "hazmat_suit", "color": "light_red", - "covers": [ "HEAD", "TORSO", "ARMS", "HANDS", "LEGS", "FEET" ], + "covers": [ "head", "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ], "coverage": 100, "encumbrance": 35, "warmth": 50, @@ -66,7 +66,7 @@ "symbol": "[", "looks_like": "armor_larmor", "color": "brown", - "covers": [ "LEGS", "TORSO", "ARMS" ], + "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r" ], "coverage": 90, "encumbrance": 18, "max_encumbrance": 22, @@ -95,7 +95,7 @@ "symbol": "[", "looks_like": "armor_larmor", "color": "green", - "covers": [ "LEGS", "TORSO" ], + "covers": [ "torso", "leg_l", "leg_r" ], "coverage": 90, "encumbrance": 10, "warmth": 10, @@ -130,7 +130,7 @@ "symbol": "[", "looks_like": "armor_larmor", "color": "brown", - "covers": [ "LEGS", "TORSO", "ARMS" ], + "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r" ], "coverage": 90, "encumbrance": 21, "max_encumbrance": 25, @@ -159,7 +159,7 @@ "symbol": "[", "looks_like": "touring_suit", "color": "brown", - "covers": [ "LEGS", "TORSO" ], + "covers": [ "torso", "leg_l", "leg_r" ], "coverage": 90, "encumbrance": 12, "max_encumbrance": 20, @@ -188,7 +188,7 @@ "symbol": "[", "looks_like": "armor_larmor", "color": "light_gray", - "covers": [ "TORSO", "LEGS", "ARMS" ], + "covers": [ "torso", "leg_l", "leg_r", "arm_l", "arm_r" ], "coverage": 95, "encumbrance": 20, "warmth": 20, @@ -209,7 +209,7 @@ "symbol": "[", "looks_like": "touring_suit", "color": "light_red", - "covers": [ "TORSO", "ARMS", "LEGS" ], + "covers": [ "torso", "arm_l", "arm_r", "leg_l", "leg_r" ], "coverage": 95, "encumbrance": 10, "max_encumbrance": 20, @@ -246,7 +246,7 @@ "looks_like": "armor_nomad", "symbol": "[", "color": "light_gray", - "covers": [ "TORSO", "ARMS", "LEGS" ], + "covers": [ "torso", "arm_l", "arm_r", "leg_l", "leg_r" ], "coverage": 80, "encumbrance": 8, "max_encumbrance": 16, @@ -283,7 +283,7 @@ "material": [ "leather", "iron" ], "symbol": "[", "color": "brown", - "covers": [ "LEGS", "TORSO", "ARMS" ], + "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r" ], "looks_like": "armor_larmor", "coverage": 90, "encumbrance": 17, @@ -315,7 +315,7 @@ "symbol": "[", "looks_like": "armor_lightplate", "color": "light_gray", - "covers": [ "TORSO", "LEGS", "ARMS" ], + "covers": [ "torso", "leg_l", "leg_r", "arm_l", "arm_r" ], "coverage": 90, "encumbrance": 45, "warmth": 20, @@ -339,7 +339,7 @@ "symbol": "[", "looks_like": "kevlar", "color": "light_gray", - "covers": [ "TORSO", "LEGS", "ARMS" ], + "covers": [ "torso", "leg_l", "leg_r", "arm_l", "arm_r" ], "coverage": 85, "encumbrance": 10, "warmth": 10, @@ -361,7 +361,7 @@ "symbol": "[", "looks_like": "armor_lightplate", "color": "dark_gray", - "covers": [ "TORSO", "LEGS", "ARMS", "HANDS" ], + "covers": [ "torso", "leg_l", "leg_r", "arm_l", "arm_r", "hand_l", "hand_r" ], "coverage": 85, "encumbrance": 15, "warmth": 25, @@ -382,7 +382,7 @@ "symbol": "[", "looks_like": "armor_nomad", "color": "green", - "covers": [ "TORSO", "ARMS", "LEGS" ], + "covers": [ "torso", "arm_l", "arm_r", "leg_l", "leg_r" ], "coverage": 100, "encumbrance": 30, "pocket_data": [ @@ -416,7 +416,7 @@ "symbol": "[", "looks_like": "armor_lightplate", "color": "light_gray", - "covers": [ "TORSO", "LEGS", "ARMS" ], + "covers": [ "torso", "leg_l", "leg_r", "arm_l", "arm_r" ], "coverage": 80, "encumbrance": 18, "warmth": 20, @@ -438,7 +438,7 @@ "symbol": "[", "looks_like": "hazmat_suit", "color": "white", - "covers": [ "LEGS", "TORSO", "ARMS" ], + "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r" ], "coverage": 100, "encumbrance": 10, "max_encumbrance": 17, @@ -468,7 +468,7 @@ "symbol": "[", "looks_like": "armor_blarmor", "color": "light_red", - "covers": [ "TORSO", "ARMS", "LEGS" ], + "covers": [ "torso", "arm_l", "arm_r", "leg_l", "leg_r" ], "coverage": 95, "encumbrance": 20, "warmth": 30, @@ -490,7 +490,7 @@ "symbol": "[", "looks_like": "touring_suit", "color": "light_red", - "covers": [ "TORSO", "HEAD", "ARMS", "LEGS" ], + "covers": [ "torso", "head", "arm_l", "arm_r", "leg_l", "leg_r" ], "coverage": 95, "encumbrance": 20, "warmth": 30, @@ -511,7 +511,7 @@ "material": [ "iron", "cotton" ], "symbol": "[", "color": "light_red", - "covers": [ "TORSO", "HEAD", "ARMS", "HANDS", "LEGS", "FEET", "MOUTH", "EYES" ], + "covers": [ "torso", "head", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r", "mouth", "eyes" ], "coverage": 100, "encumbrance": 30, "material_thickness": 4, @@ -530,7 +530,7 @@ "symbol": "[", "looks_like": "jumpsuit", "color": "white", - "covers": [ "LEGS", "FEET", "HEAD", "TORSO", "ARMS" ], + "covers": [ "leg_l", "leg_r", "foot_l", "foot_r", "head", "torso", "arm_l", "arm_r" ], "coverage": 100, "encumbrance": 25, "warmth": 10, @@ -551,7 +551,7 @@ "symbol": "[", "looks_like": "jumpsuit", "color": "light_gray", - "covers": [ "HEAD", "TORSO", "ARMS", "HANDS", "LEGS", "FEET" ], + "covers": [ "head", "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ], "coverage": 100, "encumbrance": 50, "warmth": 30, @@ -575,7 +575,7 @@ "symbol": "[", "looks_like": "survivor_suit", "color": "light_gray", - "covers": [ "LEGS", "TORSO", "ARMS" ], + "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r" ], "coverage": 100, "encumbrance": 15, "max_encumbrance": 30, @@ -607,7 +607,7 @@ "symbol": "[", "looks_like": "coat_winter", "color": "light_gray", - "covers": [ "TORSO", "ARMS", "LEGS" ], + "covers": [ "torso", "arm_l", "arm_r", "leg_l", "leg_r" ], "coverage": 80, "encumbrance": 15, "warmth": 30, @@ -629,7 +629,7 @@ "symbol": "[", "looks_like": "beekeeping_suit", "color": "yellow", - "covers": [ "HEAD", "TORSO", "ARMS", "HANDS", "LEGS", "FEET" ], + "covers": [ "head", "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ], "coverage": 100, "encumbrance": 37, "warmth": 40, @@ -653,7 +653,7 @@ "symbol": "[", "looks_like": "survivor_suit", "color": "dark_gray", - "covers": [ "LEGS", "TORSO", "ARMS" ], + "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r" ], "coverage": 100, "encumbrance": 17, "max_encumbrance": 35, @@ -682,7 +682,7 @@ "symbol": "[", "looks_like": "survivor_suit", "color": "green", - "covers": [ "LEGS", "TORSO", "ARMS" ], + "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r" ], "coverage": 100, "encumbrance": 7, "max_encumbrance": 15, @@ -711,7 +711,7 @@ "symbol": "[", "looks_like": "jumpsuit", "color": "light_gray", - "covers": [ "LEGS", "TORSO", "ARMS" ], + "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r" ], "coverage": 100, "encumbrance": 6, "warmth": 5, @@ -733,7 +733,7 @@ "symbol": "[", "looks_like": "hazmat_suit", "color": "brown", - "covers": [ "HEAD", "TORSO", "ARMS", "HANDS", "LEGS", "FEET" ], + "covers": [ "head", "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ], "coverage": 100, "encumbrance": 7, "max_encumbrance": 15, @@ -785,7 +785,7 @@ "symbol": "[", "looks_like": "jumpsuit", "color": "light_gray", - "covers": [ "LEGS", "TORSO", "ARMS" ], + "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r" ], "coverage": 95, "encumbrance": 7, "max_encumbrance": 15, @@ -817,7 +817,7 @@ "symbol": "[", "looks_like": "touring_suit", "color": "brown", - "covers": [ "LEGS", "TORSO", "ARMS" ], + "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r" ], "coverage": 100, "encumbrance": 12, "max_encumbrance": 25, @@ -851,7 +851,7 @@ "symbol": "[", "looks_like": "touring_suit", "color": "dark_gray", - "armor_portion_data": [ { "covers": [ "torso", "LEGS", "ARMS" ], "coverage": 95, "encumbrance": [ 12, 25 ] } ], + "armor_portion_data": [ { "covers": [ "torso", "leg_l", "leg_r", "arm_l", "arm_r" ], "coverage": 95, "encumbrance": [ 12, 25 ] } ], "pocket_data": [ { "pocket_type": "CONTAINER", "max_contains_volume": "1 L", "max_contains_weight": "3 kg", "moves": 80 }, { "pocket_type": "CONTAINER", "max_contains_volume": "1 L", "max_contains_weight": "3 kg", "moves": 80 }, @@ -880,7 +880,7 @@ "symbol": "[", "looks_like": "jumpsuit", "color": "light_red", - "covers": [ "LEGS", "TORSO", "ARMS" ], + "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r" ], "coverage": 95, "encumbrance": 14, "max_encumbrance": 15, @@ -907,7 +907,7 @@ "symbol": "[", "looks_like": "survivor_suit", "color": "light_gray", - "covers": [ "LEGS", "TORSO", "ARMS" ], + "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r" ], "coverage": 100, "encumbrance": 18, "max_encumbrance": 37, @@ -939,7 +939,7 @@ "symbol": "[", "looks_like": "survivor_suit", "color": "brown", - "covers": [ "LEGS", "TORSO", "ARMS" ], + "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r" ], "coverage": 100, "encumbrance": 17, "max_encumbrance": 35, @@ -973,7 +973,7 @@ "symbol": "[", "looks_like": "hsurvivor_suit", "color": "dark_gray", - "covers": [ "LEGS", "TORSO", "ARMS" ], + "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r" ], "coverage": 100, "encumbrance": 22, "max_encumbrance": 45, diff --git a/data/json/items/armor/swimming.json b/data/json/items/armor/swimming.json index b6dfda73ffde4..0b47bd28fd2f7 100644 --- a/data/json/items/armor/swimming.json +++ b/data/json/items/armor/swimming.json @@ -13,7 +13,7 @@ "symbol": "[", "looks_like": "shorts", "color": "blue", - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "coverage": 35, "material_thickness": 1, "flags": [ "VARSIZE", "WATER_FRIENDLY" ] @@ -32,7 +32,7 @@ "symbol": "[", "looks_like": "wetsuit_spring", "color": "dark_gray", - "covers": [ "LEGS", "TORSO", "ARMS" ], + "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r" ], "coverage": 100, "encumbrance": 11, "max_encumbrance": 15, @@ -60,7 +60,7 @@ "symbol": "[", "looks_like": "hood_rain", "color": "dark_gray", - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 100, "encumbrance": 10, "warmth": 30, @@ -84,7 +84,7 @@ "symbol": "[", "looks_like": "wetsuit_hood", "color": "dark_gray", - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 100, "encumbrance": 25, "warmth": 15, @@ -108,7 +108,7 @@ "symbol": "[", "looks_like": "wetsuit", "color": "dark_gray", - "covers": [ "LEGS", "TORSO", "ARMS" ], + "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r" ], "coverage": 100, "encumbrance": 10, "max_encumbrance": 20, @@ -139,7 +139,7 @@ "symbol": "[", "looks_like": "gloves_rubber", "color": "dark_gray", - "covers": [ "HANDS" ], + "covers": [ "hand_l", "hand_r" ], "coverage": 100, "encumbrance": 25, "warmth": 15, @@ -161,7 +161,7 @@ "symbol": "[", "looks_like": "wetsuit", "color": "pink", - "covers": [ "TORSO", "ARMS" ], + "covers": [ "torso", "arm_l", "arm_r" ], "coverage": 90, "encumbrance": 2, "max_encumbrance": 5, @@ -190,7 +190,7 @@ "symbol": "[", "looks_like": "chainmail_hauberk", "color": "light_red", - "covers": [ "TORSO", "HEAD", "ARMS", "HANDS", "LEGS", "FEET" ], + "covers": [ "torso", "head", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ], "coverage": 100, "encumbrance": 30, "warmth": 5, @@ -211,7 +211,7 @@ "symbol": "[", "looks_like": "chainmail_suit", "color": "light_red", - "covers": [ "TORSO", "HEAD", "ARMS", "HANDS", "LEGS", "FEET" ], + "covers": [ "torso", "head", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ], "coverage": 100, "encumbrance": 30, "warmth": 5, @@ -232,7 +232,7 @@ "symbol": "[", "looks_like": "goggles_welding", "color": "light_blue", - "covers": [ "EYES" ], + "covers": [ "eyes" ], "coverage": 100, "encumbrance": 10, "warmth": 10, @@ -254,7 +254,7 @@ "symbol": "[", "looks_like": "gloves_tactical", "color": "dark_gray", - "covers": [ "HANDS" ], + "covers": [ "hand_l", "hand_r" ], "coverage": 100, "encumbrance": 10, "warmth": 30, diff --git a/data/json/items/armor/torso_armor.json b/data/json/items/armor/torso_armor.json index bb84550b34029..30b16b94751de 100644 --- a/data/json/items/armor/torso_armor.json +++ b/data/json/items/armor/torso_armor.json @@ -15,7 +15,7 @@ "symbol": "[", "looks_like": "cuirass_lightplate", "color": "yellow", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 90, "encumbrance": 15, "warmth": 15, @@ -36,7 +36,7 @@ "looks_like": "vest_leather", "copy-from": "armor_chitin", "color": "brown", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 80, "encumbrance": 20, "warmth": 20, @@ -58,7 +58,7 @@ "symbol": "[", "looks_like": "armor_lamellar", "color": "light_gray", - "covers": [ "TORSO", "ARMS" ], + "covers": [ "torso", "arm_l", "arm_r" ], "coverage": 90, "encumbrance": 15, "warmth": 15, @@ -80,7 +80,7 @@ "symbol": "O", "looks_like": "armor_scrapsuit", "color": "light_gray", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 80, "encumbrance": 20, "warmth": 10, @@ -102,7 +102,7 @@ "symbol": "[", "looks_like": "vest_leather", "color": "light_red", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 95, "encumbrance": 20, "material_thickness": 4, @@ -124,7 +124,7 @@ "symbol": "H", "looks_like": "cuirass_lightplate", "color": "dark_gray", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 90, "encumbrance": 20, "warmth": 20, @@ -147,7 +147,7 @@ "symbol": "[", "looks_like": "chestguard_hard", "color": "light_gray", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 95, "encumbrance": 20, "warmth": 20, @@ -171,7 +171,7 @@ "symbol": "[", "looks_like": "cuirass_lightplate", "color": "light_gray", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 80, "encumbrance": 18, "warmth": 20, @@ -192,7 +192,7 @@ "symbol": "[", "looks_like": "coat_lab", "color": "white", - "covers": [ "TORSO", "ARMS" ], + "covers": [ "torso", "arm_l", "arm_r" ], "coverage": 100, "encumbrance": 5, "warmth": 25, @@ -214,7 +214,7 @@ "symbol": "[", "looks_like": "jacket_leather", "color": "dark_gray", - "covers": [ "TORSO", "ARMS" ], + "covers": [ "torso", "arm_l", "arm_r" ], "coverage": 85, "encumbrance": 20, "max_encumbrance": 24, @@ -250,7 +250,7 @@ "material": [ "cotton", "budget_steel" ], "symbol": "[", "color": "light_gray", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 100, "encumbrance": 8, "warmth": 10, @@ -270,7 +270,7 @@ "material": [ "cotton", "budget_steel" ], "symbol": "[", "color": "light_gray", - "covers": [ "TORSO", "ARMS" ], + "covers": [ "torso", "arm_l", "arm_r" ], "coverage": 100, "encumbrance": 8, "warmth": 10, @@ -292,7 +292,7 @@ "symbol": "[", "looks_like": "chestguard_hard", "color": "light_gray", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 45, "encumbrance": 35, "warmth": 10, @@ -316,7 +316,7 @@ "symbol": "[", "looks_like": "vest_leather", "color": "light_gray", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 85, "encumbrance": 5, "warmth": 15, @@ -337,7 +337,7 @@ "symbol": "[", "looks_like": "lsurvivor_suit", "color": "green", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 95, "encumbrance": 8, "max_encumbrance": 16, @@ -369,7 +369,7 @@ "symbol": "[", "looks_like": "jacket_leather", "color": "dark_gray", - "covers": [ "TORSO", "ARMS" ], + "covers": [ "torso", "arm_l", "arm_r" ], "coverage": 95, "encumbrance": 28, "max_encumbrance": 30, @@ -395,7 +395,7 @@ "material": [ "cotton" ], "symbol": "[", "color": "white", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 65, "warmth": 5, "material_thickness": 3, @@ -413,7 +413,7 @@ "material": [ "plastic" ], "symbol": "[", "color": "white", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 35, "encumbrance": 2, "warmth": 5, @@ -434,7 +434,7 @@ "symbol": "[", "looks_like": "vest_leather", "color": "dark_gray", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 90, "encumbrance": 17, "max_encumbrance": 24, @@ -458,7 +458,7 @@ "weight": "16300 g", "volume": "15 L", "price": 200000, - "covers": [ "TORSO", "ARMS" ], + "covers": [ "torso", "arm_l", "arm_r" ], "coverage": 100, "encumbrance": 80, "warmth": 65, @@ -478,7 +478,7 @@ "weight": "7000 g", "volume": "15 L", "price": 200000, - "covers": [ "TORSO", "ARMS" ], + "covers": [ "torso", "arm_l", "arm_r" ], "coverage": 100, "encumbrance": 40, "warmth": 40, diff --git a/data/json/items/armor/torso_clothes.json b/data/json/items/armor/torso_clothes.json index e3f4ca38991a5..99b4b72bd5eea 100644 --- a/data/json/items/armor/torso_clothes.json +++ b/data/json/items/armor/torso_clothes.json @@ -13,7 +13,7 @@ "symbol": "[", "looks_like": "vest_leather", "color": "brown", - "covers": [ "TORSO", "LEGS" ], + "covers": [ "torso", "leg_l", "leg_r" ], "coverage": 70, "encumbrance": 2, "max_encumbrance": 5, @@ -48,7 +48,7 @@ "symbol": "[", "looks_like": "jacket_light", "color": "dark_gray", - "covers": [ "TORSO", "ARMS" ], + "covers": [ "torso", "arm_l", "arm_r" ], "coverage": 85, "encumbrance": 16, "max_encumbrance": 20, @@ -78,7 +78,7 @@ "symbol": "[", "looks_like": "robe", "color": "pink", - "covers": [ "LEGS", "TORSO" ], + "covers": [ "torso", "leg_l", "leg_r" ], "coverage": 85, "encumbrance": 7, "warmth": 15, @@ -99,7 +99,7 @@ "symbol": "[", "looks_like": "longshirt", "color": "white", - "covers": [ "TORSO", "ARMS" ], + "covers": [ "torso", "arm_l", "arm_r" ], "coverage": 90, "encumbrance": 4, "max_encumbrance": 5, @@ -122,7 +122,7 @@ "symbol": "[", "looks_like": "dress", "color": "white", - "covers": [ "LEGS", "TORSO" ], + "covers": [ "torso", "leg_l", "leg_r" ], "coverage": 90, "encumbrance": 45, "warmth": 30, @@ -143,7 +143,7 @@ "symbol": "[", "looks_like": "tshirt", "color": "light_red", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 90, "warmth": 10, "material_thickness": 1, @@ -164,7 +164,7 @@ "symbol": "[", "looks_like": "vest_leather", "color": "yellow", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 40, "encumbrance": 40, "warmth": 5, @@ -186,7 +186,7 @@ "symbol": "[", "looks_like": "vest_leather", "color": "brown", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 40, "encumbrance": 50, "warmth": 5, @@ -207,7 +207,7 @@ "symbol": "[", "looks_like": "dress", "color": "dark_gray", - "covers": [ "TORSO", "LEGS" ], + "covers": [ "torso", "leg_l", "leg_r" ], "coverage": 75, "encumbrance": 14, "warmth": 5, @@ -229,7 +229,7 @@ "symbol": "[", "looks_like": "tank_top", "color": "pink", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 25, "warmth": 2, "material_thickness": 1, @@ -248,7 +248,7 @@ "symbol": "[", "looks_like": "sweater", "color": "dark_gray", - "covers": [ "TORSO", "ARMS" ], + "covers": [ "torso", "arm_l", "arm_r" ], "coverage": 95, "encumbrance": 6, "max_encumbrance": 12, @@ -276,7 +276,7 @@ "symbol": "[", "looks_like": "tshirt", "color": "yellow", - "covers": [ "TORSO", "ARMS" ], + "covers": [ "torso", "arm_l", "arm_r" ], "coverage": 90, "encumbrance": 7, "warmth": 25, @@ -341,7 +341,7 @@ "material": [ "lycra" ], "symbol": "[", "color": "dark_gray", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 55, "warmth": 5, "material_thickness": 1, @@ -361,7 +361,7 @@ "symbol": "[", "looks_like": "tshirt", "color": "dark_gray", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 90, "encumbrance": 5, "warmth": 5, @@ -415,7 +415,7 @@ "symbol": "[", "looks_like": "dress_shirt", "color": "blue", - "covers": [ "TORSO", "ARMS" ], + "covers": [ "torso", "arm_l", "arm_r" ], "coverage": 90, "encumbrance": 3, "warmth": 5, @@ -436,7 +436,7 @@ "symbol": "[", "looks_like": "dress", "color": "blue", - "covers": [ "TORSO", "ARMS", "LEGS" ], + "covers": [ "torso", "arm_l", "arm_r", "leg_l", "leg_r" ], "coverage": 75, "encumbrance": 5, "max_encumbrance": 7, @@ -461,7 +461,7 @@ "symbol": "[", "looks_like": "tshirt", "color": "light_red", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 90, "encumbrance": 7, "warmth": 15, @@ -482,7 +482,7 @@ "symbol": "[", "looks_like": "polo_shirt", "color": "light_blue", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 90, "pocket_data": [ { "pocket_type": "CONTAINER", "max_contains_volume": "500 ml", "max_contains_weight": "1 kg", "moves": 80 }, @@ -506,7 +506,7 @@ "symbol": "[", "looks_like": "dress_shirt", "color": "light_gray", - "covers": [ "TORSO", "ARMS" ], + "covers": [ "torso", "arm_l", "arm_r" ], "coverage": 90, "encumbrance": 3, "max_encumbrance": 5, @@ -529,7 +529,7 @@ "symbol": "[", "looks_like": "longshirt", "color": "white", - "covers": [ "TORSO", "ARMS" ], + "covers": [ "torso", "arm_l", "arm_r" ], "coverage": 90, "encumbrance": 5, "warmth": 5, @@ -550,7 +550,7 @@ "symbol": "[", "looks_like": "dress", "color": "yellow", - "covers": [ "LEGS", "TORSO" ], + "covers": [ "torso", "leg_l", "leg_r" ], "coverage": 65, "material_thickness": 1, "flags": [ "VARSIZE", "FANCY" ] @@ -568,7 +568,7 @@ "symbol": "[", "looks_like": "longshirt", "color": "blue", - "covers": [ "TORSO", "ARMS" ], + "covers": [ "torso", "arm_l", "arm_r" ], "coverage": 95, "encumbrance": 10, "warmth": 40, @@ -590,7 +590,7 @@ "symbol": "[", "looks_like": "longshirt", "color": "light_red", - "covers": [ "TORSO", "ARMS" ], + "covers": [ "torso", "arm_l", "arm_r" ], "coverage": 95, "encumbrance": 10, "warmth": 30, @@ -612,7 +612,7 @@ "symbol": "[", "looks_like": "polo_shirt", "color": "light_gray", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 40, "encumbrance": 4, "max_encumbrance": 5, @@ -639,7 +639,7 @@ "symbol": "[", "looks_like": "camisole", "color": "white", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 90, "warmth": 5, "material_thickness": 1, @@ -659,7 +659,7 @@ "symbol": "[", "looks_like": "tshirt", "color": "white", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 90, "warmth": 5, "material_thickness": 1, @@ -731,7 +731,7 @@ "symbol": "[", "looks_like": "vest", "color": "brown", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 90, "encumbrance": 4, "max_encumbrance": 8, @@ -760,7 +760,7 @@ "symbol": "[", "looks_like": "hoodie", "color": "dark_gray", - "covers": [ "TORSO", "ARMS" ], + "covers": [ "torso", "arm_l", "arm_r" ], "coverage": 95, "encumbrance": 6, "max_encumbrance": 12, diff --git a/data/json/items/armor/undergarment.json b/data/json/items/armor/undergarment.json index b93bfb79669b9..7dfb15d99205f 100644 --- a/data/json/items/armor/undergarment.json +++ b/data/json/items/armor/undergarment.json @@ -12,7 +12,7 @@ "symbol": "[", "looks_like": "armguard_larmor", "color": "light_gray", - "covers": [ "ARMS" ], + "covers": [ "arm_l", "arm_r" ], "coverage": 80, "encumbrance": 1, "warmth": 20, @@ -32,7 +32,7 @@ "symbol": "[", "looks_like": "tank_top", "color": "green", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 60, "material_thickness": 1, "flags": [ "VARSIZE", "WATER_FRIENDLY", "SKINTIGHT" ] @@ -50,7 +50,7 @@ "symbol": "[", "looks_like": "panties", "color": "light_red", - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "coverage": 15, "warmth": 5, "material_thickness": 1, @@ -69,7 +69,7 @@ "symbol": "[", "looks_like": "bra", "color": "light_red", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 10, "material_thickness": 1, "flags": [ "VARSIZE", "WATER_FRIENDLY", "SKINTIGHT" ] @@ -87,7 +87,7 @@ "symbol": "[", "looks_like": "bikini_top", "color": "brown", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 10, "warmth": 10, "material_thickness": 1, @@ -106,7 +106,7 @@ "symbol": "[", "looks_like": "bikini_top", "color": "dark_gray", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 10, "warmth": 5, "material_thickness": 1, @@ -125,7 +125,7 @@ "symbol": "[", "looks_like": "shorts", "color": "light_gray", - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "coverage": 20, "warmth": 5, "material_thickness": 1, @@ -154,7 +154,7 @@ "symbol": "[", "looks_like": "boxer_briefs", "color": "light_gray", - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "coverage": 25, "warmth": 5, "material_thickness": 1, @@ -183,7 +183,7 @@ "symbol": "[", "looks_like": "boxer_briefs", "color": "light_gray", - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "coverage": 25, "warmth": 5, "material_thickness": 1, @@ -212,7 +212,7 @@ "symbol": "[", "looks_like": "tank_top", "color": "white", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 15, "warmth": 5, "material_thickness": 1, @@ -231,7 +231,7 @@ "symbol": "[", "looks_like": "boxer_briefs", "color": "white", - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "coverage": 15, "warmth": 5, "material_thickness": 1, @@ -251,7 +251,7 @@ "symbol": "[", "looks_like": "tank_top", "color": "light_blue", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 45, "material_thickness": 1, "flags": [ "VARSIZE", "SKINTIGHT" ] @@ -269,7 +269,7 @@ "symbol": "[", "looks_like": "tshirt", "color": "brown", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 25, "warmth": 5, "material_thickness": 1, @@ -288,7 +288,7 @@ "symbol": "[", "looks_like": "chestwrap_leather", "color": "brown", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 25, "encumbrance": 5, "warmth": 20, @@ -308,7 +308,7 @@ "symbol": "[", "looks_like": "chestwrap", "color": "brown", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 25, "encumbrance": 5, "warmth": 10, @@ -328,7 +328,7 @@ "symbol": "[", "looks_like": "chestwrap", "color": "blue", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 25, "encumbrance": 5, "warmth": 15, @@ -349,7 +349,7 @@ "symbol": "[", "looks_like": "vest_leather", "color": "dark_gray", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 75, "encumbrance": 15, "warmth": 25, @@ -370,7 +370,7 @@ "symbol": "[", "looks_like": "leggings", "color": "light_gray", - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "coverage": 60, "encumbrance": 1, "warmth": 20, @@ -390,7 +390,7 @@ "symbol": "[", "looks_like": "leg_warmers", "color": "brown", - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "coverage": 60, "encumbrance": 3, "warmth": 40, @@ -410,7 +410,7 @@ "symbol": "[", "looks_like": "leg_warmers", "color": "light_gray", - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "coverage": 60, "encumbrance": 7, "warmth": 20, @@ -430,7 +430,7 @@ "symbol": "[", "looks_like": "leggings", "color": "light_gray", - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "coverage": 95, "encumbrance": 3, "warmth": 30, @@ -450,7 +450,7 @@ "symbol": "[", "looks_like": "longshirt", "color": "light_gray", - "covers": [ "TORSO", "ARMS" ], + "covers": [ "torso", "arm_l", "arm_r" ], "coverage": 95, "encumbrance": 3, "warmth": 30, @@ -470,7 +470,7 @@ "symbol": "[", "looks_like": "long_undertop", "color": "light_gray", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 95, "encumbrance": 3, "warmth": 30, @@ -490,7 +490,7 @@ "symbol": "[", "looks_like": "briefs", "color": "white", - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "coverage": 15, "warmth": 5, "material_thickness": 1, @@ -508,7 +508,7 @@ "material": [ "lycra" ], "symbol": "[", "color": "dark_gray", - "covers": [ "TORSO", "ARMS" ], + "covers": [ "torso", "arm_l", "arm_r" ], "coverage": 95, "warmth": 20, "material_thickness": 1, @@ -527,7 +527,7 @@ "symbol": "[", "looks_like": "bra", "color": "white", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 30, "warmth": 5, "material_thickness": 1, @@ -556,7 +556,7 @@ "symbol": "[", "looks_like": "tshirt", "color": "light_gray", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 40, "material_thickness": 1, "flags": [ "VARSIZE", "WATER_FRIENDLY", "SKINTIGHT" ] @@ -575,7 +575,7 @@ "symbol": "[", "looks_like": "leggings", "color": "dark_gray", - "covers": [ "FEET", "LEGS" ], + "covers": [ "foot_l", "foot_r", "leg_r", "leg_l" ], "coverage": 100, "warmth": 10, "material_thickness": 1, @@ -594,7 +594,7 @@ "symbol": "[", "looks_like": "longshirt", "color": "dark_gray", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 95, "warmth": 20, "material_thickness": 1, @@ -613,7 +613,7 @@ "symbol": "[", "looks_like": "shorts", "color": "dark_gray", - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "coverage": 45, "warmth": 20, "material_thickness": 1, @@ -632,7 +632,7 @@ "symbol": "[", "looks_like": "tshirt", "color": "white", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 60, "warmth": 10, "material_thickness": 1, @@ -650,7 +650,7 @@ "material": [ "lycra" ], "symbol": "[", "color": "dark_gray", - "covers": [ "TORSO", "LEGS" ], + "covers": [ "torso", "leg_l", "leg_r" ], "coverage": 90, "warmth": 20, "material_thickness": 1, diff --git a/data/json/items/chemicals_and_resources.json b/data/json/items/chemicals_and_resources.json index d45d49e308d70..6f0152e954cf3 100644 --- a/data/json/items/chemicals_and_resources.json +++ b/data/json/items/chemicals_and_resources.json @@ -383,71 +383,6 @@ "freezing_point": 28, "fun": -1 }, - { - "type": "COMESTIBLE", - "id": "water_acid", - "name": { "str_sp": "acid water" }, - "weight": "260 g", - "color": "light_green", - "flags": [ "ACID" ], - "use_action": [ "BLECH" ], - "container": "jug_plastic", - "comestible_type": "DRINK", - "symbol": "~", - "quench": -56, - "healthy": -2, - "description": "Water collected during an acid rainstorm. Don't drink it. Boiling it concentrates the acid.", - "price": 0, - "price_postapoc": 0, - "volume": "250 ml", - "phase": "liquid", - "category": "chems", - "fun": -30 - }, - { - "type": "COMESTIBLE", - "id": "water_acid_weak", - "name": { "str_sp": "weak acid water" }, - "weight": "255 g", - "color": "light_green", - "flags": [ "ACID" ], - "use_action": [ "BLECH" ], - "container": "jug_plastic", - "comestible_type": "DRINK", - "symbol": "~", - "quench": -28, - "healthy": -1, - "description": "A mixture of rain and acid rain. Don't drink it. Boiling it concentrates the acid.", - "price": 0, - "price_postapoc": 0, - "volume": "250 ml", - "phase": "liquid", - "category": "chems", - "fun": -15 - }, - { - "type": "COMESTIBLE", - "id": "acid", - "name": { "str_sp": "concentrated acid" }, - "weight": "250 g", - "color": "green", - "flags": [ "ACID", "DROP_ACTION_ONLY_IF_LIQUID" ], - "use_action": [ "BLECH" ], - "container": "jug_plastic", - "comestible_type": "DRINK", - "symbol": "~", - "quench": -96, - "healthy": -4, - "description": "Concentrated acid. Don't drink it.", - "price": 2000, - "price_postapoc": 50, - "volume": "250 ml", - "phase": "liquid", - "category": "chems", - "fun": -45, - "freezing_point": 25, - "drop_action": { "type": "emit_actor", "emits": [ "emit_acid_splash" ], "scale_qty": true } - }, { "type": "COMESTIBLE", "id": "sewage", diff --git a/data/json/items/classes/gun.json b/data/json/items/classes/gun.json index 283b85699b02e..e0b390bb23592 100644 --- a/data/json/items/classes/gun.json +++ b/data/json/items/classes/gun.json @@ -53,6 +53,26 @@ [ "underbarrel", 1 ] ] }, + { + "abstract": "pistol_classic", + "copy-from": "pistol_base", + "type": "GUN", + "name": { "str": "classic pistol" }, + "//": "usually pre-1990's pistols that lack underbarrel rails, and sight mounting locations.", + "valid_mod_locations": [ + [ "accessories", 2 ], + [ "barrel", 1 ], + [ "bore", 1 ], + [ "brass catcher", 1 ], + [ "grip", 1 ], + [ "mechanism", 4 ], + [ "magazine", 1 ], + [ "muzzle", 1 ], + [ "sights mount", 1 ], + [ "stock", 1 ], + [ "underbarrel mount", 1 ] + ] + }, { "abstract": "pistol_backup", "copy-from": "pistol_base", diff --git a/data/json/items/classes/magazine.json b/data/json/items/classes/magazine.json index 9db3aec4b4e43..f21f6fa9f684d 100644 --- a/data/json/items/classes/magazine.json +++ b/data/json/items/classes/magazine.json @@ -10,7 +10,7 @@ "material": [ "steel" ], "symbol": "#", "color": "light_gray", - "armor_data": { "covers": [ "TORSO" ], "coverage": 5 }, + "armor_data": { "covers": [ "torso" ], "coverage": 5 }, "flags": [ "MAG_BELT", "MAG_DESTROY", "BELTED", "OVERSIZE", "WATER_FRIENDLY" ] } ] diff --git a/data/json/items/containers.json b/data/json/items/containers.json index 3fcad6edce7bc..2698d5652a1c4 100644 --- a/data/json/items/containers.json +++ b/data/json/items/containers.json @@ -25,7 +25,7 @@ "max_contains_weight": "5 kg" } ], - "armor_data": { "covers": [ "TORSO" ], "coverage": 10, "encumbrance": 4, "material_thickness": 2 }, + "armor_data": { "covers": [ "torso" ], "coverage": 10, "encumbrance": 4, "material_thickness": 2 }, "flags": [ "WAIST", "OVERSIZE", "WATER_FRIENDLY" ] }, { @@ -540,7 +540,7 @@ "max_contains_weight": "20 kg" } ], - "armor_data": { "covers": [ "TORSO" ], "coverage": 15, "material_thickness": 1 }, + "armor_data": { "covers": [ "torso" ], "coverage": 15, "material_thickness": 1 }, "flags": [ "BELTED" ] }, { @@ -694,7 +694,7 @@ "max_contains_weight": "3 kg" } ], - "armor_data": { "covers": [ "LEG_EITHER" ], "coverage": 5, "encumbrance": 2, "material_thickness": 2 }, + "armor_data": { "covers": [ "leg_l", "leg_r" ], "sided": true, "coverage": 5, "encumbrance": 2, "material_thickness": 2 }, "flags": [ "WAIST", "OVERSIZE", "WATER_FRIENDLY" ] }, { @@ -993,7 +993,7 @@ "max_contains_weight": "1 kg" } ], - "armor_data": { "covers": [ "LEG_EITHER" ], "coverage": 2, "material_thickness": 1 }, + "armor_data": { "covers": [ "leg_l", "leg_r" ], "sided": true, "coverage": 2, "material_thickness": 1 }, "qualities": [ [ "BOIL", 1 ] ], "flags": [ "WAIST", "OVERSIZE", "WATER_FRIENDLY" ] }, @@ -1317,7 +1317,7 @@ "max_contains_weight": "3 kg" } ], - "armor_data": { "covers": [ "TORSO" ], "coverage": 5, "encumbrance": 5, "material_thickness": 2 }, + "armor_data": { "covers": [ "torso" ], "coverage": 5, "encumbrance": 5, "material_thickness": 2 }, "flags": [ "WAIST", "WATER_FRIENDLY" ] }, { @@ -1370,7 +1370,7 @@ "max_contains_weight": "3 kg" } ], - "armor_data": { "covers": [ "LEG_EITHER" ], "coverage": 5, "material_thickness": 2 }, + "armor_data": { "covers": [ "leg_l", "leg_r" ], "sided": true, "coverage": 5, "material_thickness": 2 }, "flags": [ "WAIST", "WATER_FRIENDLY" ] }, { @@ -1398,7 +1398,7 @@ "max_contains_weight": "6 kg" } ], - "armor_data": { "covers": [ "TORSO" ], "coverage": 10, "material_thickness": 2 }, + "armor_data": { "covers": [ "torso" ], "coverage": 10, "material_thickness": 2 }, "flags": [ "WAIST", "WATER_FRIENDLY" ] }, { @@ -1426,7 +1426,7 @@ "max_contains_weight": "10 kg" } ], - "armor_data": { "covers": [ "TORSO" ], "coverage": 15, "material_thickness": 2 }, + "armor_data": { "covers": [ "torso" ], "coverage": 15, "material_thickness": 2 }, "flags": [ "BELTED", "WATER_FRIENDLY" ] }, { diff --git a/data/json/items/generic/bedding.json b/data/json/items/generic/bedding.json index d92aa43526505..496ea29e4c3b4 100644 --- a/data/json/items/generic/bedding.json +++ b/data/json/items/generic/bedding.json @@ -13,7 +13,7 @@ "symbol": "[", "looks_like": "blanket", "color": "white", - "covers": [ "TORSO", "ARMS", "HANDS", "LEGS", "FEET" ], + "covers": [ "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ], "coverage": 100, "encumbrance": 15, "warmth": 10, @@ -34,7 +34,7 @@ "symbol": "[", "looks_like": "towel", "color": "blue", - "covers": [ "TORSO", "ARMS", "HANDS", "LEGS", "FEET" ], + "covers": [ "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ], "coverage": 100, "encumbrance": 35, "warmth": 50, @@ -56,7 +56,7 @@ "symbol": "[", "looks_like": "blanket", "color": "blue", - "covers": [ "TORSO", "ARMS", "HANDS", "LEGS", "FEET" ], + "covers": [ "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ], "coverage": 100, "encumbrance": 45, "warmth": 70, @@ -78,7 +78,7 @@ "symbol": "[", "looks_like": "blanket", "color": "brown", - "covers": [ "TORSO", "ARMS", "HANDS", "LEGS", "FEET" ], + "covers": [ "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ], "coverage": 100, "encumbrance": 55, "warmth": 80, @@ -100,7 +100,7 @@ "symbol": "[", "looks_like": "blanket", "color": "light_red", - "covers": [ "TORSO", "HEAD", "MOUTH", "ARMS", "HANDS", "LEGS", "FEET" ], + "covers": [ "torso", "head", "mouth", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ], "coverage": 100, "encumbrance": 80, "warmth": 80, diff --git a/data/json/items/generic/dining_kitchen.json b/data/json/items/generic/dining_kitchen.json index feb8409db3010..8fa5665d2c6fb 100644 --- a/data/json/items/generic/dining_kitchen.json +++ b/data/json/items/generic/dining_kitchen.json @@ -369,9 +369,9 @@ "id": "bowl_plastic", "type": "GENERIC", "category": "other", - "name": { "str": "plastic bowl" }, + "name": { "str": "plastic tupperware" }, "symbol": "u", - "description": "A plastic bowl with a convenient sealing lid. Holds 750 ml of liquid.", + "description": "A piece of plastic tupperware with a tupperware lid. Holds 750 ml of liquid.", "copy-from": "base_plastic_dish", "volume": "787 ml", "pocket_data": [ diff --git a/data/json/items/generic/string.json b/data/json/items/generic/string.json index 06daccb1b7162..ff8f010dbb6c5 100644 --- a/data/json/items/generic/string.json +++ b/data/json/items/generic/string.json @@ -46,7 +46,7 @@ "type": "GENERIC", "name": { "str": "short rope" }, "description": "A 6-foot (or about 180 cm) long piece of rope. Too small to be of much use.", - "armor_data": { "covers": [ "TORSO" ], "coverage": 5, "encumbrance": 3, "material_thickness": 2 }, + "armor_data": { "covers": [ "torso" ], "coverage": 5, "encumbrance": 3, "material_thickness": 2 }, "proportional": { "weight": 6, "volume": 6, "price": 6 }, "extend": { "flags": [ "TIE_UP", "BELTED", "WATER_FRIENDLY", "OVERSIZE" ] } }, @@ -56,7 +56,7 @@ "type": "GENERIC", "name": { "str": "long rope" }, "description": "A 30-foot (or about 9 m) long rope. Useful for keeping yourself safe from falls.", - "armor_data": { "covers": [ "TORSO" ], "coverage": 10, "encumbrance": 12, "material_thickness": 6 }, + "armor_data": { "covers": [ "torso" ], "coverage": 10, "encumbrance": 12, "material_thickness": 6 }, "qualities": [ [ "ROPE", 2 ] ], "proportional": { "weight": 5, "volume": 5, "price": 5 } }, diff --git a/data/json/items/gun/10mm.json b/data/json/items/gun/10mm.json new file mode 100644 index 0000000000000..a419f60ec4b02 --- /dev/null +++ b/data/json/items/gun/10mm.json @@ -0,0 +1,315 @@ +[ + { + "id": "sw_610", + "copy-from": "pistol_revolver", + "looks_like": "sw_619", + "type": "GUN", + "name": { "str_sp": "S&W 610" }, + "description": "The Smith and Wesson 610 is a classic six-shooter revolver chambered for 10mm rounds, or for S&W's own .40 round.", + "weight": "1420 g", + "volume": "754 ml", + "price": 74000, + "price_postapoc": 2250, + "to_hit": -2, + "bashing": 10, + "material": [ "steel", "wood" ], + "symbol": "(", + "color": "dark_gray", + "ammo": [ "10mm", "40" ], + "ranged_damage": { "damage_type": "bullet", "amount": -7 }, + "dispersion": 320, + "durability": 8, + "blackpowder_tolerance": 56, + "clip_size": 6, + "pocket_data": [ { "pocket_type": "MAGAZINE", "holster": true, "ammo_restriction": { "10mm": 6, "40": 6 } } ] + }, + { + "id": "glock_29", + "copy-from": "pistol_base", + "looks_like": "glock_19", + "type": "GUN", + "name": { "str": "Glock 29" }, + "description": "A modestly sized version of the highly successful Glock, chambered in hard-hitting 10mm Auto. It is easy to carry because of its small size, but also recoils fiercely.", + "weight": "690 g", + "volume": "410 ml", + "longest_side": "177 mm", + "price": 60500, + "price_postapoc": 2500, + "to_hit": -2, + "bashing": 6, + "material": [ "plastic", "steel" ], + "symbol": "(", + "color": "dark_gray", + "ammo": "10mm", + "ranged_damage": { "damage_type": "bullet", "amount": -7 }, + "dispersion": 510, + "durability": 8, + "blackpowder_tolerance": 48, + "min_cycle_recoil": 380, + "pocket_data": [ + { + "magazine_well": "99 ml", + "pocket_type": "MAGAZINE_WELL", + "holster": true, + "max_contains_volume": "20 L", + "max_contains_weight": "20 kg", + "item_restriction": [ "glock_29mag", "glock_20mag", "tdi_10mm_mag" ] + } + ] + }, + { + "id": "glock_20", + "copy-from": "pistol_base", + "looks_like": "glock_17", + "type": "GUN", + "name": { "str": "Glock 20" }, + "description": "A full-sized version of the highly successful Glock, chambered in hard-hitting 10mm Auto. The third model of Glock designed, all other full-sized, large framed Glocks are adaptations of this one.", + "weight": "780 g", + "volume": "480 ml", + "longest_side": "205 mm", + "price": 59200, + "price_postapoc": 2500, + "to_hit": -2, + "bashing": 8, + "material": [ "plastic", "steel" ], + "symbol": "(", + "color": "dark_gray", + "ammo": "10mm", + "ranged_damage": { "damage_type": "bullet", "amount": -6 }, + "dispersion": 480, + "durability": 8, + "blackpowder_tolerance": 48, + "min_cycle_recoil": 380, + "pocket_data": [ + { + "magazine_well": "103 ml", + "pocket_type": "MAGAZINE_WELL", + "holster": true, + "max_contains_volume": "20 L", + "max_contains_weight": "20 kg", + "item_restriction": [ "glock_20mag", "tdi_10mm_mag" ] + } + ] + }, + { + "id": "glock_40", + "copy-from": "pistol_base", + "looks_like": "glock_17", + "type": "GUN", + "name": { "str": "Glock 40 MOS" }, + "description": "A full-sized, long-slide version of the highly successful Glock, chambered in hard-hitting 10mm Auto. The extra barrel length makes for slightly even harder hitting ammo, and the extra slide length means the sights are a little easier to use. It also features Glock's Modular Optic System, making aftermarket optics much easier to mount.", + "weight": "915 g", + "volume": "528 ml", + "longest_side": "241 mm", + "price": 59200, + "price_postapoc": 2500, + "to_hit": -2, + "bashing": 8, + "material": [ "plastic", "steel" ], + "symbol": "(", + "color": "dark_gray", + "ammo": "10mm", + "ranged_damage": { "damage_type": "bullet", "amount": -4 }, + "dispersion": 440, + "sight_dispersion": 440, + "durability": 8, + "blackpowder_tolerance": 48, + "min_cycle_recoil": 380, + "pocket_data": [ + { + "magazine_well": "103 ml", + "pocket_type": "MAGAZINE_WELL", + "holster": true, + "max_contains_volume": "20 L", + "max_contains_weight": "20 kg", + "item_restriction": [ "glock_20mag", "tdi_10mm_mag" ] + } + ] + }, + { + "id": "hk_mp5_10_semi", + "copy-from": "hk_mp5_semi_pistol", + "looks_like": "hk_mp5", + "type": "GUN", + "name": { "str": "BA10" }, + "description": "The MP5/10 served the FBI briefly alongside their 10mm Auto pistols, adding to the caliber's overall mystique. Though the guns' usage was shortlived, a handful of clones were made and sold occasionally. This semi-automatic clone manufactured by Brethren Arms features a welded on M1913 rail and a collapsible arm brace.", + "weight": "2667 g", + "volume": "2411 ml", + "longest_side": "498 mm", + "price": 360000, + "price_postapoc": 2300, + "durability": 7, + "ammo": "10mm", + "skill": "rifle", + "ranged_damage": { "damage_type": "bullet", "amount": -1 }, + "built_in_mods": [ "folding_stock" ], + "modes": [ [ "DEFAULT", "semi-auto", 1 ] ], + "pocket_data": [ + { + "pocket_type": "MAGAZINE_WELL", + "magazine_well": "62 ml", + "holster": true, + "max_contains_volume": "20 L", + "max_contains_weight": "20 kg", + "item_restriction": [ "mp5_10_mag" ] + } + ] + }, + { + "id": "m1911_10", + "copy-from": "pistol_classic", + "looks_like": "m1911", + "type": "GUN", + "name": { "str": "Colt Delta Elite" }, + "description": "A modernized, match-grade variant of the venerable M1911 chambered in hard-hitting 10mm Auto. Early variants were known to crack frames; modern 1911's, like this one, are slotted to prevent such crack formation.", + "weight": "1077 g", + "volume": "413 ml", + "longest_side": "210 mm", + "price": 105000, + "price_postapoc": 2750, + "to_hit": -2, + "bashing": 12, + "material": [ "steel" ], + "symbol": "(", + "color": "light_gray", + "ammo": "10mm", + "ranged_damage": { "damage_type": "bullet", "amount": -5 }, + "dispersion": 480, + "built_in_mods": [ "match_trigger" ], + "durability": 6, + "min_cycle_recoil": 540, + "blackpowder_tolerance": 48, + "pocket_data": [ + { + "magazine_well": "60 ml", + "pocket_type": "MAGAZINE_WELL", + "holster": true, + "max_contains_volume": "20 L", + "max_contains_weight": "20 kg", + "item_restriction": [ "m1911_10mag" ] + } + ] + }, + { + "id": "witness_10", + "copy-from": "pistol_classic", + "looks_like": "cz75", + "type": "GUN", + "name": { "str": "EAA Witness 10mm" }, + "description": "The EAA Witness is a modified variant of the CZ-75, produced in Italy by Tanfoglio. This is the standard steel framed version chambered in 10mm Auto.", + "weight": "936 g", + "volume": "459 ml", + "longest_side": "203 mm", + "price": 64900, + "price_postapoc": 2500, + "to_hit": -2, + "bashing": 8, + "material": [ "steel" ], + "color": "dark_gray", + "ammo": "10mm", + "ranged_damage": { "damage_type": "bullet", "amount": -6 }, + "dispersion": 480, + "durability": 7, + "pocket_data": [ + { + "magazine_well": "84 ml", + "pocket_type": "MAGAZINE_WELL", + "holster": true, + "max_contains_volume": "20 L", + "max_contains_weight": "20 kg", + "item_restriction": [ "witness_mag_10" ] + } + ] + }, + { + "id": "p220_10", + "copy-from": "pistol_base", + "looks_like": "p226_357sig", + "type": "GUN", + "name": { "str": "SIG P220 10mm" }, + "description": "The Sig Sauer P220 was developed for the Swiss military in 1975, and its simplified action was later used in most other Sig Sauer designs, including the P226. The all-steel construction adds heft to this model, which is chambered in hard-hitting 10mm Auto.", + "weight": "964 g", + "volume": "549 ml", + "longest_side": "224 mm", + "price": 50000, + "price_postapoc": 2250, + "to_hit": -1, + "bashing": 8, + "material": [ "steel" ], + "symbol": "(", + "color": "dark_gray", + "ammo": "10mm", + "ranged_damage": { "damage_type": "bullet", "amount": -5 }, + "dispersion": 410, + "durability": 7, + "pocket_data": [ + { + "magazine_well": "60 ml", + "pocket_type": "MAGAZINE_WELL", + "holster": true, + "max_contains_volume": "20 L", + "max_contains_weight": "20 kg", + "item_restriction": [ "p220_10_mag" ] + } + ] + }, + { + "id": "xd_10", + "copy-from": "pistol_base", + "looks_like": "glock_19", + "type": "GUN", + "name": { "str": "XD(M) Competition 10mm" }, + "description": "Designed by HS Produkt in Croatia, the HS2000 has become a commercial success for Springfield Armory, who imports and markets it as the eXtreme Duty. The XD has since been offered in a variety of chamberings and sizes, including this full-sized match grade variant in 10mm Auto.", + "weight": "930 g", + "volume": "549 ml", + "longest_side": "211 mm", + "price": 50000, + "price_postapoc": 2250, + "to_hit": -1, + "bashing": 8, + "material": [ "steel", "plastic" ], + "symbol": "(", + "color": "dark_gray", + "ammo": "10mm", + "ranged_damage": { "damage_type": "bullet", "amount": -5 }, + "dispersion": 480, + "durability": 8, + "pocket_data": [ + { + "magazine_well": "81 ml", + "pocket_type": "MAGAZINE_WELL", + "holster": true, + "max_contains_volume": "20 L", + "max_contains_weight": "20 kg", + "item_restriction": [ "xd_10_mag" ] + } + ] + }, + { + "id": "TDI_10", + "copy-from": "TDI", + "looks_like": "TDI", + "type": "GUN", + "name": { "str": "Vector SDP 10mm" }, + "description": "The Vector SDP is a delayed blowback \"pistol\" with a unique, downward reciprocating bolt that helps combat muzzle climb. This one is chambered in 10mm Auto.", + "weight": "2867 g", + "volume": "4386 ml", + "longest_side": "429 mm", + "price": 142900, + "price_postapoc": 2300, + "skill": "pistol", + "ammo": "10mm", + "ranged_damage": { "damage_type": "bullet", "amount": -4 }, + "modes": [ [ "DEFAULT", "semi-auto", 1 ] ], + "pocket_data": [ + { + "pocket_type": "MAGAZINE_WELL", + "magazine_well": "103 ml", + "holster": true, + "max_contains_volume": "20 L", + "max_contains_weight": "20 kg", + "item_restriction": [ "glock_20mag", "tdi_10mm_mag" ] + } + ] + } +] diff --git a/data/json/items/gun/20x66mm.json b/data/json/items/gun/20x66mm.json index 5d007280c1538..f137e58f5b926 100644 --- a/data/json/items/gun/20x66mm.json +++ b/data/json/items/gun/20x66mm.json @@ -7,8 +7,9 @@ "reload_noise": "chuk chuk.", "name": { "str": "RM120c shotgun" }, "description": "Utilizing a powerful and unusual caliber, the Rivtech RM120c caseless pump-action shotgun was designed for hunting big game, with durability and ease of use as priorities.", - "weight": "1880 g", + "weight": "2480 g", "volume": "2250 ml", + "longest_side": "920 mm", "price": 310000, "price_postapoc": 2250, "to_hit": -1, @@ -45,8 +46,9 @@ "reload_noise_volume": 10, "name": { "str": "RM20 autoshotgun" }, "description": "Utilizing a powerful and unusual caliber, the Rivtech RM20 caseless automatic combat shotgun was designed with durability and overwhelming power in mind.", - "weight": "2820 g", - "volume": "1750 ml", + "weight": "2920 g", + "volume": "2450 ml", + "longest_side": "775 mm", "price": 1320000, "price_postapoc": 10000, "to_hit": -1, @@ -91,6 +93,7 @@ "description": "Chambering the powerful 20x66mm caseless shotgun cartridge, the Rivtech RM228 PDW was designed for the civilian personal defense market with durability and ease of use as priorities. While lauded for its small size and light weight, its hefty price tag kept it out of the reach of casual collectors.", "weight": "780 g", "volume": "750 ml", + "longest_side": "275 mm", "price": 330000, "price_postapoc": 10000, "to_hit": -2, diff --git a/data/json/items/gun/40.json b/data/json/items/gun/40.json index 1ad19f058240a..9150048fef811 100644 --- a/data/json/items/gun/40.json +++ b/data/json/items/gun/40.json @@ -286,41 +286,6 @@ "flags": [ "RELOAD_ONE", "NEVER_JAMS", "RELOAD_EJECT" ], "pocket_data": [ { "pocket_type": "MAGAZINE", "rigid": true, "ammo_restriction": { "40": 6 } } ] }, - { - "id": "sw_610", - "copy-from": "pistol_revolver", - "looks_like": "sw_619", - "type": "GUN", - "name": { "str_sp": "S&W 610" }, - "description": "The Smith and Wesson 610 is a classic six-shooter revolver chambered for 10mm rounds, or for S&W's own .40 round.", - "weight": "1420 g", - "volume": "754 ml", - "longest_side": "332 mm", - "price": 74000, - "price_postapoc": 2250, - "to_hit": -2, - "bashing": 10, - "material": [ "steel", "wood" ], - "symbol": "(", - "color": "dark_gray", - "ammo": [ "10mm", "40" ], - "ranged_damage": { "damage_type": "bullet", "amount": 1 }, - "dispersion": 320, - "durability": 8, - "blackpowder_tolerance": 56, - "clip_size": 6, - "valid_mod_locations": [ - [ "accessories", 2 ], - [ "barrel", 1 ], - [ "bore", 1 ], - [ "grip", 1 ], - [ "rail", 1 ], - [ "sights", 1 ], - [ "stock", 1 ], - [ "underbarrel", 1 ] - ], - "pocket_data": [ { "pocket_type": "MAGAZINE", "holster": true, "rigid": true, "ammo_restriction": { "10mm": 6, "40": 6 } } ] - }, { "id": "hi_power_40", "copy-from": "pistol_base", diff --git a/data/json/items/gun/40x46mm.json b/data/json/items/gun/40x46mm.json index 8bd960446ab64..18c12889da243 100644 --- a/data/json/items/gun/40x46mm.json +++ b/data/json/items/gun/40x46mm.json @@ -8,6 +8,7 @@ "description": "A simple, home-made grenade launcher. Basically a tube with a pin firing mechanism to activate the grenade.", "weight": "2267 g", "volume": "1250 ml", + "longest_side": "450 mm", "price": 40000, "price_postapoc": 750, "to_hit": -3, @@ -37,8 +38,9 @@ "type": "GUN", "name": { "str": "M320 standalone launcher" }, "description": "Heckler & Koch's M320 grenade launcher offers the functionality of larger launchers in a very small package at the cost of decreased accuracy. This one is combined with a buttstock for standalone operation.", - "weight": "2100 g", - "volume": "750 ml", + "weight": "2200 g", + "volume": "1750 ml", + "longest_side": "372 mm", "price": 850000, "price_postapoc": 2250, "to_hit": -3, @@ -59,8 +61,9 @@ "type": "GUN", "name": { "str": "M79 launcher" }, "description": "A widely-used grenade launcher that first saw use by American forces in the Vietnam War. Though mostly replaced by more modern launchers, the M79 still sees use with many units worldwide.", - "weight": "2930 g", - "volume": "1 L", + "weight": "2700 g", + "volume": "2800 ml", + "longest_side": "736 mm", "price": 400000, "price_postapoc": 2500, "to_hit": -3, @@ -92,7 +95,8 @@ "name": { "str_sp": "Milkor MGL" }, "description": "The Milkor Multi-Grenade Launcher is designed to compensate for the drawback of single-shot grenade launchers by allowing sustained heavy firepower. However, it is still slow to reload and must be used with careful planning.", "weight": "5300 g", - "volume": "2250 ml", + "volume": "4230 ml", + "longest_side": "565 mm", "price": 1040000, "price_postapoc": 5000, "to_hit": -3, @@ -124,7 +128,8 @@ "//": "Either Rivtech or milspec would make it Expensive. Combined, you could buy a half-decent car for the price.", "description": "The Rivtech RM802 pump-action 40mm grenade launcher was designed to be a step ahead of single-shot grenade launchers by allowing sustained heavy firepower. However, its capacity is fairly limited so it must be used with careful planning.", "weight": "3120 g", - "volume": "1500 ml", + "volume": "2500 ml", + "longest_side": "820 mm", "price": 2920000, "price_postapoc": 8000, "to_hit": -1, @@ -169,6 +174,7 @@ "description": "An array of six M203 grenade launchers for use on the TALON UGV platform.", "weight": "8200 g", "volume": "4 L", + "longest_side": "400 mm", "price": 250000, "price_postapoc": 4500, "to_hit": -1, diff --git a/data/json/items/gun/45.json b/data/json/items/gun/45.json index a1131ded07107..68307a8641e34 100644 --- a/data/json/items/gun/45.json +++ b/data/json/items/gun/45.json @@ -4,8 +4,8 @@ "looks_like": "hk_mp5", "type": "GUN", "reload_noise_volume": 10, - "name": { "str": "TDI Vector" }, - "description": "The TDI Vector is a submachine gun with a unique, in-line design that makes recoil very manageable, even in the powerful .45 caliber.", + "name": { "str": "Vector SMG .45" }, + "description": "The Vector SMG is a delayed blowback submachine gun with a unique, in-line design that places both the shooter's hand and shoulder in line with the bore axis, reducing muzzle climb during bursts. This one is chambered in .45 ACP.", "weight": "3100 g", "volume": "4248 ml", "longest_side": "611 mm", @@ -27,7 +27,7 @@ [ "barrel", 1 ], [ "bore", 1 ], [ "brass catcher", 1 ], - [ "grip", 1 ], + [ "grip_mount", 1 ], [ "mechanism", 4 ], [ "muzzle", 1 ], [ "rail", 1 ], @@ -37,6 +37,7 @@ [ "underbarrel", 1 ] ], "faults": [ "fault_gun_blackpowder", "fault_gun_dirt", "fault_gun_chamber_spent" ], + "default_mods": [ "folding_stock" ], "pocket_data": [ { "pocket_type": "MAGAZINE_WELL", diff --git a/data/json/items/gun/5x50.json b/data/json/items/gun/5x50.json index aaef493348292..bbd431370f4cb 100644 --- a/data/json/items/gun/5x50.json +++ b/data/json/items/gun/5x50.json @@ -8,6 +8,7 @@ "description": "This light carbine fires 5x50mm armor-piercing flechette cartridges. Classified as a special purpose individual weapon, this advanced firearm was developed by Rivtech for the US military shortly before the end of the world. Designed to be fired in bursts, it excels in close combat.", "weight": "1302 g", "volume": "1250 ml", + "longest_side": "690 mm", "price": 2320000, "price_postapoc": 8000, "to_hit": -2, @@ -55,7 +56,8 @@ "name": { "str": "RM232 IDW" }, "description": "This lightweight machine pistol fires 5x50mm armor-piercing flechette cartridges. Classified as an individual defense weapon, this advanced firearm was developed by Rivtech for the US military shortly before the end of the world. Designed to be fired in bursts, it excels in close combat.", "weight": "682 g", - "volume": "750 ml", + "volume": "620 ml", + "longest_side": "255 mm", "price": 1200000, "price_postapoc": 8000, "to_hit": -2, diff --git a/data/json/items/gun/8x40mm.json b/data/json/items/gun/8x40mm.json index cd862352b786f..9fd027a5c22a9 100644 --- a/data/json/items/gun/8x40mm.json +++ b/data/json/items/gun/8x40mm.json @@ -9,6 +9,7 @@ "description": "Considered overkill by many, the Rivtech M103A remains one of the most powerful sidearms ever developed. Accepts stick magazines.", "weight": "1450 g", "volume": "750 ml", + "longest_side": "295 mm", "price": 230000, "price_postapoc": 6000, "to_hit": -2, @@ -51,7 +52,8 @@ "name": { "str": "RM11B scout rifle" }, "description": "Intended to function as a long-range sharpshooter support weapon for the military, the Rivtech RM11B scout rifle was designed for durability and accuracy under less than ideal circumstances. Its bullpup layout, integrated suppressor and digital scope, and two round burst mode allows it to deliver precise long-range takedowns, utilizing the proprietary Rivtech 8mm caseless round. Accepts stick magazines.", "weight": "3100 g", - "volume": "2 L", + "volume": "2850 ml", + "longest_side": "760 mm", "price": 2900000, "price_postapoc": 10000, "to_hit": -1, @@ -97,7 +99,8 @@ "name": { "str": "RM2000 submachine gun" }, "description": "Utilizing a powerful and unusual caliber, the Rivtech RM2000 submachine gun was designed for durability and ease of carrying under less than ideal circumstances. Accepts stick magazines.", "weight": "1900 g", - "volume": "1 L", + "volume": "1750 ml", + "longest_side": "660 mm", "price": 1900000, "price_postapoc": 10000, "to_hit": -2, @@ -139,7 +142,8 @@ "name": { "str": "RM298 HMG" }, "description": "Utilizing a powerful and unusual caliber, the Rivtech RM298 heavy machine gun was designed for durability and extreme volume of sustained fire under the worst possible circumstances. Accepts RMXB500 box and RMGD250 drum magazines.", "weight": "24500 g", - "volume": "4500 ml", + "volume": "10500 ml", + "longest_side": "1260 mm", "price": 7500000, "price_postapoc": 15000, "to_hit": -4, @@ -175,7 +179,8 @@ "name": { "str": "RM51 assault rifle" }, "description": "Originally produced for military use, the Rivtech RM51 assault rifle was designed for durability and ease of use under less than ideal circumstances, with its considerable bulk minimized by a compact and ergonomic layout. Accepts box magazines.", "weight": "2850 g", - "volume": "1750 ml", + "volume": "2150 ml", + "longest_side": "905 mm", "price": 1800000, "price_postapoc": 12000, "to_hit": -1, @@ -219,6 +224,7 @@ "description": "Utilizing a powerful and unusual caliber, the Rivtech RM614 light machine gun was designed for durability and extreme volume of sustained fire under the worst possible circumstances. Accepts RMXB500 box and RMGD250 drum magazines.", "weight": "4600 g", "volume": "2750 ml", + "longest_side": "935 mm", "price": 3750000, "price_postapoc": 15000, "to_hit": -1, @@ -264,6 +270,7 @@ "description": "Originally produced for military use, the Rivtech RM88 battle rifle was designed for durability and extreme firepower under less than ideal circumstances, with a heavy ported barrel for maximum controllability. Accepts box and RMGD250 drum magazines.", "weight": "3200 g", "volume": "2500 ml", + "longest_side": "995 mm", "price": 900000, "to_hit": -1, "bashing": 12, diff --git a/data/json/items/gun/9mm.json b/data/json/items/gun/9mm.json index 26b02aa303d26..0bd1fb6bef80c 100644 --- a/data/json/items/gun/9mm.json +++ b/data/json/items/gun/9mm.json @@ -301,7 +301,13 @@ "bashing": 15, "dispersion": 520, "sight_dispersion": 520, - "armor_data": { "covers": [ "ARM_EITHER", "HAND_EITHER" ], "coverage": 10, "encumbrance": 30, "material_thickness": 2 }, + "armor_data": { + "covers": [ "arm_l", "arm_r", "hand_l", "hand_r" ], + "sided": true, + "coverage": 10, + "encumbrance": 30, + "material_thickness": 2 + }, "flags": [ "OVERSIZE", "RELOAD_EJECT", "BELTED", "RESTRICT_HANDS" ], "valid_mod_locations": [ ], "pocket_data": [ diff --git a/data/json/items/gun/flammable.json b/data/json/items/gun/flammable.json index f413d2c19c829..0999e72899f46 100644 --- a/data/json/items/gun/flammable.json +++ b/data/json/items/gun/flammable.json @@ -45,6 +45,7 @@ "description": "A military-grade combat flamethrower designed by Rivtech, the RM451 flamethrower incorporates a cycling pressure rapid-feed fuel system with a high-speed piezoelectric igniter. Solidly built with durability in mind, it serves as an incredibly destructive weapon in the right hands.", "weight": "1320 g", "volume": "3500 ml", + "longest_side": "945 mm", "price": 970000, "price_postapoc": 10000, "to_hit": -1, diff --git a/data/json/items/gunmod/underbarrel.json b/data/json/items/gunmod/underbarrel.json index 2532c90e61d35..d91f5d4031d00 100644 --- a/data/json/items/gunmod/underbarrel.json +++ b/data/json/items/gunmod/underbarrel.json @@ -418,6 +418,7 @@ "description": "The Rivtech RM121 auxiliary weapon system is a magazine-fed semi-automatic caseless shotgun, which can be mounted under the barrel of many rifles. Accepts RMSA10 box magazines.", "weight": "1140 g", "volume": "750 ml", + "longest_side": "380 mm", "price": 120000, "price_postapoc": 5000, "material": [ "superalloy", "ceramic" ], diff --git a/data/json/items/magazine/10mm.json b/data/json/items/magazine/10mm.json new file mode 100644 index 0000000000000..9b0934d76ec7f --- /dev/null +++ b/data/json/items/magazine/10mm.json @@ -0,0 +1,167 @@ +[ + { + "id": "40_speedloader6", + "looks_like": "38_speedloader", + "type": "MAGAZINE", + "name": { "str": "10mm 6-round speedloader" }, + "description": "This speedloader can hold 6 rounds of .40 S&W or 10mm Auto and quickly reload a compatible revolver.", + "weight": "92 g", + "volume": "250 ml", + "price": 1500, + "price_postapoc": 100, + "material": "steel", + "symbol": "#", + "color": "light_gray", + "ammo_type": [ "40", "10mm" ], + "capacity": 6, + "flags": [ "SPEEDLOADER" ], + "pocket_data": [ { "pocket_type": "MAGAZINE", "ammo_restriction": { "40": 6, "10mm": 6 } } ] + }, + { + "id": "glock_20mag", + "looks_like": "glock17_17", + "type": "MAGAZINE", + "name": { "str": "Glock 20 magazine" }, + "description": "A compact light-weight steel and polymer magazine for use with Glock pistols chambered for 10mm Auto.", + "weight": "70 g", + "volume": "103 ml", + "longest_side": "114 mm", + "price": 2400, + "price_postapoc": 100, + "material": [ "plastic", "steel" ], + "symbol": "#", + "color": "light_gray", + "ammo_type": [ "10mm" ], + "capacity": 15, + "flags": [ "MAG_COMPACT" ], + "pocket_data": [ { "pocket_type": "MAGAZINE", "rigid": true, "ammo_restriction": { "10mm": 15 } } ] + }, + { + "id": "glock_29mag", + "looks_like": "glock17_17", + "type": "MAGAZINE", + "name": { "str": "Glock 29 magazine" }, + "description": "A stubby steel and polymer magazine for use with the Glock 29. It is too short to insert into most other 10mm Glock pattern magwells.", + "weight": "90 g", + "volume": "99 ml", + "longest_side": "112 mm", + "price": 2500, + "price_postapoc": 100, + "material": [ "plastic", "steel" ], + "symbol": "#", + "color": "light_gray", + "ammo_type": [ "10mm" ], + "capacity": 10, + "flags": [ "MAG_COMPACT" ], + "pocket_data": [ { "pocket_type": "MAGAZINE", "rigid": true, "ammo_restriction": { "10mm": 10 } } ] + }, + { + "id": "m1911_10mag", + "looks_like": "m1911mag", + "copy-from": "m1911mag", + "type": "MAGAZINE", + "name": { "str": "Colt Delta Elite magazine" }, + "description": "An 8-round single stack steel box magazine for use with 1911 pattern guns chambered in 10mm Auto.", + "price": 3500, + "price_postapoc": 100, + "material": "steel", + "ammo_type": [ "10mm" ], + "capacity": 8, + "pocket_data": [ { "pocket_type": "MAGAZINE", "rigid": true, "ammo_restriction": { "10mm": 8 } } ] + }, + { + "id": "mp5_10_mag", + "looks_like": "ump45mag", + "type": "MAGAZINE", + "name": { "str": "MP5/10 magazine" }, + "description": "A straight 30-round box magazine for use with MP5/10's and similar 10mm MP5 clones such as the Brethren Arms BA10.", + "weight": "159 g", + "volume": "231 ml", + "longest_side": "227 mm", + "price": 4950, + "price_postapoc": 100, + "material": [ "plastic", "steel" ], + "symbol": "#", + "color": "light_gray", + "ammo_type": [ "10mm" ], + "capacity": 30, + "flags": [ "MAG_COMPACT" ], + "pocket_data": [ { "pocket_type": "MAGAZINE", "rigid": true, "ammo_restriction": { "10mm": 30 } } ] + }, + { + "id": "p220_10_mag", + "looks_like": "glock17_17", + "type": "MAGAZINE", + "name": { "str": "P220 10mm magazine" }, + "description": "An 8-round steel box magazine for the Sig Sauer P220 in 10mm Auto.", + "weight": "60 g", + "volume": "58 ml", + "longest_side": "141 mm", + "price": 4000, + "price_postapoc": 100, + "material": "steel", + "symbol": "#", + "color": "light_gray", + "ammo_type": [ "10mm" ], + "capacity": 8, + "flags": [ "MAG_COMPACT" ], + "pocket_data": [ { "pocket_type": "MAGAZINE", "rigid": true, "ammo_restriction": { "10mm": 8 } } ] + }, + { + "id": "tdi_10mm_mag", + "looks_like": "tdi_mag", + "type": "MAGAZINE", + "name": { "str": "Vector 10mm magazine" }, + "description": "A 30-round plastic and steel box 10mm Auto magazine for use with the Glock pattern mag wells, namely the Vector SMG.", + "weight": "210 g", + "volume": "194 ml", + "longest_side": "256 mm", + "price": 1800, + "price_postapoc": 100, + "material": [ "plastic", "steel" ], + "symbol": "#", + "color": "light_gray", + "ammo_type": [ "10mm" ], + "capacity": 30, + "flags": [ "MAG_COMPACT" ], + "pocket_data": [ { "pocket_type": "MAGAZINE", "rigid": true, "ammo_restriction": { "10mm": 30 } } ] + }, + { + "id": "witness_mag_10", + "looks_like": "cz75mag_12rd", + "type": "MAGAZINE", + "name": { "str": "EAA Witness 10mm magazine" }, + "description": "A 15-round steel box magazine for 10mm Auto EAA Witness pistols.", + "weight": "135 g", + "volume": "84 ml", + "longest_side": "134 mm", + "price": 2600, + "price_postapoc": 100, + "material": "steel", + "symbol": "#", + "color": "light_gray", + "ammo_type": [ "10mm" ], + "capacity": 15, + "flags": [ "MAG_COMPACT" ], + "pocket_data": [ { "pocket_type": "MAGAZINE", "rigid": true, "ammo_restriction": { "10mm": 15 } } ] + }, + { + "id": "xd_10_mag", + "looks_like": "m9mag", + "type": "MAGAZINE", + "name": { "str": "XD(M) 10mm magazine" }, + "description": "A 15-round steel box magazine for 10mm Auto XD(M) pistols.", + "weight": "80 g", + "volume": "81 ml", + "longest_side": "124 mm", + "price": 2800, + "price_postapoc": 100, + "material": "steel", + "symbol": "#", + "color": "light_gray", + "ammo_type": [ "10mm" ], + "capacity": 15, + "flags": [ "MAG_COMPACT" ], + "pocket_data": [ { "pocket_type": "MAGAZINE", "rigid": true, "ammo_restriction": { "10mm": 15 } } ] + } +] diff --git a/data/json/items/magazine/40.json b/data/json/items/magazine/40.json index 7b0f9fdea649e..fa752d8fc9c57 100644 --- a/data/json/items/magazine/40.json +++ b/data/json/items/magazine/40.json @@ -1,22 +1,4 @@ [ - { - "id": "40_speedloader6", - "looks_like": "38_speedloader", - "type": "MAGAZINE", - "name": { "str": ".40 6-round speedloader" }, - "description": "This speedloader can hold 6 rounds of .40 S&W or 10mm Auto and quickly reload a compatible revolver.", - "weight": "92 g", - "volume": "250 ml", - "price": 1500, - "price_postapoc": 100, - "material": [ "steel" ], - "symbol": "#", - "color": "light_gray", - "ammo_type": [ "40", "10mm" ], - "capacity": 6, - "flags": [ "SPEEDLOADER" ], - "pocket_data": [ { "pocket_type": "MAGAZINE", "rigid": true, "ammo_restriction": { "40": 6, "10mm": 6 } } ] - }, { "id": "90two40mag", "looks_like": "glock17_17", diff --git a/data/json/items/magazine/45.json b/data/json/items/magazine/45.json index 775763cfd7f93..5f75e55734f59 100644 --- a/data/json/items/magazine/45.json +++ b/data/json/items/magazine/45.json @@ -40,13 +40,13 @@ "id": "tdi_mag", "looks_like": "mp5mag", "type": "MAGAZINE", - "name": { "str": "TDI Vector magazine" }, - "description": "A 30-round steel box magazine for use with the TDI Vector", + "name": { "str": "Vector .45 magazine" }, + "description": "A 30-round polymer and steel box magazine for use with the KRISS Vector.", "weight": "210 g", "volume": "500 ml", "price": 1800, "price_postapoc": 100, - "material": [ "steel" ], + "material": [ "plastic", "steel" ], "symbol": "#", "color": "light_gray", "ammo_type": [ "45" ], @@ -128,7 +128,7 @@ "volume": "500 ml", "price": 4950, "price_postapoc": 100, - "material": [ "steel" ], + "material": [ "plastic", "steel" ], "symbol": "#", "color": "light_gray", "ammo_type": [ "45" ], diff --git a/data/json/items/magazine/460.json b/data/json/items/magazine/460.json index 492e010489167..6c5898814c805 100644 --- a/data/json/items/magazine/460.json +++ b/data/json/items/magazine/460.json @@ -22,7 +22,8 @@ "name": { "str": "M1911 magazine" }, "description": "A military issue 7-round magazine for use with the M1911 handgun.", "weight": "70 g", - "volume": "250 ml", + "volume": "61 ml", + "longest_side": "132 mm", "price": 2980, "price_postapoc": 100, "material": [ "steel" ], diff --git a/data/json/items/magazine/shot.json b/data/json/items/magazine/shot.json index 62ac2206d7718..1f3467fc1c7bf 100644 --- a/data/json/items/magazine/shot.json +++ b/data/json/items/magazine/shot.json @@ -88,7 +88,7 @@ "color": "light_gray", "ammo_type": [ "shot" ], "capacity": 20, - "armor_data": { "covers": [ "TORSO" ], "coverage": 5, "material_thickness": 1, "encumbrance": 2 }, + "armor_data": { "covers": [ "torso" ], "coverage": 5, "material_thickness": 1, "encumbrance": 2 }, "flags": [ "MAG_EJECT", "BELTED", "OVERSIZE", "WATER_FRIENDLY" ], "pocket_data": [ { "pocket_type": "MAGAZINE", "rigid": true, "ammo_restriction": { "shot": 20 } } ] }, diff --git a/data/json/items/melee/unarmed_weapons.json b/data/json/items/melee/unarmed_weapons.json index 206e2081b73f5..ef9f7cca75be4 100644 --- a/data/json/items/melee/unarmed_weapons.json +++ b/data/json/items/melee/unarmed_weapons.json @@ -29,7 +29,7 @@ "bashing": 2, "price_postapoc": 250, "flags": [ "UNARMED_WEAPON", "DURABLE_MELEE", "NONCONDUCTIVE" ], - "covers": [ "HANDS" ], + "covers": [ "hand_l", "hand_r" ], "coverage": 50, "encumbrance": 5, "material_thickness": 1 diff --git a/data/json/items/migration.json b/data/json/items/migration.json index 295ec79297044..ab49e90e07105 100644 --- a/data/json/items/migration.json +++ b/data/json/items/migration.json @@ -1268,6 +1268,21 @@ "type": "MIGRATION", "replace": "condiment_bottle_sealed" }, + { + "id": "acid", + "type": "MIGRATION", + "replace": "chem_sulphuric_acid" + }, + { + "id": "water_acid", + "type": "MIGRATION", + "replace": "chem_sulphuric_acid" + }, + { + "id": "water_acid_weak", + "type": "MIGRATION", + "replace": "chem_acetic_acid" + }, { "id": "four_winds_shotgun", "type": "MIGRATION", diff --git a/data/json/items/obsolete.json b/data/json/items/obsolete.json index 1b0da29acfb48..c094c5167c576 100644 --- a/data/json/items/obsolete.json +++ b/data/json/items/obsolete.json @@ -519,7 +519,7 @@ "material": [ "bone", "leather" ], "symbol": "[", "color": "white", - "covers": [ "ARMS" ], + "covers": [ "arm_l", "arm_r" ], "coverage": 95, "encumbrance": 22, "warmth": 20, @@ -541,7 +541,7 @@ "material": [ "bone", "leather" ], "symbol": "[", "color": "white", - "covers": [ "LEGS", "TORSO" ], + "covers": [ "torso", "leg_l", "leg_r" ], "coverage": 95, "encumbrance": 24, "warmth": 20, @@ -562,7 +562,7 @@ "material": [ "bone", "leather" ], "symbol": "[", "color": "white", - "covers": [ "HANDS" ], + "covers": [ "hand_l", "hand_r" ], "coverage": 95, "encumbrance": 15, "warmth": 20, @@ -584,7 +584,7 @@ "material": [ "bone" ], "symbol": "[", "color": "white", - "covers": [ "HEAD", "EYES", "MOUTH" ], + "covers": [ "head", "eyes", "mouth" ], "coverage": 100, "encumbrance": 25, "warmth": 10, @@ -1692,7 +1692,7 @@ "symbol": "[", "looks_like": "helmet_army", "color": "dark_gray", - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 100, "encumbrance": 25, "warmth": 15, @@ -1716,7 +1716,7 @@ "symbol": "[", "looks_like": "helmet_survivor", "color": "dark_gray", - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 100, "encumbrance": 50, "warmth": 15, @@ -1740,7 +1740,7 @@ "symbol": "[", "looks_like": "helmet_survivor", "color": "dark_gray", - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 100, "encumbrance": 40, "warmth": 25, @@ -1973,7 +1973,7 @@ "material": [ "glass", "steel" ], "symbol": "[", "color": "light_gray", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 40, "encumbrance": 12, "material_thickness": 3, @@ -1994,7 +1994,7 @@ "material": [ "glass", "steel" ], "symbol": "[", "color": "blue", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 40, "encumbrance": 20, "material_thickness": 1, @@ -2364,7 +2364,7 @@ "symbol": "[", "looks_like": "modularvestkevlar", "color": "light_gray", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 85, "encumbrance": 7, "warmth": 15, @@ -2388,7 +2388,7 @@ "symbol": "[", "looks_like": "modularvestkevlar", "color": "light_gray", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 85, "encumbrance": 15, "warmth": 15, @@ -2412,7 +2412,7 @@ "symbol": "[", "looks_like": "modularvestkevlar", "color": "light_cyan", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 85, "encumbrance": 25, "warmth": 15, @@ -2436,7 +2436,7 @@ "symbol": "[", "looks_like": "vest", "color": "light_gray", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 85, "encumbrance": 12, "warmth": 15, @@ -2460,7 +2460,7 @@ "symbol": "[", "looks_like": "modularvestkevlar", "color": "light_cyan", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 85, "encumbrance": 20, "warmth": 15, @@ -2484,7 +2484,7 @@ "symbol": "[", "looks_like": "modularvestkevlar", "color": "light_cyan", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 85, "encumbrance": 15, "warmth": 15, diff --git a/data/json/items/ranged/archery.json b/data/json/items/ranged/archery.json index fa3c666e5c57c..90c7c87d07f4a 100644 --- a/data/json/items/ranged/archery.json +++ b/data/json/items/ranged/archery.json @@ -374,7 +374,7 @@ "volume": "2500 ml", "price_postapoc": 50, "bashing": 6, - "armor_data": { "covers": [ "TORSO" ], "coverage": 5, "material_thickness": 1, "encumbrance": 20 }, + "armor_data": { "covers": [ "torso" ], "coverage": 5, "material_thickness": 1, "encumbrance": 20 }, "ranged_damage": { "damage_type": "stab", "amount": 1 }, "range": 8, "dispersion": 1250, @@ -401,7 +401,7 @@ "volume": "1500 ml", "price_postapoc": 500, "bashing": 6, - "armor_data": { "covers": [ "TORSO" ], "coverage": 5, "material_thickness": 1, "encumbrance": 14 }, + "armor_data": { "covers": [ "torso" ], "coverage": 5, "material_thickness": 1, "encumbrance": 14 }, "reload_noise_volume": 3, "loudness": 6, "ranged_damage": { "damage_type": "stab", "amount": 4 }, @@ -502,7 +502,7 @@ "volume": "1750 ml", "price_postapoc": 3000, "bashing": 8, - "armor_data": { "covers": [ "TORSO" ], "coverage": 5, "material_thickness": 1, "encumbrance": 14 }, + "armor_data": { "covers": [ "torso" ], "coverage": 5, "material_thickness": 1, "encumbrance": 14 }, "reload_noise_volume": 3, "loudness": 6, "ranged_damage": { "damage_type": "stab", "amount": 8 }, @@ -532,7 +532,7 @@ "volume": "2500 ml", "price_postapoc": 2000, "bashing": 12, - "armor_data": { "covers": [ "TORSO" ], "coverage": 5, "material_thickness": 1, "encumbrance": 20 }, + "armor_data": { "covers": [ "torso" ], "coverage": 5, "material_thickness": 1, "encumbrance": 20 }, "reload_noise_volume": 3, "loudness": 8, "ranged_damage": { "damage_type": "stab", "amount": 6 }, @@ -562,7 +562,7 @@ "volume": "1500 ml", "price_postapoc": 2000, "bashing": 12, - "armor_data": { "covers": [ "TORSO" ], "coverage": 5, "material_thickness": 1, "encumbrance": 14 }, + "armor_data": { "covers": [ "torso" ], "coverage": 5, "material_thickness": 1, "encumbrance": 14 }, "reload_noise_volume": 3, "loudness": 6, "ranged_damage": { "damage_type": "stab", "amount": 6 }, @@ -592,7 +592,7 @@ "volume": "3500 ml", "price_postapoc": 5000, "bashing": 12, - "armor_data": { "covers": [ "TORSO" ], "coverage": 5, "material_thickness": 1, "encumbrance": 20 }, + "armor_data": { "covers": [ "torso" ], "coverage": 5, "material_thickness": 1, "encumbrance": 20 }, "reload_noise_volume": 3, "loudness": 8, "ranged_damage": { "damage_type": "stab", "amount": 10 }, @@ -621,7 +621,7 @@ "volume": "3500 ml", "price_postapoc": 3000, "bashing": 10, - "armor_data": { "covers": [ "TORSO" ], "coverage": 5, "material_thickness": 1, "encumbrance": 20 }, + "armor_data": { "covers": [ "torso" ], "coverage": 5, "material_thickness": 1, "encumbrance": 20 }, "reload_noise_volume": 3, "loudness": 8, "ranged_damage": { "damage_type": "stab", "amount": 5 }, @@ -644,7 +644,7 @@ "weight": "3200 g", "volume": "6250 ml", "price_postapoc": 2000, - "armor_data": { "covers": [ "TORSO" ], "coverage": 7, "material_thickness": 2, "encumbrance": 25 }, + "armor_data": { "covers": [ "torso" ], "coverage": 7, "material_thickness": 2, "encumbrance": 25 }, "durability": 8, "loudness": 16, "ranged_damage": { "damage_type": "stab", "amount": 11 }, @@ -698,7 +698,7 @@ "volume": "2 L", "price_postapoc": 6000, "bashing": 12, - "armor_data": { "covers": [ "TORSO" ], "coverage": 5, "material_thickness": 1, "encumbrance": 14 }, + "armor_data": { "covers": [ "torso" ], "coverage": 5, "material_thickness": 1, "encumbrance": 14 }, "reload_noise_volume": 3, "loudness": 8, "ranged_damage": { "damage_type": "stab", "amount": 6 }, diff --git a/data/json/items/tool/cooking.json b/data/json/items/tool/cooking.json index 44716bac99200..01a694f8d2d88 100644 --- a/data/json/items/tool/cooking.json +++ b/data/json/items/tool/cooking.json @@ -931,7 +931,7 @@ "description": "This is a portable heat sealer unit with an air pump. It's used for vacuum packing food to preserve it.", "weight": "1770 g", "volume": "4100 ml", - "longest_side": "35cm", + "longest_side": "35 cm", "price": 2500, "price_postapoc": 2000, "to_hit": -1, diff --git a/data/json/items/tool/musical_instruments.json b/data/json/items/tool/musical_instruments.json index 341ebe3e6ec42..b83585366c593 100644 --- a/data/json/items/tool/musical_instruments.json +++ b/data/json/items/tool/musical_instruments.json @@ -15,7 +15,6 @@ "material": [ "wood", "iron" ], "symbol": "|", "color": "white", - "initial_charges": 1, "use_action": { "type": "musical_instrument", "volume": 18, @@ -45,7 +44,6 @@ "material": [ "bone" ], "symbol": "-", "color": "white", - "initial_charges": 1, "use_action": { "type": "musical_instrument", "volume": 12, @@ -77,7 +75,6 @@ "material": [ "wood", "iron" ], "symbol": "|", "color": "light_gray", - "initial_charges": 1, "use_action": { "type": "musical_instrument", "volume": 14, @@ -107,7 +104,6 @@ "material": [ "iron", "silver" ], "symbol": "-", "color": "light_gray", - "initial_charges": 1, "use_action": { "type": "musical_instrument", "volume": 12, @@ -138,7 +134,6 @@ "material": [ "brass" ], "symbol": "-", "color": "yellow", - "initial_charges": 1, "use_action": { "type": "musical_instrument", "volume": 21, @@ -169,7 +164,6 @@ "material": [ "wood" ], "symbol": "(", "color": "brown", - "initial_charges": 1, "use_action": { "type": "musical_instrument", "volume": 16, @@ -200,7 +194,6 @@ "material": [ "wood" ], "symbol": "}", "color": "brown", - "initial_charges": 1, "use_action": { "type": "musical_instrument", "volume": 18, @@ -231,7 +224,6 @@ "material": [ "gold" ], "symbol": "}", "color": "yellow", - "initial_charges": 1, "use_action": { "type": "musical_instrument", "volume": 25, diff --git a/data/json/items/tool/science.json b/data/json/items/tool/science.json index 2c874172222f1..fec3bcd663492 100644 --- a/data/json/items/tool/science.json +++ b/data/json/items/tool/science.json @@ -463,7 +463,7 @@ "id": "filter_paper_qualitative", "type": "TOOL", "name": { "str_sp": "qualitative filter paper" }, - "description": "filter paper for seperating solids from liquids. This filter paper has a rating of 2 microns, seperating more solids out than quantitative filter paper but the process takes longer.", + "description": "Filter paper for separating solids from liquids. This filter paper has a rating of 2 microns, separating more solids out than quantitative filter paper but the process takes longer.", "symbol": "E", "color": "dark_gray", "looks_like": "paper", @@ -479,7 +479,7 @@ "id": "filter_paper_quantitative", "type": "TOOL", "name": { "str_sp": "quantitative filter paper" }, - "description": "filter paper for seperating solids from liquids. This filter paper has a rating of 20 microns, seperating less solids out than qualitative filter paper but the process is much faster.", + "description": "Filter paper for separating solids from liquids. This filter paper has a rating of 20 microns, separating less solids out than qualitative filter paper but the process is much faster.", "symbol": "E", "color": "dark_gray", "looks_like": "paper", @@ -597,7 +597,7 @@ "id": "recovery_pump", "type": "TOOL", "name": { "str": "recovery pump" }, - "description": "A medium sized vacuum pump designed to recover solvent (hydrocarbons) from extracted essential oils.", + "description": "A medium-sized vacuum pump designed to recover solvent (hydrocarbons) from extracted essential oils.", "symbol": "E", "color": "dark_gray", "looks_like": "well_pump", diff --git a/data/json/items/tool_armor.json b/data/json/items/tool_armor.json index 931aaef12a14a..7d0da34ea9044 100644 --- a/data/json/items/tool_armor.json +++ b/data/json/items/tool_armor.json @@ -12,7 +12,8 @@ "symbol": "[", "looks_like": "armguard_hard", "color": "white", - "covers": [ "ARM_EITHER" ], + "covers": [ "arm_l", "arm_r" ], + "sided": true, "coverage": 75, "encumbrance": 70, "warmth": 5, @@ -46,7 +47,8 @@ "symbol": "{", "looks_like": "armguard_hard", "color": "red", - "covers": [ "ARM_EITHER" ], + "covers": [ "arm_l", "arm_r" ], + "sided": true, "coverage": 10, "encumbrance": 70, "warmth": 0, @@ -61,7 +63,8 @@ "description": "First aid device used to apply pressure to a limb or extremity in order to limit blood flow. Should be employed only to manage heavy bleedings, because prolonged use will harm the limb. It can be adjusted in size to fit different limbs.", "copy-from": "tourniquet_upper", "looks_like": "tourniquet_upper", - "covers": [ "ARM_EITHER" ], + "covers": [ "arm_l", "arm_r" ], + "sided": true, "use_action": { "target": "tourniquet_lower", "msg": "You adjust the tourniquet.", "menu_text": "Adjust", "type": "transform" }, "flags": [ "WATER_FRIENDLY", "OUTER", "TOURNIQUET", "OVERSIZE" ] }, @@ -72,7 +75,8 @@ "description": "First aid device used to apply pressure to a limb or extremity in order to limit blood flow. Should be employed only to manage heavy bleedings, because prolonged use will harm the limb. It can be adjusted in size to fit different limbs.", "copy-from": "tourniquet_upper", "looks_like": "tourniquet_upper", - "covers": [ "LEG_EITHER" ], + "covers": [ "leg_l", "leg_r" ], + "sided": true, "use_action": { "target": "tourniquet_lower_XL", "msg": "You adjust the tourniquet.", "menu_text": "Adjust", "type": "transform" }, "flags": [ "WATER_FRIENDLY", "OUTER", "TOURNIQUET" ] }, @@ -83,7 +87,8 @@ "description": "First aid device used to apply pressure to a limb or extremity in order to limit blood flow. Should be employed only to manage heavy bleedings, because prolonged use will harm the limb. It can be adjusted in size to fit different limbs.", "copy-from": "tourniquet_upper", "looks_like": "tourniquet_upper", - "covers": [ "LEG_EITHER" ], + "covers": [ "leg_l", "leg_r" ], + "sided": true, "use_action": { "target": "tourniquet_upper", "msg": "You adjust the tourniquet.", "menu_text": "Adjust", "type": "transform" }, "flags": [ "WATER_FRIENDLY", "OUTER", "TOURNIQUET", "OVERSIZE" ] }, @@ -101,7 +106,7 @@ "symbol": "[", "looks_like": "scarf", "color": "dark_gray", - "covers": [ "EYES" ], + "covers": [ "eyes" ], "coverage": 95, "encumbrance": 10, "warmth": 5, @@ -139,7 +144,7 @@ "symbol": "[", "looks_like": "duffelbag", "color": "green", - "covers": [ "TORSO", "ARMS" ], + "covers": [ "torso", "arm_l", "arm_r" ], "coverage": 50, "encumbrance": 35, "warmth": 10, @@ -170,7 +175,8 @@ "symbol": "[", "looks_like": "legguard_hard", "color": "white", - "covers": [ "LEG_EITHER" ], + "covers": [ "leg_l", "leg_r" ], + "sided": true, "coverage": 75, "encumbrance": 70, "warmth": 5, @@ -215,7 +221,7 @@ "need_charges": 1, "need_charges_msg": "The helmet's batteries are dead." }, - "covers": [ "HEAD" ], + "covers": [ "head" ], "techniques": [ "WBLOCK_1" ], "warmth": 5, "encumbrance": 15, @@ -251,7 +257,7 @@ "power_draw": 15000, "revert_to": "miner_hat", "use_action": { "menu_text": "Turn off", "type": "transform", "msg": "The %s flicks off.", "target": "miner_hat" }, - "covers": [ "HEAD" ], + "covers": [ "head" ], "techniques": [ "WBLOCK_1" ] }, { @@ -269,7 +275,7 @@ "material": [ "plastic" ], "symbol": "[", "color": "dark_gray", - "covers": [ "HEAD", "MOUTH", "EYES" ], + "covers": [ "head", "eyes", "mouth" ], "coverage": 90, "warmth": 5, "encumbrance": 60, @@ -296,7 +302,7 @@ "material": [ "steel" ], "symbol": "[", "color": "dark_gray", - "covers": [ "HEAD", "MOUTH", "EYES" ], + "covers": [ "head", "eyes", "mouth" ], "coverage": 90, "warmth": 5, "encumbrance": 60, @@ -323,7 +329,7 @@ "material": [ "steel" ], "symbol": "[", "color": "dark_gray", - "covers": [ "HEAD" ], + "covers": [ "head" ], "warmth": 5, "encumbrance": 60, "material_thickness": 2, @@ -348,7 +354,7 @@ "material": [ "plastic" ], "symbol": "[", "color": "dark_gray", - "covers": [ "HEAD" ], + "covers": [ "head" ], "warmth": 5, "encumbrance": 60, "material_thickness": 3, @@ -364,7 +370,8 @@ "weight": "112 g", "to_hit": -1, "color": "light_gray", - "covers": [ "HAND_EITHER" ], + "covers": [ "hand_l", "hand_r" ], + "sided": true, "price": 6000, "price_postapoc": 100, "material": [ "plastic" ], @@ -394,7 +401,8 @@ "weight": "30 g", "to_hit": -1, "color": "light_gray", - "covers": [ "HAND_EITHER" ], + "covers": [ "hand_l", "hand_r" ], + "sided": true, "price": 5000, "price_postapoc": 100, "material": [ "plastic" ], @@ -416,7 +424,7 @@ "material": [ "superalloy" ], "symbol": "[", "color": "light_gray", - "covers": [ "TORSO", "HEAD", "ARMS", "LEGS" ], + "covers": [ "torso", "head", "arm_l", "arm_r", "leg_l", "leg_r" ], "coverage": 65, "encumbrance": 10, "pocket_data": [ @@ -430,6 +438,7 @@ } ], "ammo": "battery", + "max_charges": 500, "initial_charges": 500, "charges_per_use": 25, "warmth": 10, @@ -445,7 +454,7 @@ "name": { "str": "fedora" }, "weight": "350 g", "color": "brown", - "covers": [ "HEAD" ], + "covers": [ "head" ], "use_action": { "menu_text": "Tip", "type": "transform", "target": "fedora", "msg": "You tip your %s." }, "symbol": "[", "description": "A high-crowned, wide-brimmed, sable colored fedora. Its brim helps keep the sun out of your eyes. The perfect hat for treasure hunting.", @@ -484,7 +493,7 @@ "need_charges": 1, "need_charges_msg": "The %s's batteries are dead." }, - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "warmth": 10, "coverage": 100, "material_thickness": 1, @@ -544,7 +553,7 @@ "need_charges": 1, "need_charges_msg": "The %s's batteries are dead." }, - "covers": [ "TORSO", "ARMS", "LEGS" ], + "covers": [ "torso", "arm_l", "arm_r", "leg_l", "leg_r" ], "warmth": 10, "coverage": 100, "material_thickness": 1, @@ -604,7 +613,7 @@ "need_charges": 1, "need_charges_msg": "The %s's batteries are dead." }, - "covers": [ "HANDS" ], + "covers": [ "hand_l", "hand_r" ], "warmth": 10, "coverage": 100, "material_thickness": 1, @@ -664,7 +673,7 @@ "need_charges": 1, "need_charges_msg": "The %s's batteries are dead." }, - "covers": [ "HEAD", "MOUTH" ], + "covers": [ "head", "mouth" ], "warmth": 10, "coverage": 100, "material_thickness": 1, @@ -717,7 +726,7 @@ "bashing": 4, "to_hit": -1, "use_action": { "type": "firestarter", "moves": 1000, "moves_slow": 25000, "need_sunlight": true }, - "covers": [ "TORSO" ], + "covers": [ "torso" ], "encumbrance": 2, "coverage": 10, "material_thickness": 2 @@ -747,7 +756,7 @@ "need_charges": 1, "need_charges_msg": "The headlamp batteries are dead." }, - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 15, "material_thickness": 1, "pocket_data": [ @@ -807,7 +816,7 @@ "need_charges": 1, "need_charges_msg": "The survivor headlamp batteries are dead." }, - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 20, "material_thickness": 1, "pocket_data": [ @@ -865,7 +874,7 @@ "target": "wearable_atomic_light_off", "active": true }, - "covers": [ "HEAD" ], + "covers": [ "head" ], "encumbrance": 5, "coverage": 20, "material_thickness": 1 @@ -962,7 +971,7 @@ "ammo": "battery", "charges_per_use": 5, "use_action": [ "RM13ARMOR_OFF" ], - "covers": [ "HEAD", "MOUTH", "EYES", "TORSO", "ARMS", "HANDS", "LEGS", "FEET" ], + "covers": [ "head", "mouth", "eyes", "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ], "warmth": 30, "environmental_protection": 15, "encumbrance": 30, @@ -1024,6 +1033,7 @@ } ], "ammo": "battery", + "max_charges": 1000, "initial_charges": 1000, "use_action": { "type": "transform", @@ -1033,7 +1043,7 @@ "need_charges": 1, "need_charges_msg": "It seems like this device needs power." }, - "covers": [ "TORSO" ], + "covers": [ "torso" ], "warmth": 10, "coverage": 50, "encumbrance": 2, @@ -1056,7 +1066,7 @@ "msg": "The %s LED light flickers off.", "target": "dimensional_anchor" }, - "covers": [ "TORSO" ], + "covers": [ "torso" ], "flags": [ "DIMENSIONAL_ANCHOR", "OVERSIZE", "STRAPPED" ] }, { @@ -1084,6 +1094,7 @@ } ], "ammo": "battery", + "max_charges": 1000, "initial_charges": 1000, "use_action": { "type": "transform", @@ -1093,7 +1104,7 @@ "need_charges": 1, "need_charges_msg": "Warning: Operating on minimal power. Protection compromised." }, - "covers": [ "HEAD", "MOUTH", "EYES", "TORSO", "ARMS", "HANDS", "LEGS", "FEET" ], + "covers": [ "head", "mouth", "eyes", "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ], "warmth": 30, "environmental_protection": 10, "coverage": 100, @@ -1124,7 +1135,7 @@ "turns_per_charge": 25, "revert_to": "phase_immersion_suit", "use_action": { "type": "transform", "menu_text": "Turn off", "msg": "Suit shutting down.", "target": "phase_immersion_suit" }, - "covers": [ "HEAD", "MOUTH", "EYES", "TORSO", "ARMS", "HANDS", "LEGS", "FEET" ], + "covers": [ "head", "mouth", "eyes", "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ], "environmental_protection": 80, "flags": [ "RAD_PROOF", @@ -1164,6 +1175,7 @@ "to_hit": -3, "pocket_data": [ { "pocket_type": "MAGAZINE", "rigid": true, "ammo_restriction": { "rebreather_filter": 60 } } ], "ammo": "rebreather_filter", + "max_charges": 60, "initial_charges": 60, "charges_per_use": 1, "use_action": { @@ -1174,7 +1186,7 @@ "need_charges": 1, "need_charges_msg": "The %s's filter is used up." }, - "covers": [ "MOUTH" ], + "covers": [ "mouth" ], "warmth": 10, "environmental_protection": 1, "encumbrance": 30, @@ -1212,6 +1224,7 @@ "to_hit": -3, "pocket_data": [ { "pocket_type": "MAGAZINE", "rigid": true, "ammo_restriction": { "rebreather_filter": 60 } } ], "ammo": "rebreather_filter", + "max_charges": 60, "initial_charges": 60, "charges_per_use": 1, "use_action": { @@ -1222,7 +1235,7 @@ "need_charges": 1, "need_charges_msg": "The %s's filter is used up." }, - "covers": [ "MOUTH" ], + "covers": [ "mouth" ], "warmth": 10, "environmental_protection": 1, "encumbrance": 30, @@ -1240,7 +1253,7 @@ "turns_per_charge": 30, "revert_to": "rebreather_xl", "use_action": { "type": "transform", "menu_text": "Turn off", "msg": "Your %s deactivates.", "target": "rebreather_xl" }, - "covers": [ "MOUTH" ], + "covers": [ "mouth" ], "environmental_protection": 15, "encumbrance": 20 }, @@ -1258,7 +1271,7 @@ "material": [ "plastic" ], "symbol": "[", "color": "light_gray", - "covers": [ "MOUTH" ], + "covers": [ "mouth" ], "coverage": 100, "encumbrance": 20, "warmth": 10, @@ -1267,6 +1280,7 @@ "environmental_protection_with_filter": 7, "pocket_data": [ { "pocket_type": "MAGAZINE", "rigid": true, "ammo_restriction": { "gasfilter_s": 100 } } ], "ammo": "gasfilter_s", + "max_charges": 100, "initial_charges": 100, "use_action": [ "GASMASK" ] }, @@ -1295,6 +1309,7 @@ "environmental_protection_with_filter": 16, "pocket_data": [ { "pocket_type": "MAGAZINE", "rigid": true, "ammo_restriction": { "gasfilter_m": 100 } } ], "ammo": "gasfilter_m", + "max_charges": 100, "initial_charges": 100, "use_action": [ "GASMASK" ] }, @@ -1322,6 +1337,7 @@ "environmental_protection_with_filter": 16, "pocket_data": [ { "pocket_type": "MAGAZINE", "rigid": true, "ammo_restriction": { "gasfilter_m": 100 } } ], "ammo": "gasfilter_m", + "max_charges": 100, "initial_charges": 100, "use_action": [ "GASMASK" ], "flags": [ "OVERSIZE", "SLEEP_IGNORE" ] @@ -1351,6 +1367,7 @@ "environmental_protection_with_filter": 15, "pocket_data": [ { "pocket_type": "MAGAZINE", "rigid": true, "ammo_restriction": { "gasfilter_m": 100 } } ], "ammo": "gasfilter_m", + "max_charges": 100, "initial_charges": 100, "use_action": [ "GASMASK" ], "flags": [ "VARSIZE", "STURDY", "SUN_GLASSES", "SLEEP_IGNORE" ] @@ -1380,6 +1397,7 @@ "environmental_protection_with_filter": 15, "pocket_data": [ { "pocket_type": "MAGAZINE", "rigid": true, "ammo_restriction": { "gasfilter_m": 100 } } ], "ammo": "gasfilter_m", + "max_charges": 100, "initial_charges": 100, "use_action": [ "GASMASK" ], "flags": [ "VARSIZE", "STURDY", "OVERSIZE", "SUN_GLASSES", "SLEEP_IGNORE" ] @@ -1402,6 +1420,7 @@ "to_hit": -3, "pocket_data": [ { "pocket_type": "MAGAZINE", "rigid": true, "ammo_restriction": { "gasfilter_m": 100 } } ], "ammo": "gasfilter_m", + "max_charges": 100, "initial_charges": 100, "use_action": [ "GASMASK" ], "warmth": 30, @@ -1427,6 +1446,7 @@ "to_hit": -3, "pocket_data": [ { "pocket_type": "MAGAZINE", "rigid": true, "ammo_restriction": { "gasfilter_m": 100 } } ], "ammo": "gasfilter_m", + "max_charges": 100, "initial_charges": 100, "use_action": [ "GASMASK" ], "material": [ "kevlar_layered", "steel" ], @@ -1456,6 +1476,7 @@ "to_hit": -3, "pocket_data": [ { "pocket_type": "MAGAZINE", "rigid": true, "ammo_restriction": { "gasfilter_m": 100 } } ], "ammo": "gasfilter_m", + "max_charges": 100, "initial_charges": 100, "use_action": [ "GASMASK" ], "material": [ "kevlar_layered", "cotton" ], @@ -1485,6 +1506,7 @@ "to_hit": -3, "pocket_data": [ { "pocket_type": "MAGAZINE", "rigid": true, "ammo_restriction": { "gasfilter_m": 100 } } ], "ammo": "gasfilter_m", + "max_charges": 100, "initial_charges": 100, "use_action": [ "GASMASK" ], "material": [ "kevlar_layered", "leather" ], @@ -1514,6 +1536,7 @@ "to_hit": -3, "pocket_data": [ { "pocket_type": "MAGAZINE", "rigid": true, "ammo_restriction": { "gasfilter_m": 100 } } ], "ammo": "gasfilter_m", + "max_charges": 100, "initial_charges": 100, "use_action": [ "GASMASK" ], "material": [ "kevlar_layered", "plastic" ], @@ -1543,6 +1566,7 @@ "to_hit": -3, "pocket_data": [ { "pocket_type": "MAGAZINE", "rigid": true, "ammo_restriction": { "gasfilter_m": 100 } } ], "ammo": "gasfilter_m", + "max_charges": 100, "initial_charges": 100, "use_action": [ "GASMASK" ], "material": [ "kevlar_layered", "fur" ], @@ -1572,6 +1596,7 @@ "to_hit": -3, "pocket_data": [ { "pocket_type": "MAGAZINE", "rigid": true, "ammo_restriction": { "gasfilter_m": 100 } } ], "ammo": "gasfilter_m", + "max_charges": 100, "initial_charges": 100, "use_action": [ "GASMASK" ], "material": [ "kevlar_layered", "fur" ], @@ -1613,7 +1638,7 @@ "need_charges": 1, "need_charges_msg": "The %s's batteries are dead." }, - "covers": [ "EYES" ], + "covers": [ "eyes" ], "warmth": 10, "environmental_protection": 6, "encumbrance": 40, @@ -1678,7 +1703,7 @@ "need_charges": 1, "need_charges_msg": "The %s's batteries are dead." }, - "covers": [ "EYES" ], + "covers": [ "eyes" ], "warmth": 10, "environmental_protection": 6, "encumbrance": 40, @@ -1714,7 +1739,7 @@ "power_draw": 1000, "revert_to": "goggles_ir", "use_action": { "type": "transform", "menu_text": "Turn off", "msg": "Your %s deactivates.", "target": "goggles_ir" }, - "covers": [ "EYES" ], + "covers": [ "eyes" ], "warmth": 25, "encumbrance": 20 }, @@ -1883,7 +1908,7 @@ "to_hit": -3, "revert_to": "folding_poncho", "use_action": [ "PACK_ITEM" ], - "covers": [ "TORSO", "ARMS" ], + "covers": [ "torso", "arm_l", "arm_r" ], "flags": [ "WATERPROOF", "RAINPROOF", "HOOD", "OVERSIZE", "OUTER" ], "environmental_protection": 1, "coverage": 90, @@ -1920,7 +1945,7 @@ "to_hit": -3, "revert_to": "emer_blanket", "use_action": [ "PACK_ITEM" ], - "covers": [ "TORSO", "ARMS", "HANDS", "LEGS", "FEET" ], + "covers": [ "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ], "flags": [ "OVERSIZE", "OUTER", "ALLOWS_NATURAL_ATTACKS" ], "warmth": 50, "environmental_protection": 1, @@ -1945,7 +1970,7 @@ "charges_per_use": 1, "ammo": "battery", "use_action": [ "RADGLOVE" ], - "covers": [ "HAND_EITHER" ], + "covers": [ "hand_l", "hand_r" ], "coverage": 5, "material_thickness": 1, "flags": [ "BELTED", "FRAGILE", "ALLOWS_NATURAL_ATTACKS", "WATER_FRIENDLY", "OVERSIZE" ], @@ -1966,7 +1991,7 @@ "name": { "str": "survivor utility belt" }, "weight": "3390 g", "color": "brown", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "symbol": "[", "description": "A custom-built leather utility belt covered with straps and pouches containing many useful hand tools and a sheath to carry a smaller blade. Durable and carefully crafted to be comfortable to wear. Activate to sheathe/draw a weapon.", "price": 50000, @@ -2046,7 +2071,7 @@ "price": 4500, "price_postapoc": 10, "material": [ "cotton" ], - "covers": [ "TORSO", "LEGS" ], + "covers": [ "torso", "leg_l", "leg_r" ], "weight": "370 g", "volume": "500 ml", "to_hit": -1, @@ -2066,7 +2091,7 @@ "price": 2000, "price_postapoc": 0, "material": [ "cotton" ], - "covers": [ "TORSO", "LEGS" ], + "covers": [ "torso", "leg_l", "leg_r" ], "weight": "400 g", "volume": "500 ml", "to_hit": -1, @@ -2087,7 +2112,7 @@ "price": 2000, "price_postapoc": 0, "material": [ "cotton" ], - "covers": [ "TORSO", "LEGS" ], + "covers": [ "torso", "leg_l", "leg_r" ], "weight": "400 g", "volume": "500 ml", "to_hit": -1, @@ -2104,7 +2129,7 @@ "name": { "str": "straw fedora" }, "weight": "300 g", "color": "light_gray", - "covers": [ "HEAD" ], + "covers": [ "head" ], "use_action": { "menu_text": "Tip", "type": "transform", "target": "straw_fedora", "msg": "You tip your %s." }, "symbol": "[", "description": "Straw fedora hat, comfortable and stylish. Its brim helps keep the sun out of your eyes.", @@ -2134,7 +2159,7 @@ "volume": "500 ml", "to_hit": -3, "use_action": { "type": "transform", "msg": "You loosen your %s.", "target": "patchwork_scarf_loose", "menu_text": "Loosen" }, - "covers": [ "MOUTH" ], + "covers": [ "mouth" ], "flags": [ "OUTER" ], "warmth": 20, "environmental_protection": 1, @@ -2159,7 +2184,7 @@ "to_hit": -3, "revert_to": "patchwork_scarf", "use_action": { "type": "transform", "msg": "You wrap your scarf tighter.", "target": "patchwork_scarf", "menu_text": "Wrap tighter" }, - "covers": [ "MOUTH" ], + "covers": [ "mouth" ], "flags": [ "OUTER", "ALLOWS_NATURAL_ATTACKS" ], "warmth": 10, "environmental_protection": 1, @@ -2182,7 +2207,7 @@ "volume": "1 L", "to_hit": -3, "use_action": { "type": "transform", "msg": "You loosen your %s.", "target": "long_patchwork_scarf_loose", "menu_text": "Loosen" }, - "covers": [ "MOUTH" ], + "covers": [ "mouth" ], "flags": [ "OVERSIZE", "POCKETS", "OUTER" ], "warmth": 20, "environmental_protection": 1, @@ -2212,7 +2237,7 @@ "menu_text": "Wrap tighter" }, "revert_to": "long_patchwork_scarf", - "covers": [ "MOUTH" ], + "covers": [ "mouth" ], "flags": [ "OVERSIZE", "POCKETS", "OUTER", "ALLOWS_NATURAL_ATTACKS" ], "warmth": 10, "environmental_protection": 1, @@ -2235,7 +2260,7 @@ "volume": "750 ml", "to_hit": -3, "use_action": { "type": "transform", "msg": "You loosen your %s.", "target": "knit_scarf_loose", "menu_text": "Loosen" }, - "covers": [ "MOUTH" ], + "covers": [ "mouth" ], "flags": [ "OUTER" ], "warmth": 30, "environmental_protection": 2, @@ -2260,7 +2285,7 @@ "to_hit": -3, "revert_to": "knit_scarf", "use_action": { "type": "transform", "msg": "You wrap your scarf tighter.", "target": "knit_scarf", "menu_text": "Wrap tighter" }, - "covers": [ "MOUTH" ], + "covers": [ "mouth" ], "flags": [ "OUTER", "ALLOWS_NATURAL_ATTACKS" ], "warmth": 15, "environmental_protection": 1, @@ -2283,7 +2308,7 @@ "volume": "1250 ml", "to_hit": -3, "use_action": { "type": "transform", "msg": "You loosen your %s.", "target": "long_knit_scarf_loose", "menu_text": "Loosen" }, - "covers": [ "MOUTH" ], + "covers": [ "mouth" ], "flags": [ "OVERSIZE", "POCKETS", "OUTER" ], "warmth": 30, "environmental_protection": 2, @@ -2308,7 +2333,7 @@ "to_hit": -3, "use_action": { "type": "transform", "msg": "You wrap your scarf tighter.", "target": "long_knit_scarf", "menu_text": "Wrap tighter" }, "revert_to": "long_knit_scarf", - "covers": [ "MOUTH" ], + "covers": [ "mouth" ], "flags": [ "OVERSIZE", "POCKETS", "OUTER", "ALLOWS_NATURAL_ATTACKS" ], "warmth": 15, "environmental_protection": 1, @@ -2331,7 +2356,7 @@ "volume": "750 ml", "to_hit": -3, "use_action": { "type": "transform", "msg": "You loosen your %s.", "target": "scarf_loose", "menu_text": "Loosen" }, - "covers": [ "MOUTH" ], + "covers": [ "mouth" ], "flags": [ "OUTER" ], "warmth": 50, "environmental_protection": 2, @@ -2356,7 +2381,7 @@ "to_hit": -3, "revert_to": "scarf", "use_action": { "type": "transform", "msg": "You wrap your scarf a bit tighter.", "target": "scarf", "menu_text": "Wrap tighter" }, - "covers": [ "MOUTH" ], + "covers": [ "mouth" ], "flags": [ "OUTER", "ALLOWS_NATURAL_ATTACKS" ], "warmth": 25, "environmental_protection": 1, @@ -2379,7 +2404,7 @@ "volume": "1250 ml", "to_hit": -3, "use_action": { "type": "transform", "msg": "You loosen your %s.", "target": "scarf_long_loose", "menu_text": "Loosen" }, - "covers": [ "MOUTH" ], + "covers": [ "mouth" ], "flags": [ "OVERSIZE", "POCKETS", "OUTER" ], "warmth": 50, "environmental_protection": 2, @@ -2404,7 +2429,7 @@ "to_hit": -3, "use_action": { "type": "transform", "msg": "You wrap your scarf tighter.", "target": "scarf_long", "menu_text": "Wrap tighter" }, "revert_to": "scarf_long", - "covers": [ "MOUTH" ], + "covers": [ "mouth" ], "flags": [ "OVERSIZE", "POCKETS", "OUTER", "ALLOWS_NATURAL_ATTACKS" ], "warmth": 25, "environmental_protection": 1, @@ -2427,7 +2452,7 @@ "volume": "1 L", "to_hit": -3, "use_action": { "type": "transform", "msg": "You loosen your %s.", "target": "scarf_fur_loose", "menu_text": "Loosen" }, - "covers": [ "MOUTH" ], + "covers": [ "mouth" ], "flags": [ "OUTER" ], "warmth": 70, "environmental_protection": 3, @@ -2452,7 +2477,7 @@ "to_hit": -3, "revert_to": "scarf_fur", "use_action": { "type": "transform", "msg": "You wrap your scarf a bit tighter.", "target": "scarf_fur", "menu_text": "Wrap tighter" }, - "covers": [ "MOUTH" ], + "covers": [ "mouth" ], "flags": [ "OUTER", "ALLOWS_NATURAL_ATTACKS" ], "warmth": 35, "environmental_protection": 2, @@ -2475,7 +2500,7 @@ "volume": "2 L", "to_hit": -3, "use_action": { "type": "transform", "msg": "You loosen your %s.", "target": "scarf_fur_long_loose", "menu_text": "Loosen" }, - "covers": [ "MOUTH" ], + "covers": [ "mouth" ], "flags": [ "OVERSIZE", "POCKETS", "OUTER" ], "warmth": 70, "environmental_protection": 3, @@ -2500,7 +2525,7 @@ "to_hit": -3, "use_action": { "type": "transform", "msg": "You wrap your scarf tighter.", "target": "scarf_fur_long", "menu_text": "Wrap tighter" }, "revert_to": "scarf_fur_long", - "covers": [ "MOUTH" ], + "covers": [ "mouth" ], "flags": [ "OVERSIZE", "POCKETS", "OUTER", "ALLOWS_NATURAL_ATTACKS" ], "warmth": 35, "environmental_protection": 2, @@ -2531,7 +2556,7 @@ "need_charges": 1, "need_charges_msg": "The %s's batteries are dead." }, - "covers": [ "HEAD", "MOUTH", "TORSO", "ARMS", "LEGS", "HANDS", "FEET" ], + "covers": [ "head", "mouth", "torso", "arm_l", "arm_r", "leg_l", "leg_r", "hand_l", "hand_r", "foot_l", "foot_r" ], "warmth": 10, "coverage": 100, "material_thickness": 1, @@ -2557,7 +2582,7 @@ "power_draw": 130000, "revert_to": "thermal_outfit", "use_action": { "type": "transform", "menu_text": "Turn off", "msg": "Your %s deactivates.", "target": "thermal_outfit" }, - "covers": [ "HEAD", "MOUTH", "TORSO", "ARMS", "LEGS", "HANDS", "FEET" ], + "covers": [ "head", "mouth", "torso", "arm_l", "arm_r", "leg_l", "leg_r", "hand_l", "hand_r", "foot_l", "foot_r" ], "warmth": 60 }, { @@ -2567,7 +2592,7 @@ "category": "clothing", "weight": "86 g", "color": "dark_gray", - "covers": [ "HEAD", "MOUTH" ], + "covers": [ "head", "mouth" ], "use_action": { "type": "transform", "menu_text": "Loosen", @@ -2594,7 +2619,7 @@ "category": "clothing", "weight": "86 g", "color": "dark_gray", - "covers": [ "HEAD", "MOUTH" ], + "covers": [ "head", "mouth" ], "use_action": { "type": "transform", "menu_text": "Tighten", @@ -2648,8 +2673,7 @@ "category": "tools", "weight": "200 g", "color": "brown", - "covers": [ "HEAD" ], - "initial_charges": 1, + "covers": [ "head" ], "use_action": { "type": "musical_instrument", "speed_penalty": 10, @@ -2676,9 +2700,8 @@ "category": "tools", "weight": "2500 g", "color": "brown", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "to_hit": 2, - "initial_charges": 1, "use_action": { "type": "musical_instrument", "speed_penalty": 15, @@ -2713,9 +2736,8 @@ "category": "tools", "weight": "2250 g", "color": "red", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "to_hit": 2, - "initial_charges": 1, "use_action": { "type": "musical_instrument", "speed_penalty": 15, @@ -2755,9 +2777,8 @@ "category": "tools", "weight": "2300 g", "color": "green", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "to_hit": -2, - "initial_charges": 1, "use_action": { "type": "musical_instrument", "speed_penalty": 15, @@ -2795,10 +2816,9 @@ "category": "tools", "weight": "10000 g", "color": "yellow", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "flags": [ "BELTED", "SLEEP_IGNORE" ], "to_hit": -1, - "initial_charges": 1, "use_action": { "type": "musical_instrument", "speed_penalty": 25, @@ -2830,10 +2850,9 @@ "category": "tools", "weight": "2000 g", "color": "yellow", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "flags": [ "BELTED", "SLEEP_IGNORE" ], "to_hit": 1, - "initial_charges": 1, "use_action": { "type": "musical_instrument", "speed_penalty": 18, @@ -2887,7 +2906,7 @@ "need_charges": 1, "need_charges_msg": "The earmuff's batteries are dead." }, - "covers": [ "HEAD" ], + "covers": [ "head" ], "warmth": 5, "encumbrance": 5, "coverage": 10, @@ -2931,7 +2950,7 @@ "ammo": "battery", "revert_to": "powered_earmuffs", "use_action": { "type": "transform", "menu_text": "Turn off", "msg": "The %s flicks off.", "target": "powered_earmuffs" }, - "covers": [ "HEAD" ], + "covers": [ "head" ], "warmth": 5, "encumbrance": 5, "coverage": 10, @@ -2949,7 +2968,7 @@ "material": [ "plastic", "aluminum" ], "weight": "150 g", "volume": "250 ml", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "encumbrance": 1, "flags": [ "BELTED", "SAFECRACK" ], "coverage": 5 @@ -2966,7 +2985,7 @@ "material": [ "plastic" ], "weight": "400 g", "volume": "500 ml", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "encumbrance": 3, "flags": [ "BELTED", "SAFECRACK" ], "coverage": 8 @@ -2985,7 +3004,7 @@ "material": [ "glass", "steel" ], "symbol": "[", "color": "light_gray", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 40, "encumbrance": 12, "material_thickness": 3, @@ -3007,7 +3026,7 @@ "material": [ "glass", "steel" ], "symbol": "[", "color": "blue", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 40, "encumbrance": 20, "material_thickness": 1, @@ -3032,7 +3051,7 @@ "material": [ "plastic", "steel" ], "symbol": "[", "color": "dark_gray", - "covers": [ "HEAD", "EYES", "MOUTH" ], + "covers": [ "head", "eyes", "mouth" ], "coverage": 95, "encumbrance": 20, "warmth": 10, @@ -3058,7 +3077,7 @@ "material": [ "plastic", "steel" ], "symbol": "[", "color": "dark_gray", - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 95, "encumbrance": 20, "warmth": 10, @@ -3083,12 +3102,13 @@ "material": [ "steel", "plastic" ], "symbol": ";", "color": "light_gray", + "max_charges": 60, "initial_charges": 60, "ammo": "nitrox", "pocket_data": [ { "pocket_type": "MAGAZINE", "airtight": true, "rigid": true, "watertight": true, "ammo_restriction": { "nitrox": 60 } } ], - "covers": [ "TORSO" ], + "covers": [ "torso" ], "flags": [ "WATER_FRIENDLY", "BELTED", "ONLY_ONE", "STURDY", "NO_UNLOAD" ], "environmental_protection": 1, "environmental_protection_with_filter": 16, @@ -3120,7 +3140,7 @@ ], "charges_per_use": 1, "turns_per_charge": 60, - "covers": [ "TORSO", "MOUTH" ], + "covers": [ "torso", "mouth" ], "flags": [ "WATER_FRIENDLY", "BELTED", "ONLY_ONE", "STURDY", "NO_UNLOAD" ], "environmental_protection": 1, "environmental_protection_with_filter": 16, @@ -3150,7 +3170,7 @@ { "pocket_type": "MAGAZINE", "airtight": true, "rigid": true, "watertight": true, "ammo_restriction": { "nitrox": 20 } } ], "max_charges": 20, - "covers": [ "TORSO" ], + "covers": [ "torso" ], "flags": [ "WATER_FRIENDLY", "BELTED", "ONLY_ONE", "STURDY", "NO_UNLOAD" ], "environmental_protection": 1, "environmental_protection_with_filter": 16, @@ -3182,7 +3202,7 @@ ], "charges_per_use": 1, "turns_per_charge": 60, - "covers": [ "TORSO", "MOUTH" ], + "covers": [ "torso", "mouth" ], "flags": [ "WATER_FRIENDLY", "BELTED", "ONLY_ONE", "STURDY", "NO_UNLOAD" ], "environmental_protection": 1, "environmental_protection_with_filter": 16, @@ -3204,7 +3224,7 @@ "material": [ "cotton" ], "symbol": "[", "color": "brown", - "covers": [ "TORSO", "ARMS", "HANDS", "LEGS", "FEET" ], + "covers": [ "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ], "coverage": 100, "encumbrance": 35, "warmth": 50, @@ -3258,7 +3278,7 @@ "material": [ "cotton", "plastic" ], "symbol": "Q", "color": "pink", - "covers": [ "HEAD", "MOUTH", "EYES" ], + "covers": [ "head", "eyes", "mouth" ], "coverage": 100, "encumbrance": 30, "warmth": 50, diff --git a/data/json/mapgen/house/urban_10_house_brick_pool.json b/data/json/mapgen/house/urban_10_house_brick_pool.json new file mode 100644 index 0000000000000..4f2c1201c879a --- /dev/null +++ b/data/json/mapgen/house/urban_10_house_brick_pool.json @@ -0,0 +1,174 @@ +[ + { + "method": "json", + "om_terrain": [ [ "urban_10_1", "urban_10_2" ] ], + "type": "mapgen", + "object": { + "fill_ter": "t_floor", + "rows": [ + ".......................``.......................", + ".......................``````````````````````...", + ".....................[.``.[.................`...", + ".........%%%..%%%......``......%%%..%%%.....`...", + ".......###o####o###....``....###o####o###...`...", + ".......#y y#....``....#R #...`...", + ".......# hffh J#``````````#R HH x#...`...", + "......%# hffh J#``````````#R H l x#%..`...", + "......%o hffh y###o#**#o### H l xo%..`...", + "..[...%#R iiiL iii H y#%..`...", + ".......#R ET #...`...", + "......^#|||7,AA,,,||+|| ||+||||+|||||||#^..`...", + ".......#6,|F,JJ,,,|U q|><|t,S|T R#%..`[..", + "$$$ƃ$$$#6,+,,,,,,,############E hr #$$$ƃ$$$", + "$......#6,|1O523,Y#``GKG`````* rrr R#%..`..$", + "$......######o##*##``````````##o######o##...`..$", + "$.............%```````~~~~```````%...%%%....`..$", + "$.............%``````~~~~~~``````%......X..``..$", + "$........[....%```~~~~~~~~~~~~```%..[......`.[.$", + "$.............%```~~~~~~~~~~~~``````````````...$", + "$...[.........%```~~~~~~~~~~~~```..........`...$", + "$.............%``````````````````%......[..`...$", + "$.............%%%%%%%%%%%%%%%%%%%%.........`...$", + "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ƃ$$$$" + ], + "palettes": [ + "standard_domestic_palette", + "standard_domestic_lino_kitchen", + "standard_domestic_lino_bathroom", + "standard_domestic_landscaping_palette" + ], + "terrain": { + ",": "t_linoleum_gray", + "K": "t_concrete", + "G": "t_concrete", + "Y": "t_linoleum_gray", + "A": "t_linoleum_gray", + "$": "t_privacy_fence", + "~": "t_water_pool_outdoors", + "ƃ": "t_privacy_fencegate_c" + }, + "place_loot": [ { "item": "television", "x": 39, "y": 7, "chance": 100 }, { "item": "stereo", "x": 39, "y": 8, "chance": 50 } ] + } + }, + { + "method": "json", + "om_terrain": [ [ "urban_10_3", "urban_10_4" ] ], + "type": "mapgen", + "object": { + "fill_ter": "t_floor", + "rows": [ + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~####o##o####~~~~~~~~~~####o##o####~~~~~~~", + "~~~~~~~# I@@@I b|D#~~~~~~~~~~#R yssY RRR#~~~~~~~", + "~~~~~~~o @@@ + #~~~~~~~~~~o o~~~~~~~", + "~~~~~~~# @@@ |D#~~~~~~~~~~#R R#~~~~~~~", + "~~~~~~~#d ||###o####o### EsE R#~~~~~~~", + "~~~~~~~#d + iiy R#~~~~~~~", + "~~~~~~^#|+||dd|||+| |+|||||||||#^~~~~~~", + "~~~~~~~#S,,||||S,,|||+| |+||| ddT Ir#~~~~~~~", + "~~~~~~~#8,,+,w|8,,+w|q|y>|U|D+ hI#~~~~~~~", + "~~~~~~~ot,,||||t,B############@ Io~~~~~~~", + "~~~~~~~#8BB|U +,,B#~~~~~~~~~~#@s s@@ ≠#~~~~~~~", + "~~~~~~~###o####o###~~~~~~~~~~###o####o###~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" + ], + "palettes": [ "standard_domestic_palette", "standard_domestic_lino_kitchen", "standard_domestic_lino_bathroom" ], + "terrain": { "~": "t_open_air", ",": "t_linoleum_gray" } + } + }, + { + "method": "json", + "om_terrain": [ [ "urban_10_5", "urban_10_6" ] ], + "type": "mapgen", + "object": { + "fill_ter": "t_shingle_flat_roof", + "rows": [ + " ", + " ", + " ", + " ", + " |22222222223 |22222222223 ", + " |..........3 |..........3 ", + " |.......N..3 |..........3 ", + " |..........3 |......=...3 ", + " |..........32222222222|..........3 ", + " |................................3 ", + " 5.......X...................&....5 ", + " |................................3 ", + " |................................3 ", + " |..........------------..........3 ", + " |..........3 |..........3 ", + " |----------- |----------3 ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " " + ], + "palettes": [ "roof_palette" ], + "terrain": { ".": "t_shingle_flat_roof" } + } + }, + { + "method": "json", + "om_terrain": [ [ "urban_10_7", "urban_10_8" ] ], + "type": "mapgen", + "object": { + "fill_ter": "t_thconc_floor", + "rows": [ + " ", + " ", + " ", + " ", + " |||||||||||| |||||||||||| ", + " |2.........| |1.........| ", + " |..........| |..........| ", + " |..........||||||||||||..........| ", + " |...........zzWJJZ.UU............| ", + " |................................| ", + " |................................| ", + " |................................| ", + " |...............<..gF............| ", + " |..........||||||||||||..........| ", + " |..........| |..........| ", + " |||||||||||| |||||||||||| ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " " + ], + "palettes": [ "basement_empty" ], + "nested": { + "1": { + "chunks": [ + [ "null", 70 ], + [ "room_10x10_woodworker_W", 20 ], + [ "room_10x10_guns_W", 7 ], + [ "room_10x10_junk_W", 30 ], + [ "room_10x10_recording_studio_W", 20 ] + ] + }, + "2": { + "chunks": [ [ "null", 70 ], [ "room_10x10_woodworker_E", 20 ], [ "room_10x10_guns_E", 5 ], [ "room_10x10_pool_E", 5 ] ] + } + } + } + } +] diff --git a/data/json/mapgen/house/urban_11_house_brick.json b/data/json/mapgen/house/urban_11_house_brick.json new file mode 100644 index 0000000000000..f0aaa24f059bf --- /dev/null +++ b/data/json/mapgen/house/urban_11_house_brick.json @@ -0,0 +1,129 @@ +[ + { + "method": "json", + "om_terrain": [ [ "urban_11_1", "urban_11_2" ] ], + "type": "mapgen", + "object": { + "fill_ter": "t_floor", + "rows": [ + "...............................p________........", + "..............[...............%.________.%......", + "................................________........", + "..............................%.________.%......", + ".......[........................________........", + "....................[...........________.%...[..", + ".........................```````________........", + ".........................```````________.%......", + "..........%%..%..%..%..%.```...&________........", + "..........%#####o#######o#*#####========##......", + "...........#yTE HH L + Q|&'''''''''#%.....", + "...[.......#x l H ||||''''''''''o%.....", + "...........#x l H |q'+''''''''''#%.....", + "...........o AAA <| |+||||'''''''''q#......", + "...........#|||JJJ| ||| |,,,B|'''''''''q#......", + "...........#F,,,,,,,,66| |S8tB|'''''''''q#......", + "..........^#7,,,,,,,,,,,,||||||''''''''''#^.....", + "...........o5,,,,,hffh,,,+ +''''''''''o......", + "..........%#12O34,hffh,,Y| WZ|'NN''''''g#%.....", + "..........%########oo#####*#o######o######%.....", + "..........%%%.....%%%%..`````...........%%%.....", + ".....[..................`````...................", + ".............................................[..", + "................................................" + ], + "palettes": [ + "standard_domestic_palette", + "standard_domestic_lino_kitchen", + "standard_domestic_lino_bathroom", + "standard_domestic_landscaping_palette" + ], + "terrain": { + ",": "t_linoleum_gray", + "h": "t_linoleum_gray", + "f": "t_linoleum_gray", + "'": "t_thconc_floor", + "Q": "t_floor", + "g": "t_thconc_floor", + "=": "t_door_metal_locked", + "&": "t_gates_control_brick", + "q": "t_thconc_floor", + "N": "t_thconc_floor", + "Y": "t_linoleum_gray" + }, + "place_loot": [ { "item": "television", "x": 12, "y": 11, "chance": 100 }, { "item": "stereo", "x": 12, "y": 12, "chance": 50 } ], + "place_vehicles": [ { "vehicle": "suburban_home", "x": 35, "y": 13, "chance": 100, "rotation": 270 } ] + } + }, + { + "method": "json", + "om_terrain": [ [ "urban_11_3", "urban_11_4" ] ], + "type": "mapgen", + "object": { + "fill_ter": "t_floor", + "rows": [ + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&~~~~~~", + "~~~~~~~~~~~&&&&#oo#&&&&&#ooo#&&&&&#oo#&&&&~~~~~~", + "~~~~~~~~~~~#####ii#######iii#######ii#####~~~~~~", + "~~~~~~~~~~~#Dbdd + |rII s#~~~~~~", + "~~~~~~~~~~~# |>||||||| |Ih @@@#~~~~~~", + "~~~~~~~~~~~o |||8S8S8| + @@@o~~~~~~", + "~~~~~~~~~~^# @@ + |,,,,,|||D s#^~~~~~", + "~~~~~~~~~~~#I@@I R|D|t,,,,,,+ db #~~~~~~", + "~~~~~~~~~~~#####HH#######BBB#######HH#####~~~~~~", + "~~~~~~~~~~~&&&&#oo#&&&&&#ooo#&&&&&#oo#&&&&~~~~~~", + "~~~~~~~~~~~&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" + ], + "palettes": [ "standard_domestic_palette", "standard_domestic_lino_kitchen", "standard_domestic_lino_bathroom" ], + "terrain": { "~": "t_open_air", "&": "t_shingle_flat_roof", ",": "t_linoleum_gray" } + } + }, + { + "method": "json", + "om_terrain": [ [ "urban_11_5", "urban_11_6" ] ], + "type": "mapgen", + "object": { + "fill_ter": "t_shingle_flat_roof", + "rows": [ + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " 2222 22222 2222 ", + " |2222..2222222...2222222..22223 ", + " |.............................3 ", + " |.............................3 ", + " |.............................3 ", + " |....&....................N...3 ", + " 5............=................5 ", + " |----..-------...-------..----3 ", + " ---- ----- ---- ", + " ", + " ", + " ", + " ", + " " + ], + "palettes": [ "roof_palette" ], + "terrain": { ".": "t_shingle_flat_roof" } + } + } +] diff --git a/data/json/mapgen/house/urban_12_house.json b/data/json/mapgen/house/urban_12_house.json new file mode 100644 index 0000000000000..ef9851e4dc901 --- /dev/null +++ b/data/json/mapgen/house/urban_12_house.json @@ -0,0 +1,136 @@ +[ + { + "method": "json", + "om_terrain": [ [ "urban_12_1", "urban_12_2" ] ], + "type": "mapgen", + "object": { + "fill_ter": "t_floor", + "rows": [ + "........________..............p.``..............", + "........________...............%``%.........[...", + ".....[..________...............````.............", + "........________.......%..%..##''''##..%..%.....", + "........________&....###oo#####o**o#####oo###...", + "......##========##...# c| |T xxxx #...", + "......#'''''''''&#...# hffh sL|E o...", + "......#''''''''''o...# hffh | ||| #...", + "......o''''''''''#%.%# hffh |<| | H ll H#...", + ".....^#N'''''''''#%%%# ||| HHHHHH#^..", + "......#N'''''''''##o## xxx|w+ o...", + "......#N'''''''''|U'U| |||||||| | RR #...", + "......o''''''''''+'''+ ciic ###oo######...", + "......#''''''''''|W'Z| #'''GKG''$....", + "......#'''''''qqq##*##|+||,,,,,,,,1''''''''$....", + "......####o##o####```#,,,|6,,,,,,Y#''''''''ƃ....", + "...[..............```#t,S|6,,,JJ,no''₸''₸'y$....", + "................%%```#||||,,,,JJ,5o''''''''$....", + "................%%```#,,,+,,,,,,,2#''y''y''$....", + "............[........#666|JJF34O71#$$$ƃ$$$$#....", + ".....................#####o##o#####.............", + "................................................", + ".....[....................................[.....", + "................................................" + ], + "palettes": [ + "standard_domestic_palette", + "standard_domestic_lino_kitchen", + "standard_domestic_lino_bathroom", + "standard_domestic_landscaping_palette" + ], + "terrain": { + ",": "t_linoleum_gray", + "h": "t_carpet_purple", + "f": "t_carpet_purple", + "'": "t_thconc_floor", + "K": "t_thconc_floor", + "Z": "t_thconc_floor", + "₸": "t_thconc_floor", + "W": "t_thconc_floor", + "U": "t_thconc_floor", + "G": "t_thconc_floor", + "N": "t_thconc_floor", + "y": "t_thconc_floor", + "q": "t_thconc_floor", + "=": "t_door_metal_locked", + "&": "t_gates_control_brick", + "ƃ": "t_screen_door_c", + "$": "t_screened_porch_wall", + "Y": "t_linoleum_gray" + }, + "place_loot": [ { "item": "television", "x": 40, "y": 5, "chance": 100 }, { "item": "stereo", "x": 41, "y": 5, "chance": 50 } ], + "place_vehicles": [ { "vehicle": "suburban_home", "x": 11, "y": 9, "chance": 100, "rotation": 270 } ] + } + }, + { + "method": "json", + "om_terrain": [ [ "urban_12_3", "urban_12_4" ] ], + "type": "mapgen", + "object": { + "fill_ter": "t_floor", + "rows": [ + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~&&&&&&&&~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~##o##########o###o###o##~~~", + "~~~~~~####o##o####~~~# R|t,B|D|M I@@@I T #~~~", + "~~~~~~# sDd |89#~~~# R|8,B| + @@@ #~~~", + "~~~~~~o +,,#~~~# |S,,|||Ø @@@ o~~~", + "~~~~~~#s hr |St#~~~#s ||+||>|E #~~~", + "~~~~~~#@@ r |||#~~~#E |D o~~~", + "~~~~~^#@@ + #:::# + hI#^~~", + "~~~~~~#|||||||| iii |||||||dbd IrI#~~~", + "~~~~~~#I PP| |B8S88|||###o###o###~~~", + "~~~~~~oIh + iii y|B,,,t| U#&&&&&&&&&~~~~", + "~~~~~~#rI RRR|yy#:::#|+||||+|||+|#&&&&&&&&&~~~~", + "~~~~~~####o##o####~~~#d ∞ D#&&&&&&&&&~~~~", + "~~~~~~~~~~~~~~~~~~~~~ob ≠#&&&&&&&&&~~~~", + "~~~~~~~~~~~~~~~~~~~~~#d o&&&&&&&&&~~~~", + "~~~~~~~~~~~~~~~~~~~~~o @@ hI#&&&&&&&&&~~~~", + "~~~~~~~~~~~~~~~~~~~~~# d@@d IrI#&&&&&&&&&~~~~", + "~~~~~~~~~~~~~~~~~~~~~###o######o###~~~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" + ], + "palettes": [ "standard_domestic_palette", "standard_domestic_lino_kitchen", "standard_domestic_lino_bathroom" ], + "terrain": { "~": "t_open_air", "&": "t_shingle_flat_roof", ",": "t_linoleum_gray" } + } + }, + { + "method": "json", + "om_terrain": [ [ "urban_12_5", "urban_12_6" ] ], + "type": "mapgen", + "object": { + "fill_ter": "t_shingle_flat_roof", + "rows": [ + " ", + " ", + " ", + " ", + " |22222222222222222222222 ", + " |22222222223 |......................3 ", + " |..........3 |......................3 ", + " |..........3 |......................3 ", + " |..........3 |.........N............3 ", + " 5..........3 |......................5 ", + " |....:.....3222|......................3 ", + " |.....................................3 ", + " |...........................3---------3 ", + " |....=......................3 ", + " |..........3---|.........&..3 ", + " |----------3 |............3 ", + " |............3 ", + " |............3 ", + " |............3 ", + " |............3 ", + " |------------3 ", + " ", + " ", + " " + ], + "palettes": [ "roof_palette" ], + "terrain": { ".": "t_shingle_flat_roof" } + } + } +] diff --git a/data/json/mapgen/house/urban_15_house.json b/data/json/mapgen/house/urban_15_house.json new file mode 100644 index 0000000000000..a9a3e633117f4 --- /dev/null +++ b/data/json/mapgen/house/urban_15_house.json @@ -0,0 +1,139 @@ +[ + { + "method": "json", + "om_terrain": [ [ "urban_15_1", "urban_15_2" ] ], + "type": "mapgen", + "object": { + "fill_ter": "t_floor", + "rows": [ + "..................................._______.p....", + ".............[....................._______......", + "...````````````````````````````````_______......", + "...`[........!!!!!!!...'''......```_______......", + "...`...#######o##o#####'''.%%%%%```_______&.....", + "...`.!.#BB,8| s@@ II|D##*###ooo##*#=======##....", + "...`.!.o,,,S| @@ h + |L 1235n4|'''''''''&#....", + "...`.!.#t,,S|E ||| ,,,,,7|''''''''''#....", + "...`.!.#Y,,8|T dby|U+ ,AJJ,O|''''''''''#....", + "...`.!.#w|+|||+||||||||R ,AJJ,J|'''''''''q#....", + "...`.!.#|| < ,AJJ,J|'''''''''q#....", + "...`.!.#D| ,,,,,F|'''''''''N#^...", + "...`.!.#+||||+||y |'''''''''N#....", + "...`...# II T|x l H hffh ||+||||||||#....", + "$$$ƃ$$$#d h |x l H hffh g#$ƃ$$", + "$......#b @@ |x H hffh |+||+|| 0#...$", + "$.....^# s@@sy|T HHHH E|6|t,S|WZ00#...$", + "$......##o###o####ooo####o#::#o#########oo##...$", + "$.................!!!....``````................$", + "$....[...................``````...u............$", + "$.........X...........................[........$", + "$..............................................$", + "$..................[...........................$", + "$$$$$$$$$$$$$$$$$$$$$$$$$$ƃ$$$$$$$$$$$$$$$$$$$$$" + ], + "palettes": [ + "standard_domestic_palette", + "standard_domestic_lino_kitchen", + "standard_domestic_lino_bathroom", + "standard_domestic_landscaping_palette" + ], + "terrain": { + ",": "t_linoleum_gray", + ":": "t_door_glass_c", + "'": "t_thconc_floor", + "N": "t_thconc_floor", + "q": "t_thconc_floor", + "=": "t_door_metal_locked", + "&": "t_gates_control_brick", + "ƃ": "t_privacy_fencegate_c", + "$": "t_privacy_fence", + "Y": "t_linoleum_gray", + "A": "t_linoleum_gray" + }, + "furniture": { "0": "f_counter" }, + "place_loot": [ { "item": "television", "x": 16, "y": 14, "chance": 100 }, { "item": "stereo", "x": 16, "y": 15, "chance": 50 } ], + "place_vehicles": [ { "vehicle": "suburban_home", "x": 37, "y": 9, "chance": 50, "rotation": 270 } ] + } + }, + { + "method": "json", + "om_terrain": [ [ "urban_15_3", "urban_15_4" ] ], + "type": "mapgen", + "object": { + "fill_ter": "t_floor", + "rows": [ + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~%%%~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~$%%%%%%%%%%%%%%%%&_~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~$&&&&&&&&&&&&&&&&&%%%%%%%%%%%%%%%%%%_~~~~", + "~~~~~~~$&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&_~~~~", + "~~~~~~~$&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&_~~~~", + "~~~~~~~$&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&_~~~~", + "~~~~~~~$&&&&&&&#########oo###&&&&&&&&&&&&&&_~~~~", + "~~~~~~~$&&&&&&S8|>|by RR#&&&&&&&&&&&&&&_~~~~", + "~~~~~~~$&&&&&&&o,,,+ + #&&&&&&&&&&&&&&_~~~~", + "~~~~~~~$&&&&&&&o,,B||| @@ #&&&&&&&&&&&&&&!~~~~", + "~~~~~~~$&&&&&&&#t,B|D+ I@@Id#^&&&&&&&&&&&&&_~~~~", + "~~~~~~~$&&&&&&&########o##o##&&&&&&&&&&&&&&_~~~~", + "~~~~~~~$&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&_~~~~", + "~~~~~~~!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&_~~~~", + "~~~~~~~$-----------------------------------_~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" + ], + "palettes": [ "standard_domestic_palette", "standard_domestic_lino_kitchen", "standard_domestic_lino_bathroom" ], + "terrain": { + "~": "t_open_air", + "&": "t_shingle_flat_roof", + ",": "t_linoleum_gray", + "!": "t_gutter_drop", + "%": "t_gutter_north", + "-": "t_gutter_south", + "_": "t_gutter_east", + "$": "t_gutter_west" + } + } + }, + { + "method": "json", + "om_terrain": [ [ "urban_15_5", "urban_15_6" ] ], + "type": "mapgen", + "object": { + "fill_ter": "t_shingle_flat_roof", + "rows": [ + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " |2222222222223 ", + " |............3 ", + " |..&.........3 ", + " |.......N....3 ", + " |...=........5 ", + " |------------3 ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " " + ], + "palettes": [ "roof_palette" ], + "terrain": { ".": "t_shingle_flat_roof" } + } + } +] diff --git a/data/json/mapgen/house/urban_16_house_ranch.json b/data/json/mapgen/house/urban_16_house_ranch.json new file mode 100644 index 0000000000000..9ac2de6d0218d --- /dev/null +++ b/data/json/mapgen/house/urban_16_house_ranch.json @@ -0,0 +1,98 @@ +[ + { + "method": "json", + "om_terrain": [ [ "urban_16_1", "urban_16_2" ] ], + "type": "mapgen", + "object": { + "fill_ter": "t_floor", + "rows": [ + ".......________.......p.```.....................", + ".......________.........```.....................", + "....%..________..####oo##*####o#######o###...[..", + "...%%%.________.##y L|@@sy|98|≠II @#......", + "....%..________.#a HH R||| +,,+ h @#......", + ".......________.## lH x|d+ ≠ |St| T#......", + ".......________..#x H R||||||+||||+||+|#......", + "..[....________..# |d D#......", + ".......________.!#1,,,0f0||+|||||||+|||||#......", + ".......________.!o5,,,0f0|t,S|D + b s#......", + "....%..________.!#O,,,,,,||||||||d @@#......", + "...%%%.________..#2347,,Y|,,,,,,+ h @@#...[..", + "....%..________&%#|||F,,6|t|BB8S|yTII s#^.....", + ".....##========###WZ|J,,6##########oo##o##......", + "....^#'''''''''&'#,,+,,,,*'''₸K₸'''''$..........", + ".....#'''''''''''#|||| ###'''''''''''$..........", + ".....o'''''''''''# #'''''''''''''$..........", + ".....#'''''''''''+ ||+|#'''#$$$$ƃ$$$$#..........", + ".....#N''''''''''#||L *'''$!!!```!!!.....%.....", + ".....oN''''''''''#U+ ii#'''$...```.......%%%....", + ".....#N'''''''''q####o##$$$#......u.......%.....", + ".[...#''''''''''q#..............................", + ".....#############..............[...............", + "................................................" + ], + "palettes": [ + "standard_domestic_palette", + "standard_domestic_lino_kitchen", + "standard_domestic_lino_bathroom", + "standard_domestic_landscaping_palette" + ], + "terrain": { + ",": "t_linoleum_gray", + "Z": "t_linoleum_gray", + "0": "t_linoleum_gray", + "f": "t_linoleum_gray", + "W": "t_linoleum_gray", + "₸": "t_thconc_floor", + "K": "t_thconc_floor", + "'": "t_thconc_floor", + "N": "t_thconc_floor", + "q": "t_thconc_floor", + "=": "t_door_metal_locked", + "&": "t_gates_control_brick", + "ƃ": "t_screen_door_c", + "$": "t_screened_porch_wall", + "Y": "t_linoleum_gray" + }, + "furniture": { "0": "f_chair" }, + "place_loot": [ { "item": "television", "x": 18, "y": 6, "chance": 100 }, { "item": "stereo", "x": 24, "y": 5, "chance": 50 } ], + "place_vehicles": [ { "vehicle": "suburban_home", "x": 10, "y": 5, "chance": 100, "rotation": 270 } ] + } + }, + { + "method": "json", + "om_terrain": [ [ "urban_16_3", "urban_16_4" ] ], + "type": "mapgen", + "object": { + "fill_ter": "t_shingle_flat_roof", + "rows": [ + " ", + " ", + " |222222222222222222222223 ", + " ||.......................3 ", + " |~.......................3 ", + " ||.......................3 ", + " |.......................3 ", + " |......&.........N......3 ", + " |.......................3 ", + " |.......................3 ", + " |.......................3 ", + " |......=................3 ", + " |.......................5 ", + " |22222222222|...................3---3 ", + " 5................X..............3 ", + " |...............................3 ", + " |...............................3 ", + " |.....................3---------3 ", + " |.....................3 ", + " |.....................3 ", + " |...........3---------3 ", + " |...........3 ", + " |-----------3 ", + " " + ], + "palettes": [ "roof_palette" ], + "terrain": { ".": "t_shingle_flat_roof" } + } + } +] diff --git a/data/json/mapgen/house/urban_17_house_ranch.json b/data/json/mapgen/house/urban_17_house_ranch.json new file mode 100644 index 0000000000000..7411b5fde119b --- /dev/null +++ b/data/json/mapgen/house/urban_17_house_ranch.json @@ -0,0 +1,102 @@ +[ + { + "method": "json", + "om_terrain": [ [ "urban_17_1", "urban_17_2" ] ], + "type": "mapgen", + "object": { + "fill_ter": "t_floor", + "rows": [ + ".._________p...........``.......................", + ".._________.....#$$$$$$ƃƃ$$$$$$###oo###.........", + ".._________.....$''GKG'''''''''#D ER#^........", + ".._________.....###*####oo#oo###d #.........", + ".._________.....#L+ + | @@ o......[..", + ".._________...###||||| HH | @@s #.........", + ".._________...# E|x lH |+|||||#.........", + ".._________...o rrr |x lH | +,,,B#.........", + ".._________...o rE | HH | |S8tB#.........", + ".._________...# RR + | |||||#.........", + ".._________...#||||||| |BB|t#.........", + ".._________...#6,,,,,,,,, | |,,+,#.........", + ".._________...oZ,|4,,JJJ, hffh |+|,8||#.........", + ".._________...oW,|O,,,,,, hffh | +,S|D#.........", + "..__________..#0,|125n3F, | ||||+#...[.....", + "..___________.#|+||||||##::;::## II #.........", + "..___________&#&'''''''#```````# E R#.........", + "..____________=''''''''#^``````#d o.........", + "..____________='''''''U#```````#b @@ o.........", + "..____________='''''''U#```````#T @@s #.........", + "...___________=''''''''o```````##o##o##.........", + ".[..__________=''''''''#....................[...", + "..............####o#####........................", + "................................................" + ], + "palettes": [ + "standard_domestic_palette", + "standard_domestic_lino_kitchen", + "standard_domestic_lino_bathroom", + "standard_domestic_landscaping_palette" + ], + "terrain": { + ",": "t_linoleum_gray", + "Z": "t_linoleum_gray", + "0": "t_linoleum_gray", + "f": "t_carpet_green", + "h": "t_carpet_green", + "W": "t_linoleum_gray", + "₸": "t_thconc_floor", + "U": "t_thconc_floor", + "K": "t_thconc_floor", + "G": "t_thconc_floor", + "'": "t_thconc_floor", + "N": "t_thconc_floor", + "q": "t_thconc_floor", + "=": "t_door_metal_locked", + "&": "t_gates_control_brick", + "ƃ": "t_screen_door_c", + ";": "t_door_glass_c", + "$": "t_screened_porch_wall", + "Y": "t_linoleum_gray" + }, + "furniture": { "0": "f_counter" }, + "place_loot": [ { "item": "television", "x": 22, "y": 6, "chance": 100 }, { "item": "stereo", "x": 22, "y": 7, "chance": 50 } ], + "place_vehicles": [ { "vehicle": "suburban_home", "x": 5, "y": 10, "chance": 100, "rotation": 100 } ] + } + }, + { + "method": "json", + "om_terrain": [ [ "urban_17_3", "urban_17_4" ] ], + "type": "mapgen", + "object": { + "fill_ter": "t_shingle_flat_roof", + "rows": [ + " ", + " |2222222222222222222223 ", + " |.....................5 ", + " |.....................3 ", + " |.....................3 ", + " |2|.....................3 ", + " |.........N.............3 ", + " |.......................3 ", + " |...........X......&....3 ", + " |.......................3 ", + " |.......................3 ", + " |.......................3 ", + " |...................=...3 ", + " |.......................3 ", + " |.......................3 ", + " |........3-------|......3 ", + " |........3 |......3 ", + " |........5 |......3 ", + " |........3 |......3 ", + " |........3 |......3 ", + " |........3 |------3 ", + " |........3 ", + " |--------3 ", + " " + ], + "palettes": [ "roof_palette" ], + "terrain": { ".": "t_shingle_flat_roof" } + } + } +] diff --git a/data/json/mapgen/house/urban_18_victorian.json b/data/json/mapgen/house/urban_18_victorian.json new file mode 100644 index 0000000000000..482de29e1753d --- /dev/null +++ b/data/json/mapgen/house/urban_18_victorian.json @@ -0,0 +1,209 @@ +[ + { + "method": "json", + "om_terrain": [ [ "urban_18_1", "urban_18_2" ] ], + "type": "mapgen", + "object": { + "fill_ter": "t_thconc_floor", + "rows": [ + " ", + " ", + " ", + " ", + " ||||| ", + " |:::| ||||| ", + " |||:::||| |...| ", + " |:::::::| |||...||| ", + " |:::::::||||||||||||UU...JJ| ", + " |:::::::::::::::::::....A.J||| ", + " |||:::::::::::::||||........Z| ", + " |::::::||||::::|<.........W| ", + " ||:||||||||::|||||.......||| ", + " |::::zz||||::|F.g|:||:||:| ", + " |:::::z::::::|...|:::::::| ", + " |:::::::::|::||+||::zz:::| ", + " |:::::::::|:::::::::z::::| ", + " |||||:::||||||||||:::::::| ", + " |:::| |:::::::| ", + " ||||| ||||||||| ", + " ", + " ", + " ", + " " + ], + "palettes": [ "basement_empty" ], + "terrain": { ":": "t_dirtfloor", "z": "t_dirtfloor", "|": "t_rock_wall" }, + "place_loot": [ { "item": "basket_laundry", "x": 36, "y": 9, "chance": 75 } ] + } + }, + { + "method": "json", + "om_terrain": [ [ "urban_18_3", "urban_18_4" ] ], + "type": "mapgen", + "weight": 250, + "object": { + "fill_ter": "t_floor", + "rows": [ + "......................p``.......................", + ".$$$$$$$$$$$$$$$$$$$$$$``$$$$$$$$$$$$$$$$$$$$$$.", + ".$....................$``$....................$.", + ".$....[....!!!!!!!.....``.....................$.", + ".$.........!##o##!.....``.....!!!!!!!.........$.", + ".$.........!oyxyo!!....``.....!#o#o#!....[....$.", + ".$........### ###''''''''''!!oiiio!.........$.", + ".$........# hhh #''''''''''### ###........$.", + ".$........o hfffh ##o##**##o## #........$.", + ".$........# hhh + THHHH #o#......$.", + ".$........### |+| L||||E llH ro%.....$.", + ".$..........# |U|''' <|>+ hro%.....$.", + ".$..........#|+||||#a#| ||||| #o#%.....$.", + ".$.....[....#3,J74|###| |B,t|RRxxxRR#........$.", + ".$.....%%%..o5,,,,,,,,+ |B,S||||||||#..[.....$.", + ".$....`````!on,,,,||+|| ||+||y s@@sT#........$.", + ".$......%%`!#12OF,|6,6| + @@ o........$.", + ".$.......!`!#####,||####o#*###E o........$.", + ".$.......!`!!!!`*,,<#''''''''#R Dbd y#.....[..$.", + ".$..[....!``````#####''''''''##o###o##........$.", + ".$........[....`````^```......................$.", + ".$............................................$.", + ".$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$.", + "................................................" + ], + "palettes": [ + "standard_domestic_palette", + "standard_domestic_lino_kitchen", + "standard_domestic_lino_bathroom", + "standard_domestic_landscaping_palette" + ], + "terrain": { "#": "t_rock_wall", "$": "t_drystone_wall_half", "'": "t_thconc_floor", ",": "t_linoleum_gray" }, + "furniture": { "0": "f_counter" }, + "place_nested": [ { "chunks": [ [ "greenhouse_6x6_herbal", 100 ] ], "x": 3, "y": 15 } ], + "place_loot": [ + { "item": "television", "x": 33, "y": 13, "chance": 100 }, + { "item": "stereo", "x": 34, "y": 13, "chance": 50 }, + { "item": "hose", "x": 12, "y": 18, "chance": 100 }, + { "item": "lawnmower", "x": 38, "y": 18, "chance": 75 } + ] + } + }, + { + "method": "json", + "om_terrain": [ [ "urban_18_5", "urban_18_6" ] ], + "type": "mapgen", + "object": { + "fill_ter": "t_floor", + "rows": [ + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~##o##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~oIrIo~~~~~~~~~~~~~~#o#o#~~~~~~~~~~~~", + "~~~~~~~~~~###IhI###&&&&&&&&&&~~oHHHo~~~~~~~~~~~~", + "~~~~~~~~~~#PP H#&&&&&&&&&&### l ###~~~~~~~~~~", + "~~~~~~~~~~o H##o######o##Dy dT#~~~~~~~~~~", + "~~~~~~~~~~#TE c ii c | #o#~~~~~~~~", + "~~~~~~~~~~###|+||+| + hIo~~~~~~~~", + "~~~~~~~~~~~~oS,t|U|### |> <| @@ Io~~~~~~~~", + "~~~~~~~~~~~~#||||||#a# ||||| s@@s #o#~~~~~~~~", + "~~~~~~~~~~~~#RRyTRR#'#|++|MMM||||||||#~~~~~~~~~~", + "~~~~~~~~~~~~o H |ÆsØ #~~~~~~~~~~", + "~~~~~~~~~~~~o h H ee #~~~~~~~~~~", + "~~~)))))~~~~# rr EsE TRRRR|0A ee o~~~~~~~~~~", + "~~~)))))~~~~#####|+|##o#######0AA ee o~~~~~~~~~~", + "~~~)))))~~~~~~~~#< >#&&&&^&&� #~~~~~~~~~~", + "~~~)))))~~~~~~~~##o##_:______##o###o##~~~~~~~~~~", + "~~~)))))~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" + ], + "palettes": [ "standard_domestic_palette", "standard_domestic_lino_kitchen", "standard_domestic_lino_bathroom" ], + "terrain": { + "~": "t_open_air", + "'": "t_thconc_floor", + ",": "t_linoleum_gray", + "&": "t_shingle_flat_roof", + ":": "t_gutter_drop", + "_": "t_gutter_south", + "#": "t_rock_wall", + ")": "t_glass_roof" + }, + "furniture": { "0": "f_counter" }, + "place_loot": [ { "item": "stereo", "x": 30, "y": 18, "chance": 50 } ] + } + }, + { + "method": "json", + "om_terrain": [ [ "urban_18_7", "urban_18_8" ] ], + "type": "mapgen", + "object": { + "fill_ter": "t_floor", + "rows": [ + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~##o##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~oHHHo~~~~~~~~~~~~~~#o#o#~~~~~~~~~~~~", + "~~~~~~~~~~### ###~~~~~~~~~~~~oHHHo~~~~~~~~~~~~", + "~~~~~~~~~~#H x#~~~~~~~~~~### ###~~~~~~~~~~", + "~~~~~~~~~~oH x#####o###o##Db yd#~~~~~~~~~~", + "~~~~~~~~~~#H |D|8S8| | #o#~~~~~~~~", + "~~~~~~~~~~### + +,,,| + Io~~~~~~~~", + "~~~~~~~~~~~~#s y###,,t| |>| @@ hIo~~~~~~~~", + "~~~~~~~~~~~~#@@ 'a#BBB| |||Ts@@s #o#~~~~~~~~", + "~~~~~~~~~~~~#@@ y###|||| ||||||||#~~~~~~~~~~", + "~~~~~~~~~~~~#s c|T + s@@s #~~~~~~~~~~", + "~~~~~~~~~~~~o || ||+|| @@ #~~~~~~~~~~", + "~~~~~~~~~~~~#dbd + yY|S,t|E o~~~~~~~~~~", + "~~~~~~~~~~~~#####||+##o####o## o~~~~~~~~~~", + "~~~~~~~~~~~~~~~~#> #~~~^~~~~#D ≠c≠ d#~~~~~~~~~~", + "~~~~~~~~~~~~~~~~##o##~~~~~~~~##o###o##~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" + ], + "palettes": [ "standard_domestic_palette", "standard_domestic_lino_kitchen", "standard_domestic_lino_bathroom" ], + "terrain": { "~": "t_open_air", ",": "t_linoleum_gray", "'": "t_thconc_floor", "#": "t_rock_wall" }, + "place_loot": [ { "item": "television", "x": 17, "y": 8, "chance": 100 } ] + } + }, + { + "method": "json", + "om_terrain": [ [ "urban_18_9", "urban_18_10" ] ], + "type": "mapgen", + "object": { + "fill_ter": "t_shingle_flat_roof", + "rows": [ + " ", + " ", + " ", + " ", + " |2223 ", + " |...3 |2223 ", + " |2|...323 |...3 ", + " |.......3 |2|...323 ", + " |.......32222222222|.......3 ", + " |..........................323 ", + " |--....=.....................3 ", + " |..........................3 ", + " |................&.......3-3 ", + " |...........~............3 ", + " |........................3 ", + " |....N...................3 ", + " |........................3 ", + " |---|...----5----|.......3 ", + " |...3 |.......3 ", + " |---3 |-------3 ", + " ", + " ", + " ", + " " + ], + "palettes": [ "roof_palette" ], + "terrain": { ".": "t_shingle_flat_roof" } + } + } +] diff --git a/data/json/mapgen/house/urban_8_house_brick_garden.json b/data/json/mapgen/house/urban_8_house_brick_garden.json new file mode 100644 index 0000000000000..e93d9c73091a0 --- /dev/null +++ b/data/json/mapgen/house/urban_8_house_brick_garden.json @@ -0,0 +1,144 @@ +[ + { + "method": "json", + "om_terrain": [ [ "urban_8_1", "urban_8_2" ] ], + "type": "mapgen", + "weight": 250, + "object": { + "fill_ter": "t_floor", + "rows": [ + "....................................`p..........", + ".~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`~~~~~~~~~~.", + ".~....................`````````````````.......~.", + ".~.............%%.....`.........!!`````.......~.", + ".~.....%%...[..%%.....`.....####((##*#######..~.", + ".~.....%%.............`.....#R E s L|S8,t#..~.", + ".~....................`.....#x lH +,,,,(..~.", + ".~........`````````````.....#x lH |+|||#..~.", + ".~....................`.....(y <|w|bD#..~.", + ".~...............0000.`.....#|||||| |||||+|#..~.", + ".~...............0000.`....^#F66JJ| |TE R#^.~.", + ".~...............0000.`.....#,,,,, + d(!.~.", + ".~...............0000.`.....*,,,,1|+| @@ #!.~.", + ".~...............0000.``````(453O2|U|Y @@s (!.~.", + ".~........`..............`..##(######(######..~.", + ".~.......................`....................~.", + ".~.....%.................`..u.................~.", + ".~.....%...........[.....`......00000.........~.", + ".~.....%..............)))])))...00000.........~.", + ".~...............%%...)q:::W)...00000....[....~.", + ".~...............%%...)q:::Z)...00000.........~.", + ".~....................)q:::g).................~.", + ".~~~~~~~~~~~~~~~~~~~~~)))))))~~~~~~~~~~~~~~~~~~.", + "................................................" + ], + "palettes": [ + "standard_domestic_palette", + "standard_domestic_lino_kitchen", + "standard_domestic_lino_bathroom", + "standard_domestic_landscaping_palette" + ], + "terrain": { + "(": "t_window_bars_curtains", + ")": "t_scrap_wall", + "0": "t_dirtmound", + ":": "t_metal_floor", + "g": "t_metal_floor", + "Z": "t_metal_floor", + "W": "t_metal_floor", + "q": "t_metal_floor", + "]": "t_door_metal_pickable", + "~": "t_drystone_wall_half", + ";": "t_dirtfloor", + ",": "t_linoleum_gray", + "$": "t_reinforced_glass_shutter", + "}": "t_reinforced_door_glass_c" + }, + "place_nested": [ + { "chunks": [ [ "greenhouse_6x6_herbal", 100 ] ], "x": 8, "y": 8 }, + { "chunks": [ [ "greenhouse_6x6_vegetable", 100 ] ], "x": 8, "y": 15 } + ], + "place_loot": [ + { "item": "television", "x": 29, "y": 6, "chance": 100 }, + { "item": "stereo", "x": 29, "y": 7, "chance": 50 }, + { "item": "hose", "x": 21, "y": 21, "chance": 100 }, + { "item": "lawnmower", "x": 25, "y": 21, "chance": 75 }, + { "item": "basket_laundry", "x": 26, "y": 21, "chance": 75 } + ] + } + }, + { + "method": "json", + "om_terrain": [ [ "urban_8_3", "urban_8_4" ] ], + "type": "mapgen", + "weight": 250, + "object": { + "fill_ter": "t_floor", + "rows": [ + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~&&&&&#oooo#&&&&&~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~##oo##TIIy######~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~#s Db h |D D#~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~#@@ ||||+||#~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~#@@ |>| d@#~~~~", + "~~~~~~~~`````~~~~~~~~~~~~~~~od RR + + @o~~~~", + "~~~~~~~~`````~~~~~~~~~~~~~~~#|+|||||| |Ih ≠#~~~~", + "~~~~~~~~`````~~~~~~~~~~~~~~^#U |BtS|+|I #^~~~", + "~~~~~~~~`````~~~~~~~~~~~~~~~#q |B,,,,| @@d#~~~~", + "~~~~~~~~`````~~~~~~~~~~~~~~~#######o###o####~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~&&&&&&&&&&&&&&&&~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~`````~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~`````~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~`````~~~~~~~~~&&&&&&&~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~`````~~~~~~~~~&&&&&&&~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~`````~~~~~~~~~&&&&&&&~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~&&&&&&&~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~&&&&&&&~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" + ], + "palettes": [ "standard_domestic_palette", "standard_domestic_lino_kitchen", "standard_domestic_lino_bathroom" ], + "terrain": { "~": "t_open_air", "&": "t_shingle_flat_roof", ",": "t_linoleum_gray", "`": "t_glass_roof" } + } + }, + { + "method": "json", + "om_terrain": "urban_8_6", + "type": "mapgen", + "weight": 250, + "object": { + "fill_ter": "t_shingle_flat_roof", + "rows": [ + " ", + " ", + " ", + " ", + " 222222 ", + " |22222....222223 ", + " |..............3 ", + " |..............3 ", + " |.........N....3 ", + " |...........=..3 ", + " |..............3 ", + " 5....X.....&...5 ", + " |..............3 ", + " |--------------3 ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " " + ], + "palettes": [ "roof_palette" ], + "terrain": { ".": "t_shingle_flat_roof" } + } + } +] diff --git a/data/json/mapgen_palettes/house_general_palette.json b/data/json/mapgen_palettes/house_general_palette.json index b3d66129f9ce2..6b9c170336600 100644 --- a/data/json/mapgen_palettes/house_general_palette.json +++ b/data/json/mapgen_palettes/house_general_palette.json @@ -168,7 +168,7 @@ { "item": "cleaning", "chance": 30, "repeat": [ 1, 2 ] }, { "item": "bed", "chance": 30, "repeat": [ 1, 2 ] } ], - "R": [ { "item": "homebooks", "chance": 30, "repeat": [ 1, 4 ] }, { "item": "games", "chance": 30, "repeat": [ 1, 2 ] } ], + "R": [ { "item": "homebooks", "chance": 40, "repeat": [ 1, 4 ] }, { "item": "games", "chance": 20, "repeat": [ 1, 2 ] } ], "S": [ { "item": "SUS_bathroom_sink", "chance": 80 }, { "item": "SUS_bathroom_medicine", "chance": 60 } ], "U": [ { "item": "home_hw", "chance": 20, "repeat": [ 1, 2 ] }, @@ -259,5 +259,18 @@ "Q": "t_linoleum_gray", "w": "t_linoleum_gray" } + }, + { + "type": "palette", + "id": "standard_domestic_landscaping_palette", + "//": "Intended to be used in conjunction with standard_domestic_palette. Load the domestic palette first, then this one to use open symbols for landscaping.", + "terrain": { + "%": [ "t_region_shrub", "t_region_shrub_fruit", "t_region_shrub_decorative" ], + "[": [ [ "t_region_tree_fruit", 2 ], [ "t_region_tree_nut", 2 ], "t_region_tree_shade" ], + "!": "t_region_groundcover_urban", + "_": "t_pavement", + "`": "t_concrete" + }, + "furniture": { "!": "f_region_flower" } } ] diff --git a/data/json/monsters/bird.json b/data/json/monsters/bird.json index 476baa968cd5a..ac17edcadcd4e 100644 --- a/data/json/monsters/bird.json +++ b/data/json/monsters/bird.json @@ -152,7 +152,7 @@ "type": "MONSTER", "copy-from": "mon_turkey", "name": { "str": "pheasant" }, - "description": "A medium sized game bird that can have bright feathers depending on the sex and species.", + "description": "A medium-sized game bird that can have bright feathers depending on the sex and species.", "volume": "750 ml", "weight": "1 kg", "hp": 6, diff --git a/data/json/monsters/fish.json b/data/json/monsters/fish.json index a4b815e9549d2..7a4da42b7cfd8 100644 --- a/data/json/monsters/fish.json +++ b/data/json/monsters/fish.json @@ -3,7 +3,7 @@ "id": "mon_alpha_razorclaw", "type": "MONSTER", "name": { "str": "alpha razorclaw" }, - "description": "A blood red, gigantic razorclaw. Its sword like pincers serve as the keepers of the nest.", + "description": "A blood-red, gigantic razorclaw. Its sword like pincers serve as the keepers of the nest.", "default_faction": "razorclaw", "bodytype": "crab", "species": [ "MUTANT" ], diff --git a/data/json/monsters/insect_spider.json b/data/json/monsters/insect_spider.json index 418edaecae37b..389ee3822e6c9 100644 --- a/data/json/monsters/insect_spider.json +++ b/data/json/monsters/insect_spider.json @@ -112,7 +112,7 @@ "id": "mon_worm_small", "type": "MONSTER", "name": { "str": "large worm" }, - "description": "A disturbingly large mutated subterannean creature similar to a nightcrawler. It possesses a fanged mouth and a long slender body that comes up to your knees, with even more surely hiding underground.", + "description": "A disturbingly large mutated subterranean creature similar to a nightcrawler. It possesses a fanged mouth and a long slender body that comes up to your knees, with even more surely hiding underground.", "copy-from": "mon_halfworm", "looks_like": "mon_worm", "upgrades": { "half_life": 14, "into": "mon_worm" } diff --git a/data/json/monsters/mammal.json b/data/json/monsters/mammal.json index 0186c4fb0d277..8c72cc23a4b68 100644 --- a/data/json/monsters/mammal.json +++ b/data/json/monsters/mammal.json @@ -375,7 +375,7 @@ "type": "MONSTER", "copy-from": "mon_cat", "name": "Siamese cat", - "description": "This cat has the distinctive dark extremeties of a Siamese, first native to Asia but a common domestic breed in North America.", + "description": "This cat has the distinctive dark extremities of a Siamese, first native to Asia but a common domestic breed in North America.", "reproduction": { "baby_monster": "mon_cat_siamese_kitten", "baby_count": 4, "baby_timer": 60 } }, { @@ -1325,7 +1325,7 @@ "id": "mon_dog_gshepherd", "copy-from": "mon_dog", "type": "MONSTER", - "name": { "str": "German shepherd" }, + "name": { "str": "German Shepherd" }, "description": "The original K-9 breed. An easy to train and great attack dog that will also defend its owner to the death, however they don't work well in packs.", "volume": "35000 ml", "weight": "35 kg", @@ -1342,8 +1342,8 @@ { "id": "mon_dog_gshepherd_pup", "type": "MONSTER", - "name": { "str": "German shepherd puppy", "str_pl": "German shepherd puppies" }, - "description": "An adorable, defenseless German shepherd puppy. Much safer to tame than an adult dog.", + "name": { "str": "German Shepherd puppy", "str_pl": "German Shepherd puppies" }, + "description": "An adorable, defenseless German Shepherd puppy. Much safer to tame than an adult dog.", "default_faction": "dog", "bodytype": "dog", "categories": [ "WILDLIFE" ], @@ -1826,7 +1826,7 @@ "id": "mon_muskrat", "type": "MONSTER", "name": { "str": "muskrat" }, - "description": "A large omnivorous rodent with a thick furry pelt, found in wetlands across the northern hemisphere. It marks its territory with a musky odor for which it is named.", + "description": "A large omnivorous rodent with a thick furry pelt, found in wetlands across the Northern Hemisphere. It marks its territory with a musky odor for which it is named.", "default_faction": "small_animal", "bodytype": "pig", "categories": [ "WILDLIFE" ], @@ -2163,7 +2163,7 @@ "id": "mon_sheep", "type": "MONSTER", "name": { "str_sp": "sheep" }, - "description": "A timid, hooved grazing mammal, and one of the first animals ever domesticated. Its body is covered in a thick layer of wool, and the males have long, spiralling horns.", + "description": "A timid, hooved grazing mammal, and one of the first animals ever domesticated. Its body is covered in a thick layer of wool, and the males have long, spiraling horns.", "default_faction": "herbivore", "bodytype": "dog", "categories": [ "WILDLIFE" ], diff --git a/data/json/monsters/zanimal_upgrade.json b/data/json/monsters/zanimal_upgrade.json index 22d9ebe4ee1cb..eee3025fb11d7 100644 --- a/data/json/monsters/zanimal_upgrade.json +++ b/data/json/monsters/zanimal_upgrade.json @@ -156,7 +156,7 @@ "type": "MONSTER", "name": { "str": "skeletal zombear" }, "copy-from": "mon_zombear", - "description": "A monstrous overgrowth of ossified tissue has replaced this zombear's rotting skin with an organic armor of dense bone. Large clumps of black goo seep from its joints as it shambles aimlessly, with sickening crackling sounds filling the air around it.", + "description": "A monstrous overgrowth of ossified tissue has replaced this zombear's rotting skin with an organic armor of dense bone. Large clumps of black goo seep from its joints as it shambles aimlessly, with sickening crackling sounds filling the surrounding air.", "hp": 70, "speed": 100, "material": [ "bone" ], diff --git a/data/json/monsters/zed-animal.json b/data/json/monsters/zed-animal.json index a3a6da67eb13d..4cd8a60e8aa28 100644 --- a/data/json/monsters/zed-animal.json +++ b/data/json/monsters/zed-animal.json @@ -64,7 +64,7 @@ "id": "mon_dog_zombie_cop", "type": "MONSTER", "name": { "str": "Z-9" }, - "description": "A zombified version of one of the German shepherd dogs used in law enforcement. Its deformed body is encased in a protective Kevlar harness.", + "description": "A zombified version of one of the German Shepherd dogs used in law enforcement. Its deformed body is encased in a protective Kevlar harness.", "default_faction": "zombie", "bodytype": "dog", "categories": [ "CLASSIC" ], diff --git a/data/json/monsters/zed_misc.json b/data/json/monsters/zed_misc.json index 80a6225190837..eaf6df31bb35b 100644 --- a/data/json/monsters/zed_misc.json +++ b/data/json/monsters/zed_misc.json @@ -607,7 +607,7 @@ "id": "mon_zombie_master", "type": "MONSTER", "name": { "str": "zombie master" }, - "description": "Once human, its features have tightened, its lips pulled back into an unnatural grin, revealing rows of blackened teeth beneath its large, piercing eyes. It stands tall and its movements are fluid and tightly controlled. A feeling of danger permeates the air around it, and the light that falls on it seems somehow harsher and more glaring.", + "description": "Once human, its features have tightened, its lips pulled back into an unnatural grin, revealing rows of blackened teeth beneath its large, piercing eyes. It stands tall and its movements are fluid and tightly controlled. A feeling of danger permeates the surrounding air, and the light that falls on it seems somehow harsher and more glaring.", "default_faction": "zombie", "bodytype": "human", "species": [ "ZOMBIE", "HUMAN" ], @@ -657,7 +657,7 @@ "id": "mon_zombie_necro", "type": "MONSTER", "name": { "str": "zombie necromancer" }, - "description": "A twisted mockery of the human form, emaciated, with jet black skin and glowing red eyes. It is somehow painful to look at, awakening fears deep within your psyche, and even the air around it seems more sinister, somehow darker and more dangerous.", + "description": "A twisted mockery of the human form, emaciated, with jet black skin and glowing red eyes. It is somehow painful to look at, awakening fears deep within your psyche, and even the surrounding air seems more sinister, somehow darker and more dangerous.", "default_faction": "zombie", "bodytype": "human", "species": [ "ZOMBIE", "HUMAN" ], diff --git a/data/json/monsters/zed_skeletal.json b/data/json/monsters/zed_skeletal.json index 77a8ee3ac6e01..6530c044e0e9d 100644 --- a/data/json/monsters/zed_skeletal.json +++ b/data/json/monsters/zed_skeletal.json @@ -3,7 +3,7 @@ "id": "mon_skeleton", "type": "MONSTER", "name": { "str": "skeleton" }, - "description": "A monstrous overgrowth of ossified tissue has replaced this zombie's rotting skin with an organic armor of dense bone. Large clumps of black goo seep from its joints as it shambles aimlessly, with sickening crackling sounds filling the air around it.", + "description": "A monstrous overgrowth of ossified tissue has replaced this zombie's rotting skin with an organic armor of dense bone. Large clumps of black goo seep from its joints as it shambles aimlessly, with sickening crackling sounds filling the surrounding air.", "default_faction": "zombie", "bodytype": "human", "species": [ "ZOMBIE", "HUMAN" ], diff --git a/data/json/mutations/mutations.json b/data/json/mutations/mutations.json index a501522c8174d..faac2805dafa1 100644 --- a/data/json/mutations/mutations.json +++ b/data/json/mutations/mutations.json @@ -2535,7 +2535,7 @@ "points": 9, "visibility": 12, "ugliness": 6, - "description": "You leaves are vibrant, large, and green, and have become a major source of nutrition for your body. Whenever your arms and head are uncovered you will gain a large amount of nutrition by standing in the sunlight. Reduces wet effects.", + "description": "Your leaves are vibrant, large, and green, and have become a major source of nutrition for your body. Whenever your arms and head are uncovered you will gain a large amount of nutrition by standing in the sunlight. Reduces wet effects.", "prereqs": [ "LEAVES2" ], "prereqs2": [ "TRANSPIRATION" ], "threshreq": [ "THRESH_PLANT" ], @@ -2609,7 +2609,7 @@ "points": 6, "visibility": 5, "ugliness": 3, - "description": "Local organisms seem to regard open spore-dispersal as a danger, and attack the Mycus. Accordingly our local spore sacs remain quiescent, until local guidance determines that it is safe to germinate. Rapid development taxes local nutrient reserves but ensures swift and effective growth.", + "description": "Local organisms seem to regard open spore-dispersal as a danger, and attack the Mycus. Accordingly, our local spore sacs remain quiescent, until local guidance determines that it is safe to germinate. Rapid development taxes local nutrient reserves but ensures swift and effective growth.", "valid": false, "changes_to": [ "M_PROVENANCE" ], "prereqs": [ "M_SPORES" ], @@ -2644,7 +2644,7 @@ "points": 6, "visibility": 10, "ugliness": 1, - "description": "Local organisms seem to regard open spore-dispersal as a danger, and attack the Mycus. Accordingly our local blossoms remain quiescent, until local guidance determines that it is safe to germinate. Rapid development taxes local nutrient reserves but ensures swift and effective growth.", + "description": "Local organisms seem to regard open spore-dispersal as a danger, and attack the Mycus. Accordingly, our local blossoms remain quiescent, until local guidance determines that it is safe to germinate. Rapid development taxes local nutrient reserves but ensures swift and effective growth.", "valid": false, "changes_to": [ "M_PROVENANCE" ], "cancels": [ "M_SPORES", "M_FERTILE" ], @@ -2769,7 +2769,7 @@ "cut_dmg_bonus": 3, "pierce_dmg_bonus": 3, "butchering_quality": 4, - "description": "Sharp claws are exten from the end of your fingers.", + "description": "Sharp claws are extending from the end of your fingers.", "transform": { "target": "CLAWS_RETRACT", "msg_transform": "You retract your claws.", "active": false, "moves": 10 }, "cost": 0 }, @@ -3673,7 +3673,7 @@ "id": "NOPAIN", "name": { "str": "Deadened" }, "points": 2, - "description": "Nothing hurts any more. Those bites tickle and the wounds itch a bit, but that's it.", + "description": "Nothing hurts anymore. Those bites tickle and the wounds itch a bit, but that's it.", "valid": false, "purifiable": false, "prereqs": [ "MASOCHIST", "PAINRESIST" ], @@ -4049,7 +4049,7 @@ "id": "WEB_RAPPEL", "name": { "str": "Web Diver" }, "points": 2, - "description": "Your webbing is easily strong enough to support your weight. You'll use it to descend down any sheer drops you may encounter.", + "description": "Your webbing is easily strong enough to support your weight. You'll use it to descend any sheer drops you may encounter.", "prereqs": [ "WEB_WEAVER" ], "threshreq": [ "THRESH_SPIDER" ], "category": [ "SPIDER" ] @@ -6153,7 +6153,7 @@ "id": "THRESH_SPIDER", "name": { "str": "Arachnid" }, "points": 1, - "description": "Well, maybe you'll just have to make your own world wide web.", + "description": "Well, maybe you'll just have to make your own world-wide web.", "valid": false, "purifiable": false, "threshold": true @@ -6296,7 +6296,7 @@ "points": 2, "visibility": 3, "ugliness": 4, - "description": "Like a true fish, your eyes lack eyelids, and are are instead covered by a translucent, protective membrane that blocks irritants and water, and provides minor armor. It also allows you to sleep with your eyes open! Activate to cause the approach of hostile creatures to wake you up.", + "description": "Like a true fish, your eyes lack eyelids, and are instead covered by a translucent, protective membrane that blocks irritants and water, and provides minor armor. It also allows you to sleep with your eyes open! Activate to cause the approach of hostile creatures to wake you up.", "category": [ "FISH" ], "threshreq": [ "THRESH_FISH" ], "armor": [ { "parts": "eyes", "cut": 3, "bash": 1 } ], diff --git a/data/json/obsolete.json b/data/json/obsolete.json index 75a53bcd953b1..260f259cfd508 100644 --- a/data/json/obsolete.json +++ b/data/json/obsolete.json @@ -339,11 +339,6 @@ "desc": [ "You took some magnesium supplements. These will help with sleep deprivation." ], "rating": "good" }, - { - "type": "recipe", - "result": "reloaded_270", - "obsolete": true - }, { "id": "tool_rdx_charge", "type": "TOOL", @@ -565,26 +560,6 @@ }, "flags": [ "BOMB", "TRADER_AVOID" ] }, - { - "type": "recipe", - "result": "tool_anfo_charge", - "obsolete": true - }, - { - "type": "recipe", - "result": "tool_rdx_charge", - "obsolete": true - }, - { - "type": "recipe", - "result": "reloaded_laser_pack", - "obsolete": true - }, - { - "type": "recipe", - "result": "unbio_blaster_gun", - "obsolete": true - }, { "id": "bio_blaster", "copy-from": "bionic_general", @@ -729,11 +704,6 @@ "ammo_effects": [ "PLASMA", "EXPLOSIVE", "FLAME", "NEVER_JAMS" ], "flags": [ "NO_UNLOAD" ] }, - { - "type": "recipe", - "result": "fertilizer_bomb", - "obsolete": true - }, { "id": "ftk93", "type": "GUN", @@ -813,11 +783,6 @@ "count": 20, "effects": [ "COOKOFF", "RECYCLED" ] }, - { - "type": "recipe", - "result": "flamethrower_simple", - "obsolete": true - }, { "id": "wheel_steerable", "copy-from": "wheel", @@ -1058,26 +1023,6 @@ }, "flags": [ "BOMB", "TRADER_AVOID", "DANGEROUS" ] }, - { - "result": "double_plutonium_core", - "type": "recipe", - "obsolete": true - }, - { - "result": "ring", - "type": "recipe", - "obsolete": true - }, - { - "result": "pipebomb", - "type": "recipe", - "obsolete": true - }, - { - "result": "tool_black_powder_charge", - "type": "recipe", - "obsolete": true - }, { "id": "tool_black_powder_charge", "type": "TOOL", @@ -1140,66 +1085,6 @@ "react_cost": "2 J", "time": 1 }, - { - "type": "recipe", - "result": "pipe_combination_gun", - "obsolete": true - }, - { - "type": "recipe", - "result": "rifle_308", - "obsolete": true - }, - { - "type": "recipe", - "result": "surv_carbine_223", - "obsolete": true - }, - { - "type": "recipe", - "result": "rifle_3006", - "obsolete": true - }, - { - "type": "recipe", - "result": "tihar", - "obsolete": true - }, - { - "type": "recipe", - "result": "helsing", - "obsolete": true - }, - { - "type": "recipe", - "result": "pneumatic_shotgun", - "obsolete": true - }, - { - "type": "recipe", - "result": "mininuke_launcher", - "obsolete": true - }, - { - "type": "recipe", - "result": "rebar_rifle", - "obsolete": true - }, - { - "type": "recipe", - "result": "heavy_rail_rifle", - "obsolete": true - }, - { - "result": "nailrifle", - "type": "recipe", - "obsolete": true - }, - { - "type": "recipe", - "result": "mininuke_mod", - "obsolete": true - }, { "id": "mounted_mininuke_launcher", "copy-from": "turret", @@ -1662,10 +1547,5 @@ { "item": "scrap", "count": [ 3, 7 ] } ] } - }, - { - "type": "recipe", - "result": "foot_crank", - "obsolete": true } ] diff --git a/data/json/overmap/multitile_city_buildings.json b/data/json/overmap/multitile_city_buildings.json index cd09d4ed715ce..fb18ffba2b3f7 100644 --- a/data/json/overmap/multitile_city_buildings.json +++ b/data/json/overmap/multitile_city_buildings.json @@ -121,6 +121,19 @@ "locations": [ "land" ], "flags": [ "CLASSIC" ] }, + { + "type": "city_building", + "id": "urban_8_house_brick_garden", + "overmaps": [ + { "point": [ 0, 0, 0 ], "overmap": "urban_8_1_north" }, + { "point": [ 1, 0, 0 ], "overmap": "urban_8_2_north" }, + { "point": [ 0, 0, 1 ], "overmap": "urban_8_3_north" }, + { "point": [ 1, 0, 1 ], "overmap": "urban_8_4_north" }, + { "point": [ 1, 0, 2 ], "overmap": "urban_8_6_north" } + ], + "locations": [ "land" ], + "flags": [ "CLASSIC" ] + }, { "type": "city_building", "id": "urban_9_house_garage_loft", @@ -135,6 +148,50 @@ "locations": [ "land" ], "flags": [ "CLASSIC" ] }, + { + "type": "city_building", + "id": "urban_10_house_brick_pool", + "overmaps": [ + { "point": [ 0, 0, 0 ], "overmap": "urban_10_1_north" }, + { "point": [ 1, 0, 0 ], "overmap": "urban_10_2_north" }, + { "point": [ 0, 0, 1 ], "overmap": "urban_10_3_north" }, + { "point": [ 1, 0, 1 ], "overmap": "urban_10_4_north" }, + { "point": [ 0, 0, 2 ], "overmap": "urban_10_5_north" }, + { "point": [ 1, 0, 2 ], "overmap": "urban_10_6_north" }, + { "point": [ 0, 0, -1 ], "overmap": "urban_10_7_north" }, + { "point": [ 1, 0, -1 ], "overmap": "urban_10_8_north" } + ], + "locations": [ "land" ], + "flags": [ "CLASSIC" ] + }, + { + "type": "city_building", + "id": "urban_11_house_brick", + "overmaps": [ + { "point": [ 0, 0, 0 ], "overmap": "urban_11_1_north" }, + { "point": [ 1, 0, 0 ], "overmap": "urban_11_2_north" }, + { "point": [ 0, 0, 1 ], "overmap": "urban_11_3_north" }, + { "point": [ 1, 0, 1 ], "overmap": "urban_11_4_north" }, + { "point": [ 0, 0, 2 ], "overmap": "urban_11_5_north" }, + { "point": [ 1, 0, 2 ], "overmap": "urban_11_6_north" } + ], + "locations": [ "land" ], + "flags": [ "CLASSIC" ] + }, + { + "type": "city_building", + "id": "urban_12_house", + "overmaps": [ + { "point": [ 0, 0, 0 ], "overmap": "urban_12_1_north" }, + { "point": [ 1, 0, 0 ], "overmap": "urban_12_2_north" }, + { "point": [ 0, 0, 1 ], "overmap": "urban_12_3_north" }, + { "point": [ 1, 0, 1 ], "overmap": "urban_12_4_north" }, + { "point": [ 0, 0, 2 ], "overmap": "urban_12_5_north" }, + { "point": [ 1, 0, 2 ], "overmap": "urban_12_6_north" } + ], + "locations": [ "land" ], + "flags": [ "CLASSIC" ] + }, { "type": "city_building", "id": "urban_13_dense_house_apt_house", @@ -177,6 +234,62 @@ "locations": [ "land" ], "flags": [ "CLASSIC" ] }, + { + "type": "city_building", + "id": "urban_15_house", + "overmaps": [ + { "point": [ 0, 0, 0 ], "overmap": "urban_15_1_north" }, + { "point": [ 1, 0, 0 ], "overmap": "urban_15_2_north" }, + { "point": [ 0, 0, 1 ], "overmap": "urban_15_3_north" }, + { "point": [ 1, 0, 1 ], "overmap": "urban_15_4_north" }, + { "point": [ 0, 0, 2 ], "overmap": "urban_15_5_north" }, + { "point": [ 1, 0, 2 ], "overmap": "urban_15_6_north" } + ], + "locations": [ "land" ], + "flags": [ "CLASSIC" ] + }, + { + "type": "city_building", + "id": "urban_16_house_ranch", + "overmaps": [ + { "point": [ 0, 0, 0 ], "overmap": "urban_16_1_north" }, + { "point": [ 1, 0, 0 ], "overmap": "urban_16_2_north" }, + { "point": [ 0, 0, 1 ], "overmap": "urban_16_3_north" }, + { "point": [ 1, 0, 1 ], "overmap": "urban_16_4_north" } + ], + "locations": [ "land" ], + "flags": [ "CLASSIC" ] + }, + { + "type": "city_building", + "id": "urban_17_house_ranch", + "overmaps": [ + { "point": [ 0, 0, 0 ], "overmap": "urban_17_1_north" }, + { "point": [ 1, 0, 0 ], "overmap": "urban_17_2_north" }, + { "point": [ 0, 0, 1 ], "overmap": "urban_17_3_north" }, + { "point": [ 1, 0, 1 ], "overmap": "urban_17_4_north" } + ], + "locations": [ "land" ], + "flags": [ "CLASSIC" ] + }, + { + "type": "city_building", + "id": "urban_18_victorian", + "overmaps": [ + { "point": [ 0, 0, -1 ], "overmap": "urban_18_1_north" }, + { "point": [ 1, 0, -1 ], "overmap": "urban_18_2_north" }, + { "point": [ 0, 0, 0 ], "overmap": "urban_18_3_north" }, + { "point": [ 1, 0, 0 ], "overmap": "urban_18_4_north" }, + { "point": [ 0, 0, 1 ], "overmap": "urban_18_5_north" }, + { "point": [ 1, 0, 1 ], "overmap": "urban_18_6_north" }, + { "point": [ 0, 0, 2 ], "overmap": "urban_18_7_north" }, + { "point": [ 1, 0, 2 ], "overmap": "urban_18_8_north" }, + { "point": [ 0, 0, 3 ], "overmap": "urban_18_9_north" }, + { "point": [ 1, 0, 3 ], "overmap": "urban_18_10_north" } + ], + "locations": [ "land" ], + "flags": [ "CLASSIC" ] + }, { "type": "city_building", "id": "urban_29_dense_row", diff --git a/data/json/overmap/overmap_terrain/overmap_terrain_residential.json b/data/json/overmap/overmap_terrain/overmap_terrain_residential.json index f8eceef6a5716..aecc84ad6b018 100644 --- a/data/json/overmap/overmap_terrain/overmap_terrain_residential.json +++ b/data/json/overmap/overmap_terrain/overmap_terrain_residential.json @@ -172,8 +172,24 @@ "urban_6_2", "urban_7_1", "urban_7_2", + "urban_8_1", + "urban_8_2", "urban_9_1", - "urban_9_2" + "urban_9_2", + "urban_10_1", + "urban_10_2", + "urban_11_1", + "urban_11_2", + "urban_12_1", + "urban_12_2", + "urban_15_1", + "urban_15_2", + "urban_16_1", + "urban_16_2", + "urban_17_1", + "urban_17_2", + "urban_18_3", + "urban_18_4" ], "copy-from": "generic_city_house", "see_cost": 10 @@ -211,10 +227,39 @@ "urban_7_4", "urban_7_5", "urban_7_6", + "urban_8_3", + "urban_8_4", + "urban_8_6", "urban_9_3", "urban_9_4", "urban_9_5", - "urban_9_6" + "urban_9_6", + "urban_10_3", + "urban_10_4", + "urban_10_5", + "urban_10_6", + "urban_11_3", + "urban_11_4", + "urban_11_5", + "urban_11_6", + "urban_12_3", + "urban_12_4", + "urban_12_5", + "urban_12_6", + "urban_15_3", + "urban_15_4", + "urban_15_5", + "urban_15_6", + "urban_16_3", + "urban_16_4", + "urban_17_3", + "urban_17_4", + "urban_18_5", + "urban_18_6", + "urban_18_7", + "urban_18_8", + "urban_18_9", + "urban_18_10" ], "copy-from": "generic_city_house_no_sidewalk", "see_cost": 10 @@ -422,7 +467,11 @@ "urban_7_1_basement", "urban_7_2_basement", "urban_29_1", - "urban_29_2" + "urban_29_2", + "urban_10_7", + "urban_10_8", + "urban_18_1", + "urban_18_2" ], "copy-from": "generic_city_house_basement" }, diff --git a/data/json/player_activities.json b/data/json/player_activities.json index f66090b8e2350..082d3456474dc 100644 --- a/data/json/player_activities.json +++ b/data/json/player_activities.json @@ -29,7 +29,7 @@ { "id": "ACT_MULTIPLE_CONSTRUCTION", "type": "activity_type", - "activity_level": "ACTIVE_EXERCISE", + "activity_level": "BRISK_EXERCISE", "verb": "constructing", "based_on": "neither", "suspendable": false, @@ -57,7 +57,7 @@ { "id": "ACT_VEHICLE_DECONSTRUCTION", "type": "activity_type", - "activity_level": "ACTIVE_EXERCISE", + "activity_level": "BRISK_EXERCISE", "verb": "deconstructing a vehicle", "based_on": "neither", "suspendable": false, @@ -67,7 +67,7 @@ { "id": "ACT_VEHICLE_REPAIR", "type": "activity_type", - "activity_level": "ACTIVE_EXERCISE", + "activity_level": "BRISK_EXERCISE", "verb": "repairing a vehicle", "based_on": "neither", "suspendable": false, @@ -165,14 +165,14 @@ { "id": "ACT_BUTCHER", "type": "activity_type", - "activity_level": "ACTIVE_EXERCISE", + "activity_level": "BRISK_EXERCISE", "verb": "butchering", "based_on": "speed" }, { "id": "ACT_BUTCHER_FULL", "type": "activity_type", - "activity_level": "ACTIVE_EXERCISE", + "activity_level": "BRISK_EXERCISE", "verb": "butchering", "based_on": "speed" }, @@ -214,7 +214,7 @@ { "id": "ACT_LONGSALVAGE", "type": "activity_type", - "activity_level": "ACTIVE_EXERCISE", + "activity_level": "BRISK_EXERCISE", "verb": "salvaging", "based_on": "speed", "no_resume": true, @@ -231,7 +231,7 @@ { "id": "ACT_BUILD", "type": "activity_type", - "activity_level": "ACTIVE_EXERCISE", + "activity_level": "BRISK_EXERCISE", "based_on": "neither", "refuel_fires": true, "auto_needs": true, @@ -240,7 +240,7 @@ { "id": "ACT_VEHICLE", "type": "activity_type", - "activity_level": "ACTIVE_EXERCISE", + "activity_level": "BRISK_EXERCISE", "verb": "interacting with the vehicle", "based_on": "speed" }, @@ -402,7 +402,7 @@ { "id": "ACT_MULTIPLE_FARM", "type": "activity_type", - "activity_level": "ACTIVE_EXERCISE", + "activity_level": "BRISK_EXERCISE", "verb": "farming", "suspendable": false, "based_on": "neither", @@ -672,7 +672,7 @@ { "id": "ACT_PLANT_SEED", "type": "activity_type", - "activity_level": "EXTRA_EXERCISE", + "activity_level": "MODERATE_EXERCISE", "verb": "planting seeds", "based_on": "time" }, diff --git a/data/json/professions.json b/data/json/professions.json index 2a022469d5e8d..20ae7ff9ee423 100644 --- a/data/json/professions.json +++ b/data/json/professions.json @@ -1082,7 +1082,7 @@ "type": "profession", "id": "homeless", "name": "Hobo", - "description": "Society drove you to the fringes and left you with no home, no family, no friends. You found solace in the bottom of a bottle. Well, society doesn't mean a thing anymore, and for all the crap thrown your way, you're still standing. God damn, you need a drink.", + "description": "Society drove you to the fringes and left you with no home, no family, no friends. You found solace in the bottom of a bottle. Well, society doesn't mean a thing anymore, and for all the crap thrown your way, you're still standing. God-damn, you need a drink.", "points": -1, "items": { "both": { @@ -3476,7 +3476,7 @@ "type": "profession", "id": "science_club_mem", "name": "Science Club Member", - "description": "The school never let your club play with the really fun chemicals, the kind that make things go boom, but there aren't any teachers around to enforce the rules any more.", + "description": "The school never let your club play with the really fun chemicals, the kind that make things go boom, but there aren't any teachers around to enforce the rules anymore.", "points": 1, "skills": [ { "level": 1, "name": "chemistry" }, { "level": 1, "name": "mechanics" } ], "items": { diff --git a/data/json/proficiencies/misc.json b/data/json/proficiencies/misc.json index e33065adb881d..1bd4966f937de 100644 --- a/data/json/proficiencies/misc.json +++ b/data/json/proficiencies/misc.json @@ -3,18 +3,32 @@ "type": "proficiency", "id": "prof_knapping", "name": { "str": "Knapping" }, - "description": "The art of turning stones into more useful tools." + "description": "The art of turning stones into more useful tools.", + "can_learn": true, + "time_to_learn": "10 h" }, { "type": "proficiency", "id": "prof_blacksmithing", "name": { "str": "Blacksmithing" }, - "description": "The craft of working metal into tools and other items of use." + "description": "The craft of working metal into tools and other items of use.", + "can_learn": true, + "time_to_learn": "10 h" + }, + { + "type": "proficiency", + "id": "prof_bladesmith", + "name": { "str": "Bladesmithing" }, + "description": "How to fabricate sharp and reliable blades from scratch.", + "can_learn": true, + "time_to_learn": "12 h", + "required_proficiencies": [ "prof_blacksmithing" ] }, { "type": "proficiency", "id": "prof_helicopter_pilot", "name": { "str": "Helicopter Piloting" }, - "description": "Before the cataclysm, you were a helicopter pilot. Now, you just hope you can fly again." + "description": "Before the cataclysm, you were a helicopter pilot. Now, you just hope you can fly again.", + "can_learn": false } ] diff --git a/data/json/recipes/armor/head.json b/data/json/recipes/armor/head.json index a8d29aa576dd5..781b0d6e7fa3d 100644 --- a/data/json/recipes/armor/head.json +++ b/data/json/recipes/armor/head.json @@ -642,7 +642,7 @@ "qualities": [ { "id": "CUT", "level": 1 } ], "components": [ [ [ "cordage_short", 2, "LIST" ], [ "filament", 100, "LIST" ] ], - [ [ "2x4", 1 ], [ "stick", 1 ], [ "bone", 1 ], [ "bone_human", 1 ] ] + [ [ "2x4", 1 ], [ "stick", 1 ], [ "bone_sturdy", 1, "LIST" ] ] ] }, { diff --git a/data/json/recipes/armor/pets_dog.json b/data/json/recipes/armor/pets_dog.json index d1962c99ffd3b..9b1391b98772e 100644 --- a/data/json/recipes/armor/pets_dog.json +++ b/data/json/recipes/armor/pets_dog.json @@ -70,7 +70,7 @@ "difficulty": 2, "time": "30 m", "using": [ [ "sewing_standard", 15 ] ], - "components": [ [ [ "bone", 13 ], [ "bone_human", 13 ], [ "bone_tainted", 25 ] ], [ [ "vest_leather", 1 ] ] ] + "components": [ [ [ "bone", 13 ], [ "bone_human", 13 ], [ "bone_demihuman", 13 ] ], [ [ "vest_leather", 1 ] ] ] }, { "result": "leatherbone_harness_dog", @@ -83,7 +83,7 @@ "time": "15 m", "autolearn": true, "using": [ [ "sewing_standard", 5 ] ], - "components": [ [ [ "bone", 13 ], [ "bone_human", 13 ], [ "bone_tainted", 25 ] ], [ [ "leather_harness_dog", 1 ] ] ] + "components": [ [ [ "bone_sturdy", 13, "LIST" ] ], [ [ "leather_harness_dog", 1 ] ] ] }, { "result": "leatherbone_harness_dog", @@ -97,7 +97,7 @@ "autolearn": true, "book_learn": [ [ "textbook_tailor", 3 ], [ "manual_tailor", 3 ] ], "using": [ [ "sewing_standard", 20 ] ], - "components": [ [ [ "bone", 13 ], [ "bone_human", 13 ], [ "bone_tainted", 25 ] ], [ [ "leather", 6 ], [ "tanned_hide", 1 ] ] ] + "components": [ [ [ "bone_sturdy", 13, "LIST" ] ], [ [ "leather", 6 ], [ "tanned_hide", 1 ] ] ] }, { "result": "rubber_harness_dog", diff --git a/data/json/recipes/armor/pets_horse.json b/data/json/recipes/armor/pets_horse.json index 343944527e500..4063f39ff62f4 100644 --- a/data/json/recipes/armor/pets_horse.json +++ b/data/json/recipes/armor/pets_horse.json @@ -95,7 +95,7 @@ "difficulty": 4, "time": "210 m", "using": [ [ "sewing_standard", 75 ] ], - "components": [ [ [ "bone", 39 ], [ "bone_human", 39 ], [ "bone_tainted", 75 ] ], [ [ "armor_blarmor", 3 ] ] ] + "components": [ [ [ "bone", 39 ], [ "bone_human", 39 ], [ "bone_demihuman", 39 ] ], [ [ "armor_blarmor", 3 ] ] ] }, { "result": "leatherbone_armor_horse", @@ -109,7 +109,7 @@ "autolearn": true, "byproducts": [ [ "rag", 6 ] ], "using": [ [ "sewing_standard", 35 ] ], - "components": [ [ [ "bone", 39 ], [ "bone_human", 39 ], [ "bone_tainted", 75 ] ], [ [ "leather_armor_horse", 1 ] ] ] + "components": [ [ [ "bone_sturdy", 39, "LIST" ] ], [ [ "leather_armor_horse", 1 ] ] ] }, { "result": "leatherbone_armor_horse", @@ -136,7 +136,7 @@ [ [ "water", 30 ], [ "water_clean", 30 ] ], [ [ "wax", 6 ], [ "any_tallow", 24, "LIST" ], [ "vinegar", 30 ], [ "pine_bough", 60 ] ], [ [ "salt", 150 ] ], - [ [ "bone", 39 ], [ "bone_human", 39 ], [ "bone_tainted", 75 ] ], + [ [ "bone_sturdy", 39, "LIST" ] ], [ [ "leather", 105 ], [ "tanned_hide", 17 ] ] ] }, diff --git a/data/json/recipes/basecamps/recipe_modular_canteen/recipe_modular_canteen_common.json b/data/json/recipes/basecamps/recipe_modular_canteen/recipe_modular_canteen_common.json index 9c732166cea9e..ce2e6fa50bf85 100644 --- a/data/json/recipes/basecamps/recipe_modular_canteen/recipe_modular_canteen_common.json +++ b/data/json/recipes/basecamps/recipe_modular_canteen/recipe_modular_canteen_common.json @@ -109,7 +109,7 @@ { "type": "recipe", "result": "faction_base_modular_canteen_counters", - "description": "Lets build some counters and shelves.", + "description": "Let's build some counters and shelves.", "category": "CC_BUILDING", "subcategory": "CSC_BUILDING_BASES", "autolearn": false, diff --git a/data/json/recipes/basecamps/recipe_modular_canteen/recipe_modular_canteen_log.json b/data/json/recipes/basecamps/recipe_modular_canteen/recipe_modular_canteen_log.json index e8934b821aaaf..f27eac50259f3 100644 --- a/data/json/recipes/basecamps/recipe_modular_canteen/recipe_modular_canteen_log.json +++ b/data/json/recipes/basecamps/recipe_modular_canteen/recipe_modular_canteen_log.json @@ -2,7 +2,7 @@ { "type": "recipe", "result": "faction_base_canteen_room_center_log", - "description": "Lets start building the central kitchen log walls.", + "description": "Let's start building the central kitchen log walls.", "category": "CC_BUILDING", "subcategory": "CSC_BUILDING_BASES", "autolearn": false, @@ -32,7 +32,7 @@ { "type": "recipe", "result": "faction_base_canteen_room2_center_log", - "description": "Lets finish the central kitchen log walls.", + "description": "Let's finish the central kitchen log walls.", "category": "CC_BUILDING", "subcategory": "CSC_BUILDING_BASES", "autolearn": false, @@ -62,7 +62,7 @@ { "type": "recipe", "result": "faction_base_canteen_smoking_area_log", - "description": "Lets get this log wall smoking area covered to protect the workers from the weather.", + "description": "Let's get this log wall smoking area covered to protect the workers from the weather.", "category": "CC_BUILDING", "subcategory": "CSC_BUILDING_BASES", "autolearn": false, @@ -85,7 +85,7 @@ { "type": "recipe", "result": "faction_base_canteen_pantry_log", - "description": "Lets build a log wall pantry west of the kitchen.", + "description": "Let's build a log wall pantry west of the kitchen.", "category": "CC_BUILDING", "subcategory": "CSC_BUILDING_BASES", "autolearn": false, @@ -114,7 +114,7 @@ { "type": "recipe", "result": "faction_base_canteen_dining_west_log", - "description": "Lets build the west log wall of the dining hall.", + "description": "Let's build the west log wall of the dining hall.", "category": "CC_BUILDING", "subcategory": "CSC_BUILDING_BASES", "autolearn": false, @@ -144,7 +144,7 @@ { "type": "recipe", "result": "faction_base_canteen_dining_east_log", - "description": "Lets build the east log wall of the dining hall.", + "description": "Let's build the east log wall of the dining hall.", "category": "CC_BUILDING", "subcategory": "CSC_BUILDING_BASES", "autolearn": false, @@ -173,7 +173,7 @@ { "type": "recipe", "result": "faction_base_canteen_dining_center_log", - "description": "Lets build the center of the log wall dining hall.", + "description": "Let's build the center of the log wall dining hall.", "category": "CC_BUILDING", "subcategory": "CSC_BUILDING_BASES", "autolearn": false, diff --git a/data/json/recipes/basecamps/recipe_modular_canteen/recipe_modular_canteen_metal.json b/data/json/recipes/basecamps/recipe_modular_canteen/recipe_modular_canteen_metal.json index 3e7ea8a66a403..44c37896d2e64 100644 --- a/data/json/recipes/basecamps/recipe_modular_canteen/recipe_modular_canteen_metal.json +++ b/data/json/recipes/basecamps/recipe_modular_canteen/recipe_modular_canteen_metal.json @@ -2,7 +2,7 @@ { "type": "recipe", "result": "faction_base_canteen_room_center_metal", - "description": "Lets start building the central kitchen metal walls.", + "description": "Let's start building the central kitchen metal walls.", "category": "CC_BUILDING", "subcategory": "CSC_BUILDING_BASES", "autolearn": false, @@ -43,7 +43,7 @@ { "type": "recipe", "result": "faction_base_canteen_room2_center_metal", - "description": "Lets finish the central kitchen metal walls.", + "description": "Let's finish the central kitchen metal walls.", "category": "CC_BUILDING", "subcategory": "CSC_BUILDING_BASES", "autolearn": false, @@ -84,7 +84,7 @@ { "type": "recipe", "result": "faction_base_canteen_smoking_area_metal", - "description": "Lets get this metal wall smoking area covered to protect the workers from the weather.", + "description": "Let's get this metal wall smoking area covered to protect the workers from the weather.", "category": "CC_BUILDING", "subcategory": "CSC_BUILDING_BASES", "autolearn": false, @@ -120,7 +120,7 @@ { "type": "recipe", "result": "faction_base_canteen_pantry_metal", - "description": "Lets build a metal wall pantry west of the kitchen.", + "description": "Let's build a metal wall pantry west of the kitchen.", "category": "CC_BUILDING", "subcategory": "CSC_BUILDING_BASES", "autolearn": false, @@ -157,7 +157,7 @@ { "type": "recipe", "result": "faction_base_canteen_dining_west_metal", - "description": "Lets build the west metal wall of the dining hall.", + "description": "Let's build the west metal wall of the dining hall.", "category": "CC_BUILDING", "subcategory": "CSC_BUILDING_BASES", "autolearn": false, @@ -198,7 +198,7 @@ { "type": "recipe", "result": "faction_base_canteen_dining_east_metal", - "description": "Lets build the east metal wall of the dining hall.", + "description": "Let's build the east metal wall of the dining hall.", "category": "CC_BUILDING", "subcategory": "CSC_BUILDING_BASES", "autolearn": false, @@ -235,7 +235,7 @@ { "type": "recipe", "result": "faction_base_canteen_dining_center_metal", - "description": "Lets build the center of the metal wall dining hall.", + "description": "Let's build the center of the metal wall dining hall.", "category": "CC_BUILDING", "subcategory": "CSC_BUILDING_BASES", "autolearn": false, diff --git a/data/json/recipes/basecamps/recipe_modular_canteen/recipe_modular_canteen_migo_resin.json b/data/json/recipes/basecamps/recipe_modular_canteen/recipe_modular_canteen_migo_resin.json index 5d43ad7c37835..059b324392d21 100644 --- a/data/json/recipes/basecamps/recipe_modular_canteen/recipe_modular_canteen_migo_resin.json +++ b/data/json/recipes/basecamps/recipe_modular_canteen/recipe_modular_canteen_migo_resin.json @@ -2,7 +2,7 @@ { "type": "recipe", "result": "faction_base_canteen_room_center_migo_resin", - "description": "Lets start building the central kitchen mi-go resin walls.", + "description": "Let's start building the central kitchen mi-go resin walls.", "category": "CC_BUILDING", "subcategory": "CSC_BUILDING_BASES", "autolearn": false, @@ -21,7 +21,7 @@ { "type": "recipe", "result": "faction_base_canteen_room2_center_migo_resin", - "description": "Lets finish the central kitchen mi-go resin walls.", + "description": "Let's finish the central kitchen mi-go resin walls.", "category": "CC_BUILDING", "subcategory": "CSC_BUILDING_BASES", "autolearn": false, @@ -40,7 +40,7 @@ { "type": "recipe", "result": "faction_base_canteen_smoking_area_migo_resin", - "description": "Lets get this mi-go resin smoking area covered to protect the workers from the weather.", + "description": "Let's get this mi-go resin smoking area covered to protect the workers from the weather.", "category": "CC_BUILDING", "subcategory": "CSC_BUILDING_BASES", "autolearn": false, @@ -63,7 +63,7 @@ { "type": "recipe", "result": "faction_base_canteen_pantry_migo_resin", - "description": "Lets build a mi-go resin wall pantry west of the kitchen.", + "description": "Let's build a mi-go resin wall pantry west of the kitchen.", "category": "CC_BUILDING", "subcategory": "CSC_BUILDING_BASES", "autolearn": false, @@ -82,7 +82,7 @@ { "type": "recipe", "result": "faction_base_canteen_dining_west_migo_resin", - "description": "Lets build the west mi-go resin wall of the dining hall.", + "description": "Let's build the west mi-go resin wall of the dining hall.", "category": "CC_BUILDING", "subcategory": "CSC_BUILDING_BASES", "autolearn": false, @@ -105,7 +105,7 @@ { "type": "recipe", "result": "faction_base_canteen_dining_east_migo_resin", - "description": "Lets build the east mi-go resin wall of the dining hall.", + "description": "Let's build the east mi-go resin wall of the dining hall.", "category": "CC_BUILDING", "subcategory": "CSC_BUILDING_BASES", "autolearn": false, @@ -128,7 +128,7 @@ { "type": "recipe", "result": "faction_base_canteen_dining_center_migo_resin", - "description": "Lets build the center of the mi-go resin dining hall.", + "description": "Let's build the center of the mi-go resin dining hall.", "category": "CC_BUILDING", "subcategory": "CSC_BUILDING_BASES", "autolearn": false, diff --git a/data/json/recipes/basecamps/recipe_modular_canteen/recipe_modular_canteen_rammed_earth.json b/data/json/recipes/basecamps/recipe_modular_canteen/recipe_modular_canteen_rammed_earth.json index df177b1e0c3e8..4184cf08d5e47 100644 --- a/data/json/recipes/basecamps/recipe_modular_canteen/recipe_modular_canteen_rammed_earth.json +++ b/data/json/recipes/basecamps/recipe_modular_canteen/recipe_modular_canteen_rammed_earth.json @@ -2,7 +2,7 @@ { "type": "recipe", "result": "faction_base_canteen_room_center_rammed_earth", - "description": "Lets start building the central kitchen rammed earth walls.", + "description": "Let's start building the central kitchen rammed earth walls.", "category": "CC_BUILDING", "subcategory": "CSC_BUILDING_BASES", "autolearn": false, @@ -39,7 +39,7 @@ { "type": "recipe", "result": "faction_base_canteen_room2_center_rammed_earth", - "description": "Lets finish the central kitchen rammed earth walls.", + "description": "Let's finish the central kitchen rammed earth walls.", "category": "CC_BUILDING", "subcategory": "CSC_BUILDING_BASES", "autolearn": false, @@ -76,7 +76,7 @@ { "type": "recipe", "result": "faction_base_canteen_smoking_area_rammed_earth", - "description": "Lets get this rammed earth smoking area covered to protect the workers from the weather.", + "description": "Let's get this rammed earth smoking area covered to protect the workers from the weather.", "category": "CC_BUILDING", "subcategory": "CSC_BUILDING_BASES", "autolearn": false, @@ -107,7 +107,7 @@ { "type": "recipe", "result": "faction_base_canteen_pantry_rammed_earth", - "description": "Lets build a rammed earth wall pantry west of the kitchen.", + "description": "Let's build a rammed earth wall pantry west of the kitchen.", "category": "CC_BUILDING", "subcategory": "CSC_BUILDING_BASES", "autolearn": false, @@ -138,7 +138,7 @@ { "type": "recipe", "result": "faction_base_canteen_dining_west_rammed_earth", - "description": "Lets build the west rammed earth wall of the dining hall.", + "description": "Let's build the west rammed earth wall of the dining hall.", "category": "CC_BUILDING", "subcategory": "CSC_BUILDING_BASES", "autolearn": false, @@ -179,7 +179,7 @@ { "type": "recipe", "result": "faction_base_canteen_dining_east_rammed_earth", - "description": "Lets build the east rammed earth wall of the dining hall.", + "description": "Let's build the east rammed earth wall of the dining hall.", "category": "CC_BUILDING", "subcategory": "CSC_BUILDING_BASES", "autolearn": false, @@ -210,7 +210,7 @@ { "type": "recipe", "result": "faction_base_canteen_dining_center_rammed_earth", - "description": "Lets build the center of the rammed earth dining hall.", + "description": "Let's build the center of the rammed earth dining hall.", "category": "CC_BUILDING", "subcategory": "CSC_BUILDING_BASES", "autolearn": false, diff --git a/data/json/recipes/basecamps/recipe_modular_canteen/recipe_modular_canteen_rock.json b/data/json/recipes/basecamps/recipe_modular_canteen/recipe_modular_canteen_rock.json index 7b1cf960d09f3..fb2ae74040175 100644 --- a/data/json/recipes/basecamps/recipe_modular_canteen/recipe_modular_canteen_rock.json +++ b/data/json/recipes/basecamps/recipe_modular_canteen/recipe_modular_canteen_rock.json @@ -2,7 +2,7 @@ { "type": "recipe", "result": "faction_base_canteen_room_center_rock", - "description": "Lets start building the central kitchen rock walls.", + "description": "Let's start building the central kitchen rock walls.", "category": "CC_BUILDING", "subcategory": "CSC_BUILDING_BASES", "autolearn": false, @@ -34,7 +34,7 @@ { "type": "recipe", "result": "faction_base_canteen_room2_center_rock", - "description": "Lets finish the central kitchen rock walls.", + "description": "Let's finish the central kitchen rock walls.", "category": "CC_BUILDING", "subcategory": "CSC_BUILDING_BASES", "autolearn": false, @@ -66,7 +66,7 @@ { "type": "recipe", "result": "faction_base_canteen_smoking_area_rock", - "description": "Lets get this rock wall smoking area covered to protect the workers from the weather.", + "description": "Let's get this rock wall smoking area covered to protect the workers from the weather.", "category": "CC_BUILDING", "subcategory": "CSC_BUILDING_BASES", "autolearn": false, @@ -96,7 +96,7 @@ { "type": "recipe", "result": "faction_base_canteen_pantry_rock", - "description": "Lets build a rock wall pantry west of the kitchen.", + "description": "Let's build a rock wall pantry west of the kitchen.", "category": "CC_BUILDING", "subcategory": "CSC_BUILDING_BASES", "autolearn": false, @@ -127,7 +127,7 @@ { "type": "recipe", "result": "faction_base_canteen_dining_west_rock", - "description": "Lets build the west rock wall of the rock wall dining hall.", + "description": "Let's build the west rock wall of the rock wall dining hall.", "category": "CC_BUILDING", "subcategory": "CSC_BUILDING_BASES", "autolearn": false, @@ -159,7 +159,7 @@ { "type": "recipe", "result": "faction_base_canteen_dining_east_rock", - "description": "Lets build the east rock wall of the rock wall dining hall.", + "description": "Let's build the east rock wall of the rock wall dining hall.", "category": "CC_BUILDING", "subcategory": "CSC_BUILDING_BASES", "autolearn": false, @@ -190,7 +190,7 @@ { "type": "recipe", "result": "faction_base_canteen_dining_center_rock", - "description": "Lets build the center of the rock wall dining hall.", + "description": "Let's build the center of the rock wall dining hall.", "category": "CC_BUILDING", "subcategory": "CSC_BUILDING_BASES", "autolearn": false, diff --git a/data/json/recipes/basecamps/recipe_modular_canteen/recipe_modular_canteen_wad.json b/data/json/recipes/basecamps/recipe_modular_canteen/recipe_modular_canteen_wad.json index 39269eb482cf2..cb36ab8a2978c 100644 --- a/data/json/recipes/basecamps/recipe_modular_canteen/recipe_modular_canteen_wad.json +++ b/data/json/recipes/basecamps/recipe_modular_canteen/recipe_modular_canteen_wad.json @@ -2,7 +2,7 @@ { "type": "recipe", "result": "faction_base_canteen_room_center_wad", - "description": "Lets start building the central kitchen wattle and daub walls.", + "description": "Let's start building the central kitchen wattle and daub walls.", "category": "CC_BUILDING", "subcategory": "CSC_BUILDING_BASES", "autolearn": false, @@ -34,7 +34,7 @@ { "type": "recipe", "result": "faction_base_canteen_room2_center_wad", - "description": "Lets finish the central kitchen wattle and daub walls.", + "description": "Let's finish the central kitchen wattle and daub walls.", "category": "CC_BUILDING", "subcategory": "CSC_BUILDING_BASES", "autolearn": false, @@ -66,7 +66,7 @@ { "type": "recipe", "result": "faction_base_canteen_smoking_area_wad", - "description": "Lets get this wattle and daub smoking area covered to protect the workers from the weather.", + "description": "Let's get this wattle and daub smoking area covered to protect the workers from the weather.", "category": "CC_BUILDING", "subcategory": "CSC_BUILDING_BASES", "autolearn": false, @@ -97,7 +97,7 @@ { "type": "recipe", "result": "faction_base_canteen_pantry_wad", - "description": "Lets build a wattle and daub wall pantry west of the kitchen.", + "description": "Let's build a wattle and daub wall pantry west of the kitchen.", "category": "CC_BUILDING", "subcategory": "CSC_BUILDING_BASES", "autolearn": false, @@ -128,7 +128,7 @@ { "type": "recipe", "result": "faction_base_canteen_dining_west_wad", - "description": "Lets build the west wattle and daub wall of the dining hall.", + "description": "Let's build the west wattle and daub wall of the dining hall.", "category": "CC_BUILDING", "subcategory": "CSC_BUILDING_BASES", "autolearn": false, @@ -160,7 +160,7 @@ { "type": "recipe", "result": "faction_base_canteen_dining_east_wad", - "description": "Lets build the east wattle and daub wall of the dining hall.", + "description": "Let's build the east wattle and daub wall of the dining hall.", "category": "CC_BUILDING", "subcategory": "CSC_BUILDING_BASES", "autolearn": false, @@ -191,7 +191,7 @@ { "type": "recipe", "result": "faction_base_canteen_dining_center_wad", - "description": "Lets build the center of the wattle and daub dining hall.", + "description": "Let's build the center of the wattle and daub dining hall.", "category": "CC_BUILDING", "subcategory": "CSC_BUILDING_BASES", "autolearn": false, diff --git a/data/json/recipes/basecamps/recipe_modular_canteen/recipe_modular_canteen_wood.json b/data/json/recipes/basecamps/recipe_modular_canteen/recipe_modular_canteen_wood.json index 7e317ca88b339..95626a42e1075 100644 --- a/data/json/recipes/basecamps/recipe_modular_canteen/recipe_modular_canteen_wood.json +++ b/data/json/recipes/basecamps/recipe_modular_canteen/recipe_modular_canteen_wood.json @@ -2,7 +2,7 @@ { "type": "recipe", "result": "faction_base_canteen_room_center_wood", - "description": "Lets start building the central kitchen wood panel walls.", + "description": "Let's start building the central kitchen wood panel walls.", "category": "CC_BUILDING", "subcategory": "CSC_BUILDING_BASES", "autolearn": false, @@ -25,7 +25,7 @@ { "type": "recipe", "result": "faction_base_canteen_room2_center_wood", - "description": "Lets finish the central kitchen wood panel walls.", + "description": "Let's finish the central kitchen wood panel walls.", "category": "CC_BUILDING", "subcategory": "CSC_BUILDING_BASES", "autolearn": false, @@ -48,7 +48,7 @@ { "type": "recipe", "result": "faction_base_canteen_smoking_area_wood", - "description": "Lets get this wood panel smoking area covered to protect the workers from the weather.", + "description": "Let's get this wood panel smoking area covered to protect the workers from the weather.", "category": "CC_BUILDING", "subcategory": "CSC_BUILDING_BASES", "autolearn": false, @@ -71,7 +71,7 @@ { "type": "recipe", "result": "faction_base_canteen_pantry_wood", - "description": "Lets build a wood panel pantry west of the kitchen.", + "description": "Let's build a wood panel pantry west of the kitchen.", "category": "CC_BUILDING", "subcategory": "CSC_BUILDING_BASES", "autolearn": false, @@ -94,7 +94,7 @@ { "type": "recipe", "result": "faction_base_canteen_dining_west_wood", - "description": "Lets build the west wood panel wall of the dining hall.", + "description": "Let's build the west wood panel wall of the dining hall.", "category": "CC_BUILDING", "subcategory": "CSC_BUILDING_BASES", "autolearn": false, @@ -117,7 +117,7 @@ { "type": "recipe", "result": "faction_base_canteen_dining_east_wood", - "description": "Lets build the east wood panel wall of the dining hall.", + "description": "Let's build the east wood panel wall of the dining hall.", "category": "CC_BUILDING", "subcategory": "CSC_BUILDING_BASES", "autolearn": false, @@ -140,7 +140,7 @@ { "type": "recipe", "result": "faction_base_canteen_dining_center_wood", - "description": "Lets build the center of the wood panel dining hall.", + "description": "Let's build the center of the wood panel dining hall.", "category": "CC_BUILDING", "subcategory": "CSC_BUILDING_BASES", "autolearn": false, diff --git a/data/json/recipes/basecamps/recipe_modular_saltworks/recipe_modular_saltworks_common.json b/data/json/recipes/basecamps/recipe_modular_saltworks/recipe_modular_saltworks_common.json index 9a09e005276d3..6246399c16bce 100644 --- a/data/json/recipes/basecamps/recipe_modular_saltworks/recipe_modular_saltworks_common.json +++ b/data/json/recipes/basecamps/recipe_modular_saltworks/recipe_modular_saltworks_common.json @@ -17,7 +17,7 @@ { "type": "recipe", "result": "faction_base_modular_brewery1_southwest", - "description": "We could uprade the workspace in the brewery to add a still, wood stove and work table.", + "description": "We could upgrade the workspace in the brewery to add a still, wood stove and work table.", "category": "CC_BUILDING", "subcategory": "CSC_BUILDING_BASES", "autolearn": false, diff --git a/data/json/recipes/basecamps/recipe_modular_shelter/recipe_modular_shelter_common.json b/data/json/recipes/basecamps/recipe_modular_shelter/recipe_modular_shelter_common.json index 3fb71758e35f8..eaa11c3aa5dee 100644 --- a/data/json/recipes/basecamps/recipe_modular_shelter/recipe_modular_shelter_common.json +++ b/data/json/recipes/basecamps/recipe_modular_shelter/recipe_modular_shelter_common.json @@ -399,7 +399,7 @@ { "type": "recipe", "result": "faction_base_modular_shelter_beds_standard_NW", - "description": "Let's furnish the north west bedroom with regular beds.", + "description": "Let's furnish the northwest bedroom with regular beds.", "category": "CC_BUILDING", "subcategory": "CSC_BUILDING_BASES", "autolearn": false, @@ -492,7 +492,7 @@ { "type": "recipe", "result": "faction_base_modular_beds_straw_NW", - "description": "Let's furnish the north west bedroom with straw beds.", + "description": "Let's furnish the northwest bedroom with straw beds.", "category": "CC_BUILDING", "subcategory": "CSC_BUILDING_BASES", "autolearn": false, @@ -553,7 +553,7 @@ { "type": "recipe", "result": "faction_base_modular_shelter_beds_makeshift_NW", - "description": "Let's furnish the north west bedroom with makeshift beds.", + "description": "Let's furnish the northwest bedroom with makeshift beds.", "category": "CC_BUILDING", "subcategory": "CSC_BUILDING_BASES", "autolearn": false, diff --git a/data/json/recipes/basecamps/recipe_modular_storehouse/recipe_modular_storehouse_wood.json b/data/json/recipes/basecamps/recipe_modular_storehouse/recipe_modular_storehouse_wood.json index 2afd2013978b8..896cb0591ff40 100644 --- a/data/json/recipes/basecamps/recipe_modular_storehouse/recipe_modular_storehouse_wood.json +++ b/data/json/recipes/basecamps/recipe_modular_storehouse/recipe_modular_storehouse_wood.json @@ -224,7 +224,7 @@ { "type": "recipe", "result": "faction_base_modular_furniture1_west", - "description": "We could use some storage containers. Lets build some book cases to in the western alcove.", + "description": "We could use some storage containers. Let's build some book cases to in the western alcove.", "category": "CC_BUILDING", "subcategory": "CSC_BUILDING_BASES", "autolearn": false, @@ -247,7 +247,7 @@ { "type": "recipe", "result": "faction_base_modular_furniture2_east", - "description": "We could use some storage containers. Lets build some lockers in the eastern alcove.", + "description": "We could use some storage containers. Let's build some lockers in the eastern alcove.", "category": "CC_BUILDING", "subcategory": "CSC_BUILDING_BASES", "autolearn": false, @@ -277,7 +277,7 @@ { "type": "recipe", "result": "faction_base_modular_furniture3_center", - "description": "We could use some storage containers. Lets build some tables.", + "description": "We could use some storage containers. Let's build some tables.", "category": "CC_BUILDING", "subcategory": "CSC_BUILDING_BASES", "autolearn": false, diff --git a/data/json/recipes/basecamps/recipe_modular_workshop/recipe_modular_workshop.rock.json b/data/json/recipes/basecamps/recipe_modular_workshop/recipe_modular_workshop.rock.json index 2a5e41892bf93..7a6c56d9c199b 100644 --- a/data/json/recipes/basecamps/recipe_modular_workshop/recipe_modular_workshop.rock.json +++ b/data/json/recipes/basecamps/recipe_modular_workshop/recipe_modular_workshop.rock.json @@ -97,7 +97,7 @@ { "type": "recipe", "result": "faction_base_modular_workshop_room5_rock_center", - "description": "Let's expand work area with a rock wall, and add add a bookshelf for our reference books.", + "description": "Let's expand work area with a rock wall, and add a bookshelf for our reference books.", "category": "CC_BUILDING", "subcategory": "CSC_BUILDING_BASES", "autolearn": false, diff --git a/data/json/recipes/basecamps/recipe_modular_workshop/recipe_modular_workshop_log.json b/data/json/recipes/basecamps/recipe_modular_workshop/recipe_modular_workshop_log.json index 33dd0ad456761..bf20efc108815 100644 --- a/data/json/recipes/basecamps/recipe_modular_workshop/recipe_modular_workshop_log.json +++ b/data/json/recipes/basecamps/recipe_modular_workshop/recipe_modular_workshop_log.json @@ -86,7 +86,7 @@ { "type": "recipe", "result": "faction_base_modular_workshop_room5_log_center", - "description": "Let's expand work area with a log wall, and add add a bookshelf for our reference books.", + "description": "Let's expand work area with a log wall, and add a bookshelf for our reference books.", "category": "CC_BUILDING", "subcategory": "CSC_BUILDING_BASES", "autolearn": false, diff --git a/data/json/recipes/basecamps/recipe_modular_workshop/recipe_modular_workshop_metal.json b/data/json/recipes/basecamps/recipe_modular_workshop/recipe_modular_workshop_metal.json index 452e2c6323bc8..12dd57780a9d8 100644 --- a/data/json/recipes/basecamps/recipe_modular_workshop/recipe_modular_workshop_metal.json +++ b/data/json/recipes/basecamps/recipe_modular_workshop/recipe_modular_workshop_metal.json @@ -107,7 +107,7 @@ { "type": "recipe", "result": "faction_base_modular_workshop_room5_metal_center", - "description": "Let's expand work area with a metal wall, and add add a bookshelf for our reference books.", + "description": "Let's expand work area with a metal wall, and add a bookshelf for our reference books.", "category": "CC_BUILDING", "subcategory": "CSC_BUILDING_BASES", "autolearn": false, diff --git a/data/json/recipes/basecamps/recipe_modular_workshop/recipe_modular_workshop_migo_resin.json b/data/json/recipes/basecamps/recipe_modular_workshop/recipe_modular_workshop_migo_resin.json index c067fd9d7576c..e8137d7dd2dad 100644 --- a/data/json/recipes/basecamps/recipe_modular_workshop/recipe_modular_workshop_migo_resin.json +++ b/data/json/recipes/basecamps/recipe_modular_workshop/recipe_modular_workshop_migo_resin.json @@ -73,7 +73,7 @@ { "type": "recipe", "result": "faction_base_modular_workshop_room5_migo_resin_center", - "description": "Let's expand work area with a mi-go resin wall, and add add a bookshelf for our reference books.", + "description": "Let's expand work area with a mi-go resin wall, and add a bookshelf for our reference books.", "category": "CC_BUILDING", "subcategory": "CSC_BUILDING_BASES", "autolearn": false, diff --git a/data/json/recipes/basecamps/recipe_modular_workshop/recipe_modular_workshop_rammed_earth.json b/data/json/recipes/basecamps/recipe_modular_workshop/recipe_modular_workshop_rammed_earth.json index ab5f8a13d4624..248668ce71754 100644 --- a/data/json/recipes/basecamps/recipe_modular_workshop/recipe_modular_workshop_rammed_earth.json +++ b/data/json/recipes/basecamps/recipe_modular_workshop/recipe_modular_workshop_rammed_earth.json @@ -108,7 +108,7 @@ { "type": "recipe", "result": "faction_base_modular_workshop_room5_rammed_earth_center", - "description": "Let's expand work area with a rammed earth wall, and add add a bookshelf for our reference books.", + "description": "Let's expand work area with a rammed earth wall, and add a bookshelf for our reference books.", "category": "CC_BUILDING", "subcategory": "CSC_BUILDING_BASES", "autolearn": false, diff --git a/data/json/recipes/basecamps/recipe_modular_workshop/recipe_modular_workshop_wad.json b/data/json/recipes/basecamps/recipe_modular_workshop/recipe_modular_workshop_wad.json index f1e80bdf60f41..f2c7bc8727011 100644 --- a/data/json/recipes/basecamps/recipe_modular_workshop/recipe_modular_workshop_wad.json +++ b/data/json/recipes/basecamps/recipe_modular_workshop/recipe_modular_workshop_wad.json @@ -103,7 +103,7 @@ { "type": "recipe", "result": "faction_base_modular_workshop_room5_wad_center", - "description": "Let's expand work area with a wattle and daub wall, and add add a bookshelf for our reference books.", + "description": "Let's expand work area with a wattle and daub wall, and add a bookshelf for our reference books.", "category": "CC_BUILDING", "subcategory": "CSC_BUILDING_BASES", "autolearn": false, diff --git a/data/json/recipes/basecamps/recipe_modular_workshop/recipe_modular_workshop_wood.json b/data/json/recipes/basecamps/recipe_modular_workshop/recipe_modular_workshop_wood.json index 44588e7d0ccfe..775dbe61efd7a 100644 --- a/data/json/recipes/basecamps/recipe_modular_workshop/recipe_modular_workshop_wood.json +++ b/data/json/recipes/basecamps/recipe_modular_workshop/recipe_modular_workshop_wood.json @@ -93,7 +93,7 @@ { "type": "recipe", "result": "faction_base_modular_workshop_room5_wood_center", - "description": "Let's expand work area, and add add a bookshelf for our reference books.", + "description": "Let's expand work area, and add a bookshelf for our reference books.", "category": "CC_BUILDING", "subcategory": "CSC_BUILDING_BASES", "autolearn": false, diff --git a/data/json/recipes/basecamps/recipe_primitive_field.json b/data/json/recipes/basecamps/recipe_primitive_field.json index b3648644563b6..c5b6eca175bec 100644 --- a/data/json/recipes/basecamps/recipe_primitive_field.json +++ b/data/json/recipes/basecamps/recipe_primitive_field.json @@ -683,7 +683,7 @@ { "type": "recipe", "result": "faction_base_garage_6", - "description": "Attaching a quarters will let our mechanics work longer hours when needed.", + "description": "Attaching quarters will let our mechanics work longer hours when needed.", "category": "CC_BUILDING", "subcategory": "CSC_BUILDING_BASES", "skill_used": "fabrication", diff --git a/data/json/recipes/chem/fuel.json b/data/json/recipes/chem/fuel.json index 0ed8983868f12..460a12121fd97 100644 --- a/data/json/recipes/chem/fuel.json +++ b/data/json/recipes/chem/fuel.json @@ -48,6 +48,7 @@ "type": "recipe", "category": "CC_CHEM", "subcategory": "CSC_CHEM_FUEL", + "byproducts": [ [ "chem_glycerol", 4 ] ], "skill_used": "chemistry", "difficulty": 5, "result_mult": 4, diff --git a/data/json/recipes/chem/other.json b/data/json/recipes/chem/other.json index 9415555939a1e..684c7570450db 100644 --- a/data/json/recipes/chem/other.json +++ b/data/json/recipes/chem/other.json @@ -13,7 +13,7 @@ "book_learn": [ [ "recipe_arrows", 1 ], [ "textbook_survival", 1 ], [ "survival_book", 1 ] ], "qualities": [ { "id": "COOK", "level": 2 } ], "tools": [ [ [ "surface_heat", 3, "LIST" ] ] ], - "components": [ [ [ "water", 1 ], [ "water_clean", 1 ] ], [ [ "bone", 10 ], [ "bone_human", 10 ], [ "bone_tainted", 20 ] ] ] + "components": [ [ [ "water", 1 ], [ "water_clean", 1 ] ], [ [ "bone_any", 10, "LIST" ] ] ] }, { "result": "superglue", @@ -31,9 +31,7 @@ [ [ "bleach", 1 ], [ "lye_powder", 100 ], - [ "bone", 20 ], - [ "bone_human", 20 ], - [ "bone_tainted", 40 ], + [ "bone_any", 20, "LIST" ], [ "cured_hide", 2 ], [ "pine_bough", 10 ], [ "raw_dandelion", 20 ], diff --git a/data/json/recipes/electronics/parts.json b/data/json/recipes/electronics/parts.json index eb1bdb89dfadb..55d3685b90cc2 100644 --- a/data/json/recipes/electronics/parts.json +++ b/data/json/recipes/electronics/parts.json @@ -18,7 +18,7 @@ [ [ "plastic_chunk", 20 ] ], [ [ "scrap", 4 ] ], [ [ "lead", 5000 ] ], - [ [ "acid", 4 ], [ "fertilizer_liquid", 4 ], [ "fertilizer_commercial", 4 ] ] + [ [ "chem_sulphuric_acid", 4 ], [ "fertilizer_liquid", 4 ], [ "fertilizer_commercial", 4 ] ] ] }, { @@ -40,7 +40,7 @@ [ [ "plastic_chunk", 4 ] ], [ [ "scrap", 1 ] ], [ [ "lead", 1000 ] ], - [ [ "acid", 2 ], [ "fertilizer_liquid", 2 ], [ "fertilizer_commercial", 2 ] ] + [ [ "chem_sulphuric_acid", 2 ], [ "fertilizer_liquid", 2 ], [ "fertilizer_commercial", 2 ] ] ] }, { diff --git a/data/json/recipes/food/canned.json b/data/json/recipes/food/canned.json index e07714e6a3647..0958ef2a6d007 100644 --- a/data/json/recipes/food/canned.json +++ b/data/json/recipes/food/canned.json @@ -491,7 +491,7 @@ "batch_time_factors": [ 80, 4 ], "qualities": [ { "id": "COOK", "level": 3 } ], "tools": [ [ [ "surface_heat", 100, "LIST" ] ], [ [ "pot_canning", -1 ] ] ], - "components": [ [ [ "jar_glass_sealed", 1 ] ], [ [ "bone", 20 ] ], [ [ "water", 12 ], [ "water_clean", 12 ] ] ] + "components": [ [ [ "jar_glass_sealed", 1 ] ], [ [ "bone_edible", 20, "LIST" ] ], [ [ "water", 12 ], [ "water_clean", 12 ] ] ] }, { "type": "recipe", @@ -1109,7 +1109,7 @@ "batch_time_factors": [ 80, 4 ], "qualities": [ { "id": "COOK", "level": 3 } ], "tools": [ [ [ "surface_heat", 200, "LIST" ] ], [ [ "pot_canning", -1 ] ] ], - "components": [ [ [ "jar_3l_glass_sealed", 1 ] ], [ [ "water", 22 ], [ "water_clean", 22 ] ], [ [ "bone", 120 ] ] ] + "components": [ [ [ "jar_3l_glass_sealed", 1 ] ], [ [ "water", 22 ], [ "water_clean", 22 ] ], [ [ "bone_edible", 120, "LIST" ] ] ] }, { "type": "recipe", @@ -1333,7 +1333,12 @@ { "id": "COOK", "level": 3 } ], "tools": [ [ [ "surface_heat", 10, "LIST" ] ], [ [ "can_sealer", -1 ] ] ], - "components": [ [ [ "can_medium", 1 ] ], [ [ "scrap", 1 ] ], [ [ "bone", 20 ] ], [ [ "water", 2 ], [ "water_clean", 2 ] ] ] + "components": [ + [ [ "can_medium", 1 ] ], + [ [ "scrap", 1 ] ], + [ [ "bone_edible", 20, "LIST" ] ], + [ [ "water", 2 ], [ "water_clean", 2 ] ] + ] }, { "type": "recipe", diff --git a/data/json/recipes/food/offal_dishes.json b/data/json/recipes/food/offal_dishes.json index eaf66e6ac8e95..e6d9b3da74bde 100644 --- a/data/json/recipes/food/offal_dishes.json +++ b/data/json/recipes/food/offal_dishes.json @@ -55,7 +55,7 @@ "difficulty": 6, "charges": 1, "time": "30 m", - "book_learn": [ [ "mag_glam", 5 ], [ "cookbook_liverforkids", 5, "Buttery Duck Bites" ] ], + "book_learn": { "mag_glam": { "skill_level": 5 }, "cookbook_liverforkids": { "skill_level": 5, "recipe_name": "Buttery Duck Bites" } }, "qualities": [ { "id": "CUT", "level": 1 }, { "id": "COOK", "level": 3 } ], "tools": [ [ [ "surface_heat", 50, "LIST" ] ] ], "components": [ diff --git a/data/json/recipes/other/materials.json b/data/json/recipes/other/materials.json index 249fa7503c627..830b371abbb3a 100644 --- a/data/json/recipes/other/materials.json +++ b/data/json/recipes/other/materials.json @@ -72,27 +72,6 @@ "qualities": [ { "id": "SEW", "level": 1 }, { "id": "CUT", "level": 1 } ], "components": [ [ [ "rag", 5 ] ], [ [ "filament", 15, "LIST" ] ] ] }, - { - "type": "recipe", - "result": "sheet_neoprene", - "category": "CC_OTHER", - "subcategory": "CSC_OTHER_MATERIALS", - "skill_used": "chemistry", - "difficulty": 5, - "time": "25 m", - "book_learn": [ [ "adv_chemistry", 3 ], [ "textbook_chemistry", 3 ] ], - "charges": 120, - "qualities": [ { "id": "CHEM", "level": 2 } ], - "tools": [ [ [ "surface_heat", 100, "LIST" ] ], [ [ "sheet_metal", -1 ] ] ], - "components": [ - [ [ "chem_ethanol", 50 ], [ "denat_alcohol", 50 ] ], - [ [ "copper_scrap_equivalent", 2, "LIST" ] ], - [ [ "acid", 1 ] ], - [ [ "bleach", 2 ] ], - [ [ "oxy_powder", 50 ] ], - [ [ "scrap", 1 ] ] - ] - }, { "result": "sheet_neoprene_patchwork", "type": "recipe", @@ -183,7 +162,7 @@ "batch_time_factors": [ 50, 2 ], "tools": [ [ [ "electrolysis_kit", 100 ] ], [ [ "jar_glass_sealed", -1 ], [ "jar_3l_glass_sealed", -1 ] ] ], "components": [ - [ [ "acid", 1 ] ], + [ [ "any_strong_acid", 1, "LIST" ] ], [ [ "water", 3 ], [ "water_clean", 3 ] ], [ [ "tin_plate", 1 ], [ "tin_cup", 1 ], [ "bowl_pewter", 1 ] ] ] diff --git a/data/json/recipes/other/tool.json b/data/json/recipes/other/tool.json index e98e2db180f9c..6075542b43f81 100644 --- a/data/json/recipes/other/tool.json +++ b/data/json/recipes/other/tool.json @@ -151,6 +151,10 @@ "difficulty": 3, "time": "3 h", "autolearn": true, + "proficiencies": [ + { "proficiency": "prof_blacksmithing", "required": false, "time_multiplier": 3.0 }, + { "proficiency": "prof_bladesmith", "required": false, "time_multiplier": 2.5 } + ], "using": [ [ "blacksmithing_standard", 1 ] ], "qualities": [ { "id": "CHISEL", "level": 3 } ], "tools": [ [ [ "swage", -1 ] ] ], @@ -182,6 +186,10 @@ "difficulty": 3, "time": "3 h", "autolearn": true, + "proficiencies": [ + { "proficiency": "prof_blacksmithing", "required": false, "time_multiplier": 3.0 }, + { "proficiency": "prof_bladesmith", "required": false, "time_multiplier": 2.5 } + ], "using": [ [ "forging_standard", 4 ] ], "qualities": [ { "id": "ANVIL", "level": 3 }, { "id": "HAMMER", "level": 3 }, { "id": "CHISEL", "level": 3 } ], "tools": [ [ [ "tongs", -1 ] ], [ [ "swage", -1 ] ], [ [ "mold_plastic", -1 ] ] ], @@ -196,6 +204,10 @@ "difficulty": 3, "time": "3 h", "autolearn": true, + "proficiencies": [ + { "proficiency": "prof_blacksmithing", "required": false, "time_multiplier": 3.0 }, + { "proficiency": "prof_bladesmith", "required": false, "time_multiplier": 2.5 } + ], "using": [ [ "forging_standard", 4 ], [ "soldering_standard", 20 ] ], "qualities": [ { "id": "ANVIL", "level": 3 }, { "id": "HAMMER", "level": 3 }, { "id": "CHISEL", "level": 3 } ], "tools": [ [ [ "tongs", -1 ] ], [ [ "swage", -1 ] ], [ [ "mold_plastic", -1 ] ] ], @@ -211,6 +223,10 @@ "time": "3 h", "reversible": true, "autolearn": true, + "proficiencies": [ + { "proficiency": "prof_blacksmithing", "required": false, "time_multiplier": 3.0 }, + { "proficiency": "prof_bladesmith", "required": false, "time_multiplier": 2.5 } + ], "using": [ [ "blacksmithing_standard", 1 ], [ "steel_tiny", 1 ] ], "qualities": [ { "id": "CHISEL", "level": 3 } ], "tools": [ [ [ "swage", -1 ] ] ] @@ -225,6 +241,10 @@ "time": "3 h", "reversible": true, "autolearn": true, + "proficiencies": [ + { "proficiency": "prof_blacksmithing", "required": false, "time_multiplier": 3.0 }, + { "proficiency": "prof_bladesmith", "required": false, "time_multiplier": 2.5 } + ], "using": [ [ "blacksmithing_standard", 1 ], [ "steel_tiny", 1 ] ], "qualities": [ { "id": "CHISEL", "level": 3 } ], "tools": [ [ [ "swage", -1 ] ] ] @@ -253,6 +273,10 @@ "time": "3 h", "reversible": true, "autolearn": true, + "proficiencies": [ + { "proficiency": "prof_blacksmithing", "required": false, "time_multiplier": 3.0 }, + { "proficiency": "prof_bladesmith", "required": false, "time_multiplier": 2.5 } + ], "using": [ [ "blacksmithing_standard", 1 ], [ "steel_tiny", 1 ] ], "qualities": [ { "id": "CHISEL", "level": 3 } ], "tools": [ [ [ "swage", -1 ] ] ] @@ -267,6 +291,10 @@ "time": "3 h", "reversible": true, "autolearn": true, + "proficiencies": [ + { "proficiency": "prof_blacksmithing", "required": false, "time_multiplier": 3.0 }, + { "proficiency": "prof_bladesmith", "required": false, "time_multiplier": 2.5 } + ], "using": [ [ "blacksmithing_standard", 2 ], [ "steel_tiny", 2 ] ], "qualities": [ { "id": "CHISEL", "level": 3 } ], "tools": [ [ [ "swage", -1 ] ] ] @@ -281,6 +309,10 @@ "time": "5 h", "reversible": true, "autolearn": true, + "proficiencies": [ + { "proficiency": "prof_blacksmithing", "required": false, "time_multiplier": 3.0 }, + { "proficiency": "prof_bladesmith", "required": false, "time_multiplier": 2.5 } + ], "using": [ [ "blacksmithing_standard", 1 ] ], "qualities": [ { "id": "CHISEL", "level": 3 } ], "tools": [ [ [ "swage", -1 ] ] ], @@ -310,7 +342,7 @@ "time": "10 m", "autolearn": true, "qualities": [ { "id": "CUT", "level": 1 } ], - "components": [ [ [ "bone", 1 ], [ "bone_human", 1 ] ] ] + "components": [ [ [ "bone_sturdy", 1, "LIST" ] ] ] }, { "result": "awl_steel", diff --git a/data/json/recipes/recipe_ammo.json b/data/json/recipes/recipe_ammo.json index e4b0c5bc2cc15..19485712339e9 100644 --- a/data/json/recipes/recipe_ammo.json +++ b/data/json/recipes/recipe_ammo.json @@ -199,9 +199,7 @@ [ [ "adhesive", 1, "LIST" ], [ "filament", 20, "LIST" ] ], [ [ "stick", 2 ], [ "broom", 2 ], [ "2x4", 2 ], [ "bee_sting", 2 ] ], [ - [ "bone", 5 ], - [ "bone_human", 5 ], - [ "bone_tainted", 10 ], + [ "bone_sturdy", 5, "LIST" ], [ "rock", 1 ], [ "ceramic_shard", 1 ], [ "scrap", 2 ], @@ -358,9 +356,7 @@ [ [ "adhesive", 1, "LIST" ], [ "filament", 20, "LIST" ] ], [ [ "stick", 2 ], [ "broom", 2 ], [ "2x4", 2 ], [ "bee_sting", 2 ] ], [ - [ "bone", 5 ], - [ "bone_human", 5 ], - [ "bone_tainted", 10 ], + [ "bone_sturdy", 5, "LIST" ], [ "rock", 1 ], [ "ceramic_shard", 1 ], [ "scrap", 2 ], diff --git a/data/json/recipes/recipe_food.json b/data/json/recipes/recipe_food.json index 5197222d9396e..b1ac0dd767d18 100644 --- a/data/json/recipes/recipe_food.json +++ b/data/json/recipes/recipe_food.json @@ -2139,7 +2139,7 @@ "batch_time_factors": [ 80, 4 ], "qualities": [ { "id": "COOK", "level": 3 } ], "tools": [ [ [ "surface_heat", 6, "LIST" ] ] ], - "components": [ [ [ "bone", 10 ], [ "bone_human", 10 ] ], [ [ "water", 1 ], [ "water_clean", 1 ] ] ] + "components": [ [ [ "bone_edible", 10, "LIST" ] ], [ [ "water", 1 ], [ "water_clean", 1 ] ] ] }, { "type": "recipe", @@ -3964,10 +3964,7 @@ "book_learn": [ [ "adv_chemistry", 7 ], [ "textbook_chemistry", 8 ], [ "recipe_labchem", 6 ] ], "qualities": [ { "id": "CHEM", "level": 2 } ], "tools": [ [ [ "surface_heat", 50, "LIST" ] ] ], - "components": [ - [ [ "pine_bough", 6 ], [ "2x4", 8 ], [ "stick", 8 ], [ "splinter", 16 ] ], - [ [ "water_acid_weak", 3 ], [ "water_acid", 2 ], [ "acid", 1 ] ] - ] + "components": [ [ [ "pine_bough", 6 ], [ "2x4", 8 ], [ "stick", 8 ], [ "splinter", 16 ] ], [ [ "any_strong_acid", 1, "LIST" ] ] ] }, { "type": "recipe", @@ -4124,7 +4121,7 @@ "batch_time_factors": [ 83, 3 ], "flags": [ "BLIND_EASY" ], "tools": [ [ [ "rock_quern", -1 ], [ "clay_quern", -1 ] ] ], - "components": [ [ [ "bone", 1 ], [ "bone_human", 1 ] ] ] + "components": [ [ [ "bone_edible", 1, "LIST" ] ] ] }, { "type": "recipe", @@ -5766,7 +5763,7 @@ "autolearn": true, "batch_time_factors": [ 83, 3 ], "tools": [ [ [ "food_processor", 20 ] ] ], - "components": [ [ [ "bone", 1 ], [ "bone_human", 1 ] ] ] + "components": [ [ [ "bone_edible", 1, "LIST" ] ] ] }, { "result": "meal_bone_tainted", @@ -6063,7 +6060,7 @@ "batch_time_factors": [ 83, 3 ], "flags": [ "BLIND_EASY" ], "tools": [ [ [ "mortar_pestle", -1 ] ] ], - "components": [ [ [ "bone", 1 ], [ "bone_human", 1 ] ] ] + "components": [ [ [ "bone_edible", 1, "LIST" ] ] ] }, { "type": "recipe", diff --git a/data/json/recipes/recipe_medsandchemicals.json b/data/json/recipes/recipe_medsandchemicals.json index a9fe058d18c81..82221ba6307e4 100644 --- a/data/json/recipes/recipe_medsandchemicals.json +++ b/data/json/recipes/recipe_medsandchemicals.json @@ -45,20 +45,7 @@ }, { "type": "recipe", - "result": "acid", - "category": "CC_CHEM", - "subcategory": "CSC_CHEM_CHEMICALS", - "skill_used": "chemistry", - "difficulty": 4, - "time": "10 m", - "autolearn": true, - "qualities": [ { "id": "BOIL", "level": 2 } ], - "tools": [ [ [ "surface_heat", 3, "LIST" ] ] ], - "components": [ [ [ "water_acid", 1 ], [ "water_acid_weak", 2 ] ] ] - }, - { - "type": "recipe", - "result": "acid", + "result": "chem_sulphuric_acid", "id_suffix": "from batteries", "category": "CC_CHEM", "subcategory": "CSC_CHEM_CHEMICALS", @@ -80,19 +67,6 @@ ] ] }, - { - "type": "recipe", - "result": "water_acid", - "category": "CC_CHEM", - "subcategory": "CSC_CHEM_CHEMICALS", - "skill_used": "chemistry", - "skills_required": [ "electronics", 1 ], - "difficulty": 2, - "time": "10 m", - "book_learn": [ [ "adv_chemistry", 1 ], [ "textbook_chemistry", 1 ] ], - "qualities": [ { "id": "CHEM", "level": 3 } ], - "components": [ [ [ "salt_water", 1 ] ] ] - }, { "type": "recipe", "result": "tallow_tainted", @@ -315,7 +289,7 @@ [ [ "chem_sulphur", 150 ] ], [ [ "oxy_powder", 100 ] ], [ [ "ammonia", 5 ] ], - [ [ "acid", 1 ] ], + [ [ "chem_sulphuric_acid", 1 ] ], [ [ "chem_saltpetre", 5 ] ], [ [ "bleach", 5 ] ] ] @@ -367,7 +341,7 @@ "components": [ [ [ "vitamins", 5 ] ], [ [ "aspirin", 10 ] ], - [ [ "acid", 1 ], [ "datura_seed", 8 ] ], + [ [ "any_strong_acid", 1, "LIST" ], [ "datura_seed", 8 ] ], [ [ "bleach", 1 ], [ "oxy_powder", 100 ] ] ] }, @@ -440,25 +414,6 @@ "tools": [ [ [ "surface_heat", 3, "LIST" ] ] ], "components": [ [ [ "salt_water", 1 ], [ "salt", 10 ], [ "saline", 5 ] ], [ [ "diazepam", 5 ] ], [ [ "oxy_powder", 50 ] ] ] }, - { - "type": "recipe", - "result": "lsd", - "category": "CC_CHEM", - "subcategory": "CSC_CHEM_DRUGS", - "skill_used": "chemistry", - "difficulty": 6, - "time": "30 m", - "book_learn": [ [ "textbook_chemistry", 8 ], [ "adv_chemistry", 6 ], [ "recipe_labchem", 6 ] ], - "qualities": [ { "id": "CHEM", "level": 3 } ], - "tools": [ [ [ "surface_heat", 20, "LIST" ] ] ], - "components": [ - [ [ "datura_seed", 2 ] ], - [ [ "acid", 1 ] ], - [ [ "aspirin", 10 ] ], - [ [ "salt_water", 1 ], [ "saline", 5 ] ], - [ [ "ammonia", 1 ], [ "lye_powder", 100 ] ] - ] - }, { "type": "recipe", "result": "canister_goo", @@ -579,20 +534,6 @@ "tools": [ [ [ "electrolysis_kit", 750 ] ], [ [ "surface_heat", 25, "LIST" ] ], [ [ "platinum_small", -1 ] ] ], "components": [ [ [ "salt_water", 4 ], [ "saline", 20 ] ], [ [ "ammonia", 1 ] ], [ [ "chem_muriatic_acid", 1 ] ] ] }, - { - "type": "recipe", - "result": "lye_powder", - "category": "CC_CHEM", - "subcategory": "CSC_CHEM_CHEMICALS", - "skill_used": "chemistry", - "difficulty": 3, - "time": "3 h", - "batch_time_factors": [ 80, 4 ], - "book_learn": [ [ "adv_chemistry", 2 ], [ "textbook_chemistry", 2 ], [ "recipe_labchem", 2 ], [ "basic_chemistry", 2 ] ], - "qualities": [ { "id": "CHEM", "level": 1 } ], - "tools": [ [ [ "surface_heat", 25, "LIST" ] ] ], - "components": [ [ [ "charcoal", 50 ] ], [ [ "water_clean", 2 ], [ "water", 2 ] ] ] - }, { "type": "recipe", "result": "lye_powder", @@ -723,6 +664,7 @@ "result": "soap", "category": "CC_CHEM", "subcategory": "CSC_CHEM_CHEMICALS", + "byproducts": [ [ "chem_glycerol", 1 ] ], "skill_used": "chemistry", "difficulty": 2, "time": "45 m", @@ -730,8 +672,8 @@ "autolearn": true, "tools": [ [ [ "surface_heat", 18, "LIST" ] ] ], "components": [ - [ [ "edible_tallow_lard", 2, "LIST" ], [ "cooking_oil", 16 ], [ "cooking_oil2", 16 ] ], - [ [ "lye", 2 ], [ "lye_powder", 75 ] ], + [ [ "edible_tallow_lard", 4, "LIST" ], [ "cooking_oil", 14 ], [ "cooking_oil2", 14 ] ], + [ [ "lye", 1 ], [ "lye_powder", 11 ] ], [ [ "water", 2 ], [ "water_clean", 2 ] ] ], "flags": [ "ALLOW_ROTTEN" ] @@ -1237,10 +1179,7 @@ "charges": 250, "qualities": [ { "id": "CHEM", "level": 2 }, { "id": "CONTAIN", "level": 1 } ], "byproducts": [ [ "water_clean" ] ], - "components": [ - [ [ "chem_ethanol", 250 ] ], - [ [ "chem_acetic_acid", 1 ], [ "chem_nitric_acid", 1 ], [ "chem_sulphuric_acid", 1 ], [ "acid", 1 ] ] - ] + "components": [ [ [ "chem_ethanol", 250 ] ], [ [ "chem_acetic_acid", 1 ], [ "any_strong_acid", 1, "LIST" ] ] ] }, { "result": "zinc_metal", diff --git a/data/json/recipes/recipe_obsolete.json b/data/json/recipes/recipe_obsolete.json index fbaaee45812e4..1c36b4cf58cf4 100644 --- a/data/json/recipes/recipe_obsolete.json +++ b/data/json/recipes/recipe_obsolete.json @@ -2499,5 +2499,166 @@ "type": "recipe", "result": "slam_shotgun", "obsolete": true + }, + { + "type": "recipe", + "result": "can_medium_unsealed", + "obsolete": true + }, + { + "type": "recipe", + "result": "acid", + "id_suffix": "from batteries", + "obsolete": true + }, + { + "type": "recipe", + "result": "toolbox", + "obsolete": true + }, + { + "type": "recipe", + "result": "reloaded_270", + "obsolete": true + }, + { + "type": "recipe", + "result": "tool_anfo_charge", + "obsolete": true + }, + { + "type": "recipe", + "result": "tool_rdx_charge", + "obsolete": true + }, + { + "type": "recipe", + "result": "reloaded_laser_pack", + "obsolete": true + }, + { + "type": "recipe", + "result": "unbio_blaster_gun", + "obsolete": true + }, + { + "type": "recipe", + "result": "fertilizer_bomb", + "obsolete": true + }, + { + "type": "recipe", + "result": "lsd", + "obsolete": true + }, + { + "type": "recipe", + "result": "sheet_neoprene", + "obsolete": true + }, + { + "type": "recipe", + "result": "acid", + "obsolete": true + }, + { + "type": "recipe", + "result": "water_acid", + "obsolete": true + }, + { + "type": "recipe", + "result": "lye_powder", + "obsolete": true + }, + { + "type": "recipe", + "result": "flamethrower_simple", + "obsolete": true + }, + { + "result": "double_plutonium_core", + "type": "recipe", + "obsolete": true + }, + { + "result": "ring", + "type": "recipe", + "obsolete": true + }, + { + "result": "pipebomb", + "type": "recipe", + "obsolete": true + }, + { + "result": "tool_black_powder_charge", + "type": "recipe", + "obsolete": true + }, + { + "type": "recipe", + "result": "pipe_combination_gun", + "obsolete": true + }, + { + "type": "recipe", + "result": "rifle_308", + "obsolete": true + }, + { + "type": "recipe", + "result": "surv_carbine_223", + "obsolete": true + }, + { + "type": "recipe", + "result": "rifle_3006", + "obsolete": true + }, + { + "type": "recipe", + "result": "tihar", + "obsolete": true + }, + { + "type": "recipe", + "result": "helsing", + "obsolete": true + }, + { + "type": "recipe", + "result": "pneumatic_shotgun", + "obsolete": true + }, + { + "type": "recipe", + "result": "mininuke_launcher", + "obsolete": true + }, + { + "type": "recipe", + "result": "rebar_rifle", + "obsolete": true + }, + { + "type": "recipe", + "result": "heavy_rail_rifle", + "obsolete": true + }, + { + "result": "nailrifle", + "type": "recipe", + "obsolete": true + }, + { + "type": "recipe", + "result": "mininuke_mod", + "obsolete": true + }, + { + "type": "recipe", + "result": "foot_crank", + "obsolete": true } ] diff --git a/data/json/recipes/recipe_others.json b/data/json/recipes/recipe_others.json index 68c9f54498d16..5fcaff1d81bfc 100644 --- a/data/json/recipes/recipe_others.json +++ b/data/json/recipes/recipe_others.json @@ -685,7 +685,7 @@ "time": "20 m", "autolearn": true, "qualities": [ { "id": "CUT", "level": 1 } ], - "components": [ [ [ "bone", 1 ], [ "bone_human", 1 ], [ "skewer_bone", 1 ] ] ] + "components": [ [ [ "bone_sturdy", 1, "LIST" ], [ "skewer_bone", 1 ] ] ] }, { "type": "recipe", @@ -710,7 +710,7 @@ "time": "1 h", "autolearn": true, "qualities": [ { "id": "CUT", "level": 1 } ], - "components": [ [ [ "bone", 1 ], [ "bone_human", 1 ] ] ] + "components": [ [ [ "bone_sturdy", 1, "LIST" ] ] ] }, { "type": "recipe", @@ -757,11 +757,15 @@ "autolearn": true, "qualities": [ { "id": "HAMMER", "level": 2 }, - { "id": "SAW_W", "level": 2 }, + { "id": "SAW_W", "level": 1 }, { "id": "CUT", "level": 1 }, { "id": "CHISEL_WOOD", "level": 1 } ], - "components": [ [ [ "stick", 1 ], [ "2x4", 1 ] ], [ [ "2x4", 1 ] ], [ [ "nail", 2 ] ] ] + "components": [ + [ [ "stick", 1 ], [ "2x4", 1 ] ], + [ [ "2x4", 1 ] ], + [ [ "nail", 2 ], [ "cordage_short", 2, "LIST" ], [ "filament", 100, "LIST" ], [ "duct_tape", 40 ] ] + ] }, { "type": "recipe", @@ -2285,7 +2289,7 @@ [ [ "copper_scrap_equivalent", 20, "LIST" ] ], [ [ "tin", 30 ] ], [ [ "water", 3 ], [ "water_clean", 3 ] ], - [ [ "acid", 1 ] ] + [ [ "any_strong_acid", 1, "LIST" ] ] ] }, { @@ -2856,16 +2860,7 @@ "time": "1 m", "autolearn": true, "components": [ - [ - [ "splinter", 40 ], - [ "2x4", 6 ], - [ "stick", 8 ], - [ "bone", 40 ], - [ "bone_human", 40 ], - [ "bone_tainted", 40 ], - [ "pine_bough", 20 ], - [ "log", 1 ] - ], + [ [ "splinter", 40 ], [ "2x4", 6 ], [ "stick", 8 ], [ "bone_any", 40, "LIST" ], [ "pine_bough", 20 ], [ "log", 1 ] ], [ [ "char_kiln", 1 ] ] ] }, @@ -2996,7 +2991,7 @@ [ [ "ammonia", 1 ] ], [ [ "salt", 20 ], [ "salt_water", 2 ], [ "saline", 10 ] ], [ [ "water", 2 ], [ "water_clean", 2 ], [ "salt_water", 2 ], [ "saline", 10 ] ], - [ [ "material_quicklime", 2 ], [ "meal_bone", 1 ], [ "meal_bone_tainted", 2 ] ] + [ [ "material_quicklime", 2 ], [ "bone_meal_any", 1, "LIST" ] ] ] }, { @@ -3200,17 +3195,7 @@ "time": "2 m", "autolearn": true, "qualities": [ { "id": "CUT", "level": 1 } ], - "components": [ - [ - [ "bone", 1 ], - [ "bone_human", 1 ], - [ "stick", 1 ], - [ "broom", 1 ], - [ "pool_cue", 1 ], - [ "splinter", 1 ], - [ "2x4", 1 ] - ] - ] + "components": [ [ [ "bone_sturdy", 1, "LIST" ], [ "stick", 1 ], [ "broom", 1 ], [ "pool_cue", 1 ], [ "splinter", 1 ], [ "2x4", 1 ] ] ] }, { "type": "recipe", @@ -3221,7 +3206,7 @@ "time": "1 m", "autolearn": true, "qualities": [ { "id": "CUT", "level": 1 } ], - "components": [ [ [ "bone", 1 ], [ "bone_human", 1 ] ] ] + "components": [ [ [ "bone_sturdy", 1, "LIST" ] ] ] }, { "type": "recipe", @@ -4204,7 +4189,7 @@ "components": [ [ [ "chem_ethanol", 50 ], [ "denat_alcohol", 50 ] ], [ [ "copper_scrap_equivalent", 2, "LIST" ] ], - [ [ "acid", 1 ] ], + [ [ "any_strong_acid", 1, "LIST" ] ], [ [ "bleach", 2 ] ], [ [ "oxy_powder", 50 ] ], [ [ "scrap", 1 ] ] @@ -4454,7 +4439,8 @@ "time": "1 h", "reversible": true, "autolearn": true, - "components": [ [ [ "withered", 12 ], [ "straw_pile", 12 ], [ "willowbark", 6 ], [ "birchbark", 6 ] ], [ [ "plant_fibre", 100 ] ] ] + "using": [ [ "sewing_standard", 100 ] ], + "components": [ [ [ "withered", 12 ], [ "straw_pile", 12 ], [ "willowbark", 6 ], [ "birchbark", 6 ] ] ] }, { "type": "recipe", @@ -4485,7 +4471,7 @@ [ [ "steel_grille", 1 ] ], [ [ "platinum_small", 100 ] ], [ [ "water", 3 ], [ "water_clean", 3 ] ], - [ [ "acid", 1 ] ] + [ [ "any_strong_acid", 1, "LIST" ] ] ] }, { diff --git a/data/json/recipes/recipe_weapon.json b/data/json/recipes/recipe_weapon.json index f28e8aedff28f..658f7e2a2ad0d 100644 --- a/data/json/recipes/recipe_weapon.json +++ b/data/json/recipes/recipe_weapon.json @@ -55,6 +55,10 @@ "difficulty": 6, "time": "7 h 40 m", "autolearn": true, + "proficiencies": [ + { "proficiency": "prof_blacksmithing", "required": false, "time_multiplier": 3.0 }, + { "proficiency": "prof_bladesmith", "required": false, "time_multiplier": 2.5 } + ], "using": [ [ "blacksmithing_standard", 24 ], [ "steel_standard", 6 ] ], "qualities": [ { "id": "CHISEL", "level": 3 } ], "tools": [ [ [ "swage", -1 ] ] ], @@ -368,6 +372,10 @@ "difficulty": 2, "time": "1 h", "autolearn": true, + "proficiencies": [ + { "proficiency": "prof_blacksmithing", "required": false, "time_multiplier": 3.0 }, + { "proficiency": "prof_bladesmith", "required": false, "time_multiplier": 2.5 } + ], "using": [ [ "blacksmithing_standard", 1 ] ], "qualities": [ { "id": "CHISEL", "level": 3 } ], "components": [ [ [ "javelin", 1 ] ], [ [ "scrap", 1 ] ] ] @@ -544,7 +552,7 @@ "autolearn": true, "book_learn": [ [ "recipe_bows", 4 ], [ "manual_archery", 5 ] ], "qualities": [ { "id": "CUT", "level": 1 } ], - "components": [ [ [ "stick", 3 ], [ "2x4", 2 ] ], [ [ "bone", 3 ], [ "bone_human", 3 ] ], [ [ "cordage_superior", 2, "LIST" ] ] ] + "components": [ [ [ "stick", 3 ], [ "2x4", 2 ] ], [ [ "bone_sturdy", 3, "LIST" ] ], [ [ "cordage_superior", 2, "LIST" ] ] ] }, { "type": "recipe", @@ -729,7 +737,7 @@ "time": "1 h", "book_learn": [ [ "recipe_bows", 5 ], [ "manual_archery", 6 ], [ "book_archery", 6 ], [ "textbook_armschina", 6 ] ], "qualities": [ { "id": "CUT", "level": 1 }, { "id": "SCREW", "level": 1 }, { "id": "WRENCH", "level": 1 } ], - "components": [ [ [ "stick", 5 ], [ "2x4", 3 ] ], [ [ "bone", 3 ], [ "bone_human", 3 ] ], [ [ "cordage_superior", 1, "LIST" ] ] ] + "components": [ [ [ "stick", 5 ], [ "2x4", 3 ] ], [ [ "bone_sturdy", 3, "LIST" ] ], [ [ "cordage_superior", 1, "LIST" ] ] ] }, { "type": "recipe", @@ -968,6 +976,10 @@ "skills_required": [ "gun", 1 ], "difficulty": 9, "time": "55 m", + "proficiencies": [ + { "proficiency": "prof_blacksmithing", "required": false, "time_multiplier": 3.0 }, + { "proficiency": "prof_bladesmith", "required": false, "time_multiplier": 2.5 } + ], "book_learn": [ [ "welding_book", 7 ], [ "recipe_melee", 5 ] ], "using": [ [ "blacksmithing_standard", 12 ], [ "steel_standard", 3 ] ], "qualities": [ { "id": "CHISEL", "level": 3 } ], @@ -1455,6 +1467,10 @@ "difficulty": 6, "time": "5 h", "autolearn": true, + "proficiencies": [ + { "proficiency": "prof_blacksmithing", "required": false, "time_multiplier": 3.0 }, + { "proficiency": "prof_bladesmith", "required": false, "time_multiplier": 2.5 } + ], "using": [ [ "blacksmithing_standard", 4 ], [ "steel_standard", 1 ] ], "qualities": [ { "id": "CHISEL", "level": 3 } ], "tools": [ [ [ "swage", -1 ] ] ], @@ -1469,6 +1485,10 @@ "difficulty": 6, "time": "6 h", "book_learn": [ [ "textbook_fireman", 6 ] ], + "proficiencies": [ + { "proficiency": "prof_blacksmithing", "required": false, "time_multiplier": 3.0 }, + { "proficiency": "prof_bladesmith", "required": false, "time_multiplier": 2.5 } + ], "using": [ [ "blacksmithing_standard", 4 ], [ "steel_standard", 1 ] ], "qualities": [ { "id": "CHISEL", "level": 3 } ], "tools": [ [ [ "crucible", -1 ], [ "crucible_clay", -1 ] ] ], @@ -1483,6 +1503,10 @@ "difficulty": 4, "time": "6 h", "autolearn": true, + "proficiencies": [ + { "proficiency": "prof_blacksmithing", "required": false, "time_multiplier": 3.0 }, + { "proficiency": "prof_bladesmith", "required": false, "time_multiplier": 2.5 } + ], "using": [ [ "blacksmithing_standard", 8 ], [ "steel_standard", 2 ] ], "qualities": [ { "id": "CHISEL", "level": 3 } ], "tools": [ [ [ "swage", -1 ] ] ], @@ -1498,6 +1522,10 @@ "time": "4 h", "reversible": true, "autolearn": true, + "proficiencies": [ + { "proficiency": "prof_blacksmithing", "required": false, "time_multiplier": 3.0 }, + { "proficiency": "prof_bladesmith", "required": false, "time_multiplier": 2.5 } + ], "using": [ [ "blacksmithing_standard", 4 ], [ "steel_standard", 1 ] ], "qualities": [ { "id": "CHISEL", "level": 3 } ], "tools": [ [ [ "swage", -1 ] ] ], @@ -1511,6 +1539,10 @@ "skill_used": "fabrication", "difficulty": 6, "time": "6 h", + "proficiencies": [ + { "proficiency": "prof_blacksmithing", "required": false, "time_multiplier": 3.0 }, + { "proficiency": "prof_bladesmith", "required": false, "time_multiplier": 2.5 } + ], "using": [ [ "blacksmithing_standard", 4 ], [ "steel_standard", 1 ] ], "book_learn": [ [ "manual_knives", 4 ], [ "recipe_melee", 5 ] ], "qualities": [ { "id": "CHISEL", "level": 3 } ], @@ -1526,6 +1558,10 @@ "difficulty": 6, "time": "6 h 30 m", "book_learn": [ [ "manual_knives", 4 ], [ "recipe_melee", 5 ] ], + "proficiencies": [ + { "proficiency": "prof_blacksmithing", "required": false, "time_multiplier": 3.0 }, + { "proficiency": "prof_bladesmith", "required": false, "time_multiplier": 2.5 } + ], "using": [ [ "blacksmithing_standard", 8 ], [ "steel_standard", 2 ] ], "qualities": [ { "id": "CHISEL", "level": 3 } ], "tools": [ [ [ "swage", -1 ] ] ], @@ -1540,6 +1576,10 @@ "difficulty": 4, "time": "6 h 30 m", "book_learn": [ [ "manual_knives", 3 ], [ "recipe_melee", 4 ] ], + "proficiencies": [ + { "proficiency": "prof_blacksmithing", "required": false, "time_multiplier": 3.0 }, + { "proficiency": "prof_bladesmith", "required": false, "time_multiplier": 2.5 } + ], "using": [ [ "blacksmithing_standard", 4 ], [ "steel_standard", 1 ] ], "qualities": [ { "id": "CHISEL", "level": 3 } ], "tools": [ [ [ "swage", -1 ] ] ], @@ -1554,6 +1594,10 @@ "difficulty": 8, "time": "6 h", "book_learn": [ [ "manual_knives", 9 ], [ "textbook_weapeast", 8 ] ], + "proficiencies": [ + { "proficiency": "prof_blacksmithing", "required": false, "time_multiplier": 3.0 }, + { "proficiency": "prof_bladesmith", "required": false, "time_multiplier": 2.5 } + ], "using": [ [ "blacksmithing_standard", 4 ], [ "steel_standard", 1 ] ], "qualities": [ { "id": "CHISEL", "level": 3 } ], "tools": [ [ [ "swage", -1 ] ] ], @@ -1568,6 +1612,10 @@ "difficulty": 4, "time": "4 h", "autolearn": true, + "proficiencies": [ + { "proficiency": "prof_blacksmithing", "required": false, "time_multiplier": 3.0 }, + { "proficiency": "prof_bladesmith", "required": false, "time_multiplier": 2.5 } + ], "using": [ [ "blacksmithing_standard", 8 ], [ "steel_tiny", 2 ] ], "qualities": [ { "id": "CHISEL", "level": 3 } ], "tools": [ [ [ "swage", -1 ] ] ] @@ -1581,6 +1629,10 @@ "difficulty": 3, "time": "3 h", "autolearn": true, + "proficiencies": [ + { "proficiency": "prof_blacksmithing", "required": false, "time_multiplier": 3.0 }, + { "proficiency": "prof_bladesmith", "required": false, "time_multiplier": 2.5 } + ], "using": [ [ "blacksmithing_standard", 3 ], [ "steel_tiny", 3 ] ], "qualities": [ { "id": "CUT", "level": 1 }, { "id": "CHISEL", "level": 3 } ], "components": [ [ [ "2x4", 1 ], [ "stick", 1 ] ] ] @@ -1609,6 +1661,10 @@ "time": "7 h 40 m", "autolearn": true, "book_learn": [ [ "manual_knives", 5 ], [ "recipe_melee", 5 ] ], + "proficiencies": [ + { "proficiency": "prof_blacksmithing", "required": false, "time_multiplier": 3.0 }, + { "proficiency": "prof_bladesmith", "required": false, "time_multiplier": 2.5 } + ], "using": [ [ "blacksmithing_standard", 3 ], [ "steel_tiny", 3 ] ], "qualities": [ { "id": "CHISEL", "level": 3 } ], "tools": [ [ [ "swage", -1 ] ] ], @@ -1624,6 +1680,10 @@ "time": "6 h", "autolearn": true, "book_learn": [ [ "manual_knives", 5 ], [ "recipe_melee", 6 ] ], + "proficiencies": [ + { "proficiency": "prof_blacksmithing", "required": false, "time_multiplier": 3.0 }, + { "proficiency": "prof_bladesmith", "required": false, "time_multiplier": 2.5 } + ], "using": [ [ "blacksmithing_standard", 2 ], [ "steel_tiny", 2 ] ], "qualities": [ { "id": "CHISEL", "level": 3 } ], "tools": [ [ [ "swage", -1 ] ] ], @@ -1639,6 +1699,10 @@ "time": "1 h 30 m", "autolearn": true, "book_learn": [ [ "manual_knives", 3 ], [ "recipe_melee", 2 ] ], + "proficiencies": [ + { "proficiency": "prof_blacksmithing", "required": false, "time_multiplier": 3.0 }, + { "proficiency": "prof_bladesmith", "required": false, "time_multiplier": 2.5 } + ], "using": [ [ "blacksmithing_standard", 4 ], [ "steel_standard", 1 ] ], "qualities": [ { "id": "CHISEL", "level": 3 } ], "tools": [ [ [ "swage", -1 ] ] ] @@ -1674,6 +1738,10 @@ "difficulty": 9, "time": "7 h", "book_learn": [ [ "textbook_fireman", 8 ], [ "textbook_fabrication", 9 ] ], + "proficiencies": [ + { "proficiency": "prof_blacksmithing", "required": false, "time_multiplier": 3.0 }, + { "proficiency": "prof_bladesmith", "required": false, "time_multiplier": 2.5 } + ], "using": [ [ "blacksmithing_standard", 16 ], [ "steel_standard", 4 ] ], "qualities": [ { "id": "CHISEL", "level": 3 } ], "tools": [ [ [ "crucible", -1 ], [ "crucible_clay", -1 ] ] ], @@ -1688,6 +1756,10 @@ "difficulty": 6, "time": "7 h 40 m", "autolearn": true, + "proficiencies": [ + { "proficiency": "prof_blacksmithing", "required": false, "time_multiplier": 3.0 }, + { "proficiency": "prof_bladesmith", "required": false, "time_multiplier": 2.5 } + ], "using": [ [ "blacksmithing_standard", 24 ], [ "steel_standard", 6 ] ], "qualities": [ { "id": "CHISEL", "level": 3 } ], "tools": [ [ [ "swage", -1 ] ] ], @@ -1789,7 +1861,7 @@ "time": "2 m", "autolearn": true, "qualities": [ { "id": "HAMMER", "level": 1 } ], - "components": [ [ [ "bone", 1 ], [ "bone_human", 1 ] ] ] + "components": [ [ [ "bone_sturdy", 1, "LIST" ] ] ] }, { "type": "recipe", @@ -1823,6 +1895,10 @@ "difficulty": 7, "time": "6 h 40 m", "book_learn": [ [ "textbook_weapwest", 6 ] ], + "proficiencies": [ + { "proficiency": "prof_blacksmithing", "required": false, "time_multiplier": 3.0 }, + { "proficiency": "prof_bladesmith", "required": false, "time_multiplier": 2.5 } + ], "using": [ [ "blacksmithing_standard", 12 ], [ "steel_standard", 3 ] ], "qualities": [ { "id": "CHISEL", "level": 3 } ], "tools": [ [ [ "swage", -1 ] ] ], @@ -1837,6 +1913,10 @@ "difficulty": 8, "time": "8 h", "book_learn": [ [ "textbook_weapwest", 7 ] ], + "proficiencies": [ + { "proficiency": "prof_blacksmithing", "required": false, "time_multiplier": 3.0 }, + { "proficiency": "prof_bladesmith", "required": false, "time_multiplier": 2.5 } + ], "using": [ [ "blacksmithing_standard", 12 ], [ "steel_standard", 3 ] ], "qualities": [ { "id": "CHISEL", "level": 3 } ], "tools": [ [ [ "swage", -1 ] ] ], @@ -1851,6 +1931,10 @@ "difficulty": 8, "time": "7 h", "book_learn": [ [ "textbook_weapwest", 7 ] ], + "proficiencies": [ + { "proficiency": "prof_blacksmithing", "required": false, "time_multiplier": 3.0 }, + { "proficiency": "prof_bladesmith", "required": false, "time_multiplier": 2.5 } + ], "using": [ [ "blacksmithing_standard", 12 ], [ "steel_standard", 3 ] ], "qualities": [ { "id": "CHISEL", "level": 3 } ], "tools": [ [ [ "swage", -1 ] ] ], @@ -1865,6 +1949,10 @@ "difficulty": 8, "time": "8 h", "book_learn": [ [ "textbook_weapwest", 8 ], [ "recipe_melee", 7 ] ], + "proficiencies": [ + { "proficiency": "prof_blacksmithing", "required": false, "time_multiplier": 3.0 }, + { "proficiency": "prof_bladesmith", "required": false, "time_multiplier": 2.5 } + ], "using": [ [ "blacksmithing_standard", 12 ], [ "steel_standard", 3 ] ], "qualities": [ { "id": "CHISEL", "level": 3 } ], "tools": [ [ [ "swage", -1 ] ] ], @@ -1879,6 +1967,10 @@ "difficulty": 7, "time": "8 h", "book_learn": [ [ "textbook_weapwest", 8 ], [ "recipe_melee", 6 ] ], + "proficiencies": [ + { "proficiency": "prof_blacksmithing", "required": false, "time_multiplier": 3.0 }, + { "proficiency": "prof_bladesmith", "required": false, "time_multiplier": 2.5 } + ], "using": [ [ "blacksmithing_standard", 8 ], [ "steel_standard", 2 ] ], "qualities": [ { "id": "CHISEL", "level": 3 } ], "tools": [ [ [ "swage", -1 ] ] ], @@ -1893,6 +1985,10 @@ "difficulty": 9, "time": "7 h", "book_learn": [ [ "textbook_weapwest", 8 ] ], + "proficiencies": [ + { "proficiency": "prof_blacksmithing", "required": false, "time_multiplier": 3.0 }, + { "proficiency": "prof_bladesmith", "required": false, "time_multiplier": 2.5 } + ], "using": [ [ "blacksmithing_standard", 8 ], [ "steel_standard", 2 ] ], "qualities": [ { "id": "CHISEL", "level": 3 } ], "tools": [ [ [ "swage", -1 ] ] ], @@ -2006,6 +2102,10 @@ "difficulty": 8, "time": "8 h", "book_learn": [ [ "textbook_armschina", 7 ] ], + "proficiencies": [ + { "proficiency": "prof_blacksmithing", "required": false, "time_multiplier": 3.0 }, + { "proficiency": "prof_bladesmith", "required": false, "time_multiplier": 2.5 } + ], "using": [ [ "blacksmithing_standard", 12 ], [ "steel_standard", 3 ] ], "qualities": [ { "id": "CHISEL", "level": 3 } ], "tools": [ [ [ "swage", -1 ] ] ], @@ -2020,6 +2120,10 @@ "difficulty": 8, "time": "7 h", "book_learn": [ [ "textbook_armschina", 7 ] ], + "proficiencies": [ + { "proficiency": "prof_blacksmithing", "required": false, "time_multiplier": 3.0 }, + { "proficiency": "prof_bladesmith", "required": false, "time_multiplier": 2.5 } + ], "using": [ [ "blacksmithing_standard", 12 ], [ "steel_standard", 3 ] ], "qualities": [ { "id": "CHISEL", "level": 3 } ], "tools": [ [ [ "swage", -1 ] ] ], @@ -2034,6 +2138,10 @@ "difficulty": 8, "time": "8 h 10 m", "book_learn": [ [ "textbook_weapwest", 7 ] ], + "proficiencies": [ + { "proficiency": "prof_blacksmithing", "required": false, "time_multiplier": 3.0 }, + { "proficiency": "prof_bladesmith", "required": false, "time_multiplier": 2.5 } + ], "using": [ [ "blacksmithing_standard", 16 ], [ "steel_standard", 4 ] ], "qualities": [ { "id": "CHISEL", "level": 3 } ], "tools": [ [ [ "swage", -1 ] ] ], @@ -2048,6 +2156,10 @@ "difficulty": 8, "time": "7 h", "book_learn": [ [ "textbook_weapwest", 7 ] ], + "proficiencies": [ + { "proficiency": "prof_blacksmithing", "required": false, "time_multiplier": 3.0 }, + { "proficiency": "prof_bladesmith", "required": false, "time_multiplier": 2.5 } + ], "using": [ [ "blacksmithing_standard", 16 ], [ "steel_standard", 4 ] ], "qualities": [ { "id": "CHISEL", "level": 3 } ], "tools": [ [ [ "swage", -1 ] ] ], @@ -2062,6 +2174,10 @@ "difficulty": 9, "time": "8 h", "book_learn": [ [ "textbook_weapwest", 8 ], [ "scots_cookbook", 10 ] ], + "proficiencies": [ + { "proficiency": "prof_blacksmithing", "required": false, "time_multiplier": 3.0 }, + { "proficiency": "prof_bladesmith", "required": false, "time_multiplier": 2.5 } + ], "using": [ [ "blacksmithing_standard", 16 ], [ "steel_standard", 4 ] ], "qualities": [ { "id": "CHISEL", "level": 3 } ], "tools": [ [ [ "swage", -1 ] ] ], @@ -2101,6 +2217,10 @@ "difficulty": 7, "time": "6 h 20 m", "book_learn": [ [ "textbook_weapeast", 6 ], [ "manual_knives", 7 ], [ "recipe_melee", 8 ] ], + "proficiencies": [ + { "proficiency": "prof_blacksmithing", "required": false, "time_multiplier": 3.0 }, + { "proficiency": "prof_bladesmith", "required": false, "time_multiplier": 2.5 } + ], "using": [ [ "blacksmithing_standard", 4 ], [ "steel_standard", 1 ] ], "qualities": [ { "id": "CHISEL", "level": 3 } ], "tools": [ [ [ "swage", -1 ] ] ], @@ -2115,6 +2235,10 @@ "difficulty": 8, "time": "7 h", "book_learn": [ [ "textbook_weapeast", 7 ] ], + "proficiencies": [ + { "proficiency": "prof_blacksmithing", "required": false, "time_multiplier": 3.0 }, + { "proficiency": "prof_bladesmith", "required": false, "time_multiplier": 2.5 } + ], "using": [ [ "blacksmithing_standard", 8 ], [ "steel_standard", 2 ] ], "qualities": [ { "id": "CHISEL", "level": 3 } ], "tools": [ [ [ "swage", -1 ] ] ], @@ -2129,6 +2253,10 @@ "difficulty": 9, "time": "8 h", "book_learn": [ [ "textbook_weapeast", 8 ] ], + "proficiencies": [ + { "proficiency": "prof_blacksmithing", "required": false, "time_multiplier": 3.0 }, + { "proficiency": "prof_bladesmith", "required": false, "time_multiplier": 2.5 } + ], "using": [ [ "blacksmithing_standard", 8 ], [ "steel_standard", 2 ] ], "qualities": [ { "id": "CHISEL", "level": 3 } ], "tools": [ [ [ "swage", -1 ] ] ], @@ -2143,6 +2271,10 @@ "difficulty": 10, "time": "9 h 40 m", "book_learn": [ [ "textbook_weapeast", 8 ] ], + "proficiencies": [ + { "proficiency": "prof_blacksmithing", "required": false, "time_multiplier": 3.0 }, + { "proficiency": "prof_bladesmith", "required": false, "time_multiplier": 2.5 } + ], "using": [ [ "blacksmithing_standard", 20 ], [ "steel_standard", 5 ] ], "qualities": [ { "id": "CHISEL", "level": 3 } ], "tools": [ [ [ "swage", -1 ] ] ], @@ -2184,6 +2316,10 @@ "difficulty": 7, "time": "6 h", "book_learn": [ [ "textbook_weapwest", 6 ] ], + "proficiencies": [ + { "proficiency": "prof_blacksmithing", "required": false, "time_multiplier": 3.0 }, + { "proficiency": "prof_bladesmith", "required": false, "time_multiplier": 2.5 } + ], "using": [ [ "blacksmithing_standard", 8 ], [ "steel_standard", 2 ] ], "qualities": [ { "id": "CHISEL", "level": 3 } ], "tools": [ [ [ "swage", -1 ] ] ], @@ -2331,6 +2467,10 @@ "difficulty": 3, "time": "1 h", "autolearn": true, + "proficiencies": [ + { "proficiency": "prof_blacksmithing", "required": false, "time_multiplier": 3.0 }, + { "proficiency": "prof_bladesmith", "required": false, "time_multiplier": 2.5 } + ], "using": [ [ "blacksmithing_standard", 2 ], [ "steel_tiny", 2 ] ], "qualities": [ { "id": "CHISEL", "level": 3 } ], "tools": [ [ [ "swage", -1 ] ] ] @@ -2344,6 +2484,10 @@ "difficulty": 6, "time": "3 h", "autolearn": true, + "proficiencies": [ + { "proficiency": "prof_blacksmithing", "required": false, "time_multiplier": 3.0 }, + { "proficiency": "prof_bladesmith", "required": false, "time_multiplier": 2.5 } + ], "using": [ [ "blacksmithing_standard", 4 ], [ "steel_standard", 1 ] ], "qualities": [ { "id": "CHISEL", "level": 3 } ], "tools": [ [ [ "swage", -1 ] ] ] @@ -2357,6 +2501,10 @@ "difficulty": 7, "time": "7 h 40 m", "book_learn": [ [ "textbook_armschina", 6 ] ], + "proficiencies": [ + { "proficiency": "prof_blacksmithing", "required": false, "time_multiplier": 3.0 }, + { "proficiency": "prof_bladesmith", "required": false, "time_multiplier": 2.5 } + ], "using": [ [ "blacksmithing_standard", 4 ], [ "steel_standard", 1 ] ], "qualities": [ { "id": "CHISEL", "level": 3 } ], "tools": [ [ [ "swage", -1 ] ] ], @@ -2371,6 +2519,10 @@ "difficulty": 7, "time": "6 h", "book_learn": [ [ "textbook_weapwest", 6 ] ], + "proficiencies": [ + { "proficiency": "prof_blacksmithing", "required": false, "time_multiplier": 3.0 }, + { "proficiency": "prof_bladesmith", "required": false, "time_multiplier": 2.5 } + ], "using": [ [ "blacksmithing_standard", 12 ], [ "steel_standard", 3 ] ], "qualities": [ { "id": "CHISEL", "level": 3 } ], "tools": [ [ [ "swage", -1 ] ] ], @@ -2385,6 +2537,10 @@ "difficulty": 7, "time": "7 h 40 m", "book_learn": [ [ "textbook_weapwest", 6 ] ], + "proficiencies": [ + { "proficiency": "prof_blacksmithing", "required": false, "time_multiplier": 3.0 }, + { "proficiency": "prof_bladesmith", "required": false, "time_multiplier": 2.5 } + ], "using": [ [ "blacksmithing_standard", 8 ], [ "steel_standard", 2 ] ], "qualities": [ { "id": "CHISEL", "level": 3 } ], "tools": [ [ [ "swage", -1 ] ] ], @@ -2399,6 +2555,10 @@ "difficulty": 7, "time": "7 h 40 m", "book_learn": [ [ "textbook_weapeast", 6 ] ], + "proficiencies": [ + { "proficiency": "prof_blacksmithing", "required": false, "time_multiplier": 3.0 }, + { "proficiency": "prof_bladesmith", "required": false, "time_multiplier": 2.5 } + ], "using": [ [ "blacksmithing_standard", 8 ], [ "steel_standard", 2 ] ], "qualities": [ { "id": "CHISEL", "level": 3 } ], "tools": [ [ [ "swage", -1 ] ] ], @@ -2512,6 +2672,10 @@ "difficulty": 5, "time": "13 h 20 m", "book_learn": [ [ "textbook_weapeast", 6 ] ], + "proficiencies": [ + { "proficiency": "prof_blacksmithing", "required": false, "time_multiplier": 3.0 }, + { "proficiency": "prof_bladesmith", "required": false, "time_multiplier": 2.5 } + ], "using": [ [ "blacksmithing_standard", 20 ], [ "steel_standard", 5 ] ], "qualities": [ { "id": "CHISEL", "level": 3 } ], "//": "basically 2.5x the resources of a single machete to cover the fact that it's two weapons, each with a hand guard", @@ -2551,6 +2715,10 @@ "difficulty": 7, "time": "6 h", "book_learn": [ [ "textbook_weapwest", 6 ] ], + "proficiencies": [ + { "proficiency": "prof_blacksmithing", "required": false, "time_multiplier": 3.0 }, + { "proficiency": "prof_bladesmith", "required": false, "time_multiplier": 2.5 } + ], "using": [ [ "blacksmithing_standard", 12 ], [ "steel_standard", 3 ] ], "qualities": [ { "id": "CHISEL", "level": 3 } ], "tools": [ [ [ "swage", -1 ] ] ], diff --git a/data/json/recipes/weapon/cutting.json b/data/json/recipes/weapon/cutting.json index 07b73650607fa..1ad537431aa2d 100644 --- a/data/json/recipes/weapon/cutting.json +++ b/data/json/recipes/weapon/cutting.json @@ -8,6 +8,10 @@ "difficulty": 8, "time": "420 m", "book_learn": [ [ "textbook_weapwest", 7 ] ], + "proficiencies": [ + { "proficiency": "prof_blacksmithing", "required": false, "time_multiplier": 3.0 }, + { "proficiency": "prof_bladesmith", "required": false, "time_multiplier": 2.5 } + ], "using": [ [ "forging_standard", 2 ], [ "steel_standard", 2 ] ], "qualities": [ { "id": "ANVIL", "level": 3 }, { "id": "HAMMER", "level": 3 }, { "id": "CHISEL", "level": 3 } ], "tools": [ [ [ "tongs", -1 ] ], [ [ "swage", -1 ] ] ], @@ -22,6 +26,10 @@ "difficulty": 7, "time": 55000, "book_learn": [ [ "textbook_armschina", 5 ] ], + "proficiencies": [ + { "proficiency": "prof_blacksmithing", "required": false, "time_multiplier": 3.0 }, + { "proficiency": "prof_bladesmith", "required": false, "time_multiplier": 2.5 } + ], "using": [ [ "forging_standard", 2 ], [ "bronzesmithing_tools", 1 ] ], "components": [ [ @@ -45,6 +53,10 @@ "difficulty": 6, "time": 45000, "book_learn": [ [ "textbook_weapwest", 4 ] ], + "proficiencies": [ + { "proficiency": "prof_blacksmithing", "required": false, "time_multiplier": 3.0 }, + { "proficiency": "prof_bladesmith", "required": false, "time_multiplier": 2.5 } + ], "using": [ [ "forging_standard", 2 ], [ "bronzesmithing_tools", 1 ] ], "components": [ [ @@ -68,6 +80,10 @@ "difficulty": 7, "time": 55000, "book_learn": [ [ "textbook_weapwest", 5 ] ], + "proficiencies": [ + { "proficiency": "prof_blacksmithing", "required": false, "time_multiplier": 3.0 }, + { "proficiency": "prof_bladesmith", "required": false, "time_multiplier": 2.5 } + ], "using": [ [ "forging_standard", 2 ], [ "bronzesmithing_tools", 1 ] ], "components": [ [ diff --git a/data/json/recipes/weapon/explosive.json b/data/json/recipes/weapon/explosive.json index 5470cf0966d6c..114c15c75dce6 100644 --- a/data/json/recipes/weapon/explosive.json +++ b/data/json/recipes/weapon/explosive.json @@ -10,7 +10,7 @@ "autolearn": true, "components": [ [ [ "jar_glass_sealed", 1 ], [ "bottle_glass", 1 ], [ "clay_canister", 2 ], [ "flask_glass", 2 ] ], - [ [ "acid", 2 ] ], + [ [ "any_strong_acid", 2, "LIST" ] ], [ [ "cordage_short", 1, "LIST" ] ] ] }, @@ -27,15 +27,10 @@ "tools": [ [ [ "surface_heat", 25, "LIST" ] ] ], "components": [ [ [ "paper", 5 ], [ "rolling_paper", 32 ] ], - [ [ "acid", 2 ], [ "chem_sulphuric_acid", 2 ], [ "chem_nitric_acid", 2 ] ], + [ [ "chem_sulphuric_acid", 2 ] ], + [ [ "chem_nitric_acid", 1 ] ], [ [ "ammonia", 1 ], [ "chem_ethanol", 250 ], [ "denat_alcohol", 250 ] ], - [ - [ "soap", 3 ], - [ "edible_tallow_lard", 2, "LIST" ], - [ "tallow_tainted", 2 ], - [ "cooking_oil", 16 ], - [ "cooking_oil2", 16 ] - ] + [ [ "chem_glycerol", 2 ] ] ] }, { @@ -334,8 +329,8 @@ "qualities": [ { "id": "SCREW", "level": 1 } ], "components": [ [ [ "water", 1 ], [ "water_clean", 1 ], [ "salt_water", 1 ], [ "saline", 5 ] ], - [ [ "candy", 1 ], [ "cola", 1 ] ], - [ [ "vitamins", 10 ], [ "aspirin", 8 ] ], + [ [ "sugar", 16 ] ], + [ [ "chem_saltpetre", 24 ] ], [ [ "canister_empty", 1 ], [ "can_food", 1 ], [ "clay_canister", 1 ], [ "can_drink", 1 ] ], [ [ "superglue", 1 ] ] ] diff --git a/data/json/recipes/weapon/piercing.json b/data/json/recipes/weapon/piercing.json index 5f909c736419a..8af3a03001767 100644 --- a/data/json/recipes/weapon/piercing.json +++ b/data/json/recipes/weapon/piercing.json @@ -53,6 +53,10 @@ "difficulty": 5, "time": "3 h", "book_learn": [ [ "textbook_weapeast", 5 ] ], + "proficiencies": [ + { "proficiency": "prof_blacksmithing", "required": false, "time_multiplier": 3.0 }, + { "proficiency": "prof_bladesmith", "required": false, "time_multiplier": 2.5 } + ], "using": [ [ "blacksmithing_standard", 2 ], [ "steel_tiny", 2 ] ], "qualities": [ { "id": "CHISEL", "level": 3 } ], "tools": [ [ [ "swage", -1 ] ] ] @@ -66,6 +70,10 @@ "difficulty": 9, "time": "10 h", "book_learn": [ [ "textbook_weapeast", 9 ] ], + "proficiencies": [ + { "proficiency": "prof_blacksmithing", "required": false, "time_multiplier": 3.0 }, + { "proficiency": "prof_bladesmith", "required": false, "time_multiplier": 2.5 } + ], "using": [ [ "blacksmithing_standard", 2 ], [ "steel_tiny", 2 ] ], "qualities": [ { "id": "CHISEL", "level": 3 } ], "tools": [ [ [ "swage", -1 ] ] ], @@ -94,6 +102,10 @@ "difficulty": 8, "time": "8 h", "book_learn": [ [ "textbook_weapwest", 8 ] ], + "proficiencies": [ + { "proficiency": "prof_blacksmithing", "required": false, "time_multiplier": 3.0 }, + { "proficiency": "prof_bladesmith", "required": false, "time_multiplier": 2.5 } + ], "using": [ [ "blacksmithing_standard", 3 ], [ "steel_tiny", 3 ] ], "qualities": [ { "id": "CHISEL", "level": 3 } ], "tools": [ [ [ "swage", -1 ] ] ], @@ -108,6 +120,10 @@ "difficulty": 4, "time": "60 m", "autolearn": true, + "proficiencies": [ + { "proficiency": "prof_blacksmithing", "required": false, "time_multiplier": 3.0 }, + { "proficiency": "prof_bladesmith", "required": false, "time_multiplier": 2.5 } + ], "using": [ [ "forging_standard", 1 ], [ "steel_standard", 1 ] ], "qualities": [ { "id": "ANVIL", "level": 3 }, { "id": "HAMMER", "level": 3 }, { "id": "CHISEL", "level": 3 } ], "tools": [ [ [ "tongs", -1 ] ], [ [ "crucible", -1 ], [ "crucible_clay", -1 ] ] ], @@ -175,6 +191,10 @@ "difficulty": 6, "time": 50000, "book_learn": [ [ "textbook_armschina", 5 ] ], + "proficiencies": [ + { "proficiency": "prof_blacksmithing", "required": false, "time_multiplier": 3.0 }, + { "proficiency": "prof_bladesmith", "required": false, "time_multiplier": 2.5 } + ], "using": [ [ "forging_standard", 2 ], [ "bronzesmithing_tools", 1 ] ], "qualities": [ { "id": "CUT", "level": 1 } ], "components": [ @@ -192,6 +212,10 @@ "difficulty": 4, "time": 30000, "book_learn": [ [ "textbook_weapwest", 4 ] ], + "proficiencies": [ + { "proficiency": "prof_blacksmithing", "required": false, "time_multiplier": 3.0 }, + { "proficiency": "prof_bladesmith", "required": false, "time_multiplier": 2.5 } + ], "using": [ [ "forging_standard", 1 ], [ "bronzesmithing_tools", 1 ] ], "qualities": [ { "id": "CUT", "level": 1 } ], "components": [ diff --git a/data/json/regional_map_settings.json b/data/json/regional_map_settings.json index aab786f70026c..d54a1a01ddf05 100644 --- a/data/json/regional_map_settings.json +++ b/data/json/regional_map_settings.json @@ -665,7 +665,15 @@ "urban_5_house": 50, "urban_6_house": 50, "urban_7_house_garden": 50, + "urban_8_house_brick_garden": 50, "urban_9_house_garage_loft": 50, + "urban_10_house_brick_pool": 50, + "urban_11_house_brick": 50, + "urban_12_house": 50, + "urban_15_house": 50, + "urban_16_house_ranch": 50, + "urban_17_house_ranch": 50, + "urban_18_victorian": 50, "emptyresidentiallot": 20, "house_vacant": 20, "house_vacant2": 20, diff --git a/data/json/requirements/chemistry.json b/data/json/requirements/chemistry.json new file mode 100644 index 0000000000000..0f566319b9da3 --- /dev/null +++ b/data/json/requirements/chemistry.json @@ -0,0 +1,14 @@ +[ + { + "id": "any_strong_acid", + "type": "requirement", + "//": "This should contain all strong acids, based on pKa value.", + "components": [ [ [ "chem_sulphuric_acid", 1 ], [ "chem_muriatic_acid", 1 ], [ "chem_nitric_acid", 1 ] ] ] + }, + { + "id": "any_weak_acid", + "type": "requirement", + "//": "This should contain all weak acids, based on pKa value.", + "components": [ [ [ "chem_acetic_acid", 1 ] ] ] + } +] diff --git a/data/json/requirements/materials.json b/data/json/requirements/materials.json index 1345b739a8e45..e0f496819cb4a 100644 --- a/data/json/requirements/materials.json +++ b/data/json/requirements/materials.json @@ -11,12 +11,30 @@ "//": "Materials used when forming bullets", "components": [ [ [ "lead", 1 ] ] ] }, + { + "id": "bone_edible", + "type": "requirement", + "//": "Any kind of non-poisonous bones, human or not.", + "components": [ [ [ "bone", 1 ], [ "bone_human", 1 ], [ "bone_demihuman", 1 ] ] ] + }, { "id": "bone_sturdy", "type": "requirement", "//": "Any kind of bones, human or not. Tainted bones are too brittle and won't work for this purpose.", "components": [ [ [ "bone", 1 ], [ "bone_human", 1 ], [ "bone_demihuman", 1 ] ] ] }, + { + "id": "bone_any", + "type": "requirement", + "//": "Any kind of bones. May possibly be poisonous to eat, or fragile.", + "components": [ [ [ "bone_sturdy", 1, "LIST" ], [ "bone_tainted", 1 ] ] ] + }, + { + "id": "bone_meal_any", + "type": "requirement", + "//": "Any kind of bone meal, edible or not. May possibly be poisonous to eat.", + "components": [ [ [ "meal_bone", 1 ], [ "meal_bone_tainted", 1 ] ] ] + }, { "id": "copper_scrap_equivalent", "type": "requirement", diff --git a/data/json/snippets/survivor_notes.json b/data/json/snippets/survivor_notes.json index 9484dd3f62286..c74177ea231a9 100644 --- a/data/json/snippets/survivor_notes.json +++ b/data/json/snippets/survivor_notes.json @@ -6,7 +6,7 @@ { "id": "note_1", "text": "\"WE WERE RIGHT THE GOVERNMENT DID IT\"" }, { "id": "note_2", - "text": "\"Have seen a zombie making its kin raise even despite damage that normally would take them down, the air around it shimmered like around that hole in the air we've seen creatures coming through back home\"" + "text": "\"Have seen a zombie making its kin raise even despite damage that normally would take them down, the surrounding air shimmered like around that hole in the air we've seen creatures coming through back home\"" }, { "id": "note_3", "text": "\"I shot the sheriff; but I couldn't find the deputy\"" }, { @@ -96,7 +96,7 @@ { "id": "note_31", "text": "\"Why are all the lawnmowers broken?!\"" }, { "id": "note_32", - "text": "\"Some of the bridges, they're right next to each other, right? If you see something up ahead one of those, just careen through to the other side. My van was long enough to bridge right across!\"" + "text": "\"Some bridges, they're right next to each other, right? If you see something up ahead one of those, just careen through to the other side. My van was long enough to bridge right across!\"" }, { "id": "note_33", "text": "\"BURN BURN BURN BURN BURN ALL BURN ALL BURN ALL BURN\"" }, { diff --git a/data/json/vehicleparts/vehicle_parts.json b/data/json/vehicleparts/vehicle_parts.json index d93af7b136294..3967ecdf29387 100644 --- a/data/json/vehicleparts/vehicle_parts.json +++ b/data/json/vehicleparts/vehicle_parts.json @@ -1802,7 +1802,7 @@ "broken_color": "light_gray", "damage_modifier": 10, "durability": 50, - "description": "A metal pipe that reduces some of noise of the engine.", + "description": "A metal pipe that somewhat reduces engine noise.", "bonus": 40, "item": "muffler", "requirements": { @@ -3250,7 +3250,7 @@ "broken_color": "blue", "damage_modifier": 20, "durability": 200, - "description": "An LCD display attached to one or more cameras. When turned on, it lets you see from the cameras, but drains power from the vehicle's batteries. You can 'e'xamine the tile to access the controls, or use the vehicle control key (default '^').", + "description": "An LCD attached to one or more cameras. When turned on, it lets you see from the cameras, but drains power from the vehicle's batteries. You can 'e'xamine the tile to access the controls, or use the vehicle control key (default '^').", "folded_volume": "2500 ml", "item": "camera_control", "epower": -20, diff --git a/data/legacy/1/obsolete.json b/data/legacy/1/obsolete.json index cd99a8bafd726..cfa5f86f8681a 100644 --- a/data/legacy/1/obsolete.json +++ b/data/legacy/1/obsolete.json @@ -330,7 +330,7 @@ "name": "helmet netting", "weight": "25 g", "color": "green", - "covers": [ "HEAD" ], + "covers": [ "head" ], "to_hit": -1, "symbol": "[", "description": "A webbing of strings worn on a helmet, to attach camouflage.", diff --git a/data/legacy/4/boots.json b/data/legacy/4/boots.json index 36d9718eb42b8..c219a6ab0717f 100644 --- a/data/legacy/4/boots.json +++ b/data/legacy/4/boots.json @@ -12,7 +12,7 @@ "material": [ "leather" ], "symbol": "[", "color": "dark_gray", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 90, "encumbrance": 12, "warmth": 20, @@ -51,7 +51,7 @@ "material": [ "bone", "leather" ], "symbol": "[", "color": "white", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 95, "encumbrance": 16, "warmth": 20, @@ -89,7 +89,7 @@ "material": [ "plastic", "nomex" ], "symbol": "[", "color": "dark_gray", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 100, "encumbrance": 40, "warmth": 35, @@ -128,7 +128,7 @@ "material": [ "chitin" ], "symbol": "[", "color": "green", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 95, "encumbrance": 14, "warmth": 10, @@ -167,7 +167,7 @@ "material": [ "kevlar", "leather" ], "symbol": "[", "color": "dark_gray", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 100, "encumbrance": 25, "warmth": 25, @@ -206,7 +206,7 @@ "material": [ "kevlar", "nomex" ], "symbol": "[", "color": "light_gray", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 100, "encumbrance": 35, "warmth": 15, @@ -244,7 +244,7 @@ "material": [ "leather", "fur" ], "symbol": "[", "color": "brown", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 90, "encumbrance": 20, "warmth": 60, @@ -283,7 +283,7 @@ "material": [ "kevlar", "plastic", "neoprene" ], "symbol": "[", "color": "dark_gray", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 100, "encumbrance": 32, "warmth": 15, @@ -321,7 +321,7 @@ "material": [ "leather", "plastic" ], "symbol": "[", "color": "brown", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 95, "encumbrance": 12, "warmth": 30, @@ -360,7 +360,7 @@ "material": [ "kevlar", "steel" ], "symbol": "[", "color": "dark_gray", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 100, "encumbrance": 35, "warmth": 15, @@ -399,7 +399,7 @@ "material": [ "leather" ], "symbol": "[", "color": "brown", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 95, "encumbrance": 18, "warmth": 25, @@ -438,7 +438,7 @@ "material": [ "kevlar", "cotton" ], "symbol": "[", "color": "green", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 100, "encumbrance": 18, "warmth": 15, @@ -477,7 +477,7 @@ "material": [ "iron", "leather" ], "symbol": "[", "color": "light_gray", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 100, "encumbrance": 28, "warmth": 20, @@ -514,7 +514,7 @@ "material": [ "plastic" ], "symbol": "[", "color": "dark_gray", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 100, "encumbrance": 30, "warmth": 10, @@ -552,7 +552,7 @@ "material": [ "leather", "steel" ], "symbol": "[", "color": "brown", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 90, "encumbrance": 20, "warmth": 30, @@ -591,7 +591,7 @@ "material": [ "kevlar", "leather" ], "symbol": "[", "color": "brown", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 100, "encumbrance": 24, "warmth": 15, @@ -629,7 +629,7 @@ "material": [ "leather" ], "symbol": "[", "color": "dark_gray", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 95, "encumbrance": 22, "warmth": 20, @@ -666,7 +666,7 @@ "material": [ "wool", "plastic" ], "symbol": "[", "color": "light_gray", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 90, "encumbrance": 25, "warmth": 80, @@ -705,7 +705,7 @@ "material": [ "kevlar", "fur" ], "symbol": "[", "color": "light_gray", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 100, "encumbrance": 38, "warmth": 75, @@ -744,7 +744,7 @@ "material": [ "kevlar", "leather" ], "symbol": "[", "color": "brown", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 100, "encumbrance": 38, "warmth": 15, @@ -782,7 +782,7 @@ "material": [ "leather" ], "symbol": "[", "color": "dark_gray", - "covers": [ "FEET", "LEGS" ], + "covers": [ "foot_l", "foot_r", "leg_r", "leg_l" ], "coverage": 65, "encumbrance": 20, "warmth": 20, @@ -819,7 +819,7 @@ "material": [ "plastic", "cotton" ], "symbol": "[", "color": "light_gray", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 100, "encumbrance": 25, "warmth": 20, @@ -857,7 +857,7 @@ "material": [ "leather", "steel" ], "symbol": "[", "color": "brown", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 100, "encumbrance": 25, "warmth": 30, diff --git a/data/mods/Aftershock/itemgroups/bionics_groups.json b/data/mods/Aftershock/itemgroups/bionics_groups.json index 2fee362616910..332e20adfd54d 100644 --- a/data/mods/Aftershock/itemgroups/bionics_groups.json +++ b/data/mods/Aftershock/itemgroups/bionics_groups.json @@ -8,6 +8,7 @@ [ "afs_bio_missiles", 10 ], [ "afs_bio_linguistic_coprocessor", 10 ], [ "afs_bio_dopamine_stimulators", 10 ], + [ "afs_bio_neurosoft_aeronautics", 5 ], [ "bio_blaster", 5 ] ] }, @@ -19,7 +20,7 @@ { "id": "bionics_mil", "type": "item_group", - "items": [ [ "bio_blaster", 5 ] ] + "items": [ [ "bio_blaster", 5 ], [ "afs_bio_neurosoft_aeronautics", 10 ] ] }, { "id": "bionics_sci", @@ -33,6 +34,7 @@ [ "bn_bio_solar", 15 ], [ "afs_bio_wind_turbine", 10 ], [ "afs_bio_missiles", 10 ], + [ "afs_bio_neurosoft_aeronautics", 10 ], [ "afs_bio_dopamine_stimulators", 10 ] ] }, diff --git a/data/mods/Aftershock/items/armor.json b/data/mods/Aftershock/items/armor.json index 40da5e6643082..1a1d48f990cce 100644 --- a/data/mods/Aftershock/items/armor.json +++ b/data/mods/Aftershock/items/armor.json @@ -13,7 +13,7 @@ "material": [ "glass", "superalloy", "platinum" ], "symbol": "[", "color": "cyan", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "looks_like": "molle_pack", "coverage": 30, "encumbrance": 5, @@ -36,7 +36,7 @@ "symbol": "[", "looks_like": "armor_scrapsuit", "color": "white", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 80, "encumbrance": 4, "material_thickness": 2 @@ -64,7 +64,7 @@ "material": [ "graphene_weave" ], "symbol": "[", "color": "dark_gray", - "covers": [ "TORSO", "HEAD", "ARMS", "LEGS" ], + "covers": [ "torso", "head", "arm_l", "arm_r", "leg_l", "leg_r" ], "coverage": 85, "encumbrance": 4, "warmth": 30, @@ -131,7 +131,7 @@ "material": [ "glass", "steel" ], "symbol": "[", "color": "light_gray", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 40, "encumbrance": 12, "material_thickness": 3, @@ -152,7 +152,7 @@ "material": [ "glass", "steel" ], "symbol": "[", "color": "blue", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 40, "encumbrance": 20, "material_thickness": 1, @@ -177,7 +177,7 @@ "symbol": "[", "looks_like": "touring_suit", "color": "dark_gray", - "covers": [ "LEGS", "TORSO", "ARMS" ], + "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r" ], "coverage": 95, "encumbrance": 25, "warmth": 35, @@ -203,7 +203,7 @@ "material": [ "nylon" ], "symbol": "[", "color": "light_gray", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 85, "encumbrance": 6, "warmth": 15, @@ -222,7 +222,7 @@ "material": [ "nylon", "ceramic" ], "symbol": "[", "color": "light_gray", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 85, "encumbrance": 10, "warmth": 15, @@ -246,7 +246,7 @@ "symbol": "[", "looks_like": "boots", "color": "dark_gray", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 100, "encumbrance": 25, "warmth": 25, @@ -269,7 +269,7 @@ "symbol": "[", "looks_like": "fire_gauntlets", "color": "dark_gray", - "covers": [ "HANDS" ], + "covers": [ "hand_l", "hand_r" ], "coverage": 100, "encumbrance": 13, "warmth": 20, @@ -291,7 +291,7 @@ "symbol": "[", "looks_like": "fire_gauntlets", "color": "dark_gray", - "covers": [ "HANDS" ], + "covers": [ "hand_l", "hand_r" ], "coverage": 100, "encumbrance": 5, "warmth": 20, diff --git a/data/mods/Aftershock/items/cast_spell_items.json b/data/mods/Aftershock/items/cast_spell_items.json index 69ce6773d784c..40c1d67223ffe 100644 --- a/data/mods/Aftershock/items/cast_spell_items.json +++ b/data/mods/Aftershock/items/cast_spell_items.json @@ -10,7 +10,7 @@ "material": [ "superalloy" ], "symbol": "[", "color": "light_red", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 0, "warmth": 0, "flags": [ "WATER_FRIENDLY", "ALLOWS_NATURAL_ATTACKS", "ONLY_ONE", "TORSO" ] diff --git a/data/mods/Aftershock/items/cbms.json b/data/mods/Aftershock/items/cbms.json index 0446f6db69961..bc2e4c32dbe9d 100644 --- a/data/mods/Aftershock/items/cbms.json +++ b/data/mods/Aftershock/items/cbms.json @@ -46,6 +46,16 @@ "price_postapoc": 100000, "difficulty": 8 }, + { + "id": "afs_bio_neurosoft_aeronautics", + "copy-from": "bionic_general", + "type": "BIONIC_ITEM", + "name": { "str": "Neurosoft: Aeronautics CBM" }, + "description": "A brain implant that grants instinctual knowledge about the operation of flying machines.", + "price": 1000000, + "price_postapoc": 100000, + "difficulty": 8 + }, { "id": "afs_bio_cranialbomb", "copy-from": "bionic_general", diff --git a/data/mods/Aftershock/items/items.json b/data/mods/Aftershock/items/items.json index 8bdac367f1b44..7841631be6935 100644 --- a/data/mods/Aftershock/items/items.json +++ b/data/mods/Aftershock/items/items.json @@ -243,7 +243,8 @@ "material": [ "titanium" ], "symbol": "[", "color": "light_gray", - "covers": [ "HAND_EITHER" ], + "covers": [ "hand_l", "hand_r" ], + "sided": true, "coverage": 5, "flags": [ "WATCH", "STURDY", "BELTED", "ALLOWS_NATURAL_ATTACKS", "WATER_FRIENDLY", "OVERSIZE" ] }, diff --git a/data/mods/Aftershock/items/obsolete.json b/data/mods/Aftershock/items/obsolete.json index b1c89ac2a4e07..c6f592f92e6e9 100644 --- a/data/mods/Aftershock/items/obsolete.json +++ b/data/mods/Aftershock/items/obsolete.json @@ -76,7 +76,7 @@ "price": 100000000, "price_postapoc": 50000, "material": [ "superalloy", "kevlar" ], - "covers": [ "TORSO", "ARMS", "HANDS", "LEGS", "FEET" ], + "covers": [ "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ], "coverage": 100, "material_thickness": 2, "encumbrance": 4, @@ -112,7 +112,7 @@ "price": 10000000, "price_postapoc": 5000, "material": [ "superalloy", "plastic" ], - "covers": [ "HEAD", "EYES", "MOUTH" ], + "covers": [ "head", "eyes", "mouth" ], "coverage": 100, "material_thickness": 2, "encumbrance": 15, @@ -174,7 +174,7 @@ "symbol": "[", "looks_like": "quiver", "color": "dark_gray", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 20, "encumbrance": 5, "material_thickness": 1, @@ -193,7 +193,7 @@ "material": [ "wool" ], "symbol": "[", "color": "white", - "covers": [ "TORSO", "ARMS", "HANDS", "LEGS", "FEET" ], + "covers": [ "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ], "coverage": 100, "encumbrance": 40, "warmth": 100, @@ -238,7 +238,7 @@ "symbol": "[", "looks_like": "armor_blarmor", "color": "brown", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 100, "encumbrance": 16, "warmth": 25, @@ -260,7 +260,7 @@ "symbol": "[", "looks_like": "kevlar", "color": "light_gray", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 85, "encumbrance": 3, "max_encumbrance": 7, @@ -286,7 +286,7 @@ "symbol": "[", "looks_like": "armor_blarmor", "color": "white", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 95, "encumbrance": 14, "warmth": 20, diff --git a/data/mods/Aftershock/items/tool_armor.json b/data/mods/Aftershock/items/tool_armor.json index e1bbb5f9f1d69..57ea1950fb1cf 100644 --- a/data/mods/Aftershock/items/tool_armor.json +++ b/data/mods/Aftershock/items/tool_armor.json @@ -33,7 +33,7 @@ "need_charges": 5, "need_charges_msg": "The %s's batteries are dead." }, - "covers": [ "HEAD", "MOUTH", "EYES", "TORSO", "ARMS", "HANDS", "LEGS", "FEET" ], + "covers": [ "head", "mouth", "eyes", "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ], "warmth": 20, "environmental_protection": 10, "coverage": 100, diff --git a/data/mods/Aftershock/items/tools.json b/data/mods/Aftershock/items/tools.json index 8597032339992..945a1cfca3060 100644 --- a/data/mods/Aftershock/items/tools.json +++ b/data/mods/Aftershock/items/tools.json @@ -223,7 +223,8 @@ "coverage": 5, "ammo": [ "battery" ], "encumbrance": 2, - "covers": [ "LEG_EITHER" ], + "covers": [ "leg_l", "leg_r" ], + "sided": true, "pocket_data": [ { "pocket_type": "MAGAZINE", "rigid": true, "ammo_restriction": { "battery": 1500 } } ], "flags": [ "RECHARGE", "WAIST", "FRAGILE", "OVERSIZE", "WATERPROOF", "IS_UPS" ] }, @@ -235,7 +236,8 @@ "description": "This is an advanced version of the unified power supply, or UPS. This device has been significantly redesigned to provide better efficiency as well as to consume plutonium fuel cells rather than batteries, and is both slimmer and lighter to wear. Sadly, its plutonium reactor can't be charged in UPS charging station.", "coverage": 5, "encumbrance": 1, - "covers": [ "LEG_EITHER" ], + "covers": [ "leg_l", "leg_r" ], + "sided": true, "flags": [ "WAIST", "FRAGILE", "OVERSIZE", "IS_UPS" ] }, { diff --git a/data/mods/Aftershock/items/weapons.json b/data/mods/Aftershock/items/weapons.json index e1f30b5db0e41..70e816b7784f7 100644 --- a/data/mods/Aftershock/items/weapons.json +++ b/data/mods/Aftershock/items/weapons.json @@ -85,7 +85,7 @@ "weight": "113 g", "volume": "1500 ml", "bashing": 8, - "armor_data": { "covers": [ "TORSO" ], "coverage": 5, "material_thickness": 1, "encumbrance": 7 }, + "armor_data": { "covers": [ "torso" ], "coverage": 5, "material_thickness": 1, "encumbrance": 7 }, "reload_noise_volume": 0, "loudness": 0, "ranged_damage": { "damage_type": "heat", "amount": 30, "armor_penetration": 15 }, diff --git a/data/mods/Aftershock/maps/furniture.json b/data/mods/Aftershock/maps/furniture.json index 32009d86c09fb..d69b84ee19287 100644 --- a/data/mods/Aftershock/maps/furniture.json +++ b/data/mods/Aftershock/maps/furniture.json @@ -65,6 +65,127 @@ }, "looks_like": "f_fridge" }, + { + "type": "furniture", + "id": "f_autodoc", + "name": "chirurgic suite", + "symbol": "&", + "color": "light_cyan", + "copy-from": "f_autodoc", + "flags": [ "TRANSPARENT", "AUTODOC" ], + "description": "A multitude of surgical arms seamlessly meld with the chromed ceiling. They expectantly unravel with your approach, animated by an AI whose performances blur the lines between medicine and art.", + "examine_action": "autodoc", + "//": "Easy installation", + "surgery_skill_multiplier": 999999, + "deconstruct": { + "items": [ + { "item": "afs_circuitry_4", "count": [ 1, 2 ] }, + { "item": "afs_circuitry_3", "count": [ 4, 8 ] }, + { "item": "cable", "charges": [ 4, 6 ] }, + { "item": "small_lcd_screen", "count": [ 1, 2 ] }, + { "item": "afs_material_2", "count": [ 6, 10 ] }, + { "item": "afs_energy_storage_2", "count": [ 2, 4 ] }, + { "item": "afs_energy_storage_3", "count": [ 1, 2 ] }, + { "item": "plastic_chunk", "count": [ 10, 12 ] }, + { "item": "afs_material_4", "count": [ 6, 8 ] } + ] + }, + "bash": { + "str_min": 8, + "str_max": 150, + "sound": "crunch!", + "sound_fail": "whack!", + "items": [ + { "item": "afs_circuitry_3", "prob": 25 }, + { "item": "afs_circuitry_1", "count": [ 1, 2 ], "prob": 50 }, + { "item": "cable", "charges": [ 1, 2 ], "prob": 50 }, + { "item": "small_lcd_screen", "prob": 25 }, + { "item": "afs_circuitry_1", "count": [ 1, 4 ], "prob": 50 }, + { "item": "afs_energy_storage_2", "prob": 25 }, + { "item": "plastic_chunk", "count": [ 4, 10 ], "prob": 50 }, + { "item": "afs_material_2", "count": [ 2, 6 ], "prob": 50 } + ] + } + }, + { + "type": "furniture", + "id": "f_autodoc_average", + "name": "Autodoc Mk. XVI", + "symbol": "&", + "color": "light_red", + "copy-from": "f_autodoc", + "flags": [ "TRANSPARENT", "AUTODOC" ], + "examine_action": "autodoc", + "surgery_skill_multiplier": 1.6, + "deconstruct": { + "items": [ + { "item": "afs_circuitry_3", "count": [ 1, 2 ] }, + { "item": "afs_circuitry_2", "count": [ 4, 8 ] }, + { "item": "cable", "charges": [ 4, 6 ] }, + { "item": "small_lcd_screen", "count": [ 1, 2 ] }, + { "item": "afs_material_2", "count": [ 6, 10 ] }, + { "item": "afs_energy_storage_2", "count": [ 1, 2 ] }, + { "item": "afs_energy_storage_3", "count": [ 0, 1 ] }, + { "item": "plastic_chunk", "count": [ 10, 12 ] }, + { "item": "afs_material_2", "count": [ 6, 8 ] } + ] + }, + "bash": { + "str_min": 8, + "str_max": 150, + "sound": "crunch!", + "sound_fail": "whack!", + "items": [ + { "item": "afs_circuitry_2", "prob": 25 }, + { "item": "afs_circuitry_1", "count": [ 1, 2 ], "prob": 50 }, + { "item": "cable", "charges": [ 1, 2 ], "prob": 50 }, + { "item": "small_lcd_screen", "prob": 25 }, + { "item": "afs_energy_storage_2", "prob": 25 }, + { "item": "plastic_chunk", "count": [ 4, 10 ], "prob": 50 }, + { "item": "afs_material_2", "count": [ 2, 6 ], "prob": 50 } + ] + } + }, + { + "type": "furniture", + "id": "f_autodoc_cheap", + "name": "salvaged autodoc", + "symbol": "&", + "color": "light_red", + "copy-from": "f_autodoc", + "description": "The kind of worn-down and dubiously safe surgical device that is perfectly at home in a back alley clinic. It would take great skill to safely operate this.", + "flags": [ "TRANSPARENT", "AUTODOC" ], + "examine_action": "autodoc", + "surgery_skill_multiplier": 0.6, + "deconstruct": { + "items": [ + { "item": "afs_circuitry_2", "count": [ 1, 2 ] }, + { "item": "afs_circuitry_1", "count": [ 4, 8 ] }, + { "item": "cable", "charges": [ 4, 6 ] }, + { "item": "small_lcd_screen", "count": [ 1, 2 ] }, + { "item": "afs_material_2", "count": [ 6, 10 ] }, + { "item": "afs_energy_storage_1", "count": [ 1, 2 ] }, + { "item": "afs_energy_storage_2", "count": [ 0, 1 ] }, + { "item": "plastic_chunk", "count": [ 10, 12 ] }, + { "item": "afs_material_1", "count": [ 6, 8 ] } + ] + }, + "bash": { + "str_min": 8, + "str_max": 150, + "sound": "crunch!", + "sound_fail": "whack!", + "items": [ + { "item": "afs_circuitry_2", "prob": 25 }, + { "item": "afs_circuitry_1", "count": [ 1, 2 ], "prob": 50 }, + { "item": "cable", "charges": [ 1, 2 ], "prob": 50 }, + { "item": "small_lcd_screen", "prob": 25 }, + { "item": "afs_energy_storage_2", "prob": 25 }, + { "item": "plastic_chunk", "count": [ 4, 10 ], "prob": 50 }, + { "item": "afs_material_1", "count": [ 2, 6 ], "prob": 50 } + ] + } + }, { "type": "furniture", "id": "f_sleep_pod", diff --git a/data/mods/Aftershock/maps/mapgen/basement_bionic.json b/data/mods/Aftershock/maps/mapgen/basement_bionic.json new file mode 100644 index 0000000000000..bf0c5457d4d36 --- /dev/null +++ b/data/mods/Aftershock/maps/mapgen/basement_bionic.json @@ -0,0 +1,78 @@ +[ + { + "type": "mapgen", + "method": "json", + "om_terrain": [ "basement_bionic" ], + "weight": 1000000, + "object": { + "fill_ter": "t_rock_floor", + "rows": [ + " ", + " |----------| ", + " |...___....| ", + " |..........| ", + " |..~~~~~~..| ", + " |---------|..~~~~~~..| ", + " |...__..i|L..~~~~~~..| ", + " |?.......|...~~~~~~..| ", + " |/.......+L..........| ", + " |.ccc.ccc|LL...___...| ", + " |------------+-------| ", + " |{{{{|bbbbbb|...rrccr| ", + " |....|s....b|ff......| ", + " |__..|s.t..b|...ccccc| ", + " |....|a....b|........| ", + " |^.!.............s..t| ", + " |................s..t| ", + " |%.@.............s..t| ", + " |...............|----| ", + " |.....|+-|++|...|&..i| ", + " |.....|.W|..|...+...C| ", + " |.}...|.F|.<|...|.cc*| ", + " ---------------------- ", + " " + ], + "palettes": [ "basement_game" ], + "terrain": { "~": "t_water_pool" }, + "furniture": { + "}": "f_pinball_machine", + "*": "f_shower", + "!": [ "f_ergometer", "f_ergometer_mechanical" ], + "@": [ "f_treadmill", "f_treadmill_mechanical" ], + "^": "f_exercise", + "%": "f_floor_canvas", + "C": "f_cupboard", + "{": "f_bigmirror", + "_": "f_bench", + "L": "f_locker", + "?": "f_autodoc_cheap", + "/": "f_autodoc_couch", + "F": "f_home_furnace", + "W": "f_water_heater" + }, + "liquids": { "W": { "liquid": "water_clean", "amount": [ 0, 100 ] } }, + "place_loot": [ + { "group": "alcohol", "x": [ 14, 15 ], "y": 12, "chance": 96, "repeat": [ 1, 2 ] }, + { "group": "fridgesnacks", "x": [ 14, 15 ], "y": 12, "chance": 80, "repeat": [ 1, 2 ] }, + { "group": "homebooks", "x": [ 7, 12 ], "y": 11, "chance": 70, "repeat": [ 1, 2 ] }, + { "group": "homebooks", "x": 12, "y": [ 12, 14 ], "chance": 70, "repeat": [ 1, 2 ] }, + { "group": "magazines", "x": 21, "y": [ 15, 17 ], "chance": 30 }, + { "group": "magazines", "x": 9, "y": 12, "chance": 30 }, + { "group": "snacks", "x": [ 16, 21 ], "y": 11, "chance": 40, "repeat": [ 1, 2 ] }, + { "group": "snacks", "x": [ 16, 21 ], "y": 13, "chance": 40, "repeat": [ 1, 2 ] }, + { "group": "softdrugs", "x": 21, "y": 20, "chance": 75, "repeat": [ 1, 2 ] }, + { "group": "cleaning", "x": 11, "y": 5, "chance": 70, "repeat": [ 1, 2 ] }, + { "group": "cleaning", "x": [ 11, 12 ], "y": 8, "chance": 70, "repeat": [ 1, 2 ] }, + { "group": "surgery", "x": [ 8, 9 ], "y": 9, "chance": 70, "repeat": [ 1, 2 ] }, + { "group": "bionics_common", "x": 7, "y": 9 }, + { "item": "anesthetic_kit", "x": 7, "y": 9, "ammo": 100 }, + { "item": "television", "x": 21, "y": 16, "chance": 95 }, + { "item": "soap", "x": 19, "y": 21, "chance": 80 }, + { "item": "towel", "x": 20, "y": 21, "chance": 80 }, + { "item": "towel", "x": 3, "y": 13, "chance": 60 }, + { "item": "stereo", "x": 2, "y": 13, "chance": 50 } + ], + "place_monster": [ { "monster": "mon_broken_cyborg", "x": 14, "y": 3, "chance": 100 } ] + } + } +] diff --git a/data/mods/Aftershock/options.json b/data/mods/Aftershock/options.json index 5b369d68858b2..a491b2346fe7b 100644 --- a/data/mods/Aftershock/options.json +++ b/data/mods/Aftershock/options.json @@ -1,16 +1,4 @@ [ - { - "type": "furniture", - "id": "f_autodoc", - "name": "Autodoc Mk. XI", - "symbol": "&", - "color": "light_cyan", - "copy-from": "f_autodoc", - "flags": [ "TRANSPARENT", "AUTODOC" ], - "examine_action": "autodoc", - "//": "Easy installation", - "surgery_skill_multiplier": 999999 - }, { "id": "anesthetic", "type": "requirement", diff --git a/data/mods/Aftershock/player/bionics.json b/data/mods/Aftershock/player/bionics.json index 9e40266d1387a..0bddbb26537f0 100644 --- a/data/mods/Aftershock/player/bionics.json +++ b/data/mods/Aftershock/player/bionics.json @@ -50,6 +50,14 @@ "react_cost": 5, "time": 200 }, + { + "id": "afs_bio_neurosoft_aeronautics", + "type": "bionic", + "name": { "str": "Neurosoft: Aeronautics" }, + "description": "A brain implant that grants instinctual knowledge about the operation of flying machines.", + "occupied_bodyparts": [ [ "head", 2 ] ], + "learned_proficiencies": [ "prof_helicopter_pilot" ] + }, { "id": "afs_bio_cranialbomb", "type": "bionic", diff --git a/data/mods/Aftershock/recipes/recipes.json b/data/mods/Aftershock/recipes/recipes.json index 2fe7055696d51..f540a37b25147 100644 --- a/data/mods/Aftershock/recipes/recipes.json +++ b/data/mods/Aftershock/recipes/recipes.json @@ -11,7 +11,7 @@ "book_learn": [ [ "manual_electronics", 1 ], [ "mag_electronics", 1 ], [ "textbook_anarch", 1 ] ], "qualities": [ { "id": "SCREW", "level": 1 } ], "components": [ - [ [ "acid", 1 ] ], + [ [ "chem_sulphuric_acid", 1 ] ], [ [ "steel_chunk", 1 ], [ "scrap", 1 ] ], [ [ "can_drink", 1 ], [ "can_food", 1 ], [ "canister_empty", 1 ] ] ] diff --git a/data/mods/CRT_EXPANSION/deadspace/deadspaceitems.json b/data/mods/CRT_EXPANSION/deadspace/deadspaceitems.json index c5f374b482a68..ed52e818c0b93 100644 --- a/data/mods/CRT_EXPANSION/deadspace/deadspaceitems.json +++ b/data/mods/CRT_EXPANSION/deadspace/deadspaceitems.json @@ -34,7 +34,7 @@ "material": [ "superalloy", "nomex", "kevlar" ], "symbol": "[", "color": "light_gray", - "covers": [ "HEAD", "EYES", "MOUTH", "TORSO", "LEGS", "ARMS", "HANDS", "FEET" ], + "covers": [ "head", "eyes", "mouth", "torso", "leg_l", "leg_r", "arm_l", "arm_r", "hand_l", "hand_r", "foot_l", "foot_r" ], "coverage": 100, "encumbrance": 25, "warmth": 15, diff --git a/data/mods/CRT_EXPANSION/items/crt_armor.json b/data/mods/CRT_EXPANSION/items/crt_armor.json index 0e701477fb918..f4be3adc445be 100644 --- a/data/mods/CRT_EXPANSION/items/crt_armor.json +++ b/data/mods/CRT_EXPANSION/items/crt_armor.json @@ -12,7 +12,7 @@ "material": [ "neoprene", "kevlar" ], "symbol": "[", "color": "dark_gray", - "covers": [ "EYES", "MOUTH" ], + "covers": [ "eyes", "mouth" ], "coverage": 100, "encumbrance": 20, "warmth": 30, @@ -49,7 +49,7 @@ "material": [ "rubber", "superalloy", "nomex" ], "symbol": "[", "color": "dark_gray", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 100, "encumbrance": 10, "warmth": 25, @@ -135,7 +135,7 @@ "material": [ "superalloy", "neoprene", "rubber" ], "symbol": "[", "color": "white", - "covers": [ "ARMS" ], + "covers": [ "arm_l", "arm_r" ], "coverage": 100, "encumbrance": 20, "warmth": 17, @@ -166,7 +166,7 @@ "material": [ "neoprene", "rubber", "kevlar" ], "symbol": "[", "color": "black_green", - "covers": [ "TORSO", "ARMS", "LEGS" ], + "covers": [ "torso", "arm_l", "arm_r", "leg_l", "leg_r" ], "coverage": 100, "encumbrance": 10, "max_encumbrance": 20, @@ -195,7 +195,7 @@ "material": [ "kevlar", "nomex", "plastic" ], "symbol": "[", "color": "light_green", - "covers": [ "TORSO", "LEGS", "ARMS" ], + "covers": [ "torso", "leg_l", "leg_r", "arm_l", "arm_r" ], "coverage": 100, "encumbrance": 17, "max_encumbrance": 25, @@ -219,7 +219,7 @@ "material": [ "plastic", "cotton", "rubber" ], "symbol": "[", "color": "dark_gray", - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "coverage": 30, "encumbrance": 1, "max_encumbrance": 3, @@ -244,7 +244,7 @@ "material": [ "steel", "kevlar" ], "symbol": "[", "color": "cyan", - "covers": [ "TORSO", "LEGS", "ARMS" ], + "covers": [ "torso", "leg_l", "leg_r", "arm_l", "arm_r" ], "coverage": 90, "encumbrance": 27, "max_encumbrance": 35, @@ -271,7 +271,7 @@ "material": [ "kevlar", "superalloy" ], "symbol": "[", "color": "dark_gray", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 100, "encumbrance": 30, "warmth": 5, @@ -291,7 +291,7 @@ "material": [ "neoprene", "kevlar", "superalloy" ], "symbol": "[", "color": "light_blue", - "covers": [ "TORSO", "LEGS", "ARMS" ], + "covers": [ "torso", "leg_l", "leg_r", "arm_l", "arm_r" ], "coverage": 100, "encumbrance": 3, "max_encumbrance": 7, @@ -316,7 +316,7 @@ "material": [ "hardsteel", "kevlar" ], "symbol": "[", "color": "light_green", - "covers": [ "TORSO", "LEGS", "ARMS" ], + "covers": [ "torso", "leg_l", "leg_r", "arm_l", "arm_r" ], "coverage": 100, "encumbrance": 24, "max_encumbrance": 40, diff --git a/data/mods/CRT_EXPANSION/items/crt_clothes.json b/data/mods/CRT_EXPANSION/items/crt_clothes.json index 0eaf4b4e83c7b..f38b2f30e50b1 100644 --- a/data/mods/CRT_EXPANSION/items/crt_clothes.json +++ b/data/mods/CRT_EXPANSION/items/crt_clothes.json @@ -31,7 +31,7 @@ "symbol": "[", "material": [ "cotton", "neoprene" ], "warmth": 17, - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "encumbrance": 10, "coverage": 100, "material_thickness": 2, @@ -61,7 +61,7 @@ "material": [ "cotton", "plastic", "rubber" ], "symbol": "[", "color": "dark_gray", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 65, "encumbrance": 15, "warmth": 15, @@ -81,7 +81,7 @@ "material": [ "cotton", "neoprene" ], "symbol": "[", "color": "dark_gray", - "covers": [ "HANDS" ], + "covers": [ "hand_l", "hand_r" ], "coverage": 90, "encumbrance": 4, "warmth": 10, @@ -122,7 +122,7 @@ "material": [ "cotton", "neoprene", "rubber" ], "symbol": "[", "color": "black_green", - "covers": [ "TORSO", "ARMS", "LEGS" ], + "covers": [ "torso", "arm_l", "arm_r", "leg_l", "leg_r" ], "coverage": 100, "encumbrance": 6, "max_encumbrance": 13, @@ -148,7 +148,7 @@ "material": [ "cotton", "neoprene", "rubber" ], "symbol": "[", "color": "white", - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 50, "encumbrance": 10, "warmth": 15, diff --git a/data/mods/CRT_EXPANSION/items/crt_makeshift_survival.json b/data/mods/CRT_EXPANSION/items/crt_makeshift_survival.json index 7e1a56be307c2..a7c8d3f1e8863 100644 --- a/data/mods/CRT_EXPANSION/items/crt_makeshift_survival.json +++ b/data/mods/CRT_EXPANSION/items/crt_makeshift_survival.json @@ -12,7 +12,7 @@ "material": [ "dry_plant" ], "symbol": "[", "color": "black_green", - "covers": [ "TORSO", "LEGS" ], + "covers": [ "torso", "leg_l", "leg_r" ], "coverage": 50, "encumbrance": 15, "warmth": 7, diff --git a/data/mods/CRT_EXPANSION/items/crt_toolarmor.json b/data/mods/CRT_EXPANSION/items/crt_toolarmor.json index f0e6d42a37af8..81bb69d58e424 100644 --- a/data/mods/CRT_EXPANSION/items/crt_toolarmor.json +++ b/data/mods/CRT_EXPANSION/items/crt_toolarmor.json @@ -22,7 +22,7 @@ "material": [ "plastic", "kevlar" ], "symbol": "[", "color": "dark_gray", - "covers": [ "EYES", "MOUTH" ], + "covers": [ "eyes", "mouth" ], "coverage": 100, "encumbrance": 50, "warmth": 20, @@ -59,7 +59,7 @@ "material": [ "plastic", "kevlar" ], "symbol": "[", "color": "light_green", - "covers": [ "EYES", "MOUTH" ], + "covers": [ "eyes", "mouth" ], "coverage": 100, "encumbrance": 5, "warmth": 75, @@ -98,7 +98,7 @@ "material": [ "kevlar", "superalloy" ], "symbol": "[", "color": "light_gray", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "max_charges": 300, "initial_charges": 300, "charges_per_use": 1, @@ -136,7 +136,7 @@ "material": [ "kevlar", "superalloy" ], "symbol": "[", "color": "light_green", - "covers": [ "TORSO", "LEGS", "ARMS" ], + "covers": [ "torso", "leg_l", "leg_r", "arm_l", "arm_r" ], "coverage": 100, "encumbrance": 5, "pocket_data": [ @@ -243,7 +243,7 @@ "material": [ "cotton" ], "symbol": "[", "color": "blue", - "covers": [ "MOUTH" ], + "covers": [ "mouth" ], "coverage": 95, "encumbrance": 7, "warmth": 0, diff --git a/data/mods/Dark-Skies-Above/obsolete.json b/data/mods/Dark-Skies-Above/obsolete.json index 81da99488f6db..775497a48f981 100644 --- a/data/mods/Dark-Skies-Above/obsolete.json +++ b/data/mods/Dark-Skies-Above/obsolete.json @@ -57,7 +57,7 @@ "symbol": "[", "looks_like": "power_armor", "color": "light_gray", - "covers": [ "TORSO", "ARMS", "HANDS", "LEGS", "FEET", "HEAD" ], + "covers": [ "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r", "head" ], "coverage": 95, "encumbrance": 24, "max_encumbrance": 40, @@ -83,7 +83,8 @@ "material": [ "plastic" ], "symbol": "[", "color": "dark_gray", - "covers": [ "ARM_EITHER", "HAND_EITHER" ], + "covers": [ "arm_l", "arm_r", "hand_l", "hand_r" ], + "sided": true, "coverage": 85, "encumbrance": 16, "material_thickness": 3, @@ -103,7 +104,8 @@ "material": [ "steel" ], "symbol": "[", "color": "dark_gray", - "covers": [ "ARM_EITHER", "HAND_EITHER" ], + "covers": [ "arm_l", "arm_r", "hand_l", "hand_r" ], + "sided": true, "coverage": 90, "encumbrance": 20, "material_thickness": 3, diff --git a/data/mods/DinoMod/monstergroups/fungi.json b/data/mods/DinoMod/monstergroups/fungi.json index 3a568a9d6b556..569949fcec0f3 100644 --- a/data/mods/DinoMod/monstergroups/fungi.json +++ b/data/mods/DinoMod/monstergroups/fungi.json @@ -6,6 +6,7 @@ "monsters": [ { "monster": "mon_zpinosaurus_fungus", "freq": 0, "cost_multiplier": 0 }, { "monster": "mon_zyrannosaurus_fungus", "freq": 0, "cost_multiplier": 0 }, + { "monster": "mon_zankylosaurus_fungus", "freq": 0, "cost_multiplier": 0 }, { "monster": "mon_zeinonychus_fungus", "freq": 0, "cost_multiplier": 0 } ] }, @@ -16,6 +17,7 @@ "monsters": [ { "monster": "mon_zpinosaurus_fungus", "freq": 50, "cost_multiplier": 0 }, { "monster": "mon_zyrannosaurus_fungus", "freq": 50, "cost_multiplier": 0 }, + { "monster": "mon_zankylosaurus_fungus", "freq": 250, "cost_multiplier": 0 }, { "monster": "mon_zeinonychus_fungus", "freq": 75, "cost_multiplier": 0 } ] }, @@ -26,6 +28,7 @@ "monsters": [ { "monster": "mon_zpinosaurus_fungus", "freq": 50, "cost_multiplier": 0 }, { "monster": "mon_zyrannosaurus_fungus", "freq": 50, "cost_multiplier": 0 }, + { "monster": "mon_zankylosaurus_fungus", "freq": 250, "cost_multiplier": 0 }, { "monster": "mon_zeinonychus_fungus", "freq": 75, "cost_multiplier": 0 } ] } diff --git a/data/mods/DinoMod/monstergroups/zinosaur.json b/data/mods/DinoMod/monstergroups/zinosaur.json index 5b0f13197d8df..2eb87d3d409c0 100644 --- a/data/mods/DinoMod/monstergroups/zinosaur.json +++ b/data/mods/DinoMod/monstergroups/zinosaur.json @@ -14,7 +14,6 @@ { "monster": "mon_zankylosaurus", "freq": 5, "cost_multiplier": 40, "starts": 72 }, { "monster": "mon_ziplodocus", "freq": 10, "cost_multiplier": 40, "starts": 72, "pack_size": [ 1, 2 ] }, { "monster": "mon_zapatosaurus", "freq": 5, "cost_multiplier": 50, "starts": 72, "pack_size": [ 1, 2 ] }, - { "monster": "mon_zeratosaurus", "freq": 1, "cost_multiplier": 60, "starts": 72 }, { "monster": "mon_zallosaurus", "freq": 8, "cost_multiplier": 60, "starts": 72 }, { "monster": "mon_zeinonychus", "freq": 3, "cost_multiplier": 30, "starts": 72, "pack_size": [ 2, 3 ] }, { "monster": "mon_zutahraptor", "freq": 5, "cost_multiplier": 60, "starts": 72 }, @@ -23,7 +22,8 @@ { "monster": "mon_zorythosaurus", "freq": 20, "cost_multiplier": 20, "starts": 72, "pack_size": [ 2, 4 ] }, { "monster": "mon_zedmontosaurus", "freq": 100, "cost_multiplier": 20, "starts": 72, "pack_size": [ 4, 6 ] }, { "monster": "mon_zimorphodon", "freq": 50, "cost_multiplier": 10, "starts": 72, "pack_size": [ 2, 4 ] }, - { "monster": "mon_zilophosaurus", "freq": 1, "cost_multiplier": 20, "starts": 72, "pack_size": [ 1, 2 ] } + { "monster": "mon_zilophosaurus", "freq": 1, "cost_multiplier": 20, "starts": 72, "pack_size": [ 1, 2 ] }, + { "monster": "mon_zeratosaurus", "freq": 1, "cost_multiplier": 60, "starts": 72 } ] }, { @@ -56,11 +56,12 @@ }, { "type": "monstergroup", - "name": "GROUP_zeratosaurus_UPGRADE", - "default": "mon_seratosaurus", + "name": "GROUP_zankylosaurus_UPGRADE", + "default": "mon_sankylosaurus", "monsters": [ - { "monster": "mon_seratosaurus", "freq": 45, "cost_multiplier": 5 }, - { "monster": "mon_zeratosaurus_brute", "freq": 23, "cost_multiplier": 5 } + { "monster": "mon_sankylosaurus", "freq": 45, "cost_multiplier": 5 }, + { "monster": "mon_zankylosaurus_shady", "freq": 15, "cost_multiplier": 5 }, + { "monster": "mon_zankylosaurus_brute", "freq": 23, "cost_multiplier": 5 } ] }, { @@ -90,6 +91,15 @@ { "monster": "mon_zutahraptor_brute", "freq": 23, "cost_multiplier": 5 } ] }, + { + "type": "monstergroup", + "name": "GROUP_zeratosaurus_UPGRADE", + "default": "mon_seratosaurus", + "monsters": [ + { "monster": "mon_seratosaurus", "freq": 45, "cost_multiplier": 5 }, + { "monster": "mon_zeratosaurus_brute", "freq": 23, "cost_multiplier": 5 } + ] + }, { "type": "monstergroup", "name": "GROUP_zyrannosaurus_BRUTE", @@ -99,6 +109,15 @@ { "monster": "mon_zyrannosaurus_truck", "freq": 70, "cost_multiplier": 10 } ] }, + { + "type": "monstergroup", + "name": "GROUP_zankylosaurus_BRUTE", + "default": "mon_zankylosaurus_hulk", + "monsters": [ + { "monster": "mon_zankylosaurus_hulk", "freq": 100, "cost_multiplier": 10 }, + { "monster": "mon_zankylosaurus_tank", "freq": 70, "cost_multiplier": 10 } + ] + }, { "type": "monstergroup", "name": "GROUP_ZOMBIE", @@ -114,7 +133,6 @@ { "monster": "mon_zankylosaurus", "freq": 5, "cost_multiplier": 40, "starts": 72 }, { "monster": "mon_ziplodocus", "freq": 1, "cost_multiplier": 40, "starts": 72, "pack_size": [ 1, 2 ] }, { "monster": "mon_zapatosaurus", "freq": 1, "cost_multiplier": 50, "starts": 72, "pack_size": [ 1, 2 ] }, - { "monster": "mon_zeratosaurus", "freq": 1, "cost_multiplier": 60, "starts": 72 }, { "monster": "mon_zallosaurus", "freq": 8, "cost_multiplier": 60, "starts": 72 }, { "monster": "mon_zeinonychus", "freq": 3, "cost_multiplier": 30, "starts": 72, "pack_size": [ 2, 3 ] }, { "monster": "mon_zutahraptor", "freq": 5, "cost_multiplier": 60, "starts": 72 }, @@ -123,7 +141,8 @@ { "monster": "mon_zorythosaurus", "freq": 2, "cost_multiplier": 20, "starts": 72, "pack_size": [ 2, 4 ] }, { "monster": "mon_zedmontosaurus", "freq": 10, "cost_multiplier": 20, "starts": 72, "pack_size": [ 4, 6 ] }, { "monster": "mon_zimorphodon", "freq": 5, "cost_multiplier": 10, "starts": 72, "pack_size": [ 2, 4 ] }, - { "monster": "mon_zilophosaurus", "freq": 1, "cost_multiplier": 20, "starts": 72, "pack_size": [ 1, 2 ] } + { "monster": "mon_zilophosaurus", "freq": 1, "cost_multiplier": 20, "starts": 72, "pack_size": [ 1, 2 ] }, + { "monster": "mon_zeratosaurus", "freq": 1, "cost_multiplier": 60, "starts": 72 } ] } ] diff --git a/data/mods/DinoMod/monsters/dinosaur.json b/data/mods/DinoMod/monsters/dinosaur.json index f48e1948fea96..3cf1367e1c521 100644 --- a/data/mods/DinoMod/monsters/dinosaur.json +++ b/data/mods/DinoMod/monsters/dinosaur.json @@ -27,7 +27,6 @@ "dodge": 4, "vision_day": 50, "armor_bash": 1, - "armor_cut": 0, "hp": 20, "death_function": [ "NORMAL" ], "description": "A fast moving bipedal dinosaur about the size of a turkey. Its teeth and claws are small but sharp.", @@ -46,7 +45,6 @@ "SWIMS", "CATFOOD", "SWARMS", - "ATTACKMON", "GROUP_MORALE" ], "harvest": "mammal_leather", @@ -122,6 +120,7 @@ "dodge": 3, "armor_bash": 2, "armor_cut": 1, + "armor_bullet": 1, "hp": 40, "death_function": [ "NORMAL" ], "zombify_into": "mon_zachycephalosaurus", @@ -164,7 +163,6 @@ "melee_dice": 3, "melee_dice_sides": 8, "melee_cut": 15, - "dodge": 0, "armor_bash": 4, "armor_cut": 2, "armor_bullet": 2, @@ -175,7 +173,7 @@ "reproduction": { "baby_egg": "egg_spinosaurus", "baby_count": 3, "baby_timer": 24 }, "baby_flags": [ "SPRING", "SUMMER" ], "biosignature": { "biosig_item": "feces_bird", "biosig_timer": 3 }, - "flags": [ "SEES", "SMELLS", "HEARS", "ANIMAL", "PATH_AVOID_DANGER_1", "BASHES", "DESTROYS", "ATTACKMON", "WARM", "SWIMS" ], + "flags": [ "SEES", "SMELLS", "HEARS", "ANIMAL", "PATH_AVOID_DANGER_1", "BASHES", "DESTROYS", "WARM", "SWIMS" ], "harvest": "dino_large_pred", "anger_triggers": [ "STALK", "PLAYER_WEAK", "HURT" ], "placate_triggers": [ "MEAT" ], @@ -200,7 +198,6 @@ "melee_dice": 3, "melee_dice_sides": 6, "melee_cut": 13, - "dodge": 0, "armor_bash": 4, "armor_cut": 2, "armor_bullet": 2, @@ -211,7 +208,7 @@ "reproduction": { "baby_egg": "egg_tyrannosaurus", "baby_count": 3, "baby_timer": 24 }, "baby_flags": [ "SPRING", "SUMMER" ], "biosignature": { "biosig_item": "feces_bird", "biosig_timer": 3 }, - "flags": [ "SEES", "SMELLS", "HEARS", "ANIMAL", "PATH_AVOID_DANGER_1", "BASHES", "DESTROYS", "ATTACKMON", "WARM" ], + "flags": [ "SEES", "SMELLS", "HEARS", "ANIMAL", "PATH_AVOID_DANGER_1", "BASHES", "DESTROYS", "WARM" ], "harvest": "dino_large_feather_pred", "anger_triggers": [ "STALK", "PLAYER_WEAK", "HURT" ], "placate_triggers": [ "MEAT" ], @@ -237,7 +234,6 @@ "melee_dice": 3, "melee_dice_sides": 4, "melee_cut": 10, - "dodge": 0, "armor_bash": 4, "armor_cut": 2, "armor_bullet": 2, @@ -248,7 +244,7 @@ "reproduction": { "baby_egg": "egg_albertosaurus", "baby_count": 3, "baby_timer": 24 }, "baby_flags": [ "SPRING", "SUMMER" ], "biosignature": { "biosig_item": "feces_bird", "biosig_timer": 3 }, - "flags": [ "SEES", "SMELLS", "HEARS", "ANIMAL", "PATH_AVOID_DANGER_1", "BASHES", "ATTACKMON", "WARM" ], + "flags": [ "SEES", "SMELLS", "HEARS", "ANIMAL", "PATH_AVOID_DANGER_1", "BASHES", "WARM" ], "special_attacks": [ [ "GRAB", 7 ], [ "LUNGE", 5 ] ], "harvest": "dino_large_feather_pred", "anger_triggers": [ "STALK", "PLAYER_WEAK", "HURT" ], @@ -275,7 +271,6 @@ "melee_dice": 2, "melee_dice_sides": 8, "melee_cut": 15, - "dodge": 0, "armor_bash": 4, "armor_cut": 2, "armor_bullet": 2, @@ -357,9 +352,9 @@ "melee_dice_sides": 4, "melee_cut": 1, "dodge": 1, - "armor_bash": 6, - "armor_cut": 4, - "armor_bullet": 3, + "armor_bash": 15, + "armor_cut": 18, + "armor_bullet": 6, "hp": 120, "death_function": [ "NORMAL" ], "zombify_into": "mon_zankylosaurus", @@ -410,7 +405,7 @@ "melee_dice": 4, "melee_dice_sides": 4, "armor_bash": 6, - "armor_cut": 1, + "armor_cut": 2, "armor_bullet": 2, "hp": 400, "death_function": [ "NORMAL" ], @@ -486,7 +481,6 @@ "melee_cut": 1, "dodge": 4, "armor_bash": 1, - "armor_cut": 0, "hp": 10, "death_function": [ "NORMAL" ], "death_drops": { "subtype": "collection", "groups": [ [ "science", 100 ], [ "mut_lab", 10 ] ] }, @@ -523,7 +517,6 @@ "dodge": 3, "armor_bash": 1, "armor_cut": 1, - "armor_bullet": 1, "hp": 30, "death_function": [ "NORMAL" ], "vision_night": 5, @@ -560,7 +553,6 @@ "dodge": 2, "armor_bash": 1, "armor_cut": 1, - "armor_bullet": 1, "hp": 60, "death_function": [ "NORMAL" ], "zombify_into": "mon_zeinonychus", @@ -648,8 +640,8 @@ "melee_cut": 2, "dodge": 1, "armor_bash": 4, - "armor_cut": 1, - "armor_bullet": 1, + "armor_cut": 2, + "armor_bullet": 2, "hp": 80, "death_function": [ "NORMAL" ], "zombify_into": "mon_zamptosaurus", @@ -693,7 +685,6 @@ "melee_dice": 2, "melee_dice_sides": 6, "melee_cut": 2, - "dodge": 0, "armor_bash": 4, "armor_cut": 4, "armor_bullet": 3, diff --git a/data/mods/DinoMod/monsters/fungus.json b/data/mods/DinoMod/monsters/fungus.json index 122d5d67bff80..8bc86b455790e 100644 --- a/data/mods/DinoMod/monsters/fungus.json +++ b/data/mods/DinoMod/monsters/fungus.json @@ -8,13 +8,9 @@ "default_faction": "fungus", "species": [ "FUNGUS" ], "diff": 2, - "hp": 500, - "speed": 52, + "proportional": { "hp": 0.75, "speed": 0.65 }, "color": "light_gray", - "melee_skill": 9, - "melee_dice": 2, - "melee_dice_sides": 11, - "armor_bash": 9, + "relative": { "melee_skill": -1, "melee_dice": -1, "melee_dice_sides": 3, "armor_bash": 3 }, "vision_day": 5, "vision_night": 5, "special_attacks": [ [ "FUNGUS", 200 ], { "type": "bite", "cooldown": 5 } ], @@ -30,19 +26,33 @@ "default_faction": "fungus", "species": [ "FUNGUS" ], "diff": 2, - "hp": 375, - "speed": 26, + "proportional": { "hp": 0.75, "speed": 0.65 }, "color": "light_gray", - "melee_skill": 9, - "melee_dice": 2, - "melee_dice_sides": 9, - "armor_bash": 9, + "relative": { "melee_skill": -1, "melee_dice": -1, "melee_dice_sides": 3, "armor_bash": 3 }, "vision_day": 5, "vision_night": 5, "special_attacks": [ [ "FUNGUS", 200 ], { "type": "bite", "cooldown": 5 } ], "upgrades": { }, "flags": [ "SEES", "SMELLS", "POISON", "STUMBLES", "BASHES", "DESTROYS", "NO_BREATHE", "FILTHY", "WARM" ] }, + { + "id": "mon_zankylosaurus_fungus", + "type": "MONSTER", + "name": { "str": "fungal Ankylosaurus zombie" }, + "description": "Once something like a giant armadillo dinosaur hybrid with a spiked tail, fungal tendrils now sprout from its mouth, eyes, and other orifices, holding together an enormous shambling mass of mold-covered flesh.", + "copy-from": "mon_zankylosaurus", + "default_faction": "fungus", + "species": [ "FUNGUS" ], + "diff": 2, + "proportional": { "hp": 0.75, "speed": 0.65 }, + "color": "light_gray", + "relative": { "melee_skill": -1, "melee_dice": -1, "melee_dice_sides": 3, "armor_bash": 3 }, + "vision_day": 5, + "vision_night": 5, + "special_attacks": [ [ "FUNGUS", 200 ] ], + "upgrades": { }, + "flags": [ "SEES", "SMELLS", "POISON", "STUMBLES", "NO_BREATHE", "FILTHY", "WARM", "BASHES" ] + }, { "id": "mon_zeinonychus_fungus", "type": "MONSTER", @@ -52,13 +62,9 @@ "default_faction": "fungus", "species": [ "FUNGUS" ], "diff": 2, - "hp": 75, - "speed": 13, + "proportional": { "hp": 0.75, "speed": 0.65 }, "color": "light_gray", - "melee_skill": 6, - "melee_dice": 1, - "melee_dice_sides": 11, - "armor_bash": 5, + "relative": { "melee_skill": -1, "melee_dice": -1, "melee_dice_sides": 3, "armor_bash": 3 }, "vision_day": 5, "vision_night": 5, "special_attacks": [ [ "FUNGUS", 200 ], { "type": "bite", "cooldown": 5 } ], diff --git a/data/mods/DinoMod/monsters/zed-dinosaur.json b/data/mods/DinoMod/monsters/zed-dinosaur.json index 57abfc71bd2b4..82f655c881818 100644 --- a/data/mods/DinoMod/monsters/zed-dinosaur.json +++ b/data/mods/DinoMod/monsters/zed-dinosaur.json @@ -216,11 +216,17 @@ "type": "MONSTER", "id": "mon_zankylosaurus", "name": { "str_sp": "Ankylosaurus zombie" }, - "copy-from": "mon_zamptosaurus", "looks_like": "mon_ankylosaurus", + "species": [ "ZOMBIE" ], + "default_faction": "zombie", + "symbol": "Z", + "color": "green", "volume": "1000 L", "weight": "6000 kg", "bodytype": "elephant", + "material": [ "flesh" ], + "aggression": 100, + "morale": 100, "speed": 20, "melee_skill": 7, "melee_dice": 2, @@ -230,8 +236,14 @@ "armor_cut": 7, "armor_bullet": 4, "hp": 200, + "death_function": [ "NORMAL" ], + "special_attacks": [ [ "scratch", 10 ], { "type": "bite", "cooldown": 5 } ], "description": "The shuffling corpse of what looks like a giant armadillo with peeling armored plates and black, glistening eyes. Its tail ends in a massive spiked club of bone.", - "upgrades": { "half_life": 14, "into": "mon_zankylosaurus_brute" } + "upgrades": { "half_life": 14, "into_group": "GROUP_zankylosaurus_UPGRADE" }, + "flags": [ "SEES", "SMELLS", "HEARS", "POISON", "STUMBLES", "NO_BREATHE", "REVIVES", "FILTHY", "WARM", "BASHES" ], + "vision_night": 3, + "harvest": "zed_dino_leather", + "categories": [ "DINOSAUR", "CLASSIC" ] }, { "type": "MONSTER", @@ -503,7 +515,7 @@ "looks_like": "mon_zyrannosaurus", "volume": "540 L", "weight": "540 kg", - "speed": 200, + "speed": 150, "melee_skill": 8, "melee_dice": 3, "melee_dice_sides": 4, diff --git a/data/mods/DinoMod/monsters/zinosaur_upgrade.json b/data/mods/DinoMod/monsters/zinosaur_upgrade.json index 83480b1c769c1..b34b489af2775 100644 --- a/data/mods/DinoMod/monsters/zinosaur_upgrade.json +++ b/data/mods/DinoMod/monsters/zinosaur_upgrade.json @@ -180,7 +180,7 @@ "armor_bullet": 5, "vision_night": 1 }, - "upgrades": { }, + "upgrades": { "half_life": 21, "into_group": "GROUP_zankylosaurus_BRUTE" }, "special_attacks": [ [ "SMASH", 30 ] ], "extend": { "flags": [ "GROUP_BASH", "PUSH_MON", "PUSH_VEH" ] }, "categories": [ "DINOSAUR" ] @@ -231,30 +231,6 @@ "extend": { "flags": [ "GROUP_BASH", "PUSH_MON", "PUSH_VEH" ] }, "categories": [ "DINOSAUR" ] }, - { - "type": "MONSTER", - "id": "mon_zeratosaurus_brute", - "name": { "str": "Draco Titan" }, - "copy-from": "mon_zeratosaurus", - "looks_like": "mon_zyrannosaurus", - "description": "This zombie is enormous, scaly, studded with bony spikes, and it moves with horrible speed. Its colorful horns and bone spikes sit on a body bulging with distended muscles and swollen, festering wounds.", - "diff": 2, - "color": "red", - "proportional": { "hp": 1.5, "speed": 1.5 }, - "relative": { - "melee_dice": 1, - "melee_dice_sides": 5, - "melee_cut": 2, - "armor_bash": 4, - "armor_cut": 6, - "armor_bullet": 5, - "vision_night": 1 - }, - "upgrades": { }, - "special_attacks": [ [ "SMASH", 30 ] ], - "extend": { "flags": [ "GROUP_BASH", "PUSH_MON", "PUSH_VEH" ] }, - "categories": [ "DINOSAUR" ] - }, { "type": "MONSTER", "id": "mon_zallosaurus_brute", @@ -309,7 +285,8 @@ "description": "The swaying, hopping corpse of a large bipedal dinosaur with feathered arms, a long tail, and long sharp scythe-like claws. Its entire body bulges with distended muscles and swollen, festering wounds.", "diff": 2, "color": "red", - "proportional": { "hp": 1.5, "speed": 1.5 }, + "proportional": { "hp": 1.5 }, + "speed": 150, "relative": { "melee_dice": 1, "melee_dice_sides": 5, @@ -462,6 +439,30 @@ "extend": { "flags": [ "GROUP_BASH", "PUSH_MON", "PUSH_VEH" ] }, "categories": [ "DINOSAUR" ] }, + { + "type": "MONSTER", + "id": "mon_zeratosaurus_brute", + "name": { "str": "Draco Titan" }, + "copy-from": "mon_zeratosaurus", + "looks_like": "mon_zyrannosaurus", + "description": "This zombie is enormous, scaly, studded with bony spikes, and it moves with horrible speed. Its colorful horns and bone spikes sit on a body bulging with distended muscles and swollen, festering wounds.", + "diff": 2, + "color": "red", + "proportional": { "hp": 1.5 }, + "relative": { + "melee_dice": 1, + "melee_dice_sides": 5, + "melee_cut": 2, + "armor_bash": 4, + "armor_cut": 6, + "armor_bullet": 5, + "vision_night": 1 + }, + "upgrades": { }, + "special_attacks": [ [ "SMASH", 30 ] ], + "extend": { "flags": [ "GROUP_BASH", "PUSH_MON", "PUSH_VEH" ] }, + "categories": [ "DINOSAUR" ] + }, { "type": "MONSTER", "id": "mon_zpinosaurus_shady", @@ -489,6 +490,19 @@ "vision_night": 30, "categories": [ "DINOSAUR" ] }, + { + "type": "MONSTER", + "id": "mon_zankylosaurus_shady", + "name": { "str": "shady Ankylosaurus zombie" }, + "copy-from": "mon_zankylosaurus", + "color": "light_gray", + "description": "An uncanny shadow envelops this dinosaur. You can make out the outline of a large, heavily armored four-legged dinosaur with a spiked tail.", + "upgrades": { }, + "extend": { "flags": [ "NIGHT_INVISIBILITY" ] }, + "vision_day": 3, + "vision_night": 40, + "categories": [ "DINOSAUR" ] + }, { "type": "MONSTER", "id": "mon_zeinonychus_shady", @@ -554,6 +568,32 @@ "harvest": "mr_bones", "categories": [ "DINOSAUR" ] }, + { + "type": "MONSTER", + "id": "mon_sankylosaurus", + "name": { "str_sp": "Bone Fortress" }, + "copy-from": "mon_zankylosaurus", + "looks_like": "mon_ankylosaurus", + "color": "white", + "material": [ "bone" ], + "armor_bash": 0, + "description": "Already heavily protected, this zombified Ankylosaurus has grown even denser bone armor and a larger and spikier bony tail and it must be even slower if possible", + "proportional": { "hp": 0.4, "speed": 0.875 }, + "relative": { + "melee_dice": 9, + "melee_dice_sides": 5, + "melee_cut": 7, + "armor_cut": 22, + "armor_bullet": 30, + "armor_stab": 30, + "armor_acid": 3, + "vision_day": -20 + }, + "upgrades": { }, + "extend": { "flags": [ "HARDTOSHOOT" ] }, + "harvest": "mr_bones", + "categories": [ "DINOSAUR" ] + }, { "type": "MONSTER", "id": "mon_seratosaurus", @@ -653,6 +693,29 @@ ], "death_function": [ "FIREBALL" ] }, + { + "type": "MONSTER", + "id": "mon_zankylosaurus_tank", + "name": { "str_sp": "Tankylosaurus" }, + "copy-from": "mon_zankylosaurus_brute", + "looks_like": "mon_ankylosaurus", + "description": "Enormous heavily armored zombie dinosaur lifting a spiked tail and what looks like a US Army M1 Abrams Tank with a sparking but still functional turret.", + "diff": 30, + "color": "dark_gray_red", + "luminance": 20, + "proportional": { "hp": 1.5, "speed": 0.8 }, + "relative": { "armor_bash": 30, "armor_cut": 37, "armor_bullet": 30, "armor_stab": 30, "armor_acid": 3 }, + "extend": { "flags": [ "DRIPS_GASOLINE", "LOUDMOVES" ] }, + "special_attacks": [ [ "MULTI_ROBOT", 30 ] ], + "upgrades": { }, + "death_drops": [ + { "item": "mil_plate", "count": 4 }, + { "group": "helicopter", "count": 10 }, + { "group": "mil_hw", "count": 10 }, + { "group": "supplies_metal", "count": 10 } + ], + "death_function": [ "FIREBALL" ] + }, { "type": "MONSTER", "id": "mon_zyrannosaurus_hulk", @@ -666,5 +729,19 @@ "proportional": { "hp": 4, "speed": 1.25 }, "relative": { "melee_dice": 1, "melee_cut": -4, "armor_bash": 4, "armor_cut": 6, "armor_bullet": 5 }, "special_attacks": [ [ "SMASH", 20 ] ] + }, + { + "type": "MONSTER", + "id": "mon_zankylosaurus_hulk", + "name": { "str_sp": "Ankylosaurus hulk" }, + "copy-from": "mon_zankylosaurus_brute", + "looks_like": "mon_ankylosaurus", + "description": "A hideously swollen zombified Ankylosaurus body towering into the sky. Its massive body bulges with distended muscles and enormous bony armor.", + "diff": 5, + "weight": "55000 kg", + "color": "white_magenta", + "proportional": { "hp": 4, "speed": 1.25 }, + "relative": { "melee_dice": 1, "melee_cut": -4, "armor_bash": 4, "armor_cut": 6, "armor_bullet": 5 }, + "special_attacks": [ [ "SMASH", 20 ] ] } ] diff --git a/data/mods/Generic_Guns/firearms/gg_firearms_migration.json b/data/mods/Generic_Guns/firearms/gg_firearms_migration.json index 398eaa75f7b0e..79b1dea68c626 100644 --- a/data/mods/Generic_Guns/firearms/gg_firearms_migration.json +++ b/data/mods/Generic_Guns/firearms/gg_firearms_migration.json @@ -118,13 +118,20 @@ "90two", "px4", "90two40", - "px4_40" + "px4_40", + "glock_29", + "glock_20", + "glock_40", + "m1911_10", + "witness_10", + "p220_10", + "xd_10" ], "type": "MIGRATION", "replace": "pistol_medium" }, { - "id": [ "cx4", "hk_mp5_semi_pistol", "ksub2000", "calico" ], + "id": [ "cx4", "hk_mp5_semi_pistol", "ksub2000", "calico", "hk_mp5_10_semi", "TDI_10" ], "type": "MIGRATION", "replace": "pistol_pcc" }, diff --git a/data/mods/Generic_Guns/magazines/gg_magazines_migration.json b/data/mods/Generic_Guns/magazines/gg_magazines_migration.json index 43e4b3a2bbe60..e21b4da1436f2 100644 --- a/data/mods/Generic_Guns/magazines/gg_magazines_migration.json +++ b/data/mods/Generic_Guns/magazines/gg_magazines_migration.json @@ -52,7 +52,13 @@ "ccpmag", "px4mag", "90two40mag", - "px4_40mag" + "px4_40mag", + "glock_20mag", + "glock_29mag", + "m1911_10mag", + "p220_10_mag", + "xd_10_mag", + "witness_mag_10" ], "type": "MIGRATION", "replace": "pistol_mag" @@ -99,7 +105,9 @@ "tec9mag", "uzimag", "cz75mag_26rd", - "skorpion82mag" + "skorpion82mag", + "mp5_10_mag", + "tdi_10mm_mag" ], "type": "MIGRATION", "replace": "pistol_smg_mag" diff --git a/data/mods/Magiclysm/Spells/animist.json b/data/mods/Magiclysm/Spells/animist.json index 2433112624798..75906365c2e17 100644 --- a/data/mods/Magiclysm/Spells/animist.json +++ b/data/mods/Magiclysm/Spells/animist.json @@ -237,5 +237,27 @@ "min_duration": 6000, "max_duration": 60000, "duration_increment": 2160 + }, + { + "id": "animist_summon_decaying_boneclub", + "type": "SPELL", + "name": { "str": "Decaying Boneclub" }, + "description": "This spell links your live blood to the dead blood & bones, creating a club hungry for the flesh of the living.", + "effect": "spawn_item", + "effect_str": "decaying_boneclub", + "valid_targets": [ "self" ], + "flags": [ "SOMATIC", "CONCENTRATE", "VERBAL" ], + "components": "spell_components_decayingboneclub", + "max_level": 15, + "min_damage": 1, + "max_damage": 1, + "min_duration": 30000, + "max_duration": 120000, + "duration_increment": 6000, + "spell_class": "ANIMIST", + "base_casting_time": 400, + "base_energy_cost": 6, + "energy_source": "HP", + "difficulty": 6 } ] diff --git a/data/mods/Magiclysm/Spells/biomancer.json b/data/mods/Magiclysm/Spells/biomancer.json index 903832890d06d..dd17c1b2037dd 100644 --- a/data/mods/Magiclysm/Spells/biomancer.json +++ b/data/mods/Magiclysm/Spells/biomancer.json @@ -272,5 +272,51 @@ "min_duration": 6000, "max_duration": 12000, "duration_increment": 300 + }, + { + "id": "corrosive_aura_spell", + "type": "SPELL", + "name": "Caustic Feedback", + "description": "This is a sub-spell of the Caustic Aura spell.", + "valid_targets": [ "hostile" ], + "effect": "target_attack", + "damage_type": "acid", + "min_damage": 3, + "max_damage": 3, + "flags": [ "SILENT" ], + "sound_type": "combat", + "sound_description": "acidic sizzle!", + "min_range": 2, + "max_range": 2, + "min_dot": 2, + "max_dot": 2, + "min_duration": 300, + "max_duration": 300 + }, + { + "id": "biomancer_caustic_aura", + "type": "SPELL", + "name": "Caustic Aura", + "description": "This spell suspends acid in a layer around you, corroding melee attackers when struck and enhancing your melee damage.", + "valid_targets": [ "self" ], + "effect": "spawn_item", + "effect_str": "aura_caustic", + "flags": [ "SOMATIC", "CONCENTRATE" ], + "components": "spell_components_causticaura", + "energy_source": "MANA", + "spell_class": "BIOMANCER", + "difficulty": 4, + "min_damage": 1, + "max_damage": 1, + "base_casting_time": 400, + "final_casting_time": 400, + "base_energy_cost": 350, + "final_energy_cost": 350, + "max_level": 15, + "min_range": 1, + "max_range": 1, + "min_duration": 6000, + "max_duration": 30000, + "duration_increment": 1600 } ] diff --git a/data/mods/Magiclysm/Spells/druid.json b/data/mods/Magiclysm/Spells/druid.json index 3b4bd216081d9..cb88cdfbe5ec9 100644 --- a/data/mods/Magiclysm/Spells/druid.json +++ b/data/mods/Magiclysm/Spells/druid.json @@ -330,5 +330,27 @@ "max_pierce": 3, "pierce_increment": 0.3, "damage_type": "cut" + }, + { + "id": "druid_feralform", + "type": "SPELL", + "name": "Feral Form", + "description": "This spell unleashs your inner beast, growing claws & fangs to rend your foes limb from limb.", + "valid_targets": [ "self" ], + "effect": "spawn_item", + "effect_str": "aura_feral", + "flags": [ "SOMATIC", "VERBAL" ], + "components": "spell_components_feralform", + "spell_class": "DRUID", + "energy_source": "MANA", + "difficulty": 4, + "base_casting_time": 400, + "base_energy_cost": 200, + "max_level": 15, + "min_damage": 1, + "max_damage": 1, + "min_duration": 60000, + "max_duration": 150000, + "duration_increment": 6000 } ] diff --git a/data/mods/Magiclysm/Spells/earthshaper.json b/data/mods/Magiclysm/Spells/earthshaper.json index 97e7e26c540b3..9f152e45bb459 100644 --- a/data/mods/Magiclysm/Spells/earthshaper.json +++ b/data/mods/Magiclysm/Spells/earthshaper.json @@ -76,6 +76,7 @@ "description": "This spell projects a wide spray of sharp metal shards, cutting into your foes and friends alike.", "valid_targets": [ "hostile", "ground", "ally" ], "flags": [ "SOMATIC", "LOUD" ], + "components": "spell_components_shardspray", "effect": "cone_attack", "spell_class": "EARTHSHAPER", "energy_source": "MANA", @@ -83,16 +84,19 @@ "base_casting_time": 100, "base_energy_cost": 100, "max_level": 20, - "min_damage": 10, - "max_damage": 60, - "damage_increment": 2, + "min_damage": 30, + "max_damage": 80, + "damage_increment": 2.5, "damage_type": "cut", "min_aoe": 25, "max_aoe": 60, "aoe_increment": 5, - "min_range": 1, + "min_range": 3, "max_range": 10, - "range_increment": 0.5 + "range_increment": 0.5, + "min_pierce": 0, + "max_pierce": 5, + "pierce_increment": 0.4 }, { "id": "eshaper_piercing_bolt", diff --git a/data/mods/Magiclysm/Spells/kelvinist.json b/data/mods/Magiclysm/Spells/kelvinist.json index db7d093729da0..0b4d7e04ded04 100644 --- a/data/mods/Magiclysm/Spells/kelvinist.json +++ b/data/mods/Magiclysm/Spells/kelvinist.json @@ -304,5 +304,59 @@ "spell_class": "KELVINIST", "energy_source": "MANA", "flags": [ "PERMANENT", "NO_LEGS", "CONCENTRATE" ] + }, + { + "id": "kelvinist_summon_flamesword", + "type": "SPELL", + "name": "Flamesword", + "description": "This spell ignites a wooden sword, creating a flaming blade able to burn, bruise, and chop.", + "valid_targets": [ "none" ], + "flags": [ "NO_LEGS" ], + "effect": "spawn_item", + "effect_str": "flamesword", + "components": "spell_components_flamesword", + "min_damage": 1, + "max_damage": 1, + "min_duration": 30000, + "max_duration": 90000, + "duration_increment": 6000, + "max_level": 10, + "spell_class": "KELVINIST", + "energy_source": "MANA", + "base_casting_time": 250, + "base_energy_cost": 300, + "difficulty": 4 + }, + { + "id": "kelvinist_flamebreath", + "type": "SPELL", + "name": { "str": "Flamebreath" }, + "description": "This spell ignites dust scattered in the air, creating a cone of flame. The hot ashes can cling to targets, causing additional burns over time.", + "effect": "cone_attack", + "valid_targets": [ "ally", "hostile", "ground" ], + "flags": [ "SOMATIC", "CONCENTRATE", "IGNITE_FLAMMABLE" ], + "components": "spell_components_flamebreath", + "max_level": 10, + "min_damage": 25, + "max_damage": 45, + "damage_increment": 2, + "min_dot": 2, + "max_dot": 5, + "dot_increment": 0.3, + "min_duration": 400, + "max_duration": 1000, + "duration_increment": 60, + "min_range": 5, + "max_range": 12, + "range_increment": 0.7, + "min_aoe": 15, + "max_aoe": 30, + "aoe_increment": 1.5, + "spell_class": "KELVINIST", + "base_casting_time": 150, + "base_energy_cost": 200, + "energy_source": "MANA", + "difficulty": 5, + "damage_type": "fire" } ] diff --git a/data/mods/Magiclysm/Spells/magus.json b/data/mods/Magiclysm/Spells/magus.json index 70d3f2d7e95a3..dd88cf5cff181 100644 --- a/data/mods/Magiclysm/Spells/magus.json +++ b/data/mods/Magiclysm/Spells/magus.json @@ -297,5 +297,27 @@ "flags": [ "VERBAL", "SOMATIC", "NO_LEGS", "CONCENTRATE" ], "effect": "target_attack", "effect_str": "foxs_cunning" + }, + { + "id": "magus_summon_impact_sling", + "type": "SPELL", + "name": { "str": "Impact Sling" }, + "description": "This spell infuses a sling with tremendous force, delivering devasting pebble shots until the energy tears it apart.", + "effect": "spawn_item", + "effect_str": "impactsling", + "valid_targets": [ "self" ], + "flags": [ "SOMATIC", "CONCENTRATE", "VERBAL" ], + "components": "spell_components_impactsling", + "max_level": 15, + "min_damage": 1, + "max_damage": 1, + "min_duration": 18000, + "max_duration": 60000, + "duration_increment": 3000, + "spell_class": "MAGUS", + "base_casting_time": 400, + "base_energy_cost": 350, + "energy_source": "MANA", + "difficulty": 4 } ] diff --git a/data/mods/Magiclysm/Spells/technomancer.json b/data/mods/Magiclysm/Spells/technomancer.json index c19fa33fc41b1..2c9bc032c9960 100644 --- a/data/mods/Magiclysm/Spells/technomancer.json +++ b/data/mods/Magiclysm/Spells/technomancer.json @@ -480,5 +480,57 @@ "max_range": 6, "energy_source": "MANA", "spell_class": "TECHNOMANCER" + }, + { + "id": "technomancer_knifeshot", + "type": "SPELL", + "name": "Knifeshot", + "description": "This spell generates a magnetic field around a knife, before launching it at high speed.", + "valid_targets": [ "hostile", "ally" ], + "flags": [ "CONCENTRATE", "SILENT", "SOMATIC" ], + "components": "spell_components_knifeshot", + "effect": "projectile_attack", + "spell_class": "TECHNOMANCER", + "energy_source": "BIONIC", + "difficulty": 5, + "max_level": 20, + "base_casting_time": 600, + "casting_time_increment": -15, + "final_casting_time": 300, + "base_energy_cost": 50, + "min_damage": 30, + "max_damage": 70, + "damage_increment": 2.0, + "damage_type": "stab", + "min_range": 10, + "max_range": 20, + "range_increment": 0.5, + "min_pierce": 3, + "max_pierce": 10, + "pierce_increment": 0.35, + "learn_spells": { "technomancer_knifeshot_superior": 20 } + }, + { + "id": "technomancer_knifeshot_superior", + "type": "SPELL", + "name": "Hypervelocity Knifeshot", + "description": "This spell goes even further beyond, launching a knife so fast it can pierce through targets.", + "valid_targets": [ "hostile", "ally" ], + "flags": [ "CONCENTRATE", "LOUD", "SOMATIC" ], + "components": "spell_components_knifeshot", + "effect": "line_attack", + "spell_class": "TECHNOMANCER", + "energy_source": "BIONIC", + "difficulty": 7, + "max_level": 1, + "base_casting_time": 500, + "base_energy_cost": 125, + "min_damage": 125, + "max_damage": 125, + "damage_type": "bullet", + "min_range": 7, + "max_range": 7, + "min_pierce": 15, + "max_pierce": 15 } ] diff --git a/data/mods/Magiclysm/itemgroups/spellbooks.json b/data/mods/Magiclysm/itemgroups/spellbooks.json index 8a9b27f143ee8..87d26ef3d1ba1 100644 --- a/data/mods/Magiclysm/itemgroups/spellbooks.json +++ b/data/mods/Magiclysm/itemgroups/spellbooks.json @@ -71,7 +71,12 @@ [ "spell_scroll_earthshaper_pillar", 35 ], [ "spell_scroll_biomancer_coagulant_weave", 30 ], [ "spell_scroll_repelling_arc", 30 ], - [ "spell_scroll_knock", 35 ] + [ "spell_scroll_knock", 35 ], + [ "spell_scroll_caustic_aura", 30 ], + [ "spell_scroll_impactsling", 20 ], + [ "spell_scroll_boneclub", 20 ], + [ "spell_scroll_flamesword", 35 ], + [ "spell_scroll_flamebreath", 30 ] ] }, { @@ -109,7 +114,9 @@ [ "spell_scroll_dark_sight", 30 ], [ "spell_scroll_druidic_regrowth", 20 ], [ "spell_scroll_stormshaper_ionization", 40 ], - [ "spell_scroll_improved_knock", 35 ] + [ "spell_scroll_improved_knock", 35 ], + [ "spell_scroll_knifeshot", 35 ], + [ "spell_scroll_feralform", 30 ] ] }, { diff --git a/data/mods/Magiclysm/items/alchemy_items.json b/data/mods/Magiclysm/items/alchemy_items.json index c1f25ed62dd4b..928af78cbd6d1 100644 --- a/data/mods/Magiclysm/items/alchemy_items.json +++ b/data/mods/Magiclysm/items/alchemy_items.json @@ -61,7 +61,7 @@ "material": [ "copper", "wood" ], "symbol": "[", "color": "brown", - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 5, "encumbrance": 1, "warmth": 0, diff --git a/data/mods/Magiclysm/items/archery.json b/data/mods/Magiclysm/items/archery.json index e3d93c59717f7..366408933002e 100644 --- a/data/mods/Magiclysm/items/archery.json +++ b/data/mods/Magiclysm/items/archery.json @@ -16,7 +16,7 @@ "weight": "740 g", "volume": "5 L", "bashing": 14, - "armor_data": { "covers": [ "TORSO" ], "coverage": 5, "material_thickness": 1, "encumbrance": 14 }, + "armor_data": { "covers": [ "torso" ], "coverage": 5, "material_thickness": 1, "encumbrance": 14 }, "reload_noise_volume": 2, "loudness": 5, "ranged_damage": { "damage_type": "stab", "amount": 15 }, diff --git a/data/mods/Magiclysm/items/black_dragon_items.json b/data/mods/Magiclysm/items/black_dragon_items.json index d0a7b20559da8..b80da5799de16 100644 --- a/data/mods/Magiclysm/items/black_dragon_items.json +++ b/data/mods/Magiclysm/items/black_dragon_items.json @@ -84,7 +84,7 @@ "material": [ "black_dragon_hide" ], "symbol": "[", "color": "black_white", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 100, "encumbrance": 30, "warmth": 20, @@ -106,7 +106,7 @@ "material": [ "black_dragon_hide" ], "symbol": "[", "color": "black_white", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 100, "encumbrance": 18, "warmth": 20, @@ -128,7 +128,7 @@ "material": [ "black_dragon_hide" ], "symbol": "[", "color": "black_white", - "covers": [ "HEAD", "EYES", "MOUTH" ], + "covers": [ "head", "eyes", "mouth" ], "coverage": 100, "encumbrance": 32, "warmth": 15, @@ -151,7 +151,7 @@ "material": [ "black_dragon_hide" ], "symbol": "[", "color": "black_white", - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 100, "encumbrance": 32, "warmth": 15, @@ -174,7 +174,7 @@ "material": [ "black_dragon_hide" ], "symbol": "[", "color": "black_white", - "covers": [ "LEGS", "TORSO", "ARMS" ], + "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r" ], "coverage": 100, "encumbrance": 25, "warmth": 15, @@ -196,7 +196,7 @@ "material": [ "black_dragon_hide" ], "symbol": "[", "color": "black_white", - "covers": [ "LEGS", "TORSO", "ARMS" ], + "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r" ], "coverage": 100, "encumbrance": 18, "warmth": 15, @@ -217,7 +217,7 @@ "material": [ "black_dragon_hide" ], "symbol": "[", "color": "black_white", - "covers": [ "HANDS" ], + "covers": [ "hand_l", "hand_r" ], "coverage": 100, "encumbrance": 20, "warmth": 15, @@ -238,7 +238,7 @@ "material": [ "black_dragon_hide" ], "symbol": "[", "color": "black_white", - "covers": [ "HANDS" ], + "covers": [ "hand_l", "hand_r" ], "coverage": 100, "encumbrance": 8, "warmth": 15, diff --git a/data/mods/Magiclysm/items/enchanted.json b/data/mods/Magiclysm/items/enchanted.json index 664cd2886444e..67b479646bebc 100644 --- a/data/mods/Magiclysm/items/enchanted.json +++ b/data/mods/Magiclysm/items/enchanted.json @@ -45,7 +45,7 @@ "material": [ "cotton" ], "symbol": "^", "color": "light_blue", - "covers": [ "HEAD" ], + "covers": [ "head" ], "coverage": 50, "encumbrance": 12, "warmth": 7, @@ -84,7 +84,7 @@ "material": [ "black_dragon_hide" ], "symbol": "[", "color": "dark_gray", - "covers": [ "TORSO", "HEAD", "ARMS", "LEGS" ], + "covers": [ "torso", "head", "arm_l", "arm_r", "leg_l", "leg_r" ], "coverage": 85, "encumbrance": 4, "warmth": 30, diff --git a/data/mods/Magiclysm/items/enchanted_belts.json b/data/mods/Magiclysm/items/enchanted_belts.json index a44fbf944485a..8acf157f35633 100644 --- a/data/mods/Magiclysm/items/enchanted_belts.json +++ b/data/mods/Magiclysm/items/enchanted_belts.json @@ -11,7 +11,7 @@ "material": [ "leather" ], "symbol": "[", "color": "brown", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 5, "material_thickness": 2, "pocket_data": [ @@ -171,7 +171,7 @@ "name": { "str": "technomancer's toolbelt" }, "weight": "2000 g", "color": "brown", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "pocket_data": [ { "pocket_type": "CONTAINER", "max_contains_volume": "1 L", "max_contains_weight": "3 kg", "moves": 2, "holster": true } ], diff --git a/data/mods/Magiclysm/items/enchanted_bracers.json b/data/mods/Magiclysm/items/enchanted_bracers.json index db81b952fa06d..544b3559189b8 100644 --- a/data/mods/Magiclysm/items/enchanted_bracers.json +++ b/data/mods/Magiclysm/items/enchanted_bracers.json @@ -12,7 +12,7 @@ "material": [ "steel", "leather" ], "symbol": "[", "color": "light_gray", - "covers": [ "ARMS" ], + "covers": [ "arm_l", "arm_r" ], "coverage": 45, "encumbrance": 10, "warmth": 10, @@ -26,7 +26,8 @@ "name": { "str": "steel bracer" }, "weight": "770 g", "volume": "1250 ml", - "covers": [ "ARM_EITHER" ] + "covers": [ "arm_l", "arm_r" ], + "sided": true }, { "copy-from": "mbracer_steel_single", diff --git a/data/mods/Magiclysm/items/enchanted_masks.json b/data/mods/Magiclysm/items/enchanted_masks.json index cd767847d6422..39ad89f15aea0 100644 --- a/data/mods/Magiclysm/items/enchanted_masks.json +++ b/data/mods/Magiclysm/items/enchanted_masks.json @@ -12,7 +12,7 @@ "material": [ "steel", "leather" ], "symbol": "[", "color": "dark_gray", - "covers": [ "MOUTH", "EYES" ], + "covers": [ "eyes", "mouth" ], "coverage": 95, "encumbrance": 10, "warmth": 10, @@ -38,7 +38,7 @@ "name": { "str": "mask of perfect vision", "str_pl": "masks of perfect vision" }, "description": "A decidedly steampunk-looking half mask that covers the eye area of the face, it has large lenses that correct and greatly enhance the vision of the wearer.", "copy-from": "mmask", - "covers": [ "EYES" ], + "covers": [ "eyes" ], "coverage": 100, "encumbrance": 5, "environmental_protection": 6, diff --git a/data/mods/Magiclysm/items/enchanted_ranged.json b/data/mods/Magiclysm/items/enchanted_ranged.json index 31119a80b097f..c04afd1274895 100644 --- a/data/mods/Magiclysm/items/enchanted_ranged.json +++ b/data/mods/Magiclysm/items/enchanted_ranged.json @@ -21,7 +21,7 @@ "WATER_FRIENDLY" ], "min_strength": 10, - "armor_data": { "covers": [ "TORSO" ], "coverage": 5, "material_thickness": 1, "encumbrance": 13 }, + "armor_data": { "covers": [ "torso" ], "coverage": 5, "material_thickness": 1, "encumbrance": 13 }, "valid_mod_locations": [ [ "sights", 1 ], [ "accessories", 1 ], [ "dampening", 1 ] ] }, { diff --git a/data/mods/Magiclysm/items/enchanted_rings.json b/data/mods/Magiclysm/items/enchanted_rings.json index 66b40a4a84dcd..585286645a884 100644 --- a/data/mods/Magiclysm/items/enchanted_rings.json +++ b/data/mods/Magiclysm/items/enchanted_rings.json @@ -10,7 +10,8 @@ "material": [ "copper" ], "symbol": "[", "color": "light_red", - "covers": [ "HAND_EITHER" ], + "covers": [ "hand_l", "hand_r" ], + "sided": true, "coverage": 0, "warmth": 0, "flags": [ "WATER_FRIENDLY", "ALLOWS_NATURAL_ATTACKS", "FANCY", "ONLY_ONE", "SKINTIGHT" ] @@ -26,7 +27,8 @@ "material": [ "silver" ], "symbol": "[", "color": "light_gray", - "covers": [ "HAND_EITHER" ], + "covers": [ "hand_l", "hand_r" ], + "sided": true, "coverage": 0, "warmth": 0, "flags": [ "WATER_FRIENDLY", "ALLOWS_NATURAL_ATTACKS", "FANCY", "ONLY_ONE", "SKINTIGHT" ] @@ -42,7 +44,8 @@ "material": [ "gold" ], "symbol": "[", "color": "yellow", - "covers": [ "HAND_EITHER" ], + "covers": [ "hand_l", "hand_r" ], + "sided": true, "coverage": 0, "warmth": 0, "flags": [ "WATER_FRIENDLY", "ALLOWS_NATURAL_ATTACKS", "FANCY", "ONLY_ONE", "SKINTIGHT" ] @@ -58,7 +61,8 @@ "material": [ "platinum" ], "symbol": "[", "color": "light_gray", - "covers": [ "HAND_EITHER" ], + "covers": [ "hand_l", "hand_r" ], + "sided": true, "coverage": 0, "warmth": 0, "flags": [ "WATER_FRIENDLY", "ALLOWS_NATURAL_ATTACKS", "FANCY", "ONLY_ONE", "SKINTIGHT" ] diff --git a/data/mods/Magiclysm/items/ethereal_items.json b/data/mods/Magiclysm/items/ethereal_items.json index 2cc6e97e9f495..ba949fd97642b 100644 --- a/data/mods/Magiclysm/items/ethereal_items.json +++ b/data/mods/Magiclysm/items/ethereal_items.json @@ -13,7 +13,7 @@ "symbol": "[", "color": "light_gray", "armor_data": { - "covers": [ "HANDS", "ARMS" ], + "covers": [ "arm_l", "arm_r", "hand_l", "hand_r" ], "coverage": 100, "encumbrance": 0, "warmth": 20, @@ -51,7 +51,7 @@ "material": [ "superalloy" ], "symbol": "[", "color": "light_gray", - "covers": [ "HANDS", "ARMS" ], + "covers": [ "arm_l", "arm_r", "hand_l", "hand_r" ], "coverage": 100, "encumbrance": 0, "warmth": 20, @@ -74,7 +74,7 @@ "bashing": 8, "symbol": ",", "color": "light_green", - "covers": [ "HEAD" ], + "covers": [ "head" ], "flags": [ "LIGHT_15", "LEAK_DAM", "AURA", "SEMITANGIBLE" ] }, { @@ -88,7 +88,7 @@ "price": 0, "symbol": ",", "color": "light_green", - "covers": [ "HEAD" ], + "covers": [ "head" ], "flags": [ "LIGHT_5", "LEAK_DAM", "AURA", "SEMITANGIBLE" ] }, { @@ -105,7 +105,8 @@ "material": [ "steel" ], "symbol": "[", "color": "light_gray", - "covers": [ "ARM_EITHER", "HAND_EITHER" ], + "covers": [ "arm_l", "arm_r", "hand_l", "hand_r" ], + "sided": true, "coverage": 70, "encumbrance": 15, "material_thickness": 3, @@ -125,7 +126,7 @@ "material": [ "steel" ], "symbol": "[", "color": "brown", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 100, "encumbrance": 0, "warmth": 30, @@ -240,7 +241,7 @@ "material": [ "flesh" ], "symbol": "[", "color": "green", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 40, "encumbrance": 5, "max_encumbrance": 10, @@ -350,7 +351,7 @@ "price": 3646, "symbol": "o", "color": "white", - "covers": [ "LEGS", "TORSO", "ARMS", "HANDS", "HEAD", "FEET", "MOUTH", "EYES" ], + "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r", "hand_l", "hand_r", "head", "foot_l", "foot_r", "mouth", "eyes" ], "flags": [ "AURA", "SEMITANGIBLE", "OVERSIZE", "ONLY_ONE", "TRADER_AVOID", "NO_TAKEOFF", "NONCONDUCTIVE" ], "relic_data": { "passive_effects": [ { "has": "WORN", "condition": "ALWAYS", "values": [ { "value": "BONUS_DODGE", "add": 2 } ] } ] } }, @@ -364,7 +365,7 @@ "price": 3646, "symbol": "o", "color": "green", - "covers": [ "LEGS", "TORSO", "ARMS", "HANDS", "HEAD", "FEET", "MOUTH", "EYES" ], + "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r", "hand_l", "hand_r", "head", "foot_l", "foot_r", "mouth", "eyes" ], "flags": [ "AURA", "SEMITANGIBLE", "OVERSIZE", "ONLY_ONE", "TRADER_AVOID", "NO_TAKEOFF", "NONCONDUCTIVE" ], "relic_data": { "passive_effects": [ { "has": "WORN", "condition": "ALWAYS", "values": [ { "value": "ARMOR_ACID", "multiply": -0.25 } ] } ] @@ -380,7 +381,7 @@ "price": 3646, "symbol": "o", "color": "green", - "covers": [ "LEGS", "TORSO", "ARMS", "HANDS", "HEAD", "FEET", "MOUTH", "EYES" ], + "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r", "hand_l", "hand_r", "head", "foot_l", "foot_r", "mouth", "eyes" ], "flags": [ "AURA", "SEMITANGIBLE", "OVERSIZE", "ONLY_ONE", "TRADER_AVOID", "NO_TAKEOFF", "NONCONDUCTIVE" ], "relic_data": { "passive_effects": [ { "has": "WORN", "condition": "ALWAYS", "values": [ { "value": "ARMOR_ACID", "multiply": -0.6 } ] } ] @@ -397,7 +398,7 @@ "material": [ "steel" ], "symbol": "[", "color": "light_gray", - "covers": [ "HEAD", "MOUTH", "EYES", "TORSO", "ARMS", "HANDS", "LEGS", "FEET" ], + "covers": [ "head", "mouth", "eyes", "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ], "coverage": 100, "encumbrance": 10, "warmth": 0, @@ -416,7 +417,7 @@ "material": [ "stone" ], "symbol": "[", "color": "light_gray", - "covers": [ "HEAD", "MOUTH", "EYES", "TORSO", "ARMS", "HANDS", "LEGS", "FEET" ], + "covers": [ "head", "mouth", "eyes", "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ], "coverage": 100, "encumbrance": 20, "warmth": 5, @@ -446,7 +447,7 @@ "volume": "1 ml", "symbol": "~", "color": "light_red", - "covers": [ "EYES", "MOUTH" ], + "covers": [ "eyes", "mouth" ], "encumbrance": 18, "relic_data": { "passive_effects": [ { "id": "ench_overcharge_burn_scar" } ] }, "flags": [ "NO_TAKEOFF", "TRADER_AVOID", "BLIND" ] @@ -461,7 +462,7 @@ "symbol": "o", "color": "blue", "environmental_protection": 15, - "covers": [ "LEGS", "TORSO", "ARMS", "HANDS", "HEAD", "FEET", "MOUTH", "EYES" ], + "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r", "hand_l", "hand_r", "head", "foot_l", "foot_r", "mouth", "eyes" ], "flags": [ "AURA", "SEMITANGIBLE", "OVERSIZE", "ONLY_ONE", "TRADER_AVOID", "NO_TAKEOFF", "NONCONDUCTIVE" ] }, { @@ -475,5 +476,146 @@ "color": "blue", "flags": [ "AURA", "ONLY_ONE", "TRADER_AVOID", "NO_TAKEOFF", "NONCONDUCTIVE", "OVERSIZE" ], "relic_data": { "passive_effects": [ { "has": "WORN", "condition": "ALWAYS", "hit_me_effect": [ { "id": "thorns_zap" } ] } ] } + }, + { + "id": "aura_feral", + "type": "ARMOR", + "name": "feral aura", + "description": "The manifestion of your rage. It won't disappear until you calm down.", + "weight": "1 g", + "volume": "1 ml", + "price": 3646, + "symbol": "o", + "color": "white", + "flags": [ "PERSONAL", "SEMITANGIBLE", "OVERSIZE", "ONLY_ONE", "TRADER_AVOID", "NO_TAKEOFF", "NONCONDUCTIVE" ], + "relic_data": { + "passive_effects": [ + { + "has": "WORN", + "condition": "ALWAYS", + "values": [ + { "value": "STRENGTH", "add": 3 }, + { "value": "DEXTERITY", "add": 3 }, + { "value": "INTELLIGENCE", "add": -3 }, + { "value": "PERCEPTION", "add": -3 } + ], + "mutations": [ "LIGHTFUR", "CLAWS", "ADRENALINE" ] + } + ] + } + }, + { + "id": "flamesword", + "type": "GENERIC", + "symbol": "/", + "color": "light_gray", + "looks_like": "sword_wood", + "name": { "str": "flaming sword" }, + "description": "This wooden sword is ablaze! It seems to be safe-ish to hold, but will burn up soon.", + "material": [ "wood" ], + "flags": [ + "UNBREAKABLE_MELEE", + "NONCONDUCTIVE", + "NO_REPAIR", + "NO_SALVAGE", + "MAGIC_FOCUS", + "LIGHT_10", + "FIRESTARTER", + "FIRE", + "TRADER_AVOID" + ], + "techniques": [ "WBLOCK_1", "WIDE", "BRUTAL" ], + "weight": "900 g", + "volume": "1250 ml", + "longest_side": "100 cm", + "bashing": 12, + "cutting": 2, + "to_hit": 2, + "relic_data": { + "passive_effects": [ { "has": "WIELD", "condition": "ALWAYS", "values": [ { "value": "ITEM_DAMAGE_HEAT", "add": 8 } ] } ] + } + }, + { + "id": "decaying_boneclub", + "type": "GENERIC", + "symbol": "/", + "color": "light_gray", + "looks_like": "bone", + "name": { "str": "decaying boneclub" }, + "description": "A pulsating club made of bone, stained with an ever-moving blood coating eager to absorb the living.", + "material": [ "bone", "flesh" ], + "flags": [ + "UNBREAKABLE_MELEE", + "NONCONDUCTIVE", + "ONLY_ONE", + "NO_REPAIR", + "NO_SALVAGE", + "MAGIC_FOCUS", + "BELT_CLIP", + "TRADER_AVOID" + ], + "techniques": [ "WBLOCK_2", "RAPID", "PRECISE" ], + "weight": "700 g", + "volume": "800 ml", + "longest_side": "70 cm", + "bashing": 12, + "to_hit": 3, + "relic_data": { + "passive_effects": [ { "has": "WIELD", "condition": "ALWAYS", "values": [ { "value": "ITEM_DAMAGE_BIO", "add": 8 } ] } ] + } + }, + { + "id": "impactsling", + "looks_like": "sling", + "type": "GUN", + "symbol": "(", + "color": "brown", + "name": { "str": "impact sling" }, + "description": "A leather sling, quivering with energy when in your palm to the point of almost tearing. A pebble appears when you begin spinning it.", + "price": 150, + "material": [ "leather" ], + "flags": [ + "NEVER_JAMS", + "PRIMITIVE_RANGED_WEAPON", + "BELT_CLIP", + "FIRE_TWOHAND", + "TRADER_AVOID", + "NO_AMMO", + "NO_UNLOAD", + "NO_REPAIR" + ], + "weight": "86 g", + "volume": "250 ml", + "skill": "throw", + "price_postapoc": 250, + "to_hit": -1, + "ranged_damage": { "damage_type": "bash", "amount": 20 }, + "range": 20, + "dispersion": 135, + "durability": 7, + "bashing": 4, + "reload_noise_volume": 3, + "loudness": 6 + }, + { + "id": "aura_caustic", + "type": "ARMOR", + "name": "acid aura", + "description": "An aura of thin acid, swirling around your body ready to corrode when struck or while striking.", + "weight": "1 g", + "volume": "1 ml", + "symbol": "o", + "color": "blue", + "flags": [ "AURA", "ONLY_ONE", "TRADER_AVOID", "NO_TAKEOFF", "NONCONDUCTIVE", "OVERSIZE" ], + "relic_data": { + "passive_effects": [ + { + "has": "WORN", + "condition": "ALWAYS", + "hit_me_effect": [ { "id": "caustic_aura_spell" } ], + "values": [ { "value": "ARMOR_ACID", "add": -5 }, { "value": "ITEM_DAMAGE_ACID", "add": 3 } ] + } + ] + } } ] diff --git a/data/mods/Magiclysm/items/spell_scrolls.json b/data/mods/Magiclysm/items/spell_scrolls.json index 73e9a9e50783a..e1314d8b80fda 100644 --- a/data/mods/Magiclysm/items/spell_scrolls.json +++ b/data/mods/Magiclysm/items/spell_scrolls.json @@ -917,5 +917,61 @@ "name": { "str": "Sappy Scroll" }, "description": "This scroll is covered in sap and rose thorns. You can still make out some of the writings, but it probably won't work the same.", "use_action": { "type": "learn_spell", "spells": [ "druid_tornskin" ] } + }, + { + "type": "BOOK", + "copy-from": "spell_scroll", + "id": "spell_scroll_feralform", + "name": { "str": "Scroll of Feral Form", "str_pl": "Scrolls of Feral Form" }, + "description": "Unleash your inner beast by snapping a fur-covered bone, becoming beastly.", + "use_action": { "type": "learn_spell", "spells": [ "druid_feralform" ] } + }, + { + "type": "BOOK", + "copy-from": "spell_scroll", + "id": "spell_scroll_flamesword", + "name": { "str": "Scroll of Flamesword", "str_pl": "Scrolls of Flamesword" }, + "description": "Ignite a wooden sword to create a flaming saber.", + "use_action": { "type": "learn_spell", "spells": [ "kelvinist_summon_flamesword" ] } + }, + { + "type": "BOOK", + "copy-from": "spell_scroll", + "id": "spell_scroll_flamebreath", + "name": { "str": "Scroll of Flamebreath", "str_pl": "Scrolls of Flamebreath" }, + "description": "A pocketful of combustible powder is ignited, creating a cone of flame with ashes that stick to those in its path.", + "use_action": { "type": "learn_spell", "spells": [ "kelvinist_flamebreath" ] } + }, + { + "type": "BOOK", + "copy-from": "spell_scroll", + "id": "spell_scroll_caustic_aura", + "name": { "str": "Scroll of Caustic Aura", "str_pl": "Scrolls of Caustic Aura" }, + "description": "Animate a layer of acid around you, burning attackers and increasing your melee damage.", + "use_action": { "type": "learn_spell", "spells": [ "biomancer_caustic_aura" ] } + }, + { + "type": "BOOK", + "copy-from": "spell_scroll", + "id": "spell_scroll_boneclub", + "name": { "str": "Scroll of Decaying Boneclub", "str_pl": "Scrolls of Decaying Boneclub" }, + "description": "Link your live blood to dead blood and bones, creating a club eager to harvest the living.", + "use_action": { "type": "learn_spell", "spells": [ "animist_summon_decaying_boneclub" ] } + }, + { + "type": "BOOK", + "copy-from": "spell_scroll", + "id": "spell_scroll_impactsling", + "name": { "str": "Scroll of Impact Sling", "str_pl": "Scrolls of Impact Sling" }, + "description": "Infuse a sling with excess energy, delivering devasting throws before it tears itself apart.", + "use_action": { "type": "learn_spell", "spells": [ "magus_summon_impact_sling" ] } + }, + { + "type": "BOOK", + "copy-from": "spell_scroll", + "id": "spell_scroll_knifeshot", + "name": { "str": "Scroll of Knifeshot", "str_pl": "Scrolls of Knifeshot" }, + "description": "Emulate a railgun, launching a knife at high speed.", + "use_action": { "type": "learn_spell", "spells": [ "technomancer_knifeshot" ] } } ] diff --git a/data/mods/Magiclysm/items/spellbooks.json b/data/mods/Magiclysm/items/spellbooks.json index 121c4a3fa3cbd..00e03ae04a4a2 100644 --- a/data/mods/Magiclysm/items/spellbooks.json +++ b/data/mods/Magiclysm/items/spellbooks.json @@ -67,7 +67,10 @@ "material": [ "paper" ], "symbol": "?", "color": "light_red", - "use_action": { "type": "learn_spell", "spells": [ "point_flare", "fireball", "burning_hands", "create_lighter" ] } + "use_action": { + "type": "learn_spell", + "spells": [ "point_flare", "fireball", "burning_hands", "create_lighter", "kelvinist_summon_flamesword" ] + } }, { "id": "wizard_advanced", @@ -232,14 +235,17 @@ "id": "magus_spellbook", "type": "BOOK", "name": { "str": "The Tome of The Battle Mage", "str_pl": "copies of The Tome of The Battle Mage" }, - "//": "3 Magus spells", + "//": "4 Magus spells", "description": "Your standard wizardy looking spellbook, filled with Magus combat spells. You sure lucked out!", "weight": "434 g", "volume": "750 ml", "material": [ "paper" ], "symbol": "?", "color": "light_gray", - "use_action": { "type": "learn_spell", "spells": [ "magus_mana_beam", "magus_mana_bolt", "magus_mana_blast" ] } + "use_action": { + "type": "learn_spell", + "spells": [ "magus_mana_beam", "magus_mana_bolt", "magus_mana_blast", "magus_summon_impact_sling" ] + } }, { "id": "eshaper_spellbook", @@ -300,14 +306,17 @@ "id": "techno_fundamentals", "type": "BOOK", "name": { "str": "Fundamentals of Technomancy", "str_pl": "copies of Fundamentals of Technomancy" }, - "//": "3 Technomancer spells", + "//": "4 Technomancer spells", "description": "This thick manual instructs the spellcaster on manipulating and empowering various forms of matter and energy.", "weight": "258 g", "volume": "750 ml", "material": [ "paper" ], "symbol": "?", "color": "light_gray", - "use_action": { "type": "learn_spell", "spells": [ "synaptic_stimulation", "animated_blade", "mirror_image" ] } + "use_action": { + "type": "learn_spell", + "spells": [ "synaptic_stimulation", "animated_blade", "mirror_image", "technomancer_knifeshot" ] + } }, { "id": "techno_idiots", @@ -329,14 +338,14 @@ "str": "Technomancy and the Electromagnetic Spectrum", "str_pl": "copies of Technomancy and the Electromagnetic Spectrum" }, - "//": "2 Technomancer spells", + "//": "3 Technomancer spells", "description": "This lab reference material book is thick and overflowing with information on combining magic with EM radiation.", "weight": "284 g", "volume": "1 L", "material": [ "paper" ], "symbol": "?", "color": "light_gray", - "use_action": { "type": "learn_spell", "spells": [ "taze", "laze" ] } + "use_action": { "type": "learn_spell", "spells": [ "taze", "laze", "technomancer_knifeshot" ] } }, { "id": "animist_shadows", diff --git a/data/mods/Magiclysm/martialarts.json b/data/mods/Magiclysm/martialarts.json index d404b96f8de55..fb58932f95470 100644 --- a/data/mods/Magiclysm/martialarts.json +++ b/data/mods/Magiclysm/martialarts.json @@ -43,7 +43,8 @@ "rune_animist_weapon", "springstaff-retracted", "mjolnir", - "gram" + "gram", + "decaying_boneclub" ] } }, @@ -64,7 +65,8 @@ "cavalry_sabre_plus_two", "broadsword_plus_one", "broadsword_plus_two", - "springstaff-retracted" + "springstaff-retracted", + "decaying_boneclub" ] } }, @@ -137,7 +139,8 @@ "rune_animist_weapon", "m47a1", "springstaff-retracted", - "gram" + "gram", + "decaying_boneclub" ] } }, @@ -160,7 +163,8 @@ "zweihander_plus_two", "rune_kelvinist_weapon", "gunblade", - "gram" + "gram", + "flamesword" ] } }, @@ -219,7 +223,8 @@ "rune_kelvinist_weapon", "rune_magus_weapon", "springstaff-extended", - "gunblade" + "gunblade", + "flamesword" ] } }, @@ -235,7 +240,8 @@ "nodachi_plus_one", "nodachi_plus_two", "wakizashi_plus_one", - "wakizashi_plus_two" + "wakizashi_plus_two", + "flamesword" ] } }, @@ -277,7 +283,8 @@ "springstaff-retracted", "springstaff-extended", "gungnir", - "laevateinn" + "laevateinn", + "decaying_boneclub" ] } }, diff --git a/data/mods/Magiclysm/professions.json b/data/mods/Magiclysm/professions.json index 31f541fb6dc4d..f8f26c5d533cd 100644 --- a/data/mods/Magiclysm/professions.json +++ b/data/mods/Magiclysm/professions.json @@ -188,7 +188,10 @@ "points": 2, "skills": [ { "level": 1, "name": "spellcraft" } ], "items": { - "both": [ "jeans", "tshirt", "gloves_light", "hat_ball", "boots", "socks", "hoodie", "knit_scarf", "primitive_knife" ], + "both": { + "items": [ "jeans", "tshirt", "gloves_light", "hat_ball", "boots", "socks", "hoodie", "knit_scarf", "leather_belt" ], + "entries": [ { "item": "primitive_knife", "container-item": "sheath" } ] + }, "male": [ "boxer_briefs" ], "female": [ "bra", "panties" ] }, diff --git a/data/mods/Magiclysm/recipes/alchemy.json b/data/mods/Magiclysm/recipes/alchemy.json index 445f5c37c736a..7f8e89c7cac53 100644 --- a/data/mods/Magiclysm/recipes/alchemy.json +++ b/data/mods/Magiclysm/recipes/alchemy.json @@ -26,7 +26,7 @@ "tools": [ [ [ "paint_brush", -1 ] ] ], "components": [ [ [ "tainted_blood", 2000 ], [ "blood", 8 ], [ "dragon_blood", 2000 ] ], - [ [ "acid", 4 ] ], + [ [ "any_strong_acid", 4, "LIST" ] ], [ [ "water", 2 ], [ "water_clean", 2 ] ] ], "time": "2 h", diff --git a/data/mods/Magiclysm/requirements/spell_components.json b/data/mods/Magiclysm/requirements/spell_components.json new file mode 100644 index 0000000000000..f10edfa178a6f --- /dev/null +++ b/data/mods/Magiclysm/requirements/spell_components.json @@ -0,0 +1,70 @@ +[ + { + "id": "spell_components_flamesword", + "type": "requirement", + "//": "Wooden swords usable for the Flamesword spell", + "components": [ [ [ "sword_wood", 1 ], [ "sword_nail", 1 ], [ "sword_crude", 1 ] ] ] + }, + { + "id": "spell_components_flamebreath", + "type": "requirement", + "//": "100ml portions of combustible dusts usable for the Flamebreath spell", + "components": [ [ [ "sugar", 28 ], [ "flour", 4 ], [ "tinder", 100 ], [ "cinnamon", 40 ], [ "chilly-p", 40 ] ] ] + }, + { + "id": "spell_components_knifeshot", + "type": "requirement", + "//": "Iron or steel pointed knives suitable for the Knifeshot spell", + "components": [ + [ + [ "xacto", 1 ], + [ "diveknife", 1 ], + [ "knife_butcher", 1 ], + [ "knife_combat", 1 ], + [ "knife_chef", 1 ], + [ "knife_hunting", 1 ], + [ "knife_rambo", 1 ], + [ "knife_paring", 1 ], + [ "knife_steak", 1 ], + [ "throwing_knife", 1 ], + [ "knife_baselard", 1 ] + ] + ] + }, + { + "id": "spell_components_decayingboneclub", + "type": "requirement", + "//": "Weapon materials and 1000 energy from blood suitable for the Decaying Boneclub spell", + "components": [ + [ [ "bone", 3 ], [ "bone_demihuman", 3 ], [ "bone_human", 3 ], [ "bone_tainted", 6 ] ], + [ [ "blood", 4 ], [ "tainted_blood", 200 ], [ "dragon_blood", 20 ] ] + ] + }, + { + "id": "spell_components_feralform", + "type": "requirement", + "//": "Fur and bones suitable for the Feral Form spell", + "components": [ + [ [ "fur", 3 ], [ "hairball", 2 ] ], + [ [ "bone", 1 ], [ "bone_demihuman", 1 ], [ "bone_human", 1 ], [ "bone_tainted", 2 ] ] + ] + }, + { + "id": "spell_components_impactsling", + "type": "requirement", + "//": "Sling for the Impact Sling spell", + "components": [ [ [ "sling", 1 ] ] ] + }, + { + "id": "spell_components_causticaura", + "type": "requirement", + "//": "Strong acids suitable for the Caustic Aura spell", + "components": [ [ [ "acid", 2 ], [ "chem_sulphuric_acid", 2 ], [ "chem_muriatic_acid", 2 ], [ "chem_nitric_acid", 2 ] ] ] + }, + { + "id": "spell_components_shardspray", + "type": "requirement", + "//": "A kilo of metal fragments suitable for the Shardspray spell", + "components": [ [ [ "scrap", 40 ], [ "copper", 500 ], [ "gold", 200 ], [ "silver", 333 ], [ "lead", 333 ] ] ] + } +] diff --git a/data/mods/No_Fungi/comestibles.json b/data/mods/No_Fungi/comestibles.json index 598f756d0fd95..b5dc8e6631379 100644 --- a/data/mods/No_Fungi/comestibles.json +++ b/data/mods/No_Fungi/comestibles.json @@ -25,6 +25,7 @@ "symbol": ".", "description": "If we left this as it should be, one could just walk into the Garden uncontested and partake of the Seed. We can't have that, can we?", "material": [ "fruit" ], + "volume": "250 ml", "charges": 1, "stack_size": 10 }, @@ -39,6 +40,7 @@ "symbol": "~", "description": "If we left this as it should be, one could just walk into the Spire uncontested and partake of the Sap. Wait, how did you even GET this anyway?", "material": [ "fruit" ], + "volume": "250 ml", "charges": 1, "stack_size": 10, "fun": 30 diff --git a/data/mods/TEST_DATA/items.json b/data/mods/TEST_DATA/items.json index 92acba019d21f..85fb1df9127c2 100644 --- a/data/mods/TEST_DATA/items.json +++ b/data/mods/TEST_DATA/items.json @@ -88,7 +88,7 @@ "symbol": "[", "looks_like": "holster", "color": "brown", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 20, "encumbrance": 2, "material_thickness": 2, @@ -382,7 +382,7 @@ "symbol": "[", "looks_like": "socks_wool", "color": "white", - "covers": [ "FEET" ], + "covers": [ "foot_l", "foot_r" ], "coverage": 100, "warmth": 5, "material_thickness": 1, @@ -400,7 +400,7 @@ "symbol": "[", "looks_like": "dress_shirt", "color": "blue", - "covers": [ "TORSO", "ARMS" ], + "covers": [ "torso", "arm_l", "arm_r" ], "coverage": 90, "encumbrance": 3, "warmth": 5, @@ -435,7 +435,7 @@ "symbol": "[", "looks_like": "beekeeping_suit", "color": "yellow", - "covers": [ "HEAD", "TORSO", "ARMS", "HANDS", "LEGS", "FEET" ], + "covers": [ "head", "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ], "coverage": 100, "encumbrance": 37, "warmth": 40, @@ -595,7 +595,7 @@ "material": [ "leather" ], "symbol": ")", "color": "brown", - "armor_data": { "covers": [ "LEG_EITHER" ], "coverage": 5, "material_thickness": 2 }, + "armor_data": { "covers": [ "leg_l", "leg_r" ], "sided": true, "coverage": 5, "material_thickness": 2 }, "pocket_data": [ { "max_item_volume": "15 ml", @@ -650,7 +650,7 @@ "symbol": "[", "looks_like": "ragpouch", "color": "green", - "covers": [ "TORSO" ], + "covers": [ "torso" ], "coverage": 30, "encumbrance": 2, "max_encumbrance": 15, @@ -674,7 +674,8 @@ "symbol": "[", "looks_like": "plastic_shopping_bag", "color": "light_gray", - "covers": [ "ARM_EITHER", "HAND_EITHER" ], + "covers": [ "arm_l", "arm_r", "hand_l", "hand_r" ], + "sided": true, "coverage": 10, "encumbrance": 30, "pocket_data": [ @@ -703,7 +704,8 @@ "symbol": "[", "looks_like": "bscabbard", "color": "brown", - "covers": [ "LEG_EITHER" ], + "covers": [ "leg_l", "leg_r" ], + "sided": true, "coverage": 10, "encumbrance": 3, "material_thickness": 1, @@ -1132,7 +1134,7 @@ "symbol": "[", "looks_like": "depowered_armor", "color": "light_gray", - "covers": [ "TORSO", "ARMS", "HANDS", "LEGS", "FEET" ], + "covers": [ "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ], "coverage": 100, "encumbrance": 50, "pocket_data": [ @@ -1237,7 +1239,7 @@ "symbol": "[", "looks_like": "touring_suit", "color": "dark_gray", - "armor_portion_data": [ { "covers": [ "torso", "LEGS", "ARMS" ], "coverage": 95, "encumbrance": [ 12, 25 ] } ], + "armor_portion_data": [ { "covers": [ "torso", "leg_l", "leg_r", "arm_l", "arm_r" ], "coverage": 95, "encumbrance": [ 12, 25 ] } ], "pocket_data": [ { "pocket_type": "CONTAINER", "max_contains_volume": "1 L", "max_contains_weight": "3 kg", "moves": 80 }, { "pocket_type": "CONTAINER", "max_contains_volume": "1 L", "max_contains_weight": "3 kg", "moves": 80 }, @@ -1264,7 +1266,7 @@ "symbol": "[", "looks_like": "pants", "color": "brown", - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "coverage": 95, "encumbrance": 16, "max_encumbrance": 20, @@ -1287,7 +1289,7 @@ "name": { "str_sp": "faux fur pants" }, "description": "A pair of long cotton pants lined with warm imitation fur.", "material": [ "faux_fur", "cotton" ], - "covers": [ "LEGS" ], + "covers": [ "leg_l", "leg_r" ], "warmth": 70 }, { diff --git a/data/mods/Urban_Development/building_jsons/urban_10_house_brick_pool.json b/data/mods/Urban_Development/building_jsons/urban_10_house_brick_pool.json deleted file mode 100644 index 1d47729d53545..0000000000000 --- a/data/mods/Urban_Development/building_jsons/urban_10_house_brick_pool.json +++ /dev/null @@ -1,274 +0,0 @@ -[ - { - "type": "mapgen", - "method": "json", - "om_terrain": [ "urban_10_1" ], - "weight": 250, - "object": { - "fill_ter": "t_floor", - "rows": [ - ",,,,,,,,,,,,,,,,,,,,,,,,", - ",,,,,,,,,,,,,,##########", - ",,,,,,,,,,,,,,#;;;;;;;;;", - ",,,,^,,,,,,,,,,;;;PPPPPP", - ",,,,,,,,,,,,,,,;;;PPPPPP", - ",,,,,,,,,^,,,,#;;;PPPPPP", - ",,,,,,,,,,,,,,#;;;;;;PPP", - ",,,,,,,,,,,,,,#;;;;;;;PP", - ",,,,,,,Iiiiiiwii!iI;;;;;", - ",,,,,,,Iu |CoSC222I;;G;;", - ",,,,,,,Iu +2222222Iiiiii", - ",,,,,,,Iu |f2CC222|r r|>", - ",,,,,,,I--|C2CC222|-+-| ", - ",,,,,,,IO ", - ",,^,,,wIO ", - ",,,,,,ww httth cIiiwi!", - ",,,,,,wI httth cI;;;;;", - ",,,,,,,I httth cI;;;;;", - ",,,,,,,I cI,,,,;", - ",,,,,,,IiiwiiiiwiiI,,,,;", - ",,,,,,,,,###,,###,,,,,,;", - ",,,,,,,,,,,,,,,,,,,,,^,;", - ",,,,,,,,,,,,,,,,,,,,,,,;", - ",,,,,,,,,,,,,,,,,,,,,,,;" - ], - "palettes": [ "acidia_residential_commercial_palette" ], - "items": { - " ": { "item": "livingroom", "chance": 2 }, - "C": { "item": "kitchen", "chance": 25 }, - "O": { "item": "homebooks", "chance": 60 }, - "b": { "item": "bed", "chance": 60 }, - "c": { "item": "livingroom", "chance": 25 }, - "f": { "item": "fridge", "chance": 70 }, - "o": { "item": "oven", "chance": 30 }, - "r": { "item": "cleaning", "chance": 60 }, - "t": { "item": "dining", "chance": 25 }, - "u": { "item": "cannedfood", "chance": 50 } - }, - "place_monsters": [ { "monster": "GROUP_ZOMBIE", "x": [ 1, 22 ], "y": [ 1, 22 ], "density": 0.09 } ] - } - }, - { - "type": "mapgen", - "method": "json", - "om_terrain": [ "urban_10_2" ], - "weight": 250, - "object": { - "fill_ter": "t_floor", - "rows": [ - ",,,,,,,,,,,,,,,,,,,,,,,,", - "##########,,,,,,,,,,,,,,", - ";;;;;;;;;#,,,,,,^,,,,,,,", - "PPPPPP;;;,,,,,,,,,,,,,,,", - "PPPPPP;;;,,,,,,,,,,,,,,,", - "PPPPPP;;;#,,^,,,,,,,,^,,", - "PPP;;;;;;#,,,,,,,,,,,,,,", - "PP;;;;;;;#,,,###,,,,,,,,", - ";;;;;IiwiiiiiiwiI,,,,,,,", - ";;;;;I dd6 OI#,,,,,,", - "iiiiiI hd w#,,,,,,", - ">|T2S|h I#,,,^,,", - " |-+-|--+-------I,,,,,,,", - " A I,,,,,,,", - " @ cI#,,,,,,", - "!iwiiIc @ t cw#,,,,,,", - ";;;;;Ic @ t cI#,,,,,,", - ";;;;;Ic @@ cI,,,,,,,", - ";,,,,Ic I,,,,,,,", - ";,,,,IiiwiiiiwiiI,,,,,,,", - ";,,,,,,###,,###,,,,,,,,,", - ";,^,,,,,,,,,,,,,,,,,,,,,", - ";,,,,,,,,,,,,,,,,,,,,,,,", - ";,,,,,,,,,,,,,,,,,,,,,,," - ], - "palettes": [ "acidia_residential_commercial_palette" ], - "toilets": { "T": { } }, - "items": { - " ": { "item": "livingroom", "chance": 2 }, - "2": { "item": "softdrugs", "chance": 10 }, - "4": { "item": "dining", "chance": 25 }, - "@": { "item": "magazines", "chance": 10 }, - "A": { "item": "livingroom", "chance": 15 }, - "O": { "item": "homebooks", "chance": 60 }, - "c": { "item": "livingroom", "chance": 25 }, - "d": { "item": "office", "chance": 40 }, - "t": { "item": "coffee_table", "chance": 25 } - }, - "place_monsters": [ { "monster": "GROUP_ZOMBIE", "x": [ 1, 22 ], "y": [ 1, 22 ], "density": 0.09 } ] - } - }, - { - "type": "mapgen", - "method": "json", - "om_terrain": [ "urban_10_3" ], - "weight": 250, - "object": { - "fill_ter": "t_floor", - "rows": [ - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - ".......IiiwiiiiwiiI.....", - ".......ICBB|r +22BI.....", - ".......wT22|--|T2BIiiiii", - ".......IC22+ r|C22+u|u|<", - ".......IS22|--|S22|-|+| ", - ".......I-+-|ee|-|+| ", - ".......Ie + c", - ".......Ie |-Iiiwii", - ".......I bbb |rI.....", - ".......w bbb + I.....", - ".......I ebbbe |rI.....", - ".......IiiiwiiwiiiI.....", - "........................", - "........................", - "........................", - "........................" - ], - "palettes": [ "acidia_residential_commercial_palette" ], - "toilets": { "T": { } }, - "items": { - " ": { "item": "livingroom", "chance": 2 }, - "2": { "item": "softdrugs", "chance": 10 }, - "b": { "item": "bed", "chance": 60 }, - "c": { "item": "livingroom", "chance": 25 }, - "d": { "item": "office", "chance": 40 }, - "r": { "item": "bedroom", "chance": 60 }, - "u": { "item": "cleaning", "chance": 60 } - }, - "place_monsters": [ - { "monster": "GROUP_ZOMBIE", "x": [ 8, 17 ], "y": [ 9, 18 ], "density": 0.09 }, - { "monster": "GROUP_ZOMBIE", "x": [ 18, 22 ], "y": [ 11, 14 ], "density": 0.09 } - ] - } - }, - { - "type": "mapgen", - "method": "json", - "om_terrain": [ "urban_10_4" ], - "weight": 250, - "object": { - "fill_ter": "t_floor", - "rows": [ - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - ".....IiiwiiiiwiiI.......", - ".....Ib ebb I.......", - "iiiiiIb dw.......", - "<|r|u+ hdI.......", - " |+|-| ee d6I.......", - " |+---------I.......", - "c OI.......", - "iiwiiI AtA OI.......", - ".....IO OI.......", - ".....w w.......", - ".....IO tt OOOI.......", - ".....IiiiwiiwiiiI.......", - "........................", - "........................", - "........................", - "........................" - ], - "palettes": [ "acidia_residential_commercial_palette" ], - "items": { - " ": { "item": "livingroom", "chance": 2 }, - "A": { "item": "livingroom", "chance": 15 }, - "O": { "item": "homebooks", "chance": 60 }, - "b": { "item": "bed", "chance": 60 }, - "c": { "item": "livingroom", "chance": 25 }, - "d": { "item": "office", "chance": 40 }, - "e": { "item": "dresser", "chance": 60 }, - "r": { "item": "cleaning", "chance": 60 }, - "t": { "item": "coffee_table", "chance": 25 }, - "u": { "item": "bedroom", "chance": 60 } - }, - "place_monsters": [ - { "monster": "GROUP_ZOMBIE", "x": [ 8, 17 ], "y": [ 9, 18 ], "density": 0.09 }, - { "monster": "GROUP_ZOMBIE", "x": [ 6, 15 ], "y": [ 11, 14 ], "density": 0.09 } - ] - } - }, - { - "type": "mapgen", - "method": "json", - "om_terrain": [ "urban_10_5" ], - "weight": 250, - "object": { - "fill_ter": "t_floor", - "rows": [ - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - ".......RRRRRRRRRRRR.....", - ".......RRRRRRRRRRRR.....", - ".......RRRRRRRRRRRRRRRRR", - ".......RRRRRRRRRRRRRRRRR", - ".......RRRRRRRRRRRRRRRRR", - ".......RRRRRRRRRRRRRRRRR", - ".......RRRRRRRRRRRRRRRRR", - ".......RRRRRRRRRRRRRRRRR", - ".......RRRRRRRRRRRR.....", - ".......RRRRRRRRRRRR.....", - ".......RRRRRRRRRRRR.....", - ".......RRRRRRRRRRRR.....", - "........................", - "........................", - "........................", - "........................" - ], - "palettes": [ "acidia_residential_commercial_palette" ] - } - }, - { - "type": "mapgen", - "method": "json", - "om_terrain": [ "urban_10_6" ], - "weight": 250, - "object": { - "fill_ter": "t_floor", - "rows": [ - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - ".....RRRRRRRRRRRR.......", - ".....RRRRRRRRRRRR.......", - "RRRRRRRRRRRRRRRRR.......", - "RRRRRRRRRRRRRRRRR.......", - "RRRRRRRRRRRRRRRRR.......", - "RRRRRRRRRRRRRRRRR.......", - "RRRRRRRRRRRRRRRRR.......", - "RRRRRRRRRRRRRRRRR.......", - ".....RRRRRRRRRRRR.......", - ".....RRRRRRRRRRRR.......", - ".....RRRRRRRRRRRR.......", - ".....RRRRRRRRRRRR.......", - "........................", - "........................", - "........................", - "........................" - ], - "palettes": [ "acidia_residential_commercial_palette" ] - } - } -] diff --git a/data/mods/Urban_Development/building_jsons/urban_11_house_brick.json b/data/mods/Urban_Development/building_jsons/urban_11_house_brick.json deleted file mode 100644 index 0f3d3db8731b3..0000000000000 --- a/data/mods/Urban_Development/building_jsons/urban_11_house_brick.json +++ /dev/null @@ -1,266 +0,0 @@ -[ - { - "type": "mapgen", - "method": "json", - "om_terrain": [ "urban_11_1" ], - "weight": 250, - "object": { - "fill_ter": "t_floor", - "rows": [ - ",,,,,,,,,,,,,,,,,,,,,,,,", - ",,,,,,,,,,,,,,,,,,,,,,,,", - ",,,,,^,,,,,,,,,,,,,,,,,,", - ",,,,,,,,,,###,,,,,####qq", - ",,,,,,,,,,#Iiiiiiiiwwiii", - ",,,,,,,,,,#ICCoC22H44H22", - ",,,,,,,,,,,wS22222H44H22", - ",,,,,,,,,,,IC22222222222", - ",,,,,,,,,,,If222222222j|", - ",,,,,,,,,,,I---ccc- --|", - ",,,,,,,,,,,w >|", - ",,,,,,,,,,,Ic t @ ", - ",,,^,,,,,,,Ic t @ ", - ",,,,,,,,,,,I @@ ", - ",,,,,,,,,,#Iiiiiwiiiiiii", - ",,,,,,,,,,##,,#,,#,,#,,#", - ",,,,,,,,,,,,,,,,,,,,,,,,", - ",,,,,,,,,,,,,,,,,,,,,,,,", - ",,,,,,,,,,,,,,,,,,,,^,,,", - ",,,,,,,^,,,,,,,,,,,,,,,,", - ",,,,,,,,,,,,,,,,,,,,,,,,", - ",,,,,,,,,,,,,,,,,,,,,,,,", - ",,,,,,,,,,,,,,^,,,,,,,,,", - ",,,,,,,,,,,,,,,,,,,,,,,," - ], - "palettes": [ "acidia_residential_commercial_palette" ], - "items": { - " ": { "item": "livingroom", "chance": 2 }, - "4": { "item": "dining", "chance": 25 }, - "@": { "item": "magazines", "chance": 10 }, - "C": { "item": "kitchen", "chance": 25 }, - "c": { "item": "livingroom", "chance": 25 }, - "f": { "item": "fridge", "chance": 70 }, - "j": { "item": "cannedfood", "chance": 50 }, - "o": { "item": "oven", "chance": 30 }, - "q": { "item": "trash", "chance": 50 }, - "t": { "item": "coffee_table", "chance": 25 } - }, - "place_monsters": [ { "monster": "GROUP_ZOMBIE", "x": [ 1, 22 ], "y": [ 1, 22 ], "density": 0.09 } ] - } - }, - { - "type": "mapgen", - "method": "json", - "om_terrain": [ "urban_11_2" ], - "weight": 250, - "object": { - "fill_ter": "t_floor", - "rows": [ - ",,,,,,,,,,,,,,,,,,,,,,,,", - ",,,,,,,,,,,,,,,,,,,,,^,,", - ";;;;;,,,,,,,,,,,,,,,,,,,", - ";;;;;,,,,,,,,,,,###,,,,,", - "ii!iwiiiiiiwiiiiiI#,,,,,", - "j| WD|'rr'''''''I#,,,,,", - "2+ +''''''''''w,,,,,,", - "2|----|''''''''''I,,,,,,", - " |SCTB|'''''''''rI,,,,,,", - " |222B|'''''''''cI,,,,,,", - " |+|--|'''''''''cI,,,,,,", - " |r +''''''''''I#,,,,,", - " |--|''''''''''w#,,,,,", - " + O|/'''''''''I#,,,,,", - "wi!iiiii========iI,,,,,,", - ",;;;,,,,________,,,,,,,,", - ",;;;;;;;________,#,,,,,,", - ",;;;;;;;________,,,,,,,,", - ",,,,,,,,________,#,,,^,,", - ",,,,,,,,________,,,,,,,,", - ",,,,,,#,________,#,,,,,,", - ",,,,,,,,________,,,,,,,,", - ",,,,,,#,________,#,,,,,,", - ",,,,,,,,________,,,,,,,," - ], - "palettes": [ "acidia_residential_commercial_palette" ], - "toilets": { "T": { } }, - "items": { - " ": { "item": "livingroom", "chance": 2 }, - "'": { "item": "mechanics", "chance": 2 }, - "2": { "item": "softdrugs", "chance": 10 }, - "O": { "item": "jackets", "chance": 60 }, - "c": { "item": "home_hw", "chance": 25 }, - "j": { "item": "cannedfood", "chance": 50 }, - "q": { "item": "trash", "chance": 50 }, - "r": { "item": "mechanics", "chance": 60 } - }, - "place_monsters": [ { "monster": "GROUP_ZOMBIE", "x": [ 1, 22 ], "y": [ 1, 22 ], "density": 0.09 } ], - "place_vehicles": [ { "vehicle": "suburban_home", "x": 11, "y": 8, "chance": 100, "rotation": 270 } ] - } - }, - { - "type": "mapgen", - "method": "json", - "om_terrain": [ "urban_11_3" ], - "weight": 250, - "object": { - "fill_ter": "t_floor", - "rows": [ - "........................", - "........................", - "........................", - "........................", - "...........RRRRRRRRRRRRR", - "...........RRRRIwwIRRRRR", - "...........IiiiIccIiiiii", - "...........Iebbe O|r|", - "...........I bb + |", - "...........w |-|", - "...........I |<|", - "...........I eee + ", - "...........IiiiIccIiiiii", - "...........RRRRIwwIRRRRR", - "...........RRRRRRRRRRRRR", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................" - ], - "palettes": [ "acidia_residential_commercial_palette" ], - "items": { - " ": { "item": "livingroom", "chance": 2 }, - "O": { "item": "homebooks", "chance": 60 }, - "b": { "item": "bed", "chance": 60 }, - "c": { "item": "livingroom", "chance": 25 }, - "e": { "item": "dresser", "chance": 60 }, - "r": { "item": "bedroom", "chance": 60 } - }, - "place_monsters": [ { "monster": "GROUP_ZOMBIE", "x": [ 12, 22 ], "y": [ 7, 11 ], "density": 0.09 } ] - } - }, - { - "type": "mapgen", - "method": "json", - "om_terrain": [ "urban_11_4" ], - "weight": 250, - "object": { - "fill_ter": "t_floor", - "rows": [ - "........................", - "........................", - "........................", - "........................", - "RRRRRRRRRRRRRRRRRR......", - "IwwwIRRRRRIwwIRRRR......", - "IBBBIiiiiiIeeIiiiI......", - "T222222+ eI......", - "22222|-| bbbI......", - "CSCSC| + bbbw......", - "-----| |dh bbbI......", - " |6dd eI......", - "IcccIiiiiiIccIiiiI......", - "IwwwIRRRRRIwwIRRRR......", - "RRRRRRRRRRRRRRRRRR......", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................" - ], - "palettes": [ "acidia_residential_commercial_palette" ], - "toilets": { "T": { } }, - "items": { - " ": { "item": "livingroom", "chance": 2 }, - "2": { "item": "softdrugs", "chance": 10 }, - "C": { "item": "cleaning", "chance": 10 }, - "O": { "item": "homebooks", "chance": 60 }, - "b": { "item": "bed", "chance": 60 }, - "c": { "item": "livingroom", "chance": 25 }, - "d": { "item": "office", "chance": 40 }, - "e": { "item": "dresser", "chance": 60 }, - "r": { "item": "bedroom", "chance": 60 } - }, - "place_monsters": [ { "monster": "GROUP_ZOMBIE", "x": [ 1, 15 ], "y": [ 7, 11 ], "density": 0.09 } ] - } - }, - { - "type": "mapgen", - "method": "json", - "om_terrain": [ "urban_11_5" ], - "weight": 250, - "object": { - "fill_ter": "t_floor", - "rows": [ - "........................", - "........................", - "........................", - "........................", - "........................", - "...............RRRR.....", - "...........RRRRRRRRRRRRR", - "...........RRRRRRRRRRRRR", - "...........RRRRRRRRRRRRR", - "...........RRRRRRRRRRRRR", - "...........RRRRRRRRRRRRR", - "...........RRRRRRRRRRRRR", - "...........RRRRRRRRRRRRR", - "...............RRRR.....", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................" - ], - "palettes": [ "acidia_residential_commercial_palette" ] - } - }, - { - "type": "mapgen", - "method": "json", - "om_terrain": [ "urban_11_6" ], - "weight": 250, - "object": { - "fill_ter": "t_floor", - "rows": [ - "........................", - "........................", - "........................", - "........................", - "........................", - "RRRRR.....RRRR..........", - "RRRRRRRRRRRRRRRRRR......", - "RRRRRRRRRRRRRRRRRR......", - "RRRRRRRRRRRRRRRRRR......", - "RRRRRRRRRRRRRRRRRR......", - "RRRRRRRRRRRRRRRRRR......", - "RRRRRRRRRRRRRRRRRR......", - "RRRRRRRRRRRRRRRRRR......", - "RRRRR.....RRRR..........", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................" - ], - "palettes": [ "acidia_residential_commercial_palette" ] - } - } -] diff --git a/data/mods/Urban_Development/building_jsons/urban_12_house.json b/data/mods/Urban_Development/building_jsons/urban_12_house.json deleted file mode 100644 index 06a027bec6a34..0000000000000 --- a/data/mods/Urban_Development/building_jsons/urban_12_house.json +++ /dev/null @@ -1,274 +0,0 @@ -[ - { - "type": "mapgen", - "method": "json", - "om_terrain": [ "urban_12_1" ], - "weight": 250, - "object": { - "fill_ter": "t_floor", - "rows": [ - ",,,,,,,,,,,,,,,,,,,,,,,,", - ",,,,,^,,,,,,,,,,,,,,,,,,", - ",,,,,,,,,,,,,,,,,,,,,,,,", - ",,,,,,,,,,,,,,,,,,,,qIii", - ",,,,,,,,,,,,^,,,,,,,qIrr", - ",,,,,,,,,,,,,,,,##;;;I ", - ",,,,,,,,,,,,,,,,##;;;I--", - ",,,^,,,,,,,,,,,,,,;;;IT2", - ",,,,,,IiiiwiiwiiiI;;;I22", - ",,,,,,I'''''''rcrIi!iI-+", - ",,,,,,I''''''''''|W D| ", - ",,,,,,w''''''''''+ + ", - ",,,,,,Ic'''''''''|u u| ", - ",,,,,,Ic'''''''''IiwiI ", - ",,,,,,Ic'''''''''I###I ", - ",,,,,,w''''''''''I#,#I h", - ",,,,,,I''''''''''w,,,I h", - ",,,,,,I'''''''''/I,,,I h", - ",,,,,,Ii========iI,,,I ", - ",,,,,,,,________,,,,,Iii", - ",,,,,,,,________,,,,,,,#", - ",,,,,^,,________,,,,,,,,", - ",,,,,,,,________,,,,,,,,", - ",,,,,,,,________,,,,,,,," - ], - "palettes": [ "acidia_residential_commercial_palette" ], - "toilets": { "T": { } }, - "items": { - " ": { "item": "livingroom", "chance": 2 }, - "'": { "item": "mechanics", "chance": 1 }, - "2": { "item": "softdrugs", "chance": 10 }, - "q": { "item": "trash", "chance": 50 }, - "r": { "item": "cannedfood", "chance": 60 }, - "u": { "item": "cleaning", "chance": 50 } - }, - "place_monsters": [ { "monster": "GROUP_ZOMBIE", "x": [ 1, 22 ], "y": [ 1, 22 ], "density": 0.09 } ], - "place_vehicles": [ { "vehicle": "suburban_home", "x": 11, "y": 12, "chance": 100, "rotation": 270 } ] - } - }, - { - "type": "mapgen", - "method": "json", - "om_terrain": [ "urban_12_2" ], - "weight": 250, - "object": { - "fill_ter": "t_floor", - "rows": [ - ",,,,,,,,,,,,,,,,,,,,,,,,", - ",,,,,,,,,,,,,,,,,,^,,,,,", - ",,,,,,,,,,,,,,,,,,,,,,,,", - "iiwiiwiiiiI,,,,,,,,,,,,,", - "r|2ffCCoCCI''''''''I,,,,", - " +2222222CI''''''''',,,,", - "-|2222CC2Sw''''''''',,,,", - "S|r 22CC2Sw'''''''G',,,,", - "2|r 22222CI''''''''',,,,", - "-| 2222221''''''''',,,,", - " I''''''''',,,,", - " cu IiiwwiiiiiI,,,", - "|----|-| | OO I,,,", - " cuc|L+ w,,,", - " |-| @@@@@@I,,,", - "tth |>| | @ @I,,,", - "tth | |-| I,,,", - "tth |A w,,,", - " | | cccc I,,,", - "wwiiiIIw11wIIiiiwwiiI,,,", - ",,#,,II''''II,,#,,#,,,,,", - ",,,,,,,;;;;,,,,,,,,,,,,,", - ",,,,,,,#;;#,,,,,,,,,^,,,", - ",,,,,,,,;;,,,,,,,,,,,,,," - ], - "palettes": [ "acidia_residential_commercial_palette" ], - "items": { - " ": { "item": "livingroom", "chance": 2 }, - "@": { "item": "magazines", "chance": 10 }, - "A": { "item": "livingroom", "chance": 15 }, - "C": { "item": "kitchen", "chance": 25 }, - "O": { "item": "homebooks", "chance": 60 }, - "c": { "item": "livingroom", "chance": 25 }, - "o": { "item": "oven", "chance": 30 }, - "r": { "item": "cannedfood", "chance": 60 }, - "t": { "item": "dining", "chance": 25 }, - "u": { "item": "dining", "chance": 50 } - }, - "place_monsters": [ { "monster": "GROUP_ZOMBIE", "x": [ 1, 22 ], "y": [ 1, 22 ], "density": 0.09 } ] - } - }, - { - "type": "mapgen", - "method": "json", - "om_terrain": [ "urban_12_3" ], - "weight": 250, - "object": { - "fill_ter": "t_floor", - "rows": [ - "........................", - "........................", - "........................", - ".....................Iii", - ".....................I ", - ".....................w ", - ".....................Ie ", - ".....................wu ", - "......IiiiwiiwiiiI...Ie ", - "......I6d OO | IiwiI-+", - "......wdh + ", - "......Id | ", - "......I-------| ", - "......Ibb + IiwiI ", - "......Ibb t |--I...IA ", - "......Ie t |STI...It ", - "......w +22I...I ", - "......I eee |BBI...I ", - "......IiiiwiiwiiiI...I ", - ".....................Iiw", - "........................", - "........................", - "........................", - "........................" - ], - "palettes": [ "acidia_residential_commercial_palette" ], - "toilets": { "T": { } }, - "items": { - " ": { "item": "livingroom", "chance": 2 }, - "2": { "item": "softdrugs", "chance": 10 }, - "A": { "item": "livingroom", "chance": 15 }, - "O": { "item": "homebooks", "chance": 60 }, - "b": { "item": "bed", "chance": 60 }, - "d": { "item": "office", "chance": 40 }, - "e": { "item": "dresser", "chance": 60 }, - "t": { "item": "coffee_table", "chance": 25 }, - "u": { "item": "bedroom", "chance": 60 } - }, - "place_monsters": [ - { "monster": "GROUP_ZOMBIE", "x": [ 7, 16 ], "y": [ 9, 17 ], "density": 0.09 }, - { "monster": "GROUP_ZOMBIE", "x": [ 22, 23 ], "y": [ 4, 18 ], "density": 0.09 } - ] - } - }, - { - "type": "mapgen", - "method": "json", - "om_terrain": [ "urban_12_4" ], - "weight": 250, - "object": { - "fill_ter": "t_floor", - "rows": [ - "........................", - "........................", - "........................", - "wiiiiiiwiiI.............", - " ebbe d6dIRRRRRRRRR....", - " bb hdIRRRRRRRRR....", - " wRRRRRRRRR....", - " cIRRRRRRRRR....", - " cIRRRRRRRRR....", - "-|--+--|+-IRRRRRRRRR....", - " |B222T| rIRRRRRRRRR....", - " |BCSCC|--IiiwiiiwiiI...", - " |-----|eue d6dI...", - " + hdI...", - " |e w...", - " |-+-|<|e I...", - " |S22|-|e bbb w...", - "O|C2B| + bbb I...", - "O|T2B|r| ebbbe I...", - "iiiiiiiiiiwiiiwiiiwiI...", - ".....RRRRRRRR...........", - "........................", - "........................", - "........................" - ], - "palettes": [ "acidia_residential_commercial_palette" ], - "toilets": { "T": { } }, - "items": { - " ": { "item": "livingroom", "chance": 2 }, - "2": { "item": "softdrugs", "chance": 10 }, - "O": { "item": "homebooks", "chance": 60 }, - "b": { "item": "bed", "chance": 60 }, - "c": { "item": "livingroom", "chance": 25 }, - "d": { "item": "office", "chance": 40 }, - "e": { "item": "dresser", "chance": 60 }, - "r": { "item": "dresser", "chance": 60 }, - "u": { "item": "bedroom", "chance": 25 } - }, - "place_monsters": [ - { "monster": "GROUP_ZOMBIE", "x": [ 1, 9 ], "y": [ 4, 18 ], "density": 0.09 }, - { "monster": "GROUP_ZOMBIE", "x": [ 10, 19 ], "y": [ 12, 18 ], "density": 0.09 } - ] - } - }, - { - "type": "mapgen", - "method": "json", - "om_terrain": [ "urban_12_5" ], - "weight": 250, - "object": { - "fill_ter": "t_floor", - "rows": [ - "........................", - "........................", - "........................", - ".....................RRR", - ".....................RRR", - ".....................RRR", - ".....................RRR", - ".....................RRR", - "......RRRRRRRRRRRR...RRR", - "......RRRRRRRRRRRRRRRRRR", - "......RRRRRRRRRRRRRRRRRR", - "......RRRRRRRRRRRRRRRRRR", - "......RRRRRRRRRRRRRRRRRR", - "......RRRRRRRRRRRRRRRRRR", - "......RRRRRRRRRRRR...RRR", - "......RRRRRRRRRRRR...RRR", - "......RRRRRRRRRRRR...RRR", - "......RRRRRRRRRRRR...RRR", - "......RRRRRRRRRRRR...RRR", - ".....................RRR", - "........................", - "........................", - "........................", - "........................" - ], - "palettes": [ "acidia_residential_commercial_palette" ] - } - }, - { - "type": "mapgen", - "method": "json", - "om_terrain": [ "urban_12_6" ], - "weight": 250, - "object": { - "fill_ter": "t_floor", - "rows": [ - "........................", - "........................", - "........................", - "RRRRRRRRRRR.............", - "RRRRRRRRRRR.............", - "RRRRRRRRRRR.............", - "RRRRRRRRRRR.............", - "RRRRRRRRRRR.............", - "RRRRRRRRRRR.............", - "RRRRRRRRRRR.............", - "RRRRRRRRRRR.............", - "RRRRRRRRRRRRRRRRRRRRR...", - "RRRRRRRRRRRRRRRRRRRRR...", - "RRRRRRRRRRRRRRRRRRRRR...", - "RRRRRRRRRRRRRRRRRRRRR...", - "RRRRRRRRRRRRRRRRRRRRR...", - "RRRRRRRRRRRRRRRRRRRRR...", - "RRRRRRRRRRRRRRRRRRRRR...", - "RRRRRRRRRRRRRRRRRRRRR...", - "RRRRRRRRRRRRRRRRRRRRR...", - "........................", - "........................", - "........................", - "........................" - ], - "palettes": [ "acidia_residential_commercial_palette" ] - } - } -] diff --git a/data/mods/Urban_Development/building_jsons/urban_15_house.json b/data/mods/Urban_Development/building_jsons/urban_15_house.json deleted file mode 100644 index e1ecf84d5dbce..0000000000000 --- a/data/mods/Urban_Development/building_jsons/urban_15_house.json +++ /dev/null @@ -1,266 +0,0 @@ -[ - { - "type": "mapgen", - "method": "json", - "om_terrain": [ "urban_15_1" ], - "weight": 250, - "object": { - "fill_ter": "t_floor", - "rows": [ - ",,,,,,,,,,,,,,,,,,,,,,,,", - ",,,,,,,,,,,,,,,,,,,^,,,,", - ",,,,,,,,,,,,,,,,,,,,,,,,", - ",,,,,,,,,,,,,,,,,,,,,,,,", - ",,,,,^,,,,,,,,,,,,,,,,,,", - ",,,,,,,,,,,,,,,,,,,,,,,,", - ",,,,,,,|-w---w-|--www---", - ",,,,,,,| bbbe | @@@@ ", - ",,,,,,,|e bbb |c @ ", - ",,,,,,,|e bbb |c t @ ", - ",,,,,,,| |c t @ ", - ",,,,,,,|+|---+-| ", - ",,,,,,,| | ", - ",,,,,,,|r| > ", - ",,,,,,,|-|+-|-+-----|-|O", - ",,,,,,,|222C| ee |u+ ", - ",,,,,,,|T22S| |-| ", - ",,,,,,,w222S| bb h + | ", - ",,,,,,,|BB2C| ebbd6d|r|-", - ",,,,,,,|----|-w--w--|-|'", - ",,,,^,,,,,,,,,,,,,,,,,,'", - ",,,,,,,,,,,,,,,,,,,,,,,,", - ",,,,,,,,,,,,,^,,,,,,,,,,", - ",,,,,,,,,,,,,,,,,,,,,,,," - ], - "palettes": [ "acidia_residential_commercial_palette" ], - "toilets": { "T": { } }, - "items": { - " ": { "item": "livingroom", "chance": 2 }, - "2": { "item": "softdrugs", "chance": 10 }, - "@": { "item": "magazines", "chance": 10 }, - "C": { "item": "cleaning", "chance": 10 }, - "O": { "item": "homebooks", "chance": 60 }, - "b": { "item": "bed", "chance": 60 }, - "c": { "item": "livingroom", "chance": 25 }, - "d": { "item": "office", "chance": 40 }, - "e": { "item": "dresser", "chance": 60 }, - "r": { "item": "bedroom", "chance": 60 }, - "t": { "item": "coffee_table", "chance": 25 }, - "u": { "item": "jackets", "chance": 50 } - }, - "place_monsters": [ { "monster": "GROUP_ZOMBIE", "x": [ 1, 22 ], "y": [ 1, 22 ], "density": 0.09 } ] - } - }, - { - "type": "mapgen", - "method": "json", - "om_terrain": [ "urban_15_2" ], - "weight": 250, - "object": { - "fill_ter": "t_floor", - "rows": [ - ",,,,,,,,,,,,,,,,,,,,,,,,", - ",,,,,,,,,,,,,,,,,,,,,,,,", - ",,,,,,,,,,,,,,,,,,,,,,,,", - ",,,,,,,,,,,,,,^,,,,,,,,,", - ",'''''',,,,,,,,,,,,,,,,,", - ",'''''',,,,,,,,,,,,,,,,,", - "-w-11-w-|-|---|-ww-|,,,,", - " A|u|T2S|WDcc|,,,,", - " htth |+|-+-| c|,,,,", - " htth c|,,,,", - " htth |-+--------|,,,,", - " |'''''''''r|,,,,", - " 22222f|'''''''''r|,,,,", - " 22CC2C|'''''''''c|,,,,", - " 22CC2C|''''''''''|,,,,", - " 22CC2o|''''''''''|,,,,", - " 22222C|''''''''''|,,,,", - " CCCSSC|'''''''''/|,,,,", - "1---www-|!-=======-|,,,,", - "'',#####;;;_______,,,,,,", - "'',,,,,,;;;_______,,,,,,", - ";;;;;;;;;;;_______,,,,,,", - ",,,,,,,,,,,_______,,,,,,", - ",,,,,,,,,,,_______,qq,,," - ], - "palettes": [ "acidia_residential_commercial_palette" ], - "toilets": { "T": { } }, - "items": { - " ": { "item": "livingroom", "chance": 2 }, - "'": { "item": "mechanics", "chance": 1 }, - "A": { "item": "livingroom", "chance": 15 }, - "C": { "item": "kitchen", "chance": 25 }, - "c": { "item": "cleaning", "chance": 25 }, - "f": { "item": "fridge", "chance": 70 }, - "o": { "item": "oven", "chance": 30 }, - "q": { "item": "trash", "chance": 50 }, - "r": { "item": "home_hw", "chance": 60 }, - "t": { "item": "dining", "chance": 25 }, - "u": { "item": "cannedfood", "chance": 50 } - }, - "place_monsters": [ { "monster": "GROUP_ZOMBIE", "x": [ 1, 22 ], "y": [ 1, 22 ], "density": 0.09 } ], - "place_vehicles": [ { "vehicle": "suburban_home", "x": 13, "y": 13, "chance": 100, "rotation": 270 } ] - } - }, - { - "type": "mapgen", - "method": "json", - "om_terrain": [ "urban_15_3" ], - "weight": 250, - "object": { - "fill_ter": "t_floor", - "rows": [ - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - ".......RRRRRRRRRRRRRRRRR", - ".......RRRRRRRRRRRRRRRRR", - ".......RRRRRRRRRRRRRRRRR", - ".......RRRRRRRR|---|-|-w", - ".......RRRRRRRR|T2B|r+ e", - ".......RRRRRRRRw22B|-| ", - ".......RRRRRRRRw222+ + ", - ".......RRRRRRRR|CSC|<| ", - ".......RRRRRRRR|---|-|--", - ".......RRRRRRRRRRRRRRRRR", - ".......RRRRRRRRRRRRRRRRR", - ".......RRRRRRRRRRRRRRRRR", - ".......RRRRRRRRRRRRRRRRR", - ".......RRRRRRRRRRRRRRRRR", - ".......................R", - "........................", - "........................", - "........................" - ], - "palettes": [ "acidia_residential_commercial_palette" ], - "toilets": { "T": { } }, - "items": { - " ": { "item": "livingroom", "chance": 2 }, - "2": { "item": "softdrugs", "chance": 10 }, - "C": { "item": "cleaning", "chance": 25 }, - "e": { "item": "dresser", "chance": 60 }, - "r": { "item": "bedroom", "chance": 60 } - }, - "place_monsters": [ { "monster": "GROUP_ZOMBIE", "x": [ 16, 22 ], "y": [ 10, 13 ], "density": 0.09 } ] - } - }, - { - "type": "mapgen", - "method": "json", - "om_terrain": [ "urban_15_4" ], - "weight": 250, - "object": { - "fill_ter": "t_floor", - "rows": [ - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "RRRRRRRRRRRRRRRRRRRR....", - "RRRRRRRRRRRRRRRRRRRR....", - "RRRRRRRRRRRRRRRRRRRR....", - "--w-|RRRRRRRRRRRRRRR....", - "bbe |RRRRRRRRRRRRRRR....", - "bb |RRRRRRRRRRRRRRR....", - " |RRRRRRRRRRRRRRR....", - " OO|RRRRRRRRRRRRRRR....", - "ww--|RRRRRRRRRRRRRRR....", - "RRRRRRRRRRRRRRRRRRRR....", - "RRRRRRRRRRRRRRRRRRRR....", - "RRRRRRRRRRRRRRRRRRRR....", - "RRRRRRRRRRRRRRRRRRRR....", - "RR......................", - "RR......................", - "........................", - "........................", - "........................" - ], - "palettes": [ "acidia_residential_commercial_palette" ], - "items": { - " ": { "item": "livingroom", "chance": 2 }, - "O": { "item": "homebooks", "chance": 60 }, - "b": { "item": "bed", "chance": 60 }, - "e": { "item": "dresser", "chance": 60 } - }, - "place_monsters": [ { "monster": "GROUP_ZOMBIE", "x": [ 1, 3 ], "y": [ 10, 13 ], "density": 0.09 } ] - } - }, - { - "type": "mapgen", - "method": "json", - "om_terrain": [ "urban_15_5" ], - "weight": 250, - "object": { - "fill_ter": "t_floor", - "rows": [ - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "...............RRRRRRRRR", - "...............RRRRRRRRR", - "...............RRRRRRRRR", - "...............RRRRRRRRR", - "...............RRRRRRRRR", - "...............RRRRRRRRR", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................" - ], - "palettes": [ "acidia_residential_commercial_palette" ] - } - }, - { - "type": "mapgen", - "method": "json", - "om_terrain": [ "urban_15_6" ], - "weight": 250, - "object": { - "fill_ter": "t_floor", - "rows": [ - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "RRRRR...................", - "RRRRR...................", - "RRRRR...................", - "RRRRR...................", - "RRRRR...................", - "RRRRR...................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................" - ], - "palettes": [ "acidia_residential_commercial_palette" ] - } - } -] diff --git a/data/mods/Urban_Development/building_jsons/urban_16_house_ranch.json b/data/mods/Urban_Development/building_jsons/urban_16_house_ranch.json deleted file mode 100644 index 58226177953fe..0000000000000 --- a/data/mods/Urban_Development/building_jsons/urban_16_house_ranch.json +++ /dev/null @@ -1,174 +0,0 @@ -[ - { - "type": "mapgen", - "method": "json", - "om_terrain": [ "urban_16_1" ], - "weight": 250, - "object": { - "fill_ter": "t_floor", - "rows": [ - ",,,,,,,,,,,,,,,,,,,,,,,,", - ",,,,,|-----------|,,,,,,", - ",^,,,|''''''''''r|,,,,,,", - ",,,,,|''''''''''r|---w-|", - ",,,,,w'''''''''''|u+ cc|", - ",,,,,|'''''''''''|-| 1", - ",,,,,|'''''''''''+ |-+-|", - ",,,,,w'''''''''''| |", - ",,,,,|'''''''''''|--|- |", - ",,,,,|'''''''''/'|22+ ", - ",,,,,|-========--|WD| ", - ",,,,#,,________qq|--| ", - ",,,###,________,,|CCf ", - ",,,,#,,________,,|o22 ", - ",,,,,,,________,,wS2Htth", - ",,,,,,,________,,|C2Htth", - ",,^,,,,________,,| ", - ",,,,,,,________,,|c @ ", - ",,,,,,,________,II @ ", - ",,,,#,,________,IF @@ ", - ",,,###,________,II ", - ",,,,#,,________,,|---ww-", - ",,,,,,,________,,,,,,,,,", - ",,,,,,,________,,,,,,,,," - ], - "palettes": [ "acidia_residential_commercial_palette" ], - "items": { - " ": { "item": "livingroom", "chance": 2 }, - "'": { "item": "mechanics", "chance": 1 }, - "@": { "item": "magazines", "chance": 10 }, - "C": { "item": "kitchen", "chance": 25 }, - "c": { "item": "livingroom", "chance": 25 }, - "f": { "item": "fridge", "chance": 70 }, - "o": { "item": "oven", "chance": 30 }, - "q": { "item": "trash", "chance": 50 }, - "r": { "item": "home_hw", "chance": 60 }, - "t": { "item": "dining", "chance": 25 }, - "u": { "item": "cleaning", "chance": 50 } - }, - "place_monsters": [ { "monster": "GROUP_ZOMBIE", "x": [ 1, 22 ], "y": [ 1, 22 ], "density": 0.09 } ], - "place_vehicles": [ { "vehicle": "suburban_home", "x": 10, "y": 5, "chance": 100, "rotation": 270 } ] - } - }, - { - "type": "mapgen", - "method": "json", - "om_terrain": [ "urban_16_2" ], - "weight": 250, - "object": { - "fill_ter": "t_floor", - "rows": [ - ",,,,,,,,,,,,,,,,,,,,,,,,", - ",,,,,,,,^,,,,,,,,,,,,,,,", - ",,,,,,,,,,,,,,,,,,,,,,,,", - "'''',,,,,,,,,,,,,,#,,,,,", - "'''',,,,,,,,,,,,,###,,,,", - "'''',,,,,,,,,,,,,,#,,,,,", - "''''''''G''''',,,,,,,,,,", - "'''''''''''''',,,,,,,,,,", - "-|'''''''''''',,,,,,,,,,", - " 1'''''''''''',,,,,,,,,,", - " |-|----|----ww--|,,,,,,", - " |T|BBCS| d6d e|,,,,,,", - " |222222+ h bb|,,,^,,", - " |---|--| bb|,,,,,,", - " |T2S|r + e|,,,,,,", - " |-+-|--|--+-|---|,,,,,,", - " |r r|,,,,,,", - " |-|---+|--|+|-+-|,,,,,,", - " |r+ |ST| |,,,,,,", - " |-| +22+ b|,,,,,,", - " |bbe |BB|e b|,,,,,,", - "-1-|--w-|--|--w--|,,,^,,", - "''',,,,,,,,,,,,,,,,,,,,,", - ";;;,,,,,,,,,,,,,,,,,,,,," - ], - "palettes": [ "acidia_residential_commercial_palette" ], - "toilets": { "T": { } }, - "items": { - " ": { "item": "livingroom", "chance": 2 }, - "'": { "item": "mechanics", "chance": 2 }, - "2": { "item": "softdrugs", "chance": 10 }, - "C": { "item": "cleaning", "chance": 10 }, - "b": { "item": "bed", "chance": 60 }, - "c": { "item": "livingroom", "chance": 25 }, - "d": { "item": "office", "chance": 40 }, - "e": { "item": "dresser", "chance": 60 }, - "r": { "item": "bedroom", "chance": 60 } - }, - "place_monsters": [ { "monster": "GROUP_ZOMBIE", "x": [ 1, 22 ], "y": [ 1, 22 ], "density": 0.09 } ] - } - }, - { - "type": "mapgen", - "method": "json", - "om_terrain": [ "urban_16_3" ], - "weight": 250, - "object": { - "fill_ter": "t_floor", - "rows": [ - "........................", - ".....RRRRRRRRRRRRR......", - ".....RRRRRRRRRRRRR......", - ".....RRRRRRRRRRRRRRRRRRR", - ".....RRRRRRRRRRRRRRRRRRR", - ".....RRRRRRRRRRRRRRRRRRR", - ".....RRRRRRRRRRRRRRRRRRR", - ".....RRRRRRRRRRRRRRRRRRR", - ".....RRRRRRRRRRRRRRRRRRR", - ".................RRRRRRR", - ".................RRRRRRR", - ".................RRRRRRR", - ".................RRRRRRR", - ".................RRRRRRR", - ".................RRRRRRR", - ".................RRRRRRR", - ".................RRRRRRR", - ".................RRRRRRR", - "................RRRRRRRR", - "................RRRRRRRR", - "................RRRRRRRR", - ".................RRRRRRR", - "........................", - "........................" - ], - "palettes": [ "acidia_residential_commercial_palette" ] - } - }, - { - "type": "mapgen", - "method": "json", - "om_terrain": [ "urban_16_4" ], - "weight": 250, - "object": { - "fill_ter": "t_floor", - "rows": [ - "........................", - "........................", - "........................", - "RRRR....................", - "RRRR....................", - "RRRR....................", - "RRRRRRRRRRRRRR..........", - "RRRRRRRRRRRRRR..........", - "RRRRRRRRRRRRRR..........", - "RRRRRRRRRRRRRR..........", - "RRRRRRRRRRRRRRRRRR......", - "RRRRRRRRRRRRRRRRRR......", - "RRRRRRRRRRRRRRRRRR......", - "RRRRRRRRRRRRRRRRRR......", - "RRRRRRRRRRRRRRRRRR......", - "RRRRRRRRRRRRRRRRRR......", - "RRRRRRRRRRRRRRRRRR......", - "RRRRRRRRRRRRRRRRRR......", - "RRRRRRRRRRRRRRRRRR......", - "RRRRRRRRRRRRRRRRRR......", - "RRRRRRRRRRRRRRRRRR......", - "RRRRRRRRRRRRRRRRRR......", - "........................", - "........................" - ], - "palettes": [ "acidia_residential_commercial_palette" ] - } - } -] diff --git a/data/mods/Urban_Development/building_jsons/urban_17_house_ranch.json b/data/mods/Urban_Development/building_jsons/urban_17_house_ranch.json deleted file mode 100644 index 665e5ff5d7b17..0000000000000 --- a/data/mods/Urban_Development/building_jsons/urban_17_house_ranch.json +++ /dev/null @@ -1,174 +0,0 @@ -[ - { - "type": "mapgen", - "method": "json", - "om_terrain": [ "urban_17_1" ], - "weight": 250, - "object": { - "fill_ter": "t_floor", - "rows": [ - ",,,,,,,,,,,,,,,,,,,,,,,,", - ",,,,,,,,,,,,,,----w----|", - ",^,,__________=''''''''|", - ",,,___________=''''''''w", - ",,____________='''''''r|", - ",,____________='''''''r|", - ",,____________=''''''''|", - ",,____________=/'''''''|", - ",,___________,|-+|-----|", - ",,__________,,|C2|CCSSCf", - ",,_________,,,wW2|o22222", - ",,_________,,,wD2|C22CCC", - ",,_________,,,|j22222222", - ",,_________,,,|------| ", - ",,_________,,,| + ", - ",,_________,,,w dh | ", - ",,_________,,,w d6d |c ", - ",,_________,,,| |c ", - ",,_________,,,|-|-|--| ", - ",,_________,,,,,|L+ + ", - ",,_________,,,,,|-|1-|--", - ",,_________,,,,,''''''''", - ",,_________,,,,,''''''''", - ",,_________qq,,,,,,,,,,;" - ], - "palettes": [ "acidia_residential_commercial_palette" ], - "items": { - " ": { "item": "livingroom", "chance": 2 }, - "'": { "item": "mechanics", "chance": 1 }, - "C": { "item": "kitchen", "chance": 25 }, - "L": { "item": "jackets", "chance": 70 }, - "c": { "item": "livingroom", "chance": 25 }, - "d": { "item": "office", "chance": 40 }, - "f": { "item": "fridge", "chance": 70 }, - "j": { "item": "cannedfood", "chance": 50 }, - "o": { "item": "oven", "chance": 30 }, - "q": { "item": "trash", "chance": 50 }, - "r": { "item": "home_hw", "chance": 60 } - }, - "place_monsters": [ { "monster": "GROUP_ZOMBIE", "x": [ 1, 22 ], "y": [ 1, 22 ], "density": 0.09 } ], - "place_vehicles": [ { "vehicle": "suburban_home", "x": 19, "y": 4, "chance": 100, "rotation": 0 } ] - } - }, - { - "type": "mapgen", - "method": "json", - "om_terrain": [ "urban_17_2" ], - "weight": 250, - "object": { - "fill_ter": "t_floor", - "rows": [ - ",,,,,,,,,,,,,,,,,,,,,,,,", - ",,,,,,,,,,,,,,,,,,,,,,,,", - ",,,,,,,,,,,,,,,,,,,,^,,,", - ";;;;;;;|-w--w-|,,,,,,,,,", - ";;;G;;;|e bb |,,,,,,,,,", - ";;;;;;;|e bb w,,,,,,,,,", - ";;;;;;;|e w,,,,,,,,,", - ";;;;;;;| O|,,,,,,,,,", - "-vv!vv-| |,,,,,,,,,", - "2 | |--|+|,,,^,,,,,", - "2 htth | +2S|r|,,,,,,,,,", - "2 htth |+|2C|-|,,,,,,,,,", - "2 | |22+2|,,,,,,,,,", - " |BB|T|,,,,,,,,,", - " | |--|-|,,,,,,,,,", - " @@ | |SCTB|,,,,,,,,,", - " t @ | +222B|,,,,,,,,,", - " t @ |+|----|,,,,,,,,,", - " @@ | bbe |,,,,,,,,,", - " | bb w,,,,,,^,,", - "vv-vv--|e |,,,,,,,,,", - "'''''''|e O|,,,,,,,,,", - "'''''''|--ww--|,,,,,,,,,", - ";,,,,,,,,,,,,,,,,,,,,,,," - ], - "palettes": [ "acidia_residential_commercial_palette" ], - "toilets": { "T": { } }, - "items": { - " ": { "item": "livingroom", "chance": 2 }, - "2": { "item": "softdrugs", "chance": 10 }, - "@": { "item": "magazines", "chance": 10 }, - "C": { "item": "cleaning", "chance": 10 }, - "O": { "item": "homebooks", "chance": 60 }, - "b": { "item": "bed", "chance": 60 }, - "e": { "item": "dresser", "chance": 60 }, - "r": { "item": "bedroom", "chance": 60 }, - "t": { "item": "coffee_table", "chance": 25 } - }, - "place_monsters": [ { "monster": "GROUP_ZOMBIE", "x": [ 1, 22 ], "y": [ 1, 22 ], "density": 0.09 } ] - } - }, - { - "type": "mapgen", - "method": "json", - "om_terrain": [ "urban_17_3" ], - "weight": 250, - "object": { - "fill_ter": "t_floor", - "rows": [ - "........................", - "..............RRRRRRRRRR", - "..............RRRRRRRRRR", - "..............RRRRRRRRRR", - "..............RRRRRRRRRR", - "..............RRRRRRRRRR", - "..............RRRRRRRRRR", - "..............RRRRRRRRRR", - "..............RRRRRRRRRR", - "..............RRRRRRRRRR", - "..............RRRRRRRRRR", - "..............RRRRRRRRRR", - "..............RRRRRRRRRR", - "..............RRRRRRRRRR", - "..............RRRRRRRRRR", - "..............RRRRRRRRRR", - "..............RRRRRRRRRR", - "..............RRRRRRRRRR", - "..............RRRRRRRRRR", - "................RRRRRRRR", - "................RRRRRRRR", - "................RRRRRRRR", - "................RRRRRRRR", - "........................" - ], - "palettes": [ "acidia_residential_commercial_palette" ] - } - }, - { - "type": "mapgen", - "method": "json", - "om_terrain": [ "urban_17_4" ], - "weight": 250, - "object": { - "fill_ter": "t_floor", - "rows": [ - "........................", - "........................", - "........................", - ".......RRRRRRRR.........", - ".......RRRRRRRR.........", - ".......RRRRRRRR.........", - ".......RRRRRRRR.........", - ".......RRRRRRRR.........", - "RRRRRRRRRRRRRRR.........", - "RRRRRRRRRRRRRRR.........", - "RRRRRRRRRRRRRRR.........", - "RRRRRRRRRRRRRRR.........", - "RRRRRRRRRRRRRRR.........", - "RRRRRRRRRRRRRRR.........", - "RRRRRRRRRRRRRRR.........", - "RRRRRRRRRRRRRRR.........", - "RRRRRRRRRRRRRRR.........", - "RRRRRRRRRRRRRRR.........", - "RRRRRRRRRRRRRRR.........", - "RRRRRRRRRRRRRRR.........", - "RRRRRRRRRRRRRRR.........", - "RRRRRRRRRRRRRRR.........", - "RRRRRRRRRRRRRRR.........", - "........................" - ], - "palettes": [ "acidia_residential_commercial_palette" ] - } - } -] diff --git a/data/mods/Urban_Development/building_jsons/urban_18_victorian.json b/data/mods/Urban_Development/building_jsons/urban_18_victorian.json deleted file mode 100644 index 3c885e07111d0..0000000000000 --- a/data/mods/Urban_Development/building_jsons/urban_18_victorian.json +++ /dev/null @@ -1,439 +0,0 @@ -[ - { - "type": "mapgen", - "method": "json", - "om_terrain": [ "urban_18_1" ], - "weight": 250, - "object": { - "fill_ter": "t_floor", - "rows": [ - "%%%%%%%%%%%%%%%%%%%%%%%%", - "%%%%%%%%%%%%%%%%%%%%%%%%", - "%%%%%%%%%%%%%%%%%%%%%%%%", - "%%%%%%%%%%%%%%%%%%%%%%%%", - "%%%%%%%%%%%%%%%%iiiii%%%", - "%%%%%%%%%%%%%%%%i:::i%%%", - "%%%%%%%%%%%%iiiii:::iiii", - "%%%%%%%%%%%%i:::::::::i:", - "%%%%%%%%%%%%i:::::::::i:", - "%%%%%%%%%%%%i:::::Z:::::", - "%%%%%%%%%%%%i::::ZZiiii:", - "%%%%%%%%%%%%ii:iiiiiiii:", - "%%%%%%%%%%%%i::::::iiii:", - "%%%%%%%%%%iii:::::::::::", - "%%%%%%%%%%i:::::::::::::", - "%%%%%%%%%%i:::::::iiiiii", - "%%%%%%%%%%i:::::::i%%%%%", - "%%%%%%%%%%iii:::iii%%%%%", - "%%%%%%%%%%%%i:::i%%%%%%%", - "%%%%%%%%%%%%iiiii%%%%%%%", - "%%%%%%%%%%%%%%%%%%%%%%%%", - "%%%%%%%%%%%%%%%%%%%%%%%%", - "%%%%%%%%%%%%%%%%%%%%%%%%", - "%%%%%%%%%%%%%%%%%%%%%%%%" - ], - "palettes": [ "acidia_residential_commercial_palette" ], - "items": { ":": { "item": "home_hw", "chance": 2 } }, - "place_monsters": [ { "monster": "GROUP_ZOMBIE", "x": [ 13, 19 ], "y": [ 7, 14 ], "density": 0.03 } ] - } - }, - { - "type": "mapgen", - "method": "json", - "om_terrain": [ "urban_18_2" ], - "weight": 250, - "object": { - "fill_ter": "t_floor", - "rows": [ - "%%%%%%%%%%%%%%%%%%%%%%%%", - "%%%%%%%%%%%%%%%%%%%%%%%%", - "%%%%%%%%%%%%%%%%%%%%%%%%", - "%%%%%%%%%%%%%%%%%%%%%%%%", - "%%%%%iiiiiiiii%%%%%%%%%%", - "%%%%%i:::::::i%%%%%%%%%%", - "iiiiii:::::::i%%%%%%%%%%", - "::::::::Z::::i%%%%%%%%%%", - ":ii+ii::ZZ:::i%%%%%%%%%%", - ":iL ri:::::::i%%%%%%%%%%", - ":iL ri:ii:ii:i%%%%%%%%%%", - ":iiiii'''''''iii%%%%%%%%", - ":::i>'''''''''Wi%%%%%%%%", - "::iiii''''''''Di%%%%%%%%", - "::::::''''''ciii%%%%%%%%", - "iiiiiirr'''cci%%%%%%%%%%", - "%%%%%iii'''iii%%%%%%%%%%", - "%%%%%%%i'''i%%%%%%%%%%%%", - "%%%%%%%iiiii%%%%%%%%%%%%", - "%%%%%%%%%%%%%%%%%%%%%%%%", - "%%%%%%%%%%%%%%%%%%%%%%%%", - "%%%%%%%%%%%%%%%%%%%%%%%%", - "%%%%%%%%%%%%%%%%%%%%%%%%", - "%%%%%%%%%%%%%%%%%%%%%%%%" - ], - "palettes": [ "acidia_residential_commercial_palette" ], - "items": { - ":": { "item": "home_hw", "chance": 2 }, - "D": { "item": "allclothes", "chance": 60 }, - "L": { "item": "homeguns", "chance": 25 }, - "W": { "item": "allclothes", "chance": 60 }, - "c": { "item": "cleaning", "chance": 60 }, - "r": { "item": "electronics", "chance": 60 } - }, - "place_monsters": [ { "monster": "GROUP_ZOMBIE", "x": [ 1, 12 ], "y": [ 7, 14 ], "density": 0.02 } ] - } - }, - { - "type": "mapgen", - "method": "json", - "om_terrain": [ "urban_18_3" ], - "weight": 250, - "object": { - "fill_ter": "t_floor", - "rows": [ - ",,,,,,,,,,,,,,,,,,,,,,,,", - ",iinnninnnninnnninnnninn", - ",i,,,,,,,,,,,,,,,,,,,,,,", - ",N,,,,,,,,^,,,,;;;;;;;,,", - ",N,,^,,,,,,,,,,;|---|'''", - ",N,,,,,,,,,,,,,;!22>|'''", - ",i,,,,,,,,,,|---|2|-|-|-", - ",N,,,,,,,,,,|CCof2|u u| ", - ",N,,,,,,,,,,wS2222|-+-| ", - ",N,,,,,,,,,,wS22222222+ ", - ",i,,,,,^,,,,|C2222|IiI| ", - ",N,,,,,,,,,,|-+-|-|IFI| ", - ",N,,,,,,,,,,| |r|''' ", - ",i,,,,,,,,|-| h |+| ", - ",N,,,,,,,,| t ", - ",N,,,,,,,,w httth |-w--1", - ",N,,,,,,,,| t |'''''", - ",i,,,,,,,,|-| h |-|'''''", - ",N,,,,,,,,,,w w,,,,,,;", - ",N,,,,,,,,,,|-w-|,,,,,,;", - ",N,,,,^,,,,,,,,,,,,,,,,;", - ",i,,,,,,,,,,,,,,,,,,,,i;", - ",iinnninnnninnnninnnnii;", - ",,,,,,,,,,,,,,,,,,,,,,,;" - ], - "palettes": [ "acidia_residential_commercial_palette" ], - "items": { - " ": { "item": "livingroom", "chance": 2 }, - "C": { "item": "kitchen", "chance": 25 }, - "f": { "item": "fridge", "chance": 70 }, - "o": { "item": "oven", "chance": 30 }, - "r": { "item": "jackets", "chance": 60 }, - "t": { "item": "dining", "chance": 25 }, - "u": { "item": "cannedfood", "chance": 50 } - }, - "place_monsters": [ { "monster": "GROUP_ZOMBIE", "x": [ 1, 22 ], "y": [ 1, 22 ], "density": 0.15 } ] - } - }, - { - "type": "mapgen", - "method": "json", - "om_terrain": [ "urban_18_4" ], - "weight": 250, - "object": { - "fill_ter": "t_floor", - "rows": [ - ",,,,,,,,,,,,,,,,,,,,,,,,", - "nninnnninnnninnnninnnii,", - ",,,,,,,,,,,,,,,,,,,,,,i,", - ",,,,,,,,,,,,,,,,,,,,,,N,", - "''''q|-w---w-|,,,,,,,,N,", - "''''q| |,,,,,^,,N,", - "w-1--| bbb w,,,,,,,,i,", - " + bbb w,,,,,,,,N,", - " |-+-| ebbbe |,,,,,,,,N,", - " |B2S|-------|,,^,,,,,N,", - " |B2T|O ccc |,,,,,,,,i,", - " |-|-| |w|,,,,,,N,", - " >|<+ t cw,,,,,,N,", - " -|-| @ cw,,,,,,i,", - " + @@@@ |w|,,,,,,N,", - "1--w-| |,,,,,,,,N,", - "'''''|-| |-|,,,,,,,,N,", - "''''',,wcccw,,,,,,,,,,i,", - ";,,,,,,|w-w|,,,,,^,,,,N,", - ";,,,,,,,,,,,,,,,,,,,,,N,", - ";,,,,,,,,,,,,,,,,,,,,,N,", - ";i,,,,,,,,,,,,,,,,,,,,i,", - ";iinnnninnnninnnninnnii,", - ";,,,,,,,,,,,,,,,,,,,,,,," - ], - "palettes": [ "acidia_residential_commercial_palette" ], - "toilets": { "T": { } }, - "items": { - " ": { "item": "livingroom", "chance": 2 }, - "2": { "item": "softdrugs", "chance": 10 }, - "@": { "item": "magazines", "chance": 10 }, - "O": { "item": "homebooks", "chance": 60 }, - "b": { "item": "bed", "chance": 60 }, - "c": { "item": "livingroom", "chance": 25 }, - "e": { "item": "dresser", "chance": 60 }, - "t": { "item": "coffee_table", "chance": 25 } - }, - "place_monsters": [ { "monster": "GROUP_ZOMBIE", "x": [ 1, 22 ], "y": [ 1, 22 ], "density": 0.15 } ] - } - }, - { - "type": "mapgen", - "method": "json", - "om_terrain": [ "urban_18_5" ], - "weight": 250, - "object": { - "fill_ter": "t_floor", - "rows": [ - "........................", - "........................", - "........................", - "........................", - "................|-w-|RRR", - "................|> <|RRR", - "............|---|-+-|-w-", - "............|OOOO u", - "............w AtA ", - "............w ", - "............|OOOO OI'I-+", - "............|---|+|IFI ", - "............wS2T|r|IiI ", - "..........|-|-+-|-| ", - "..........|OO ", - "..........w |-w---", - "..........| |RRRRR", - "..........|-|dhd|-|RRRRR", - "............wd6dw.......", - "............|-w-|.......", - "........................", - "........................", - "........................", - "........................" - ], - "palettes": [ "acidia_residential_commercial_palette" ], - "toilets": { "T": { } }, - "items": { - " ": { "item": "livingroom", "chance": 2 }, - "2": { "item": "softdrugs", "chance": 10 }, - "@": { "item": "magazines", "chance": 10 }, - "A": { "item": "livingroom", "chance": 15 }, - "O": { "item": "homebooks", "chance": 60 }, - "d": { "item": "office", "chance": 40 }, - "r": { "item": "alcohol", "chance": 80 }, - "t": { "item": "coffee_table", "chance": 25 } - }, - "place_monsters": [ { "monster": "GROUP_ZOMBIE", "x": [ 13, 22 ], "y": [ 7, 14 ], "density": 0.09 } ] - } - }, - { - "type": "mapgen", - "method": "json", - "om_terrain": [ "urban_18_6" ], - "weight": 250, - "object": { - "fill_ter": "t_floor", - "rows": [ - "........................", - "........................", - "........................", - "........................", - "RRRRR|-w---w-|..........", - "RRRRR|O |..........", - "-----|O ppp w..........", - "OOOOO|O ppp w..........", - " ppp |..........", - " | |..........", - "+|OOO|-------|..........", - " |---| ebbbe |w|........", - " |< >| bbb cw........", - " + bbb cw........", - " | |w|........", - "---w-| ee|..........", - "RRRRR|-| |-|..........", - "RRRRR..wcccw............", - ".......|w-w|............", - "........................", - "........................", - "........................", - "........................", - "........................" - ], - "palettes": [ "acidia_residential_commercial_palette" ], - "items": { - " ": { "item": "livingroom", "chance": 2 }, - "O": { "item": "homebooks", "chance": 60 }, - "b": { "item": "bed", "chance": 60 }, - "c": { "item": "livingroom", "chance": 25 }, - "e": { "item": "dresser", "chance": 60 }, - "p": { "item": "pool_table", "chance": 35 } - }, - "place_monsters": [ { "monster": "GROUP_ZOMBIE", "x": [ 1, 12 ], "y": [ 7, 14 ], "density": 0.09 } ] - } - }, - { - "type": "mapgen", - "method": "json", - "om_terrain": [ "urban_18_7" ], - "weight": 250, - "object": { - "fill_ter": "t_floor", - "rows": [ - "........................", - "........................", - "........................", - "........................", - "................|-w-|...", - "................|< |...", - "............|---|-|+|-w-", - "............|OuO | O", - "............w + ", - "............|e | ", - "............|bbb iiiI--", - "............|bbb ''FIBB", - "............|bbb iiiI22", - "..........|-|e + +22", - "..........|@ O|rr|CS", - "..........w@ t O|--|-w", - "..........|@ O|.....", - "..........|-| |-|.....", - "............w@@@w.......", - "............|-w-|.......", - "........................", - "........................", - "........................", - "........................" - ], - "palettes": [ "acidia_residential_commercial_palette" ], - "items": { - " ": { "item": "livingroom", "chance": 2 }, - "2": { "item": "softdrugs", "chance": 10 }, - "@": { "item": "magazines", "chance": 10 }, - "C": { "item": "cleaning", "chance": 40 }, - "O": { "item": "homebooks", "chance": 60 }, - "b": { "item": "bed", "chance": 60 }, - "e": { "item": "dresser", "chance": 60 }, - "r": { "item": "bedroom", "chance": 60 }, - "t": { "item": "coffee_table", "chance": 25 }, - "u": { "item": "alcohol", "chance": 70 } - }, - "place_monsters": [ { "monster": "GROUP_ZOMBIE", "x": [ 13, 22 ], "y": [ 7, 14 ], "density": 0.09 } ] - } - }, - { - "type": "mapgen", - "method": "json", - "om_terrain": [ "urban_18_8" ], - "weight": 250, - "object": { - "fill_ter": "t_floor", - "rows": [ - "........................", - "........................", - "........................", - "........................", - ".....|-w---w-|..........", - ".....| e|..........", - "-|-w-| ew..........", - "O|S2T| bbb w..........", - " |-+-| bbb |..........", - " + ebbbe |..........", - "-| |-------|..........", - "B| |-| ebbbe |w|........", - "T| |<| bbb cw........", - "2| + bbb cw........", - "C| | |w|........", - "-|-w-| ee|..........", - ".....|-| |-|..........", - ".......wcccw............", - ".......|w-w|............", - "........................", - "........................", - "........................", - "........................", - "........................" - ], - "palettes": [ "acidia_residential_commercial_palette" ], - "toilets": { "T": { } }, - "items": { - " ": { "item": "livingroom", "chance": 2 }, - "2": { "item": "softdrugs", "chance": 10 }, - "O": { "item": "homebooks", "chance": 60 }, - "b": { "item": "bed", "chance": 60 }, - "c": { "item": "livingroom", "chance": 40 }, - "e": { "item": "dresser", "chance": 60 } - }, - "place_monsters": [ { "monster": "GROUP_ZOMBIE", "x": [ 1, 12 ], "y": [ 7, 14 ], "density": 0.09 } ] - } - }, - { - "type": "mapgen", - "method": "json", - "om_terrain": [ "urban_18_9" ], - "weight": 250, - "object": { - "fill_ter": "t_floor", - "rows": [ - "........................", - "........................", - "........................", - "........................", - "................RRRRR...", - "................RRRRR...", - "............RRRRRRRRRRRR", - "............RRRRRRRRRRRR", - "............RRRRRRRRRRRR", - "............RRRRRRRRRRRR", - "............RRRRRRRRRRRR", - "............RRRRRRRRRRRR", - "............RRRRRRRRRRRR", - "..........RRRRRRRRRRRRRR", - "..........RRRRRRRRRRRRRR", - "..........RRRRRRRRRRRRRR", - "..........RRRRRRRRR.....", - "..........RRRRRRRRR.....", - "............RRRRR.......", - "............RRRRR.......", - "........................", - "........................", - "........................", - "........................" - ], - "palettes": [ "acidia_residential_commercial_palette" ] - } - }, - { - "type": "mapgen", - "method": "json", - "om_terrain": [ "urban_18_10" ], - "weight": 250, - "object": { - "fill_ter": "t_floor", - "rows": [ - "........................", - "........................", - "........................", - "........................", - ".....RRRRRRRRR..........", - ".....RRRRRRRRR..........", - "RRRRRRRRRRRRRR..........", - "RRRRRRRRRRRRRR..........", - "RRRRRRRRRRRRRR..........", - "RRRRRRRRRRRRRR..........", - "RRRRRRRRRRRRRR..........", - "RRRRRRRRRRRRRRRR........", - "RRRRRRRRRRRRRRRR........", - "RRRRRRRRRRRRRRRR........", - "RRRRRRRRRRRRRRRR........", - "RRRRRRRRRRRRRR..........", - ".....RRRRRRRRR..........", - ".......RRRRR............", - ".......RRRRR............", - "........................", - "........................", - "........................", - "........................", - "........................" - ], - "palettes": [ "acidia_residential_commercial_palette" ] - } - } -] diff --git a/data/mods/Urban_Development/building_jsons/urban_8_house_brick_garden.json b/data/mods/Urban_Development/building_jsons/urban_8_house_brick_garden.json deleted file mode 100644 index c46c7783b587f..0000000000000 --- a/data/mods/Urban_Development/building_jsons/urban_8_house_brick_garden.json +++ /dev/null @@ -1,212 +0,0 @@ -[ - { - "type": "mapgen", - "method": "json", - "om_terrain": [ "urban_8_1" ], - "weight": 250, - "object": { - "fill_ter": "t_floor", - "rows": [ - ",,,,,,,,,,,,,,,,,,,,,,,,", - ",Nnnnnnnnnnnnnnnnnnnnn|-", - ",N,,,,,,,,,,,,,,,,,,,,|r", - ",N,,,,,,,,,,,,,,,##,,,wr", - ",N,,,,,,,,,,,,,,,##,,,|r", - ",N,,,,,#|vv+vv|,,,,,,,|-", - ",N,,,,,#v:::::v,,,,^,,,,", - ",N,,,,,,v:::::v,,,,,,,,,", - ",N,,,,,,v:::::v,,,,,,,,,", - ",N,,,,,,|:::::|,,,,,,,,,", - ",N,,,,,,v:::::v,,mmmm,,,", - ",N,,,,,,|:::::|,,mmmm,;;", - ",N,,,,,,v:::::v,,mmmm,;,", - ",N,,,,,,v:::::v,,mmmm,;,", - ",N,,,,,,v:::::v,,mmmm,;,", - ",N,,,,,,|vv+vv|,,,,,,,;,", - ",N,,,,,,,,,;;;;;;;;;;;;,", - ",N,,,,,,,,,,,,,,,,,,,,;,", - ",N,,,,,##,,,,,,,,,,,,,;,", - ",N,,,,,##,,,^,,##,,,,,;,", - ",N,,,,,,,,,,,,,##,,,,,;,", - ",N,,,,,,,,,,,,,,,,,,,,;;", - ",Nnnnnnnnnnnnnnnnnnnnnnn", - ",,,,,,,,,,,,,,,,,,,,,,,," - ], - "palettes": [ "acidia_residential_commercial_palette" ], - "items": { ":": { "item": "farming_tools", "chance": 8 }, "r": { "item": "farming_tools", "chance": 60 } }, - "place_monsters": [ { "monster": "GROUP_ZOMBIE", "x": [ 1, 22 ], "y": [ 1, 22 ], "density": 0.09 } ] - } - }, - { - "type": "mapgen", - "method": "json", - "om_terrain": [ "urban_8_2" ], - "weight": 250, - "object": { - "fill_ter": "t_floor", - "rows": [ - ",,,,,,,,,,,,,,,,,,,,,,,,", - "-w--|nnnnnnnnnnnnnnnnnN,", - ":::L|,,,,,,,,,,,,,,,,,N,", - ":::Lw,,,mmmmm,,,,,,,,,N,", - ":::L|,,,mmmmm,,,,^,,,,N,", - "-+--|,,,mmmmm,,,,,,,,,N,", - ",;,,,,,,mmmmm,,,,,,,,,N,", - ",;,,,,,,,,,,,,,,,,,,,,N,", - ",;,,,,,,,,,,,,,,,,,,,,N,", - ",;,qIiYiiiiiiYiiiiiI,,N,", - ",;,qICSCoC|u| bbe I,,N,", - ";;;;!22222|+| bb Y,,N,", - ",,,,I22222 + eY,,N,", - ",,,,If2Wjj| | eI,,N,", - ",,,,I-----| |-|-|+-I,,N,", - ",,,,Y >|r| rI,,N,", - ",,,,Ic @ |+|--I,,N,", - ",,,,Ic @ +2222Y,,N,", - ",,,,I A |SC2TI,,N,", - ",,,,IiiiYYii!iIiiiiI,,N,", - ",,,,,,,,,,;;;;;,,,,,,,N,", - ";;;;;;;;;;;;;;;,,,,,,,N,", - "nnnnnnnnnnnn;nnnnnnnnnN,", - ",,,,,,,,,,,,;,,,,,,,,,,," - ], - "palettes": [ "acidia_residential_commercial_palette" ], - "toilets": { "T": { } }, - "items": { - " ": { "item": "livingroom", "chance": 2 }, - "@": { "item": "magazines", "chance": 10 }, - "A": { "item": "livingroom", "chance": 15 }, - "C": { "item": "kitchen", "chance": 25 }, - "L": { "item": "farming_seeds", "chance": 60 }, - "b": { "item": "bed", "chance": 60 }, - "c": { "item": "livingroom", "chance": 25 }, - "e": { "item": "dresser", "chance": 60 }, - "f": { "item": "fridge", "chance": 70 }, - "j": { "item": "cannedfood", "chance": 50 }, - "o": { "item": "oven", "chance": 30 }, - "q": { "item": "trash", "chance": 50 }, - "r": { "item": "bedroom", "chance": 60 }, - "u": { "item": "cleaning", "chance": 50 } - }, - "place_monsters": [ { "monster": "GROUP_ZOMBIE", "x": [ 1, 22 ], "y": [ 1, 22 ], "density": 0.09 } ] - } - }, - { - "type": "mapgen", - "method": "json", - "om_terrain": [ "urban_8_3" ], - "weight": 250, - "object": { - "fill_ter": "t_floor", - "rows": [ - "........................", - "......................RR", - "......................RR", - "......................RR", - "......................RR", - "........RRRRRRR.......RR", - "........RRRRRRR.........", - "........RRRRRRR.........", - "........RRRRRRR.........", - "........RRRRRRR.........", - "........RRRRRRR.........", - "........RRRRRRR.........", - "........RRRRRRR.........", - "........RRRRRRR.........", - "........RRRRRRR.........", - "........RRRRRRR.........", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................" - ], - "palettes": [ "acidia_residential_commercial_palette" ] - } - }, - { - "type": "mapgen", - "method": "json", - "om_terrain": [ "urban_8_4" ], - "weight": 250, - "object": { - "fill_ter": "t_floor", - "rows": [ - "........................", - "RRRRR...................", - "RRRRR...................", - "RRRRR...................", - "RRRRR...................", - "RRRRR...................", - "........................", - "........................", - "........................", - "....RRRRRRRRRRRRRRRR....", - "....IiiiiiiwiiiwiiiI....", - "....Ir |B2222| bbeI....", - "....Ir |BTS|+| I....", - "....I-+-|---| | I....", - "....we + + w....", - "....Ibb |<| bbeI....", - "....Ibb |-|+---I....", - "....I | rI....", - "....IiiiiIccccIiiiiI....", - "....RRRRRIwwwwIRRRRR....", - "........................", - "........................", - "........................", - "........................" - ], - "palettes": [ "acidia_residential_commercial_palette" ], - "toilets": { "T": { } }, - "items": { - " ": { "item": "livingroom", "chance": 2 }, - "2": { "item": "softdrugs", "chance": 10 }, - "b": { "item": "bed", "chance": 60 }, - "c": { "item": "livingroom", "chance": 25 }, - "e": { "item": "dresser", "chance": 60 }, - "r": { "item": "bedroom", "chance": 60 } - }, - "place_monsters": [ { "monster": "GROUP_ZOMBIE", "x": [ 5, 18 ], "y": [ 11, 17 ], "density": 0.09 } ] - } - }, - { - "type": "mapgen", - "method": "json", - "om_terrain": [ "urban_8_6" ], - "weight": 250, - "object": { - "fill_ter": "t_floor", - "rows": [ - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "....RRRRRRRRRRRRRRRR....", - "....RRRRRRRRRRRRRRRR....", - "....RRRRRRRRRRRRRRRR....", - "....RRRRRRRRRRRRRRRR....", - "....RRRRRRRRRRRRRRRR....", - "....RRRRRRRRRRRRRRRR....", - "....RRRRRRRRRRRRRRRR....", - "....RRRRRRRRRRRRRRRR....", - "....RRRRRRRRRRRRRRRR....", - ".........RRRRRR.........", - "........................", - "........................", - "........................", - "........................" - ], - "palettes": [ "acidia_residential_commercial_palette" ] - } - } -] diff --git a/data/mods/Urban_Development/overmap_specials.json b/data/mods/Urban_Development/overmap_specials.json index fa51b56f8a89d..3c2ed16714fde 100644 --- a/data/mods/Urban_Development/overmap_specials.json +++ b/data/mods/Urban_Development/overmap_specials.json @@ -1,115 +1,4 @@ [ - { - "type": "city_building", - "id": "urban_8_house_brick_garden", - "overmaps": [ - { "point": [ 1, 0, 0 ], "overmap": "urban_8_1_south" }, - { "point": [ 0, 0, 0 ], "overmap": "urban_8_2_south" }, - { "point": [ 1, 0, 1 ], "overmap": "urban_8_3_south" }, - { "point": [ 0, 0, 1 ], "overmap": "urban_8_4_south" }, - { "point": [ 0, 0, 2 ], "overmap": "urban_8_6_south" } - ], - "locations": [ "land" ], - "flags": [ "CLASSIC" ] - }, - { - "type": "city_building", - "id": "urban_10_house_brick_pool", - "overmaps": [ - { "point": [ 1, 0, 0 ], "overmap": "urban_10_1_south" }, - { "point": [ 0, 0, 0 ], "overmap": "urban_10_2_south" }, - { "point": [ 1, 0, 1 ], "overmap": "urban_10_3_south" }, - { "point": [ 0, 0, 1 ], "overmap": "urban_10_4_south" }, - { "point": [ 1, 0, 2 ], "overmap": "urban_10_5_south" }, - { "point": [ 0, 0, 2 ], "overmap": "urban_10_6_south" } - ], - "locations": [ "land" ], - "flags": [ "CLASSIC" ] - }, - { - "type": "city_building", - "id": "urban_11_house_brick", - "overmaps": [ - { "point": [ 1, 0, 0 ], "overmap": "urban_11_1_south" }, - { "point": [ 0, 0, 0 ], "overmap": "urban_11_2_south" }, - { "point": [ 1, 0, 1 ], "overmap": "urban_11_3_south" }, - { "point": [ 0, 0, 1 ], "overmap": "urban_11_4_south" }, - { "point": [ 1, 0, 2 ], "overmap": "urban_11_5_south" }, - { "point": [ 0, 0, 2 ], "overmap": "urban_11_6_south" } - ], - "locations": [ "land" ], - "flags": [ "CLASSIC" ] - }, - { - "type": "city_building", - "id": "urban_12_house", - "overmaps": [ - { "point": [ 1, 0, 0 ], "overmap": "urban_12_1_south" }, - { "point": [ 0, 0, 0 ], "overmap": "urban_12_2_south" }, - { "point": [ 1, 0, 1 ], "overmap": "urban_12_3_south" }, - { "point": [ 0, 0, 1 ], "overmap": "urban_12_4_south" }, - { "point": [ 1, 0, 2 ], "overmap": "urban_12_5_south" }, - { "point": [ 0, 0, 2 ], "overmap": "urban_12_6_south" } - ], - "locations": [ "land" ], - "flags": [ "CLASSIC" ] - }, - { - "type": "city_building", - "id": "urban_15_house", - "overmaps": [ - { "point": [ 1, 0, 0 ], "overmap": "urban_15_1_south" }, - { "point": [ 0, 0, 0 ], "overmap": "urban_15_2_south" }, - { "point": [ 1, 0, 1 ], "overmap": "urban_15_3_south" }, - { "point": [ 0, 0, 1 ], "overmap": "urban_15_4_south" }, - { "point": [ 1, 0, 2 ], "overmap": "urban_15_5_south" }, - { "point": [ 0, 0, 2 ], "overmap": "urban_15_6_south" } - ], - "locations": [ "land" ], - "flags": [ "CLASSIC" ] - }, - { - "type": "city_building", - "id": "urban_16_house_ranch", - "overmaps": [ - { "point": [ 1, 0, 0 ], "overmap": "urban_16_1_south" }, - { "point": [ 0, 0, 0 ], "overmap": "urban_16_2_south" }, - { "point": [ 1, 0, 1 ], "overmap": "urban_16_3_south" }, - { "point": [ 0, 0, 1 ], "overmap": "urban_16_4_south" } - ], - "locations": [ "land" ], - "flags": [ "CLASSIC" ] - }, - { - "type": "city_building", - "id": "urban_17_house_ranch", - "overmaps": [ - { "point": [ 1, 0, 0 ], "overmap": "urban_17_1_south" }, - { "point": [ 0, 0, 0 ], "overmap": "urban_17_2_south" }, - { "point": [ 1, 0, 1 ], "overmap": "urban_17_3_south" }, - { "point": [ 0, 0, 1 ], "overmap": "urban_17_4_south" } - ], - "locations": [ "land" ], - "flags": [ "CLASSIC" ] - }, - { - "type": "city_building", - "id": "urban_18_victorian", - "overmaps": [ - { "point": [ 1, 0, -1 ], "overmap": "urban_18_1_south" }, - { "point": [ 0, 0, -1 ], "overmap": "urban_18_2_south" }, - { "point": [ 1, 0, 0 ], "overmap": "urban_18_3_south" }, - { "point": [ 0, 0, 0 ], "overmap": "urban_18_4_south" }, - { "point": [ 1, 0, 1 ], "overmap": "urban_18_5_south" }, - { "point": [ 0, 0, 1 ], "overmap": "urban_18_6_south" }, - { "point": [ 1, 0, 2 ], "overmap": "urban_18_7_south" }, - { "point": [ 0, 0, 2 ], "overmap": "urban_18_8_south" }, - { "point": [ 1, 0, 3 ], "overmap": "urban_18_9_south" }, - { "point": [ 0, 0, 3 ], "overmap": "urban_18_10_south" } - ], - "locations": [ "land" ], - "flags": [ "CLASSIC" ] - }, { "type": "city_building", "id": "urban_19_victorian", diff --git a/data/mods/Urban_Development/overmap_terrain.json b/data/mods/Urban_Development/overmap_terrain.json index b3b861ec94c23..d43e440bbf1dd 100644 --- a/data/mods/Urban_Development/overmap_terrain.json +++ b/data/mods/Urban_Development/overmap_terrain.json @@ -1,474 +1,4 @@ [ - { - "id": "urban_8_1", - "type": "overmap_terrain", - "name": "house", - "sym": "v", - "color": "light_green", - "see_cost": 10, - "mondensity": 2, - "flags": [ "SIDEWALK" ] - }, - { - "id": "urban_8_2", - "type": "overmap_terrain", - "name": "house", - "sym": "v", - "color": "light_green", - "see_cost": 10, - "mondensity": 2, - "flags": [ "SIDEWALK" ] - }, - { - "id": "urban_8_3", - "type": "overmap_terrain", - "name": "house", - "sym": "v", - "color": "light_green", - "see_cost": 10, - "mondensity": 2, - "flags": [ "SIDEWALK" ] - }, - { - "id": "urban_8_4", - "type": "overmap_terrain", - "name": "house", - "sym": "v", - "color": "light_green", - "see_cost": 10, - "mondensity": 2, - "flags": [ "SIDEWALK" ] - }, - { - "id": "urban_8_6", - "type": "overmap_terrain", - "name": "house", - "sym": "v", - "color": "light_green", - "see_cost": 10, - "mondensity": 2, - "flags": [ "SIDEWALK" ] - }, - { - "id": "urban_10_1", - "type": "overmap_terrain", - "name": "house", - "sym": "v", - "color": "light_green", - "see_cost": 10, - "mondensity": 2, - "flags": [ "SIDEWALK" ] - }, - { - "id": "urban_10_2", - "type": "overmap_terrain", - "name": "house", - "sym": "v", - "color": "light_green", - "see_cost": 10, - "mondensity": 2, - "flags": [ "SIDEWALK" ] - }, - { - "id": "urban_10_3", - "type": "overmap_terrain", - "name": "house", - "sym": "v", - "color": "light_green", - "see_cost": 10, - "mondensity": 2, - "flags": [ "SIDEWALK" ] - }, - { - "id": "urban_10_4", - "type": "overmap_terrain", - "name": "house", - "sym": "v", - "color": "light_green", - "see_cost": 10, - "mondensity": 2, - "flags": [ "SIDEWALK" ] - }, - { - "id": "urban_10_5", - "type": "overmap_terrain", - "name": "house", - "sym": "v", - "color": "light_green", - "see_cost": 10, - "mondensity": 2, - "flags": [ "SIDEWALK" ] - }, - { - "id": "urban_10_6", - "type": "overmap_terrain", - "name": "house", - "sym": "v", - "color": "light_green", - "see_cost": 10, - "mondensity": 2, - "flags": [ "SIDEWALK" ] - }, - { - "id": "urban_11_1", - "type": "overmap_terrain", - "name": "house", - "sym": "v", - "color": "light_green", - "see_cost": 10, - "mondensity": 2, - "flags": [ "SIDEWALK" ] - }, - { - "id": "urban_11_2", - "type": "overmap_terrain", - "name": "house", - "sym": "v", - "color": "light_green", - "see_cost": 10, - "mondensity": 2, - "flags": [ "SIDEWALK" ] - }, - { - "id": "urban_11_3", - "type": "overmap_terrain", - "name": "house", - "sym": "v", - "color": "light_green", - "see_cost": 10, - "mondensity": 2, - "flags": [ "SIDEWALK" ] - }, - { - "id": "urban_11_4", - "type": "overmap_terrain", - "name": "house", - "sym": "v", - "color": "light_green", - "see_cost": 10, - "mondensity": 2, - "flags": [ "SIDEWALK" ] - }, - { - "id": "urban_11_5", - "type": "overmap_terrain", - "name": "house", - "sym": "v", - "color": "light_green", - "see_cost": 10, - "mondensity": 2, - "flags": [ "SIDEWALK" ] - }, - { - "id": "urban_11_6", - "type": "overmap_terrain", - "name": "house", - "sym": "v", - "color": "light_green", - "see_cost": 10, - "mondensity": 2, - "flags": [ "SIDEWALK" ] - }, - { - "id": "urban_12_1", - "type": "overmap_terrain", - "name": "house", - "sym": "v", - "color": "light_green", - "see_cost": 10, - "mondensity": 2, - "flags": [ "SIDEWALK" ] - }, - { - "id": "urban_12_2", - "type": "overmap_terrain", - "name": "house", - "sym": "v", - "color": "light_green", - "see_cost": 10, - "mondensity": 2, - "flags": [ "SIDEWALK" ] - }, - { - "id": "urban_12_3", - "type": "overmap_terrain", - "name": "house", - "sym": "v", - "color": "light_green", - "see_cost": 10, - "mondensity": 2, - "flags": [ "SIDEWALK" ] - }, - { - "id": "urban_12_4", - "type": "overmap_terrain", - "name": "house", - "sym": "v", - "color": "light_green", - "see_cost": 10, - "mondensity": 2, - "flags": [ "SIDEWALK" ] - }, - { - "id": "urban_12_5", - "type": "overmap_terrain", - "name": "house", - "sym": "v", - "color": "light_green", - "see_cost": 10, - "mondensity": 2, - "flags": [ "SIDEWALK" ] - }, - { - "id": "urban_12_6", - "type": "overmap_terrain", - "name": "house", - "sym": "v", - "color": "light_green", - "see_cost": 10, - "mondensity": 2, - "flags": [ "SIDEWALK" ] - }, - { - "id": "urban_15_1", - "type": "overmap_terrain", - "name": "house", - "sym": "v", - "color": "light_green", - "see_cost": 10, - "mondensity": 2, - "flags": [ "SIDEWALK" ] - }, - { - "id": "urban_15_2", - "type": "overmap_terrain", - "name": "house", - "sym": "v", - "color": "light_green", - "see_cost": 10, - "mondensity": 2, - "flags": [ "SIDEWALK" ] - }, - { - "id": "urban_15_3", - "type": "overmap_terrain", - "name": "house", - "sym": "v", - "color": "light_green", - "see_cost": 10, - "mondensity": 2, - "flags": [ "SIDEWALK" ] - }, - { - "id": "urban_15_4", - "type": "overmap_terrain", - "name": "house", - "sym": "v", - "color": "light_green", - "see_cost": 10, - "mondensity": 2, - "flags": [ "SIDEWALK" ] - }, - { - "id": "urban_15_5", - "type": "overmap_terrain", - "name": "house", - "sym": "v", - "color": "light_green", - "see_cost": 10, - "mondensity": 2, - "flags": [ "SIDEWALK" ] - }, - { - "id": "urban_15_6", - "type": "overmap_terrain", - "name": "house", - "sym": "v", - "color": "light_green", - "see_cost": 10, - "mondensity": 2, - "flags": [ "SIDEWALK" ] - }, - { - "id": "urban_16_1", - "type": "overmap_terrain", - "name": "house", - "sym": "v", - "color": "light_green", - "see_cost": 10, - "mondensity": 2, - "flags": [ "SIDEWALK" ] - }, - { - "id": "urban_16_2", - "type": "overmap_terrain", - "name": "house", - "sym": "v", - "color": "light_green", - "see_cost": 10, - "mondensity": 2, - "flags": [ "SIDEWALK" ] - }, - { - "id": "urban_16_3", - "type": "overmap_terrain", - "name": "house", - "sym": "v", - "color": "light_green", - "see_cost": 10, - "mondensity": 2, - "flags": [ "SIDEWALK" ] - }, - { - "id": "urban_16_4", - "type": "overmap_terrain", - "name": "house", - "sym": "v", - "color": "light_green", - "see_cost": 10, - "mondensity": 2, - "flags": [ "SIDEWALK" ] - }, - { - "id": "urban_17_1", - "type": "overmap_terrain", - "name": "house", - "sym": "v", - "color": "light_green", - "see_cost": 10, - "mondensity": 2, - "flags": [ "SIDEWALK" ] - }, - { - "id": "urban_17_2", - "type": "overmap_terrain", - "name": "house", - "sym": "v", - "color": "light_green", - "see_cost": 10, - "mondensity": 2, - "flags": [ "SIDEWALK" ] - }, - { - "id": "urban_17_3", - "type": "overmap_terrain", - "name": "house", - "sym": "v", - "color": "light_green", - "see_cost": 10, - "mondensity": 2, - "flags": [ "SIDEWALK" ] - }, - { - "id": "urban_17_4", - "type": "overmap_terrain", - "name": "house", - "sym": "v", - "color": "light_green", - "see_cost": 10, - "mondensity": 2, - "flags": [ "SIDEWALK" ] - }, - { - "id": "urban_18_1", - "type": "overmap_terrain", - "name": "basement", - "sym": "O", - "color": "dark_gray", - "see_cost": 10, - "mondensity": 2, - "flags": [ "SIDEWALK" ] - }, - { - "id": "urban_18_2", - "type": "overmap_terrain", - "name": "basement", - "sym": "O", - "color": "dark_gray", - "see_cost": 10, - "mondensity": 2, - "flags": [ "SIDEWALK" ] - }, - { - "id": "urban_18_3", - "type": "overmap_terrain", - "name": "house", - "sym": "v", - "color": "light_green", - "see_cost": 10, - "mondensity": 2, - "flags": [ "SIDEWALK" ] - }, - { - "id": "urban_18_4", - "type": "overmap_terrain", - "name": "house", - "sym": "v", - "color": "light_green", - "see_cost": 10, - "mondensity": 2, - "flags": [ "SIDEWALK" ] - }, - { - "id": "urban_18_5", - "type": "overmap_terrain", - "name": "house", - "sym": "v", - "color": "light_green", - "see_cost": 10, - "mondensity": 2, - "flags": [ "SIDEWALK" ] - }, - { - "id": "urban_18_6", - "type": "overmap_terrain", - "name": "house", - "sym": "v", - "color": "light_green", - "see_cost": 10, - "mondensity": 2, - "flags": [ "SIDEWALK" ] - }, - { - "id": "urban_18_7", - "type": "overmap_terrain", - "name": "house", - "sym": "v", - "color": "light_green", - "see_cost": 10, - "mondensity": 2, - "flags": [ "SIDEWALK" ] - }, - { - "id": "urban_18_8", - "type": "overmap_terrain", - "name": "house", - "sym": "v", - "color": "light_green", - "see_cost": 10, - "mondensity": 2, - "flags": [ "SIDEWALK" ] - }, - { - "id": "urban_18_9", - "type": "overmap_terrain", - "name": "house", - "sym": "v", - "color": "light_green", - "see_cost": 10, - "mondensity": 2, - "flags": [ "SIDEWALK" ] - }, - { - "id": "urban_18_10", - "type": "overmap_terrain", - "name": "house", - "sym": "v", - "color": "light_green", - "see_cost": 10, - "mondensity": 2, - "flags": [ "SIDEWALK" ] - }, { "id": "urban_19_1", "type": "overmap_terrain", diff --git a/data/mods/Urban_Development/regional_overlay.json b/data/mods/Urban_Development/regional_overlay.json index d14bc80dc7799..d637af469c345 100644 --- a/data/mods/Urban_Development/regional_overlay.json +++ b/data/mods/Urban_Development/regional_overlay.json @@ -4,14 +4,6 @@ "regions": [ "all" ], "city": { "houses": { - "urban_8_house_brick_garden": 30, - "urban_10_house_brick_pool": 30, - "urban_11_house_brick": 30, - "urban_12_house": 30, - "urban_15_house": 30, - "urban_16_house_ranch": 30, - "urban_17_house_ranch": 30, - "urban_18_victorian": 30, "urban_19_victorian": 30, "urban_20_duplex": 30, "urban_21_house": 30, diff --git a/doc/ARTIFACTS.md b/doc/ARTIFACTS.md index f5beaa44006a3..24d7e5b5bc87c 100644 --- a/doc/ARTIFACTS.md +++ b/doc/ARTIFACTS.md @@ -11,6 +11,17 @@ The procedural generation of artifacts is defined in Json. The object looks like { "type": "relic_procgen_data", "id": "cult", + "charge_types": [ + { + "weight": 100, + "charges": { "range": [ 0, 3 ], "power": 25 }, + "charges_per_use":{ "range": [ 1, 1 ], "power": 25 }, + "max_charges": { "range": [ 1, 3 ], "power": 25 }, + "recharge_type": "periodic", + "time": [ "3 h", "6 h" ] + } + ], + "active_procgen_values": [ { "weight": 100, "spell_id": "AEA_PAIN" } ], "passive_add_procgen_values": [ { "weight": 100, @@ -36,6 +47,21 @@ The procedural generation of artifacts is defined in Json. The object looks like } ``` +### charge_types + +The various ways this artifact can charge and use charges. + +- **charges** the number of charges this artifact starts with - a random value between the two ones in 'range' are picked, and power is the power value. +- **charges_per_use** how many charges you spend with each use of this artifact - a random value between the two ones in 'range' are picked, and power is the power value. +- **max_charges** The maximum number of charges this artifact can have. - a random value between the two ones in 'range' are picked, and power is the power value. +- **recharge_type** How this artifact recharges +- **time** The amount of time this artifact takes to recharge - a random value between the two ones provided is picked. + +#### recharge_types + +- **none** This artifact does not recharge +- **periodic** This artifact takes 'time' amount of time to recharge + ### passive_add_procgen_values and passive_mult_procgen_values As the names suggest, these are *passive* benefits/penalties to having the artifact (ie. always present without activating the artifact's abilities). **Add** values add or subtract from existing scores, and **mult** values multiply them. These are entered as a list of possible 'abilities' the artifact could get. It does not by default get all these abilities, rather when it spawns it selects from the list provided. diff --git a/doc/COMPILING/COMPILING-VS-VCPKG.md b/doc/COMPILING/COMPILING-VS-VCPKG.md index 7a52ec15f119b..d506c67bbb5b7 100644 --- a/doc/COMPILING/COMPILING-VS-VCPKG.md +++ b/doc/COMPILING/COMPILING-VS-VCPKG.md @@ -73,7 +73,7 @@ Even if you do not need languages other than English, you may still want to exec ### Debugging -Ensure that the Cataclysm project (`Cataclysm-vcpkg-static`) is the selected startup project, configure the working directory in the project settings to `$(ProjectDir)..`, and then press the debug button (or use the appropriate shortcut, e.g. F5). +Ensure that the Cataclysm project (`Cataclysm-vcpkg-static`) is the selected startup project, configure the working directory in the project settings to `$(ProjectDir)..` (under Debugging section), and then press the debug button (or use the appropriate shortcut, e.g. F5). If you discover that after pressing the debug button in Visual Studio, Cataclysm just exits after launch with return code 1, that is because of the wrong working directory. @@ -81,7 +81,10 @@ When debugging, it is not strictly necessary to use a `Debug` build; `Release` b ### Running unit tests -Ensure that the Cataclysm test project (`Cataclysm-test-vcpkg-static`) is the selected startup project, configure the working directory in the project settings to `$(ProjectDir)..`, and then press the debug button (or use the appropriate shortcut, e.g. F5). This will run all of the unit tests. Additional command line arguments may be configured in the project's command line arguments setting, or if you are using a compatible unit test runner (e.g. Resharper) you can run or debug individual tests from the unit test sessions. +Ensure that the Cataclysm test project (`Cataclysm-test-vcpkg-static`) is the selected startup project, configure the working directory in the project settings to `$(ProjectDir)..`, and then press the debug button (or use the appropriate shortcut, e.g. F5). This will run all of the unit tests. + +Additional command line arguments may be configured in the project's command line arguments setting, or if you are using a compatible unit test runner (e.g. Resharper) you can run or debug individual tests from the unit test sessions. +You can also start the test runner library manually from windows console. Run it with `--help` for an overview of the arguments. ### Make a distribution diff --git a/doc/COMPILING/COMPILING.md b/doc/COMPILING/COMPILING.md index 582b49fb450fc..b52b3e49f9e64 100644 --- a/doc/COMPILING/COMPILING.md +++ b/doc/COMPILING/COMPILING.md @@ -538,7 +538,7 @@ Pass the ``--help`` flag to list options. ### dmg distribution -You can build a nice dmg distribution file with the `dmgdist` target. You will need a tool called [dmgbuild](https://pypi.python.org/pypi/dmgbuild). To install this tool, you will need Python first. If you are on Mac OS X >= 10.8, Python 2.7 is pre-installed with the OS. If you are on an older version of OS X, you can download Python [on their official website](https://www.python.org/downloads/) or install it with homebrew `brew install python`. Once you have Python, you should be able to install `dmgbuild` by running: +You can build a nice dmg distribution file with the `dmgdist` target. You will need a tool called [dmgbuild](https://pypi.python.org/pypi/dmgbuild). To install this tool, you may need to install Python first. You can download Python [on their official website](https://www.python.org/downloads/) or install it with homebrew `brew install python`. Once you have Python, you should be able to install `dmgbuild` by running: # This install pip. It might not be required if it is already installed. curl --silent --show-error --retry 5 https://bootstrap.pypa.io/get-pip.py | sudo python diff --git a/doc/DEVELOPER_TOOLING.md b/doc/DEVELOPER_TOOLING.md index d7d86864be1e3..98842b380fe99 100644 --- a/doc/DEVELOPER_TOOLING.md +++ b/doc/DEVELOPER_TOOLING.md @@ -141,8 +141,8 @@ lit -v build/tools/clang-tidy-plugin/test To build llvm on Windows, you'll first need to get some tools installed. - Cmake -- Python 3 (Python 2 may not work for building llvm, but it's still required to run -the lit test, which will be discussed in the next section.) +- Python 3 (Python 2 may be still required to run the lit test, +which will be discussed in the next section.) - MinGW-w64 (other compilers may or may not work. Clang itself does not seem to be building llvm on Windows correctly.) - A shell environment @@ -202,8 +202,7 @@ After building clang-tidy as a library from the llvm source, the next step is to build clang-tidy as an executable, with the custom checks from the CDDA source. In this step, the following tools are required. -- Python 2 (used to run the lit test for the custom checks) -- Python 3 (used to run other python scripts) +- Python 3 (Python 2 may still be required to run the lit test for the custom checks) - CMake - MinGW-w64 - FileCheck (built from the llvm source) @@ -272,7 +271,7 @@ index 4ab6e913a7..d1a4418ba6 100644 The next step is to run CMake to generate the compilation database. The compilation database contains compiler flags that clang-tidy uses to check the source files. -Make sure Python 2, Python 3, CMake, MinGW-w64, and FileCheck are on the path. +Make sure Python 3 (and Python 2 if it's still required), CMake, MinGW-w64, and FileCheck are on the path. Note that two `bin` directories of MinGW-w64 should be on the path: `/bin`, and `/x86_64-w64-mingw32/bin`. FileCheck's path is `/build/bin`, if you built it with the instructions in the previous section. Python 2 should diff --git a/doc/JSON_INFO.md b/doc/JSON_INFO.md index 3a40024dc2d20..2fe5770c345fd 100644 --- a/doc/JSON_INFO.md +++ b/doc/JSON_INFO.md @@ -1090,16 +1090,23 @@ Crafting recipes are defined as a JSON object with the following fields: ```C++ "result": "javelin", // ID of resulting item +"byproducts": [ [ "" ] ], // Optional (default: empty). Additional items generated by crafting this recipe. "category": "CC_WEAPON", // Category of crafting recipe. CC_NONCRAFT used for disassembly recipes +"subcategory": "CSC_WEAPON_PIERCING", "id_suffix": "", // Optional (default: empty string). Some suffix to make the ident of the recipe unique. The ident of the recipe is "". "override": false, // Optional (default: false). If false and the ident of the recipe is already used by another recipe, loading of recipes fails. If true and a recipe with the ident is already defined, the existing recipe is replaced by the new recipe. "delete_flags": [ "CANNIBALISM" ], // Optional (default: empty list). Flags specified here will be removed from the resultant item upon crafting. This will override flag inheritance, but *will not* delete flags that are part of the item type itself. "skill_used": "fabrication", // Skill trained and used for success checks "skills_required": [["survival", 1], ["throw", 2]], // Skills required to unlock recipe -"book_learn": [ // (optional) Array of books that this recipe can be learned from. Each entry contains the id of the book and the skill level at which it can be learned. - [ "textbook_anarch", 7, "something" ], // The optional third entry defines a name for the recipe as it should appear in the books description (default is the name of resulting item of the recipe) - [ "textbook_gaswarfare", 8, "" ] // If the name is empty, the recipe is hidden, it will not be shown in the description of the book. -], +"book_learn": { // (optional) Books that this recipe can be learned from. + "textbook_anarch" : { // ID of the book the recipe can be learned from + "skill_level" : 7, // Skill level at which it can be learned + "recipe_name" : "something", // (optional) Name of the recipe as it should appear in the book's description (default is the name of resulting item of the recipe) + "hidden" : true }, // (optional) If set to true, recipe will not be shown in the description of the book + "textbook_gaswarfare" : { // Additional book this recipe can be learnt from. + "skill_level" : 8 + } +}, "difficulty": 3, // Difficulty of success check "time": "5 m", // Preferred time to perform recipe, can specify in minutes, hours etc. "time": 5000, // Legacy time to perform recipe (where 1000 ~= 10 turns ~= 10 seconds game time). @@ -1120,6 +1127,8 @@ Crafting recipes are defined as a JSON object with the following fields: "required": false, // Whether or not you must have the proficiency to craft it. Incompatible with `time_multiplier` "time_multiplier": 2.0 // The multiplier on time taken to craft this recipe if you do not have this proficiency "fail_multiplier": 2.5 // The multiplier on failure chance when crafting without this proficiency. Defaults to 2.5. Multiple proficiencies will multiply this value. (if all have the default, it's fail_multiplier ^ n, where n is the number of proficiencies that are lacked) + "learning_time_multiplier": 1.2 // The multiplier on learning speed for this proficiency. By default, it's the time of the recipe, divded by the time multiplier, and by the number of proficiencies that can also be learned from it. + "max_experience": "15 m" // This recipe cannot raise your experience for that proficiency above 15 minutes worth. } ] "batch_time_factors": [25, 15], // Optional factors for batch crafting time reduction. First number specifies maximum crafting time reduction as percentage, and the second number the minimal batch size to reach that number. In this example given batch size of 20 the last 6 crafts will take only 3750 time units. @@ -2116,7 +2125,7 @@ Armor can be defined like this: "type" : "ARMOR", // Defines this as armor ... // same entries as above for the generic item. // additional some armor specific entries: -"covers" : ["FEET"], // Where it covers. Possible options are TORSO, HEAD, EYES, MOUTH, ARMS, HANDS, LEGS, FEET +"covers" : [ "foot_l", "foot_r" ], // Where it covers. Use bodypart_id defined in body_parts.json "warmth" : 10, // (Optional, default = 0) How much warmth clothing provides "environmental_protection" : 0, // (Optional, default = 0) How much environmental protection it affords "encumbrance" : 0, // Base encumbrance (unfitted value) @@ -2133,7 +2142,7 @@ Alternately, every item (book, tool, gun, even food) can be used as armor if it "type" : "TOOL", // Or any other item type ... // same entries as for the type (e.g. same entries as for any tool), "armor_data" : { // additionally the same armor data like above - "covers" : ["FEET"], + "covers" : [ "foot_l", "foot_r" ], "warmth" : 10, "environmental_protection" : 0, "encumbrance" : 0, @@ -2763,7 +2772,8 @@ The contents of use_action fields can either be a string indicating a built-in f "npc_class_id": "true_foodperson", // npc class id, see npcs/classes.json "summon_msg": "You summon a food hero!", // (optional) message when summoning the npc. "place_randomly": true, // if true: places npc randomly around the player, if false: let the player decide where to put it (default: false) - "moves": 50 // how many move points the action takes. + "moves": 50, // how many move points the action takes. + "radius": 1 // maximum radius for random npc placement. }, "use_action" : { "type" : "delayed_transform", // Like transform, but it will only transform when the item has a certain age diff --git a/doc/MISSIONS_JSON.md b/doc/MISSIONS_JSON.md index fdf225c09165a..57c63d29f65e4 100644 --- a/doc/MISSIONS_JSON.md +++ b/doc/MISSIONS_JSON.md @@ -171,7 +171,7 @@ are applied afterwards. The `om_terrain` is the only required field. ``` If the `om_terrain` is part of an overmap special, it's essential to specify the `om_special` -value as well--otherwise, the game will not know how to spawn the entire special. +value as well--otherwise, the game will not know how to spawn the entire special. If a multitile `om_special` is used it is important to specify the exact `om_terrain` that you would like the target to appear in. `om_terrain_match_type` defaults to TYPE if unspecified, and has the following possible values: diff --git a/doc/NPCs.md b/doc/NPCs.md index b088f8904b039..fd787bca5ee1f 100644 --- a/doc/NPCs.md +++ b/doc/NPCs.md @@ -19,7 +19,7 @@ defined, and all defined topics are referenced in a response or an NPC's chat, i There is a python script in `tools/dialogue_validator.py` that will map all topics to responses and vice versa. Invoke it with ```sh -python tools/dialogue_validator.py data/json/npcs/* data/json/npcs/Backgrounds/* data/json/npcs/refugee_center/* +python3 tools/dialogue_validator.py data/json/npcs/* data/json/npcs/Backgrounds/* data/json/npcs/refugee_center/* ``` If you are writing a mod with dialogue, you can add the paths to the mod's dialogue files. diff --git a/doc/PROFICIENCY.md b/doc/PROFICIENCY.md index 859c401f5b28b..83405f9dbf614 100644 --- a/doc/PROFICIENCY.md +++ b/doc/PROFICIENCY.md @@ -6,14 +6,37 @@ { "id": "prof_knapping", "type": "proficiency", - "name": { "str": "Knapping" } + "name": { "str": "Knapping" }, + "desription": "The ability to turn stones into usable tools.", + "can_learn": true, + "time_to_learn": "10 h", + "required_proficiencies": [ "prof_foo" ] }, ``` ### `id` -Mandatory. The id of the proficiency. +Mandatory. String +The id of the proficiency. ### `type` -Mandatory. Must be `proficiency`. +Mandatory. String +Must be `proficiency`. ### `name` -Mandatory. The name of the proficiency. +Mandatory. String +The name of the proficiency. + +### `description` +Mandatory. String +The description of the proficiency. + +### `can_learn` +Mandatory. Bool +Whether or not this proficiency can be learned through normal means during the game. + +### `time_to_learn` +Optional. time_duration, as a string +The (optimal) time required to learn this proficiency. + +### `required_proficiencies` +Optional. Array of strings +The proficiencies that must be obtained before this one can. diff --git a/doc/TILESET.md b/doc/TILESET.md index 51dc6136ed09e..e4e7fe444e655 100644 --- a/doc/TILESET.md +++ b/doc/TILESET.md @@ -12,7 +12,7 @@ This is a Python script that will convert a legacy tileset into a compositing ti It requires pyvips to do the image processing. It takes a single mandatory argument, which is the path to the tileset directory. For example: -`python tools/gfx_tools/decompose.py gfx/ChestHole16Tileset` will convert the legacy ChestHole16 tileset to a compositing tileset. +`python3 tools/gfx_tools/decompose.py gfx/ChestHole16Tileset` will convert the legacy ChestHole16 tileset to a compositing tileset. decompose.py creates a sufficient directory hierarchy and file names for a tileset to be compositing, but it is machine generated and badly organized. New compositing tilesets should use more sensible file names and a better organization. diff --git a/doc/VEHICLES_JSON.md b/doc/VEHICLES_JSON.md index 962a3d2f67538..7ff5304542834 100644 --- a/doc/VEHICLES_JSON.md +++ b/doc/VEHICLES_JSON.md @@ -19,13 +19,13 @@ Vehicle prototypes do not currently accept copy-from { "x": 0, "y": 0, "part": "frame" }, // Part definition, positive x direction is up, { "x": 0, "y": 0, "part": "seat" }, // positive y is to the right { "x": 0, "y": 0, "part": "controls"}, // See vehicle_parts.json for part ids - { "x": 0, "y": 1, "parts: [ "frame", "seat" ] }, // Arrays of parts on the same space - { "x": 0, "y": 1, "parts: [ { "part": "tank", "fuel": "gasoline" }, "battery_car" }, + { "x": 0, "y": 1, "parts": [ "frame", "seat" ] }, // Arrays of parts on the same space + { "x": 0, "y": 1, "parts": [ { "part": "tank", "fuel": "gasoline" }, "battery_car" }, { "x": 0, "y": 1, "part": "stereo" }, // parts arrays and part may be mixed on the same space - { "x": 1, "y": 0, "parts: [ "frame, "wheel" ] }, - { "x": 1, "y": 1, "parts: [ "frame, "wheel" ] }, - { "x": -1, "y": 0, "parts: [ "frame, "wheel" ] }, - { "x": -1, "y": 1, "parts: [ "frame, "wheel" ] } + { "x": 1, "y": 0, "parts": [ "frame", "wheel" ] }, + { "x": 1, "y": 1, "parts": [ "frame", "wheel" ] }, + { "x": -1, "y": 0, "parts": [ "frame", "wheel" ] }, + { "x": -1, "y": 1, "parts": [ "frame", "wheel" ] } ], "items": [ // Item spawn list { "x": 0, "y": 0, "items": "helmet_army" }, // individual item diff --git a/lang/CMakeLists.txt b/lang/CMakeLists.txt index 65b5dad1c23f9..591a78e9e77bf 100644 --- a/lang/CMakeLists.txt +++ b/lang/CMakeLists.txt @@ -18,7 +18,7 @@ MESSAGE("\n") add_custom_target ( extract_string - COMMAND python lang/extract_json_strings.py + COMMAND python3 lang/extract_json_strings.py WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} ) diff --git a/lang/extract_json_strings.py b/lang/extract_json_strings.py index 0a449743d44b1..e823038eed983 100755 --- a/lang/extract_json_strings.py +++ b/lang/extract_json_strings.py @@ -15,6 +15,7 @@ parser.add_option("-v", "--verbose", dest="verbose", help="be verbose") (options, args) = parser.parse_args() + # Exceptions class WrongJSONItem(Exception): def __init__(self, msg, item): @@ -24,6 +25,7 @@ def __init__(self, msg, item): def __str__(self): return ("---\nJSON error\n{0}\n--- JSON Item:\n{1}\n---".format(self.msg, self.item)) + # there may be some non-json files in data/raw not_json = {os.path.normpath(i) for i in { "sokoban.txt", @@ -47,12 +49,14 @@ def __str__(self): "data/mods/Tanks/monsters.json" }} + def warning_supressed(filename): for i in warning_suppressed_list: if filename.startswith(i): return True return False + # these files will not be parsed. Full related path. ignore_files = {os.path.normpath(i) for i in { "data/json/anatomy.json", @@ -205,6 +209,7 @@ def warning_supressed(filename): # For handling grammatical gender all_genders = ["f", "m", "n"] + def gender_options(subject): return [subject + ":" + g for g in all_genders] @@ -221,6 +226,7 @@ def extract_achievement(a): if "description" in req: writestr(outfile, req["description"]) + def extract_bodypart(item): outfile = get_outfile("bodypart") # See comments in `body_part_struct::load` of bodypart.cpp about why xxx and xxx_multiple are not inside a single translation object. @@ -236,22 +242,26 @@ def extract_bodypart(item): if "hp_bar_ui_text" in item: writestr(outfile, item["hp_bar_ui_text"]) + def extract_clothing_mod(item): outfile = get_outfile("clothing_mod") writestr(outfile, item["implement_prompt"]) writestr(outfile, item["destroy_prompt"]) + def extract_construction(item): outfile = get_outfile("construction") writestr(outfile, item["description"]) if "pre_note" in item: writestr(outfile, item["pre_note"]) + def extract_harvest(item): outfile = get_outfile("harvest") if "message" in item: writestr(outfile, item["message"]) + def extract_material(item): outfile = get_outfile("material") writestr(outfile, item["name"]) @@ -268,9 +278,10 @@ def extract_material(item): writestr(outfile, item["dmg_adj"][2]) writestr(outfile, item["dmg_adj"][3]) wrote = True - if not wrote and not "copy-from" in item : + if not wrote and "copy-from" not in item: print("WARNING: {}: no mandatory field in item: {}".format("/data/json/materials.json", item)) + def extract_martial_art(item): outfile = get_outfile("martial_art") if "name" in item: @@ -300,11 +311,12 @@ def extract_martial_art(item): for buff in buffs: writestr(outfile, buff["name"]) if buff["name"] == item["name"]: - c="Description of buff for martial art '{}'".format(name) + c = "Description of buff for martial art '{}'".format(name) else: - c="Description of buff '{}' for martial art '{}'".format(buff["name"], name) + c = "Description of buff '{}' for martial art '{}'".format(buff["name"], name) writestr(outfile, buff["description"], comment=c) + def extract_move_mode(item): outfile = get_outfile("move_modes") # Move mode name @@ -326,18 +338,19 @@ def extract_move_mode(item): change_good_mech = item["change_good_mech"] writestr(outfile, change_good_mech, comment="Successfully switch to this move mode, mech steed") if "change_bad_none" in item: - # Failed change message + # Failed change message change_bad_none = item["change_bad_none"] writestr(outfile, change_bad_none, comment="Failure to switch to this move mode, no steed") if "change_bad_animal" in item: - # Failed change message (animal steed) + # Failed change message (animal steed) change_bad_animal = item["change_bad_animal"] writestr(outfile, change_bad_animal, comment="Failure to switch to this move mode, animal steed") if "change_bad_mech" in item: - # Failed change message (mech steed) + # Failed change message (mech steed) change_bad_mech = item["change_bad_mech"] writestr(outfile, change_bad_mech, comment="Failure to switch to this move mode, mech steed") + def extract_effect_type(item): # writestr will not write string if it is None. outfile = get_outfile("effects") @@ -415,10 +428,12 @@ def extract_effect_type(item): writestr(outfile, msg, context="memorial_male") writestr(outfile, msg, context="memorial_female") else: - writestr(outfile, msg, context="memorial_male", - comment="Male memorial remove log for effect(s) '{}'.".format(', '.join(name))) - writestr(outfile, msg, context="memorial_female", - comment="Female memorial remove log for effect(s) '{}'.".format(', '.join(name))) + writestr( + outfile, msg, context="memorial_male", + comment="Male memorial remove log for effect(s) '{}'.".format(', '.join(name))) + writestr( + outfile, msg, context="memorial_female", + comment="Female memorial remove log for effect(s) '{}'.".format(', '.join(name))) def extract_gun(item): @@ -491,6 +506,7 @@ def extract_professions(item): writestr(outfile, item["description"], context="prof_desc_female", comment="Profession (female {}) description".format(nm)) + def extract_scenarios(item): outfile = get_outfile("scenario") # writestr will not write string if it is None. @@ -525,6 +541,7 @@ def extract_scenarios(item): found = item.get(f, None) writestr(outfile, found) + def extract_mapgen(item): outfile = get_outfile("mapgen") # writestr will not write string if it is None. @@ -549,6 +566,7 @@ def extract_mapgen(item): writestr(outfile, v.get("access_denied"), comment="Computer access denied warning") + def extract_monster_attack(item): outfile = get_outfile("monster_attack") if "hit_dmg_u" in item: @@ -579,6 +597,7 @@ def extract_recipe_group(item): for i in item.get("recipes"): writestr(outfile, i.get("description")) + def extract_gendered_dynamic_line_optional(line, outfile): if "gendered_line" in line: msg = line["gendered_line"] @@ -588,12 +607,14 @@ def extract_gendered_dynamic_line_optional(line, outfile): context = " ".join(context_list) writestr(outfile, msg, context=context) + def extract_dynamic_line_optional(line, member, outfile): if member in line: extract_dynamic_line(line[member], outfile) + dynamic_line_string_keys = [ -# from `simple_string_conds` in `condition.h` + # from `simple_string_conds` in `condition.h` "u_male", "u_female", "npc_male", "npc_female", "has_no_assigned_mission", "has_assigned_mission", "has_many_assigned_missions", "has_no_available_mission", "has_available_mission", "has_many_available_missions", @@ -604,10 +625,11 @@ def extract_dynamic_line_optional(line, member, outfile): "u_can_stow_weapon", "npc_can_stow_weapon", "u_has_weapon", "npc_has_weapon", "u_driving", "npc_driving", "has_pickup_list", "is_by_radio", "has_reason", -# yes/no strings for complex conditions, 'and' list + # yes/no strings for complex conditions, 'and' list "yes", "no", "and" ] + def extract_dynamic_line(line, outfile): if type(line) == list: for l in line: @@ -619,6 +641,7 @@ def extract_dynamic_line(line, outfile): elif type(line) == str: writestr(outfile, line) + def extract_talk_effects(effects, outfile): if type(effects) != list: effects = [effects] @@ -627,6 +650,7 @@ def extract_talk_effects(effects, outfile): if "u_buy_monster" in eff and "name" in eff: writestr(outfile, eff["name"], comment="Nickname for creature '{}'".format(eff["u_buy_monster"])) + def extract_talk_response(response, outfile): if "text" in response: writestr(outfile, response["text"]) @@ -647,6 +671,7 @@ def extract_talk_response(response, outfile): if "effect" in response: extract_talk_effects(response["effect"], outfile) + def extract_talk_topic(item): outfile = get_outfile("talk_topic") if "dynamic_line" in item: @@ -657,12 +682,14 @@ def extract_talk_topic(item): if "effect" in item: extract_talk_effects(item["effect"], outfile) + def extract_trap(item): outfile = get_outfile("trap") writestr(outfile, item["name"]) if "vehicle_data" in item and "sound" in item["vehicle_data"]: writestr(outfile, item["vehicle_data"]["sound"], comment="Trap-vehicle collision message for trap '{}'".format(item["name"])) + def extract_missiondef(item): outfile = get_outfile("mission_def") item_name = item.get("name") @@ -698,6 +725,7 @@ def extract_missiondef(item): if "fail" in item and "effect" in item["fail"]: extract_talk_effects(item["fail"]["effect"], outfile) + def extract_mutation(item): outfile = get_outfile("mutation") @@ -710,7 +738,7 @@ def extract_mutation(item): else: writestr(outfile, found) - simple_fields = [ "description" ] + simple_fields = ["description"] for f in simple_fields: found = item.get(f) @@ -735,6 +763,7 @@ def extract_mutation(item): if "spawn_item" in item: writestr(outfile, item.get("spawn_item").get("message")) + def extract_mutation_category(item): outfile = get_outfile("mutation_category") @@ -743,12 +772,12 @@ def extract_mutation_category(item): raise WrongJSONItem("JSON item don't contain 'name' field", item) writestr(outfile, found, comment="Mutation class name") - simple_fields = [ "mutagen_message", - "iv_message", - "iv_sleep_message", - "iv_sound_message", - "junkie_message" - ] + simple_fields = ["mutagen_message", + "iv_message", + "iv_sleep_message", + "iv_sound_message", + "junkie_message" + ] for f in simple_fields: found = item.get(f) @@ -773,6 +802,7 @@ def extract_vehspawn(item): for st in found: writestr(outfile, st.get("description"), comment="Vehicle Spawn Description") + def extract_recipe_category(item): outfile = get_outfile("recipe_category") @@ -794,6 +824,7 @@ def extract_recipe_category(item): writestr(outfile, subcat_name, comment="Crafting recipes subcategory of '{}' category".format(cat_name)) + def extract_gate(item): outfile = get_outfile("gates") messages = item.get("messages", {}) @@ -802,22 +833,26 @@ def extract_gate(item): writestr(outfile, v, comment="'{}' action message of some gate object.".format(k)) + def extract_field_type(item): outfile = get_outfile("field_type") for fd in item.get("intensity_levels"): - if "name" in fd: - writestr(outfile,fd.get("name")) + if "name" in fd: + writestr(outfile, fd.get("name")) + def extract_ter_furn_transform_messages(item): - outfile = get_outfile("ter_furn_transform_messages") - writestr(outfile,item.get("fail_message")) - for terrain in item.get("terrain"): - writestr(outfile,terrain.get("message")) + outfile = get_outfile("ter_furn_transform_messages") + writestr(outfile, item.get("fail_message")) + for terrain in item.get("terrain"): + writestr(outfile, terrain.get("message")) + def extract_skill_display_type(item): outfile = get_outfile("skill_display_type") writestr(outfile, item["display_string"], comment="display string for skill display type '{}'".format(item["id"])) + def extract_fault(item): outfile = get_outfile("fault") writestr(outfile, item["name"]) @@ -830,17 +865,19 @@ def extract_fault(item): if "success_msg" in method: writestr(outfile, method["success_msg"], format_strings=True, comment="success message for mending method '{}' of fault '{}'".format(method["name"], item["name"])) + def extract_snippets(item): outfile = get_outfile("snippet") - text = item["text"]; + text = item["text"] if type(text) is not list: - text = [text]; + text = [text] for snip in text: if type(snip) is str: writestr(outfile, snip) else: writestr(outfile, snip["text"]) + # these objects need to have their strings specially extracted extract_specials = { "achievement": extract_achievement, @@ -903,7 +940,8 @@ def extract_snippets(item): # clean any old extracted strings, it will all be redone for filename in os.listdir(to_dir): - if not filename.endswith(".py"): continue + if not filename.endswith(".py"): + continue f = os.path.join(to_dir, filename) os.remove(f) @@ -917,6 +955,7 @@ def tlcomment(fs, string): for line in string.splitlines(): fs.write("#~ {}\n".format(line)) + def gettextify(string, context=None, plural=None): "Put the string in a fake gettext call, and add a newline." if context: @@ -930,6 +969,7 @@ def gettextify(string, context=None, plural=None): else: return "_(%r)\n" % string + def writestr(filename, string, context=None, format_strings=False, comment=None, pl_fmt=False): "Wrap the string and write to the file." if type(string) is list: @@ -942,7 +982,7 @@ def writestr(filename, string, context=None, format_strings=False, comment=None, comment = string["//~"] else: comment = "{}\n{}".format(comment, string["//~"]) - context = string.get( "ctxt" ) + context = string.get("ctxt") str_pl = None if pl_fmt: if "str_pl" in string: @@ -971,7 +1011,7 @@ def writestr(filename, string, context=None, format_strings=False, comment=None, else: str_pl = None elif string is None: - return; + return else: raise WrongJSONItem("ERROR: value is not a string, dict, list, or None", string) @@ -983,11 +1023,13 @@ def writestr(filename, string, context=None, format_strings=False, comment=None, # we must tell xgettext this explicitly if not format_strings and ("%" in str_singular or (str_pl is not None and "%" in str_pl)): fs.write("# xgettext:no-python-format\n") - fs.write(gettextify(str_singular,context=context,plural=str_pl)) + fs.write(gettextify(str_singular, context=context, plural=str_pl)) + def get_outfile(json_object_type): return os.path.join(to_dir, json_object_type + "_from_json.py") + use_action_msgs = { "activate_msg", "deactive_msg", @@ -1023,13 +1065,15 @@ def get_outfile(json_object_type): "gerund" } + def extract_use_action_msgs(outfile, use_action, it_name, kwargs): """Extract messages for iuse_actor objects. """ for f in sorted(use_action_msgs): if type(use_action) is dict and f in use_action: if it_name: - writestr(outfile, use_action[f], - comment="Use action {} for {}.".format(f, it_name), **kwargs) + writestr( + outfile, use_action[f], + comment="Use action {} for {}.".format(f, it_name), **kwargs) # Recursively check sub objects as they may contain more messages. if type(use_action) is list: for i in use_action: @@ -1038,14 +1082,16 @@ def extract_use_action_msgs(outfile, use_action, it_name, kwargs): for (k, v) in sorted(use_action.items(), key=lambda x: x[0]): extract_use_action_msgs(outfile, v, it_name, kwargs) -found_types = set(); + +found_types = set() known_types = ignorable | use_format_strings | extract_specials.keys() | automatically_convertible + # extract commonly translatable data from json to fake-python def extract(item, infilename): """Find any extractable strings in the given json object, and write them to the appropriate file.""" - if not "type" in item: + if "type" not in item: return object_type = item["type"] found_types.add(object_type) @@ -1063,7 +1109,7 @@ def extract(item, infilename): if object_type not in known_types: print("WARNING: known_types does not contain object type '{}'".format(object_type)) wrote = False - name = item.get("name") # Used in gettext comments below. + name = item.get("name") # Used in gettext comments below. # Don't extract any record with name = "none". if name and name == "none": return @@ -1140,7 +1186,7 @@ def extract(item, infilename): wrote = True if "message" in item: writestr(outfile, item["message"], format_strings=True, - comment="Message for {} '{}'".format(object_type, name), **kwargs ) + comment="Message for {} '{}'".format(object_type, name), **kwargs) wrote = True if "messages" in item: for message in item["messages"]: @@ -1151,12 +1197,12 @@ def extract(item, infilename): writestr(outfile, mod_loc[0], **kwargs) wrote = True if "info" in item: - c = "Please leave anything in unchanged." - writestr(outfile, item["info"], comment=c, **kwargs) - wrote = True + c = "Please leave anything in unchanged." + writestr(outfile, item["info"], comment=c, **kwargs) + wrote = True if "verb" in item: - writestr(outfile, item["verb"], **kwargs) - wrote = True + writestr(outfile, item["verb"], **kwargs) + wrote = True if "special_attacks" in item: special_attacks = item["special_attacks"] for special_attack in special_attacks: @@ -1169,17 +1215,12 @@ def extract(item, infilename): .format(name, special_attack.get("spell_id")), **kwargs) wrote = True if "footsteps" in item: - writestr(outfile, item["footsteps"], **kwargs) - wrote = True - if not wrote and not "copy-from" in item: + writestr(outfile, item["footsteps"], **kwargs) + wrote = True + if not wrote and "copy-from" not in item: if not warning_supressed(infilename): print("WARNING: {}: nothing translatable found in item: {}".format(infilename, item)) -def is_official_mod(full_path): - for i in official_mods: - if full_path.find(i) != -1: - return True - return False def extract_all_from_dir(json_dir): """Extract strings from every json file in the specified directory, @@ -1187,7 +1228,7 @@ def extract_all_from_dir(json_dir): allfiles = os.listdir(json_dir) allfiles.sort() dirs = [] - skiplist = [ os.path.normpath(".gitkeep") ] + skiplist = [os.path.normpath(".gitkeep")] for f in allfiles: full_name = os.path.join(json_dir, f) if os.path.isdir(full_name): @@ -1208,6 +1249,7 @@ def extract_all_from_dir(json_dir): for d in dirs: extract_all_from_dir(os.path.join(json_dir, d)) + def extract_all_from_file(json_file): "Extract translatable strings from every object in the specified file." if options.verbose: @@ -1227,9 +1269,10 @@ def extract_all_from_file(json_file): print(E) exit(1) + def prepare_git_file_list(): command_str = "git ls-files" - res = None; + res = None if platform == "win32": res = subprocess.Popen(command_str, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) else: diff --git a/lang/strip_line_numbers.py b/lang/strip_line_numbers.py index 927d0be832f01..40e8d8cf7126f 100755 --- a/lang/strip_line_numbers.py +++ b/lang/strip_line_numbers.py @@ -8,6 +8,7 @@ usage = "USAGE: strip_line_numbers.py [ ...]" + def strip_pot_file(filename): # Check pot file if not os.path.isfile(filename): @@ -18,7 +19,7 @@ def strip_pot_file(filename): except IOError as read_exc: print(read_exc) sys.exit(1) - assert(len(to_write) > 1) # Wrong .pot file + assert(len(to_write) > 1) # Wrong .pot file to_write = strip_line_numbers(to_write) to_write = strip_repeated_comments(to_write) @@ -30,13 +31,14 @@ def strip_pot_file(filename): print(write_exc) sys.exit(1) + def strip_repeated_comments(lines): to_remove = [] ln_length = len(lines) for i in range(ln_length): line = lines[i] if i < (ln_length - 1): - next_line = lines[i+1] + next_line = lines[i + 1] else: next_line = None # only act on line-comments @@ -52,6 +54,7 @@ def strip_repeated_comments(lines): return lines + def strip_line_numbers(lines): "Strip line numbers from the specified list of strings." @@ -59,7 +62,8 @@ def strip_line_numbers(lines): for i in range(len(lines)): line = lines[i] # only act on line-comments - if not line.startswith("#:"): continue + if not line.startswith("#:"): + continue # line comments are of the format: "#: : :" items = line.split() newitems = ["#:"] @@ -67,7 +71,7 @@ def strip_line_numbers(lines): # and checking for duplicates for item in items[1:]: newname = item.split(':')[0] - if not newname in newitems: + if newname not in newitems: newitems.append(newname) # replace the old line with the new newline = ' '.join(newitems) + '\n' @@ -75,6 +79,7 @@ def strip_line_numbers(lines): return lines + if __name__ == "__main__": # get filename(s) from sys.argv and strip if len(sys.argv) < 2: diff --git a/lang/unicode_check.py b/lang/unicode_check.py index b1759d1a018a7..6b0af37e17835 100755 --- a/lang/unicode_check.py +++ b/lang/unicode_check.py @@ -2,6 +2,7 @@ from __future__ import print_function import sys + def print_encode_error(unicode_err, counter): chunk = unicode_err.object err_line = counter + chunk.count(b'\n', 0, unicode_err.start) @@ -14,6 +15,7 @@ def print_encode_error(unicode_err, counter): x_start = unicode_err.start - line_start + 2 print("{0:>{1}}".format("^" * x_num, x_start)) + def check(f): count = 1 try: @@ -28,6 +30,7 @@ def check(f): return True + if __name__ == '__main__': if len(sys.argv) < 2: print("Usage: {} [FILENAME]".format(sys.argv[0])) diff --git a/src/activity_handlers.cpp b/src/activity_handlers.cpp index 472dd3714f4bd..0cb02b94b17f8 100644 --- a/src/activity_handlers.cpp +++ b/src/activity_handlers.cpp @@ -80,6 +80,7 @@ #include "player_activity.h" #include "pldata.h" #include "point.h" +#include "proficiency.h" #include "ranged.h" #include "recipe.h" #include "requirements.h" @@ -2153,18 +2154,18 @@ static bool magic_train( player_activity *act, player *p ) } const spell_id &sp_id = spell_id( act->name ); if( sp_id.is_valid() ) { - const bool knows = get_player_character().magic.knows_spell( sp_id ); + const bool knows = get_player_character().magic->knows_spell( sp_id ); if( knows ) { - spell &studying = p->magic.get_spell( sp_id ); + spell &studying = p->magic->get_spell( sp_id ); const int expert_multiplier = act->values.empty() ? 0 : act->values[0]; const int xp = roll_remainder( studying.exp_modifier( *p ) * expert_multiplier ); studying.gain_exp( xp ); p->add_msg_if_player( m_good, _( "You learn a little about the spell: %s" ), sp_id->name ); } else { - p->magic.learn_spell( act->name, *p ); + p->magic->learn_spell( act->name, *p ); // you can decline to learn this spell , as it may lock you out of other magic. - if( p->magic.knows_spell( sp_id ) ) { + if( p->magic->knows_spell( sp_id ) ) { add_msg( m_good, _( "You learn %s." ), sp_id->name.translated() ); } else { act->set_to_null(); @@ -2195,12 +2196,20 @@ void activity_handlers::train_finish( player_activity *act, player *p ) return; } + const proficiency_id &proficiency = proficiency_id( act->name ); + if( proficiency.is_valid() ) { + p->practice_proficiency( proficiency, 15_minutes ); + add_msg( m_good, _( "You get some training in %s." ), proficiency->name() ); + act->set_to_null(); + return; + } + const matype_id &ma_id = matype_id( act->name ); if( ma_id.is_valid() ) { const martialart &mastyle = ma_id.obj(); // Trained martial arts, get_event_bus().send( p->getID(), ma_id ); - p->martial_arts_data.learn_style( mastyle.id, p->is_avatar() ); + p->martial_arts_data->learn_style( mastyle.id, p->is_avatar() ); } else if( !magic_train( act, p ) ) { debugmsg( "train_finish without a valid skill or style or spell name" ); } @@ -3361,7 +3370,7 @@ void activity_handlers::operation_do_turn( player_activity *act, player *p ) } if( bp == bodypart_id( "eyes" ) ) { - p->add_effect( effect_blind, 1_hours, num_bp ); + p->add_effect( effect_blind, 1_hours ); } } } else { @@ -3710,6 +3719,9 @@ void activity_handlers::craft_do_turn( player_activity *act, player *p ) int five_percent_steps = craft->item_counter / 500'000 - old_counter / 500'000; if( five_percent_steps > 0 ) { p->craft_skill_gain( *craft, five_percent_steps ); + // Divide by 100 for seconds, 20 for 5% + const time_duration pct_time = time_duration::from_seconds( base_total_moves / 2000 ); + p->craft_proficiency_gain( *craft, pct_time * five_percent_steps ); } // Unlike skill, tools are consumed once at the start and should not be consumed at the end @@ -4297,7 +4309,7 @@ void activity_handlers::robot_control_finish( player_activity *act, player *p ) z->name() ); z->friendly = -1; if( z->has_flag( MF_RIDEABLE_MECH ) ) { - z->add_effect( effect_pet, 1_turns, num_bp, true ); + z->add_effect( effect_pet, 1_turns, true ); } } else if( success >= -2 ) { //A near success @@ -4414,7 +4426,7 @@ void activity_handlers::spellcasting_finish( player_activity *act, player *p ) // if level is -1 then we know it's a player spell, otherwise we build it from the ground up spell temp_spell( sp ); - spell &spell_being_cast = ( level_override == -1 ) ? p->magic.get_spell( sp ) : temp_spell; + spell &spell_being_cast = ( level_override == -1 ) ? p->magic->get_spell( sp ) : temp_spell; // if level != 1 then we need to set the spell's level if( level_override != -1 ) { @@ -4487,7 +4499,7 @@ void activity_handlers::spellcasting_finish( player_activity *act, player *p ) int cost = spell_being_cast.energy_cost( *p ); switch( spell_being_cast.energy_source() ) { case magic_energy_type::mana: - p->magic.mod_mana( *p, -cost ); + p->magic->mod_mana( *p, -cost ); break; case magic_energy_type::stamina: p->mod_stamina( -cost ); @@ -4537,7 +4549,7 @@ void activity_handlers::study_spell_do_turn( player_activity *act, player *p ) return; } if( act->get_str_value( 1 ) == "study" ) { - spell &studying = p->magic.get_spell( spell_id( act->name ) ); + spell &studying = p->magic->get_spell( spell_id( act->name ) ); if( act->get_str_value( 0 ) == "gain_level" ) { if( studying.get_level() < act->get_value( 1 ) ) { act->moves_left = 1000000; @@ -4559,10 +4571,10 @@ void activity_handlers::study_spell_finish( player_activity *act, player *p ) if( act->get_str_value( 1 ) == "study" ) { p->add_msg_if_player( m_good, _( "You gained %i experience from your study session." ), total_exp_gained ); - const spell &sp = p->magic.get_spell( spell_id( act->name ) ); + const spell &sp = p->magic->get_spell( spell_id( act->name ) ); p->practice( sp.skill(), total_exp_gained, sp.get_difficulty() ); } else if( act->get_str_value( 1 ) == "learn" && act->values[2] == 0 ) { - p->magic.learn_spell( act->name, *p ); + p->magic->learn_spell( act->name, *p ); } if( act->values[2] == -1 ) { p->add_msg_if_player( m_bad, _( "It's too dark to read." ) ); diff --git a/src/activity_item_handling.cpp b/src/activity_item_handling.cpp index 877f97fa21810..aa6e241291ca6 100644 --- a/src/activity_item_handling.cpp +++ b/src/activity_item_handling.cpp @@ -293,6 +293,18 @@ static void pass_to_ownership_handling( item obj, player *p ) obj.handle_pickup_ownership( *p ); } +static void unseal_containers_of( std::vector &targets ) +{ + for( item_location &loc : targets ) { + if( loc.has_parent() ) { + item_pocket *const parent_pocket = loc.parent_item()->contained_where( *loc ); + if( parent_pocket ) { + parent_pocket->unseal(); + } + } + } +} + static void stash_on_pet( const std::list &items, monster &pet, player *p ) { units::volume remaining_volume = pet.storage_item->get_total_capacity() - pet.get_carried_volume(); @@ -512,6 +524,7 @@ void activity_handlers::drop_do_turn( player_activity *act, player *p ) } } + unseal_containers_of( act->targets ); put_into_vehicle_or_drop( *p, item_drop_reason::deliberate, obtain_activity_items( *act, *p ), pos, force_ground ); } @@ -622,6 +635,7 @@ void activity_handlers::stash_do_turn( player_activity *act, player *p ) monster *pet = g->critter_at( pos ); if( pet != nullptr && pet->has_effect( effect_pet ) ) { + unseal_containers_of( act->targets ); stash_on_pet( obtain_activity_items( *act, *p ), *pet, p ); } else { p->add_msg_if_player( _( "The pet has moved somewhere else." ) ); diff --git a/src/activity_type.cpp b/src/activity_type.cpp index 0e917fb69452e..e9db1d1a1838e 100644 --- a/src/activity_type.cpp +++ b/src/activity_type.cpp @@ -40,14 +40,6 @@ static const std::unordered_map< std::string, based_on_type > based_on_type_valu { "neither", based_on_type::NEITHER } }; -static const std::map activity_levels = { - { "NO_EXERCISE", NO_EXERCISE }, - { "LIGHT_EXERCISE", LIGHT_EXERCISE }, - { "MODERATE_EXERCISE", MODERATE_EXERCISE }, - { "ACTIVE_EXERCISE", ACTIVE_EXERCISE }, - { "EXTRA_EXERCISE", EXTRA_EXERCISE } -}; - void activity_type::load( const JsonObject &jo ) { activity_type result; diff --git a/src/advanced_inv.cpp b/src/advanced_inv.cpp index 316c039e638d5..1483378abac57 100644 --- a/src/advanced_inv.cpp +++ b/src/advanced_inv.cpp @@ -50,6 +50,7 @@ #include "ui_manager.h" #include "uistate.h" #include "units.h" +#include "units_utility.h" #include "vehicle.h" #include "vehicle_selector.h" @@ -1429,7 +1430,7 @@ void advanced_inventory::action_examine( advanced_inv_listitem *sitem, } // Might have changed a stack (activated an item, repaired an item, etc.) if( spane.get_area() == AIM_INVENTORY ) { - player_character.inv.restack( player_character ); + player_character.inv->restack( player_character ); } recalc = true; } else { @@ -1457,7 +1458,7 @@ void advanced_inventory::display() init(); avatar &player_character = get_avatar(); - player_character.inv.restack( player_character ); + player_character.inv->restack( player_character ); input_context ctxt{ register_ctxt() }; diff --git a/src/advanced_inv_area.cpp b/src/advanced_inv_area.cpp index 398faf28050fa..07fa5f326f33f 100644 --- a/src/advanced_inv_area.cpp +++ b/src/advanced_inv_area.cpp @@ -34,7 +34,7 @@ int advanced_inv_area::get_item_count() const { Character &player_character = get_player_character(); if( id == AIM_INVENTORY ) { - return player_character.inv.size(); + return player_character.inv->size(); } else if( id == AIM_WORN ) { return player_character.worn.size(); } else if( id == AIM_ALL ) { @@ -242,7 +242,7 @@ item *advanced_inv_area::get_container( bool in_vehicle ) if( uistate.adv_inv_container_location != -1 ) { // try to find valid container in the area if( uistate.adv_inv_container_location == AIM_INVENTORY ) { - const invslice &stacks = player_character.inv.slice(); + const invslice &stacks = player_character.inv->slice(); // check index first if( stacks.size() > static_cast( uistate.adv_inv_container_index ) ) { diff --git a/src/animation.cpp b/src/animation.cpp index c097af99b0716..670e0fb4b9c33 100644 --- a/src/animation.cpp +++ b/src/animation.cpp @@ -84,7 +84,7 @@ class bullet_animation : public basic_animation bool is_point_visible( const tripoint &p, int margin = 0 ) { - return g->is_in_viewport( p, margin ) && get_player_character().sees( p ); + return g->is_in_viewport( p, margin ) && get_player_view().sees( p ); } bool is_radius_visible( const tripoint ¢er, int radius ) diff --git a/src/armor_layers.cpp b/src/armor_layers.cpp index 292907ca5fc35..cb710d267dc21 100644 --- a/src/armor_layers.cpp +++ b/src/armor_layers.cpp @@ -22,6 +22,7 @@ #include "string_formatter.h" #include "translations.h" #include "ui_manager.h" +#include "units_utility.h" static const activity_id ACT_ARMOR_LAYERS( "ACT_ARMOR_LAYERS" ); @@ -903,7 +904,7 @@ void player::sort_armor() } else if( invlet_to_item( invlet ) != nullptr ) { ++iiter; } else { - inv.reassign_item( w, invlet ); + inv->reassign_item( w, invlet ); ++witer; ++iiter; } diff --git a/src/avatar.cpp b/src/avatar.cpp index e2a23d8cca891..7f3f82367f70b 100644 --- a/src/avatar.cpp +++ b/src/avatar.cpp @@ -566,7 +566,7 @@ bool avatar::read( item &it, const bool continuous ) } if( it.type->use_methods.count( "MA_MANUAL" ) ) { - if( martial_arts_data.has_martialart( martial_art_learned_from( *it.type ) ) ) { + if( martial_arts_data->has_martialart( martial_art_learned_from( *it.type ) ) ) { add_msg_if_player( m_info, _( "You already know all this book has to teach." ) ); activity.set_to_null(); return false; @@ -1209,11 +1209,11 @@ void avatar::reset_stats() } if( eff.is_null() && dur > 0_turns ) { - add_effect( type, dur, num_bp, true ); + add_effect( type, dur, true ); } else if( dur > 0_turns ) { eff.set_duration( dur ); } else { - remove_effect( type, num_bp ); + remove_effect( type ); } }; // Painkiller @@ -1303,7 +1303,7 @@ void avatar::reset_stats() } // Apply static martial arts buffs - martial_arts_data.ma_static_effects( *this ); + martial_arts_data->ma_static_effects( *this ); if( calendar::once_every( 1_minutes ) ) { update_mental_focus(); @@ -1311,7 +1311,7 @@ void avatar::reset_stats() // Effects for( const auto &maps : *effects ) { - for( auto i : maps.second ) { + for( const auto &i : maps.second ) { const auto &it = i.second; bool reduced = resists_effect( it ); mod_str_bonus( it.get_mod( "STR", reduced ) ); @@ -1577,8 +1577,8 @@ bool avatar::wield( item &target, const int obtain_cost ) 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; } @@ -1586,11 +1586,15 @@ bool avatar::wield( item &target, const int obtain_cost ) bool avatar::invoke_item( item *used, const tripoint &pt ) { const std::map &use_methods = used->type->use_methods; + const int num_methods = use_methods.size(); - if( use_methods.empty() ) { + const bool has_relic = used->is_relic(); + if( use_methods.empty() && !has_relic ) { return false; - } else if( use_methods.size() == 1 ) { + } else if( num_methods == 1 && !has_relic ) { return invoke_item( used, use_methods.begin()->first, pt ); + } else if( num_methods == 0 && has_relic ) { + return used->use_relic( *this, pt ); } uilist umenu; @@ -1603,6 +1607,10 @@ bool avatar::invoke_item( item *used, const tripoint &pt ) umenu.addentry_desc( MENU_AUTOASSIGN, res.success(), MENU_AUTOASSIGN, e.second.get_name(), res.str() ); } + if( has_relic ) { + umenu.addentry_desc( MENU_AUTOASSIGN, true, MENU_AUTOASSIGN, _( "Use relic" ), + _( "Activate this relic." ) ); + } umenu.desc_enabled = std::any_of( umenu.entries.begin(), umenu.entries.end(), []( const uilist_entry & elem ) { @@ -1612,7 +1620,11 @@ bool avatar::invoke_item( item *used, const tripoint &pt ) umenu.query(); int choice = umenu.ret; - if( choice < 0 || choice >= static_cast( use_methods.size() ) ) { + // Use the relic + if( choice == num_methods ) { + return used->use_relic( *this, pt ); + } + if( choice < 0 || choice >= num_methods ) { return false; } @@ -1663,6 +1675,7 @@ static const std::map activity_levels_str = { { NO_EXERCISE, "NO_EXERCISE" }, { LIGHT_EXERCISE, "LIGHT_EXERCISE" }, { MODERATE_EXERCISE, "MODERATE_EXERCISE" }, + { BRISK_EXERCISE, "BRISK_EXERCISE" }, { ACTIVE_EXERCISE, "ACTIVE_EXERCISE" }, { EXTRA_EXERCISE, "EXTRA_EXERCISE" } }; @@ -1690,8 +1703,8 @@ std::string avatar::total_daily_calories_string() const { std::string ret = " E: Extra exercise\n A: Active exercise\n" - " M: Moderate exercise\n L: Light exercise\n" - " N: No exercise\n" + " B: Brisk Exercise\n M: Moderate exercise\n" + " L: Light exercise\n N: No exercise\n" " Each number refers to 5 minutes\n" " gained spent total\n"; int num_day = 1; @@ -1699,12 +1712,13 @@ std::string avatar::total_daily_calories_string() const // Each row is 32 columns long - for the first row, it's // 5 for the day and the offset from it, // 18 for the numbers, and 9 for the spacing between them - // For the second, 4 offset + 5 labels + 8 spacing leaves 15 for the levels - std::string activity_str = string_format( "%3dE %3dA %3dM %3dL %3dN", + // For the second, 5 offset + 6 labels + 5 spacing leaves 16 for the levels + std::string activity_str = string_format( "%3dE %3dA %3dB %3dM %3dL %3dN", day.activity_levels.at( EXTRA_EXERCISE ), day.activity_levels.at( ACTIVE_EXERCISE ), + day.activity_levels.at( BRISK_EXERCISE ), day.activity_levels.at( MODERATE_EXERCISE ), day.activity_levels.at( LIGHT_EXERCISE ), day.activity_levels.at( NO_EXERCISE ) ); - std::string act_stats = string_format( " %1s %s", colorize( ">", c_light_gray ), + std::string act_stats = string_format( " %1s %s", colorize( ">", c_light_gray ), colorize( activity_str, c_yellow ) ); std::string calorie_stats = string_format( "%2d %6d %6d %6d", num_day++, day.gained, day.spent, day.total() ); diff --git a/src/avatar.h b/src/avatar.h index 9e12caca47374..a331da1b47aa6 100644 --- a/src/avatar.h +++ b/src/avatar.h @@ -260,6 +260,7 @@ class avatar : public player activity_levels.emplace( NO_EXERCISE, 0 ); activity_levels.emplace( LIGHT_EXERCISE, 0 ); activity_levels.emplace( MODERATE_EXERCISE, 0 ); + activity_levels.emplace( BRISK_EXERCISE, 0 ); activity_levels.emplace( ACTIVE_EXERCISE, 0 ); activity_levels.emplace( EXTRA_EXERCISE, 0 ); } diff --git a/src/avatar_action.cpp b/src/avatar_action.cpp index 609255a27dc3c..e0d5c689a38eb 100644 --- a/src/avatar_action.cpp +++ b/src/avatar_action.cpp @@ -572,7 +572,7 @@ void avatar_action::swim( map &m, avatar &you, const tripoint &p ) m.board_vehicle( you.pos(), &you ); } you.moves -= ( movecost > 200 ? 200 : movecost ) * ( trigdist && diagonal ? M_SQRT2 : 1 ); - you.inv.rust_iron_items(); + you.inv->rust_iron_items(); if( !you.is_mounted() ) { you.burn_move_stamina( movecost ); diff --git a/src/avatar_action.h b/src/avatar_action.h index a03a02de5eadc..e7ff6c10fde14 100644 --- a/src/avatar_action.h +++ b/src/avatar_action.h @@ -4,7 +4,7 @@ #include "optional.h" #include "point.h" -#include "units.h" +#include "units_fwd.h" class aim_activity_actor; class avatar; diff --git a/src/ballistics.cpp b/src/ballistics.cpp index 0ae6f3204b8a3..a2696fb9bcccc 100644 --- a/src/ballistics.cpp +++ b/src/ballistics.cpp @@ -9,7 +9,6 @@ #include #include "calendar.h" -#include "character.h" #include "creature.h" #include "damage.h" #include "debug.h" @@ -32,6 +31,7 @@ #include "trap.h" #include "type_id.h" #include "units.h" +#include "viewer.h" #include "visitable.h" #include "vpart_position.h" @@ -49,14 +49,10 @@ static void drop_or_embed_projectile( const dealt_projectile_attack &attack ) } const tripoint &pt = attack.end_point; - Character &player_character = get_player_character(); if( effects.count( "SHATTER_SELF" ) ) { // Drop the contents, not the thrown item - if( player_character.sees( pt ) ) { - add_msg( _( "The %s shatters!" ), drop_item.tname() ); - } - + add_msg_if_player_sees( pt, _( "The %s shatters!" ), drop_item.tname() ); drop_item.visit_items( [&pt]( const item * it ) { get_map().add_item_or_charges( pt, *it ); return VisitResponse::NEXT; @@ -71,9 +67,7 @@ static void drop_or_embed_projectile( const dealt_projectile_attack &attack ) if( effects.count( "BURST" ) ) { // Drop the contents, not the thrown item - if( player_character.sees( pt ) ) { - add_msg( _( "The %s bursts!" ), drop_item.tname() ); - } + add_msg_if_player_sees( pt, _( "The %s bursts!" ), drop_item.tname() ); // copies the drop item to spill the contents item( drop_item ).spill_contents( pt ); @@ -108,9 +102,8 @@ static void drop_or_embed_projectile( const dealt_projectile_attack &attack ) if( embed ) { mon->add_item( dropped_item ); - if( player_character.sees( *mon ) ) { - add_msg( _( "The %1$s embeds in %2$s!" ), dropped_item.tname(), mon->disp_name() ); - } + add_msg_if_player_sees( pt, _( "The %1$s embeds in %2$s!" ), + dropped_item.tname(), mon->disp_name() ); } else { bool do_drop = true; // monsters that are able to be tied up will store the item another way diff --git a/src/bionics.cpp b/src/bionics.cpp index 51eb85a51addb..a8dafbf93b849 100644 --- a/src/bionics.cpp +++ b/src/bionics.cpp @@ -508,9 +508,8 @@ void npc::check_or_use_weapon_cbm( const bionic_id &cbm_id ) if( is_armed() ) { stow_item( weapon ); } - if( get_player_character().sees( pos() ) ) { - add_msg( m_info, _( "%s activates their %s." ), disp_name(), bio.info().name ); - } + add_msg_if_player_sees( pos(), m_info, _( "%s activates their %s." ), + disp_name(), bio.info().name ); weapon = item( bio.info().fake_item ); mod_power_level( -bio.info().power_activate ); @@ -677,7 +676,7 @@ bool Character::activate_bionic( int b, bool eff_only, bool *close_bionics_ui ) } else if( bio.id == bio_cqb ) { add_msg_activate(); const avatar *you = as_avatar(); - if( you && !martial_arts_data.pick_style( *you ) ) { + if( you && !martial_arts_data->pick_style( *you ) ) { bio.powered = false; add_msg_if_player( m_info, _( "You change your mind and turn it off." ) ); return false; @@ -1154,12 +1153,11 @@ bool Character::deactivate_bionic( int b, bool eff_only ) add_msg_if_player( m_neutral, _( "You deactivate your %s." ), bio.info().name ); } - Character &player_character = get_player_character(); // Deactivation effects go here if( bio.info().has_flag( flag_BIO_WEAPON ) ) { if( weapon.typeId() == bio.info().fake_item ) { add_msg_if_player( _( "You withdraw your %s." ), weapon.tname() ); - if( player_character.sees( pos() ) ) { + if( get_player_view().sees( pos() ) ) { add_msg_if_npc( m_info, _( " withdraws %s %s." ), disp_name( true ), weapon.tname() ); } @@ -1170,7 +1168,7 @@ bool Character::deactivate_bionic( int b, bool eff_only ) invalidate_crafting_inventory(); } } else if( bio.id == bio_cqb ) { - martial_arts_data.selected_style_check(); + martial_arts_data->selected_style_check(); } else if( bio.id == bio_remote ) { if( g->remoteveh() != nullptr && !has_active_item( itype_remotevehcontrol ) ) { g->setremoteveh( nullptr ); @@ -1514,7 +1512,7 @@ void Character::heat_emission( int b, int fuel_energy ) here.emit_field( pos(), hotness, heat_spread ); } for( const std::pair &bp : bio.info().occupied_bodyparts ) { - add_effect( effect_heating_bionic, 2_seconds, bp.first->token, false, heat_prod ); + add_effect( effect_heating_bionic, 2_seconds, bp.first.id(), false, heat_prod ); } } @@ -1663,7 +1661,7 @@ void Character::process_bionic( int b ) if( get_power_level() >= 40_J ) { std::forward_list bleeding_bp_parts; for( const bodypart_id bp : get_all_body_parts() ) { - if( has_effect( effect_bleed, bp->token ) ) { + if( has_effect( effect_bleed, bp.id() ) ) { bleeding_bp_parts.push_front( bp ); } } @@ -1677,8 +1675,7 @@ void Character::process_bionic( int b ) for( const bodypart_id &i : bleeding_bp_parts ) { // effectively reduces by 1 intensity level if( get_stored_kcal() >= 15 ) { - get_effect( effect_bleed, i->token ).mod_duration( -get_effect( effect_bleed, - i->token ).get_int_dur_factor() ); + get_effect( effect_bleed, i ).mod_duration( -get_effect( effect_bleed, i ).get_int_dur_factor() ); mod_stored_kcal( -15 ); } else { bleeding_bp_parts.clear(); @@ -1795,7 +1792,7 @@ void Character::bionics_uninstall_failure( int difficulty, int success, float ad case 3: for( const bodypart_id &bp : get_all_body_parts() ) { const body_part enum_bp = bp->token; - if( has_effect( effect_under_operation, enum_bp ) ) { + if( has_effect( effect_under_operation, bp.id() ) ) { if( bp_hurt.count( mutate_to_main_part( enum_bp ) ) > 0 ) { continue; } @@ -1811,7 +1808,7 @@ void Character::bionics_uninstall_failure( int difficulty, int success, float ad case 5: for( const bodypart_id &bp : get_all_body_parts() ) { const body_part enum_bp = bp->token; - if( has_effect( effect_under_operation, enum_bp ) ) { + if( has_effect( effect_under_operation, bp.id() ) ) { if( bp_hurt.count( mutate_to_main_part( enum_bp ) ) > 0 ) { continue; } @@ -1884,7 +1881,7 @@ void Character::bionics_uninstall_failure( monster &installer, player &patient, case 3: for( const bodypart_id &bp : get_all_body_parts() ) { const body_part enum_bp = bp->token; - if( has_effect( effect_under_operation, enum_bp ) ) { + if( has_effect( effect_under_operation, bp.id() ) ) { if( bp_hurt.count( mutate_to_main_part( enum_bp ) ) > 0 ) { continue; } @@ -1902,7 +1899,7 @@ void Character::bionics_uninstall_failure( monster &installer, player &patient, case 5: for( const bodypart_id &bp : get_all_body_parts() ) { const body_part enum_bp = bp->token; - if( has_effect( effect_under_operation, enum_bp ) ) { + if( has_effect( effect_under_operation, bp.id() ) ) { if( bp_hurt.count( mutate_to_main_part( enum_bp ) ) > 0 ) { continue; } @@ -2196,7 +2193,7 @@ bool Character::uninstall_bionic( const bionic_id &b_id, player &installer, bool activity.str_values.push_back( "false" ); } for( const std::pair &elem : b_id->occupied_bodyparts ) { - add_effect( effect_under_operation, difficulty * 20_minutes, elem.first->token, true, difficulty ); + add_effect( effect_under_operation, difficulty * 20_minutes, elem.first.id(), true, difficulty ); } return true; @@ -2242,11 +2239,9 @@ void Character::perform_uninstall( const bionic_id &bid, int difficulty, int suc bool Character::uninstall_bionic( const bionic &target_cbm, monster &installer, player &patient, float adjusted_skill ) { - Character &player_character = get_player_character(); + viewer &player_view = get_player_view(); if( installer.ammo[itype_anesthetic] <= 0 ) { - if( player_character.sees( installer ) ) { - add_msg( _( "The %s's anesthesia kit looks empty." ), installer.name() ); - } + add_msg_if_player_sees( installer, _( "The %s's anesthesia kit looks empty." ), installer.name() ); return false; } @@ -2265,10 +2260,10 @@ bool Character::uninstall_bionic( const bionic &target_cbm, monster &installer, if( patient.is_player() ) { add_msg( m_bad, _( "You feel a tiny pricking sensation in your right arm, and lose all sensation before abruptly blacking out." ) ); - } else if( player_character.sees( installer ) ) { - add_msg( m_bad, - _( "The %1$s gently inserts a syringe into %2$s's arm and starts injecting something while holding them down." ), - installer.name(), patient.disp_name() ); + } else { + add_msg_if_player_sees( installer, m_bad, + _( "The %1$s gently inserts a syringe into %2$s's arm and starts injecting something while holding them down." ), + installer.name(), patient.disp_name() ); } installer.ammo[itype_anesthetic] -= 1; @@ -2278,9 +2273,9 @@ bool Character::uninstall_bionic( const bionic &target_cbm, monster &installer, if( patient.is_player() ) { add_msg( _( "You fall asleep and %1$s starts operating." ), installer.disp_name() ); - } else if( player_character.sees( patient ) ) { - add_msg( _( "%1$s falls asleep and %2$s starts operating." ), patient.disp_name(), - installer.disp_name() ); + } else { + add_msg_if_player_sees( patient, _( "%1$s falls asleep and %2$s starts operating." ), + patient.disp_name(), installer.disp_name() ); } if( success > 0 ) { @@ -2288,7 +2283,7 @@ bool Character::uninstall_bionic( const bionic &target_cbm, monster &installer, if( patient.is_player() ) { add_msg( m_neutral, _( "Your parts are jiggled back into their familiar places." ) ); add_msg( m_mixed, _( "Successfully removed %s." ), target_cbm.info().name ); - } else if( patient.is_npc() && player_character.sees( patient ) ) { + } else if( patient.is_npc() && player_view.sees( patient ) ) { add_msg( m_neutral, _( "%s's parts are jiggled back into their familiar places." ), patient.disp_name() ); add_msg( m_mixed, _( "Successfully removed %s." ), target_cbm.info().name ); @@ -2299,7 +2294,7 @@ bool Character::uninstall_bionic( const bionic &target_cbm, monster &installer, patient.remove_bionic( target_cbm.id ); item cbm( "burnt_out_bionic" ); if( item::type_is_defined( target_cbm.info().itype() ) ) { - cbm = item( target_cbm.id.c_str() ); + cbm = bionic_to_uninstall; } cbm.set_flag( flag_FILTHY ); cbm.set_flag( flag_NO_STERILE ); @@ -2442,7 +2437,7 @@ bool Character::install_bionics( const itype &type, player &installer, bool auto activity.str_values.push_back( "false" ); } for( const std::pair &elem : bioid->occupied_bodyparts ) { - add_effect( effect_under_operation, difficulty * 20_minutes, elem.first->token, true, difficulty ); + add_effect( effect_under_operation, difficulty * 20_minutes, elem.first.id(), true, difficulty ); } return true; @@ -2564,7 +2559,7 @@ void Character::bionics_install_failure( const bionic_id &bid, const std::string case 5: { for( const bodypart_id &bp : get_all_body_parts() ) { const body_part enum_bp = bp->token; - if( has_effect( effect_under_operation, enum_bp ) ) { + if( has_effect( effect_under_operation, bp.id() ) ) { if( bp_hurt.count( mutate_to_main_part( enum_bp ) ) > 0 ) { continue; } @@ -2683,10 +2678,10 @@ void Character::add_bionic( const bionic_id &b ) add_msg_if_player( spell_class->desc() ); } } - if( !magic.knows_spell( learned_spell ) ) { - magic.learn_spell( learned_spell, *this, true ); + if( !magic->knows_spell( learned_spell ) ) { + magic->learn_spell( learned_spell, *this, true ); } - spell &known_spell = magic.get_spell( learned_spell ); + spell &known_spell = magic->get_spell( learned_spell ); // spells you learn from installing a bionic upgrade spells you know if they are the same if( known_spell.get_level() < spell_pair.second ) { known_spell.set_level( spell_pair.second ); @@ -2729,7 +2724,7 @@ void Character::remove_bionic( const bionic_id &b ) // any spells you learn from installing a bionic you forget. for( const std::pair &spell_pair : b->learned_spells ) { if( cbm_spells.count( spell_pair.first ) == 0 ) { - magic.forget_spell( spell_pair.first ); + magic->forget_spell( spell_pair.first ); } } diff --git a/src/bodypart.cpp b/src/bodypart.cpp index 026aa2bb4bef6..de18166d04cbc 100644 --- a/src/bodypart.cpp +++ b/src/bodypart.cpp @@ -61,28 +61,6 @@ generic_factory body_part_factory( "body part" ); } // namespace -bool is_legacy_bodypart_id( const std::string &id ) -{ - static const std::vector legacy_body_parts = { - "TORSO", - "HEAD", - "EYES", - "MOUTH", - "ARM_L", - "ARM_R", - "HAND_L", - "HAND_R", - "LEG_L", - "LEG_R", - "FOOT_L", - "FOOT_R", - "NUM_BP", - }; - - return std::find( legacy_body_parts.begin(), legacy_body_parts.end(), - id ) != legacy_body_parts.end(); -} - static body_part legacy_id_to_enum( const std::string &legacy_id ) { static const std::unordered_map body_parts = { diff --git a/src/bodypart.h b/src/bodypart.h index 73af4684cbbd6..7cf2e19e43701 100644 --- a/src/bodypart.h +++ b/src/bodypart.h @@ -327,9 +327,6 @@ class body_part_set } }; -// Returns if passed string is legacy bodypart (i.e "TORSO", not "torso") -bool is_legacy_bodypart_id( const std::string &id ); - /** Returns the new id for old token */ const bodypart_str_id &convert_bp( body_part bp ); diff --git a/src/cata_tiles.cpp b/src/cata_tiles.cpp index cd27ea44ecaab..f1119e0e44ca2 100644 --- a/src/cata_tiles.cpp +++ b/src/cata_tiles.cpp @@ -3288,7 +3288,7 @@ void cata_tiles::draw_line() return; } static std::string line_overlay = "animation_line"; - if( !is_target_line || get_player_character().sees( line_pos ) ) { + if( !is_target_line || get_player_view().sees( line_pos ) ) { for( auto it = line_trajectory.begin(); it != line_trajectory.end() - 1; ++it ) { draw_from_id_string( line_overlay, *it, 0, 0, lit_level::LIT, false ); } @@ -3326,7 +3326,7 @@ void cata_tiles::draw_weather_frame() void cata_tiles::draw_sct_frame( std::multimap &overlay_strings ) { const bool use_font = get_option( "ANIMATION_SCT_USE_FONT" ); - Character &player_character = get_player_character(); + tripoint player_pos = get_player_location().pos(); for( auto iter = SCT.vSCT.begin(); iter != SCT.vSCT.end(); ++iter ) { const point iD( iter->getPosX(), iter->getPosY() ); @@ -3355,7 +3355,7 @@ void cata_tiles::draw_sct_frame( std::multimap &overlay_s if( tileset_ptr->find_tile_type( generic_id ) ) { draw_from_id_string( generic_id, C_NONE, empty_string, - iD + tripoint( iOffsetX, iOffsetY, player_character.pos().z ), 0, 0, lit_level::LIT, false ); + iD + tripoint( iOffsetX, iOffsetY, player_pos.z ), 0, 0, lit_level::LIT, false ); } if( tile_iso ) { @@ -3370,11 +3370,11 @@ void cata_tiles::draw_sct_frame( std::multimap &overlay_s void cata_tiles::draw_zones_frame() { - Character &player_character = get_player_character(); + tripoint player_pos = get_player_location().pos(); for( int iY = zone_start.y; iY <= zone_end.y; ++ iY ) { for( int iX = zone_start.x; iX <= zone_end.x; ++iX ) { draw_from_id_string( "highlight", C_NONE, empty_string, - zone_offset.xy() + tripoint( iX, iY, player_character.pos().z ), + zone_offset.xy() + tripoint( iX, iY, player_pos.z ), 0, 0, lit_level::LIT, false ); } } diff --git a/src/cata_utility.cpp b/src/cata_utility.cpp index 44e4a663bf80f..d5e2ad5365c0e 100644 --- a/src/cata_utility.cpp +++ b/src/cata_utility.cpp @@ -21,7 +21,6 @@ #include "output.h" #include "rng.h" #include "translations.h" -#include "units.h" static double pow10( unsigned int n ) { @@ -205,184 +204,6 @@ const char *velocity_units( const units_type vel_units ) return "error: unknown units!"; } -const char *weight_units() -{ - return get_option( "USE_METRIC_WEIGHTS" ) == "lbs" ? _( "lbs" ) : _( "kg" ); -} - -const char *volume_units_abbr() -{ - const std::string vol_units = get_option( "VOLUME_UNITS" ); - if( vol_units == "c" ) { - return pgettext( "Volume unit", "c" ); - } else if( vol_units == "l" ) { - return pgettext( "Volume unit", "L" ); - } else { - return pgettext( "Volume unit", "qt" ); - } -} - -const char *volume_units_long() -{ - const std::string vol_units = get_option( "VOLUME_UNITS" ); - if( vol_units == "c" ) { - return _( "cup" ); - } else if( vol_units == "l" ) { - return _( "liter" ); - } else { - return _( "quart" ); - } -} - -double convert_velocity( int velocity, const units_type vel_units ) -{ - const std::string type = get_option( "USE_METRIC_SPEEDS" ); - // internal units to mph conversion - double ret = static_cast( velocity ) / 100; - - if( type == "km/h" ) { - switch( vel_units ) { - case VU_VEHICLE: - // mph to km/h conversion - ret *= 1.609f; - break; - case VU_WIND: - // mph to m/s conversion - ret *= 0.447f; - break; - } - } else if( type == "t/t" ) { - ret /= 4; - } - - return ret; -} - -double convert_weight( const units::mass &weight ) -{ - double ret = to_gram( weight ); - if( get_option( "USE_METRIC_WEIGHTS" ) == "kg" ) { - ret /= 1000; - } else { - ret /= 453.6; - } - return ret; -} - -int convert_length( const units::length &length ) -{ - int ret = to_millimeter( length ); - const bool metric = get_option( "DISTANCE_UNITS" ) == "metric"; - if( metric ) { - if( ret % 1'000'000 == 0 ) { - // kilometers - ret /= 1'000'000; - } else if( ret % 1'000 == 0 ) { - // meters - ret /= 1'000; - } else if( ret % 10 == 0 ) { - // centimeters - ret /= 10; - } - } else { - // imperial's a doozy, we can only try to approximate - // so first we convert it to inches which are the smallest unit - ret /= 25.4; - if( ret % 63360 == 0 ) { - ret /= 63360; - } else if( ret % 36 == 0 ) { - ret /= 36; - } else if( ret % 12 == 0 ) { - ret /= 12; - } - } - return ret; -} - -std::string length_units( const units::length &length ) -{ - int length_mm = to_millimeter( length ); - const bool metric = get_option( "DISTANCE_UNITS" ) == "metric"; - if( metric ) { - if( length_mm % 1'000'000 == 0 ) { - //~ kilometers - return _( "km" ); - } else if( length_mm % 1'000 == 0 ) { - //~ meters - return _( "m" ); - } else if( length_mm % 10 == 0 ) { - //~ centimeters - return _( "cm" ); - } else { - //~ millimeters - return _( "mm" ); - } - } else { - // imperial's a doozy, we can only try to approximate - // so first we convert it to inches which are the smallest unit - length_mm /= 25.4; - if( length_mm == 0 ) { - //~ inches - return _( "in." ); - } - if( length_mm % 63360 == 0 ) { - //~ miles - return _( "mi" ); - } else if( length_mm % 36 == 0 ) { - //~ yards (length) - return _( "yd" ); - } else if( length_mm % 12 == 0 ) { - //~ feet (length) - return _( "ft" ); - } else { - //~ inches - return _( "in." ); - } - } -} - -std::string weight_to_string( const units::mass &weight ) -{ - const double converted_weight = convert_weight( weight ); - return string_format( "%.2f %s", converted_weight, weight_units() ); -} - -double convert_volume( int volume ) -{ - return convert_volume( volume, nullptr ); -} - -double convert_volume( int volume, int *out_scale ) -{ - double ret = volume; - int scale = 0; - const std::string vol_units = get_option( "VOLUME_UNITS" ); - if( vol_units == "c" ) { - ret *= 0.004; - scale = 1; - } else if( vol_units == "l" ) { - ret *= 0.001; - scale = 2; - } else { - ret *= 0.00105669; - scale = 2; - } - if( out_scale != nullptr ) { - *out_scale = scale; - } - return ret; -} - -std::string vol_to_string( const units::volume &vol ) -{ - int converted_volume_scale = 0; - const double converted_volume = - convert_volume( vol.value(), - &converted_volume_scale ); - - return string_format( "%.3f %s", converted_volume, volume_units_abbr() ); -} - double temp_to_celsius( double fahrenheit ) { return ( ( fahrenheit - 32.0 ) * 5.0 / 9.0 ); diff --git a/src/cata_utility.h b/src/cata_utility.h index 12b1e39a4993c..c9a7add3ca4ff 100644 --- a/src/cata_utility.h +++ b/src/cata_utility.h @@ -10,8 +10,6 @@ #include #include -#include "units.h" - class JsonIn; class JsonOut; class translation; @@ -74,15 +72,6 @@ T divide_round_up( T num, T den ) return ( num + den - 1 ) / den; } -/** Divide @p num by @p den, rounding up - * - * @p num must be non-negative, @p den must be positive, and @c num+den must not overflow. - */ -template -T divide_round_up( units::quantity num, units::quantity den ) -{ - return divide_round_up( num.value(), den.value() ); -} int divide_round_down( int a, int b ); @@ -184,36 +173,6 @@ int bound_mod_to_vals( int val, int mod, int max, int min ); */ const char *velocity_units( units_type vel_units ); -/** - * Create a units label for a weight value. - * - * Gives the name of the weight unit in the user selected unit system, either - * "kgs" or "lbs". Used to add unit labels to the output of @ref convert_weight. - * - * @return name of unit - */ -const char *weight_units(); - -/** - * Create an abbreviated units label for a volume value. - * - * Returns the abbreviated name for the volume unit for the user selected unit system, - * i.e. "c", "L", or "qt". Used to add unit labels to the output of @ref convert_volume. - * - * @return name of unit. - */ -const char *volume_units_abbr(); - -/** - * Create a units label for a volume value. - * - * Returns the abbreviated name for the volume unit for the user selected unit system, - * ie "cup", "liter", or "quart". Used to add unit labels to the output of @ref convert_volume. - * - * @return name of unit. - */ -const char *volume_units_long(); - /** * Convert internal velocity units to units defined by user. * @@ -225,41 +184,6 @@ const char *volume_units_long(); */ double convert_velocity( int velocity, units_type vel_units ); -/** - * Convert weight in grams to units defined by user (kg or lbs) - * - * @param weight to be converted. - * - * @returns Weight converted to user selected unit - */ -double convert_weight( const units::mass &weight ); - -/** - * converts length to largest unit available - * 1000 mm = 1 meter for example - * assumed to be used in conjunction with unit string functions - * also works for imperial units - */ -int convert_length( const units::length &length ); -std::string length_units( const units::length &length ); - -/** convert a mass unit to a string readable by a human */ -std::string weight_to_string( const units::mass &weight ); - -/** - * Convert volume from ml to units defined by user. - */ -double convert_volume( int volume ); - -/** - * Convert volume from ml to units defined by user, - * optionally returning the units preferred scale. - */ -double convert_volume( int volume, int *out_scale ); - -/** convert a volume unit to a string readable by a human */ -std::string vol_to_string( const units::volume &vol ); - /** * Convert a temperature from degrees Fahrenheit to degrees Celsius. * diff --git a/src/character.cpp b/src/character.cpp index ffd39ad523514..f508719e52eee 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -18,6 +18,7 @@ #include "bionics.h" #include "cata_utility.h" #include "catacharset.h" +#include "character_martial_arts.h" #include "colony.h" #include "construction.h" #include "coordinate_conversions.h" @@ -1056,8 +1057,8 @@ void Character::mount_creature( monster &z ) add_msg( m_debug, "mount_creature(): monster not found in critter_tracker" ); return; } - add_effect( effect_riding, 1_turns, num_bp, true ); - z.add_effect( effect_ridden, 1_turns, num_bp, true ); + add_effect( effect_riding, 1_turns, true ); + z.add_effect( effect_ridden, 1_turns, true ); if( z.has_effect( effect_tied ) ) { z.remove_effect( effect_tied ); if( z.tied_item ) { @@ -1242,7 +1243,7 @@ void Character::forced_dismount() } check_dead_state(); } - add_effect( effect_downed, 5_turns, num_bp, true ); + add_effect( effect_downed, 5_turns, true ); } else { add_msg( m_debug, "Forced_dismount could not find a square to deposit player" ); } @@ -1537,7 +1538,8 @@ bool Character::try_remove_grab() remove_effect( effect_grabbed ); /** @EFFECT_STR increases chance to escape grab */ - } else if( rng( 0, get_str() ) < rng( get_effect_int( effect_grabbed, bp_torso ), 8 ) ) { + } else if( rng( 0, get_str() ) < rng( get_effect_int( effect_grabbed, bodypart_id( "torso" ) ), + 8 ) ) { add_msg_player_or_npc( m_bad, _( "You try break out of the grab, but fail!" ), _( " tries to break out of the grab, but fails!" ) ); return false; @@ -1713,12 +1715,6 @@ bool Character::can_switch_to( const move_mode_id &mode ) const return mode->type() != move_mode_type::RUNNING || can_run(); } -void Character::add_effect( const efftype_id &eff_id, const time_duration &dur, body_part bp, - bool permanent, int intensity, bool force, bool deferred ) -{ - Creature::add_effect( eff_id, dur, bp, permanent, intensity, force, deferred ); -} - void Character::expose_to_disease( const diseasetype_id &dis_type ) { const cata::optional &healt_thresh = dis_type->health_threshold; @@ -1728,11 +1724,13 @@ void Character::expose_to_disease( const diseasetype_id &dis_type ) const std::set &bps = dis_type->affected_bodyparts; if( !bps.empty() ) { for( const body_part &bp : bps ) { - add_effect( dis_type->symptoms, rng( dis_type->min_duration, dis_type->max_duration ), bp, false, + add_effect( dis_type->symptoms, rng( dis_type->min_duration, dis_type->max_duration ), + convert_bp( bp ).id(), false, rng( dis_type->min_intensity, dis_type->max_intensity ) ); } } else { - add_effect( dis_type->symptoms, rng( dis_type->min_duration, dis_type->max_duration ), num_bp, + add_effect( dis_type->symptoms, rng( dis_type->min_duration, dis_type->max_duration ), + bodypart_id( "bp_null" ), false, rng( dis_type->min_intensity, dis_type->max_intensity ) ); } @@ -1756,8 +1754,6 @@ void Character::process_turn() } Creature::process_turn(); - - enchantment_cache.activate_passive( *this ); } void Character::recalc_hp() @@ -1780,7 +1776,8 @@ void Character::recalc_hp() int Character::get_part_hp_max( const bodypart_id &id ) const { - return enchantment_cache.modify_value( enchant_vals::mod::MAX_HP, Creature::get_part_hp_max( id ) ); + return enchantment_cache->modify_value( enchant_vals::mod::MAX_HP, + Creature::get_part_hp_max( id ) ); } void Character::update_body_wetness( const w_point &weather ) @@ -1894,7 +1891,7 @@ void Character::recalc_sight_limits() sight_max = 10; } - sight_max = enchantment_cache.modify_value( enchant_vals::mod::SIGHT_RANGE, sight_max ); + sight_max = enchantment_cache->modify_value( enchant_vals::mod::SIGHT_RANGE, sight_max ); // Debug-only NV, by vache's request if( has_trait( trait_DEBUG_NIGHTVISION ) ) { @@ -2245,7 +2242,7 @@ units::energy Character::get_power_level() const units::energy Character::get_max_power_level() const { - return enchantment_cache.modify_value( enchant_vals::mod::BIONIC_POWER, max_power_level ); + return enchantment_cache->modify_value( enchant_vals::mod::BIONIC_POWER, max_power_level ); } void Character::set_power_level( const units::energy &npower ) @@ -2464,14 +2461,14 @@ cata::optional::iterator> Character::wear_item( const item &to_w _( "This %s is too small to wear comfortably! Maybe it could be refitted." ), to_wear.tname() ); } - } else if( is_npc() && get_player_character().sees( *this ) ) { + } else if( is_npc() && get_player_view().sees( *this ) ) { add_msg_if_npc( _( " puts on their %s." ), to_wear.tname() ); } new_item_it->on_wear( *this ); - inv.update_invlet( *new_item_it ); - inv.update_cache_with_item( *new_item_it ); + inv->update_invlet( *new_item_it ); + inv->update_cache_with_item( *new_item_it ); recalc_sight_limits(); calc_encumbrance(); @@ -2552,7 +2549,7 @@ item *Character::try_add( item it, const item *avoid, const bool allow_wield ) // if there's a desired invlet for this item type, try to use it bool keep_invlet = false; const invlets_bitset cur_inv = allocated_invlets(); - for( const auto &iter : inv.assigned_invlet ) { + for( const auto &iter : inv->assigned_invlet ) { if( iter.second == item_type_id && !cur_inv[iter.first] ) { it.invlet = iter.first; keep_invlet = true; @@ -2710,7 +2707,7 @@ const item &Character::i_at( int position ) const } } - return inv.find_item( position ); + return inv->find_item( position ); } item &Character::i_at( int position ) @@ -2732,7 +2729,7 @@ int Character::get_item_position( const item *it ) const p++; } - return inv.position_by_item( it ); + return inv->position_by_item( it ); } item Character::i_rem( const item *it ) @@ -2757,7 +2754,7 @@ bool Character::i_add_or_drop( item &it, int qty, const item *avoid ) bool retval = true; bool drop = it.made_of( phase_id::LIQUID ); bool add = it.is_gun() || !it.is_irremovable(); - inv.assign_empty_invlet( it, *this ); + inv->assign_empty_invlet( it, *this ); map &here = get_map(); for( int i = 0; i < qty; ++i ) { drop |= !can_pickWeight( it, !get_option( "DANGEROUS_PICKUPS" ) ) || !can_pickVolume( it ); @@ -2831,7 +2828,7 @@ void Character::drop( const drop_locations &what, const tripoint &target, invlets_bitset Character::allocated_invlets() const { - invlets_bitset invlets = inv.allocated_invlets(); + invlets_bitset invlets = inv->allocated_invlets(); invlets.set( weapon.invlet ); for( const auto &w : worn ) { @@ -3226,7 +3223,7 @@ units::mass Character::weight_capacity() const ret += 22500_gram; } - ret = enchantment_cache.modify_value( enchant_vals::mod::CARRY_WEIGHT, ret ); + ret = enchantment_cache->modify_value( enchant_vals::mod::CARRY_WEIGHT, ret ); if( ret < 0_gram ) { ret = 0_gram; @@ -3358,7 +3355,7 @@ ret_val Character::can_wear( const item &it, bool with_equip_change ) cons if( !it.covers( bp ) ) { continue; } - effect e = get_effect( effect_bleed, bp->token ); + effect e = get_effect( effect_bleed, bp ); if( !e.is_null() && e.get_intensity() > e.get_max_intensity() / 4 && !worn_with_flag( flag_TOURNIQUET, bp ) ) { need_tourniquet = true; @@ -3490,7 +3487,7 @@ ret_val Character::can_unwield( const item &it ) const void Character::drop_invalid_inventory() { bool dropped_liquid = false; - for( const std::list *stack : inv.const_slice() ) { + for( const std::list *stack : inv->const_slice() ) { const item &it = stack->front(); if( it.made_of( phase_id::LIQUID ) ) { dropped_liquid = true; @@ -3776,14 +3773,14 @@ void Character::make_bleed( const bodypart_id &bp, time_duration duration, int i return; } - add_effect( effect_bleed, duration, bp->token, permanent, intensity, force, defferred ); + add_effect( effect_bleed, duration, bp, permanent, intensity, force, defferred ); } void Character::normalize() { Creature::normalize(); - martial_arts_data.reset_style(); + martial_arts_data->reset_style(); weapon = item( "null", 0 ); set_body(); @@ -3797,15 +3794,15 @@ void Character::die( Creature *nkiller ) set_killer( nkiller ); set_time_died( calendar::turn ); if( has_effect( effect_lightsnare ) ) { - inv.add_item( item( "string_36", 0 ) ); - inv.add_item( item( "snare_trigger", 0 ) ); + inv->add_item( item( "string_36", 0 ) ); + inv->add_item( item( "snare_trigger", 0 ) ); } if( has_effect( effect_heavysnare ) ) { - inv.add_item( item( "rope_6", 0 ) ); - inv.add_item( item( "snare_trigger", 0 ) ); + inv->add_item( item( "rope_6", 0 ) ); + inv->add_item( item( "snare_trigger", 0 ) ); } if( has_effect( effect_beartrap ) ) { - inv.add_item( item( "beartrap", 0 ) ); + inv->add_item( item( "beartrap", 0 ) ); } mission::on_creature_death( *this ); } @@ -3970,7 +3967,7 @@ units::mass Character::get_weight() const } ); ret += bodyweight(); // The base weight of the player's body - ret += inv.weight(); // Weight of the stored inventory + ret += inv->weight(); // Weight of the stored inventory ret += wornWeight; // Weight of worn items ret += weapon.weight(); // Weight of wielded item ret += bionics_weight(); // Weight of installed bionics @@ -4890,7 +4887,7 @@ void Character::regen( int rate_multiplier ) mod_part_damage_bandaged( bp, -healing_apply ); if( get_part_damage_bandaged( bp ) <= 0 ) { set_part_damage_bandaged( bp, 0 ); - remove_effect( effect_bandaged, bp->token ); + remove_effect( effect_bandaged, bp ); add_msg_if_player( _( "Bandaged wounds on your %s healed." ), body_part_name( bp ) ); } } @@ -4898,20 +4895,20 @@ void Character::regen( int rate_multiplier ) mod_part_damage_disinfected( bp, -healing_apply ); if( get_part_damage_disinfected( bp ) <= 0 ) { set_part_damage_disinfected( bp, 0 ); - remove_effect( effect_disinfected, bp->token ); + remove_effect( effect_disinfected, bp ); add_msg_if_player( _( "Disinfected wounds on your %s healed." ), body_part_name( bp ) ); } } // remove effects if the limb was healed by other way - if( has_effect( effect_bandaged, bp->token ) && ( get_part( bp )->is_at_max_hp() ) ) { + if( has_effect( effect_bandaged, bp.id() ) && ( is_part_at_max_hp( bp ) ) ) { set_part_damage_bandaged( bp, 0 ); - remove_effect( effect_bandaged, bp->token ); + remove_effect( effect_bandaged, bp ); add_msg_if_player( _( "Bandaged wounds on your %s healed." ), body_part_name( bp ) ); } - if( has_effect( effect_disinfected, bp->token ) && ( get_part( bp )->is_at_max_hp() ) ) { + if( has_effect( effect_disinfected, bp.id() ) && ( is_part_at_max_hp( bp ) ) ) { set_part_damage_disinfected( bp, 0 ); - remove_effect( effect_disinfected, bp->token ); + remove_effect( effect_disinfected, bp ); add_msg_if_player( _( "Disinfected wounds on your %s healed." ), body_part_name( bp ) ); } } @@ -4988,7 +4985,7 @@ void Character::update_body( const time_point &from, const time_point &to ) update_stomach( from, to ); recalculate_enchantment_cache(); if( ticks_between( from, to, 3_minutes ) > 0 ) { - magic.update_mana( *this->as_player(), to_turns( 3_minutes ) ); + magic->update_mana( *this->as_player(), to_turns( 3_minutes ) ); } const int five_mins = ticks_between( from, to, 5_minutes ); if( five_mins > 0 ) { @@ -5210,7 +5207,7 @@ void Character::update_stomach( const time_point &from, const time_point &to ) remove_effect( effect_hunger_starving ); remove_effect( effect_hunger_famished ); remove_effect( effect_hunger_blank ); - add_effect( hunger_effect, 24_hours, num_bp, true ); + add_effect( hunger_effect, 24_hours, true ); } } @@ -5416,8 +5413,8 @@ needs_rates Character::calc_needs_rates() const rates.thirst *= 0.25f; } - rates.fatigue = enchantment_cache.modify_value( enchant_vals::mod::FATIGUE, rates.fatigue ); - rates.thirst = enchantment_cache.modify_value( enchant_vals::mod::THIRST, rates.thirst ); + rates.fatigue = enchantment_cache->modify_value( enchant_vals::mod::FATIGUE, rates.fatigue ); + rates.thirst = enchantment_cache->modify_value( enchant_vals::mod::THIRST, rates.thirst ); return rates; } @@ -5663,10 +5660,10 @@ void Character::get_sick() if( one_in( disease_rarity ) ) { if( one_in( 6 ) ) { // The flu typically lasts 3-10 days. - add_env_effect( effect_flu, bp_mouth, 3, rng( 3_days, 10_days ) ); + add_env_effect( effect_flu, bodypart_id( "mouth" ), 3, rng( 3_days, 10_days ) ); } else { // A cold typically lasts 1-14 days. - add_env_effect( effect_common_cold, bp_mouth, 3, rng( 1_days, 14_days ) ); + add_env_effect( effect_common_cold, bodypart_id( "mouth" ), 3, rng( 1_days, 14_days ) ); } } } @@ -5860,7 +5857,7 @@ void Character::update_bodytemp() // Fire protection protects from blisters. // Heatsinks give near-immunity. if( blister_count - get_armor_fire( bp ) - ( has_heatsink ? 20 : 0 ) > 0 ) { - add_effect( effect_blisters, 1_turns, bp->token ); + add_effect( effect_blisters, 1_turns, bp ); if( pyromania ) { add_morale( MORALE_PYROMANIA_NEARFIRE, 10, 10, 1_hours, 30_minutes ); // Proximity that's close enough to harm us gives us a bit of a thrill @@ -5989,8 +5986,8 @@ void Character::update_bodytemp() // TODO: make this simpler and use time_duration/time_point to_turn( calendar::turn ) % to_turns( 1_minutes ) == to_turns ( 1_minutes * bp->token ) / to_turns( 1_minutes * num_bp ) && - get_effect_int( effect_cold, num_bp ) == 0 && - get_effect_int( effect_hot, num_bp ) == 0 && + get_effect_int( effect_cold ) == 0 && + get_effect_int( effect_hot ) == 0 && get_part_temp_conv( bp ) > BODYTEMP_COLD && get_part_temp_conv( bp ) <= BODYTEMP_NORM ) { add_morale( MORALE_COMFY, 1, 10, 2_minutes, 1_minutes, true ); } @@ -6030,30 +6027,30 @@ void Character::update_bodytemp() const int temp_after = get_part_temp_cur( bp ); // PENALTIES if( temp_after < BODYTEMP_FREEZING ) { - add_effect( effect_cold, 1_turns, bp->token, true, 3 ); + add_effect( effect_cold, 1_turns, bp, true, 3 ); } else if( temp_after < BODYTEMP_VERY_COLD ) { - add_effect( effect_cold, 1_turns, bp->token, true, 2 ); + add_effect( effect_cold, 1_turns, bp, true, 2 ); } else if( temp_after < BODYTEMP_COLD ) { - add_effect( effect_cold, 1_turns, bp->token, true, 1 ); + add_effect( effect_cold, 1_turns, bp, true, 1 ); } else if( temp_after > BODYTEMP_SCORCHING ) { - add_effect( effect_hot, 1_turns, bp->token, true, 3 ); + add_effect( effect_hot, 1_turns, bp, true, 3 ); if( bp->main_part == bp.id() ) { - add_effect( effect_hot_speed, 1_turns, bp->token, true, 3 ); + add_effect( effect_hot_speed, 1_turns, bp, true, 3 ); } } else if( temp_after > BODYTEMP_VERY_HOT ) { - add_effect( effect_hot, 1_turns, bp->token, true, 2 ); + add_effect( effect_hot, 1_turns, bp, true, 2 ); if( bp->main_part == bp.id() ) { - add_effect( effect_hot_speed, 1_turns, bp->token, true, 2 ); + add_effect( effect_hot_speed, 1_turns, bp, true, 2 ); } } else if( temp_after > BODYTEMP_HOT ) { - add_effect( effect_hot, 1_turns, bp->token, true, 1 ); + add_effect( effect_hot, 1_turns, bp, true, 1 ); if( bp->main_part == bp.id() ) { - add_effect( effect_hot_speed, 1_turns, bp->token, true, 1 ); + add_effect( effect_hot_speed, 1_turns, bp, true, 1 ); } } else { - remove_effect( effect_cold, bp->token ); - remove_effect( effect_hot, bp->token ); - remove_effect( effect_hot_speed, bp->token ); + remove_effect( effect_cold, bp ); + remove_effect( effect_hot, bp ); + remove_effect( effect_hot_speed, bp ); } // FROSTBITE - only occurs to hands, feet, face /** @@ -6095,7 +6092,7 @@ void Character::update_bodytemp() int FBwindPower = static_cast( total_windpower * ( 1 - get_wind_resistance( bp ) / 100.0 ) ); - int intense = get_effect_int( effect_frostbite, bp->token ); + int intense = get_effect_int( effect_frostbite, bp ); // This has been broken down into 8 zones // Low risk zones (stops at frostnip) @@ -6105,7 +6102,7 @@ void Character::update_bodytemp() if( get_part_frostbite_timer( bp ) < 2000 ) { mod_part_frostbite_timer( bp, 3 ); } - if( one_in( 100 ) && !has_effect( effect_frostbite, bp->token ) ) { + if( one_in( 100 ) && !has_effect( effect_frostbite, bp.id() ) ) { add_msg( m_warning, _( "Your %s will be frostnipped in the next few hours." ), body_part_name( bp ) ); } @@ -6148,18 +6145,18 @@ void Character::update_bodytemp() frostbite_timer = get_part_frostbite_timer( bp ); // Frostbite, no recovery possible if( frostbite_timer >= 3600 ) { - add_effect( effect_frostbite, 1_turns, bp->token, true, 2 ); - remove_effect( effect_frostbite_recovery, bp->token ); + add_effect( effect_frostbite, 1_turns, bp, true, 2 ); + remove_effect( effect_frostbite_recovery, bp ); // Else frostnip, add recovery if we were frostbitten } else if( frostbite_timer >= 1800 ) { if( intense == 2 ) { - add_effect( effect_frostbite_recovery, 1_turns, bp->token, true ); + add_effect( effect_frostbite_recovery, 1_turns, bp, true ); } - add_effect( effect_frostbite, 1_turns, bp->token, true, 1 ); + add_effect( effect_frostbite, 1_turns, bp, true, 1 ); // Else fully recovered } else if( frostbite_timer == 0 ) { - remove_effect( effect_frostbite, bp->token ); - remove_effect( effect_frostbite_recovery, bp->token ); + remove_effect( effect_frostbite, bp ); + remove_effect( effect_frostbite_recovery, bp ); } } // Warn the player if condition worsens @@ -6433,7 +6430,6 @@ bodypart_id Character::body_window( const std::string &menu_header, for( size_t i = 0; i < parts.size(); i++ ) { const healable_bp &e = parts[i]; const bodypart_id &bp = e.bp; - const body_part bp_token = bp->token; const int maximal_hp = get_part_hp_max( bp ); const int current_hp = get_part_hp_cur( bp ); // This will c_light_gray if the part does not have any effects cured by the item/effect @@ -6461,16 +6457,16 @@ bodypart_id Character::body_window( const std::string &menu_header, std::string msg; std::string desc; - bool bleeding = has_effect( effect_bleed, bp_token ); - bool bitten = has_effect( effect_bite, bp_token ); - bool infected = has_effect( effect_infected, bp_token ); - bool bandaged = has_effect( effect_bandaged, bp_token ); - bool disinfected = has_effect( effect_disinfected, bp_token ); - const int b_power = get_effect_int( effect_bandaged, bp_token ); - const int d_power = get_effect_int( effect_disinfected, bp_token ); + bool bleeding = has_effect( effect_bleed, bp.id() ); + bool bitten = has_effect( effect_bite, bp.id() ); + bool infected = has_effect( effect_infected, bp.id() ); + bool bandaged = has_effect( effect_bandaged, bp.id() ); + bool disinfected = has_effect( effect_disinfected, bp.id() ); + const int b_power = get_effect_int( effect_bandaged, bp ); + const int d_power = get_effect_int( effect_disinfected, bp ); int new_b_power = static_cast( std::floor( bandage_power ) ); if( bandaged ) { - const effect &eff = get_effect( effect_bandaged, bp_token ); + const effect &eff = get_effect( effect_bandaged, bp ); if( new_b_power > eff.get_max_intensity() ) { new_b_power = eff.get_max_intensity(); } @@ -6483,7 +6479,7 @@ bodypart_id Character::body_window( const std::string &menu_header, if( limb_is_mending ) { desc += colorize( _( "It is broken but has been set and just needs time to heal." ), c_blue ) + "\n"; - const auto &eff = get_effect( effect_mending, bp_token ); + const auto &eff = get_effect( effect_mending, bp ); const int mend_perc = eff.is_null() ? 0.0 : 100 * eff.get_duration() / eff.get_max_duration(); if( precise ) { @@ -6516,10 +6512,10 @@ bodypart_id Character::body_window( const std::string &menu_header, // BLEEDING block if( bleeding ) { - desc += colorize( string_format( "%s: %s", get_effect( effect_bleed, bp_token ).get_speed_name(), - get_effect( effect_bleed, bp_token ).disp_short_desc() ), c_red ) + "\n"; + desc += colorize( string_format( "%s: %s", get_effect( effect_bleed, bp ).get_speed_name(), + get_effect( effect_bleed, bp ).disp_short_desc() ), c_red ) + "\n"; if( bleed > 0 ) { - int percent = static_cast( bleed * 100 / get_effect_int( effect_bleed, bp_token ) ); + int percent = static_cast( bleed * 100 / get_effect_int( effect_bleed, bp ) ); percent = std::min( percent, 100 ); desc += colorize( string_format( _( "Expected reduction of bleeding by: %d %%" ), percent ), c_light_green ) + "\n"; @@ -6543,8 +6539,7 @@ bodypart_id Character::body_window( const std::string &menu_header, } // BITTEN block if( bitten ) { - desc += colorize( string_format( "%s: ", get_effect( effect_bite, - bp_token ).get_speed_name() ), c_red ); + desc += colorize( string_format( "%s: ", get_effect( effect_bite, bp ).get_speed_name() ), c_red ); desc += colorize( _( "It has a deep bite wound that needs cleaning." ), c_red ) + "\n"; if( bite > 0 ) { desc += colorize( string_format( _( "Chance to clean and disinfect: %d %%" ), @@ -6555,8 +6550,8 @@ bodypart_id Character::body_window( const std::string &menu_header, } // INFECTED block if( infected ) { - desc += colorize( string_format( "%s: ", get_effect( effect_infected, - bp_token ).get_speed_name() ), c_red ); + desc += colorize( string_format( "%s: ", get_effect( effect_infected, bp ).get_speed_name() ), + c_red ); desc += colorize( _( "It has a deep wound that looks infected. Antibiotics might be required." ), c_red ) + "\n"; if( infect > 0 ) { @@ -6617,17 +6612,16 @@ nc_color Character::limb_color( const bodypart_id &bp, bool bleed, bool bite, bo if( bp == bodypart_id( "bp_null" ) ) { return c_light_gray; } - const body_part bp_token = bp->token; int color_bit = 0; nc_color i_color = c_light_gray; - const int intense = get_effect_int( effect_bleed, bp_token ); + const int intense = get_effect_int( effect_bleed, bp ); if( bleed && intense > 0 ) { color_bit += 1; } - if( bite && has_effect( effect_bite, bp_token ) ) { + if( bite && has_effect( effect_bite, bp.id() ) ) { color_bit += 10; } - if( infect && has_effect( effect_infected, bp_token ) ) { + if( infect && has_effect( effect_infected, bp.id() ) ) { color_bit += 100; } switch( color_bit ) { @@ -7030,7 +7024,7 @@ bool Character::pour_into( item &container, item &liquid ) add_msg_if_player( _( "You pour %1$s into the %2$s." ), liquid.tname(), container.tname() ); liquid.charges -= container.fill_with( *liquid.type, amount ); - inv.unsort(); + inv->unsort(); if( liquid.charges > 0 ) { add_msg_if_player( _( "There's some left over!" ) ); @@ -7400,16 +7394,18 @@ float Character::healing_rate( float at_rest_quality ) const final_rate *= 1.0f + primary_hp_mod; } - return enchantment_cache.modify_value( enchant_vals::mod::REGEN_HP, final_rate ); + return enchantment_cache->modify_value( enchant_vals::mod::REGEN_HP, final_rate ); } float Character::healing_rate_medicine( float at_rest_quality, const bodypart_id &bp ) const { float rate_medicine = 0.0f; - for( const std::pair>> - &elem : *effects ) { - for( const std::pair &i : elem.second ) { + for( const + std::pair>> + &elem : + *effects ) { + for( const std::pair &i : elem.second ) { const effect &eff = i.second; float tmp_rate = static_cast( eff.get_amount( "HEAL_RATE" ) ) / to_turns ( 24_hours ); @@ -7627,7 +7623,7 @@ int Character::get_bmr() const const double base_bmr_calc = metabolic_rate_base() * activity_level * ( units::to_gram ( bodyweight() / 100.0 ) + ( 6.25 * height() ) - ( 5 * age() ) + equation_constant ); - return std::ceil( enchantment_cache.modify_value( enchant_vals::mod::METABOLISM, base_bmr_calc ) ); + return std::ceil( enchantment_cache->modify_value( enchant_vals::mod::METABOLISM, base_bmr_calc ) ); } void Character::increase_activity_level( float new_level ) @@ -7656,6 +7652,8 @@ std::string Character::activity_level_str() const return _( "LIGHT_EXERCISE" ); } else if( activity_level <= MODERATE_EXERCISE ) { return _( "MODERATE_EXERCISE" ); + } else if( activity_level <= BRISK_EXERCISE ) { + return _( "BRISK_EXERCISE" ); } else if( activity_level <= ACTIVE_EXERCISE ) { return _( "ACTIVE_EXERCISE" ); } else { @@ -7846,7 +7844,7 @@ int Character::get_stamina_max() const static const std::string max_stamina_modifier( "max_stamina_modifier" ); int maxStamina = get_option< int >( player_max_stamina ); maxStamina *= Character::mutation_value( max_stamina_modifier ); - maxStamina = enchantment_cache.modify_value( enchant_vals::mod::MAX_STAMINA, maxStamina ); + maxStamina = enchantment_cache->modify_value( enchant_vals::mod::MAX_STAMINA, maxStamina ); return maxStamina; } @@ -7923,7 +7921,7 @@ void Character::update_stamina( int turns ) // But mouth encumbrance interferes, even with mutated stamina. stamina_recovery += stamina_multiplier * std::max( 1.0f, base_regen_rate - ( encumb( bodypart_id( "mouth" ) ) / 5.0f ) ); - stamina_recovery = enchantment_cache.modify_value( enchant_vals::mod::REGEN_STAMINA, + stamina_recovery = enchantment_cache->modify_value( enchant_vals::mod::REGEN_STAMINA, stamina_recovery ); // TODO: recovering stamina causes hunger/thirst/fatigue. // TODO: Tiredness slowing recovery @@ -8223,6 +8221,23 @@ int Character::item_store_cost( const item &it, const item & /* container */, bo return item_handling_cost( it, penalties, base_cost ) / ( ( lvl + 10.0f ) / 10.0f ); } +int Character::item_retrieve_cost( const item &it, const item &container, bool penalties, + int base_cost ) const +{ + // Drawing from an holster use the same formula as storing an item for now + /** + * @EFFECT_PISTOL decreases time taken to draw pistols from holsters + * @EFFECT_SMG decreases time taken to draw smgs from holsters + * @EFFECT_RIFLE decreases time taken to draw rifles from holsters + * @EFFECT_SHOTGUN decreases time taken to draw shotguns from holsters + * @EFFECT_LAUNCHER decreases time taken to draw launchers from holsters + * @EFFECT_STABBING decreases time taken to draw stabbing weapons from sheathes + * @EFFECT_CUTTING decreases time taken to draw cutting weapons from scabbards + * @EFFECT_BASHING decreases time taken to draw bashing weapons from holsters + */ + return item_store_cost( it, container, penalties, base_cost ); +} + int Character::item_wear_cost( const item &it ) const { double mv = item_handling_cost( it ); @@ -8351,7 +8366,7 @@ int Character::get_shout_volume() const noise = std::max( minimum_noise, noise ); } - noise = enchantment_cache.modify_value( enchant_vals::mod::SHOUT_NOISE, noise ); + noise = enchantment_cache->modify_value( enchant_vals::mod::SHOUT_NOISE, noise ); // Screaming underwater is not good for oxygen and harder to do overall if( underwater ) { @@ -8436,7 +8451,8 @@ void Character::vomit() } if( !has_effect( effect_nausea ) ) { // Prevents never-ending nausea - const effect dummy_nausea( &effect_nausea.obj(), 0_turns, num_bp, false, 1, calendar::turn ); + const effect dummy_nausea( &effect_nausea.obj(), 0_turns, bodypart_str_id( "bp_null" ), false, 1, + calendar::turn ); add_effect( effect_nausea, std::max( dummy_nausea.get_max_duration() * units::to_milliliter( stomach.contains() ) / 21, dummy_nausea.get_int_dur_factor() ) ); } @@ -8610,12 +8626,12 @@ std::string Character::get_highest_category() const void Character::recalculate_enchantment_cache() { // start by resetting the cache to all inventory items - enchantment_cache = inv.get_active_enchantment_cache( *this ); + *enchantment_cache = inv->get_active_enchantment_cache( *this ); visit_items( [&]( const item * it ) { for( const enchantment &ench : it->get_enchantments() ) { if( ench.is_active( *this, *it ) ) { - enchantment_cache.force_add( ench ); + enchantment_cache->force_add( ench ); } } return VisitResponse::NEXT; @@ -8633,7 +8649,7 @@ void Character::recalculate_enchantment_cache() for( const enchantment_id &ench_id : mut.enchantments ) { const enchantment &ench = ench_id.obj(); if( ench.is_active( *this ) ) { - enchantment_cache.force_add( ench ); + enchantment_cache->force_add( ench ); } } } @@ -8647,7 +8663,7 @@ void Character::recalculate_enchantment_cache() for( const enchantment_id &ench_id : bid->enchantments ) { const enchantment &ench = ench_id.obj(); if( ench.is_active( *this ) ) { - enchantment_cache.force_add( ench ); + enchantment_cache->force_add( ench ); } } } @@ -8656,8 +8672,8 @@ void Character::recalculate_enchantment_cache() double Character::calculate_by_enchantment( double modify, enchant_vals::mod value, bool round_output ) const { - modify += enchantment_cache.get_value_add( value ); - modify *= 1.0 + enchantment_cache.get_value_multiply( value ); + modify += enchantment_cache->get_value_add( value ); + modify *= 1.0 + enchantment_cache->get_value_multiply( value ); if( round_output ) { modify = std::round( modify ); } @@ -8826,7 +8842,7 @@ void Character::absorb_hit( const bodypart_id &bp, damage_instance &dam ) destroy = armor.burn( frd ); int fuel = roll_remainder( frd.fuel_produced ); if( fuel > 0 ) { - add_effect( effect_onfire, time_duration::from_turns( fuel + 1 ), bp->token, false, 0, false, + add_effect( effect_onfire, time_duration::from_turns( fuel + 1 ), bp, false, 0, false, true ); } } @@ -8836,7 +8852,7 @@ void Character::absorb_hit( const bodypart_id &bp, damage_instance &dam ) } if( destroy ) { - if( get_player_character().sees( *this ) ) { + if( get_player_view().sees( *this ) ) { SCT.add( point( posx(), posy() ), direction::NORTH, remove_color_tags( pre_damage_name ), m_neutral, _( "destroyed" ), m_info ); } @@ -8977,7 +8993,7 @@ int Character::get_armor_fire( const bodypart_id &bp ) const void Character::did_hit( Creature &target ) { - enchantment_cache.cast_hit_you( *this, target ); + enchantment_cache->cast_hit_you( *this, target ); } ret_val Character::can_wield( const item &it ) const @@ -9037,7 +9053,7 @@ bool Character::unwield() return false; } - inv.unsort(); + inv->unsort(); return true; } @@ -9075,7 +9091,7 @@ std::string Character::weapname() const void Character::on_hit( Creature *source, bodypart_id /*bp_hit*/, float /*difficulty*/, dealt_projectile_attack const *const /*proj*/ ) { - enchantment_cache.cast_hit_me( *this, source ); + enchantment_cache->cast_hit_me( *this, source ); } /* @@ -9112,9 +9128,9 @@ void Character::apply_damage( Creature *source, bodypart_id hurt, int dam, const put_into_vehicle_or_drop( *this, item_drop_reason::tumbling, { weapon } ); i_rem( &weapon ); } - if( has_effect( effect_mending, part_to_damage->token ) && ( source == nullptr || + if( has_effect( effect_mending, part_to_damage.id() ) && ( source == nullptr || !source->is_hallucination() ) ) { - effect &e = get_effect( effect_mending, part_to_damage->token ); + effect &e = get_effect( effect_mending, part_to_damage ); float remove_mend = dam / 20.0f; e.mod_duration( -e.get_max_duration() * remove_mend ); } @@ -9126,10 +9142,10 @@ void Character::apply_damage( Creature *source, bodypart_id hurt, int dam, const if( !bypass_med ) { // remove healing effects if damaged int remove_med = roll_remainder( dam / 5.0f ); - if( remove_med > 0 && has_effect( effect_bandaged, part_to_damage->token ) ) { + if( remove_med > 0 && has_effect( effect_bandaged, part_to_damage.id() ) ) { remove_med -= reduce_healing_effect( effect_bandaged, remove_med, part_to_damage ); } - if( remove_med > 0 && has_effect( effect_disinfected, part_to_damage->token ) ) { + if( remove_med > 0 && has_effect( effect_disinfected, part_to_damage.id() ) ) { reduce_healing_effect( effect_disinfected, remove_med, part_to_damage ); } } @@ -9148,7 +9164,7 @@ dealt_damage_instance Character::deal_damage( Creature *source, bodypart_id bp, int dam = dealt_dams.total_damage(); // TODO: Pre or post blit hit tile onto "this"'s location here - if( dam > 0 && get_player_character().sees( pos() ) ) { + if( dam > 0 && get_player_view().sees( pos() ) ) { g->draw_hit_player( *this, dam ); if( is_player() && source ) { @@ -9248,7 +9264,7 @@ dealt_damage_instance Character::deal_damage( Creature *source, bodypart_id bp, } } else { int prev_effect = get_effect_int( effect_grabbed ); - add_effect( effect_grabbed, 2_turns, bp_torso, false, prev_effect + 2 ); + add_effect( effect_grabbed, 2_turns, bodypart_id( "torso" ), false, prev_effect + 2 ); source->add_effect( effect_grabbing, 2_turns ); add_msg_player_or_npc( m_bad, _( "You are grabbed by %s!" ), _( " is grabbed by %s!" ), source->disp_name() ); @@ -9271,12 +9287,12 @@ dealt_damage_instance Character::deal_damage( Creature *source, bodypart_id bp, const int combined_dam = dealt_dams.type_damage( DT_BASH ) + ( cut_type_dam * 4 ); const int infection_chance = ( combined_dam * sum_cover ) / 100; if( x_in_y( infection_chance, 100 ) ) { - if( has_effect( effect_bite, bp->token ) ) { - add_effect( effect_bite, 40_minutes, bp->token, true ); - } else if( has_effect( effect_infected, bp->token ) ) { - add_effect( effect_infected, 25_minutes, bp->token, true ); + if( has_effect( effect_bite, bp.id() ) ) { + add_effect( effect_bite, 40_minutes, bp, true ); + } else if( has_effect( effect_infected, bp.id() ) ) { + add_effect( effect_infected, 25_minutes, bp, true ); } else { - add_effect( effect_bite, 1_turns, bp->token, true ); + add_effect( effect_bite, 1_turns, bp, true ); } add_msg_if_player( _( "Filth from your clothing has implanted deep in the wound." ) ); } @@ -9289,7 +9305,7 @@ dealt_damage_instance Character::deal_damage( Creature *source, bodypart_id bp, int Character::reduce_healing_effect( const efftype_id &eff_id, int remove_med, const bodypart_id &hurt ) { - effect &e = get_effect( eff_id, hurt->token ); + effect &e = get_effect( eff_id, hurt ); int intensity = e.get_intensity(); if( remove_med < intensity ) { if( eff_id == effect_bandaged ) { @@ -9492,17 +9508,17 @@ void Character::update_vitamins( const vitamin_id &vit ) remove_effect( exc ); } if( lvl > 0 ) { - if( has_effect( def, num_bp ) ) { - get_effect( def, num_bp ).set_intensity( lvl, true ); + if( has_effect( def ) ) { + get_effect( def ).set_intensity( lvl, true ); } else { - add_effect( def, 1_turns, num_bp, true, lvl ); + add_effect( def, 1_turns, true, lvl ); } } if( lvl < 0 ) { - if( has_effect( exc, num_bp ) ) { - get_effect( exc, num_bp ).set_intensity( -lvl, true ); + if( has_effect( exc ) ) { + get_effect( exc ).set_intensity( -lvl, true ); } else { - add_effect( exc, 1_turns, num_bp, true, -lvl ); + add_effect( exc, 1_turns, true, -lvl ); } } } @@ -9644,7 +9660,7 @@ std::vector Character::inv_dump() for( auto &i : worn ) { ret.push_back( &i ); } - inv.dump( ret ); + inv->dump( ret ); return ret; } @@ -9876,9 +9892,10 @@ void Character::check_and_recover_morale() test_morale.on_mutation_gain( mut ); } - for( std::pair>> &elem : + for( std::pair>> + &elem : *effects ) { - for( std::pair &_effect_it : elem.second ) { + for( std::pair &_effect_it : elem.second ) { const effect &e = _effect_it.second; test_morale.on_effect_int_change( e.get_id(), e.get_intensity(), e.get_bp() ); } @@ -10049,7 +10066,7 @@ void Character::fall_asleep( const time_duration &duration ) void Character::migrate_items_to_storage( bool disintegrate ) { - inv.visit_items( [&]( const item * it ) { + inv->visit_items( [&]( const item * it ) { if( disintegrate ) { if( try_add( *it ) == nullptr ) { debugmsg( "ERROR: Could not put %s into inventory. Check if the profession has enough space.", @@ -10061,7 +10078,7 @@ void Character::migrate_items_to_storage( bool disintegrate ) } return VisitResponse::SKIP; } ); - inv.clear(); + inv->clear(); } std::string Character::is_snuggling() const @@ -10127,7 +10144,7 @@ int Character::warmth( const bodypart_id &bp ) const ret += std::round( warmth ); } } - ret += get_effect_int( effect_heating_bionic, bp->token ); + ret += get_effect_int( effect_heating_bionic, bp ); return ret; } @@ -10351,7 +10368,7 @@ std::list Character::use_amount( const itype_id &it, int quantity, if( quantity <= 0 ) { return ret; } - std::list tmp = inv.use_amount( it, quantity, filter ); + std::list tmp = inv->use_amount( it, quantity, filter ); ret.splice( ret.end(), tmp ); return ret; } @@ -10648,7 +10665,7 @@ void Character::on_item_takeoff( const item &it ) morale->on_item_takeoff( it ); } -void Character::on_effect_int_change( const efftype_id &eid, int intensity, body_part bp ) +void Character::on_effect_int_change( const efftype_id &eid, int intensity, const bodypart_id &bp ) { // Adrenaline can reduce perceived pain (or increase it when you enter comedown). // See @ref get_perceived_pain() @@ -10663,7 +10680,7 @@ void Character::on_effect_int_change( const efftype_id &eid, int intensity, body void Character::on_mutation_gain( const trait_id &mid ) { morale->on_mutation_gain( mid ); - magic.on_mutation_gain( mid, *this ); + magic->on_mutation_gain( mid, *this ); update_type_of_scent( mid ); recalculate_enchantment_cache(); // mutations can have enchantments } @@ -10671,7 +10688,7 @@ void Character::on_mutation_gain( const trait_id &mid ) void Character::on_mutation_loss( const trait_id &mid ) { morale->on_mutation_loss( mid ); - magic.on_mutation_loss( mid ); + magic->on_mutation_loss( mid ); update_type_of_scent( mid, false ); recalculate_enchantment_cache(); // mutations can have enchantments } @@ -11399,28 +11416,61 @@ int Character::intimidation() const if( has_effect( effect_drunk ) ) { ret -= 4; } - ret = enchantment_cache.modify_value( enchant_vals::mod::SOCIAL_INTIMIDATE, ret ); + ret = enchantment_cache->modify_value( enchant_vals::mod::SOCIAL_INTIMIDATE, ret ); return ret; } bool Character::has_proficiency( const proficiency_id &prof ) const { - return _proficiencies.count( prof ); + return _proficiencies->has_learned( prof ); } void Character::add_proficiency( const proficiency_id &prof ) { - _proficiencies.insert( prof ); + _proficiencies->learn( prof ); } void Character::lose_proficiency( const proficiency_id &prof ) { - _proficiencies.erase( prof ); + _proficiencies->remove( prof ); +} + +std::vector Character::display_proficiencies() const +{ + return _proficiencies->display(); +} + +void Character::practice_proficiency( const proficiency_id &prof, const time_duration amount, + const cata::optional max ) +{ + int amt = to_seconds( amount ); + const float pct_before = _proficiencies->pct_practiced( prof ); + time_duration focused_amount = time_duration::from_seconds( adjust_for_focus( amt ) ); + const bool learned = _proficiencies->practice( prof, focused_amount, max ); + const float pct_after = _proficiencies->pct_practiced( prof ); + + if( pct_after > pct_before ) { + focus_pool -= focus_pool / 100; + } + + if( learned ) { + add_msg_if_player( m_good, _( "You are now proficient in %s" ), prof->name() ); + } +} + +time_duration Character::proficiency_training_needed( const proficiency_id &prof ) const +{ + return _proficiencies->training_time_needed( prof ); +} + +std::vector Character::known_proficiencies() const +{ + return _proficiencies->known_profs(); } -const std::set &Character::proficiencies() const +std::vector Character::learning_proficiencies() const { - return _proficiencies; + return _proficiencies->learning_profs(); } bool Character::defer_move( const tripoint &next ) diff --git a/src/character.h b/src/character.h index eabc4e9f73238..622a52a36c47c 100644 --- a/src/character.h +++ b/src/character.h @@ -18,26 +18,17 @@ #include #include -#include "bodypart.h" #include "calendar.h" #include "cata_utility.h" #include "character_id.h" -#include "character_martial_arts.h" -#include "color.h" #include "coordinates.h" #include "creature.h" #include "damage.h" #include "enums.h" #include "flat_set.h" #include "game_constants.h" -#include "inventory.h" -#include "item.h" #include "item_location.h" -#include "magic.h" -#include "magic_enchantment.h" #include "memory_fast.h" -#include "monster.h" -#include "mtype.h" #include "optional.h" #include "pimpl.h" #include "player_activity.h" @@ -50,32 +41,43 @@ #include "units.h" #include "visitable.h" #include "weighted_list.h" -#include "weather_gen.h" -class JsonIn; -class JsonObject; -class JsonOut; -class SkillLevel; -class SkillLevelMap; class basecamp; class bionic_collection; +class character_martial_arts; class faction; +class JsonIn; +class JsonObject; +class JsonOut; +class known_magic; +class monster; +class nc_color; +class npc; class player; class player_morale; +class proficiency_set; +class recipe_subset; +class SkillLevel; +class SkillLevelMap; class vehicle; + struct bionic; struct construction; struct dealt_projectile_attack; +struct display_proficiency; /// @brief Item slot used to apply modifications from food and meds struct islot_comestible; struct itype; -class recipe_subset; struct mutation_branch; struct needs_rates; struct pathfinding_settings; struct points_left; +struct w_point; + template struct enum_traits; + enum npc_attitude : int; +enum action_id : int; static const std::string DEFAULT_HOTKEYS( "1234567890abcdefghijklmnopqrstuvwxyz" ); @@ -635,11 +637,6 @@ class Character : public Creature, public visitable virtual void set_movement_mode( const move_mode_id &mode ) = 0; - /** Performs any Character-specific modifications to the arguments before passing to Creature::add_effect(). */ - void add_effect( const efftype_id &eff_id, const time_duration &dur, body_part bp = num_bp, - bool permanent = false, - int intensity = 0, bool force = false, bool deferred = false ) override; - /**Determine if character is susceptible to dis_type and if so apply the symptoms*/ void expose_to_disease( const diseasetype_id &dis_type ); /** @@ -1005,9 +1002,7 @@ class Character : public Creature, public visitable /** Returns true if the player has any martial arts buffs attached */ bool has_mabuff( const mabuff_id &buff_id ) const; /** Returns true if the player has a grab breaking technique available */ - bool has_grab_break_tec() const override { - return martial_arts_data.has_grab_break_tec(); - } + bool has_grab_break_tec() const override; /** Returns the to hit bonus from martial arts buffs */ float mabuff_tohit_bonus() const; @@ -1294,6 +1289,17 @@ class Character : public Creature, public visitable int item_store_cost( const item &it, const item &container, bool penalties = true, int base_cost = INVENTORY_HANDLING_PENALTY ) const; + /** + * Calculate (but do not deduct) the number of moves required when drawing a weapon from an holster or sheathe + * @param it Item to calculate retrieve cost for + * @param container Container where the item is + * @param penalties Whether item volume and temporary effects (e.g. GRABBED, DOWNED) should be considered. + * @param base_cost Cost due to storage type. + * @return cost in moves ranging from 0 to MAX_HANDLING_COST + */ + int item_retrieve_cost( const item &it, const item &container, bool penalties = true, + int base_cost = INVENTORY_HANDLING_PENALTY ) const; + /** Calculate (but do not deduct) the number of moves required to wear an item */ int item_wear_cost( const item &it ) const; @@ -1597,11 +1603,16 @@ class Character : public Creature, public visitable int intimidation() const; // --------------- Proficiency Stuff ---------------- - // (bit short at the moment) bool has_proficiency( const proficiency_id &prof ) const; void add_proficiency( const proficiency_id &prof ); void lose_proficiency( const proficiency_id &prof ); - const std::set &proficiencies() const; + void practice_proficiency( const proficiency_id &prof, time_duration amount, + cata::optional max = cata::nullopt ); + time_duration proficiency_training_needed( const proficiency_id &prof ) const; + std::vector display_proficiencies() const; + std::vector known_proficiencies() const; + std::vector learning_proficiencies() const; + // --------------- Other Stuff --------------- @@ -1616,7 +1627,7 @@ class Character : public Creature, public visitable } } // magic mod - known_magic magic; + pimpl magic; void make_bleed( const bodypart_id &bp, time_duration duration, int intensity = 1, bool permanent = false, @@ -1727,13 +1738,13 @@ class Character : public Creature, public visitable player_activity activity; std::list backlog; cata::optional destination_point; - inventory inv; + pimpl inv; itype_id last_item; item weapon; int scent = 0; pimpl my_bionics; - character_martial_arts martial_arts_data; + pimpl martial_arts_data; stomach_contents stomach; stomach_contents guts; @@ -1924,7 +1935,8 @@ class Character : public Creature, public visitable /** Called when an item is washed */ void on_worn_item_washed( const item &it ); /** Called when effect intensity has been changed */ - void on_effect_int_change( const efftype_id &eid, int intensity, body_part bp = num_bp ) override; + void on_effect_int_change( const efftype_id &eid, int intensity, + const bodypart_id &bp = bodypart_id( "bp_null" ) ) override; /** Called when a mutation is gained */ void on_mutation_gain( const trait_id &mid ); /** Called when a mutation is lost */ @@ -2100,9 +2112,9 @@ class Character : public Creature, public visitable * Recharge CBMs whenever possible. * @return true when recharging was successful. */ - bool feed_reactor_with( item &it ); - bool feed_furnace_with( item &it ); - bool fuel_bionic_with( item &it ); + bool feed_reactor_with( item &it, item_pocket *parent_pocket ); + bool feed_furnace_with( item &it, item_pocket *parent_pocket ); + bool fuel_bionic_with( item &it, item_pocket *parent_pocket ); /** Used to apply stimulation modifications from food and medication **/ void modify_stimulation( const islot_comestible &comest ); /** Used to apply fatigue modifications from food and medication **/ @@ -2307,6 +2319,12 @@ class Character : public Creature, public visitable * multiple steps of incremental skill gain simultaneously if needed. */ void craft_skill_gain( const item &craft, const int &multiplier ); + /** + * Handle proficiency practice for player and followers while crafting + * @param craft - the in progress craft + * @param time - the amount of time since the last practice tick + */ + void craft_proficiency_gain( const item &craft, time_duration time ); /** * Check if the player can disassemble an item using the current crafting inventory * @param obj Object to check for disassembly @@ -2488,7 +2506,7 @@ class Character : public Creature, public visitable // --------------- Values --------------- pimpl _skills; - std::set _proficiencies; + pimpl _proficiencies; // Cached vision values. std::bitset vision_mode_cache; @@ -2550,7 +2568,7 @@ class Character : public Creature, public visitable // a cache of all active enchantment values. // is recalculated every turn in Character::recalculate_enchantment_cache - enchantment enchantment_cache; + pimpl enchantment_cache; player_activity destination_activity; /// A unique ID number, assigned by the game class. Values should never be reused. character_id id; @@ -2584,7 +2602,7 @@ class Character : public Creature, public visitable int cached_moves; tripoint cached_position; - inventory cached_crafting_inventory; + pimpl cached_crafting_inventory; protected: /** Subset of learned recipes. Needs to be mutable for lazy initialization. */ diff --git a/src/character_crafting.cpp b/src/character_crafting.cpp index c51d029860da8..60242c4120bce 100644 --- a/src/character_crafting.cpp +++ b/src/character_crafting.cpp @@ -104,7 +104,7 @@ recipe_subset Character::get_available_recipes( const inventory &crafting_inv, if( helpers != nullptr ) { for( npc *np : *helpers ) { // Directly form the helper's inventory - res.include( get_recipes_from_books( np->inv ) ); + res.include( get_recipes_from_books( *np->inv ) ); // Being told what to do res.include_if( np->get_learned_recipes(), [ this ]( const recipe & r ) { return get_skill_level( r.skill_used ) >= static_cast( r.difficulty * @@ -123,7 +123,7 @@ std::set Character::get_books_for_recipe( const inventory &crafting_in const int skill_level = get_skill_level( r->skill_used ); for( const auto &book_lvl : r->booksets ) { itype_id book_id = book_lvl.first; - int required_skill_level = book_lvl.second; + int required_skill_level = book_lvl.second.skill_req; // NPCs don't need to identify books if( !has_identified( book_id ) ) { continue; diff --git a/src/consumption.cpp b/src/consumption.cpp index 3cde72e818ea3..cf5ab54ea39a3 100644 --- a/src/consumption.cpp +++ b/src/consumption.cpp @@ -859,7 +859,7 @@ ret_val Character::will_eat( const item &food, bool interactive ) return ret_val::make_success(); } -static bool eat( item &food, player &you, bool force = false ) +static bool eat( item &food, player &you, bool force, item_pocket *const parent_pocket ) { if( !food.is_food() ) { return false; @@ -922,10 +922,16 @@ static bool eat( item &food, player &you, bool force = false ) if( !you.consume_effects( food ) ) { // Already consumed by using `food.type->invoke`? if( charges_used > 0 ) { + if( parent_pocket ) { + parent_pocket->unseal(); + } food.mod_charges( -charges_used ); } return false; } + if( parent_pocket ) { + parent_pocket->unseal(); + } food.mod_charges( -1 ); const bool amorphous = you.has_trait( trait_AMORPHOUS ); @@ -982,7 +988,7 @@ static bool eat( item &food, player &you, bool force = false ) } if( food.has_flag( flag_FUNGAL_VECTOR ) && !you.has_trait( trait_M_IMMUNE ) ) { - you.add_effect( effect_fungus, 1_turns, num_bp, true ); + you.add_effect( effect_fungus, 1_turns, true ); } // The fun changes for these effects are applied in fun_for(). @@ -1006,19 +1012,19 @@ static bool eat( item &food, player &you, bool force = false ) switch( rng( 0, 3 ) ) { case 0: if( !you.has_trait( trait_EATHEALTH ) ) { - you.add_effect( effect_tapeworm, 1_turns, num_bp, true ); + you.add_effect( effect_tapeworm, 1_turns, true ); } break; case 1: if( !you.has_trait( trait_ACIDBLOOD ) ) { - you.add_effect( effect_bloodworms, 1_turns, num_bp, true ); + you.add_effect( effect_bloodworms, 1_turns, true ); } break; case 2: - you.add_effect( effect_brainworms, 1_turns, num_bp, true ); + you.add_effect( effect_brainworms, 1_turns, true ); break; case 3: - you.add_effect( effect_paincysts, 1_turns, num_bp, true ); + you.add_effect( effect_paincysts, 1_turns, true ); } } } @@ -1411,7 +1417,7 @@ bool Character::can_feed_reactor_with( const item &it ) const } ); } -bool Character::feed_reactor_with( item &it ) +bool Character::feed_reactor_with( item &it, item_pocket *const parent_pocket ) { if( !can_feed_reactor_with( it ) ) { return false; @@ -1432,6 +1438,9 @@ bool Character::feed_reactor_with( item &it ) // TODO: Encapsulate tank_plut += amount; + if( parent_pocket ) { + parent_pocket->unseal(); + } it.charges -= 1; mod_moves( -250 ); return true; @@ -1455,7 +1464,7 @@ bool Character::can_feed_furnace_with( const item &it ) const return !it.has_flag( flag_CORPSE ); } -bool Character::feed_furnace_with( item &it ) +bool Character::feed_furnace_with( item &it, item_pocket *const parent_pocket ) { if( !can_feed_furnace_with( it ) ) { return false; @@ -1507,13 +1516,16 @@ bool Character::feed_furnace_with( item &it ) mod_power_level( units::from_kilojoule( profitable_energy ) ); } + if( parent_pocket ) { + parent_pocket->unseal(); + } it.charges -= consumed_charges; mod_moves( -250 ); return true; } -bool Character::fuel_bionic_with( item &it ) +bool Character::fuel_bionic_with( item &it, item_pocket *const parent_pocket ) { if( !can_fuel_bionic_with( it ) ) { return false; @@ -1524,6 +1536,9 @@ bool Character::fuel_bionic_with( item &it ) const bool is_magazine = !!it.type->magazine; std::string item_name = it.tname(); itype_id item_type = it.typeId(); + if( parent_pocket ) { + parent_pocket->unseal(); + } int loadable; if( is_magazine ) { const item ammo = item( it.ammo_current() ); @@ -1766,7 +1781,7 @@ static bool query_consume_ownership( item &target, player &p ) } // TODO: Properly split medications and food instead of hacking around -static bool consume_med( item &target, player &you ) +static bool consume_med( item &target, player &you, item_pocket *const parent_pocket ) { if( !target.is_medication() ) { return false; @@ -1812,11 +1827,14 @@ static bool consume_med( item &target, player &you ) you.consume_effects( target ); } + if( parent_pocket ) { + parent_pocket->unseal(); + } target.charges -= amount_used; return target.charges <= 0; } -bool player::consume( item &target, bool force ) +bool player::consume( item &target, bool force, item_pocket *const parent_pocket ) { if( target.is_null() ) { add_msg_if_player( m_info, _( "You do not have that item." ) ); @@ -1840,9 +1858,11 @@ bool player::consume( item &target, bool force ) if( is_player() && !query_consume_ownership( target, *this ) ) { return false; } - if( consume_med( comest, *this ) || - eat( comest, *this, force ) || feed_reactor_with( comest ) || feed_furnace_with( comest ) || - fuel_bionic_with( comest ) ) { + if( consume_med( comest, *this, parent_pocket ) || + eat( comest, *this, force, parent_pocket ) || + feed_reactor_with( comest, parent_pocket ) || + feed_furnace_with( comest, parent_pocket ) || + fuel_bionic_with( comest, parent_pocket ) ) { if( &target != &comest ) { target.on_contents_changed(); @@ -1861,10 +1881,14 @@ bool player::consume( item_location loc, bool force ) return false; } item &target = *loc; + item_pocket *parent_pocket = nullptr; + if( loc.has_parent() ) { + parent_pocket = loc.parent_item()->contained_where( target ); + } bool wielding = is_wielding( target ); bool worn = is_worn( target ); const bool inv_item = !( wielding || worn ); - if( consume( target, force ) ) { + if( consume( target, force, parent_pocket ) ) { if( loc.where() == item_location::type::character ) { i_rem( loc.get_item() ); } else { @@ -1875,8 +1899,8 @@ bool player::consume( item_location loc, bool force ) if( Pickup::handle_spillable_contents( *this, target, get_map() ) ) { i_rem( &target ); } - inv.restack( *this ); - inv.unsort(); + inv->restack( *this ); + inv->unsort(); } return true; diff --git a/src/crafting.cpp b/src/crafting.cpp index 91a6d9097674c..fecad446a101c 100644 --- a/src/crafting.cpp +++ b/src/crafting.cpp @@ -56,6 +56,7 @@ #include "player.h" #include "player_activity.h" #include "point.h" +#include "proficiency.h" #include "recipe.h" #include "recipe_dictionary.h" #include "requirements.h" @@ -461,8 +462,8 @@ std::vector Character::get_eligible_containers_for_crafting() cons conts.push_back( &it ); } } - for( size_t i = 0; i < inv.size(); i++ ) { - for( const auto &it : inv.const_stack( i ) ) { + for( size_t i = 0; i < inv->size(); i++ ) { + for( const auto &it : inv->const_stack( i ) ) { if( is_container_eligible_for_crafting( it, false ) ) { conts.push_back( &it ); } @@ -543,36 +544,36 @@ const inventory &Character::crafting_inventory( const tripoint &src_pos, int rad if( cached_moves == moves && cached_time == calendar::turn && cached_position == inv_pos ) { - return cached_crafting_inventory; + return *cached_crafting_inventory; } - cached_crafting_inventory.clear(); - cached_crafting_inventory.form_from_map( inv_pos, radius, this, false, clear_path ); + cached_crafting_inventory->clear(); + cached_crafting_inventory->form_from_map( inv_pos, radius, this, false, clear_path ); for( const item_location &it : all_items_loc() ) { // can't craft with containers that have items in them if( !it->contents.empty_container() ) { continue; } - cached_crafting_inventory.add_item( *it ); + cached_crafting_inventory->add_item( *it ); } for( const bionic &bio : *my_bionics ) { const bionic_data &bio_data = bio.info(); if( ( !bio_data.activated || bio.powered ) && !bio_data.fake_item.is_empty() ) { - cached_crafting_inventory += item( bio.info().fake_item, - calendar::turn, units::to_kilojoule( get_power_level() ) ); + *cached_crafting_inventory += item( bio.info().fake_item, + calendar::turn, units::to_kilojoule( get_power_level() ) ); } } if( has_trait( trait_BURROW ) ) { - cached_crafting_inventory += item( "pickaxe", calendar::turn ); - cached_crafting_inventory += item( "shovel", calendar::turn ); + *cached_crafting_inventory += item( "pickaxe", calendar::turn ); + *cached_crafting_inventory += item( "shovel", calendar::turn ); } cached_moves = moves; cached_time = calendar::turn; cached_position = inv_pos; - return cached_crafting_inventory; + return *cached_crafting_inventory; } void Character::invalidate_crafting_inventory() @@ -648,7 +649,7 @@ static item *set_item_inventory( Character &p, item &newit ) if( newit.made_of( phase_id::LIQUID ) ) { liquid_handler::handle_all_liquid( newit, PICKUP_RANGE ); } else { - p.inv.assign_empty_invlet( newit, p ); + p.inv->assign_empty_invlet( newit, p ); // We might not have space for the item if( !p.can_pickVolume( newit ) ) { //Accounts for result_mult put_into_vehicle_or_drop( p, item_drop_reason::too_large, { newit } ); @@ -893,6 +894,50 @@ void Character::craft_skill_gain( const item &craft, const int &multiplier ) } } +void Character::craft_proficiency_gain( const item &craft, const time_duration time ) +{ + if( !craft.is_craft() ) { + debugmsg( "craft_proficiency_gain() called on non-craft %s", craft.tname() ); + return; + } + + const recipe &making = craft.get_making(); + std::vector helpers = get_crafting_helpers(); + + // The proficiency, and the multiplier on the time we learn it for + std::vector>> subjects; + for( const recipe_proficiency &prof : making.proficiencies ) { + if( prof.id->can_learn() && _proficiencies->has_prereqs( prof.id ) ) { + std::tuple> subject( prof.id, + prof.learning_time_mult / prof.time_multiplier, prof.max_experience ); + subjects.push_back( subject ); + } + } + + int amount = to_seconds( time ); + if( !subjects.empty() ) { + amount /= subjects.size(); + } + time_duration learn_time = time_duration::from_seconds( amount ); + + int npc_helper_bonus = 1; + for( npc *helper : helpers ) { + for( const std::tuple> &subject : subjects ) { + if( helper->has_proficiency( std::get<0>( subject ) ) ) { + // NPCs who know the proficiency and help teach you faster + npc_helper_bonus = 2; + } + helper->practice_proficiency( std::get<0>( subject ), std::get<1>( subject ) * learn_time, + std::get<2>( subject ) ); + } + } + + for( const std::tuple> &subject : subjects ) { + practice_proficiency( std::get<0>( subject ), + learn_time * std::get<1>( subject ) * npc_helper_bonus, std::get<2>( subject ) ); + } +} + double Character::crafting_success_roll( const recipe &making ) const { int secondary_dice = 0; @@ -1264,7 +1309,7 @@ void Character::complete_craft( item &craft, const tripoint &loc ) } } - inv.restack( *this ); + inv->restack( *this ); } bool Character::can_continue_craft( item &craft ) diff --git a/src/creature.cpp b/src/creature.cpp index 41907c24ddcfa..a4b02868b7597 100644 --- a/src/creature.cpp +++ b/src/creature.cpp @@ -7,7 +7,6 @@ #include #include "anatomy.h" -#include "avatar.h" #include "calendar.h" #include "character.h" #include "color.h" @@ -35,7 +34,6 @@ #include "npc.h" #include "optional.h" #include "output.h" -#include "player.h" #include "pldata.h" #include "point.h" #include "projectile.h" @@ -597,8 +595,8 @@ void Creature::deal_projectile_attack( Creature *source, dealt_projectile_attack dealt_damage_instance &dealt_dam = attack.dealt_dam; const auto &proj_effects = proj.proj_effects; - Character &player_character = get_player_character(); - const bool u_see_this = player_character.sees( *this ); + viewer &player_view = get_player_view(); + const bool u_see_this = player_view.sees( *this ); const int avoid_roll = dodge_roll(); // Do dice(10, speed) instead of dice(speed, 10) because speed could potentially be > 10000 @@ -614,7 +612,7 @@ void Creature::deal_projectile_attack( Creature *source, dealt_projectile_attack } // "Avoid" rather than "dodge", because it includes removing self from the line of fire // rather than just Matrix-style bullet dodging - if( source != nullptr && player_character.sees( *source ) ) { + if( source != nullptr && player_view.sees( *source ) ) { add_msg_player_or_npc( m_warning, _( "You avoid %s projectile!" ), @@ -715,13 +713,13 @@ void Creature::deal_projectile_attack( Creature *source, dealt_projectile_attack // Apply ammo effects to target. if( proj.proj_effects.count( "TANGLE" ) ) { monster *z = dynamic_cast( this ); - player *n = dynamic_cast( this ); + Character *n = dynamic_cast( this ); // if its a tameable animal, its a good way to catch them if they are running away, like them ranchers do! // we assume immediate success, then certain monster types immediately break free in monster.cpp move_effects() if( z ) { const item &drop_item = proj.get_drop(); if( !drop_item.is_null() ) { - z->add_effect( effect_tied, 1_turns, num_bp, true ); + z->add_effect( effect_tied, 1_turns, true ); z->tied_item = cata::make_value( drop_item ); } else { add_msg( m_debug, "projectile with TANGLE effect, but no drop item specified" ); @@ -736,15 +734,15 @@ void Creature::deal_projectile_attack( Creature *source, dealt_projectile_attack } if( proj.proj_effects.count( "INCENDIARY" ) ) { if( made_of( material_id( "veggy" ) ) || made_of_any( cmat_flammable ) ) { - add_effect( effect_onfire, rng( 2_turns, 6_turns ), bp_hit->token ); + add_effect( effect_onfire, rng( 2_turns, 6_turns ), bp_hit ); } else if( made_of_any( cmat_flesh ) && one_in( 4 ) ) { - add_effect( effect_onfire, rng( 1_turns, 4_turns ), bp_hit->token ); + add_effect( effect_onfire, rng( 1_turns, 4_turns ), bp_hit ); } } else if( proj.proj_effects.count( "IGNITE" ) ) { if( made_of( material_id( "veggy" ) ) || made_of_any( cmat_flammable ) ) { - add_effect( effect_onfire, 6_turns, bp_hit->token ); + add_effect( effect_onfire, 6_turns, bp_hit ); } else if( made_of_any( cmat_flesh ) ) { - add_effect( effect_onfire, 10_turns, bp_hit->token ); + add_effect( effect_onfire, 10_turns, bp_hit ); } } @@ -760,7 +758,7 @@ void Creature::deal_projectile_attack( Creature *source, dealt_projectile_attack if( bp_hit == bodypart_id( "head" ) && proj_effects.count( "BLINDS_EYES" ) ) { // TODO: Change this to require bp_eyes - add_env_effect( effect_blind, bp_eyes, 5, rng( 3_turns, 10_turns ) ); + add_env_effect( effect_blind, bodypart_id( "eyes" ), 5, rng( 3_turns, 10_turns ) ); } if( proj_effects.count( "APPLY_SAP" ) ) { @@ -903,7 +901,7 @@ void Creature::deal_damage_handle_type( const damage_unit &du, bodypart_id bp, i case DT_HEAT: // heat damage sets us on fire sometimes if( rng( 0, 100 ) < adjusted_damage ) { - add_effect( effect_onfire, rng( 1_turns, 3_turns ), bp->token ); + add_effect( effect_onfire, rng( 1_turns, 3_turns ), bp ); } break; @@ -924,7 +922,7 @@ void Creature::deal_damage_handle_type( const damage_unit &du, bodypart_id bp, i if( is_avatar() || is_npc() ) { as_character()->make_bleed( bp, 1_minutes * rng( 1, adjusted_damage ) ); } else { - add_effect( effect_bleed, 1_minutes * rng( 1, adjusted_damage ), bp->token ); + add_effect( effect_bleed, 1_minutes * rng( 1, adjusted_damage ), bp ); } default: @@ -967,11 +965,12 @@ void Creature::set_fake( const bool fake_value ) void Creature::add_effect( const effect &eff, bool force, bool deferred ) { - add_effect( eff.get_id(), eff.get_duration(), eff.get_bp(), eff.is_permanent(), eff.get_intensity(), + add_effect( eff.get_id(), eff.get_duration(), eff.get_bp(), eff.is_permanent(), + eff.get_intensity(), force, deferred ); } -void Creature::add_effect( const efftype_id &eff_id, const time_duration &dur, body_part bp, +void Creature::add_effect( const efftype_id &eff_id, const time_duration &dur, bodypart_id bp, bool permanent, int intensity, bool force, bool deferred ) { // Check our innate immunity @@ -994,7 +993,7 @@ void Creature::add_effect( const efftype_id &eff_id, const time_duration &dur, b // Mutate to a main (HP'd) body_part if necessary. if( type.get_main_parts() ) { - bp = mutate_to_main_part( bp ); + bp = bp->main_part; } bool found = false; @@ -1002,7 +1001,7 @@ void Creature::add_effect( const efftype_id &eff_id, const time_duration &dur, b auto matching_map = effects->find( eff_id ); if( matching_map != effects->end() ) { auto &bodyparts = matching_map->second; - auto found_effect = bodyparts.find( bp ); + auto found_effect = bodyparts.find( bp.id() ); if( found_effect != bodyparts.end() ) { found = true; effect &e = found_effect->second; @@ -1057,7 +1056,7 @@ void Creature::add_effect( const efftype_id &eff_id, const time_duration &dur, b } // Now we can make the new effect for application - effect e( &type, dur, bp, permanent, intensity, calendar::turn ); + effect e( &type, dur, bp.id(), permanent, intensity, calendar::turn ); // Bound to max duration if( e.get_max_duration() > 0_turns && e.get_duration() > e.get_max_duration() ) { e.set_duration( e.get_max_duration() ); @@ -1075,7 +1074,7 @@ void Creature::add_effect( const efftype_id &eff_id, const time_duration &dur, b } else if( e.get_intensity() > e.get_max_intensity() ) { e.set_intensity( e.get_max_intensity() ); } - ( *effects )[eff_id][bp] = e; + ( *effects )[eff_id][bp.id()] = e; if( Character *ch = as_character() ) { get_event_bus().send( ch->getID(), eff_id ); if( is_player() && !type.get_apply_message().empty() ) { @@ -1090,14 +1089,19 @@ void Creature::add_effect( const efftype_id &eff_id, const time_duration &dur, b } } } -bool Creature::add_env_effect( const efftype_id &eff_id, body_part vector, int strength, - const time_duration &dur, body_part bp, bool permanent, int intensity, bool force ) +void Creature::add_effect( const efftype_id &eff_id, const time_duration &dur, bool permanent, + int intensity, bool force, bool deferred ) +{ + add_effect( eff_id, dur, bodypart_id( "bp_null" ), permanent, intensity, force, deferred ); +} +bool Creature::add_env_effect( const efftype_id &eff_id, const bodypart_id &vector, int strength, + const time_duration &dur, const bodypart_id &bp, bool permanent, int intensity, bool force ) { if( !force && is_immune_effect( eff_id ) ) { return false; } - if( dice( strength, 3 ) > dice( get_env_resist( convert_bp( vector ).id() ), 3 ) ) { + if( dice( strength, 3 ) > dice( get_env_resist( vector ), 3 ) ) { // Only add the effect if we fail the resist roll // Don't check immunity (force == true), because we did check above add_effect( eff_id, dur, bp, permanent, intensity, true ); @@ -1106,6 +1110,13 @@ bool Creature::add_env_effect( const efftype_id &eff_id, body_part vector, int s return false; } } +bool Creature::add_env_effect( const efftype_id &eff_id, const bodypart_id &vector, int strength, + const time_duration &dur, bool permanent, int intensity, bool force ) +{ + return add_env_effect( eff_id, vector, strength, dur, bodypart_id( "bp_null" ), permanent, + intensity, + force ); +} void Creature::clear_effects() { for( auto &elem : *effects ) { @@ -1116,9 +1127,9 @@ void Creature::clear_effects() } effects->clear(); } -bool Creature::remove_effect( const efftype_id &eff_id, body_part bp ) +bool Creature::remove_effect( const efftype_id &eff_id, const bodypart_id &bp ) { - if( !has_effect( eff_id, bp ) ) { + if( !has_effect( eff_id, bp.id() ) ) { //Effect doesn't exist, so do nothing return false; } @@ -1134,13 +1145,13 @@ bool Creature::remove_effect( const efftype_id &eff_id, body_part bp ) } // num_bp means remove all of a given effect id - if( bp == num_bp ) { + if( bp == bodypart_id( "bp_null" ) ) { for( auto &it : ( *effects )[eff_id] ) { on_effect_int_change( eff_id, 0, it.first ); } effects->erase( eff_id ); } else { - ( *effects )[eff_id].erase( bp ); + ( *effects )[eff_id].erase( bp.id() ); on_effect_int_change( eff_id, 0, bp ); // If there are no more effects of a given type remove the type map if( ( *effects )[eff_id].empty() ) { @@ -1149,10 +1160,14 @@ bool Creature::remove_effect( const efftype_id &eff_id, body_part bp ) } return true; } -bool Creature::has_effect( const efftype_id &eff_id, body_part bp ) const +bool Creature::remove_effect( const efftype_id &eff_id ) +{ + return remove_effect( eff_id, bodypart_id( "bp_null" ) ); +} +bool Creature::has_effect( const efftype_id &eff_id, const bodypart_str_id &bp ) const { // num_bp means anything targeted or not - if( bp == num_bp ) { + if( bp == bodypart_str_id( "bp_null" ) ) { return effects->find( eff_id ) != effects->end(); } else { auto got_outer = effects->find( eff_id ); @@ -1166,11 +1181,28 @@ bool Creature::has_effect( const efftype_id &eff_id, body_part bp ) const } } -bool Creature::has_effect_with_flag( const std::string &flag, body_part bp ) const +bool Creature::has_effect( const efftype_id &eff_id ) const +{ + return has_effect( eff_id, bodypart_str_id( "bp_null" ) ); +} + +bool Creature::has_effect_with_flag( const std::string &flag, const bodypart_id &bp ) const { for( auto &elem : *effects ) { - for( const std::pair &_it : elem.second ) { - if( ( bp == _it.first || bp == num_bp ) && _it.second.has_flag( flag ) ) { + for( const std::pair &_it : elem.second ) { + if( bp == _it.first && _it.second.has_flag( flag ) ) { + return true; + } + } + } + return false; +} + +bool Creature::has_effect_with_flag( const std::string &flag ) const +{ + for( auto &elem : *effects ) { + for( const std::pair &_it : elem.second ) { + if( _it.second.has_flag( flag ) ) { return true; } } @@ -1182,7 +1214,7 @@ std::vector Creature::get_effects_with_flag( const std::string &flag ) c { std::vector effs; for( auto &elem : *effects ) { - for( const std::pair &_it : elem.second ) { + for( const std::pair &_it : elem.second ) { if( _it.second.has_flag( flag ) ) { effs.push_back( _it.second ); } @@ -1191,23 +1223,23 @@ std::vector Creature::get_effects_with_flag( const std::string &flag ) c return effs; } -effect &Creature::get_effect( const efftype_id &eff_id, body_part bp ) +effect &Creature::get_effect( const efftype_id &eff_id, const bodypart_id &bp ) { return const_cast( const_cast( this )->get_effect( eff_id, bp ) ); } -const effect &Creature::get_effect( const efftype_id &eff_id, body_part bp ) const +const effect &Creature::get_effect( const efftype_id &eff_id, const bodypart_id &bp ) const { auto got_outer = effects->find( eff_id ); if( got_outer != effects->end() ) { - auto got_inner = got_outer->second.find( bp ); + auto got_inner = got_outer->second.find( bp.id() ); if( got_inner != got_outer->second.end() ) { return got_inner->second; } } return effect::null_effect; } -time_duration Creature::get_effect_dur( const efftype_id &eff_id, body_part bp ) const +time_duration Creature::get_effect_dur( const efftype_id &eff_id, const bodypart_id &bp ) const { const effect &eff = get_effect( eff_id, bp ); if( !eff.is_null() ) { @@ -1216,7 +1248,7 @@ time_duration Creature::get_effect_dur( const efftype_id &eff_id, body_part bp ) return 0_turns; } -int Creature::get_effect_int( const efftype_id &eff_id, body_part bp ) const +int Creature::get_effect_int( const efftype_id &eff_id, const bodypart_id &bp ) const { const effect &eff = get_effect( eff_id, bp ); if( !eff.is_null() ) { @@ -1231,7 +1263,7 @@ void Creature::process_effects() // monster specific removals these will need to be moved down to that level and then // passed in to this function. std::vector rem_ids; - std::vector rem_bps; + std::vector rem_bps; // Decay/removal of effects for( auto &elem : *effects ) { @@ -1239,7 +1271,7 @@ void Creature::process_effects() // Add any effects that others remove to the removal list for( const auto &removed_effect : _it.second.get_removes_effects() ) { rem_ids.push_back( removed_effect ); - rem_bps.push_back( num_bp ); + rem_bps.push_back( bodypart_id( "bp_null" ) ); } effect &e = _it.second; const int prev_int = e.get_intensity(); @@ -1718,9 +1750,9 @@ void Creature::set_all_parts_hp_to_max() } } -bool Creature::has_atleast_one_wet_part() +bool Creature::has_atleast_one_wet_part() const { - for( std::pair &elem : body ) { + for( const std::pair &elem : body ) { if( elem.second.get_wetness() > 0 ) { return true; } @@ -1728,6 +1760,11 @@ bool Creature::has_atleast_one_wet_part() return false; } +bool Creature::is_part_at_max_hp( const bodypart_id &id ) const +{ + return get_part( id ).is_at_max_hp(); +} + bodypart_id Creature::get_random_body_part( bool main ) const { // TODO: Refuse broken limbs, adjust for mutations diff --git a/src/creature.h b/src/creature.h index e95b2e81d1013..fcb64fbbf9083 100644 --- a/src/creature.h +++ b/src/creature.h @@ -13,14 +13,15 @@ #include "anatomy.h" #include "bodypart.h" #include "damage.h" +#include "debug.h" +#include "enums.h" #include "location.h" #include "pimpl.h" #include "string_formatter.h" #include "translations.h" #include "type_id.h" -#include "units.h" -#include "debug.h" -#include "enums.h" +#include "units_fwd.h" +#include "viewer.h" enum game_message_type : int; class nc_color; @@ -197,7 +198,7 @@ enum class FacingDirection : int { RIGHT = 2 }; -class Creature : public location +class Creature : public location, public viewer { public: ~Creature() override; @@ -320,8 +321,8 @@ class Creature : public location * the other monster is visible. */ /*@{*/ - virtual bool sees( const Creature &critter ) const; - virtual bool sees( const tripoint &t, bool is_avatar = false, int range_mod = 0 ) const; + bool sees( const Creature &critter ) const override; + bool sees( const tripoint &t, bool is_avatar = false, int range_mod = 0 ) const override; /*@}*/ /** @@ -469,32 +470,41 @@ class Creature : public location void add_effect( const effect &eff, bool force = false, bool deferred = false ); /** Adds or modifies an effect. If intensity is given it will set the effect intensity to the given value, or as close as max_intensity values permit. */ - virtual void add_effect( const efftype_id &eff_id, const time_duration &dur, body_part bp = num_bp, - bool permanent = false, int intensity = 0, bool force = false, bool deferred = false ); + void add_effect( const efftype_id &eff_id, const time_duration &dur, bodypart_id bp, + bool permanent = false, int intensity = 0, bool force = false, bool deferred = false ); + void add_effect( const efftype_id &eff_id, const time_duration &dur, bool permanent = false, + int intensity = 0, bool force = false, bool deferred = false ); /** Gives chance to save via environmental resist, returns false if resistance was successful. */ - bool add_env_effect( const efftype_id &eff_id, body_part vector, int strength, - const time_duration &dur, - body_part bp = num_bp, bool permanent = false, int intensity = 1, + bool add_env_effect( const efftype_id &eff_id, const bodypart_id &vector, int strength, + const time_duration &dur, const bodypart_id &bp, bool permanent = false, int intensity = 1, bool force = false ); - /** Removes a listed effect. bp = num_bp means to remove all effects of + bool add_env_effect( const efftype_id &eff_id, const bodypart_id &vector, int strength, + const time_duration &dur, bool permanent = false, int intensity = 1, bool force = false ); + /** Removes a listed effect. If the bodypart is not specified remove all effects of * a given type, targeted or untargeted. Returns true if anything was * removed. */ - virtual bool remove_effect( const efftype_id &eff_id, body_part bp = num_bp ); + bool remove_effect( const efftype_id &eff_id, const bodypart_id &bp ); + bool remove_effect( const efftype_id &eff_id ); /** Remove all effects. */ void clear_effects(); - /** Check if creature has the matching effect. bp = num_bp means to check if the Creature has any effect + /** Check if creature has the matching effect. If the bodypart is not specified check if the Creature has any effect * of the matching type, targeted or untargeted. */ - bool has_effect( const efftype_id &eff_id, body_part bp = num_bp ) const; + bool has_effect( const efftype_id &eff_id, const bodypart_str_id &bp ) const; + bool has_effect( const efftype_id &eff_id ) const; /** Check if creature has any effect with the given flag. */ - bool has_effect_with_flag( const std::string &flag, body_part bp = num_bp ) const; + bool has_effect_with_flag( const std::string &flag, const bodypart_id &bp ) const; + bool has_effect_with_flag( const std::string &flag ) const; std::vector get_effects_with_flag( const std::string &flag ) const; /** Return the effect that matches the given arguments exactly. */ - const effect &get_effect( const efftype_id &eff_id, body_part bp = num_bp ) const; - effect &get_effect( const efftype_id &eff_id, body_part bp = num_bp ); + const effect &get_effect( const efftype_id &eff_id, + const bodypart_id &bp = bodypart_id( "bp_null" ) ) const; + effect &get_effect( const efftype_id &eff_id, const bodypart_id &bp = bodypart_id( "bp_null" ) ); /** Returns the duration of the matching effect. Returns 0 if effect doesn't exist. */ - time_duration get_effect_dur( const efftype_id &eff_id, body_part bp = num_bp ) const; + time_duration get_effect_dur( const efftype_id &eff_id, + const bodypart_id &bp = bodypart_id( "bp_null" ) ) const; /** Returns the intensity of the matching effect. Returns 0 if effect doesn't exist. */ - int get_effect_int( const efftype_id &eff_id, body_part bp = num_bp ) const; + int get_effect_int( const efftype_id &eff_id, + const bodypart_id &bp = bodypart_id( "bp_null" ) ) const; /** Returns true if the creature resists an effect */ bool resists_effect( const effect &e ); @@ -652,7 +662,8 @@ class Creature : public location void set_all_parts_hp_cur( int set ); void set_all_parts_hp_to_max(); - bool has_atleast_one_wet_part(); + bool has_atleast_one_wet_part() const; + bool is_part_at_max_hp( const bodypart_id &id ) const; virtual int get_speed_base() const; virtual int get_speed_bonus() const; @@ -995,7 +1006,7 @@ class Creature : public location protected: virtual void on_stat_change( const std::string &, int ) {} - virtual void on_effect_int_change( const efftype_id &, int, body_part ) {} + virtual void on_effect_int_change( const efftype_id &, int, const bodypart_id & ) {} virtual void on_damage_of_type( int, damage_type, const bodypart_id & ) {} public: diff --git a/src/debug_menu.cpp b/src/debug_menu.cpp index cf75e53cb9d89..19a963e158241 100644 --- a/src/debug_menu.cpp +++ b/src/debug_menu.cpp @@ -408,12 +408,12 @@ static cata::optional debug_menu_uilist( bool display_all_entr void teleport_short() { const cata::optional where = g->look_around(); - Character &player_character = get_player_character(); - if( !where || *where == player_character.pos() ) { + location &player_location = get_player_location(); + if( !where || *where == player_location.pos() ) { return; } g->place_player( *where ); - const tripoint new_pos( player_character.pos() ); + const tripoint new_pos( player_location.pos() ); add_msg( _( "You teleport to point (%d,%d,%d)." ), new_pos.x, new_pos.y, new_pos.z ); } @@ -627,7 +627,7 @@ void character_edit_menu() it.on_takeoff( p ); } p.worn.clear(); - p.inv.clear(); + p.inv->clear(); p.remove_weapon(); break; case D_ITEM_WORN: { @@ -980,7 +980,7 @@ void character_edit_menu() query_int( seconds, _( "How many seconds?" ), 600 ); if( effect.is_valid() ) { - p.add_effect( effect, time_duration::from_seconds( seconds ), num_bp, false, intensity ); + p.add_effect( effect, time_duration::from_seconds( seconds ), false, intensity ); } else { add_msg( _( "Invalid effect" ) ); } @@ -1437,7 +1437,7 @@ void debug() add_msg( _( "Your eyes blink rapidly as knowledge floods your brain." ) ); for( auto &style : all_martialart_types() ) { if( style != matype_id( "style_none" ) ) { - player_character.martial_arts_data.add_martialart( style ); + player_character.martial_arts_data->add_martialart( style ); } } add_msg( m_good, _( "You now know a lot more than just 10 styles of kung fu." ) ); @@ -1859,7 +1859,7 @@ void debug() } case debug_menu_index::PRINT_NPC_MAGIC: { for( npc &guy : g->all_npcs() ) { - const std::vector spells = guy.magic.spells(); + const std::vector spells = guy.magic->spells(); if( spells.empty() ) { std::cout << guy.disp_name() << " does not know any spells." << std::endl; continue; @@ -1943,14 +1943,14 @@ void debug() add_msg( m_bad, _( "There are no spells to learn. You must install a mod that adds some." ) ); } else { for( const spell_type &learn : spell_type::get_all() ) { - player_character.magic.learn_spell( &learn, player_character, true ); + player_character.magic->learn_spell( &learn, player_character, true ); } add_msg( m_good, _( "You have become an Archwizardpriest! What will you do with your newfound power?" ) ); } break; case debug_menu_index::LEVEL_SPELLS: { - std::vector spells = player_character.magic.get_spells(); + std::vector spells = player_character.magic->get_spells(); if( spells.empty() ) { add_msg( m_bad, _( "Try learning some spells first." ) ); return; diff --git a/src/descriptions.cpp b/src/descriptions.cpp index cf723312e2a3e..6e86a401e9b92 100644 --- a/src/descriptions.cpp +++ b/src/descriptions.cpp @@ -6,6 +6,7 @@ #include "avatar.h" #include "calendar.h" +#include "character.h" #include "color.h" #include "harvest.h" #include "input.h" @@ -30,7 +31,7 @@ enum class description_target : int { static const Creature *seen_critter( const game &g, const tripoint &p ) { const Creature *critter = g.critter_at( p, true ); - if( critter != nullptr && get_player_character().sees( *critter ) ) { + if( critter != nullptr && get_player_view().sees( *critter ) ) { return critter; } diff --git a/src/dialogue.h b/src/dialogue.h index a0bebee5d01df..b820be61e309f 100644 --- a/src/dialogue.h +++ b/src/dialogue.h @@ -207,6 +207,7 @@ struct talk_response { skill_id skill = skill_id(); matype_id style = matype_id(); spell_id dialogue_spell = spell_id(); + proficiency_id proficiency = proficiency_id(); talk_effect_t success; talk_effect_t failure; @@ -301,6 +302,13 @@ struct dialogue { */ talk_response &add_response( const std::string &text, const std::string &r, const skill_id &skill, bool first = false ); + /** + * Add a simple response that switches the topic to the new one and sets the currently + * talked about proficiency to the given one. + */ + talk_response &add_response( const std::string &text, const std::string &r, + const proficiency_id &proficiency, + bool first = false ); /** * Add a simple response that switches the topic to the new one and sets the currently * talked about magic spell to the given one. diff --git a/src/dialogue_chatbin.cpp b/src/dialogue_chatbin.cpp index 7500628030423..a70b43fd4699a 100644 --- a/src/dialogue_chatbin.cpp +++ b/src/dialogue_chatbin.cpp @@ -21,9 +21,10 @@ void dialogue_chatbin::check_missions() } void dialogue_chatbin::store_chosen_training( const skill_id &c_skill, const matype_id &c_style, - const spell_id &c_spell ) + const spell_id &c_spell, const proficiency_id &c_proficiency ) { - if( c_skill == skill_id() && c_style == matype_id() && c_spell == spell_id() ) { + if( c_skill == skill_id() && c_style == matype_id() && c_spell == spell_id() && + c_proficiency == proficiency_id() ) { return; } clear_training(); @@ -33,6 +34,8 @@ void dialogue_chatbin::store_chosen_training( const skill_id &c_skill, const mat style = c_style; } else if( c_spell != spell_id() ) { dialogue_spell = c_spell; + } else if( c_proficiency != proficiency_id() ) { + proficiency = c_proficiency; } } @@ -40,6 +43,7 @@ void dialogue_chatbin::clear_training() { style = matype_id(); skill = skill_id(); + proficiency = proficiency_id(); dialogue_spell = spell_id(); } diff --git a/src/dialogue_chatbin.h b/src/dialogue_chatbin.h index d26119aec344c..52c088288b118 100644 --- a/src/dialogue_chatbin.h +++ b/src/dialogue_chatbin.h @@ -39,17 +39,21 @@ struct dialogue_chatbin { /** * The skill this dialogue offers to train. */ - skill_id skill = skill_id::NULL_ID(); + skill_id skill = skill_id(); /** * The martial art style this dialogue offers to train. */ - matype_id style; + matype_id style = matype_id(); /** * The spell this dialogue offers to train */ spell_id dialogue_spell; + /** + * The proficiency this dialogue offers to train + */ + proficiency_id proficiency; void store_chosen_training( const skill_id &c_skill, const matype_id &c_style, - const spell_id &c_spell ); + const spell_id &c_spell, const proficiency_id &c_proficiency ); void clear_training(); std::string first_topic = "TALK_NONE"; diff --git a/src/effect.cpp b/src/effect.cpp index 2d8f248345866..c5d8f4a54a418 100644 --- a/src/effect.cpp +++ b/src/effect.cpp @@ -541,8 +541,8 @@ std::string effect::disp_name() const } } } - if( bp != num_bp ) { - ret += string_format( " (%s)", body_part_name( convert_bp( bp ).id() ) ); + if( bp != bodypart_str_id( "bp_null" ) ) { + ret += string_format( " (%s)", body_part_name( bp.id() ) ); } return ret; @@ -700,7 +700,7 @@ std::string effect::disp_desc( bool reduced ) const } // Then print the effect description if( use_part_descs() ) { - ret += string_format( _( tmp_str ), body_part_name( convert_bp( bp ).id() ) ); + ret += string_format( _( tmp_str ), body_part_name( bp.id() ) ); } else { if( !tmp_str.empty() ) { ret += _( tmp_str ); @@ -727,7 +727,7 @@ std::string effect::disp_short_desc( bool reduced ) const } } -void effect::decay( std::vector &rem_ids, std::vector &rem_bps, +void effect::decay( std::vector &rem_ids, std::vector &rem_bps, const time_point &time, const bool player ) { // Decay intensity if supposed to do so @@ -742,7 +742,7 @@ void effect::decay( std::vector &rem_ids, std::vector &re // Decay duration if not permanent if( duration <= 0_turns ) { rem_ids.push_back( get_id() ); - rem_bps.push_back( bp ); + rem_bps.push_back( bp.id() ); } else if( !is_permanent() ) { mod_duration( -1_turns, player ); } @@ -791,11 +791,11 @@ time_point effect::get_start_time() const return start_time; } -body_part effect::get_bp() const +bodypart_id effect::get_bp() const { - return bp; + return bp.id(); } -void effect::set_bp( body_part part ) +void effect::set_bp( bodypart_str_id part ) { bp = part; } @@ -1364,7 +1364,7 @@ void effect::serialize( JsonOut &json ) const json.start_object(); json.member( "eff_type", eff_type != nullptr ? eff_type->id.str() : "" ); json.member( "duration", duration ); - json.member( "bp", static_cast( bp ) ); + json.member( "bp", bp.c_str() ); json.member( "permanent", permanent ); json.member( "intensity", intensity ); json.member( "start_turn", start_time ); @@ -1373,12 +1373,20 @@ void effect::serialize( JsonOut &json ) const void effect::deserialize( JsonIn &jsin ) { JsonObject jo = jsin.get_object(); - const efftype_id id( jo.get_string( "eff_type" ) ); + efftype_id id; + jo.read( "eff_type", id ); eff_type = &id.obj(); jo.read( "duration", duration ); - bp = static_cast( jo.get_int( "bp" ) ); - permanent = jo.get_bool( "permanent" ); - intensity = jo.get_int( "intensity" ); + + // TEMPORARY until 0.F + if( jo.has_int( "bp" ) ) { + bp = convert_bp( static_cast( jo.get_int( "bp" ) ) ); + } else { + jo.read( "bp", bp ); + } + + jo.read( "permanent", permanent ); + jo.read( "intensity", intensity ); start_time = calendar::turn_zero; jo.read( "start_turn", start_time ); } @@ -1445,3 +1453,4 @@ std::string texitify_bandage_power( const int power ) } return ""; } + diff --git a/src/effect.h b/src/effect.h index e14d2753fc78f..402d807dd6852 100644 --- a/src/effect.h +++ b/src/effect.h @@ -150,10 +150,10 @@ class effect_type class effect { public: - effect() : eff_type( nullptr ), duration( 0_turns ), bp( body_part::num_bp ), + effect() : eff_type( nullptr ), duration( 0_turns ), bp( bodypart_str_id( "bp_null" ) ), permanent( false ), intensity( 1 ), start_time( calendar::turn_zero ) { } - effect( const effect_type *peff_type, const time_duration &dur, body_part part, + effect( const effect_type *peff_type, const time_duration &dur, bodypart_str_id part, bool perm, int nintensity, const time_point &nstart_time ) : eff_type( peff_type ), duration( dur ), bp( part ), permanent( perm ), intensity( nintensity ), start_time( nstart_time ) { @@ -182,7 +182,7 @@ class effect /** Decays effect durations, pushing their id and bp's back to rem_ids and rem_bps for removal later * if their duration is <= 0. This is called in the middle of a loop through all effects, which is * why we aren't allowed to remove the effects here. */ - void decay( std::vector &rem_ids, std::vector &rem_bps, + void decay( std::vector &rem_ids, std::vector &rem_bps, const time_point &time, bool player ); /** Returns the remaining duration of an effect. */ @@ -200,9 +200,9 @@ class effect time_point get_start_time() const; /** Returns the targeted body_part of the effect. This is num_bp for untargeted effects. */ - body_part get_bp() const; + bodypart_id get_bp() const; /** Sets the targeted body_part of an effect. */ - void set_bp( body_part part ); + void set_bp( bodypart_str_id part ); /** Returns true if an effect is permanent, i.e. it's duration does not decrease over time. */ bool is_permanent() const; @@ -294,7 +294,7 @@ class effect protected: const effect_type *eff_type; time_duration duration; - body_part bp; + bodypart_str_id bp; bool permanent; int intensity; time_point start_time; @@ -311,7 +311,7 @@ std::string texitify_bandage_power( int power ); // Inheritance here allows forward declaration of the map in class Creature. // Storing body_part as an int to make things easier for hash and JSON class effects_map : public - std::unordered_map>> + std::unordered_map>> { }; diff --git a/src/explosion.cpp b/src/explosion.cpp index 24a7d83eba3b3..9e1598f1bd503 100644 --- a/src/explosion.cpp +++ b/src/explosion.cpp @@ -576,7 +576,7 @@ void flashbang( const tripoint &p, bool player_immune ) player_character.worn_with_flag( flag_FLASH_PROTECTION ) ) { flash_mod = 3; // Not really proper flash protection, but better than nothing } - player_character.add_env_effect( effect_blind, bp_eyes, ( 12 - flash_mod - dist ) / 2, + player_character.add_env_effect( effect_blind, bodypart_id( "eyes" ), ( 12 - flash_mod - dist ) / 2, time_duration::from_turns( 10 - dist ) ); } } diff --git a/src/faction_camp.cpp b/src/faction_camp.cpp index 6a80ea83b4d4a..1b04ec8106938 100644 --- a/src/faction_camp.cpp +++ b/src/faction_camp.cpp @@ -1999,7 +1999,7 @@ void basecamp::start_setup_hide_site() omt_pos, true ); if( forest != tripoint_abs_omt( -999, -999, -999 ) ) { int dist = rl_dist( forest.xy(), omt_pos.xy() ); - inventory tgt_inv = get_player_character().inv; + inventory tgt_inv = *get_player_character().inv; std::vector pos_inv = tgt_inv.items_with( []( const item & itm ) { return !itm.can_revive(); } ); @@ -2042,7 +2042,7 @@ void basecamp::start_relay_hide_site() omt_pos, true ); if( forest != tripoint_abs_omt( -999, -999, -999 ) ) { int dist = rl_dist( forest.xy(), omt_pos.xy() ); - inventory tgt_inv = get_player_character().inv; + inventory tgt_inv = *get_player_character().inv; std::vector pos_inv = tgt_inv.items_with( []( const item & itm ) { return !itm.can_revive(); } ); diff --git a/src/field_type.h b/src/field_type.h index e4af3951c8c84..fefa995ce5971 100644 --- a/src/field_type.h +++ b/src/field_type.h @@ -83,7 +83,7 @@ struct field_effect { return message_npc.translated(); } effect get_effect( const time_point &start_time = calendar::turn ) const { - return effect( &id.obj(), get_duration(), bp, false, intensity, start_time ); + return effect( &id.obj(), get_duration(), convert_bp( bp ), false, intensity, start_time ); } }; diff --git a/src/fungal_effects.cpp b/src/fungal_effects.cpp index ccad1deaf8807..f90794e3ff0ee 100644 --- a/src/fungal_effects.cpp +++ b/src/fungal_effects.cpp @@ -64,9 +64,8 @@ void fungal_effects::fungalize( const tripoint &p, Creature *origin, double spor Character &player_character = get_player_character(); if( monster *const mon_ptr = g->critter_at( p ) ) { monster &critter = *mon_ptr; - if( player_character.sees( p ) && - !critter.type->in_species( species_FUNGUS ) ) { - add_msg( _( "The %s is covered in tiny spores!" ), critter.name() ); + if( !critter.type->in_species( species_FUNGUS ) ) { + add_msg_if_player_sees( p, _( "The %s is covered in tiny spores!" ), critter.name() ); } if( !critter.make_fungus() ) { // Don't insta-kill non-fungables. Jabberwocks, for example @@ -85,17 +84,23 @@ void fungal_effects::fungalize( const tripoint &p, Creature *origin, double spor // Spores hit the player--is there any hope? bool hit = false; hit |= one_in( 4 ) && - player_character.add_env_effect( effect_spores, bp_head, 3, 9_minutes, bp_head ); + player_character.add_env_effect( effect_spores, bodypart_id( "head" ), 3, 9_minutes, + bodypart_id( "head" ) ); hit |= one_in( 2 ) && - player_character.add_env_effect( effect_spores, bp_torso, 3, 9_minutes, bp_torso ); + player_character.add_env_effect( effect_spores, bodypart_id( "torso" ), 3, 9_minutes, + bodypart_id( "torso" ) ); hit |= one_in( 4 ) && - player_character.add_env_effect( effect_spores, bp_arm_l, 3, 9_minutes, bp_arm_l ); + player_character.add_env_effect( effect_spores, bodypart_id( "arm_l" ), 3, 9_minutes, + bodypart_id( "arm_l" ) ); hit |= one_in( 4 ) && - player_character.add_env_effect( effect_spores, bp_arm_r, 3, 9_minutes, bp_arm_r ); + player_character.add_env_effect( effect_spores, bodypart_id( "arm_r" ), 3, 9_minutes, + bodypart_id( "arm_r" ) ); hit |= one_in( 4 ) && - player_character.add_env_effect( effect_spores, bp_leg_l, 3, 9_minutes, bp_leg_l ); + player_character.add_env_effect( effect_spores, bodypart_id( "leg_l" ), 3, 9_minutes, + bodypart_id( "leg_l" ) ); hit |= one_in( 4 ) && - player_character.add_env_effect( effect_spores, bp_leg_r, 3, 9_minutes, bp_leg_r ); + player_character.add_env_effect( effect_spores, bodypart_id( "leg_r" ), 3, 9_minutes, + bodypart_id( "leg_r" ) ); if( hit ) { add_msg( m_warning, _( "You're covered in tiny spores!" ) ); } @@ -142,7 +147,6 @@ void fungal_effects::spread_fungus_one_tile( const tripoint &p, const int growth { bool converted = false; // Terrain conversion - Character &player_character = get_player_character(); if( m.has_flag_ter( flag_DIGGABLE, p ) ) { if( x_in_y( growth * 10, 100 ) ) { m.ter_set( p, t_fungus ); @@ -183,8 +187,8 @@ void fungal_effects::spread_fungus_one_tile( const tripoint &p, const int growth if( m.get_field_intensity( p, fd_fungal_haze ) != 0 ) { if( x_in_y( growth * 10, 800 ) ) { // young trees are vulnerable m.ter_set( p, t_fungus ); - if( gm.place_critter_at( mon_fungal_blossom, p ) && player_character.sees( p ) ) { - add_msg( m_warning, _( "The young tree blooms forth into a fungal blossom!" ) ); + if( gm.place_critter_at( mon_fungal_blossom, p ) ) { + add_msg_if_player_sees( p, m_warning, _( "The young tree blooms forth into a fungal blossom!" ) ); } } else if( x_in_y( growth * 10, 400 ) ) { m.ter_set( p, t_marloss_tree ); @@ -199,8 +203,8 @@ void fungal_effects::spread_fungus_one_tile( const tripoint &p, const int growth if( m.get_field_intensity( p, fd_fungal_haze ) != 0 ) { if( x_in_y( growth * 10, 100 ) ) { m.ter_set( p, t_fungus ); - if( gm.place_critter_at( mon_fungal_blossom, p ) && player_character.sees( p ) ) { - add_msg( m_warning, _( "The tree blooms forth into a fungal blossom!" ) ); + if( gm.place_critter_at( mon_fungal_blossom, p ) ) { + add_msg_if_player_sees( p, m_warning, _( "The tree blooms forth into a fungal blossom!" ) ); } } else if( x_in_y( growth * 10, 600 ) ) { m.ter_set( p, t_marloss_tree ); diff --git a/src/game.cpp b/src/game.cpp index a966b2bf1a163..5ed72fea7012f 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -743,10 +743,10 @@ bool game::start_game() start_loc.burn( omtstart, 3, 3 ); } if( scen->has_flag( "INFECTED" ) ) { - u.add_effect( effect_infected, 1_turns, random_body_part(), true ); + u.add_effect( effect_infected, 1_turns, convert_bp( random_body_part() ).id(), true ); } if( scen->has_flag( "FUNGAL_INFECTION" ) ) { - u.add_effect( effect_fungus, 1_turns, random_body_part(), true ); + u.add_effect( effect_fungus, 1_turns, convert_bp( random_body_part() ).id(), true ); } if( scen->has_flag( "BAD_DAY" ) ) { u.add_effect( effect_flu, 1000_minutes ); @@ -797,7 +797,7 @@ bool game::start_game() for( const mtype_id &elem : u.starting_pets ) { if( monster *const mon = place_critter_around( elem, u.pos(), 5 ) ) { mon->friendly = -1; - mon->add_effect( effect_pet, 1_turns, num_bp, true ); + mon->add_effect( effect_pet, 1_turns, true ); } else { add_msg( m_debug, "cannot place starting pet, no space!" ); } @@ -1914,7 +1914,7 @@ void game::validate_mounted_npcs() } mounted_pl->mounted_creature = shared_from( m ); mounted_pl->setpos( m.pos() ); - mounted_pl->add_effect( effect_riding, 1_turns, num_bp, true ); + mounted_pl->add_effect( effect_riding, 1_turns, true ); m.mounted_player = mounted_pl; } } @@ -5317,7 +5317,7 @@ bool game::revive_corpse( const tripoint &p, item &it ) } critter.no_extra_death_drops = true; - critter.add_effect( effect_downed, 5_turns, num_bp, true ); + critter.add_effect( effect_downed, 5_turns, true ); if( it.get_var( "no_ammo" ) == "no_ammo" ) { for( auto &ammo : critter.ammo ) { @@ -5368,7 +5368,7 @@ void game::save_cyborg( item *cyborg, const tripoint &couch_pos, player &install tmp->spawn_at_precise( get_map().get_abs_sub().xy(), couch_pos ); overmap_buffer.insert_npc( tmp ); tmp->hurtall( dmg_lvl * 10, nullptr ); - tmp->add_effect( effect_downed, rng( 1_turns, 4_turns ), num_bp, false, 0, true ); + tmp->add_effect( effect_downed, rng( 1_turns, 4_turns ), false, 0, true ); load_npcs(); } else { @@ -8717,19 +8717,20 @@ void game::butcher() kmenu.addentry( MULTIBUTCHER, true, 'b', _( "Butcher everything" ) ); } if( disassembles.size() > 1 ) { - int time_to_disassemble = 0; - int time_to_disassemble_all = 0; + int time_to_disassemble_once = 0; + int time_to_disassemble_recursive = 0; for( const auto &stack : disassembly_stacks ) { const int time = recipe_dictionary::get_uncraft( stack.first->typeId() ).time_to_craft_moves( get_player_character() ); - time_to_disassemble += time; - time_to_disassemble_all += time * stack.second; + time_to_disassemble_once += time * stack.second; + time_to_disassemble_recursive += stack.first->get_recursive_disassemble_moves( + get_player_character() ) * stack.second; } kmenu.addentry_col( MULTIDISASSEMBLE_ONE, true, 'D', _( "Disassemble everything once" ), - to_string_clipped( time_duration::from_turns( time_to_disassemble / 100 ) ) ); + to_string_clipped( time_duration::from_turns( time_to_disassemble_once / 100 ) ) ); kmenu.addentry_col( MULTIDISASSEMBLE_ALL, true, 'd', _( "Disassemble everything recursively" ), - to_string_clipped( time_duration::from_turns( time_to_disassemble_all / 100 ) ) ); + to_string_clipped( time_duration::from_turns( time_to_disassemble_recursive / 100 ) ) ); } if( salvage_iuse && salvageables.size() > 1 ) { int time_to_salvage = 0; @@ -9025,8 +9026,8 @@ void game::wield( item_location loc ) } if( is_unwielding ) { - if( !u.martial_arts_data.selected_is_none() ) { - u.martial_arts_data.martialart_use_message( u ); + if( !u.martial_arts_data->selected_is_none() ) { + u.martial_arts_data->martialart_use_message( u ); } return; } @@ -9227,7 +9228,7 @@ bool game::disable_robot( const tripoint &p ) critter.name() ); } } else { - critter.add_effect( effect_docile, 1_turns, num_bp, true ); + critter.add_effect( effect_docile, 1_turns, true ); if( one_in( 3 ) ) { add_msg( _( "The %s lets out a whirring noise and starts to follow you." ), critter.name() ); @@ -9681,21 +9682,21 @@ point game::place_player( const tripoint &dest_loc ) m.has_flag_ter( "SHARP", dest_loc ) ? m.tername( dest_loc ) : m.furnname( dest_loc ) ); if( ( u.has_trait( trait_INFRESIST ) ) && ( one_in( 1024 ) ) ) { - u.add_effect( effect_tetanus, 1_turns, num_bp, true ); + u.add_effect( effect_tetanus, 1_turns, true ); } else if( ( !u.has_trait( trait_INFIMMUNE ) || !u.has_trait( trait_INFRESIST ) ) && ( one_in( 256 ) ) ) { - u.add_effect( effect_tetanus, 1_turns, num_bp, true ); + u.add_effect( effect_tetanus, 1_turns, true ); } } } } if( m.has_flag( "UNSTABLE", dest_loc ) && !u.is_mounted() ) { - u.add_effect( effect_bouldering, 1_turns, num_bp, true ); + u.add_effect( effect_bouldering, 1_turns, true ); } else if( u.has_effect( effect_bouldering ) ) { u.remove_effect( effect_bouldering ); } if( m.has_flag_ter_or_furn( TFLAG_NO_SIGHT, dest_loc ) ) { - u.add_effect( effect_no_sight, 1_turns, num_bp, true ); + u.add_effect( effect_no_sight, 1_turns, true ); } else if( u.has_effect( effect_no_sight ) ) { u.remove_effect( effect_no_sight ); } @@ -10306,7 +10307,7 @@ void game::on_move_effects() } // apply martial art move bonuses - u.martial_arts_data.ma_onmove_effects( u ); + u.martial_arts_data->ma_onmove_effects( u ); sfx::do_ambient(); } @@ -12606,6 +12607,11 @@ location &get_player_location() return g->u; } +viewer &get_player_view() +{ + return g->u; +} + avatar &get_avatar() { return g->u; diff --git a/src/game.h b/src/game.h index 07100659b33d7..f8ae8f68c6ce2 100644 --- a/src/game.h +++ b/src/game.h @@ -36,6 +36,7 @@ class Creature_tracker; class item; class spell_events; +class viewer; static constexpr int DEFAULT_TILESET_ZOOM = 16; @@ -156,6 +157,7 @@ class game friend Character &get_player_character(); friend avatar &get_avatar(); friend location &get_player_location(); + friend viewer &get_player_view(); friend weather_manager &get_weather(); friend const scenario *get_scenario(); friend void set_scenario( const scenario *new_scenario ); diff --git a/src/game_constants.h b/src/game_constants.h index 3ca2b90b1cae7..e875b871f5bba 100644 --- a/src/game_constants.h +++ b/src/game_constants.h @@ -2,6 +2,9 @@ #ifndef CATA_SRC_GAME_CONSTANTS_H #define CATA_SRC_GAME_CONSTANTS_H +#include +#include + // Fixed window sizes. static constexpr int HP_HEIGHT = 14; static constexpr int HP_WIDTH = 7; @@ -159,12 +162,22 @@ constexpr int SIMPLEX_NOISE_RANDOM_SEED_LIMIT = 32768; * in the json, think about what it would be if you * did this activity for a longer period of time. */ -constexpr float NO_EXERCISE = 1.2f; +constexpr float NO_EXERCISE = 1.0f; constexpr float LIGHT_EXERCISE = 2.0f; -constexpr float MODERATE_EXERCISE = 4.5f; +constexpr float MODERATE_EXERCISE = 4.0f; +constexpr float BRISK_EXERCISE = 6.0f; constexpr float ACTIVE_EXERCISE = 8.0f; constexpr float EXTRA_EXERCISE = 10.0f; +const std::map activity_levels = { + { "NO_EXERCISE", NO_EXERCISE }, + { "LIGHT_EXERCISE", LIGHT_EXERCISE }, + { "MODERATE_EXERCISE", MODERATE_EXERCISE }, + { "BRISK_EXERCISE", BRISK_EXERCISE }, + { "ACTIVE_EXERCISE", ACTIVE_EXERCISE }, + { "EXTRA_EXERCISE", EXTRA_EXERCISE } +}; + // these are the lower bounds of each of the weight classes. namespace character_weight_category { diff --git a/src/game_inventory.cpp b/src/game_inventory.cpp index eb8ba626863e8..4dbc5776bedf9 100644 --- a/src/game_inventory.cpp +++ b/src/game_inventory.cpp @@ -50,6 +50,7 @@ #include "type_id.h" #include "ui_manager.h" #include "units.h" +#include "units_utility.h" #include "value_ptr.h" static const activity_id ACT_EAT_MENU( "ACT_EAT_MENU" ); @@ -137,7 +138,7 @@ static item_location inv_internal( Character &u, const inventory_selector_preset ACT_CONSUME_DRINK_MENU, ACT_CONSUME_MEDS_MENU }; - u.inv.restack( u ); + u.inv->restack( u ); inv_s.clear_items(); inv_s.add_character_items( u ); @@ -195,7 +196,7 @@ void game_menus::inv::common( avatar &you ) int res = 0; do { - you.inv.restack( you ); + you.inv->restack( you ); inv_s.clear_items(); inv_s.add_character_items( you ); @@ -373,9 +374,14 @@ item_location game::inv_map_splice( const item_filter &filter, const std::string title, radius, none_message ); } -item_location game_menus::inv::container_for( Character &you, const item &liquid, int radius ) +item_location game_menus::inv::container_for( Character &you, const item &liquid, int radius, + const item *const avoid ) { - const auto filter = [ &liquid ]( const item_location & location ) { + const auto filter = [ &liquid, avoid ]( const item_location & location ) { + if( location.get_item() == avoid ) { + return false; + } + if( location.where() == item_location::type::character ) { Character *character = g->critter_at( location.position() ); if( character == nullptr ) { @@ -528,13 +534,18 @@ class comestible_inventory_preset : public inventory_selector_preset }, _( "CONSUME TIME" ) ); append_cell( [this, &player_character]( const item_location & loc ) { + std::string sealed; + if( loc.has_parent() ) { + item_pocket *pocket = loc.parent_item()->contained_where( * loc.get_item() ); + sealed = pocket->sealed() ? _( "sealed" ) : std::string(); + } if( player_character.can_estimate_rot() ) { if( loc->is_comestible() && loc->get_comestible()->spoils > 0_turns ) { - return get_freshness( loc ); + return sealed + ( sealed.empty() ? "" : " " ) + get_freshness( loc ); } return std::string( "---" ); } - return std::string(); + return sealed; }, _( "FRESHNESS" ) ); append_cell( [ this, &player_character ]( const item_location & loc ) { @@ -1186,7 +1197,9 @@ class weapon_inventory_preset: public inventory_selector_preset }, _( "MOVES" ) ); append_cell( [this]( const item_location & loc ) { - return string_format( "%d", loc.obtain_cost( this->p ) ); + return string_format( "%d", + loc.obtain_cost( this->p ) + ( this->p.is_wielding( *loc.get_item() ) ? 0 : + ( *loc.get_item() ).on_wield_cost( this->p ) ) ); }, _( "WIELD COST" ) ); } @@ -1397,7 +1410,7 @@ item_location game_menus::inv::saw_barrel( player &p, item &tool ) drop_locations game_menus::inv::multidrop( player &p ) { - p.inv.restack( p ); + p.inv->restack( p ); const inventory_filter_preset preset( [ &p ]( const item_location & location ) { return p.can_unwield( *location ).success(); @@ -1419,7 +1432,7 @@ drop_locations game_menus::inv::multidrop( player &p ) void game_menus::inv::compare( player &p, const cata::optional &offset ) { - p.inv.restack( p ); + p.inv->restack( p ); inventory_compare_selector inv_s( p ); @@ -1539,7 +1552,7 @@ void game_menus::inv::reassign_letter( player &p, item &it ) void game_menus::inv::swap_letters( player &p ) { - p.inv.restack( p ); + p.inv->restack( p ); inventory_pick_selector inv_s( p ); @@ -1555,7 +1568,7 @@ void game_menus::inv::swap_letters( player &p ) while( true ) { const std::string invlets = colorize_symbols( inv_chars.get_allowed_chars(), [ &p ]( const std::string::value_type & elem ) { - if( p.inv.assigned_invlet.count( elem ) ) { + if( p.inv->assigned_invlet.count( elem ) ) { return c_yellow; } else if( p.invlet_to_item( elem ) != nullptr ) { return c_white; @@ -1613,7 +1626,7 @@ static item_location autodoc_internal( player &u, player &patient, inv_s.set_display_stats( false ); do { - u.inv.restack( u ); + u.inv->restack( u ); inv_s.clear_items(); inv_s.add_character_items( u ); @@ -1966,7 +1979,7 @@ static item_location autoclave_internal( player &u, inv_s.set_display_stats( false ); do { - u.inv.restack( u ); + u.inv->restack( u ); inv_s.clear_items(); inv_s.add_character_items( u ); diff --git a/src/game_inventory.h b/src/game_inventory.h index 95d30ccd85b65..91b3672692a2b 100644 --- a/src/game_inventory.h +++ b/src/game_inventory.h @@ -84,7 +84,8 @@ item_location consume_drink( player &p ); /** Consuming a medication item via a custom menu. */ item_location consume_meds( player &p ); /** Choosing a container for liquid. */ -item_location container_for( Character &you, const item &liquid, int radius = 0 ); +item_location container_for( Character &you, const item &liquid, int radius = 0, + const item *avoid = nullptr ); /** Item disassembling menu. */ item_location disassemble( Character &p ); /** Gunmod installation menu. */ diff --git a/src/gamemode_tutorial.cpp b/src/gamemode_tutorial.cpp index 41a9c5a83fbeb..a240d2661e5df 100644 --- a/src/gamemode_tutorial.cpp +++ b/src/gamemode_tutorial.cpp @@ -148,7 +148,7 @@ bool tutorial_game::init() player_character.toggle_trait( trait_QUICK ); item lighter( "lighter", 0 ); lighter.invlet = 'e'; - player_character.inv.add_item( lighter, true, false ); + player_character.inv->add_item( lighter, true, false ); player_character.set_skill_level( skill_gun, 5 ); player_character.set_skill_level( skill_melee, 5 ); g->load_map( project_to( lp_abs ) ); diff --git a/src/gates.cpp b/src/gates.cpp index 091f654fbf926..284356515d085 100644 --- a/src/gates.cpp +++ b/src/gates.cpp @@ -23,7 +23,6 @@ #include "mapdata.h" #include "messages.h" #include "optional.h" -#include "player.h" #include "player_activity.h" #include "point.h" #include "string_id.h" @@ -218,7 +217,7 @@ void gates::open_gate( const tripoint &pos ) } } - if( get_player_character().sees( pos ) ) { + if( get_player_view().sees( pos ) ) { if( open ) { add_msg( gate.open_message ); } else if( close ) { @@ -231,7 +230,7 @@ void gates::open_gate( const tripoint &pos ) } } -void gates::open_gate( const tripoint &pos, player &p ) +void gates::open_gate( const tripoint &pos, Character &p ) { const gate_id gid = get_gate_id( pos ); @@ -251,7 +250,7 @@ void gates::open_gate( const tripoint &pos, player &p ) // Doors namespace -void doors::close_door( map &m, Character &who, const tripoint &closep ) +void doors::close_door( map &m, Creature &who, const tripoint &closep ) { bool didit = false; const bool inside = !m.is_outside( who.pos() ); diff --git a/src/gates.h b/src/gates.h index ee1496549f978..352b0f7b4106b 100644 --- a/src/gates.h +++ b/src/gates.h @@ -4,10 +4,10 @@ #include +class Character; +class Creature; class JsonObject; -class player; class map; -class Character; struct tripoint; namespace gates @@ -18,7 +18,7 @@ void check(); void reset(); /** opens the gate via player's activity */ -void open_gate( const tripoint &pos, player &p ); +void open_gate( const tripoint &pos, Character &p ); /** opens the gate immediately */ void open_gate( const tripoint &pos ); @@ -31,7 +31,7 @@ namespace doors * Handles deducting moves, printing messages (only non-NPCs cause messages), actually closing it, * checking if it can be closed, etc. */ -void close_door( map &m, Character &who, const tripoint &closep ); +void close_door( map &m, Creature &who, const tripoint &closep ); } // namespace doors diff --git a/src/handle_action.cpp b/src/handle_action.cpp index f3270eafea4c5..434a0e3119596 100644 --- a/src/handle_action.cpp +++ b/src/handle_action.cpp @@ -1419,7 +1419,7 @@ static void cast_spell() { Character &player_character = get_player_character(); - std::vector spells = player_character.magic.spells(); + std::vector spells = player_character.magic->spells(); if( spells.empty() ) { add_msg( game_message_params{ m_bad, gmf_bypass_cooldown }, @@ -1429,7 +1429,7 @@ static void cast_spell() bool can_cast_spells = false; for( const spell_id &sp : spells ) { - spell temp_spell = player_character.magic.get_spell( sp ); + spell temp_spell = player_character.magic->get_spell( sp ); if( temp_spell.can_cast( player_character ) ) { can_cast_spells = true; } @@ -1440,12 +1440,12 @@ static void cast_spell() _( "You can't cast any of the spells you know!" ) ); } - const int spell_index = player_character.magic.select_spell( player_character ); + const int spell_index = player_character.magic->select_spell( player_character ); if( spell_index < 0 ) { return; } - spell &sp = *player_character.magic.get_spells()[spell_index]; + spell &sp = *player_character.magic->get_spells()[spell_index]; assign_spellcasting( player_character, sp, false ); } @@ -1460,7 +1460,7 @@ static bool assign_spellcasting( Character &you, spell &sp, bool fake_spell ) return false; } - if( !you.magic.has_enough_energy( you, sp ) ) { + if( !you.magic->has_enough_energy( you, sp ) ) { add_msg( game_message_params{ m_bad, gmf_bypass_cooldown }, _( "You don't have enough %s to cast the spell." ), sp.energy_string() ); @@ -1485,7 +1485,7 @@ static bool assign_spellcasting( Character &you, spell &sp, bool fake_spell ) // [2] this value overrides the mana cost if set to 0 cast_spell.values.emplace_back( 1 ); cast_spell.name = sp.id().c_str(); - if( you.magic.casting_ignore ) { + if( you.magic->casting_ignore ) { const std::vector ignored_distractions = { distraction_type::noise, distraction_type::pain, @@ -2070,7 +2070,7 @@ bool game::handle_action() break; case ACTION_PICK_STYLE: - player_character.martial_arts_data.pick_style( player_character ); + player_character.martial_arts_data->pick_style( player_character ); break; case ACTION_RELOAD_ITEM: diff --git a/src/handle_liquid.cpp b/src/handle_liquid.cpp index 543f4f1f88cbb..8845d04e5898f 100644 --- a/src/handle_liquid.cpp +++ b/src/handle_liquid.cpp @@ -93,20 +93,20 @@ static void serialize_liquid_target( player_activity &act, const tripoint &pos ) namespace liquid_handler { -void handle_all_liquid( item liquid, const int radius ) +void handle_all_liquid( item liquid, const int radius, const item *const avoid ) { while( liquid.charges > 0 ) { // handle_liquid allows to pour onto the ground, which will handle all the liquid and // set charges to 0. This allows terminating the loop. // The result of handle_liquid is ignored, the player *has* to handle all the liquid. - handle_liquid( liquid, nullptr, radius ); + handle_liquid( liquid, avoid, radius ); } } -bool consume_liquid( item &liquid, const int radius ) +bool consume_liquid( item &liquid, const int radius, const item *const avoid ) { const auto original_charges = liquid.charges; - while( liquid.charges > 0 && handle_liquid( liquid, nullptr, radius ) ) { + while( liquid.charges > 0 && handle_liquid( liquid, avoid, radius ) ) { // try again with the remaining charges } return original_charges != liquid.charges; @@ -154,7 +154,7 @@ bool handle_liquid_from_container( item &container, int radius ) return handled; } -static bool get_liquid_target( item &liquid, item *const source, const int radius, +static bool get_liquid_target( item &liquid, const item *const source, const int radius, const tripoint *const source_pos, const vehicle *const source_veh, const monster *const source_mon, @@ -203,7 +203,8 @@ static bool get_liquid_target( item &liquid, item *const source, const int radiu // This handles containers found anywhere near the player, including on the map and in vehicle storage. menu.addentry( -1, true, 'c', _( "Pour into a container" ) ); actions.emplace_back( [&]() { - target.item_loc = game_menus::inv::container_for( player_character, liquid, radius ); + target.item_loc = game_menus::inv::container_for( player_character, liquid, + radius, /*avoid=*/source ); item *const cont = target.item_loc.get_item(); if( cont == nullptr || cont->is_null() ) { @@ -398,7 +399,7 @@ static bool perform_liquid_transfer( item &liquid, const tripoint *const source_ return transfer_ok; } -bool handle_liquid( item &liquid, item *const source, const int radius, +bool handle_liquid( item &liquid, const item *const source, const int radius, const tripoint *const source_pos, const vehicle *const source_veh, const int part_num, const monster *const source_mon ) diff --git a/src/handle_liquid.h b/src/handle_liquid.h index 8db1606d94fd1..f033bfbcf612a 100644 --- a/src/handle_liquid.h +++ b/src/handle_liquid.h @@ -42,7 +42,7 @@ namespace liquid_handler * charges of the liquid have been transferred. * `true` indicates some charges have been transferred (but not necessarily all of them). */ -void handle_all_liquid( item liquid, int radius ); +void handle_all_liquid( item liquid, int radius, const item *avoid = nullptr ); /** * Consume / handle as much of the liquid as possible in varying ways. This function can @@ -54,7 +54,7 @@ void handle_all_liquid( item liquid, int radius ); * declined all options to handle the liquid and no charges of the liquid have been transferred. * `true` indicates some charges have been transferred (but not necessarily all of them). */ -bool consume_liquid( item &liquid, int radius = 0 ); +bool consume_liquid( item &liquid, int radius = 0, const item *avoid = nullptr ); /** * Handle finite liquid from ground. The function also handles consuming move points. @@ -106,7 +106,7 @@ bool handle_liquid_from_container( item &container, int radius = 0 ); * Basically `false` indicates the user does not *want* to handle the liquid, `true` * indicates they want to handle it. */ -bool handle_liquid( item &liquid, item *source = nullptr, int radius = 0, +bool handle_liquid( item &liquid, const item *source = nullptr, int radius = 0, const tripoint *source_pos = nullptr, const vehicle *source_veh = nullptr, int part_num = -1, const monster *source_mon = nullptr ); diff --git a/src/iexamine.cpp b/src/iexamine.cpp index 58db68447e4a4..5826de4586c18 100644 --- a/src/iexamine.cpp +++ b/src/iexamine.cpp @@ -90,6 +90,7 @@ #include "ui_manager.h" #include "uistate.h" #include "units.h" +#include "units_utility.h" #include "value_ptr.h" #include "vehicle.h" #include "vehicle_selector.h" @@ -4099,8 +4100,8 @@ static int findBestGasDiscount( player &p ) { int discount = 0; - for( size_t i = 0; i < p.inv.size(); i++ ) { - item &it = p.inv.find_item( i ); + for( size_t i = 0; i < p.inv->size(); i++ ) { + item &it = p.inv->find_item( i ); if( it.has_flag( "GAS_DISCOUNT" ) ) { @@ -4402,7 +4403,7 @@ void iexamine::pay_gas( player &p, const tripoint &examp ) } if( refund == choice ) { - const int pos = p.inv.position_by_type( itype_id( "cash_card" ) ); + const int pos = p.inv->position_by_type( itype_id( "cash_card" ) ); if( pos == INT_MIN ) { add_msg( _( "Never mind." ) ); @@ -4826,7 +4827,7 @@ void iexamine::autodoc( player &p, const tripoint &examp ) // TODO: refactor this whole bit. adding items to the inventory will // cause major issues when inv gets removed. this is a shim for now // in order to reduce lines of change for nested containers. - player_character.inv.push_back( bionic_to_uninstall ); + player_character.inv->push_back( bionic_to_uninstall ); } } } @@ -4871,7 +4872,7 @@ void iexamine::autodoc( player &p, const tripoint &examp ) int broken_limbs_count = 0; for( const bodypart_id &part : patient.get_all_body_parts( true ) ) { const bool broken = patient.is_limb_broken( part ); - effect &existing_effect = patient.get_effect( effect_mending, part->token ); + effect &existing_effect = patient.get_effect( effect_mending, part ); // Skip part if not broken or already healed 50% if( !broken || ( !existing_effect.is_null() && existing_effect.get_duration() > @@ -4895,8 +4896,8 @@ void iexamine::autodoc( player &p, const tripoint &examp ) cata::optional::iterator> worn_item = patient.wear( equipped_splint, false ); } - patient.add_effect( effect_mending, 0_turns, part->token, true ); - effect &mending_effect = patient.get_effect( effect_mending, part->token ); + patient.add_effect( effect_mending, 0_turns, part, true ); + effect &mending_effect = patient.get_effect( effect_mending, part ); mending_effect.set_duration( mending_effect.get_max_duration() - 5_days ); } if( broken_limbs_count == 0 ) { @@ -4941,16 +4942,16 @@ void iexamine::autodoc( player &p, const tripoint &examp ) } for( const bodypart_id &bp_healed : patient.get_all_body_parts( true ) ) { - if( patient.has_effect( effect_bleed, bp_healed->token ) ) { - patient.remove_effect( effect_bleed, bp_healed->token ); + if( patient.has_effect( effect_bleed, bp_healed.id() ) ) { + patient.remove_effect( effect_bleed, bp_healed ); patient.add_msg_player_or_npc( m_good, _( "The autodoc detected a bleeding on your %s and applied a hemostatic drug to stop it." ), _( "The autodoc detected a bleeding on 's %s and applied a hemostatic drug to stop it." ), body_part_name( bp_healed ) ); } - if( patient.has_effect( effect_bite, bp_healed->token ) ) { - patient.remove_effect( effect_bite, bp_healed->token ); + if( patient.has_effect( effect_bite, bp_healed.id() ) ) { + patient.remove_effect( effect_bite, bp_healed ); patient.add_msg_player_or_npc( m_good, _( "The autodoc detected an open wound on your %s and applied a disinfectant to clean it." ), _( "The autodoc detected an open wound on 's %s and applied a disinfectant to clean it." ), @@ -4958,8 +4959,8 @@ void iexamine::autodoc( player &p, const tripoint &examp ) // Fixed disinfectant intensity of 4 disinfectant_power + 10 first aid skill level of autodoc. const int disinfectant_intensity = 14; - patient.add_effect( effect_disinfected, 1_turns, bp_healed->token ); - effect &e = patient.get_effect( effect_disinfected, bp_healed->token ); + patient.add_effect( effect_disinfected, 1_turns, bp_healed ); + effect &e = patient.get_effect( effect_disinfected, bp_healed ); e.set_duration( e.get_int_dur_factor() * disinfectant_intensity ); patient.set_part_damage_disinfected( bp_healed, patient.get_part_hp_max( bp_healed ) - patient.get_part_hp_cur( bp_healed ) ); diff --git a/src/input.cpp b/src/input.cpp index 01d2a56e1b437..2edb9a231808a 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -1560,36 +1560,24 @@ cata::optional input_context::get_coordinates( const catacurses::windo } #endif -std::pair input_context::get_coordinates_text( const catacurses::window +cata::optional input_context::get_coordinates_text( const catacurses::window &capture_win ) const { #if !defined( TILES ) ( void ) capture_win; - return std::make_pair( point(), false ); + return cata::nullopt; #else if( !coordinate_input_received ) { - return std::make_pair( point(), false ); + return cata::nullopt; } - const window_dimensions dim = get_window_dimensions( capture_win ); - const int &fw = dim.scaled_font_size.x; const int &fh = dim.scaled_font_size.y; const point &win_min = dim.window_pos_pixel; - const point &win_size = dim.window_size_pixel; - const point win_max = win_min + win_size; - - const half_open_rectangle win_bounds( win_min, win_max ); - const point screen_pos = coordinate - win_min; const point selected( divide_round_down( screen_pos.x, fw ), divide_round_down( screen_pos.y, fh ) ); - - if( !win_bounds.contains( coordinate ) ) { - return std::make_pair( selected, false ); - } - - return std::make_pair( selected, true ); + return selected; #endif } diff --git a/src/input.h b/src/input.h index 8fb91effdbdc0..b1f9770337242 100644 --- a/src/input.h +++ b/src/input.h @@ -715,7 +715,10 @@ class input_context */ input_event get_raw_input(); - std::pair get_coordinates_text( const catacurses::window &capture_win ) const; + /** + * Get coordinate of text level from mouse input, difference between this and get_coordinates is that one is getting pixel level coordinate. + */ + cata::optional get_coordinates_text( const catacurses::window &capture_win ) const; /** * Get the human-readable name for an action. diff --git a/src/inventory.cpp b/src/inventory.cpp index 3d8375f1f24e5..9b86ae27849b5 100644 --- a/src/inventory.cpp +++ b/src/inventory.cpp @@ -591,7 +591,8 @@ void inventory::form_from_map( map &m, std::vector pts, const Characte item food_processor = item_with_battery( "food_processor", veh_battery ); add_item( food_processor ); - item press = item_with_battery( "press", veh_battery ); + item press = item( "press" ); + press.item_tags.insert( "PSEUDO" ); add_item( press ); } if( forgepart ) { diff --git a/src/inventory.h b/src/inventory.h index 1d359a8bc8f1d..1408f18805031 100644 --- a/src/inventory.h +++ b/src/inventory.h @@ -18,7 +18,7 @@ #include "cata_utility.h" #include "item.h" #include "item_stack.h" -#include "units.h" +#include "units_fwd.h" #include "visitable.h" class Character; diff --git a/src/inventory_ui.cpp b/src/inventory_ui.cpp index a0e1ade52ba47..63aedfa28fe55 100644 --- a/src/inventory_ui.cpp +++ b/src/inventory_ui.cpp @@ -22,10 +22,12 @@ #include "translations.h" #include "type_id.h" #include "ui_manager.h" +#include "units_utility.h" #include "vehicle.h" #include "vehicle_selector.h" #include "visitable.h" #include "vpart_position.h" +#include "sdltiles.h" #if defined(__ANDROID__) #include @@ -168,7 +170,7 @@ nc_color inventory_entry::get_invlet_color() const { if( !is_selectable() ) { return c_dark_gray; - } else if( get_player_character().inv.assigned_invlet.count( get_invlet() ) ) { + } else if( get_player_character().inv->assigned_invlet.count( get_invlet() ) ) { return c_yellow; } else { return c_white; @@ -811,8 +813,8 @@ void inventory_column::prepare_paging( const std::string &filter ) Character &player_character = get_player_character(); // Place favorite items and items with an assigned inventory letter first, // since the player cared enough to assign them - const bool left_has_invlet = player_character.inv.assigned_invlet.count( lhs.any_item()->invlet ); - const bool right_has_invlet = player_character.inv.assigned_invlet.count( rhs.any_item()->invlet ); + const bool left_has_invlet = player_character.inv->assigned_invlet.count( lhs.any_item()->invlet ); + const bool right_has_invlet = player_character.inv->assigned_invlet.count( rhs.any_item()->invlet ); if( left_has_invlet != right_has_invlet ) { return left_has_invlet; } @@ -919,12 +921,12 @@ static int num_parents( const item_location &loc ) return 2 + num_parents( loc.parent_item() ); } -void inventory_column::draw( const catacurses::window &win, const point &p ) +void inventory_column::draw( const catacurses::window &win, const point &p, + std::vector, inventory_entry *>> &rect_entry_map ) { if( !visible() ) { return; } - const auto available_cell_width = [ this ]( size_t index, size_t cell_index ) { const size_t displayed_width = cells[cell_index].current_width; const size_t real_width = get_entry_cell_width( index, cell_index ); @@ -933,6 +935,7 @@ void inventory_column::draw( const catacurses::window &win, const point &p ) }; // Do the actual drawing + rect_entry_map.clear(); for( size_t index = page_offset, line = 0; index < entries.size() && line < entries_per_page; ++index, ++line ) { inventory_entry &entry = entries[index]; @@ -954,10 +957,11 @@ void inventory_column::draw( const catacurses::window &win, const point &p ) const bool selected = active && is_selected( entry ); - entry.drawn_info.text_x_start = x1; const int hx_max = p.x + get_width() + contained_offset; - entry.drawn_info.text_x_end = hx_max; - entry.drawn_info.y = yy; + inclusive_rectangle rect = inclusive_rectangle( point( x1, yy ), + point( hx_max - 1, yy ) ); + rect_entry_map.push_back( std::pair, inventory_entry *>( rect, + &entry ) ); if( selected && visible_cells() > 1 ) { for( int hx = x1; hx < hx_max; ++hx ) { @@ -1294,7 +1298,7 @@ void inventory_selector::add_character_items( Character &character ) return VisitResponse::NEXT; } ); // Visitable interface does not support stacks so it has to be here - for( std::list *elem : character.inv.slice() ) { + for( std::list *elem : character.inv->slice() ) { add_items( own_inv_column, [&character]( item * it ) { return item_location( character, it ); }, restack_items( ( *elem ).begin(), ( *elem ).end(), preset.get_checking_components() ) ); @@ -1418,20 +1422,11 @@ inventory_entry *inventory_selector::find_entry_by_invlet( int invlet ) const return nullptr; } -inventory_entry *inventory_selector::find_entry_by_coordinate( point coordinate ) const +inventory_entry *inventory_selector::find_entry_by_coordinate( const point coordinate ) const { - std::vector columns = get_visible_columns(); - const auto filter_to_selected = [&]( const inventory_entry & entry ) { - return entry.is_selectable(); - }; - for( inventory_column *column : columns ) { - std::vector entries = column->get_entries( filter_to_selected ); - for( inventory_entry *entry : entries ) { - if( entry->drawn_info.text_x_start <= coordinate.x && - coordinate.x <= entry->drawn_info.text_x_end && - entry->drawn_info.y == coordinate.y ) { - return entry; - } + for( auto pair : rect_entry_map ) { + if( pair.first.contains( coordinate ) ) { + return pair.second; } } return nullptr; @@ -1765,7 +1760,7 @@ void inventory_selector::draw_columns( const catacurses::window &w ) } if( !is_active_column( *elem ) ) { - elem->draw( w, point( x, y ) ); + elem->draw( w, point( x, y ), rect_entry_map ); } else { active_x = x; } @@ -1773,7 +1768,7 @@ void inventory_selector::draw_columns( const catacurses::window &w ) x += elem->get_width() + gap; } - get_active_column().draw( w, point( active_x, y ) ); + get_active_column().draw( w, point( active_x, y ), rect_entry_map ); if( empty() ) { center_print( w, getmaxy( w ) / 2, c_dark_gray, _( "Your inventory is empty." ) ); } @@ -1887,12 +1882,14 @@ inventory_input inventory_selector::get_input() res.action = ctxt.handle_input(); res.ch = ctxt.get_raw_input().get_first_input(); - std::pair ct_pair = ctxt.get_coordinates_text( w_inv ); - if( ct_pair.second ) { - point p = ct_pair.first; - res.entry = find_entry_by_coordinate( p ); - if( res.entry != nullptr ) { - return res; + cata::optional o_p = ctxt.get_coordinates_text( w_inv ); + if( o_p ) { + point p = o_p.value(); + if( window_contains_point_relative( w_inv, p ) ) { + res.entry = find_entry_by_coordinate( p ); + if( res.entry != nullptr && res.entry->is_selectable() ) { + return res; + } } } diff --git a/src/inventory_ui.h b/src/inventory_ui.h index 468a6361bd54b..9e271d39a3f1f 100644 --- a/src/inventory_ui.h +++ b/src/inventory_ui.h @@ -22,8 +22,9 @@ #include "item_location.h" #include "memory_fast.h" #include "pimpl.h" -#include "units.h" +#include "units_fwd.h" #include "item_category.h" +#include "ui.h" class Character; class item; @@ -47,12 +48,6 @@ struct inventory_input; using drop_location = std::pair; using drop_locations = std::list; -struct inventory_entry_drawn_info { - int text_x_start; - int text_x_end; - int y; -}; - class inventory_entry { public: @@ -133,8 +128,6 @@ class inventory_entry nc_color get_invlet_color() const; void update_cache(); - inventory_entry_drawn_info drawn_info; - private: const item_category *custom_category = nullptr; bool enabled = true; @@ -308,7 +301,8 @@ class inventory_column inventory_entry *find_by_invlet( int invlet ) const; - void draw( const catacurses::window &win, const point & ); + void draw( const catacurses::window &win, const point &p, + std::vector< std::pair, inventory_entry *>> &rect_entry_map ); void add_entry( const inventory_entry &entry ); void move_entries_to( inventory_column &dest ); @@ -594,6 +588,8 @@ class inventory_selector } std::vector get_visible_columns() const; + std::vector< std::pair, inventory_entry *>> rect_entry_map; + private: // These functions are called from resizing/redraw callbacks of ui_adaptor // and should not be made protected or public. diff --git a/src/item.cpp b/src/item.cpp index 46e27af8c82e0..094a7ec21b6e4 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -86,6 +86,7 @@ #include "text_snippets.h" #include "translations.h" #include "units.h" +#include "units_utility.h" #include "value_ptr.h" #include "vehicle.h" #include "vitamin.h" @@ -1395,6 +1396,9 @@ void item::set_owner( const Character &c ) return; } owner = c.get_faction()->id; + for( item *e : contents.all_items_top() ) { + e->set_owner( c ); + } } faction_id item::get_owner() const @@ -3567,7 +3571,7 @@ void item::combat_info( std::vector &info, const iteminfo_query *parts Character &player_character = get_player_character(); // display which martial arts styles character can use with this weapon if( parts->test( iteminfo_parts::DESCRIPTION_APPLICABLEMARTIALARTS ) ) { - const std::string valid_styles = player_character.martial_arts_data.enumerate_known_styles( + const std::string valid_styles = player_character.martial_arts_data->enumerate_known_styles( typeId() ); if( !valid_styles.empty() ) { insert_separation_line( info ); @@ -4133,12 +4137,12 @@ nc_color item::color_in_inventory() const static_cast( iuse->get_actor_ptr() ); for( const std::string &spell_id_str : actor_ptr->spells ) { const spell_id sp_id( spell_id_str ); - if( player_character.magic.knows_spell( sp_id ) && - !player_character.magic.get_spell( sp_id ).is_max_level() ) { + if( player_character.magic->knows_spell( sp_id ) && + !player_character.magic->get_spell( sp_id ).is_max_level() ) { ret = c_yellow; } - if( !player_character.magic.knows_spell( sp_id ) && - player_character.magic.can_learn_spell( player_character, sp_id ) ) { + if( !player_character.magic->knows_spell( sp_id ) && + player_character.magic->can_learn_spell( player_character, sp_id ) ) { return c_light_blue; } } @@ -4259,7 +4263,7 @@ nc_color item::color_in_inventory() const player_character.get_skill_level( tmp.skill ) < tmp.level ) { ret = c_light_blue; } else if( type->can_use( "MA_MANUAL" ) && - !player_character.martial_arts_data.has_martialart( martial_art_learned_from( *type ) ) ) { + !player_character.martial_arts_data->has_martialart( martial_art_learned_from( *type ) ) ) { ret = c_light_blue; } else if( tmp.skill && // Book can't improve skill right now, but maybe later: pink player_character.get_skill_level_object( tmp.skill ).can_train() && @@ -4289,9 +4293,10 @@ void item::on_wear( Character &p ) } } else if( has_flag( flag_TOURNIQUET ) ) { set_side( side::LEFT ); - if( ( covers( bodypart_id( "leg_l" ) ) && p.has_effect( effect_bleed, bp_leg_r ) && + if( ( covers( bodypart_id( "leg_l" ) ) && + p.has_effect( effect_bleed, bodypart_str_id( "leg_r" ) ) && !p.worn_with_flag( flag_TOURNIQUET, bodypart_id( "leg_r" ) ) ) || - ( covers( bodypart_id( "arm_l" ) ) && p.has_effect( effect_bleed, bp_arm_r ) && + ( covers( bodypart_id( "arm_l" ) ) && p.has_effect( effect_bleed, bodypart_str_id( "arm_r" ) ) && !p.worn_with_flag( flag_TOURNIQUET, bodypart_id( "arm_r" ) ) ) ) { set_side( side::RIGHT ); } @@ -4333,13 +4338,9 @@ void item::on_takeoff( Character &p ) } } -void item::on_wield( player &p, int mv ) +int item::on_wield_cost( const player &p ) const { - // TODO: artifacts currently only work with the player character - if( p.is_avatar() && type->artifact ) { - g->add_artifact_messages( type->artifact->effects_wielded ); - } - + int mv = 0; // weapons with bayonet/bipod or other generic "unhandiness" if( has_flag( flag_SLOW_WIELD ) && !is_gunmod() ) { float d = 32.0f; // arbitrary linear scaling factor @@ -4350,7 +4351,6 @@ void item::on_wield( player &p, int mv ) } int penalty = get_var( "volume", volume() / units::legacy_volume_factor ) * d; - p.moves -= penalty; mv += penalty; } @@ -4363,9 +4363,21 @@ void item::on_wield( player &p, int mv ) penalty = std::max( 0, 150 - p.get_skill_level( melee_skill() ) * 10 ); } - p.moves -= penalty; mv += penalty; } + return mv; +} + +void item::on_wield( player &p, int mv ) +{ + // TODO: artifacts currently only work with the player character + if( p.is_avatar() && type->artifact ) { + g->add_artifact_messages( type->artifact->effects_wielded ); + } + + int wield_cost = on_wield_cost( p ); + mv += wield_cost; + p.moves -= wield_cost; std::string msg; @@ -4386,8 +4398,8 @@ void item::on_wield( player &p, int mv ) } p.add_msg_if_player( m_neutral, msg, tname() ); - if( !p.martial_arts_data.selected_is_none() ) { - p.martial_arts_data.martialart_use_message( p ); + if( !p.martial_arts_data->selected_is_none() ) { + p.martial_arts_data->martialart_use_message( p ); } // Update encumbrance in case we were wearing it @@ -4708,6 +4720,9 @@ std::string item::tname( unsigned int quantity, bool with_prefix, unsigned int t if( gunmod_find( itype_barrel_small ) ) { modtext += _( "sawn-off " ); } + if( is_relic() && relic_data->max_charges() > 0 && relic_data->charges_per_use() > 0 ) { + tagtext += string_format( " (%d/%d)", relic_data->charges(), relic_data->max_charges() ); + } if( has_flag( flag_DIAMOND ) ) { modtext += std::string( pgettext( "Adjective, as in diamond katana", "diamond" ) ) + " "; } @@ -7012,7 +7027,7 @@ bool item::spill_contents( Character &c ) return spill_contents( c.pos() ); } - contents.handle_liquid_or_spill( c ); + contents.handle_liquid_or_spill( c, /*avoid=*/this ); on_contents_changed(); return true; @@ -8072,7 +8087,7 @@ bool item::reload( Character &u, item_location ammo, int qty ) if( ammo->charges == 0 && !ammo->has_flag( flag_SPEEDLOADER ) ) { ammo.remove_item(); if( container ) { - u.inv.restack( u ); // emptied containers do not stack with non-empty ones + u.inv->restack( u ); // emptied containers do not stack with non-empty ones } } return true; @@ -9300,6 +9315,11 @@ void item::overwrite_relic( const relic &nrelic ) this->relic_data = cata::make_value( nrelic ); } +bool item::use_relic( Character &guy, const tripoint &pos ) +{ + return relic_data->activate( guy, pos ); +} + void item::process_relic( Character *carrier ) { if( !is_relic() ) { @@ -9317,6 +9337,8 @@ void item::process_relic( Character *carrier ) ench.activate_passive( *carrier ); } + relic_data->try_recharge(); + // Recalculate, as it might have changed (by mod_*_bonus above) carrier->str_cur = carrier->get_str(); carrier->int_cur = carrier->get_int(); @@ -9342,12 +9364,10 @@ bool item::process_corpse( player *carrier, const tripoint &pos ) } if( rng( 0, volume() / units::legacy_volume_factor ) > burnt && g->revive_corpse( pos, *this ) ) { if( carrier == nullptr ) { - if( get_player_character().sees( pos ) ) { - if( corpse->in_species( species_ROBOT ) ) { - add_msg( m_warning, _( "A nearby robot has repaired itself and stands up!" ) ); - } else { - add_msg( m_warning, _( "A nearby corpse rises and moves towards you!" ) ); - } + if( corpse->in_species( species_ROBOT ) ) { + add_msg_if_player_sees( pos, m_warning, _( "A nearby robot has repaired itself and stands up!" ) ); + } else { + add_msg_if_player_sees( pos, m_warning, _( "A nearby corpse rises and moves towards you!" ) ); } } else { if( corpse->in_species( species_ROBOT ) ) { @@ -10294,11 +10314,27 @@ units::volume item::check_for_free_space( const item *it ) const volume += pocket.remaining_volume(); } } - } else { - if( container->contents.contents_are_rigid() ) { - volume += container->volume(); - } } } return volume; } + +int item::get_recursive_disassemble_moves( const Character &guy ) const +{ + int moves = recipe_dictionary::get_uncraft( type->get_id() ).time_to_craft_moves( guy ); + std::vector to_be_disassembled = get_uncraft_components(); + while( !to_be_disassembled.empty() ) { + item_comp current_comp = to_be_disassembled.back(); + to_be_disassembled.pop_back(); + const recipe &r = recipe_dictionary::get_uncraft( current_comp.type->get_id() ); + if( r.ident() != recipe_id::NULL_ID() ) { + moves += r.time_to_craft_moves( guy ) * current_comp.count; + std::vector components = item( current_comp.type->get_id() ).get_uncraft_components(); + for( item_comp &component : components ) { + component.count *= current_comp.count; + to_be_disassembled.push_back( component ); + } + } + } + return moves; +} diff --git a/src/item.h b/src/item.h index 677ada855ed95..0e4c22cd43f22 100644 --- a/src/item.h +++ b/src/item.h @@ -1322,6 +1322,12 @@ class item : public visitable * vector but will be removed immediately after the function returns */ void on_takeoff( Character &p ); + + /** + * Calculate (but do not deduct) the number of moves required to wield this weapon + */ + int on_wield_cost( const player &p ) const; + /** * Callback when a player starts wielding the item. The item is already in the weapon * slot and is called from there. @@ -1347,6 +1353,8 @@ class item : public visitable */ void on_damage( int qty, damage_type dt ); + bool use_relic( Character &guy, const tripoint &pos ); + /** * Name of the item type (not the item), with proper plural. * This is only special when the item itself has a special name ("name" entry in @@ -2127,6 +2135,13 @@ class item : public visitable double calculate_by_enchantment_wield( double modify, enchant_vals::mod value, bool round_value = false ) const; + /** + * Compute the number of moves needed to disassemble this item and its components + * @param guy The character performing the disassembly + * @return The number of moves to recursively disassemble this item + */ + int get_recursive_disassemble_moves( const Character &guy ) const; + private: /** migrates an item into this item. */ void migrate_content_item( const item &contained ); diff --git a/src/item_action.cpp b/src/item_action.cpp index c0aec9984caac..b299262c6b73e 100644 --- a/src/item_action.cpp +++ b/src/item_action.cpp @@ -346,8 +346,8 @@ void game::item_action_menu() u.invoke_item( it, action ); - u.inv.restack( u ); - u.inv.unsort(); + u.inv->restack( u ); + u.inv->unsort(); } std::string use_function::get_type() const diff --git a/src/item_contents.cpp b/src/item_contents.cpp index eff8ea5b097c0..2dd8e636fb406 100644 --- a/src/item_contents.cpp +++ b/src/item_contents.cpp @@ -7,6 +7,7 @@ #include "avatar.h" #include "character.h" #include "enums.h" +#include "inventory.h" #include "item.h" #include "item_category.h" #include "item_factory.h" @@ -722,11 +723,11 @@ bool item_contents::spill_open_pockets( Character &guy, const item *avoid ) return true; } -void item_contents::handle_liquid_or_spill( Character &guy ) +void item_contents::handle_liquid_or_spill( Character &guy, const item *const avoid ) { for( item_pocket &pocket : contents ) { if( pocket.is_type( item_pocket::pocket_type::CONTAINER ) ) { - pocket.handle_liquid_or_spill( guy ); + pocket.handle_liquid_or_spill( guy, avoid ); } } } @@ -1320,19 +1321,6 @@ bool item_contents::all_pockets_rigid() const return true; } -bool item_contents::contents_are_rigid() const -{ - for( const item_pocket &pocket : contents ) { - if( !pocket.is_type( item_pocket::pocket_type::CONTAINER ) ) { - continue; - } - if( !pocket.rigid() ) { - return false; - } - } - return false; -} - units::volume item_contents::item_size_modifier() const { units::volume total_vol = 0_ml; diff --git a/src/item_contents.h b/src/item_contents.h index f56ef9946d894..8971f84fc74d1 100644 --- a/src/item_contents.h +++ b/src/item_contents.h @@ -15,7 +15,7 @@ #include "optional.h" #include "ret_val.h" #include "type_id.h" -#include "units.h" +#include "units_fwd.h" #include "visitable.h" class Character; @@ -133,9 +133,6 @@ class item_contents /** True if every pocket is rigid or we have no pockets */ bool all_pockets_rigid() const; - // True if every pocket is rigid. False if not or we have no pockets - bool contents_are_rigid() const; - /** returns the best quality of the id that's contained in the item in CONTAINER pockets */ int best_quality( const quality_id &id ) const; @@ -200,7 +197,7 @@ class item_contents // does not support multiple magazine pockets! const item &first_ammo() const; // spills all liquid from the container. removing liquid from a magazine requires unload logic. - void handle_liquid_or_spill( Character &guy ); + void handle_liquid_or_spill( Character &guy, const item *avoid = nullptr ); // returns true if any of the pockets will spill if placed into a pocket bool will_spill() const; bool spill_open_pockets( Character &guy, const item *avoid = nullptr ); diff --git a/src/item_factory.cpp b/src/item_factory.cpp index b3b9ec45185e3..14c1e50c20776 100644 --- a/src/item_factory.cpp +++ b/src/item_factory.cpp @@ -101,32 +101,10 @@ static void assign( const JsonObject &jo, const std::string &name, } static bool assign_coverage_from_json( const JsonObject &jo, const std::string &key, - body_part_set &parts, bool &sided ) -{ - auto parse = [&parts, &sided]( const std::string & val ) { - if( val == "ARMS" || val == "ARM_EITHER" ) { - parts.set( bodypart_str_id( "arm_l" ) ); - parts.set( bodypart_str_id( "arm_r" ) ); - } else if( val == "HANDS" || val == "HAND_EITHER" ) { - parts.set( bodypart_str_id( "hand_l" ) ); - parts.set( bodypart_str_id( "hand_r" ) ); - } else if( val == "LEGS" || val == "LEG_EITHER" ) { - parts.set( bodypart_str_id( "leg_l" ) ); - parts.set( bodypart_str_id( "leg_r" ) ); - } else if( val == "FEET" || val == "FOOT_EITHER" ) { - parts.set( bodypart_str_id( "foot_l" ) ); - parts.set( bodypart_str_id( "foot_r" ) ); - } else { - // Convert from legacy enum to new and apply coverage - if( !is_legacy_bodypart_id( val ) ) { - parts.set( bodypart_str_id( val ) ); - } else { - parts.set( convert_bp( get_body_part_token( val ) ) ); - } - } - - sided |= val == "ARM_EITHER" || val == "HAND_EITHER" || - val == "LEG_EITHER" || val == "FOOT_EITHER"; + body_part_set &parts ) +{ + auto parse = [&parts]( const std::string & val ) { + parts.set( bodypart_str_id( val ) ); }; if( jo.has_array( key ) ) { @@ -1890,7 +1868,8 @@ void islot_armor::load( const JsonObject &jo ) data[0].coverage = tempData.coverage; } body_part_set temp_cover_data; - assign_coverage_from_json( obj, "covers", temp_cover_data, sided ); + assign_coverage_from_json( obj, "covers", temp_cover_data ); + optional( obj, was_loaded, "sided", sided, false ); if( temp_cover_data.any() ) { data[0].covers = temp_cover_data; } @@ -1905,7 +1884,8 @@ void islot_armor::load( const JsonObject &jo ) } armor_portion_data tempData; body_part_set temp_cover_data; - assign_coverage_from_json( obj, "covers", temp_cover_data, sided ); + assign_coverage_from_json( obj, "covers", temp_cover_data ); + optional( obj, was_loaded, "sided", sided, false ); tempData.covers = temp_cover_data; if( obj.has_array( "encumbrance" ) ) { @@ -1940,7 +1920,8 @@ void islot_armor::load( const JsonObject &jo ) optional( jo, was_loaded, "max_encumbrance", data[0].max_encumber, -1 ); optional( jo, was_loaded, "coverage", data[0].coverage, 0 ); body_part_set temp_cover_data; - assign_coverage_from_json( jo, "covers", temp_cover_data, sided ); + assign_coverage_from_json( jo, "covers", temp_cover_data ); + optional( jo, was_loaded, "sided", sided, false ); data[0].covers = temp_cover_data; } else { // This item has copy-from and already has taken data from parent armor_portion_data child_data; @@ -1966,7 +1947,8 @@ void islot_armor::load( const JsonObject &jo ) data[0].coverage = child_data.coverage; } body_part_set temp_cover_data; - assign_coverage_from_json( jo, "covers", temp_cover_data, sided ); + assign_coverage_from_json( jo, "covers", temp_cover_data ); + optional( jo, was_loaded, "sided", sided, false ); if( temp_cover_data.any() ) { data[0].covers = temp_cover_data; } diff --git a/src/item_location.cpp b/src/item_location.cpp index 40cdc415e08a2..e96ab33cabf4e 100644 --- a/src/item_location.cpp +++ b/src/item_location.cpp @@ -597,16 +597,23 @@ class item_location::impl::item_in_container : public item_location::impl debugmsg( "ERROR: %s does not contain %s", container->tname(), target()->tname() ); return 0; } + + int primary_cost = ch.mutation_value( "obtain_cost_multiplier" ) * ch.item_handling_cost( *target(), + true, container_mv ); int parent_obtain_cost = container.obtain_cost( ch, qty ); - if( container.where() != item_location::type::container ) { + if( container->get_use( "holster" ) ) { + if( ch.is_worn( *container ) ) { + primary_cost = ch.item_retrieve_cost( *target(), *container, false, container_mv ); + } else { + primary_cost = ch.item_retrieve_cost( *target(), *container ); + } + // for holsters, we should not include the cost of wielding the holster itself + parent_obtain_cost = 0; + } else if( container.where() != item_location::type::container ) { // a little bonus for grabbing something from what you're wearing - // TODO: Differentiate holsters from backpacks parent_obtain_cost /= 2; } - return ch.mutation_value( "obtain_cost_multiplier" ) * - ch.item_handling_cost( *target(), true, container_mv ) + - // we aren't "obtaining" the parent item, just digging through it - parent_obtain_cost; + return primary_cost + parent_obtain_cost; } }; diff --git a/src/item_pocket.cpp b/src/item_pocket.cpp index d2eea3817c79b..1ab09ca22c0a5 100644 --- a/src/item_pocket.cpp +++ b/src/item_pocket.cpp @@ -16,6 +16,7 @@ #include "player.h" #include "point.h" #include "units.h" +#include "units_utility.h" namespace io { @@ -278,6 +279,9 @@ bool item_pocket::better_pocket( const item_pocket &rhs, const item &it ) const bool item_pocket::stacks_with( const item_pocket &rhs ) const { + if( _sealed != rhs._sealed ) { + return false; + } return ( empty() && rhs.empty() ) || std::equal( contents.begin(), contents.end(), rhs.contents.begin(), rhs.contents.end(), []( const item & a, const item & b ) { @@ -291,8 +295,6 @@ bool item_pocket::is_funnel_container( units::volume &bigger_than ) const // such as item types, may be invalidated. const std::vector allowed_liquids{ item( "water", calendar::turn_zero, 1 ), - item( "water_acid", calendar::turn_zero, 1 ), - item( "water_acid_weak", calendar::turn_zero, 1 ) }; if( !data->watertight ) { return false; @@ -581,7 +583,7 @@ void item_pocket::handle_liquid_or_spill( Character &guy, const item *avoid ) if( iter->made_of( phase_id::LIQUID ) ) { item liquid( *iter ); iter = contents.erase( iter ); - liquid_handler::handle_all_liquid( liquid, 1 ); + liquid_handler::handle_all_liquid( liquid, 1, avoid ); } else { item i_copy( *iter ); iter = contents.erase( iter ); diff --git a/src/item_stack.h b/src/item_stack.h index b8df981669fd7..908a685e3c9b3 100644 --- a/src/item_stack.h +++ b/src/item_stack.h @@ -6,7 +6,7 @@ #include "colony.h" #include "item.h" // IWYU pragma: keep -#include "units.h" +#include "units_fwd.h" // A wrapper class to bundle up the references needed for a caller to safely manipulate // items and obtain information about items at a particular map x/y location. diff --git a/src/iuse.cpp b/src/iuse.cpp index d3125041f71d1..a22f5abc1acb5 100644 --- a/src/iuse.cpp +++ b/src/iuse.cpp @@ -100,6 +100,7 @@ #include "trap.h" #include "type_id.h" #include "ui.h" +#include "units_utility.h" #include "value_ptr.h" #include "veh_type.h" #include "vehicle.h" @@ -595,7 +596,7 @@ int iuse::smoking( player *p, item *it, bool, const tripoint & ) // If we're here, we better have a cig to light. p->use_charges_if_avail( itype_fire, 1 ); cig.active = true; - p->inv.add_item( cig, false, true ); + p->inv->add_item( cig, false, true ); p->add_msg_if_player( m_neutral, _( "You light a %s." ), cig.tname() ); // Parting messages @@ -721,10 +722,9 @@ int iuse::fungicide( player *p, item *it, bool, const tripoint & ) if( here.passable( dest ) && x_in_y( spore_count, 8 ) ) { if( monster *const mon_ptr = g->critter_at( dest ) ) { monster &critter = *mon_ptr; - if( get_player_character().sees( dest ) && - !critter.type->in_species( species_FUNGUS ) ) { - add_msg( m_warning, _( "The %s is covered in tiny spores!" ), - critter.name() ); + if( !critter.type->in_species( species_FUNGUS ) ) { + add_msg_if_player_sees( dest, m_warning, _( "The %s is covered in tiny spores!" ), + critter.name() ); } if( !critter.make_fungus() ) { critter.die( p ); // counts as kill by player @@ -922,7 +922,7 @@ int iuse::flu_vaccine( player *p, item *it, bool, const tripoint & ) // FIXME Removing feedback and visible status would be more realistic if( remaining_time > 0_turns ) { p->add_msg_if_player( m_good, _( "You no longer need to fear the flu, at least for some time." ) ); - p->add_effect( effect_flushot, remaining_time, num_bp, false ); + p->add_effect( effect_flushot, remaining_time, false ); } else { p->add_msg_if_player( m_bad, _( "You notice the date on the packaging is pretty old. It may no longer be effective." ) ); @@ -937,7 +937,7 @@ int iuse::antiasthmatic( player *p, item *it, bool, const tripoint & ) { p->add_msg_if_player( m_good, _( "You no longer need to worry about asthma attacks, at least for a while." ) ); - p->add_effect( effect_took_antiasthmatic, 1_days, num_bp, true ); + p->add_effect( effect_took_antiasthmatic, 1_days, true ); return it->type->charges_to_use(); } @@ -1621,7 +1621,7 @@ static int feedpet( player &p, monster &mon, item &it, m_flag food_flag, const c if( mon.has_flag( food_flag ) ) { p.add_msg_if_player( m_good, message, mon.get_name() ); mon.friendly = -1; - mon.add_effect( effect_pet, 1_turns, num_bp, true ); + mon.add_effect( effect_pet, 1_turns, true ); p.consume_charges( it, 1 ); return 0; } else { @@ -2037,15 +2037,15 @@ int iuse::extinguisher( player *p, item *it, bool, const tripoint & ) blind = true; critter.add_effect( effect_blind, rng( 1_minutes, 2_minutes ) ); } - Character &player_character = get_player_character(); - if( player_character.sees( critter ) ) { + viewer &player_view = get_player_view(); + if( player_view.sees( critter ) ) { p->add_msg_if_player( _( "The %s is sprayed!" ), critter.name() ); if( blind ) { p->add_msg_if_player( _( "The %s looks blinded." ), critter.name() ); } } if( critter.made_of( phase_id::LIQUID ) ) { - if( player_character.sees( critter ) ) { + if( player_view.sees( critter ) ) { p->add_msg_if_player( _( "The %s is frozen!" ), critter.name() ); } critter.apply_damage( p, bodypart_id( "torso" ), rng( 20, 60 ) ); @@ -2393,7 +2393,7 @@ int iuse::ma_manual( player *p, item *it, bool, const tripoint & ) return 0; } - p->martial_arts_data.learn_style( style_to_learn, p->is_avatar() ); + p->martial_arts_data->learn_style( style_to_learn, p->is_avatar() ); return 1; } @@ -3658,21 +3658,16 @@ int iuse::can_goo( player *p, item *it, bool, const tripoint & ) if( tries == 10 ) { return 0; } - Character &player_character = get_player_character(); if( monster *const mon_ptr = g->critter_at( goop ) ) { monster &critter = *mon_ptr; - if( player_character.sees( goop ) ) { - add_msg( _( "Black goo emerges from the canister and envelopes a %s!" ), - critter.name() ); - } + add_msg_if_player_sees( goop, _( "Black goo emerges from the canister and envelopes a %s!" ), + critter.name() ); critter.poly( mon_blob ); critter.set_speed_base( critter.get_speed_base() - rng( 5, 25 ) ); critter.set_hp( critter.get_speed() ); } else { - if( player_character.sees( goop ) ) { - add_msg( _( "Living black goo emerges from the canister!" ) ); - } + add_msg_if_player_sees( goop, _( "Living black goo emerges from the canister!" ) ); if( monster *const goo = g->place_critter_at( mon_blob, goop ) ) { goo->friendly = -1; } @@ -3687,9 +3682,7 @@ int iuse::can_goo( player *p, item *it, bool, const tripoint & ) found = here.passable( goop ) && here.tr_at( goop ).is_null(); } while( !found && tries < 10 ); if( found ) { - if( player_character.sees( goop ) ) { - add_msg( m_warning, _( "A nearby splatter of goo forms into a goo pit." ) ); - } + add_msg_if_player_sees( goop, m_warning, _( "A nearby splatter of goo forms into a goo pit." ) ); here.trap_set( goop, tr_goo ); } else { return 0; @@ -4087,7 +4080,7 @@ int iuse::pheromone( player *p, item *it, bool, const tripoint &pos ) } } - if( get_player_character().sees( *p ) ) { + if( get_player_view().sees( *p ) ) { if( converts == 0 ) { add_msg( _( "…but nothing happens." ) ); } else if( converts == 1 ) { @@ -4763,7 +4756,7 @@ int iuse::dog_whistle( player *p, item *it, bool, const tripoint & ) p->add_msg_if_player( _( "You blow your dog whistle." ) ); for( monster &critter : g->all_monsters() ) { if( critter.friendly != 0 && critter.has_flag( MF_DOGFOOD ) ) { - bool u_see = get_player_character().sees( critter ); + bool u_see = get_player_view().sees( critter ); if( critter.has_effect( effect_docile ) ) { if( u_see ) { p->add_msg_if_player( _( "Your %s looks ready to attack." ), critter.name() ); @@ -4773,7 +4766,7 @@ int iuse::dog_whistle( player *p, item *it, bool, const tripoint & ) if( u_see ) { p->add_msg_if_player( _( "Your %s goes docile." ), critter.name() ); } - critter.add_effect( effect_docile, 1_turns, num_bp, true ); + critter.add_effect( effect_docile, 1_turns, true ); } } } @@ -4836,7 +4829,7 @@ int iuse::blood_draw( player *p, item *it, bool, const tripoint & ) } if( acid_blood ) { - item acid( "acid", calendar::turn ); + item acid( "chem_sulphuric_acid", calendar::turn ); it->put_in( acid, item_pocket::pocket_type::CONTAINER ); if( one_in( 3 ) ) { if( it->inc_damage( DT_ACID ) ) { @@ -5453,7 +5446,7 @@ int iuse::artifact( player *p, item *it, bool, const tripoint & ) bool blood = false; for( const tripoint &tmp : here.points_in_radius( p->pos(), 4 ) ) { if( !one_in( 4 ) && here.add_field( tmp, fd_blood, 3 ) && - ( blood || get_player_character().sees( tmp ) ) ) { + ( blood || get_player_view().sees( tmp ) ) ) { blood = true; } } @@ -5537,7 +5530,7 @@ int iuse::artifact( player *p, item *it, bool, const tripoint & ) for( int j = 0; j < num; j++ ) { if( monster *const b = g->place_critter_around( bug, p->pos(), 1 ) ) { b->friendly = -1; - b->add_effect( effect_pet, 1_turns, num_bp, true ); + b->add_effect( effect_pet, 1_turns, true ); } } } @@ -5995,7 +5988,7 @@ int iuse::jet_injector( player *p, item *it, bool, const tripoint & ) } else { p->add_msg_if_player( _( "You inject yourself with the jet injector." ) ); // Intensity is 2 here because intensity = 1 is the comedown - p->add_effect( effect_jetinjector, 20_minutes, num_bp, false, 2 ); + p->add_effect( effect_jetinjector, 20_minutes, false, 2 ); p->mod_painkiller( 20 ); p->mod_stim( 10 ); p->healall( 20 ); @@ -6023,7 +6016,7 @@ int iuse::stimpack( player *p, item *it, bool, const tripoint & ) } else { p->add_msg_if_player( _( "You inject yourself with the stimulants." ) ); // Intensity is 2 here because intensity = 1 is the comedown - p->add_effect( effect_stimpack, 25_minutes, num_bp, false, 2 ); + p->add_effect( effect_stimpack, 25_minutes, false, 2 ); p->mod_painkiller( 2 ); p->mod_stim( 20 ); p->mod_fatigue( -100 ); @@ -6376,7 +6369,7 @@ int iuse::robotcontrol( player *p, item *it, bool, const tripoint & ) if( critter.friendly != 0 && critter.type->in_species( species_ROBOT ) ) { p->add_msg_if_player( _( "A following %s goes into passive mode." ), critter.name() ); - critter.add_effect( effect_docile, 1_turns, num_bp, true ); + critter.add_effect( effect_docile, 1_turns, true ); f = 1; } } @@ -8242,7 +8235,7 @@ int iuse::radiocar( player *p, item *it, bool, const tripoint & ) } else { // Disarm the car p->moves -= to_moves( 2_seconds ); - p->inv.assign_empty_invlet( *bomb_it, *p, true ); // force getting an invlet. + p->inv->assign_empty_invlet( *bomb_it, *p, true ); // force getting an invlet. p->i_add( *bomb_it ); it->remove_item( *bomb_it ); @@ -8625,7 +8618,7 @@ static bool multicooker_hallu( player &p ) add_msg( m_warning, _( "The multi-cooker runs away!" ) ); if( monster *const m = g->place_critter_around( mon_hallu_multicooker, p.pos(), 1 ) ) { m->hallucination = true; - m->add_effect( effect_run, 1_turns, num_bp, true ); + m->add_effect( effect_run, 1_turns, true ); } } else { p.add_msg_if_player( m_info, _( "You're surrounded by aggressive multi-cookers!" ) ); @@ -9796,7 +9789,7 @@ int iuse::wash_items( player *p, bool soft_items, bool hard_items ) p->add_msg_if_player( m_info, _( "You cannot do that while mounted." ) ); return 0; } - p->inv.restack( *p ); + p->inv->restack( *p ); const inventory &crafting_inv = p->crafting_inventory(); auto is_liquid = []( const item & it ) { diff --git a/src/iuse.h b/src/iuse.h index ddc3779b59180..fe50fa17dcbaa 100644 --- a/src/iuse.h +++ b/src/iuse.h @@ -9,7 +9,7 @@ #include "clone_ptr.h" #include "type_id.h" -#include "units.h" +#include "units_fwd.h" class Character; class JsonObject; diff --git a/src/iuse_actor.cpp b/src/iuse_actor.cpp index 04c4cf4f3bc0f..5042a6265a9ed 100644 --- a/src/iuse_actor.cpp +++ b/src/iuse_actor.cpp @@ -77,6 +77,7 @@ #include "translations.h" #include "trap.h" #include "ui.h" +#include "units_utility.h" #include "value_ptr.h" #include "vehicle.h" #include "vehicle_selector.h" @@ -787,7 +788,7 @@ int consume_drug_iuse::use( player &p, item &it, bool, const tripoint & ) const } else if( p.has_trait( trait_LIGHTWEIGHT ) ) { dur *= 1.2; } - p.add_effect( eff.id, dur, eff.bp, eff.permanent ); + p.add_effect( eff.id, dur, convert_bp( eff.bp ).id(), eff.permanent ); } //Apply the various damage_over_time for( const damage_over_time_data &Dot : damage_over_time ) { @@ -949,7 +950,7 @@ int place_monster_iuse::use( player &p, item &it, bool, const tripoint & ) const } newmon.friendly = -1; if( is_pet ) { - newmon.add_effect( effect_pet, 1_turns, num_bp, true ); + newmon.add_effect( effect_pet, 1_turns, true ); } } return 1; @@ -971,20 +972,16 @@ void place_npc_iuse::load( const JsonObject &obj ) int place_npc_iuse::use( player &p, item &, bool, const tripoint & ) const { map &here = get_map(); - cata::optional target_pos; - if( place_randomly ) { - const tripoint_range target_range = points_in_radius( p.pos(), 1 ); - target_pos = random_point( target_range, [&here]( const tripoint & t ) { - return !here.passable( t ); - } ); - } else { - const std::string query = _( "Place npc where?" ); - target_pos = choose_adjacent( _( "Place npc where?" ) ); - } - if( !target_pos ) { - return 0; - } - if( !here.passable( target_pos.value() ) ) { + const tripoint_range target_range = place_randomly ? + points_in_radius( p.pos(), radius ) : + points_in_radius( choose_adjacent( _( "Place npc where?" ) ).value_or( p.pos() ), 0 ); + + const cata::optional target_pos = + random_point( target_range, [&here]( const tripoint & t ) { + return here.passable( t ) && here.has_floor_or_support( t ) && !g->critter_at( t ); + } ); + + if( !target_pos.has_value() ) { p.add_msg_if_player( m_info, _( "There is no square to spawn npc in!" ) ); return 0; } @@ -1714,11 +1711,11 @@ bool cauterize_actor::cauterize_effect( player &p, item &it, bool force ) } else { p.add_msg_if_player( m_neutral, _( "It itches a little." ) ); } - if( p.has_effect( effect_bleed, hpart->token ) ) { + if( p.has_effect( effect_bleed, hpart.id() ) ) { p.add_msg_if_player( m_bad, _( "Bleeding has not stopped completely!" ) ); } - if( p.has_effect( effect_bite, hpart->token ) ) { - p.add_effect( effect_bite, 260_minutes, hpart->token, true ); + if( p.has_effect( effect_bite, hpart.id() ) ) { + p.add_effect( effect_bite, 260_minutes, hpart, true ); } p.moves = 0; @@ -2039,7 +2036,7 @@ int musical_instrument_actor::use( player &p, item &it, bool t, const tripoint & if( p.get_effect_int( effect_playing_instrument ) <= speed_penalty ) { // Only re-apply the effect if it wouldn't lower the intensity - p.add_effect( effect_playing_instrument, 2_turns, num_bp, false, speed_penalty ); + p.add_effect( effect_playing_instrument, 2_turns, false, speed_penalty ); } std::string desc = "music"; @@ -2139,8 +2136,8 @@ int learn_spell_actor::use( player &p, item &, bool, const tripoint & ) const const spell_id sp_id( sp_id_str ); sp_cb.add_spell( sp_id ); uilist_entry entry( sp_id.obj().name.translated() ); - if( p.magic.knows_spell( sp_id ) ) { - const spell sp = p.magic.get_spell( sp_id ); + if( p.magic->knows_spell( sp_id ) ) { + const spell sp = p.magic->get_spell( sp_id ); entry.ctxt = string_format( _( "Level %u" ), sp.get_level() ); if( sp.is_max_level() ) { entry.ctxt += _( " (Max)" ); @@ -2149,7 +2146,7 @@ int learn_spell_actor::use( player &p, item &, bool, const tripoint & ) const know_it_all = false; } } else { - if( p.magic.can_learn_spell( p, sp_id ) ) { + if( p.magic->can_learn_spell( p, sp_id ) ) { entry.ctxt = _( "Study to Learn" ); know_it_all = false; } else { @@ -2176,9 +2173,9 @@ int learn_spell_actor::use( player &p, item &, bool, const tripoint & ) const if( action < 0 ) { return 0; } - const bool knows_spell = p.magic.knows_spell( spells[action] ); + const bool knows_spell = p.magic->knows_spell( spells[action] ); player_activity study_spell( ACT_STUDY_SPELL, - p.magic.time_to_learn_spell( p, spells[action] ) ); + p.magic->time_to_learn_spell( p, spells[action] ) ); study_spell.str_values = { "", // reserved for "until you gain a spell level" option [0] "learn" @@ -2203,7 +2200,7 @@ int learn_spell_actor::use( player &p, item &, bool, const tripoint & ) const if( study_spell.moves_total == 10100 ) { study_spell.str_values[0] = "gain_level"; study_spell.values[0] = 0; // reserved for xp - study_spell.values[1] = p.magic.get_spell( spell_id( spells[action] ) ).get_level() + 1; + study_spell.values[1] = p.magic->get_spell( spell_id( spells[action] ) ).get_level() + 1; } study_spell.name = spells[action]; p.assign_activity( study_spell, false ); @@ -3209,14 +3206,14 @@ int heal_actor::finish_using( player &healer, player &patient, item &it, bodypar } }; - if( patient.has_effect( effect_bleed, healed->token ) ) { + if( patient.has_effect( effect_bleed, healed.id() ) ) { // small band-aids won't stop big arterial bleeding, but with tourniquet they just might int pwr = 3 * get_stopbleed_level( healer ); - if( patient.worn_with_flag( "TOURNIQUET", convert_bp( healed->token ) ) ) { + if( patient.worn_with_flag( "TOURNIQUET", healed ) ) { pwr *= 2; } - if( pwr > patient.get_effect_int( effect_bleed, healed->token ) ) { - effect &wound = patient.get_effect( effect_bleed, healed->token ); + if( pwr > patient.get_effect_int( effect_bleed, healed ) ) { + effect &wound = patient.get_effect( effect_bleed, healed ); time_duration dur = wound.get_duration() - ( get_stopbleed_level( healer ) * wound.get_int_dur_factor() ); wound.set_duration( std::max( 0_turns, dur ) ); @@ -3233,9 +3230,9 @@ int heal_actor::finish_using( player &healer, player &patient, item &it, bodypar } practice_amount += bleed / 3.0f; } - if( patient.has_effect( effect_bite, healed->token ) ) { + if( patient.has_effect( effect_bite, healed.id() ) ) { if( x_in_y( bite, 1.0f ) ) { - patient.remove_effect( effect_bite, healed->token ); + patient.remove_effect( effect_bite, healed ); heal_msg( m_good, _( "You clean the wound." ), _( "The wound is cleaned." ) ); } else { heal_msg( m_warning, _( "Your wound still aches." ), _( "The wound still looks bad." ) ); @@ -3243,10 +3240,10 @@ int heal_actor::finish_using( player &healer, player &patient, item &it, bodypar practice_amount += bite * 3.0f; } - if( patient.has_effect( effect_infected, healed->token ) ) { + if( patient.has_effect( effect_infected, healed.id() ) ) { if( x_in_y( infect, 1.0f ) ) { - const time_duration infected_dur = patient.get_effect_dur( effect_infected, healed->token ); - patient.remove_effect( effect_infected, healed->token ); + const time_duration infected_dur = patient.get_effect_dur( effect_infected, healed ); + patient.remove_effect( effect_infected, healed ); patient.add_effect( effect_recover, infected_dur ); heal_msg( m_good, _( "You disinfect the wound." ), _( "The wound is disinfected." ) ); } else { @@ -3261,7 +3258,7 @@ int heal_actor::finish_using( player &healer, player &patient, item &it, bodypar } for( const auto &eff : effects ) { - patient.add_effect( eff.id, eff.duration, eff.bp, eff.permanent ); + patient.add_effect( eff.id, eff.duration, convert_bp( eff.bp ).id(), eff.permanent ); } if( !used_up_item_id.is_empty() ) { @@ -3285,8 +3282,8 @@ int heal_actor::finish_using( player &healer, player &patient, item &it, bodypar // apply healing over time effects if( bandages_power > 0 ) { int bandages_intensity = get_bandaged_level( healer ); - patient.add_effect( effect_bandaged, 1_turns, healed->token ); - effect &e = patient.get_effect( effect_bandaged, healed->token ); + patient.add_effect( effect_bandaged, 1_turns, healed ); + effect &e = patient.get_effect( effect_bandaged, healed ); e.set_duration( e.get_int_dur_factor() * bandages_intensity ); patient.set_part_damage_bandaged( healed, patient.get_part_hp_max( healed ) - patient.get_part_hp_cur( healed ) ); @@ -3294,8 +3291,8 @@ int heal_actor::finish_using( player &healer, player &patient, item &it, bodypar } if( disinfectant_power > 0 ) { int disinfectant_intensity = get_disinfected_level( healer ); - patient.add_effect( effect_disinfected, 1_turns, healed->token ); - effect &e = patient.get_effect( effect_disinfected, healed->token ); + patient.add_effect( effect_disinfected, 1_turns, healed ); + effect &e = patient.get_effect( effect_disinfected, healed ); e.set_duration( e.get_int_dur_factor() * disinfectant_intensity ); patient.set_part_damage_disinfected( healed, patient.get_part_hp_max( healed ) - patient.get_part_hp_cur( healed ) ); @@ -3331,9 +3328,9 @@ static bodypart_id pick_part_to_heal( return bodypart_id( "bp_null" ); } - if( ( infect && patient.has_effect( effect_infected, healed_part->token ) ) || - ( bite && patient.has_effect( effect_bite, healed_part->token ) ) || - ( bleed && patient.has_effect( effect_bleed, healed_part->token ) ) ) { + if( ( infect && patient.has_effect( effect_infected, healed_part.id() ) ) || + ( bite && patient.has_effect( effect_bite, healed_part.id() ) ) || + ( bleed && patient.has_effect( effect_bleed, healed_part.id() ) ) ) { return healed_part; } @@ -3377,14 +3374,14 @@ bodypart_id heal_actor::use_healing_item( player &healer, player &patient, item for( const std::pair &elem : patient.get_body() ) { const bodypart &part = elem.second; int damage = 0; - if( ( !patient.has_effect( effect_bandaged, elem.first->token ) && bandages_power > 0 ) || - ( !patient.has_effect( effect_disinfected, elem.first->token ) && disinfectant_power > 0 ) ) { + if( ( !patient.has_effect( effect_bandaged, elem.first ) && bandages_power > 0 ) || + ( !patient.has_effect( effect_disinfected, elem.first ) && disinfectant_power > 0 ) ) { damage += part.get_hp_max() - part.get_hp_cur(); - damage += bite * patient.get_effect_dur( effect_bite, elem.first->token ) / 10_minutes; - damage += infect * patient.get_effect_dur( effect_infected, elem.first->token ) / 10_minutes; + damage += bite * patient.get_effect_dur( effect_bite, elem.first ) / 10_minutes; + damage += infect * patient.get_effect_dur( effect_infected, elem.first ) / 10_minutes; } - if( patient.get_effect_int( effect_bleed, elem.first->token ) > 5 && bleed > 0 ) { - damage += bleed * patient.get_effect_dur( effect_bleed, elem.first->token ) / 5_minutes; + if( patient.get_effect_int( effect_bleed, elem.first ) > 5 && bleed > 0 ) { + damage += bleed * patient.get_effect_dur( effect_bleed, elem.first ) / 5_minutes; } if( damage > highest_damage ) { highest_damage = damage; @@ -3919,7 +3916,7 @@ int mutagen_actor::use( player &p, item &it, bool, const tripoint & ) const p.add_msg_player_or_npc( m_bad, _( "You suddenly feel dizzy, and collapse to the ground." ), _( " suddenly collapses to the ground!" ) ); - p.add_effect( effect_downed, 1_turns, num_bp, false, 0, true ); + p.add_effect( effect_downed, 1_turns, false, 0, true ); } int mut_count = 1 + ( is_strong ? one_in( 3 ) : 0 ); @@ -4395,14 +4392,14 @@ int change_scent_iuse::use( player &p, item &it, bool, const tripoint & ) const if( waterproof ) { p.set_value( "waterproof_scent", "true" ); } - p.add_effect( efftype_id( "masked_scent" ), duration, num_bp, false, scent_mod ); + p.add_effect( efftype_id( "masked_scent" ), duration, false, scent_mod ); p.set_type_of_scent( scenttypeid ); p.mod_moves( -moves ); add_msg( m_info, _( "You use the %s to mask your scent" ), it.tname() ); // Apply the various effects. for( const auto &eff : effects ) { - p.add_effect( eff.id, eff.duration, eff.bp, eff.permanent ); + p.add_effect( eff.id, eff.duration, convert_bp( eff.bp ).id(), eff.permanent ); } return charges_to_use; } diff --git a/src/iuse_actor.h b/src/iuse_actor.h index fa8a0310acfa0..a15cddd3d75dd 100644 --- a/src/iuse_actor.h +++ b/src/iuse_actor.h @@ -377,6 +377,7 @@ class place_npc_iuse : public iuse_actor public: string_id npc_class_id; bool place_randomly = false; + int radius = 1; int moves = 100; std::string summon_msg; diff --git a/src/magic.cpp b/src/magic.cpp index 5918f9b397557..4c3aabe53bdd5 100644 --- a/src/magic.cpp +++ b/src/magic.cpp @@ -713,7 +713,7 @@ bool spell::can_cast( Character &guy ) const switch( type->energy_source ) { case magic_energy_type::mana: - return guy.magic.available_mana() >= energy_cost( guy ); + return guy.magic->available_mana() >= energy_cost( guy ); case magic_energy_type::stamina: return guy.get_stamina() >= energy_cost( guy ); case magic_energy_type::hp: { @@ -939,7 +939,7 @@ std::string spell::energy_cur_string( const Character &guy ) const return colorize( to_string( units::to_kilojoule( guy.get_power_level() ) ), c_light_blue ); } if( energy_source() == magic_energy_type::mana ) { - return colorize( to_string( guy.magic.available_mana() ), c_light_blue ); + return colorize( to_string( guy.magic->available_mana() ), c_light_blue ); } if( energy_source() == magic_energy_type::stamina ) { auto pair = get_hp_bar( guy.get_stamina(), guy.get_stamina_max() ); @@ -1396,7 +1396,7 @@ void known_magic::learn_spell( const spell_type *sp, Character &guy, bool force debugmsg( "Tried to learn invalid spell" ); return; } - if( guy.magic.knows_spell( sp->id ) ) { + if( guy.magic->knows_spell( sp->id ) ) { // you already know the spell return; } @@ -1602,7 +1602,7 @@ class spellcasting_callback : public uilist_callback invlet = popup_getkey( _( "Choose a new hotkey for this spell." ) ); if( inv_chars.valid( invlet ) ) { const bool invlet_set = - get_player_character().magic.set_invlet( known_spells[entnum]->id(), invlet, reserved_invlets ); + get_player_character().magic->set_invlet( known_spells[entnum]->id(), invlet, reserved_invlets ); if( !invlet_set ) { popup( _( "Hotkey already used." ) ); } else { @@ -1611,7 +1611,7 @@ class spellcasting_callback : public uilist_callback } } else { popup( _( "Hotkey removed." ) ); - get_player_character().magic.rem_invlet( known_spells[entnum]->id() ); + get_player_character().magic->rem_invlet( known_spells[entnum]->id() ); } return true; } @@ -2219,7 +2219,7 @@ void spell_events::notify( const cata::event &e ) int learn_at_level = it->second; if( learn_at_level == slvl ) { std::string learn_spell_id = it->first; - get_player_character().magic.learn_spell( learn_spell_id, get_player_character() ); + get_player_character().magic->learn_spell( learn_spell_id, get_player_character() ); spell_type spell_learned = spell_factory.obj( spell_id( learn_spell_id ) ); add_msg( _( "Your experience and knowledge in creating and manipulating magical energies to cast %s have opened your eyes to new possibilities, you can now cast %s." ), diff --git a/src/magic_enchantment.cpp b/src/magic_enchantment.cpp index e9c1cd1da5d38..0cd88f7a80000 100644 --- a/src/magic_enchantment.cpp +++ b/src/magic_enchantment.cpp @@ -450,7 +450,7 @@ void enchantment::activate_passive( Character &guy ) const get_map().emit_field( guy.pos(), *emitter ); } for( const std::pair eff : ench_effects ) { - guy.add_effect( eff.first, 1_seconds, num_bp, false, eff.second ); + guy.add_effect( eff.first, 1_seconds, false, eff.second ); } for( const std::pair> &activation : intermittent_activation ) { diff --git a/src/magic_enchantment.h b/src/magic_enchantment.h index b921080af5897..bd6634fdf6291 100644 --- a/src/magic_enchantment.h +++ b/src/magic_enchantment.h @@ -14,7 +14,7 @@ #include "magic.h" #include "optional.h" #include "type_id.h" -#include "units.h" +#include "units_fwd.h" class Character; class Creature; diff --git a/src/magic_spell_effect.cpp b/src/magic_spell_effect.cpp index f7c03d913c539..40412b43fa670 100644 --- a/src/magic_spell_effect.cpp +++ b/src/magic_spell_effect.cpp @@ -405,15 +405,15 @@ static void add_effect_to_target( const tripoint &target, const spell &sp ) bool bodypart_effected = false; if( guy ) { - for( const body_part bp : all_body_parts ) { - if( sp.bp_is_affected( bp ) ) { + for( const bodypart_id &bp : guy->get_all_body_parts() ) { + if( sp.bp_is_affected( bp->token ) ) { guy->add_effect( spell_effect, dur_td, bp, sp.has_flag( spell_flag::PERMANENT ) ); bodypart_effected = true; } } } if( !bodypart_effected ) { - critter->add_effect( spell_effect, dur_td, num_bp ); + critter->add_effect( spell_effect, dur_td ); } } @@ -524,10 +524,8 @@ static void magical_polymorph( monster &victim, Creature &caster, const spell &s return; } - if( get_player_character().sees( victim ) ) { - add_msg( _( "The %s transforms into a %s." ), victim.type->nname(), - new_id->nname() ); - } + add_msg_if_player_sees( victim, _( "The %s transforms into a %s." ), + victim.type->nname(), new_id->nname() ); victim.poly( new_id ); if( sp.has_flag( spell_flag::FRIENDLY_POLY ) ) { @@ -794,7 +792,7 @@ void spell_effect::recover_energy( const spell &sp, Creature &caster, const trip } if( energy_source == "MANA" ) { - p->magic.mod_mana( *p, healing ); + p->magic->mod_mana( *p, healing ); } else if( energy_source == "STAMINA" ) { p->mod_stamina( healing ); } else if( energy_source == "FATIGUE" ) { diff --git a/src/magic_teleporter_list.cpp b/src/magic_teleporter_list.cpp index 7279346cb4376..e4d4c294263e2 100644 --- a/src/magic_teleporter_list.cpp +++ b/src/magic_teleporter_list.cpp @@ -82,7 +82,7 @@ bool teleporter_list::place_avatar_overmap( Character &you, const tripoint_abs_o return false; } tripoint local_dest = omt_dest.getlocal( *global_dest ) + point( 60, 60 ); - you.add_effect( efftype_id( "ignore_fall_damage" ), 1_seconds, num_bp, false, 0, true ); + you.add_effect( efftype_id( "ignore_fall_damage" ), 1_seconds, false, 0, true ); g->place_player_overmap( omt_pt ); g->place_player( local_dest ); return true; diff --git a/src/map.cpp b/src/map.cpp index aed0cba531311..cd816e3c8c5a4 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -2786,9 +2786,10 @@ bool map::mop_spills( const tripoint &p ) } } - for( const auto &pr : field_at( p ) ) { - if( ( retval |= pr.second.get_field_type().obj().phase == phase_id::LIQUID ) ) { - break; + field &fld = field_at( p ); + for( const auto &f : fld ) { + if( f.second.get_field_type().obj().phase == phase_id::LIQUID ) { + retval |= fld.remove_field( f.first ); } } @@ -3009,18 +3010,19 @@ void map::smash_items( const tripoint &p, const int power, const std::string &ca } } - Character &player_character = get_player_character(); // Let the player know that the item was damaged if they can see it. - if( items_destroyed > 1 && player_character.sees( p ) ) { - add_msg( m_bad, _( "The %s destroys several items!" ), cause_message ); - } else if( items_destroyed == 1 && items_damaged == 1 && player_character.sees( p ) ) { + if( items_destroyed > 1 ) { + add_msg_if_player_sees( p, m_bad, _( "The %s destroys several items!" ), cause_message ); + } else if( items_destroyed == 1 && items_damaged == 1 ) { //~ %1$s: the cause of destruction, %2$s: destroyed item name - add_msg( m_bad, _( "The %1$s destroys the %2$s!" ), cause_message, damaged_item_name ); - } else if( items_damaged > 1 && player_character.sees( p ) ) { - add_msg( m_bad, _( "The %s damages several items." ), cause_message ); - } else if( items_damaged == 1 && player_character.sees( p ) ) { + add_msg_if_player_sees( p, m_bad, _( "The %1$s destroys the %2$s!" ), cause_message, + damaged_item_name ); + } else if( items_damaged > 1 ) { + add_msg_if_player_sees( p, m_bad, _( "The %s damages several items." ), cause_message ); + } else if( items_damaged == 1 ) { //~ %1$s: the cause of damage, %2$s: damaged item name - add_msg( m_bad, _( "The %1$s damages the %2$s." ), cause_message, damaged_item_name ); + add_msg_if_player_sees( p, m_bad, _( "The %1$s damages the %2$s." ), cause_message, + damaged_item_name ); } for( const item &it : contents ) { @@ -3521,7 +3523,7 @@ void map::crush( const tripoint &p ) dam * .05 ) ); // Pin whoever got hit - crushed_player->add_effect( effect_crushed, 1_turns, num_bp, true ); + crushed_player->add_effect( effect_crushed, 1_turns, true ); crushed_player->check_dead_state(); } } @@ -3531,7 +3533,7 @@ void map::crush( const tripoint &p ) monhit->deal_damage( nullptr, bodypart_id( "torso" ), damage_instance( DT_BASH, rng( 0, 25 ) ) ); // Pin whoever got hit - monhit->add_effect( effect_crushed, 1_turns, num_bp, true ); + monhit->add_effect( effect_crushed, 1_turns, true ); monhit->check_dead_state(); } @@ -3682,7 +3684,7 @@ void map::shoot( const tripoint &p, projectile &proj, const bool hit_items ) } else { //Greatly weakens power of bullets dam -= 40; - if( dam <= 0 && get_player_character().sees( p ) ) { + if( dam <= 0 && get_player_view().sees( p ) ) { if( terrain == t_reinforced_door_glass_c ) { add_msg( _( "The shot is stopped by the reinforced glass door!" ) ); } else { @@ -7015,7 +7017,7 @@ void map::rotten_item_spawn( const item &item, const tripoint &pnt ) if( rng( 0, 100 ) < chance ) { MonsterGroupResult spawn_details = MonsterGroupManager::GetResultFromGroup( mgroup ); add_spawn( spawn_details, pnt ); - if( get_player_character().sees( pnt ) ) { + if( get_player_view().sees( pnt ) ) { if( item.is_seed() ) { add_msg( m_warning, _( "Something has crawled out of the %s plants!" ), item.get_plant_name() ); } else { diff --git a/src/map.h b/src/map.h index 2d64c3882a12d..bdf4cb2c61370 100644 --- a/src/map.h +++ b/src/map.h @@ -34,7 +34,7 @@ #include "rng.h" #include "shadowcasting.h" #include "type_id.h" -#include "units.h" +#include "units_fwd.h" struct scent_block; template class safe_reference; diff --git a/src/map_field.cpp b/src/map_field.cpp index 3f8ad0c203f13..3cf5171222a70 100644 --- a/src/map_field.cpp +++ b/src/map_field.cpp @@ -131,8 +131,9 @@ int map::burn_body_part( player &u, field_entry &cur, body_part bp, const int sc total_damage += ddi.total_damage(); } // Represents acid seeping in rather than being splashed on - u.add_env_effect( effect_corroding, bp, 2 + intensity, time_duration::from_turns( rng( 2, - 1 + intensity ) ), bp, false, 0 ); + u.add_env_effect( effect_corroding, convert_bp( bp ).id(), 2 + intensity, + time_duration::from_turns( rng( 2, + 1 + intensity ) ), convert_bp( bp ).id(), false, 0 ); return total_damage; } @@ -680,16 +681,12 @@ bool map::process_fields_in_submap( submap *const current_submap, // TODO: combine with player character code above const bodypart_id hit = player_character.get_random_body_part(); p->deal_damage( nullptr, hit, damage_instance( DT_BASH, 6 ) ); - if( player_character.sees( newp ) ) { - add_msg( _( "A %1$s hits %2$s!" ), tmp.tname(), p->name ); - } + add_msg_if_player_sees( newp, _( "A %1$s hits %2$s!" ), tmp.tname(), p->name ); p->check_dead_state(); } else if( monster *const mon = g->critter_at( newp ) ) { mon->apply_damage( nullptr, bodypart_id( "torso" ), 6 - mon->get_armor_bash( bodypart_id( "torso" ) ) ); - if( player_character.sees( newp ) ) { - add_msg( _( "A %1$s hits the %2$s!" ), tmp.tname(), mon->name() ); - } + add_msg_if_player_sees( newp, _( "A %1$s hits the %2$s!" ), tmp.tname(), mon->name() ); mon->check_dead_state(); } } @@ -1546,16 +1543,16 @@ void map::player_in_field( player &u ) if( ft == fd_tear_gas ) { // Tear gas will both give you teargas disease and/or blind you. if( ( cur.get_field_intensity() > 1 || !one_in( 3 ) ) && ( !inside || one_in( 3 ) ) ) { - u.add_env_effect( effect_teargas, bp_mouth, 5, 20_seconds ); + u.add_env_effect( effect_teargas, bodypart_id( "mouth" ), 5, 20_seconds ); } if( cur.get_field_intensity() > 1 && ( !inside || one_in( 3 ) ) ) { - u.add_env_effect( effect_blind, bp_eyes, cur.get_field_intensity() * 2, 10_seconds ); + u.add_env_effect( effect_blind, bodypart_id( "eyes" ), cur.get_field_intensity() * 2, 10_seconds ); } } if( ft == fd_fungal_haze ) { if( !u.has_trait( trait_M_IMMUNE ) && ( !inside || one_in( 4 ) ) ) { - u.add_env_effect( effect_fungus, bp_mouth, 4, 10_minutes, num_bp, true ); - u.add_env_effect( effect_fungus, bp_eyes, 4, 10_minutes, num_bp, true ); + u.add_env_effect( effect_fungus, bodypart_id( "mouth" ), 4, 10_minutes, true ); + u.add_env_effect( effect_fungus, bodypart_id( "eyes" ), 4, 10_minutes, true ); } } @@ -1641,7 +1638,7 @@ void map::player_in_field( player &u ) // Get stung if [clothing on a body part isn't thick enough (like t-shirt) OR clothing covers less than 100% of body part] // AND clothing on affected body part has low environmental protection value if( ( u.get_armor_cut( bp ) <= 1 || ( sum_cover < 100 && x_in_y( 100 - sum_cover, 100 ) ) ) && - u.add_env_effect( effect_stung, bp->token, intensity, 9_minutes ) ) { + u.add_env_effect( effect_stung, bp, intensity, 9_minutes ) ) { u.add_msg_if_player( m_bad, _( "The bees sting you in %s!" ), body_part_name_accusative( bp ) ); } @@ -1659,7 +1656,7 @@ void map::player_in_field( player &u ) } else { u.add_msg_player_or_npc( m_bad, _( "The incendiary melts into your skin!" ), _( "The incendiary melts into s skin!" ) ); - u.add_effect( effect_onfire, 8_turns, bp_torso ); + u.add_effect( effect_onfire, 8_turns, bodypart_id( "torso" ) ); u.hurtall( rng( 2, 6 ), nullptr ); } } @@ -1671,11 +1668,11 @@ void map::player_in_field( player &u ) if( !( u.worn_with_flag( flag_GAS_PROOF ) && u.get_env_resist( bodypart_id( "mouth" ) ) >= 15 && u.get_env_resist( bodypart_id( "eyes" ) ) >= 15 ) ) { const int intensity = cur.get_field_intensity(); - bool inhaled = u.add_env_effect( effect_poison, bp_mouth, 5, intensity * 1_minutes ); + bool inhaled = u.add_env_effect( effect_poison, bodypart_id( "mouth" ), 5, intensity * 1_minutes ); if( u.has_trait( trait_THRESH_MYCUS ) || u.has_trait( trait_THRESH_MARLOSS ) || ( ft == fd_insecticidal_gas && ( u.get_highest_category() == "INSECT" || u.get_highest_category() == "SPIDER" ) ) ) { - inhaled |= u.add_env_effect( effect_badpoison, bp_mouth, 5, intensity * 1_minutes ); + inhaled |= u.add_env_effect( effect_badpoison, bodypart_id( "mouth" ), 5, intensity * 1_minutes ); u.hurtall( rng( intensity, intensity * 2 ), nullptr ); u.add_msg_if_player( m_bad, _( "The %s burns your skin." ), cur.name() ); } @@ -1746,7 +1743,8 @@ void map::creature_in_field( Creature &critter ) } bool effect_added = false; if( fe.is_environmental ) { - effect_added = critter.add_env_effect( fe.id, fe.bp, fe.intensity, fe.get_duration() ); + effect_added = critter.add_env_effect( fe.id, convert_bp( fe.bp ).id(), fe.intensity, + fe.get_duration() ); } else { effect_added = true; critter.add_effect( field_fx ); @@ -1785,7 +1783,7 @@ void map::monster_in_field( monster &z ) const field_type_id cur_field_type = cur.get_field_type(); if( cur_field_type == fd_web ) { if( !z.has_flag( MF_WEBWALK ) ) { - z.add_effect( effect_webbed, 1_turns, num_bp, true, cur.get_field_intensity() ); + z.add_effect( effect_webbed, 1_turns, true, cur.get_field_intensity() ); cur.set_field_intensity( 0 ); } } diff --git a/src/martialarts.cpp b/src/martialarts.cpp index 5be4a00e95960..67307d24060b7 100644 --- a/src/martialarts.cpp +++ b/src/martialarts.cpp @@ -449,13 +449,13 @@ bool ma_requirements::is_valid_character( const Character &u ) const bool cqb = u.has_active_bionic( bio_cqb ); // There are 4 different cases of "armedness": // Truly unarmed, unarmed weapon, style-allowed weapon, generic weapon - bool melee_style = u.martial_arts_data.selected_strictly_melee(); + bool melee_style = u.martial_arts_data->selected_strictly_melee(); bool is_armed = u.is_armed(); bool unarmed_weapon = is_armed && u.used_weapon().has_flag( flag_UNARMED_WEAPON ); - bool forced_unarmed = u.martial_arts_data.selected_force_unarmed(); + bool forced_unarmed = u.martial_arts_data->selected_force_unarmed(); bool weapon_ok = is_valid_weapon( u.weapon ); - bool style_weapon = u.martial_arts_data.selected_has_weapon( u.weapon.typeId() ); - bool all_weapons = u.martial_arts_data.selected_allow_melee(); + bool style_weapon = u.martial_arts_data->selected_has_weapon( u.weapon.typeId() ); + bool all_weapons = u.martial_arts_data->selected_allow_melee(); bool unarmed_ok = !is_armed || ( unarmed_weapon && unarmed_weapons_allowed ); bool melee_ok = melee_allowed && weapon_ok && ( style_weapon || all_weapons ); @@ -938,18 +938,18 @@ bool player::can_grab_break( const item &weap ) const return false; } - ma_technique tec = martial_arts_data.get_grab_break_tec( weap ); + ma_technique tec = martial_arts_data->get_grab_break_tec( weap ); return tec.is_valid_character( *this ); } bool Character::can_miss_recovery( const item &weap ) const { - if( !martial_arts_data.has_miss_recovery_tec( weap ) ) { + if( !martial_arts_data->has_miss_recovery_tec( weap ) ) { return false; } - ma_technique tec = martial_arts_data.get_miss_recovery_tec( weap ); + ma_technique tec = martial_arts_data->get_miss_recovery_tec( weap ); return tec.is_valid_character( *this ); } @@ -1204,6 +1204,11 @@ bool Character::has_mabuff( const mabuff_id &id ) const } ); } +bool Character::has_grab_break_tec() const +{ + return martial_arts_data->has_grab_break_tec(); +} + bool character_martial_arts::has_martialart( const matype_id &ma ) const { return std::find( ma_styles.begin(), ma_styles.end(), ma ) != ma_styles.end(); diff --git a/src/mattack_actors.cpp b/src/mattack_actors.cpp index 110b5636b9683..31620a768ddf4 100644 --- a/src/mattack_actors.cpp +++ b/src/mattack_actors.cpp @@ -139,11 +139,11 @@ bool leap_actor::call( monster &z ) const } z.moves -= move_cost; - Character &player_character = get_player_character(); + viewer &player_view = get_player_view(); const tripoint chosen = random_entry( options ); - bool seen = player_character.sees( z ); // We can see them jump... + bool seen = player_view.sees( z ); // We can see them jump... z.setpos( chosen ); - seen |= player_character.sees( z ); // ... or we can see them land + seen |= player_view.sees( z ); // ... or we can see them land if( seen ) { add_msg( _( "The %s leaps!" ), z.name() ); } @@ -200,9 +200,8 @@ bool mon_spellcasting_actor::call( monster &mon ) const target_name = target_monster->disp_name(); } - if( get_player_character().sees( target ) ) { - add_msg( spell_data.message(), mon.disp_name(), spell_data.name(), target_name ); - } + add_msg_if_player_sees( target, spell_data.message(), mon.disp_name(), + spell_data.name(), target_name ); spell_data.cast_all_effects( mon, target ); @@ -338,7 +337,7 @@ void melee_actor::on_damage( monster &z, Creature &target, dealt_damage_instance for( const auto &eff : effects ) { if( x_in_y( eff.chance, 100 ) ) { - const body_part affected_bp = eff.affect_hit_bp ? bp->token : eff.bp; + const bodypart_id affected_bp = eff.affect_hit_bp ? bp : convert_bp( eff.bp ).id(); target.add_effect( eff.id, time_duration::from_turns( eff.duration ), affected_bp, eff.permanent ); } } @@ -362,12 +361,12 @@ void bite_actor::on_damage( monster &z, Creature &target, dealt_damage_instance melee_actor::on_damage( z, target, dealt ); if( target.has_effect( effect_grabbed ) && one_in( no_infection_chance - dealt.total_damage() ) ) { const bodypart_id &hit = dealt.bp_hit; - if( target.has_effect( effect_bite, hit->token ) ) { - target.add_effect( effect_bite, 40_minutes, hit->token, true ); - } else if( target.has_effect( effect_infected, hit->token ) ) { - target.add_effect( effect_infected, 25_minutes, hit->token, true ); + if( target.has_effect( effect_bite, hit.id() ) ) { + target.add_effect( effect_bite, 40_minutes, hit, true ); + } else if( target.has_effect( effect_infected, hit.id() ) ) { + target.add_effect( effect_infected, 25_minutes, hit, true ); } else { - target.add_effect( effect_bite, 1_turns, hit->token, true ); + target.add_effect( effect_bite, 1_turns, hit, true ); } } if( target.has_trait( trait_TOXICFLESH ) ) { @@ -467,11 +466,12 @@ bool gun_actor::call( monster &z ) const int hostiles; // hostiles which cannot be engaged without risking friendly fire target = z.auto_find_hostile_target( max_range, hostiles ); if( !target ) { - if( hostiles > 0 && get_player_character().sees( z ) ) { - add_msg( m_warning, ngettext( "Pointed in your direction, the %s emits an IFF warning beep.", - "Pointed in your direction, the %s emits %d annoyed sounding beeps.", - hostiles ), - z.name(), hostiles ); + if( hostiles > 0 ) { + add_msg_if_player_sees( z, m_warning, + ngettext( "Pointed in your direction, the %s emits an IFF warning beep.", + "Pointed in your direction, the %s emits %d annoyed sounding beeps.", + hostiles ), + z.name(), hostiles ); } return false; } @@ -496,8 +496,8 @@ bool gun_actor::call( monster &z ) const void gun_actor::shoot( monster &z, Creature &target, const gun_mode_id &mode ) const { if( require_sunlight && !g->is_in_sunlight( z.pos() ) ) { - if( one_in( 3 ) && get_player_character().sees( z ) ) { - add_msg( _( failure_msg ), z.name() ); + if( one_in( 3 ) ) { + add_msg_if_player_sees( z, _( failure_msg ), z.name() ); } return; } @@ -574,9 +574,7 @@ void gun_actor::shoot( monster &z, Creature &target, const gun_mode_id &mode ) c tmp.weapon = gun; tmp.i_add( item( "UPS_off", calendar::turn, 1000 ) ); - if( get_player_character().sees( z ) ) { - add_msg( m_warning, _( description ), z.name(), tmp.weapon.tname() ); - } + add_msg_if_player_sees( z, m_warning, _( description ), z.name(), tmp.weapon.tname() ); z.ammo[ammo] -= tmp.fire_gun( target.pos(), gun.gun_current_mode().qty ); diff --git a/src/melee.cpp b/src/melee.cpp index a69fae92f17c1..f897527d64599 100644 --- a/src/melee.cpp +++ b/src/melee.cpp @@ -141,7 +141,7 @@ std::string melee_message( const ma_technique &tec, Character &p, const item &Character::used_weapon() const { - return martial_arts_data.selected_force_unarmed() ? null_item_reference() : weapon; + return martial_arts_data->selected_force_unarmed() ? null_item_reference() : weapon; } item &Character::used_weapon() @@ -472,7 +472,7 @@ void Character::melee_attack( Creature &t, bool allow_special, const matec_id &f } if( can_miss_recovery( *cur_weapon ) ) { - ma_technique tec = martial_arts_data.get_miss_recovery_tec( *cur_weapon ); + ma_technique tec = martial_arts_data->get_miss_recovery_tec( *cur_weapon ); add_msg( _( tec.avatar_message ), t.disp_name() ); } else if( stumble_pen >= 60 ) { add_msg( m_bad, _( "You miss and stumble with the momentum." ) ); @@ -498,12 +498,12 @@ void Character::melee_attack( Creature &t, bool allow_special, const matec_id &f // Cap stumble penalty, heavy weapons are quite weak already move_cost += std::min( 60, stumble_pen ); - if( martial_arts_data.has_miss_recovery_tec( *cur_weapon ) ) { + if( martial_arts_data->has_miss_recovery_tec( *cur_weapon ) ) { move_cost /= 2; } // trigger martial arts on-miss effects - martial_arts_data.ma_onmiss_effects( *this ); + martial_arts_data->ma_onmiss_effects( *this ); } else { melee::melee_stats.hit_count += 1; // Remember if we see the monster at start - it may change @@ -548,12 +548,12 @@ void Character::melee_attack( Creature &t, bool allow_special, const matec_id &f } //player has a very small chance, based on their intelligence, to learn a style whilst using the CQB bionic - if( has_active_bionic( bio_cqb ) && !martial_arts_data.knows_selected_style() ) { + if( has_active_bionic( bio_cqb ) && !martial_arts_data->knows_selected_style() ) { /** @EFFECT_INT slightly increases chance to learn techniques when using CQB bionic */ // Enhanced Memory Banks bionic doubles chance to learn martial art const int bionic_boost = has_active_bionic( bionic_id( bio_memory ) ) ? 2 : 1; if( one_in( ( 1400 - ( get_int() * 50 ) ) / bionic_boost ) ) { - martial_arts_data.learn_current_style_CQB( is_player() ); + martial_arts_data->learn_current_style_CQB( is_player() ); } } @@ -623,7 +623,7 @@ void Character::melee_attack( Creature &t, bool allow_special, const matec_id &f if( critical_hit ) { // trigger martial arts on-crit effects - martial_arts_data.ma_oncrit_effects( *this ); + martial_arts_data->ma_oncrit_effects( *this ); } } @@ -632,7 +632,7 @@ void Character::melee_attack( Creature &t, bool allow_special, const matec_id &f if( t.is_dead_state() ) { // trigger martial arts on-kill effects - martial_arts_data.ma_onkill_effects( *this ); + martial_arts_data->ma_onkill_effects( *this ); } } @@ -650,7 +650,7 @@ void Character::melee_attack( Creature &t, bool allow_special, const matec_id &f add_msg( m_debug, "Stamina burn: %d", std::min( -50, mod_sta ) ); mod_moves( -move_cost ); // trigger martial arts on-attack effects - martial_arts_data.ma_onattack_effects( *this ); + martial_arts_data->ma_onattack_effects( *this ); // some things (shattering weapons) can harm the attacking creature. check_dead_state(); did_hit( t ); @@ -708,7 +708,7 @@ void player::reach_attack( const tripoint &p ) if( critter == nullptr ) { add_msg_if_player( _( "You swing at the air." ) ); - if( martial_arts_data.has_miss_recovery_tec( weapon ) ) { + if( martial_arts_data->has_miss_recovery_tec( weapon ) ) { move_cost /= 3; // "Probing" is faster than a regular miss } @@ -1180,7 +1180,7 @@ matec_id Character::pick_technique( Creature &t, const item &weap, bool crit, bool dodge_counter, bool block_counter ) { - const std::vector all = martial_arts_data.get_all_techniques( weap ); + const std::vector all = martial_arts_data->get_all_techniques( weap ); std::vector possible; @@ -1625,7 +1625,7 @@ bool Character::block_hit( Creature *source, bodypart_id &bp_hit, damage_instanc // fire martial arts on-getting-hit-triggered effects // these fire even if the attack is blocked (you still got hit) - martial_arts_data.ma_ongethit_effects( *this ); + martial_arts_data->ma_ongethit_effects( *this ); if( blocks_left < 1 ) { return false; @@ -1642,7 +1642,7 @@ bool Character::block_hit( Creature *source, bodypart_id &bp_hit, damage_instanc block_bonus = blocking_ability( shield ); bool conductive_shield = shield.conductive(); bool unarmed = weapon.has_flag( "UNARMED_WEAPON" ); - bool force_unarmed = martial_arts_data.is_force_unarmed(); + bool force_unarmed = martial_arts_data->is_force_unarmed(); int melee_skill = get_skill_level( skill_melee ); int unarmed_skill = get_skill_level( skill_unarmed ); @@ -1659,7 +1659,7 @@ bool Character::block_hit( Creature *source, bodypart_id &bp_hit, damage_instanc /** @EFFECT_STR increases attack blocking effectiveness with a limb or worn/wielded item */ /** @EFFECT_UNARMED increases attack blocking effectiveness with a limb or worn/wielded item */ if( ( unarmed || force_unarmed ) ) { - if( martial_arts_data.can_limb_block( *this ) ) { + if( martial_arts_data->can_limb_block( *this ) ) { // block_bonus for limb blocks will be added when the limb is decided block_score = str_cur + melee_skill + unarmed_skill; } else if( has_shield ) { @@ -1692,9 +1692,9 @@ bool Character::block_hit( Creature *source, bodypart_id &bp_hit, damage_instanc handle_melee_wear( shield, wear_modifier ); } else { //Choose which body part to block with, assume left side first - if( martial_arts_data.can_leg_block( *this ) && martial_arts_data.can_arm_block( *this ) ) { + if( martial_arts_data->can_leg_block( *this ) && martial_arts_data->can_arm_block( *this ) ) { bp_hit = one_in( 2 ) ? bodypart_id( "leg_l" ) : bodypart_id( "arm_l" ); - } else if( martial_arts_data.can_leg_block( *this ) ) { + } else if( martial_arts_data->can_leg_block( *this ) ) { bp_hit = bodypart_id( "leg_l" ); } else { bp_hit = bodypart_id( "arm_l" ); @@ -1808,7 +1808,7 @@ bool Character::block_hit( Creature *source, bodypart_id &bp_hit, damage_instanc damage_blocked_description, thing_blocked_with ); // fire martial arts block-triggered effects - martial_arts_data.ma_onblock_effects( *this ); + martial_arts_data->ma_onblock_effects( *this ); // Check if we have any block counters matec_id tec = pick_technique( *source, shield, false, false, true ); @@ -1936,7 +1936,7 @@ std::string Character::melee_special_effects( Creature &t, damage_instance &d, i } // on-hit effects for martial arts - martial_arts_data.ma_onhit_effects( *this ); + martial_arts_data->ma_onhit_effects( *this ); return dump; } @@ -2332,7 +2332,7 @@ double player::melee_value( const item &weap ) const } // value style weapons more - if( !martial_arts_data.enumerate_known_styles( weap.type->get_id() ).empty() ) { + if( !martial_arts_data->enumerate_known_styles( weap.type->get_id() ).empty() ) { my_value *= 1.5; } diff --git a/src/memorial_logger.cpp b/src/memorial_logger.cpp index 4835c59afb380..b0732c04b732d 100644 --- a/src/memorial_logger.cpp +++ b/src/memorial_logger.cpp @@ -396,8 +396,8 @@ void memorial_logger::write_text_memorial( std::ostream &file, //Inventory file << _( "Inventory:" ) << eol; - u.inv.restack( u ); - invslice slice = u.inv.slice(); + u.inv->restack( u ); + invslice slice = u.inv->slice(); for( const std::list *elem : slice ) { const item &next_item = elem->front(); file << indent << next_item.invlet << " - " << diff --git a/src/messages.cpp b/src/messages.cpp index b4bd5270ad6d7..f7f1bb4da5e5c 100644 --- a/src/messages.cpp +++ b/src/messages.cpp @@ -18,6 +18,7 @@ #include "string_input_popup.h" #include "translations.h" #include "ui_manager.h" +#include "viewer.h" #if defined(__ANDROID__) #include @@ -880,3 +881,33 @@ void add_msg( const game_message_params ¶ms, std::string msg ) { Messages::add_msg( params, std::move( msg ) ); } + +void add_msg_if_player_sees( const tripoint &target, std::string msg ) +{ + if( get_player_view().sees( target ) ) { + Messages::add_msg( std::move( msg ) ); + } +} + +void add_msg_if_player_sees( const Creature &target, std::string msg ) +{ + if( get_player_view().sees( target ) ) { + Messages::add_msg( std::move( msg ) ); + } +} + +void add_msg_if_player_sees( const tripoint &target, const game_message_params ¶ms, + std::string msg ) +{ + if( get_player_view().sees( target ) ) { + Messages::add_msg( params, std::move( msg ) ); + } +} + +void add_msg_if_player_sees( const Creature &target, const game_message_params ¶ms, + std::string msg ) +{ + if( get_player_view().sees( target ) ) { + Messages::add_msg( params, std::move( msg ) ); + } +} diff --git a/src/messages.h b/src/messages.h index 65cac42f7c976..d2f2acde49aba 100644 --- a/src/messages.h +++ b/src/messages.h @@ -11,10 +11,13 @@ #include "enums.h" #include "debug.h" +class Creature; class JsonOut; class JsonObject; class translation; +struct tripoint; + namespace catacurses { class window; @@ -71,4 +74,86 @@ inline void add_msg( const game_message_params ¶ms, const char *const msg, A return add_msg( params, string_format( msg, std::forward( args )... ) ); } +void add_msg_if_player_sees( const tripoint &target, std::string msg ); +void add_msg_if_player_sees( const Creature &target, std::string msg ); +template +inline void add_msg_if_player_sees( const tripoint &target, const std::string &msg, + Args &&... args ) +{ + return add_msg_if_player_sees( target, string_format( msg, std::forward( args )... ) ); +} +template +inline void add_msg_if_player_sees( const Creature &target, const std::string &msg, + Args &&... args ) +{ + return add_msg_if_player_sees( target, string_format( msg, std::forward( args )... ) ); +} +template +inline void add_msg_if_player_sees( const tripoint &target, const char *const msg, Args &&... args ) +{ + return add_msg_if_player_sees( target, string_format( msg, std::forward( args )... ) ); +} +template +inline void add_msg_if_player_sees( const Creature &target, const char *const msg, Args &&... args ) +{ + return add_msg_if_player_sees( target, string_format( msg, std::forward( args )... ) ); +} +template +inline void add_msg_if_player_sees( const tripoint &target, const translation &msg, + Args &&... args ) +{ + return add_msg_if_player_sees( target, string_format( msg, std::forward( args )... ) ); +} +template +inline void add_msg_if_player_sees( const Creature &target, const translation &msg, + Args &&... args ) +{ + return add_msg_if_player_sees( target, string_format( msg, std::forward( args )... ) ); +} + +void add_msg_if_player_sees( const tripoint &target, const game_message_params ¶ms, + std::string msg ); +void add_msg_if_player_sees( const Creature &target, const game_message_params ¶ms, + std::string msg ); +template +inline void add_msg_if_player_sees( const tripoint &target, const game_message_params ¶ms, + const std::string &msg, Args &&... args ) +{ + if( params.type == m_debug && !debug_mode ) { + return; + } + return add_msg_if_player_sees( target, params, string_format( msg, + std::forward( args )... ) ); +} +template +inline void add_msg_if_player_sees( const Creature &target, const game_message_params ¶ms, + const std::string &msg, Args &&... args ) +{ + if( params.type == m_debug && !debug_mode ) { + return; + } + return add_msg_if_player_sees( target, params, string_format( msg, + std::forward( args )... ) ); +} +template +inline void add_msg_if_player_sees( const tripoint &target, const game_message_params ¶ms, + const char *const msg, Args &&... args ) +{ + if( params.type == m_debug && !debug_mode ) { + return; + } + return add_msg_if_player_sees( target, params, string_format( msg, + std::forward( args )... ) ); +} +template +inline void add_msg_if_player_sees( const Creature &target, const game_message_params ¶ms, + const char *const msg, Args &&... args ) +{ + if( params.type == m_debug && !debug_mode ) { + return; + } + return add_msg_if_player_sees( target, params, string_format( msg, + std::forward( args )... ) ); +} + #endif // CATA_SRC_MESSAGES_H diff --git a/src/monattack.cpp b/src/monattack.cpp index 7d81dae907c30..ec7a22a4e4a7a 100644 --- a/src/monattack.cpp +++ b/src/monattack.cpp @@ -415,17 +415,14 @@ bool mattack::antqueen( monster *z ) ant->poly( ant->type->upgrade_into ); } else if( egg_points.empty() ) { // There's no eggs nearby--lay one. - if( player_character.sees( *z ) ) { - add_msg( _( "The %s lays an egg!" ), z->name() ); - } + add_msg_if_player_sees( *z, _( "The %s lays an egg!" ), z->name() ); here.spawn_item( z->pos(), "ant_egg", 1, 0, calendar::turn ); } else { // There are eggs nearby. Let's hatch some. // It takes a while z->moves -= 20 * egg_points.size(); - if( player_character.sees( *z ) ) { - add_msg( m_warning, _( "The %s tends nearby eggs, and they hatch!" ), z->name() ); - } + add_msg_if_player_sees( *z, m_warning, _( "The %s tends nearby eggs, and they hatch!" ), + z->name() ); for( const tripoint &egg_pos : egg_points ) { map_stack items = here.i_at( egg_pos ); for( map_stack::iterator it = items.begin(); it != items.end(); ) { @@ -475,11 +472,7 @@ bool mattack::shriek_alert( monster *z ) !z->sees( *target ) ) { return false; } - - if( get_player_character().sees( *z ) ) { - add_msg( _( "The %s begins shrieking!" ), z->name() ); - } - + add_msg_if_player_sees( *z, _( "The %s begins shrieking!" ), z->name() ); z->moves -= 150; sounds::sound( z->pos(), 120, sounds::sound_t::alert, _( "a piercing wail!" ), false, "shout", "wail" ); @@ -527,8 +520,7 @@ bool mattack::shriek_stun( monster *z ) continue; } if( one_in( dist / 2 ) && !( target->is_immune_effect( effect_deaf ) ) ) { - target->add_effect( effect_dazed, rng( 1_minutes, 2_minutes ), num_bp, false, rng( 1, - ( 15 - dist ) / 3 ) ); + target->add_effect( effect_dazed, rng( 1_minutes, 2_minutes ), false, rng( 1, ( 15 - dist ) / 3 ) ); } } @@ -618,9 +610,8 @@ bool mattack::acid( monster *z ) auto dealt = projectile_attack( proj, z->pos(), target->pos(), dispersion_sources{ 5400 }, z ); const tripoint &hitp = dealt.end_point; const Creature *hit_critter = dealt.hit_critter; - if( hit_critter == nullptr && here.hit_with_acid( hitp ) && get_player_character().sees( hitp ) ) { - add_msg( _( "A glob of acid hits the %s!" ), - here.tername( hitp ) ); + if( hit_critter == nullptr && here.hit_with_acid( hitp ) ) { + add_msg_if_player_sees( hitp, _( "A glob of acid hits the %s!" ), here.tername( hitp ) ); if( here.impassable( hitp ) ) { // TODO: Allow it to spill on the side it hit from return true; @@ -675,8 +666,7 @@ bool mattack::acid_barf( monster *z ) int dam = rng( 5, 12 ); dam = target->deal_damage( z, hit, damage_instance( DT_ACID, dam ) ).total_damage(); - target->add_env_effect( effect_corroding, hit->token, 5, time_duration::from_turns( dam / 2 + 5 ), - hit->token ); + target->add_env_effect( effect_corroding, hit, 5, time_duration::from_turns( dam / 2 + 5 ), hit ); if( dam > 0 ) { auto msg_type = target->is_avatar() ? m_bad : m_info; @@ -690,7 +680,7 @@ bool mattack::acid_barf( monster *z ) dam ); if( hit == bodypart_id( "eyes" ) ) { - target->add_env_effect( effect_blind, bp_eyes, 3, 1_minutes ); + target->add_env_effect( effect_blind, bodypart_id( "eyes" ), 3, 1_minutes ); } } else { target->add_msg_player_or_npc( @@ -881,17 +871,14 @@ bool mattack::boomer( monster *z ) // If bile hit a solid tile, return. if( here.impassable( i ) ) { here.add_field( i, fd_bile, 3 ); - if( player_character.sees( i ) ) { - add_msg( _( "Bile splatters on the %s!" ), - here.tername( i ) ); - } + add_msg_if_player_sees( i, _( "Bile splatters on the %s!" ), here.tername( i ) ); return true; } } if( !target->uncanny_dodge() ) { ///\EFFECT_DODGE increases chance to avoid boomer effect if( rng( 0, 10 ) > target->get_dodge() || one_in( target->get_dodge() ) ) { - target->add_env_effect( effect_boomered, bp_eyes, 3, 12_turns ); + target->add_env_effect( effect_boomered, bodypart_id( "eyes" ), 3, 12_turns ); } else if( u_see ) { target->add_msg_player_or_npc( _( "You dodge it!" ), _( " dodges it!" ) ); @@ -926,20 +913,18 @@ bool mattack::boomer_glow( monster *z ) here.add_field( i, fd_bile, 1 ); if( here.impassable( i ) ) { here.add_field( i, fd_bile, 3 ); - if( player_character.sees( i ) ) { - add_msg( _( "Bile splatters on the %s!" ), here.tername( i ) ); - } + add_msg_if_player_sees( i, _( "Bile splatters on the %s!" ), here.tername( i ) ); return true; } } if( !target->uncanny_dodge() ) { ///\EFFECT_DODGE increases chance to avoid glowing boomer effect if( rng( 0, 10 ) > target->get_dodge() || one_in( target->get_dodge() ) ) { - target->add_env_effect( effect_boomered, bp_eyes, 5, 25_turns ); + target->add_env_effect( effect_boomered, bodypart_id( "eyes" ), 5, 25_turns ); target->on_dodge( z, 5 ); for( int i = 0; i < rng( 2, 4 ); i++ ) { body_part bp = random_body_part(); - target->add_env_effect( effect_glowing, bp, 4, 4_minutes ); + target->add_env_effect( effect_glowing, convert_bp( bp ).id(), 4, 4_minutes ); if( target->has_effect( effect_glowing ) ) { break; } @@ -1293,7 +1278,6 @@ bool mattack::science( monster *const z ) // I said SCIENCE again! // flavor is always okay valid_attacks[valid_attack_count++] = att_flavor; - Character &player_character = get_player_character(); //////////////////////////////////////////////////////////////////////////////////////////////// // choose and do a valid attack const int attack_index = get_random_index( valid_attack_count ); @@ -1310,12 +1294,8 @@ bool mattack::science( monster *const z ) // I said SCIENCE again! break; case att_radiation : { z->moves -= att_cost_rad; - - // if the player can see it - if( player_character.sees( *z ) ) { - add_msg( m_bad, _( "The %1$s fires a shimmering beam towards %2$s!" ), - z->name(), target->disp_name() ); - } + add_msg_if_player_sees( *z, m_bad, _( "The %1$s fires a shimmering beam towards %2$s!" ), + z->name(), target->disp_name() ); // (1) Give the target a chance at an uncanny_dodge. // (2) If that fails, always fail to dodge 1 in dodge_skill times. @@ -1348,12 +1328,8 @@ bool mattack::science( monster *const z ) // I said SCIENCE again! case att_manhack : { z->moves -= att_cost_manhack; z->ammo[itype_bot_manhack]--; - - // if the player can see it - if( player_character.sees( *z ) ) { - add_msg( m_warning, _( "A manhack flies out of one of the holes on the %s!" ), - z->name() ); - } + add_msg_if_player_sees( *z, m_warning, _( "A manhack flies out of one of the holes on the %s!" ), + z->name() ); const tripoint where = empty_neighbors.first[get_random_index( empty_neighbor_count )]; if( monster *const manhack = g->place_critter_at( mon_manhack, where ) ) { @@ -1363,13 +1339,9 @@ bool mattack::science( monster *const z ) // I said SCIENCE again! break; case att_acid_pool : { z->moves -= att_cost_acid; - - // if the player can see it - if( player_character.sees( *z ) ) { - add_msg( m_warning, - _( "The %s shudders, and some sort of caustic fluid leaks from a its damaged shell!" ), - z->name() ); - } + add_msg_if_player_sees( *z, m_warning, + _( "The %s shudders, and some sort of caustic fluid leaks from a its damaged shell!" ), + z->name() ); map &here = get_map(); // fill empty tiles with acid @@ -1396,11 +1368,7 @@ bool mattack::science( monster *const z ) // I said SCIENCE again! if( i == m_flavor.size() - 1 ) { z->moves -= att_cost_flavor; } - - // if the player can see it, else forget about it - if( player_character.sees( *z ) ) { - add_msg( m_warning, _( m_flavor[i] ), z->name() ); - } + add_msg_if_player_sees( *z, m_warning, _( m_flavor[i] ), z->name() ); } break; } @@ -1698,9 +1666,7 @@ bool mattack::fungus( monster *z ) } //~ the sound of a fungus releasing spores sounds::sound( z->pos(), 10, sounds::sound_t::combat, _( "Pouf!" ), false, "misc", "puff" ); - if( player_character.sees( *z ) ) { - add_msg( m_warning, _( "Spores are released from the %s!" ), z->name() ); - } + add_msg_if_player_sees( *z, m_warning, _( "Spores are released from the %s!" ), z->name() ); // Use less laggy methods of reproduction when there is a lot of mons around double spore_chance = 0.25; @@ -1749,7 +1715,7 @@ bool mattack::fungus_corporate( monster *z ) { if( x_in_y( 1, 20 ) ) { sounds::sound( z->pos(), 10, sounds::sound_t::speech, _( "\"Buy SpOreos(tm) now!\"" ) ); - if( get_player_character().sees( *z ) ) { + if( get_player_view().sees( *z ) ) { add_msg( m_warning, _( "Delicious snacks are released from the %s!" ), z->name() ); get_map().add_item( z->pos(), item( "sporeos" ) ); } // only spawns SpOreos if the player is near; can't have the COMMONERS stealing our product from good customers @@ -1763,9 +1729,8 @@ bool mattack::fungus_haze( monster *z ) { //~ That spore sound again sounds::sound( z->pos(), 10, sounds::sound_t::combat, _( "Pouf!" ), true, "misc", "puff" ); - if( get_player_character().sees( *z ) ) { - add_msg( m_info, _( "The %s pulses, and fresh fungal material bursts forth." ), z->name() ); - } + add_msg_if_player_sees( *z, m_info, _( "The %s pulses, and fresh fungal material bursts forth." ), + z->name() ); z->moves -= 150; map &here = get_map(); for( const tripoint &dest : here.points_in_radius( z->pos(), 3 ) ) { @@ -1778,7 +1743,7 @@ bool mattack::fungus_haze( monster *z ) bool mattack::fungus_big_blossom( monster *z ) { bool firealarm = false; - const auto u_see = get_player_character().sees( *z ); + const auto u_see = get_player_view().sees( *z ); map &here = get_map(); // Fungal fire-suppressor! >:D for( const tripoint &dest : here.points_in_radius( z->pos(), 6 ) ) { @@ -1873,7 +1838,7 @@ bool mattack::fungus_inject( monster *z ) body_part_name_accusative( hit ) ); if( one_in( 10 - dam ) ) { - player_character.add_effect( effect_fungus, 10_minutes, num_bp, true ); + player_character.add_effect( effect_fungus, 10_minutes, true ); add_msg( m_warning, _( "You feel thousands of live spores pumping into you…" ) ); } } else { @@ -1927,19 +1892,17 @@ bool mattack::fungus_bristle( monster *z ) if( dam > 0 ) { //~ 1$s is monster name, 2$s bodypart in accusative target->add_msg_if_player( m_bad, _( "The %1$s sinks several needlelike barbs into your %2$s!" ), - z->name(), - body_part_name_accusative( hit ) ); + z->name(), body_part_name_accusative( hit ) ); if( one_in( 15 - dam ) ) { - target->add_effect( effect_fungus, 20_minutes, num_bp, true ); + target->add_effect( effect_fungus, 20_minutes, true ); target->add_msg_if_player( m_warning, _( "You feel thousands of live spores pumping into you…" ) ); } } else { //~ 1$s is monster name, 2$s bodypart in accusative target->add_msg_if_player( _( "The %1$s slashes your %2$s, but your armor protects you." ), - z->name(), - body_part_name_accusative( hit ) ); + z->name(), body_part_name_accusative( hit ) ); } target->on_hit( z, hit, z->type->melee_skill ); @@ -1949,12 +1912,7 @@ bool mattack::fungus_bristle( monster *z ) bool mattack::fungus_growth( monster *z ) { - // Young fungaloid growing into an adult - if( get_player_character().sees( *z ) ) { - add_msg( m_warning, _( "The %s grows into an adult!" ), - z->name() ); - } - + add_msg_if_player_sees( *z, m_warning, _( "The %s grows into an adult!" ), z->name() ); z->poly( mon_fungaloid ); return false; @@ -2105,7 +2063,7 @@ bool mattack::fungus_fortify( monster *z ) //~ 1$s is monster name, 2$s bodypart in accusative add_msg( m_bad, _( "The %1$s sinks its point into your %2$s!" ), z->name(), body_part_name_accusative( hit ) ); - player_character.add_effect( effect_fungus, 40_minutes, num_bp, true ); + player_character.add_effect( effect_fungus, 40_minutes, true ); add_msg( m_warning, _( "You feel millions of live spores pumping into you…" ) ); } else { //~ 1$s is monster name, 2$s bodypart in accusative @@ -2246,7 +2204,7 @@ bool mattack::dermatik( monster *z ) z->name(), body_part_name_accusative( targeted ) ); if( !foe->has_trait( trait_PARAIMMUNE ) || !foe->has_trait( trait_ACIDBLOOD ) ) { - foe->add_effect( effect_dermatik, 1_turns, targeted->token, true ); + foe->add_effect( effect_dermatik, 1_turns, targeted, true ); get_event_bus().send( foe->getID() ); } @@ -2255,13 +2213,9 @@ bool mattack::dermatik( monster *z ) bool mattack::dermatik_growth( monster *z ) { - // Dermatik larva growing into an adult - if( get_player_character().sees( *z ) ) { - add_msg( m_warning, _( "The %s dermatik larva grows into an adult!" ), - z->name() ); - } + add_msg_if_player_sees( *z, m_warning, _( "The %s dermatik larva grows into an adult!" ), + z->name() ); z->poly( mon_dermatik ); - return false; } @@ -2280,21 +2234,15 @@ bool mattack::plant( monster *z ) const bool is_fungi = here.has_flag_ter( "FUNGUS", monster_position ); // Spores taking seed and growing into a fungaloid fe.spread_fungus( monster_position ); - Character &player_character = get_player_character(); if( is_fungi && one_in( 10 + g->num_creatures() / 5 ) ) { - if( player_character.sees( *z ) ) { - add_msg( m_warning, _( "The %s takes seed and becomes a young fungaloid!" ), - z->name() ); - } + add_msg_if_player_sees( *z, m_warning, _( "The %s takes seed and becomes a young fungaloid!" ), + z->name() ); z->poly( mon_fungaloid_young ); z->moves -= 1000; // It takes a while return false; } else { - if( player_character.sees( *z ) ) { - add_msg( _( "The %s falls to the ground and bursts!" ), - z->name() ); - } + add_msg_if_player_sees( *z, _( "The %s falls to the ground and bursts!" ), z->name() ); z->set_hp( 0 ); // Try fungifying once again fe.spread_fungus( monster_position ); @@ -2320,11 +2268,8 @@ static void poly_keep_speed( monster &mon, const mtype_id &id ) static bool blobify( monster &blob, monster &target ) { - if( get_player_character().sees( target ) ) { - add_msg( m_warning, _( "%s is engulfed by %s!" ), - target.disp_name(), blob.disp_name() ); - } - + add_msg_if_player_sees( target, m_warning, _( "%s is engulfed by %s!" ), + target.disp_name(), blob.disp_name() ); switch( target.get_size() ) { case creature_size::tiny: // Just consume it @@ -2469,7 +2414,7 @@ bool mattack::callblobs( monster *z ) } ( *ally )->set_dest( post ); if( !( *ally )->has_effect( effect_controlled ) ) { - ( *ally )->add_effect( effect_controlled, 1_turns, num_bp, true ); + ( *ally )->add_effect( effect_controlled, 1_turns, true ); } } // This is telepathy, doesn't take any moves. @@ -2505,14 +2450,12 @@ bool mattack::jackson( monster *z ) } ( *ally )->set_dest( post ); if( !( *ally )->has_effect( effect_controlled ) ) { - ( *ally )->add_effect( effect_controlled, 1_turns, num_bp, true ); + ( *ally )->add_effect( effect_controlled, 1_turns, true ); } } // Did we convert anybody? if( converted ) { - if( get_player_character().sees( *z ) ) { - add_msg( m_warning, _( "The %s lets out a high-pitched cry!" ), z->name() ); - } + add_msg_if_player_sees( *z, m_warning, _( "The %s lets out a high-pitched cry!" ), z->name() ); } // This is telepathy, doesn't take any moves. return true; @@ -2520,7 +2463,7 @@ bool mattack::jackson( monster *z ) bool mattack::dance( monster *z ) { - if( get_player_character().sees( *z ) ) { + if( get_player_view().sees( *z ) ) { switch( rng( 1, 10 ) ) { case 1: add_msg( m_neutral, _( "The %s swings its arms from side to side!" ), z->name() ); @@ -2565,7 +2508,7 @@ bool mattack::dogthing( monster *z ) return false; } - if( !one_in( 3 ) || !get_player_character().sees( *z ) ) { + if( !one_in( 3 ) || !get_player_view().sees( *z ) ) { return false; } @@ -2646,7 +2589,7 @@ bool mattack::ranged_pull( monster *z ) player *foe = dynamic_cast< player * >( target ); map &here = get_map(); std::vector line = here.find_clear_path( z->pos(), target->pos() ); - bool seen = get_player_character().sees( *z ); + bool seen = get_player_view().sees( *z ); for( auto &i : line ) { // Player can't be pulled though bars, furniture, cars or creatures @@ -2724,7 +2667,7 @@ bool mattack::ranged_pull( monster *z ) const int prev_effect = target->get_effect_int( effect_grabbed ); //Duration needs to be at least 2, or grab will immediately be removed - target->add_effect( effect_grabbed, 2_turns, bp_torso, false, prev_effect + 4 ); + target->add_effect( effect_grabbed, 2_turns, bodypart_id( "torso" ), false, prev_effect + 4 ); z->add_effect( effect_grabbing, 2_turns ); return true; } @@ -2771,11 +2714,11 @@ bool mattack::grab( monster *z ) target->add_msg_if_player( m_info, _( "The %s tries to grab you as well, but you bat it away!" ), z->name() ); } else if( pl->is_throw_immune() && ( !pl->is_armed() || - pl->martial_arts_data.selected_has_weapon( pl->weapon.typeId() ) ) ) { + pl->martial_arts_data->selected_has_weapon( pl->weapon.typeId() ) ) ) { target->add_msg_if_player( m_info, _( "The %s tries to grab you…" ), z->name() ); thrown_by_judo( z ); } else if( pl->has_grab_break_tec() ) { - ma_technique tech = pl->martial_arts_data.get_grab_break_tec( cur_weapon ); + ma_technique tech = pl->martial_arts_data->get_grab_break_tec( cur_weapon ); target->add_msg_player_or_npc( m_info, _( tech.avatar_message ), _( tech.npc_message ), z->name() ); } else { target->add_msg_player_or_npc( m_info, _( "The %s tries to grab you, but you break its grab!" ), @@ -2787,7 +2730,7 @@ bool mattack::grab( monster *z ) const int prev_effect = target->get_effect_int( effect_grabbed ); z->add_effect( effect_grabbing, 2_turns ); - target->add_effect( effect_grabbed, 2_turns, bp_torso, false, + target->add_effect( effect_grabbed, 2_turns, bodypart_id( "torso" ), false, prev_effect + z->get_grab_strength() ); target->add_msg_player_or_npc( m_bad, _( "The %s grabs you!" ), _( "The %s grabs !" ), z->name() ); @@ -2849,7 +2792,7 @@ bool mattack::grab_drag( monster *z ) } int prev_effect = target->get_effect_int( effect_grabbed ); z->add_effect( effect_grabbing, 2_turns ); - target->add_effect( effect_grabbed, 2_turns, bp_torso, false, prev_effect + 3 ); + target->add_effect( effect_grabbed, 2_turns, bodypart_id( "torso" ), false, prev_effect + 3 ); // cooldown was not reset prior to refactor here return true; @@ -2899,11 +2842,8 @@ bool mattack::para_sting( monster *z ) bool mattack::triffid_growth( monster *z ) { - // Young triffid growing into an adult - if( get_player_character().sees( *z ) ) { - add_msg( m_warning, _( "The %s young triffid grows into an adult!" ), - z->name() ); - } + add_msg_if_player_sees( *z, m_warning, _( "The %s young triffid grows into an adult!" ), + z->name() ); z->poly( mon_triffid ); return false; @@ -3021,7 +2961,7 @@ bool mattack::nurse_check_up( monster *z ) bool mattack::nurse_assist( monster *z ) { - const bool u_see = get_player_character().sees( *z ); + const bool u_see = get_player_view().sees( *z ); if( u_see && one_in( 100 ) ) { add_msg( m_info, _( "The %s is scanning its surroundings." ), z->name() ); @@ -3051,7 +2991,7 @@ bool mattack::nurse_assist( monster *z ) string_format( _( "a soft robotic voice say, \"Welcome doctor %s. I'll be your assistant today.\"" ), Name::generate( target->male ) ) ); - target->add_effect( effect_assisted, 20_turns, num_bp, false, 12 ); + target->add_effect( effect_assisted, 20_turns, false, 12 ); return true; } } @@ -3154,7 +3094,7 @@ bool mattack::nurse_operate( monster *z ) // Check if we successfully grabbed the target if( target->has_effect( effect_grabbed ) ) { z->dragged_foe_id = target->getID(); - z->add_effect( effect_dragging, 1_turns, num_bp, true ); + z->add_effect( effect_dragging, 1_turns, true ); return true; } } @@ -3406,9 +3346,7 @@ void mattack::rifle( monster *z, Creature *target ) } return; } - if( get_player_character().sees( *z ) ) { - add_msg( m_warning, _( "The %s opens up with its rifle!" ), z->name() ); - } + add_msg_if_player_sees( *z, m_warning, _( "The %s opens up with its rifle!" ), z->name() ); tmp.weapon = item( "m4a1" ).ammo_set( ammo_type, z->ammo[ ammo_type ] ); int burst = std::max( tmp.weapon.gun_get_mode( gun_mode_id( "AUTO" ) ).qty, 1 ); @@ -3467,9 +3405,7 @@ void mattack::frag( monster *z, Creature *target ) // This is for the bots, not } return; } - if( player_character.sees( *z ) ) { - add_msg( m_warning, _( "The %s's grenade launcher fires!" ), z->name() ); - } + add_msg_if_player_sees( *z, m_warning, _( "The %s's grenade launcher fires!" ), z->name() ); tmp.weapon = item( "mgl" ).ammo_set( ammo_type, z->ammo[ ammo_type ] ); int burst = std::max( tmp.weapon.gun_get_mode( gun_mode_id( "AUTO" ) ).qty, 1 ); @@ -3527,9 +3463,7 @@ void mattack::tankgun( monster *z, Creature *target ) } return; } - if( get_player_character().sees( *z ) ) { - add_msg( m_warning, _( "The %s's 120mm cannon fires!" ), z->name() ); - } + add_msg_if_player_sees( *z, m_warning, _( "The %s's 120mm cannon fires!" ), z->name() ); tmp.weapon = item( "TANK" ).ammo_set( ammo_type, z->ammo[ ammo_type ] ); int burst = std::max( tmp.weapon.gun_get_mode( gun_mode_id( "AUTO" ) ).qty, 1 ); @@ -3738,11 +3672,12 @@ bool mattack::flamethrower( monster *z ) // Couldn't find any targets! if( target == nullptr ) { // Because that stupid oaf was in the way! - if( boo_hoo > 0 && player_character.sees( *z ) ) { - add_msg( m_warning, ngettext( "Pointed in your direction, the %s emits an IFF warning beep.", - "Pointed in your direction, the %s emits %d annoyed sounding beeps.", - boo_hoo ), - z->name(), boo_hoo ); + if( boo_hoo > 0 ) { + add_msg_if_player_sees( *z, m_warning, + ngettext( "Pointed in your direction, the %s emits an IFF warning beep.", + "Pointed in your direction, the %s emits %d annoyed sounding beeps.", + boo_hoo ), + z->name(), boo_hoo ); } // Did reset before refactor, changed to match other turret behaviors return false; @@ -3779,15 +3714,13 @@ void mattack::flame( monster *z, Creature *target ) // break out of attack if flame hits a wall // TODO: Z if( here.hit_with_fire( tripoint( i.xy(), z->posz() ) ) ) { - if( player_character.sees( i ) ) { - add_msg( _( "The tongue of flame hits the %s!" ), - here.tername( i.xy() ) ); - } + add_msg_if_player_sees( i, _( "The tongue of flame hits the %s!" ), + here.tername( i.xy() ) ); return; } here.add_field( i, fd_fire, 1 ); } - target->add_effect( effect_onfire, 8_turns, bp_torso ); + target->add_effect( effect_onfire, 8_turns, bodypart_id( "torso" ) ); return; } @@ -3803,16 +3736,14 @@ void mattack::flame( monster *z, Creature *target ) for( auto &i : traj ) { // break out of attack if flame hits a wall if( here.hit_with_fire( tripoint( i.xy(), z->posz() ) ) ) { - if( player_character.sees( i ) ) { - add_msg( _( "The tongue of flame hits the %s!" ), - here.tername( i.xy() ) ); - } + add_msg_if_player_sees( i, _( "The tongue of flame hits the %s!" ), + here.tername( i.xy() ) ); return; } here.add_field( i, fd_fire, 1 ); } if( !target->uncanny_dodge() ) { - target->add_effect( effect_onfire, 8_turns, bp_torso ); + target->add_effect( effect_onfire, 8_turns, bodypart_id( "torso" ) ); } } @@ -3879,11 +3810,12 @@ bool mattack::chickenbot( monster *z ) } else { target = z->auto_find_hostile_target( 38, boo_hoo ); if( target == nullptr ) { - if( boo_hoo > 0 && player_character.sees( *z ) ) { // because that stupid oaf was in the way! - add_msg( m_warning, ngettext( "Pointed in your direction, the %s emits an IFF warning beep.", - "Pointed in your direction, the %s emits %d annoyed sounding beeps.", - boo_hoo ), - z->name(), boo_hoo ); + if( boo_hoo > 0 ) { // because that stupid oaf was in the way! + add_msg_if_player_sees( *z, m_warning, + ngettext( "Pointed in your direction, the %s emits an IFF warning beep.", + "Pointed in your direction, the %s emits %d annoyed sounding beeps.", + boo_hoo ), + z->name(), boo_hoo ); } return false; } @@ -3962,11 +3894,12 @@ bool mattack::multi_robot( monster *z ) } else { target = z->auto_find_hostile_target( 48, boo_hoo ); if( target == nullptr ) { - if( boo_hoo > 0 && player_character.sees( *z ) ) { // because that stupid oaf was in the way! - add_msg( m_warning, ngettext( "Pointed in your direction, the %s emits an IFF warning beep.", - "Pointed in your direction, the %s emits %d annoyed sounding beeps.", - boo_hoo ), - z->name(), boo_hoo ); + if( boo_hoo > 0 ) { // because that stupid oaf was in the way! + add_msg_if_player_sees( *z, m_warning, + ngettext( "Pointed in your direction, the %s emits an IFF warning beep.", + "Pointed in your direction, the %s emits %d annoyed sounding beeps.", + boo_hoo ), + z->name(), boo_hoo ); } return false; } @@ -4100,12 +4033,12 @@ bool mattack::upgrade( monster *z ) monster *target = random_entry( targets ); std::string old_name = target->name(); - Character &player_character = get_player_character(); - const bool could_see = player_character.sees( *target ); + viewer &player_view = get_player_view(); + const bool could_see = player_view.sees( *target ); target->hasten_upgrade(); target->try_upgrade( false ); - const bool can_see = player_character.sees( *target ); - if( player_character.sees( *z ) ) { + const bool can_see = player_view.sees( *target ); + if( player_view.sees( *z ) ) { if( could_see ) { //~ %1$s is the name of the zombie upgrading the other, %2$s is the zombie being upgraded. add_msg( m_warning, _( "A black mist floats from the %1$s around the %2$s." ), @@ -4198,7 +4131,6 @@ bool mattack::stretch_bite( monster *z ) } const bodypart_id hit = target->get_random_body_part(); - const body_part hit_token = hit->token; // More damage due to the speed of the moving head int dam = rng( 5, 15 ); dam = target->deal_damage( z, hit, damage_instance( DT_STAB, dam ) ).total_damage(); @@ -4214,12 +4146,12 @@ bool mattack::stretch_bite( monster *z ) body_part_name_accusative( hit ) ); if( one_in( 16 - dam ) ) { - if( target->has_effect( effect_bite, hit_token ) ) { - target->add_effect( effect_bite, 40_minutes, hit_token, true ); - } else if( target->has_effect( effect_infected, hit_token ) ) { - target->add_effect( effect_infected, 25_minutes, hit_token, true ); + if( target->has_effect( effect_bite, hit.id() ) ) { + target->add_effect( effect_bite, 40_minutes, hit, true ); + } else if( target->has_effect( effect_infected, hit.id() ) ) { + target->add_effect( effect_infected, 25_minutes, hit, true ); } else { - target->add_effect( effect_bite, 1_turns, hit_token, true ); + target->add_effect( effect_bite, 1_turns, hit, true ); } } } else { @@ -4281,10 +4213,8 @@ bool mattack::flesh_golem( monster *z ) // No attacking through floor, even if we can see the target somehow return false; } - if( get_player_character().sees( *z ) ) { - add_msg( _( "The %1$s swings a massive claw at %2$s!" ), z->name(), - target->disp_name() ); - } + add_msg_if_player_sees( *z, _( "The %1$s swings a massive claw at %2$s!" ), + z->name(), target->disp_name() ); z->moves -= 100; if( target->uncanny_dodge() ) { @@ -4385,7 +4315,7 @@ bool mattack::lunge( monster *z ) return false; } - bool seen = get_player_character().sees( *z ); + bool seen = get_player_view().sees( *z ); if( dist > 1 ) { if( one_in( 5 ) ) { // Out of range @@ -4538,7 +4468,7 @@ bool mattack::longswipe( monster *z ) if( target->is_player() || target->is_npc() ) { target->as_character()->make_bleed( bodypart_id( "head" ), 15_minutes ); } else { - target->add_effect( effect_bleed, 15_minutes, bp_head ); + target->add_effect( effect_bleed, 15_minutes, bodypart_id( "head" ) ); } } else { @@ -4605,10 +4535,7 @@ bool mattack::darkman( monster *z ) if( monster *const shadow = g->place_critter_around( mon_shadow, z->pos(), 1 ) ) { z->moves -= 10; shadow->make_ally( *z ); - if( player_character.sees( *z ) ) { - add_msg( m_warning, _( "A shadow splits from the %s!" ), - z->name() ); - } + add_msg_if_player_sees( *z, m_warning, _( "A shadow splits from the %s!" ), z->name() ); } // Wont do the combat stuff unless it can see you if( !z->sees( player_character ) ) { @@ -4638,7 +4565,7 @@ bool mattack::darkman( monster *z ) add_msg( _( "\"Please dont\"" ) ); break; } - player_character.add_effect( effect_darkness, 1_turns, num_bp, true ); + player_character.add_effect( effect_darkness, 1_turns, true ); return true; } @@ -5025,7 +4952,7 @@ bool mattack::evolve_kill_strike( monster *z ) bool mattack::leech_spawner( monster *z ) { - const bool u_see = get_player_character().sees( *z ); + const bool u_see = get_player_view().sees( *z ); std::list allies; for( monster &candidate : g->all_monsters() ) { if( candidate.in_species( species_LEECH_PLANT ) && !candidate.has_flag( MF_IMMOBILE ) ) { @@ -5057,7 +4984,6 @@ bool mattack::leech_spawner( monster *z ) bool mattack::mon_leech_evolution( monster *z ) { - const bool u_see = get_player_character().sees( *z ); const bool is_queen = z->has_flag( MF_QUEEN ); std::list queens; for( monster &candidate : g->all_monsters() ) { @@ -5070,10 +4996,7 @@ bool mattack::mon_leech_evolution( monster *z ) if( queens.empty() ) { z->poly( mon_leech_blossom ); z->set_hp( z->get_hp_max() ); - if( u_see ) { - add_msg( m_warning, - _( "The %s blooms into flowers!" ), z->name() ); - } + add_msg_if_player_sees( *z, m_warning, _( "The %s blooms into flowers!" ), z->name() ); } } return true; @@ -5085,16 +5008,13 @@ bool mattack::tindalos_teleport( monster *z ) if( target == nullptr ) { return false; } - Character &player_character = get_player_character(); if( one_in( 7 ) ) { if( monster *const afterimage = g->place_critter_around( mon_hound_tindalos_afterimage, z->pos(), 1 ) ) { z->moves -= 140; afterimage->make_ally( *z ); - if( player_character.sees( *z ) ) { - add_msg( m_warning, - _( "The hound's movements chaotically rewind as a living afterimage splits from it!" ) ); - } + add_msg_if_player_sees( *z, m_warning, + _( "The hound's movements chaotically rewind as a living afterimage splits from it!" ) ); } } const int distance_to_target = rl_dist( z->pos(), target->pos() ); @@ -5109,9 +5029,7 @@ bool mattack::tindalos_teleport( monster *z ) if( z->sees( *target ) ) { here.add_field( oldpos, fd_tindalos_rift, 2 ); here.add_field( dest, fd_tindalos_rift, 2 ); - if( player_character.sees( *z ) ) { - add_msg( m_bad, _( "The %s dissipates and reforms close by." ), z->name() ); - } + add_msg_if_player_sees( *z, m_bad, _( "The %s dissipates and reforms close by." ), z->name() ); return true; } } @@ -5150,10 +5068,8 @@ bool mattack::flesh_tendril( monster *z ) z->moves -= 100; summoned->make_ally( *z ); get_map().propagate_field( z->pos(), fd_gibs_flesh, 75, 1 ); - if( get_player_character().sees( *z ) ) { - add_msg( m_warning, _( "A %s struggles to pull itself free from the %s!" ), summoned->name(), - z->name() ); - } + add_msg_if_player_sees( *z, m_warning, _( "A %s struggles to pull itself free from the %s!" ), + summoned->name(), z->name() ); } return true; } @@ -5238,7 +5154,7 @@ bool mattack::bio_op_takedown( monster *z ) return false; } - bool seen = get_player_character().sees( *z ); + bool seen = get_player_view().sees( *z ); player *foe = dynamic_cast< player * >( target ); if( seen ) { add_msg( _( "The %1$s mechanically grabs at %2$s!" ), z->name(), @@ -5305,7 +5221,7 @@ bool mattack::bio_op_takedown( monster *z ) foe->add_effect( effect_downed, 3_turns ); } } else if( ( !foe->is_armed() || - foe->martial_arts_data.selected_has_weapon( foe->weapon.typeId() ) ) && + foe->martial_arts_data->selected_has_weapon( foe->weapon.typeId() ) ) && !thrown_by_judo( z ) ) { // Saved by the tentacle-bracing! :) hit = bodypart_id( "torso" ); @@ -5332,7 +5248,7 @@ bool mattack::bio_op_impale( monster *z ) return false; } - const bool seen = get_player_character().sees( *z ); + const bool seen = get_player_view().sees( *z ); player *foe = dynamic_cast< player * >( target ); if( seen ) { add_msg( _( "The %1$s mechanically lunges at %2$s!" ), z->name(), @@ -5366,7 +5282,7 @@ bool mattack::bio_op_impale( monster *z ) // Handle mons earlier - less to check for target->deal_damage( z, bodypart_id( "torso" ), damage_instance( DT_STAB, dam ) ); if( do_bleed ) { - target->add_effect( effect_bleed, rng( 3_minutes, 10_minutes ), bp_torso, true ); + target->add_effect( effect_bleed, rng( 3_minutes, 10_minutes ), bodypart_id( "torso" ), true ); } if( seen ) { add_msg( _( "The %1$s impales %2$s!" ), z->name(), target->disp_name() ); @@ -5413,7 +5329,7 @@ bool mattack::bio_op_disarm( monster *z ) return false; } - const bool seen = get_player_character().sees( *z ); + const bool seen = get_player_view().sees( *z ); player *foe = dynamic_cast< player * >( target ); // disarm doesn't work on creatures or unarmed targets @@ -5607,9 +5523,7 @@ bool mattack::kamikaze( monster *z ) */ // END HORRIBLE HACK - if( get_player_character().sees( z->pos() ) ) { - add_msg( m_bad, _( "The %s lights up menacingly." ), z->name() ); - } + add_msg_if_player_sees( z->pos(), m_bad, _( "The %s lights up menacingly." ), z->name() ); return true; } @@ -5662,7 +5576,7 @@ static int grenade_helper( monster *const z, Creature *const target, const int d z->ammo[att]--; // if the player can see it - if( get_player_character().sees( *z ) ) { + if( get_player_view().sees( *z ) ) { if( data[att].message.empty() ) { add_msg( m_debug, "Invalid ammo message in grenadier special." ); } else { @@ -5843,13 +5757,10 @@ bool mattack::zombie_fuse( monster *z ) effect_grown_of_fuse ).get_max_intensity() ) ) ) { return false; } - if( get_player_character().sees( *z ) ) { - add_msg( _( "The %1$s fuses with the %2$s." ), - critter->name(), - z->name() ); - } + add_msg_if_player_sees( *z, _( "The %1$s fuses with the %2$s." ), + critter->name(), z->name() ); z->moves -= 200; - z->add_effect( effect_grown_of_fuse, 10_days, num_bp, true, + z->add_effect( effect_grown_of_fuse, 10_days, true, critter->get_hp_max() + z->get_effect( effect_grown_of_fuse ).get_intensity() ); z->heal( critter->get_hp(), true ); critter->death_drops = false; @@ -5860,10 +5771,7 @@ bool mattack::zombie_fuse( monster *z ) bool mattack::doot( monster *z ) { z->moves -= 300; - Character &player_character = get_player_character(); - if( player_character.sees( *z ) ) { - add_msg( _( "The %s doots its trumpet!" ), z->name() ); - } + add_msg_if_player_sees( *z, _( "The %s doots its trumpet!" ), z->name() ); int spooks = 0; for( const tripoint &spookyscary : get_map().points_in_radius( z->pos(), 2 ) ) { if( !g->is_empty( spookyscary ) ) { @@ -5871,9 +5779,7 @@ bool mattack::doot( monster *z ) } const int dist = rl_dist( z->pos(), spookyscary ); if( ( one_in( dist + 3 ) || spooks == 0 ) && spooks < 5 ) { - if( player_character.sees( *z ) ) { - add_msg( _( "A spooky skeleton rises from the ground!" ) ); - } + add_msg_if_player_sees( spookyscary, _( "A spooky skeleton rises from the ground!" ) ); g->place_critter_at( mon_zombie_skeltal_minion, spookyscary ); spooks++; continue; diff --git a/src/mondeath.cpp b/src/mondeath.cpp index 02c65c35ddceb..770dbdbbffa29 100644 --- a/src/mondeath.cpp +++ b/src/mondeath.cpp @@ -93,10 +93,8 @@ void mdeath::normal( monster &z ) sfx::play_variant_sound( "mon_death", "zombie_death", sfx::get_heard_volume( z.pos() ) ); } - if( get_player_character().sees( z ) ) { - //Currently it is possible to get multiple messages that a monster died. - add_msg( m_good, _( "The %s dies!" ), z.name() ); - } + //Currently it is possible to get multiple messages that a monster died. + add_msg_if_player_sees( z, m_good, _( "The %s dies!" ), z.name() ); const int max_hp = std::max( z.get_hp_max(), 1 ); const float overflow_damage = std::max( -z.get_hp(), 0 ); @@ -238,7 +236,7 @@ void mdeath::splatter( monster &z ) void mdeath::acid( monster &z ) { - if( get_player_character().sees( z ) ) { + if( get_player_view().sees( z ) ) { if( z.type->dies.size() == 1 ) { //If this death function is the only function. The corpse gets dissolved. add_msg( m_mixed, _( "The %s's body dissolves into acid." ), z.name() ); @@ -264,7 +262,7 @@ void mdeath::boomer( monster &z ) Character &player_character = get_player_character(); if( rl_dist( z.pos(), player_character.pos() ) == 1 ) { - player_character.add_env_effect( effect_boomered, bp_eyes, 2, 24_turns ); + player_character.add_env_effect( effect_boomered, bodypart_id( "eyes" ), 2, 24_turns ); } here.propagate_field( z.pos(), fd_bile, 15, 1 ); @@ -283,10 +281,10 @@ void mdeath::boomer_glow( monster &z ) target->moves -= 250; } if( Creature *const critter = g->critter_at( dest ) ) { - critter->add_env_effect( effect_boomered, bp_eyes, 5, 25_turns ); + critter->add_env_effect( effect_boomered, bodypart_id( "eyes" ), 5, 25_turns ); for( int i = 0; i < rng( 2, 4 ); i++ ) { body_part bp = random_body_part(); - critter->add_env_effect( effect_glowing, bp, 4, 4_minutes ); + critter->add_env_effect( effect_glowing, convert_bp( bp ).id(), 4, 4_minutes ); if( critter->has_effect( effect_glowing ) ) { break; } @@ -358,9 +356,7 @@ void mdeath::vine_cut( monster &z ) void mdeath::triffid_heart( monster &z ) { - if( get_player_character().sees( z ) ) { - add_msg( m_warning, _( "The surrounding roots begin to crack and crumble." ) ); - } + add_msg_if_player_sees( z, m_warning, _( "The surrounding roots begin to crack and crumble." ) ); get_timed_events().add( timed_event_type::ROOTS_DIE, calendar::turn + 10_minutes ); } @@ -383,19 +379,15 @@ void mdeath::fungus( monster &z ) void mdeath::disintegrate( monster &z ) { - if( get_player_character().sees( z ) ) { - add_msg( m_good, _( "The %s disintegrates!" ), z.name() ); - } + add_msg_if_player_sees( z, m_good, _( "The %s disintegrates!" ), z.name() ); } void mdeath::worm( monster &z ) { - if( get_player_character().sees( z ) ) { - if( z.type->dies.size() == 1 ) { - add_msg( m_good, _( "The %s splits in two!" ), z.name() ); - } else { - add_msg( m_warning, _( "Two worms crawl out of the %s's corpse." ), z.name() ); - } + if( z.type->dies.size() == 1 ) { + add_msg_if_player_sees( z, m_good, _( "The %s splits in two!" ), z.name() ); + } else { + add_msg_if_player_sees( z, m_warning, _( "Two worms crawl out of the %s's corpse." ), z.name() ); } int worms = 2; @@ -406,9 +398,7 @@ void mdeath::worm( monster &z ) void mdeath::disappear( monster &z ) { - if( get_player_character().sees( z ) ) { - add_msg( m_good, _( "The %s disappears." ), z.name() ); - } + add_msg_if_player_sees( z, m_good, _( "The %s disappears." ), z.name() ); } void mdeath::guilt( monster &z ) @@ -483,15 +473,13 @@ void mdeath::blobsplit( monster &z ) { int speed = z.get_speed() - rng( 30, 50 ); get_map().spawn_item( z.pos(), "slime_scrap", 1, 0, calendar::turn ); - Character &player_character = get_player_character(); - if( z.get_speed() <= 0 ) { - if( player_character.sees( z ) ) { - // TODO: Add vermin-tagged tiny versions of the splattered blob :) - add_msg( m_good, _( "The %s splatters apart." ), z.name() ); - } + bool sees_blob = get_player_view().sees( z ); + if( z.get_speed() <= 0 && sees_blob ) { + // TODO: Add vermin-tagged tiny versions of the splattered blob :) + add_msg( m_good, _( "The %s splatters apart." ), z.name() ); return; } - if( player_character.sees( z ) ) { + if( sees_blob ) { if( z.type->dies.size() == 1 ) { add_msg( m_good, _( "The %s splits in two!" ), z.name() ); } else { @@ -529,16 +517,14 @@ void mdeath::jackson( monster &z ) } music_stopped = true; } - if( music_stopped && get_player_character().sees( z ) ) { - add_msg( m_warning, _( "The music stops!" ) ); + if( music_stopped ) { + add_msg_if_player_sees( z, m_warning, _( "The music stops!" ) ); } } void mdeath::melt( monster &z ) { - if( get_player_character().sees( z ) ) { - add_msg( m_good, _( "The %s melts away." ), z.name() ); - } + add_msg_if_player_sees( z, m_good, _( "The %s melts away." ), z.name() ); } void mdeath::amigara( monster &z ) @@ -604,11 +590,8 @@ void mdeath::focused_beam( monster &z ) } if( !z.inv.empty() ) { - - if( get_player_character().sees( z ) ) { - add_msg( m_warning, _( "As the final light is destroyed, it erupts in a blinding flare!" ) ); - } - + add_msg_if_player_sees( z, m_warning, + _( "As the final light is destroyed, it erupts in a blinding flare!" ) ); item &settings = z.inv[0]; point p2( z.posx() + settings.get_var( "SL_SPOT_X", 0 ), z.posy() + settings.get_var( "SL_SPOT_Y", @@ -690,11 +673,10 @@ void mdeath::broken( monster &z ) } // TODO: make mdeath::splatter work for robots - Character &player_character = get_player_character(); - if( ( broken_mon.damage() >= broken_mon.max_damage() ) && player_character.sees( z.pos() ) ) { - add_msg( m_good, _( "The %s is destroyed!" ), z.name() ); - } else if( player_character.sees( z.pos() ) ) { - add_msg( m_good, _( "The %s collapses!" ), z.name() ); + if( ( broken_mon.damage() >= broken_mon.max_damage() ) ) { + add_msg_if_player_sees( z.pos(), m_good, _( "The %s is destroyed!" ), z.name() ); + } else { + add_msg_if_player_sees( z.pos(), m_good, _( "The %s collapses!" ), z.name() ); } } @@ -702,9 +684,7 @@ void mdeath::ratking( monster &z ) { Character &player_character = get_player_character(); player_character.remove_effect( effect_rat ); - if( player_character.sees( z ) ) { - add_msg( m_warning, _( "Rats suddenly swarm into view." ) ); - } + add_msg_if_player_sees( z, m_warning, _( "Rats suddenly swarm into view." ) ); for( int rats = 0; rats < 7; rats++ ) { g->place_critter_around( mon_sewer_rat, z.pos(), 1 ); @@ -715,9 +695,7 @@ void mdeath::darkman( monster &z ) { Character &player_character = get_player_character(); player_character.remove_effect( effect_darkness ); - if( player_character.sees( z ) ) { - add_msg( m_good, _( "The %s melts away." ), z.name() ); - } + add_msg_if_player_sees( z, m_good, _( "The %s melts away." ), z.name() ); } void mdeath::gas( monster &z ) @@ -739,9 +717,7 @@ void mdeath::fungalburst( monster &z ) map &here = get_map(); // If the fungus died from anti-fungal poison, don't pouf if( here.get_field_intensity( z.pos(), fd_fungicidal_gas ) ) { - if( get_player_character().sees( z ) ) { - add_msg( m_good, _( "The %s inflates and melts away." ), z.name() ); - } + add_msg_if_player_sees( z, m_good, _( "The %s inflates and melts away." ), z.name() ); return; } @@ -789,11 +765,10 @@ void mdeath::kill_breathers( monster &/*z*/ ) void mdeath::broken_ammo( monster &z ) { - if( get_player_character().sees( z.pos() ) ) { - //~ %s is the possessive form of the monster's name - add_msg( m_info, _( "The %s's interior compartment sizzles with destructive energy." ), - z.name() ); - } + add_msg_if_player_sees( z.pos(), m_info, + //~ %s is the possessive form of the monster's name + _( "The %s's interior compartment sizzles with destructive energy." ), + z.name() ); mdeath::broken( z ); } @@ -814,13 +789,11 @@ void make_mon_corpse( monster &z, int damageLvl ) void mdeath::preg_roach( monster &z ) { - Character &player_character = get_player_character(); int num_roach = rng( 1, 3 ); while( num_roach > 0 && g->place_critter_around( mon_giant_cockroach_nymph, z.pos(), 1 ) ) { num_roach--; - if( player_character.sees( z ) ) { - add_msg( m_warning, _( "A cockroach nymph crawls out of the pregnant giant cockroach corpse." ) ); - } + add_msg_if_player_sees( z, m_warning, + _( "A cockroach nymph crawls out of the pregnant giant cockroach corpse." ) ); } } diff --git a/src/mondefense.cpp b/src/mondefense.cpp index 50994dc197149..ac4bfbaadbaeb 100644 --- a/src/mondefense.cpp +++ b/src/mondefense.cpp @@ -12,7 +12,6 @@ #include "ballistics.h" #include "bodypart.h" -#include "character.h" #include "creature.h" #include "damage.h" #include "dispersion.h" @@ -77,7 +76,7 @@ void mdefense::zapback( monster &m, Creature *const source, return; } - if( get_player_character().sees( source->pos() ) ) { + if( get_player_view().sees( source->pos() ) ) { const auto msg_type = source->is_avatar() ? m_bad : m_info; add_msg( msg_type, _( "Striking the %1$s shocks %2$s!" ), m.name(), source->disp_name() ); @@ -140,7 +139,7 @@ void mdefense::acidsplash( monster &m, Creature *const source, projectile_attack( prj, m.pos(), target, dispersion_sources{ 1200 }, &m ); } - if( get_player_character().sees( m.pos() ) ) { + if( get_player_view().sees( m.pos() ) ) { add_msg( m_warning, _( "Acid sprays out of %s as it is hit!" ), m.disp_name() ); } } diff --git a/src/monexamine.cpp b/src/monexamine.cpp index 0cdf03ebbd5e9..686eed0a89ac0 100644 --- a/src/monexamine.cpp +++ b/src/monexamine.cpp @@ -300,7 +300,7 @@ void monexamine::shear_animal( monster &z ) player_character.activity.coords.push_back( get_map().getabs( z.pos() ) ); // pin the sheep in place if it isn't already if( !z.has_effect( effect_tied ) ) { - z.add_effect( effect_tied, 1_turns, num_bp, true ); + z.add_effect( effect_tied, 1_turns, true ); player_character.activity.str_values.push_back( "temp_tie" ); } player_character.activity.targets.push_back( item_location( player_character, @@ -374,7 +374,7 @@ bool monexamine::mech_hack( monster &z ) if( player_character.has_amount( card_type, 1 ) ) { if( query_yn( _( "Swipe your ID card into the mech's security port?" ) ) ) { player_character.mod_moves( -100 ); - z.add_effect( effect_pet, 1_turns, num_bp, true ); + z.add_effect( effect_pet, 1_turns, true ); z.friendly = -1; add_msg( m_good, _( "The %s whirs into life and opens its restraints to accept a pilot." ), z.get_name() ); @@ -427,7 +427,7 @@ bool monexamine::pay_bot( monster &z ) time_duration time_bought = time_duration::from_minutes( amount ); player_character.use_charges( itype_cash_card, amount * 10 ); z.add_effect( effect_pet, time_bought ); - z.add_effect( effect_paid, time_bought, num_bp, true ); + z.add_effect( effect_paid, time_bought, true ); z.friendly = -1; popup( _( "Your friendship grows stronger!\n This %s will follow you for %s." ), z.get_name(), to_string( z.get_effect_dur( effect_pet ) ) ); @@ -454,7 +454,7 @@ void monexamine::attach_or_remove_saddle( monster &z ) add_msg( _( "Never mind." ) ); return; } - z.add_effect( effect_monster_saddled, 1_turns, num_bp, true ); + z.add_effect( effect_monster_saddled, 1_turns, true ); z.tack_item = cata::make_value( *loc.get_item() ); loc.remove_item(); } @@ -497,7 +497,7 @@ void monexamine::swap( monster &z ) g->swap_critters( player_character, z ); if( t ) { - z.add_effect( effect_tied, 1_turns, num_bp, true ); + z.add_effect( effect_tied, 1_turns, true ); } add_msg( _( "You swap positions with your %s." ), pet_name ); } else { @@ -555,7 +555,7 @@ void monexamine::attach_bag_to( monster &z ) z.storage_item = cata::make_value( it ); add_msg( _( "You mount the %1$s on your %2$s." ), it.display_name(), pet_name ); player_character.i_rem( &it ); - z.add_effect( effect_has_bag, 1_turns, num_bp, true ); + z.add_effect( effect_has_bag, 1_turns, true ); // Update encumbrance in case we were wearing it player_character.flag_encumbrance(); player_character.moves -= 200; @@ -652,7 +652,7 @@ bool monexamine::add_armor( monster &z ) add_msg( pgettext( "pet armor", "You put the %1$s on your %2$s." ), armor.display_name(), pet_name ); loc.remove_item(); - z.add_effect( effect_monster_armor, 1_turns, num_bp, true ); + z.add_effect( effect_monster_armor, 1_turns, true ); // TODO: armoring a horse takes a lot longer than 2 seconds. This should be a long action. get_player_character().moves -= 200; return true; @@ -738,7 +738,7 @@ void monexamine::tie_or_untie( monster &z ) item *rope_item = rope_inv[index - 1]; z.tied_item = cata::make_value( *rope_item ); player_character.i_rem( rope_item ); - z.add_effect( effect_tied, 1_turns, num_bp, true ); + z.add_effect( effect_tied, 1_turns, true ); } } @@ -758,7 +758,7 @@ void monexamine::milk_source( monster &source_mon ) // pin the cow in place if it isn't already bool temp_tie = !source_mon.has_effect( effect_tied ); if( temp_tie ) { - source_mon.add_effect( effect_tied, 1_turns, num_bp, true ); + source_mon.add_effect( effect_tied, 1_turns, true ); player_character.activity.str_values.push_back( "temp_tie" ); } add_msg( _( "You milk the %s." ), source_mon.get_name() ); diff --git a/src/monmove.cpp b/src/monmove.cpp index 3e433fa8bff47..2d48586406275 100644 --- a/src/monmove.cpp +++ b/src/monmove.cpp @@ -607,9 +607,7 @@ bool monster::die_if_drowning( const tripoint &at_pos, const int chance ) { if( is_aquatic_danger( at_pos ) && one_in( chance ) ) { die( nullptr ); - if( get_player_character().sees( at_pos ) ) { - add_msg( _( "The %s drowns!" ), name() ); - } + add_msg_if_player_sees( at_pos, _( "The %s drowns!" ), name() ); return true; } return false; @@ -645,10 +643,9 @@ void monster::move() //If there are. Consume them. // TODO: Stick this in a map and dispatch to it via the action string. if( action == "consume_items" ) { - if( player_character.sees( *this ) ) { - add_msg( _( "The %s flows around the objects on the floor and they are quickly dissolved!" ), - name() ); - } + add_msg_if_player_sees( *this, + _( "The %s flows around the objects on the floor and they are quickly dissolved!" ), + name() ); static const auto volume_per_hp = 250_ml; for( item &elem : here.i_at( pos() ) ) { hp += elem.volume() / volume_per_hp; // Yeah this means it can get more HP than normal. @@ -661,9 +658,7 @@ void monster::move() hp -= type->hp; //this is a new copy of the monster. Ideally we should copy the stats/effects that affect the parent spawn->make_ally( *this ); - if( player_character.sees( *this ) ) { - add_msg( _( "The %s splits in two!" ), name() ); - } + add_msg_if_player_sees( *this, _( "The %s splits in two!" ), name() ); } } } @@ -1494,7 +1489,6 @@ bool monster::move_to( const tripoint &p, bool force, bool step_on_critter, } } - Character &player_character = get_player_character(); // Allows climbing monsters to move on terrain with movecost <= 0 Creature *critter = g->critter_at( destination, is_hallucination() ); if( here.has_flag( "CLIMBABLE", destination ) ) { @@ -1502,19 +1496,15 @@ bool monster::move_to( const tripoint &p, bool force, bool step_on_critter, if( flies() ) { moves -= 100; force = true; - if( player_character.sees( *this ) ) { - add_msg( _( "The %1$s flies over the %2$s." ), name(), - here.has_flag_furn( "CLIMBABLE", p ) ? here.furnname( p ) : - here.tername( p ) ); - } + add_msg_if_player_sees( *this, _( "The %1$s flies over the %2$s." ), name(), + here.has_flag_furn( "CLIMBABLE", p ) ? here.furnname( p ) : + here.tername( p ) ); } else if( climbs() ) { moves -= 150; force = true; - if( player_character.sees( *this ) ) { - add_msg( _( "The %1$s climbs over the %2$s." ), name(), - here.has_flag_furn( "CLIMBABLE", p ) ? here.furnname( p ) : - here.tername( p ) ); - } + add_msg_if_player_sees( *this, _( "The %1$s climbs over the %2$s." ), name(), + here.has_flag_furn( "CLIMBABLE", p ) ? here.furnname( p ) : + here.tername( p ) ); } } } @@ -1549,24 +1539,25 @@ bool monster::move_to( const tripoint &p, bool force, bool step_on_critter, bool will_be_water = on_ground && can_submerge() && here.is_divable( destination ); //Birds and other flying creatures flying over the deep water terrain - if( was_water && flies() && player_character.sees( *this ) ) { + if( was_water && flies() ) { if( one_in( 4 ) ) { - add_msg( m_warning, _( "A %1$s flies over the %2$s!" ), name(), - here.tername( pos() ) ); + add_msg_if_player_sees( *this, m_warning, _( "A %1$s flies over the %2$s!" ), + name(), here.tername( pos() ) ); } - } else if( was_water && !will_be_water && player_character.sees( *this ) ) { + } else if( was_water && !will_be_water ) { // Use more dramatic messages for swimming monsters - //~ Message when a monster emerges from water - //~ %1$s: monster name, %2$s: leaps/emerges, %3$s: terrain name - add_msg( m_warning, pgettext( "monster movement", "A %1$s %2$s from the %3$s!" ), name(), - swims() || has_flag( MF_AQUATIC ) ? _( "leaps" ) : _( "emerges" ), - here.tername( pos() ) ); - } else if( !was_water && will_be_water && player_character.sees( *this ) ) { - //~ Message when a monster enters water - //~ %1$s: monster name, %2$s: dives/sinks, %3$s: terrain name - add_msg( m_warning, pgettext( "monster movement", "A %1$s %2$s into the %3$s!" ), name(), - swims() || has_flag( MF_AQUATIC ) ? _( "dives" ) : _( "sinks" ), - here.tername( destination ) ); + add_msg_if_player_sees( *this, m_warning, + //~ Message when a monster emerges from water + //~ %1$s: monster name, %2$s: leaps/emerges, %3$s: terrain name + pgettext( "monster movement", "A %1$s %2$s from the %3$s!" ), + name(), swims() || has_flag( MF_AQUATIC ) ? _( "leaps" ) : _( "emerges" ), here.tername( pos() ) ); + } else if( !was_water && will_be_water ) { + add_msg_if_player_sees( *this, m_warning, pgettext( "monster movement", + //~ Message when a monster enters water + //~ %1$s: monster name, %2$s: dives/sinks, %3$s: terrain name + "A %1$s %2$s into the %3$s!" ), + name(), swims() || + has_flag( MF_AQUATIC ) ? _( "dives" ) : _( "sinks" ), here.tername( destination ) ); } setpos( destination ); @@ -1591,13 +1582,13 @@ bool monster::move_to( const tripoint &p, bool force, bool step_on_critter, } if( here.has_flag( "UNSTABLE", destination ) && on_ground ) { - add_effect( effect_bouldering, 1_turns, num_bp, true ); + add_effect( effect_bouldering, 1_turns, true ); } else if( has_effect( effect_bouldering ) ) { remove_effect( effect_bouldering ); } if( here.has_flag_ter_or_furn( TFLAG_NO_SIGHT, destination ) && on_ground ) { - add_effect( effect_no_sight, 1_turns, num_bp, true ); + add_effect( effect_no_sight, 1_turns, true ); } else if( has_effect( effect_no_sight ) ) { remove_effect( effect_no_sight ); } @@ -1796,9 +1787,9 @@ bool monster::push_to( const tripoint &p, const int boost, const size_t depth ) critter->add_effect( effect_stunned, rng( 0_turns, 2_turns ) ); Character &player_character = get_player_character(); // Only print the message when near player or it can get spammy - if( rl_dist( player_character.pos(), pos() ) < 4 && player_character.sees( *critter ) ) { - add_msg( m_warning, _( "The %1$s tramples %2$s" ), - name(), critter->disp_name() ); + if( rl_dist( player_character.pos(), pos() ) < 4 ) { + add_msg_if_player_sees( *critter, m_warning, _( "The %1$s tramples %2$s" ), + name(), critter->disp_name() ); } moves -= movecost_attacker; @@ -1871,7 +1862,7 @@ void monster::knock_back_to( const tripoint &to ) return; } - bool u_see = get_player_character().sees( to ); + bool u_see = get_player_view().sees( to ); // First, see if we hit another monster if( monster *const z = g->critter_at( to ) ) { @@ -2052,11 +2043,10 @@ void monster::shove_vehicle( const tripoint &remote_destination, break; } if( shove_velocity > 0 ) { - if( get_player_character().sees( this->pos() ) ) { - //~ %1$s - monster name, %2$s - vehicle name - add_msg( m_bad, _( "%1$s shoves %2$s out of their way!" ), this->disp_name(), - veh.disp_name() ); - } + //~ %1$s - monster name, %2$s - vehicle name + add_msg_if_player_sees( this->pos(), m_bad, _( "%1$s shoves %2$s out of their way!" ), + this->disp_name(), + veh.disp_name() ); int shove_moves = shove_veh_mass_moves_factor * veh_mass / 10_kilogram; shove_moves = std::max( shove_moves, shove_moves_minimal ); this->mod_moves( -shove_moves ); diff --git a/src/monster.cpp b/src/monster.cpp index 02c3ef95a694c..a9624e9c1545b 100644 --- a/src/monster.cpp +++ b/src/monster.cpp @@ -1488,7 +1488,7 @@ void monster::melee_attack( Creature &target, float accuracy ) // Add any on damage effects for( const auto &eff : type->atk_effs ) { if( x_in_y( eff.chance, 100 ) ) { - const body_part affected_bp = eff.affect_hit_bp ? dealt_dam.bp_hit->token : eff.bp; + const bodypart_id affected_bp = eff.affect_hit_bp ? dealt_dam.bp_hit : convert_bp( eff.bp ).id(); target.add_effect( eff.id, time_duration::from_turns( eff.duration ), affected_bp, eff.permanent ); } } @@ -1646,7 +1646,7 @@ bool monster::move_effects( bool ) } map &here = get_map(); - bool u_see_me = get_player_character().sees( *this ); + bool u_see_me = get_player_view().sees( *this ); if( has_effect( effect_tied ) ) { // friendly pet, will stay tied down and obey. if( friendly == -1 ) { @@ -1783,13 +1783,6 @@ bool monster::move_effects( bool ) return true; } -void monster::add_effect( const efftype_id &eff_id, const time_duration &dur, body_part/*bp*/, - bool permanent, int intensity, bool force, bool deferred ) -{ - // Effects are not applied to specific monster body part - Creature::add_effect( eff_id, dur, num_bp, permanent, intensity, force, deferred ); -} - std::string monster::get_effect_status() const { std::vector effect_status; @@ -2117,9 +2110,7 @@ void monster::process_turn() sounds::sound( pos(), 5, sounds::sound_t::combat, _( "hummmmm." ), false, "humming", "electric" ); } } else { - Character &player_character = get_player_character(); for( const tripoint &zap : here.points_in_radius( pos(), 1 ) ) { - const bool player_sees = player_character.sees( zap ); const map_stack items = here.i_at( zap ); for( const auto &item : items ) { if( item.made_of( phase_id::LIQUID ) && item.flammable() ) { // start a fire! @@ -2135,14 +2126,11 @@ void monster::process_turn() if( t == ter_str_id( "t_gas_pump" ) || t == ter_str_id( "t_gas_pump_a" ) ) { if( one_in( 4 ) ) { explosion_handler::explosion( pos(), 40, 0.8, true ); - if( player_sees ) { - add_msg( m_warning, _( "The %s explodes in a fiery inferno!" ), here.tername( zap ) ); - } + add_msg_if_player_sees( zap, m_warning, _( "The %s explodes in a fiery inferno!" ), + here.tername( zap ) ); } else { - if( player_sees ) { - add_msg( m_warning, _( "Lightning from %1$s engulfs the %2$s!" ), name(), - here.tername( zap ) ); - } + add_msg_if_player_sees( zap, m_warning, _( "Lightning from %1$s engulfs the %2$s!" ), + name(), here.tername( zap ) ); here.add_field( zap, fd_fire, 1, 2_turns ); } } @@ -2154,6 +2142,7 @@ void monster::process_turn() "thunder_near" ); sounds::sound( pos(), 20, sounds::sound_t::combat, _( "vrrrRRRUUMMMMMMMM!" ), false, "explosion", "default" ); + Character &player_character = get_player_character(); if( player_character.sees( pos() ) ) { add_msg( m_bad, _( "Lightning strikes the %s!" ), name() ); add_msg( m_bad, _( "Your vision goes white!" ) ); @@ -2456,7 +2445,7 @@ void monster::process_effects() Character &player_character = get_player_character(); //If this monster has the ability to heal in combat, do it now. const int healed_amount = heal( type->regenerates ); - if( healed_amount > 0 && one_in( 2 ) && player_character.sees( *this ) ) { + if( healed_amount > 0 && one_in( 2 ) ) { std::string healing_format_string; if( healed_amount >= 50 ) { healing_format_string = _( "The %s is visibly regenerating!" ); @@ -2465,15 +2454,14 @@ void monster::process_effects() } else { healing_format_string = _( "The %s is healing slowly." ); } - add_msg( m_warning, healing_format_string, name() ); + add_msg_if_player_sees( *this, m_warning, healing_format_string, name() ); } if( type->regenerates_in_dark ) { const float light = get_map().ambient_light_at( pos() ); // Magic number 10000 was chosen so that a floodlight prevents regeneration in a range of 20 tiles - if( heal( static_cast( 50.0 * std::exp( - light * light / 10000 ) ) > 0 && one_in( 2 ) && - player_character.sees( *this ) ) ) { - add_msg( m_warning, _( "The %s uses the darkness to regenerate." ), name() ); + if( heal( static_cast( 50.0 * std::exp( - light * light / 10000 ) ) > 0 && one_in( 2 ) ) ) { + add_msg_if_player_sees( *this, m_warning, _( "The %s uses the darkness to regenerate." ), name() ); } } @@ -2500,9 +2488,7 @@ void monster::process_effects() // If this critter dies in sunlight, check & assess damage. if( has_flag( MF_SUNDEATH ) && g->is_in_sunlight( pos() ) ) { - if( player_character.sees( *this ) ) { - add_msg( m_good, _( "The %s burns horribly in the sunlight!" ), name() ); - } + add_msg_if_player_sees( *this, m_good, _( "The %s burns horribly in the sunlight!" ), name() ); apply_damage( nullptr, bodypart_id( "torso" ), 100 ); if( hp < 0 ) { hp = 0; @@ -2596,10 +2582,8 @@ bool monster::make_fungus() return false; } - if( get_player_character().sees( pos() ) ) { - add_msg( m_info, _( "The spores transform %1$s into a %2$s!" ), - old_name, name() ); - } + add_msg_if_player_sees( pos(), m_info, _( "The spores transform %1$s into a %2$s!" ), + old_name, name() ); return true; } @@ -2663,32 +2647,24 @@ units::volume monster::get_volume() const void monster::add_msg_if_npc( const std::string &msg ) const { - if( get_player_character().sees( *this ) ) { - add_msg( replace_with_npc_name( msg ) ); - } + add_msg_if_player_sees( *this, replace_with_npc_name( msg ) ); } void monster::add_msg_player_or_npc( const std::string &/*player_msg*/, const std::string &npc_msg ) const { - if( get_player_character().sees( *this ) ) { - add_msg( replace_with_npc_name( npc_msg ) ); - } + add_msg_if_player_sees( *this, replace_with_npc_name( npc_msg ) ); } void monster::add_msg_if_npc( const game_message_params ¶ms, const std::string &msg ) const { - if( get_player_character().sees( *this ) ) { - add_msg( params, replace_with_npc_name( msg ) ); - } + add_msg_if_player_sees( *this, params, replace_with_npc_name( msg ) ); } void monster::add_msg_player_or_npc( const game_message_params ¶ms, const std::string &/*player_msg*/, const std::string &npc_msg ) const { - if( get_player_character().sees( *this ) ) { - add_msg( params, replace_with_npc_name( npc_msg ) ); - } + add_msg_if_player_sees( *this, params, replace_with_npc_name( npc_msg ) ); } units::mass monster::get_carried_weight() diff --git a/src/monster.h b/src/monster.h index d414277c5adcb..3d9fe62319f15 100644 --- a/src/monster.h +++ b/src/monster.h @@ -26,7 +26,7 @@ #include "pldata.h" #include "point.h" #include "type_id.h" -#include "units.h" +#include "units_fwd.h" #include "value_ptr.h" class Character; @@ -346,10 +346,7 @@ class monster : public Creature /** Processes effects which may prevent the monster from moving (bear traps, crushed, etc.). * Returns false if movement is stopped. */ bool move_effects( bool attacking ) override; - /** Performs any monster-specific modifications to the arguments before passing to Creature::add_effect(). */ - void add_effect( const efftype_id &eff_id, const time_duration &dur, body_part bp = num_bp, - bool permanent = false, - int intensity = 0, bool force = false, bool deferred = false ) override; + /** Returns a std::string containing effects for descriptions */ std::string get_effect_status() const; diff --git a/src/morale.cpp b/src/morale.cpp index 79ab41c8866c8..73e41a4df8ed8 100644 --- a/src/morale.cpp +++ b/src/morale.cpp @@ -913,17 +913,18 @@ void player_morale::on_worn_item_washed( const item &it ) update_squeamish_penalty(); } -void player_morale::on_effect_int_change( const efftype_id &eid, int intensity, body_part bp ) +void player_morale::on_effect_int_change( const efftype_id &eid, int intensity, + const bodypart_id &bp ) { - const bodypart_id bo_id = convert_bp( bp ).id(); - if( eid == effect_took_prozac && bp == num_bp ) { + const bodypart_id bp_null( "bp_null" ); + if( eid == effect_took_prozac && bp == bp_null ) { set_prozac( intensity != 0 ); - } else if( eid == effect_took_prozac_bad && bp == num_bp ) { + } else if( eid == effect_took_prozac_bad && bp == bp_null ) { set_prozac_bad( intensity != 0 ); - } else if( eid == effect_cold && bp < num_bp ) { - body_parts[bo_id].cold = intensity; - } else if( eid == effect_hot && bp < num_bp ) { - body_parts[bo_id].hot = intensity; + } else if( eid == effect_cold && bp != bp_null ) { + body_parts[bp].cold = intensity; + } else if( eid == effect_hot && bp != bp_null ) { + body_parts[bp].hot = intensity; } } diff --git a/src/morale.h b/src/morale.h index 04c3b352f1105..c4dc4f3b0593d 100644 --- a/src/morale.h +++ b/src/morale.h @@ -68,7 +68,8 @@ class player_morale void on_item_takeoff( const item &it ); void on_worn_item_transform( const item &old_it, const item &new_it ); void on_worn_item_washed( const item &it ); - void on_effect_int_change( const efftype_id &eid, int intensity, body_part bp = num_bp ); + void on_effect_int_change( const efftype_id &eid, int intensity, + const bodypart_id &bp = bodypart_id( "bp_null" ) ); void store( JsonOut &jsout ) const; void load( const JsonObject &jsin ); diff --git a/src/move_mode.cpp b/src/move_mode.cpp index 62d2db7eda26f..d1bb924749226 100644 --- a/src/move_mode.cpp +++ b/src/move_mode.cpp @@ -27,14 +27,6 @@ static const std::map move_types { { "running", move_mode_type::RUNNING } }; -static const std::map activity_levels = { - { "NO_EXERCISE", NO_EXERCISE }, - { "LIGHT_EXERCISE", LIGHT_EXERCISE }, - { "MODERATE_EXERCISE", MODERATE_EXERCISE }, - { "ACTIVE_EXERCISE", ACTIVE_EXERCISE }, - { "EXTRA_EXERCISE", EXTRA_EXERCISE } -}; - void move_mode::load_move_mode( const JsonObject &jo, const std::string &src ) { move_mode_factory.load( jo, src ); diff --git a/src/mutation.cpp b/src/mutation.cpp index eeede3564ea70..8f601125d7551 100644 --- a/src/mutation.cpp +++ b/src/mutation.cpp @@ -152,6 +152,11 @@ void Character::set_mutation( const trait_id &trait ) mutation_effect( trait ); recalc_sight_limits(); calc_encumbrance(); + + // If the stamina is higher than the max (Languorous), set it back to max + if( get_stamina() > get_stamina_max() ) { + set_stamina( get_stamina_max() ); + } } void Character::unset_mutation( const trait_id &trait_ ) diff --git a/src/newcharacter.cpp b/src/newcharacter.cpp index aaf0744e92e6f..005b788ec60cd 100644 --- a/src/newcharacter.cpp +++ b/src/newcharacter.cpp @@ -30,6 +30,7 @@ #include "inventory.h" #include "json.h" #include "magic.h" +#include "magic_enchantment.h" #include "mapsharing.h" #include "martialarts.h" #include "monster.h" @@ -57,6 +58,7 @@ #include "type_id.h" #include "ui.h" #include "ui_manager.h" +#include "units_utility.h" #include "veh_type.h" #include "worldfactory.h" @@ -381,19 +383,19 @@ void avatar::add_profession_items() // TODO: debugmsg if food that isn't a seed is inedible if( it.has_flag( "no_auto_equip" ) ) { it.unset_flag( "no_auto_equip" ); - inv.push_back( it ); + inv->push_back( it ); } else if( it.has_flag( "auto_wield" ) ) { it.unset_flag( "auto_wield" ); if( !is_armed() ) { wield( it ); } else { - inv.push_back( it ); + inv->push_back( it ); } } else if( it.is_armor() ) { // TODO: debugmsg if wearing fails wear_item( it, false ); } else { - inv.push_back( it ); + inv->push_back( it ); } if( it.is_book() ) { items_identified.insert( it.typeId() ); @@ -597,14 +599,14 @@ bool avatar::create( character_type type, const std::string &tempname ) for( const trait_id &t : get_base_traits() ) { std::vector styles; for( const matype_id &s : t->initial_ma_styles ) { - if( !martial_arts_data.has_martialart( s ) ) { + if( !martial_arts_data->has_martialart( s ) ) { styles.push_back( s ); } } if( !styles.empty() ) { const matype_id ma_type = choose_ma_style( type, styles, *this ); - martial_arts_data.add_martialart( ma_type ); - martial_arts_data.set_style( ma_type ); + martial_arts_data->add_martialart( ma_type ); + martial_arts_data->set_style( ma_type ); } } @@ -2893,7 +2895,7 @@ std::vector Character::get_mutations( bool include_hidden ) const result.push_back( t.first ); } } - for( const trait_id &ench_trait : enchantment_cache.get_mutations() ) { + for( const trait_id &ench_trait : enchantment_cache->get_mutations() ) { if( include_hidden || ench_trait->player_display ) { bool found = false; for( const trait_id &exist : result ) { diff --git a/src/npc.cpp b/src/npc.cpp index d7f81e3ccdba3..223d33a584469 100644 --- a/src/npc.cpp +++ b/src/npc.cpp @@ -326,7 +326,7 @@ void npc::randomize( const npc_class_id &type ) } weapon = item( "null", 0 ); - inv.clear(); + inv->clear(); personality.aggression = rng( -10, 10 ); personality.bravery = rng( -3, 10 ); personality.collector = rng( -1, 10 ); @@ -447,10 +447,14 @@ void npc::randomize( const npc_class_id &type ) add_bionic( bl.first ); } } + // Add proficiencies + for( const proficiency_id &prof : type->_starting_proficiencies ) { + add_proficiency( prof ); + } // Add spells for magiclysm mod for( std::pair spell_pair : type->_starting_spells ) { - this->magic.learn_spell( spell_pair.first, *this, true ); - spell &sp = this->magic.get_spell( spell_pair.first ); + this->magic->learn_spell( spell_pair.first, *this, true ); + spell &sp = this->magic->get_spell( spell_pair.first ); while( sp.get_level() < spell_pair.second && !sp.is_max_level() ) { sp.gain_level(); } @@ -588,9 +592,9 @@ void starting_clothes( npc &who, const npc_class_id &type, bool male ) void starting_inv( npc &who, const npc_class_id &type ) { std::list res; - who.inv.clear(); + who.inv->clear(); if( item_group::group_is_defined( type->carry_override ) ) { - who.inv += item_group::items_from( type->carry_override ); + *who.inv += item_group::items_from( type->carry_override ); return; } @@ -643,7 +647,7 @@ void starting_inv( npc &who, const npc_class_id &type ) for( auto &it : res ) { it.set_owner( who ); } - who.inv += res; + *who.inv += res; } void npc::revert_after_activity() @@ -914,7 +918,7 @@ void npc::finish_read( item &book ) // NPCs don't need to identify the book or learn recipes yet. // NPCs don't read to other NPCs yet. const bool display_messages = my_fac->id == faction_id( "your_followers" ) && - get_player_character().sees( pos() ); + get_player_view().sees( pos() ); bool continuous = false; //whether to continue reading or not if( book_fun_for( book, *this ) != 0 ) { @@ -1033,7 +1037,7 @@ void npc::do_npc_read() } item &chosen = *loc.obtain( *ch ); if( can_read( chosen, fail_reasons ) ) { - if( get_player_character().sees( pos() ) ) { + if( get_player_view().sees( pos() ) ) { add_msg( m_info, _( "%s starts reading." ), disp_name() ); } start_read( chosen, pl ); @@ -1060,7 +1064,7 @@ bool npc::wear_if_wanted( const item &it, std::string &reason ) // TODO: Drop splints when healed if( it.has_flag( "SPLINT" ) ) { for( const bodypart_id &bp : get_all_body_parts( true ) ) { - if( is_limb_broken( bp ) && !has_effect( effect_mending, bp->token ) && + if( is_limb_broken( bp ) && !has_effect( effect_mending, bp.id() ) && it.covers( bp ) ) { reason = _( "Thanks, I'll wear that now." ); return !!wear_item( it, false ); @@ -1111,7 +1115,7 @@ bool npc::wear_if_wanted( const item &it, std::string &reason ) void npc::stow_item( item &it ) { - bool avatar_sees = get_player_character().sees( pos() ); + bool avatar_sees = get_player_view().sees( pos() ); if( wear_item( weapon, false ) ) { // Wearing the item was successful, remove weapon and post message. if( avatar_sees ) { @@ -1172,7 +1176,7 @@ bool npc::wield( item &it ) get_event_bus().send( getID(), weapon.typeId() ); - if( get_player_character().sees( pos() ) ) { + if( get_player_view().sees( pos() ) ) { add_msg_if_npc( m_info, _( " wields a %s." ), weapon.tname() ); } invalidate_range_cache(); @@ -1326,7 +1330,7 @@ void npc::mutiny() if( !my_fac || !is_player_ally() ) { return; } - const bool seen = get_player_character().sees( pos() ); + const bool seen = get_player_view().sees( pos() ); if( seen ) { add_msg( m_bad, _( "%s is tired of your incompetent leadership and abuse!" ), disp_name() ); } @@ -1461,19 +1465,30 @@ std::vector npc::skills_offered_to( const player &p ) const return ret; } +std::vector npc::proficiencies_offered_to( const Character &guy ) const +{ + std::vector ret; + for( const proficiency_id &known : known_proficiencies() ) { + if( !guy.has_proficiency( known ) ) { + ret.push_back( known ); + } + } + return ret; +} + std::vector npc::styles_offered_to( const player &p ) const { - return p.martial_arts_data.get_unknown_styles( martial_arts_data ); + return p.martial_arts_data->get_unknown_styles( *martial_arts_data ); } std::vector npc::spells_offered_to( player &p ) { std::vector teachable; - for( const spell_id &sp : magic.spells() ) { - const spell &teacher_spell = magic.get_spell( sp ); - if( p.magic.can_learn_spell( p, sp ) ) { - if( p.magic.knows_spell( sp ) ) { - const spell &student_spell = p.magic.get_spell( sp ); + for( const spell_id &sp : magic->spells() ) { + const spell &teacher_spell = magic->get_spell( sp ); + if( p.magic->can_learn_spell( p, sp ) ) { + if( p.magic->knows_spell( sp ) ) { + const spell &student_spell = p.magic->get_spell( sp ); if( student_spell.is_max_level() || student_spell.get_level() >= teacher_spell.get_level() ) { continue; @@ -1556,8 +1571,8 @@ void npc::say( const std::string &line, const sounds::sound_t spriority ) const } std::string sound = string_format( _( "%1$s saying \"%2$s\"" ), name, formatted_line ); - if( player_character.sees( *this ) && player_character.is_deaf() ) { - add_msg( m_warning, _( "%1$s says something but you can't hear it!" ), name ); + if( player_character.is_deaf() ) { + add_msg_if_player_sees( *this, m_warning, _( "%1$s says something but you can't hear it!" ), name ); } // Hallucinations don't make noise when they speak if( is_hallucination() ) { @@ -1731,8 +1746,8 @@ void npc::shop_restock() } has_new_items = true; - inv.clear(); - inv.push_back( ret ); + inv->clear(); + inv->push_back( ret ); } int npc::minimum_item_value() const @@ -1747,7 +1762,7 @@ void npc::update_worst_item_value() { worst_item_value = 99999; // TODO: Cache this - int inv_val = inv.worst_item_value( this ); + int inv_val = inv->worst_item_value( this ); if( inv_val < worst_item_value ) { worst_item_value = inv_val; } @@ -1938,7 +1953,7 @@ item &npc::get_healing_item( healing_options try_to_fix, bool first_best ) bool npc::has_painkiller() { - return inv.has_enough_painkiller( get_pain() ); + return inv->has_enough_painkiller( get_pain() ); } bool npc::took_painkiller() const @@ -2476,7 +2491,7 @@ void npc::reboot() ai_cache.searched_tiles.clear(); activity = player_activity(); clear_destination(); - add_effect( effect_npc_suspend, 24_hours, num_bp, true, 1 ); + add_effect( effect_npc_suspend, 24_hours, true, 1 ); } void npc::die( Creature *nkiller ) @@ -2519,22 +2534,18 @@ void npc::die( Creature *nkiller ) dead = true; Character::die( nkiller ); - Character &player_character = get_player_character(); if( is_hallucination() ) { - if( player_character.sees( *this ) ) { - add_msg( _( "%s disappears." ), name.c_str() ); - } + add_msg_if_player_sees( *this, _( "%s disappears." ), name.c_str() ); return; } - if( player_character.sees( *this ) ) { - add_msg( _( "%s dies!" ), name ); - } + add_msg_if_player_sees( *this, _( "%s dies!" ), name ); if( Character *ch = dynamic_cast( killer ) ) { get_event_bus().send( ch->getID(), getID(), get_name() ); } + Character &player_character = get_player_character(); if( killer == &player_character && ( !guaranteed_hostile() || hit_by_player ) ) { bool cannibal = player_character.has_trait( trait_CANNIBAL ); bool psycho = player_character.has_trait( trait_PSYCHOPATH ); @@ -2646,9 +2657,7 @@ void npc::add_msg_if_npc( const std::string &msg ) const void npc::add_msg_player_or_npc( const std::string &/*player_msg*/, const std::string &npc_msg ) const { - if( get_player_character().sees( *this ) ) { - add_msg( replace_with_npc_name( npc_msg ) ); - } + add_msg_if_player_sees( *this, replace_with_npc_name( npc_msg ) ); } void npc::add_msg_if_npc( const game_message_params ¶ms, const std::string &msg ) const @@ -2660,7 +2669,7 @@ void npc::add_msg_player_or_npc( const game_message_params ¶ms, const std::string &/*player_msg*/, const std::string &npc_msg ) const { - if( get_player_character().sees( *this ) ) { + if( get_player_view().sees( *this ) ) { add_msg( params, replace_with_npc_name( npc_msg ) ); } } @@ -2748,7 +2757,7 @@ void npc::on_load() map &here = get_map(); // for spawned npcs if( here.has_flag( "UNSTABLE", pos() ) ) { - add_effect( effect_bouldering, 1_turns, num_bp, true ); + add_effect( effect_bouldering, 1_turns, true ); } else if( has_effect( effect_bouldering ) ) { remove_effect( effect_bouldering ); } @@ -2809,9 +2818,9 @@ bool npc::dispose_item( item_location &&obj, const std::string & ) item_handling_cost( *obj ), [this, &obj] { moves -= item_handling_cost( *obj ); - inv.add_item_keep_invlet( *obj ); + inv->add_item_keep_invlet( *obj ); obj.remove_item(); - inv.unsort(); + inv->unsort(); } } ); } @@ -2837,7 +2846,8 @@ void npc::process_turn() player::process_turn(); // NPCs shouldn't be using stamina, but if they have, set it back to max - if( calendar::once_every( 1_minutes ) && get_stamina() < get_stamina_max() ) { + // If the stamina is higher than the max (Languorous), set it back to max + if( calendar::once_every( 1_minutes ) && get_stamina() != get_stamina_max() ) { set_stamina( get_stamina_max() ); } @@ -3184,14 +3194,14 @@ void npc::set_attitude( npc_attitude new_attitude ) new_attitude = NPCATT_FLEE_TEMP; } if( new_attitude == NPCATT_FLEE_TEMP && !has_effect( effect_npc_flee_player ) ) { - add_effect( effect_npc_flee_player, 24_hours, num_bp ); + add_effect( effect_npc_flee_player, 24_hours ); } add_msg( m_debug, "%s changes attitude from %s to %s", name, npc_attitude_id( attitude ), npc_attitude_id( new_attitude ) ); attitude_group new_group = get_attitude_group( new_attitude ); attitude_group old_group = get_attitude_group( attitude ); - if( new_group != old_group && !is_fake() && get_player_character().sees( *this ) ) { + if( new_group != old_group && !is_fake() && get_player_view().sees( *this ) ) { switch( new_group ) { case attitude_group::hostile: add_msg_if_npc( m_bad, _( " gets angry!" ) ); diff --git a/src/npc.h b/src/npc.h index ef97c22437ec5..122a56de28030 100644 --- a/src/npc.h +++ b/src/npc.h @@ -41,7 +41,7 @@ #include "string_id.h" #include "translations.h" #include "type_id.h" -#include "units.h" +#include "units_fwd.h" class JsonIn; class JsonObject; @@ -836,6 +836,10 @@ class npc : public player * words: skills this NPC could teach the player. */ std::vector skills_offered_to( const player &p ) const; + /** + * Proficiencies we know that the character doesn't + */ + std::vector < proficiency_id> proficiencies_offered_to( const Character &guy ) const; /** * Martial art styles that we known, but the player p doesn't. */ diff --git a/src/npc_class.cpp b/src/npc_class.cpp index 69b53cdcbf6d7..1180c2f7841d4 100644 --- a/src/npc_class.cpp +++ b/src/npc_class.cpp @@ -256,6 +256,8 @@ void npc_class::load( const JsonObject &jo, const std::string & ) _starting_spells.emplace( sp, level ); } } + + optional( jo, was_loaded, "proficiencies", _starting_proficiencies ); /* Mutation rounds can be specified as follows: * "mutation_rounds": { * "ANY" : { "constant": 1 }, diff --git a/src/npc_class.h b/src/npc_class.h index 1584d75a8c1c0..486292213c9d0 100644 --- a/src/npc_class.h +++ b/src/npc_class.h @@ -80,6 +80,7 @@ class npc_class // the int is what level the spell starts at std::map _starting_spells; std::map bionic_list; + std::vector _starting_proficiencies; npc_class(); std::string get_name() const; diff --git a/src/npcmove.cpp b/src/npcmove.cpp index a7c31a45d1b2f..2d1a7fc09e342 100644 --- a/src/npcmove.cpp +++ b/src/npcmove.cpp @@ -1039,9 +1039,9 @@ void npc::execute_action( npc_action action ) move_pause(); if( !has_effect( effect_lying_down ) ) { activate_bionic_by_id( bio_soporific ); - add_effect( effect_lying_down, 30_minutes, num_bp, false, 1 ); - if( player_character.sees( *this ) && !player_character.in_sleep_state() ) { - add_msg( _( "%s lies down to sleep." ), name ); + add_effect( effect_lying_down, 30_minutes, false, 1 ); + if( !player_character.in_sleep_state() ) { + add_msg_if_player_sees( *this, _( "%s lies down to sleep." ), name ); } } } else { @@ -1768,15 +1768,15 @@ healing_options npc::patient_assessment( const Character &c ) for( const std::pair &elem : c.get_body() ) { - if( c.has_effect( effect_bleed, elem.first->token ) ) { + if( c.has_effect( effect_bleed, elem.first ) ) { try_to_fix.bleed = true; } - if( c.has_effect( effect_bite, elem.first->token ) ) { + if( c.has_effect( effect_bite, elem.first ) ) { try_to_fix.bite = true; } - if( c.has_effect( effect_infected, elem.first->token ) ) { + if( c.has_effect( effect_infected, elem.first ) ) { try_to_fix.infect = true; } int part_threshold = 75; @@ -1789,10 +1789,10 @@ healing_options npc::patient_assessment( const Character &c ) part_threshold = part_threshold * elem.second.get_hp_max() / 100; if( elem.second.get_hp_cur() <= part_threshold ) { - if( !c.has_effect( effect_bandaged, elem.first->token ) ) { + if( !c.has_effect( effect_bandaged, elem.first ) ) { try_to_fix.bandage = true; } - if( !c.has_effect( effect_disinfected, elem.first->token ) ) { + if( !c.has_effect( effect_disinfected, elem.first ) ) { try_to_fix.disinfect = true; } } @@ -2435,13 +2435,13 @@ void npc::move_to( const tripoint &pt, bool no_bashing, std::set *nomo } } if( here.has_flag( "UNSTABLE", pos() ) ) { - add_effect( effect_bouldering, 1_turns, num_bp, true ); + add_effect( effect_bouldering, 1_turns, true ); } else if( has_effect( effect_bouldering ) ) { remove_effect( effect_bouldering ); } if( here.has_flag_ter_or_furn( TFLAG_NO_SIGHT, pos() ) ) { - add_effect( effect_no_sight, 1_turns, num_bp, true ); + add_effect( effect_no_sight, 1_turns, true ); } else if( has_effect( effect_no_sight ) ) { remove_effect( effect_no_sight ); } @@ -2841,10 +2841,10 @@ void npc::find_item() npc *npc_to_add = npc_to_get.get(); followers.push_back( npc_to_add ); } - Character &player_character = get_player_character(); + viewer &player_view = get_player_view(); for( auto &elem : followers ) { - if( !it.is_owned_by( *this, true ) && ( player_character.sees( this->pos() ) || - player_character.sees( wanted_item_pos ) || + if( !it.is_owned_by( *this, true ) && ( player_view.sees( this->pos() ) || + player_view.sees( wanted_item_pos ) || elem->sees( this->pos() ) || elem->sees( wanted_item_pos ) ) ) { return; } @@ -3045,9 +3045,9 @@ void npc::pick_up_item() return; } } - Character &player_character = get_player_character(); + viewer &player_view = get_player_view(); // Describe the pickup to the player - bool u_see = player_character.sees( *this ) || player_character.sees( wanted_item_pos ); + bool u_see = player_view.sees( *this ) || player_view.sees( wanted_item_pos ); if( u_see ) { if( picked_up.size() == 1 ) { add_msg( _( "%1$s picks up a %2$s." ), name, picked_up.front().tname() ); @@ -3150,7 +3150,7 @@ void npc::drop_items( const units::mass &drop_weight, const units::volume &drop_ add_msg( m_debug, "%s is dropping items-%3.2f kg, %3.2f L (%d items, wgt %3.2f/%3.2f kg, " "vol %3.2f/%3.2f L)", - name, units::to_kilogram( drop_weight ), units::to_liter( drop_volume ), inv.size(), + name, units::to_kilogram( drop_weight ), units::to_liter( drop_volume ), inv->size(), units::to_kilogram( weight_carried() ), units::to_kilogram( weight_capacity() ), units::to_liter( volume_carried() ), units::to_liter( volume_capacity() ) ); @@ -3159,7 +3159,7 @@ void npc::drop_items( const units::mass &drop_weight, const units::volume &drop_ std::vector rWgt, rVol; // Weight/Volume to value ratios // First fill our ratio vectors, so we know which things to drop first - invslice slice = inv.slice(); + invslice slice = inv->slice(); for( size_t i = 0; i < slice.size(); i++ ) { item &it = slice[i]->front(); double wgt_ratio = 0.0; @@ -3243,13 +3243,12 @@ void npc::drop_items( const units::mass &drop_weight, const units::volume &drop_ } } // Finally, describe the action if u can see it - if( get_player_character().sees( *this ) ) { - if( num_items_dropped >= 3 ) { - add_msg( ngettext( "%s drops %d item.", "%s drops %d items.", num_items_dropped ), name, - num_items_dropped ); - } else { - add_msg( _( "%1$s drops a %2$s." ), name, item_name ); - } + if( num_items_dropped >= 3 ) { + add_msg_if_player_sees( *this, ngettext( "%s drops %d item.", "%s drops %d items.", + num_items_dropped ), name, + num_items_dropped ); + } else { + add_msg_if_player_sees( *this, _( "%1$s drops a %2$s." ), name, item_name ); } update_worst_item_value(); } @@ -3489,9 +3488,7 @@ bool npc::scan_new_items() static void npc_throw( npc &np, item &it, const tripoint &pos ) { - if( get_player_character().sees( np ) ) { - add_msg( _( "%1$s throws a %2$s." ), np.name, it.tname() ); - } + add_msg_if_player_sees( np, _( "%1$s throws a %2$s." ), np.name, it.tname() ); int stack_size = -1; if( it.count_by_charges() ) { @@ -3669,9 +3666,9 @@ void npc::heal_player( player &patient ) return; } - Character &player_character = get_player_character(); + viewer &player_view = get_player_view(); // Close enough to heal! - bool u_see = player_character.sees( *this ) || player_character.sees( patient ); + bool u_see = player_view.sees( *this ) || player_view.sees( patient ); if( u_see ) { add_msg( _( "%1$s heals %2$s." ), disp_name(), patient.disp_name() ); } @@ -3692,10 +3689,9 @@ void npc::heal_player( player &patient ) void npc:: pretend_heal( player &patient, item used ) { - if( get_player_character().sees( *this ) ) { - add_msg( _( "%1$s heals %2$s." ), disp_name(), - patient.disp_name() ); // you can tell that it's not real by looking at your HP though - } + // you can tell that it's not real by looking at your HP though + add_msg_if_player_sees( *this, _( "%1$s heals %2$s." ), disp_name(), + patient.disp_name() ); consume_charges( used, 1 ); // empty hallucination's inventory to avoid spammming moves -= 100; // consumes moves to avoid infinite loop } @@ -3737,9 +3733,7 @@ void npc::heal_self() return; } - if( get_player_character().sees( *this ) ) { - add_msg( _( "%s applies a %s" ), disp_name(), used.tname() ); - } + add_msg_if_player_sees( *this, _( "%s applies a %s" ), disp_name(), used.tname() ); warn_about( "heal_self", 1_turns ); int charges_used = used.type->invoke( *this, used, pos(), "heal" ); @@ -3751,15 +3745,13 @@ void npc::heal_self() void npc::use_painkiller() { // First, find the best painkiller for our pain level - item *it = inv.most_appropriate_painkiller( get_pain() ); + item *it = inv->most_appropriate_painkiller( get_pain() ); if( it->is_null() ) { debugmsg( "NPC tried to use painkillers, but has none!" ); move_pause(); } else { - if( get_player_character().sees( *this ) ) { - add_msg( _( "%1$s takes some %2$s." ), disp_name(), it->tname() ); - } + add_msg_if_player_sees( *this, _( "%1$s takes some %2$s." ), disp_name(), it->tname() ); item_location loc = item_location( *this, it ); const time_duration &consume_time = get_consume_time( *loc ); moves -= to_moves( consume_time ); @@ -4082,11 +4074,11 @@ void npc::reach_omt_destination() if( is_player_ally() ) { Character &player_character = get_player_character(); talk_function::assign_guard( *this ); - if( rl_dist( player_character.pos(), pos() ) > SEEX * 2 || !player_character.sees( pos() ) ) { + if( rl_dist( player_character.pos(), pos() ) > SEEX * 2 ) { if( player_character.has_item_with_flag( "TWO_WAY_RADIO", true ) && has_item_with_flag( "TWO_WAY_RADIO", true ) ) { - add_msg( m_info, _( "From your two-way radio you hear %s reporting in, " - "'I've arrived, boss!'" ), disp_name() ); + add_msg_if_player_sees( pos(), m_info, _( "From your two-way radio you hear %s reporting in, " + "'I've arrived, boss!'" ), disp_name() ); } } } else { @@ -4383,11 +4375,11 @@ Creature *npc::current_ally() } // Maybe TODO: Move to Character method and use map methods -static body_part bp_affected( npc &who, const efftype_id &effect_type ) +static bodypart_id bp_affected( npc &who, const efftype_id &effect_type ) { - body_part ret = num_bp; + bodypart_id ret; int highest_intensity = INT_MIN; - for( const body_part bp : all_body_parts ) { + for( const bodypart_id &bp : who.get_all_body_parts() ) { const auto &eff = who.get_effect( effect_type, bp ); if( !eff.is_null() && eff.get_intensity() > highest_intensity ) { ret = bp; @@ -4506,15 +4498,15 @@ bool npc::complain() static const std::string hunger_string = "hunger"; static const std::string thirst_string = "thirst"; - if( !is_player_ally() || !get_player_character().sees( *this ) ) { + if( !is_player_ally() || !get_player_view().sees( *this ) ) { return false; } // When infected, complain every (4-intensity) hours // At intensity 3, ignore player wanting us to shut up if( has_effect( effect_infected ) ) { - const bodypart_id &bp = convert_bp( bp_affected( *this, effect_infected ) ).id(); - const auto &eff = get_effect( effect_infected, bp->token ); + const bodypart_id &bp = bp_affected( *this, effect_infected ); + const auto &eff = get_effect( effect_infected, bp ); int intensity = eff.get_intensity(); const std::string speech = string_format( _( "My %s wound is infected…" ), body_part_name( bp ) ); @@ -4527,7 +4519,7 @@ bool npc::complain() // When bitten, complain every hour, but respect restrictions if( has_effect( effect_bite ) ) { - const bodypart_id &bp = convert_bp( bp_affected( *this, effect_bite ) ); + const bodypart_id &bp = bp_affected( *this, effect_bite ); const std::string speech = string_format( _( "The bite wound on my %s looks bad." ), body_part_name( bp ) ); if( complain_about( bite_string, 1_hours, speech ) ) { @@ -4570,10 +4562,10 @@ bool npc::complain() //Bleeding every 5 minutes if( has_effect( effect_bleed ) ) { - const bodypart_id &bp = convert_bp( bp_affected( *this, effect_bleed ) ); + const bodypart_id &bp = bp_affected( *this, effect_bleed ); std::string speech; time_duration often; - if( get_effect( effect_bleed, bp->token ).get_intensity() < 10 ) { + if( get_effect( effect_bleed, bp ).get_intensity() < 10 ) { speech = string_format( _( "My %s is bleeding!" ), body_part_name( bp ) ); often = 5_minutes; } else { @@ -4623,7 +4615,7 @@ void npc::do_reload( const item &it ) moves -= reload_time; recoil = MAX_RECOIL; - if( get_player_character().sees( *this ) ) { + if( get_player_view().sees( *this ) ) { add_msg( _( "%1$s reloads their %2$s." ), name, it.tname() ); sfx::play_variant_sound( "reload", it.typeId().str(), sfx::get_heard_volume( pos() ), sfx::get_heard_angle( pos() ) ); diff --git a/src/npctalk.cpp b/src/npctalk.cpp index 4964dbb5a15e2..ee92264645eea 100644 --- a/src/npctalk.cpp +++ b/src/npctalk.cpp @@ -141,6 +141,20 @@ int calc_skill_training_cost( const npc &p, const skill_id &skill ) return 1000 * ( 1 + skill_level ) * ( 1 + skill_level ); } +time_duration calc_proficiency_training_time( const npc &, const proficiency_id &proficiency ) +{ + return std::min( 15_minutes, get_player_character().proficiency_training_needed( proficiency ) ); +} + +int calc_proficiency_training_cost( const npc &p, const proficiency_id &proficiency ) +{ + if( p.is_player_ally() ) { + return 0; + } + + return to_seconds( calc_proficiency_training_time( p, proficiency ) ); +} + // TODO: all styles cost the same and take the same time to train, // maybe add values to the ma_style class to makes this variable // TODO: maybe move this function into the ma_style class? Or into the NPC class? @@ -968,6 +982,14 @@ talk_response &dialogue::add_response( const std::string &text, const std::strin return result; } +talk_response &dialogue::add_response( const std::string &text, const std::string &r, + const proficiency_id &proficiency, const bool first ) +{ + talk_response &result = add_response( text, r, first ); + result.proficiency = proficiency; + return result; +} + talk_response &dialogue::add_response( const std::string &text, const std::string &r, const spell_id &sp, const bool first ) { @@ -1053,7 +1075,8 @@ void dialogue::gen_responses( const talk_topic &the_topic ) const std::vector &styles = beta->styles_offered_to( *alpha ); const std::vector &trainable = beta->skills_offered_to( *alpha ); const std::vector &teachable = beta->spells_offered_to( *alpha ); - if( trainable.empty() && styles.empty() && teachable.empty() ) { + const std::vector &proficiencies = beta->proficiencies_offered_to( *alpha ); + if( trainable.empty() && styles.empty() && teachable.empty() && proficiencies.empty() ) { add_response_none( _( "Oh, okay." ) ); return; } @@ -1075,6 +1098,12 @@ void dialogue::gen_responses( const talk_topic &the_topic ) add_response( text, "TALK_TRAIN_START", trained ); } } + for( const proficiency_id &trained : proficiencies ) { + const std::string &text = beta->proficiency_training_text( *alpha, trained ); + if( !text.empty() ) { + add_response( text, "TALK_TRAIN_START", trained ); + } + } add_response_none( _( "Eh, never mind." ) ); } else if( the_topic.id == "TALK_HOW_MUCH_FURTHER" ) { add_response_none( _( "Okay, thanks." ) ); @@ -1501,7 +1530,8 @@ talk_topic dialogue::opt( dialogue_window &d_win, const std::string &npc_name, // We can't set both skill and style or training will bug out // TODO: Allow setting both skill and style - beta->store_chosen_training( chosen.skill, chosen.style, chosen.dialogue_spell ); + beta->store_chosen_training( chosen.skill, chosen.style, chosen.dialogue_spell, + chosen.proficiency ); const bool success = chosen.trial.roll( *this ); const auto &effects = success ? chosen.success : chosen.failure; return effects.apply( *this ); @@ -2350,8 +2380,13 @@ talk_response::talk_response() return true; }; mission_selected = nullptr; - skill = skill_id::NULL_ID(); - style = matype_id::NULL_ID(); + // Why aren't these null ids? Well, it turns out most responses give + // empty ids, so things like the training code check for these empty ids + // and when it's given a null id, it breaks + // FIXME: Use null ids + skill = skill_id(); + style = matype_id(); + proficiency = proficiency_id(); dialogue_spell = spell_id(); } diff --git a/src/npctalk.h b/src/npctalk.h index 9dd6407392794..a6a69a00b53c2 100644 --- a/src/npctalk.h +++ b/src/npctalk.h @@ -93,6 +93,8 @@ void clear_overrides( npc &p ); time_duration calc_skill_training_time( const npc &p, const skill_id &skill ); int calc_skill_training_cost( const npc &p, const skill_id &skill ); +time_duration calc_proficiency_training_time( const npc &, const proficiency_id &proficiency ); +int calc_proficiency_training_cost( const npc &p, const proficiency_id &proficiency ); time_duration calc_ma_style_training_time( const npc &, const matype_id & /* id */ ); int calc_ma_style_training_cost( const npc &p, const matype_id & /* id */ ); #endif // CATA_SRC_NPCTALK_H diff --git a/src/npctalk_funcs.cpp b/src/npctalk_funcs.cpp index eb8a7bfd5cea0..904b7d86f8787 100644 --- a/src/npctalk_funcs.cpp +++ b/src/npctalk_funcs.cpp @@ -201,7 +201,7 @@ void spawn_animal( npc &p, const mtype_id &mon ) { if( monster *const mon_ptr = g->place_critter_around( mon, p.pos(), 1 ) ) { mon_ptr->friendly = -1; - mon_ptr->add_effect( effect_pet, 1_turns, num_bp, true ); + mon_ptr->add_effect( effect_pet, 1_turns, true ); } else { // TODO: handle this gracefully (return the money, proper in-character message from npc) add_msg( m_debug, "No space to spawn purchased pet" ); @@ -564,14 +564,14 @@ void talk_function::give_aid( npc &p ) Character &player_character = get_player_character(); for( const bodypart_id &bp : player_character.get_all_body_parts( true ) ) { player_character.heal( bp, 5 * rng( 2, 5 ) ); - if( player_character.has_effect( effect_bite, bp->token ) ) { - player_character.remove_effect( effect_bite, bp->token ); + if( player_character.has_effect( effect_bite, bp.id() ) ) { + player_character.remove_effect( effect_bite, bp ); } - if( player_character.has_effect( effect_bleed, bp->token ) ) { - player_character.remove_effect( effect_bleed, bp->token ); + if( player_character.has_effect( effect_bleed, bp.id() ) ) { + player_character.remove_effect( effect_bleed, bp ); } - if( player_character.has_effect( effect_infected, bp->token ) ) { - player_character.remove_effect( effect_infected, bp->token ); + if( player_character.has_effect( effect_infected, bp.id() ) ) { + player_character.remove_effect( effect_infected, bp ); } } const int moves = to_moves( 100_minutes ); @@ -587,14 +587,14 @@ void talk_function::give_all_aid( npc &p ) if( guy.is_walking_with() && rl_dist( guy.pos(), get_player_character().pos() ) < PICKUP_RANGE ) { for( const bodypart_id &bp : guy.get_all_body_parts( true ) ) { guy.heal( bp, 5 * rng( 2, 5 ) ); - if( guy.has_effect( effect_bite, bp->token ) ) { - guy.remove_effect( effect_bite, bp->token ); + if( guy.has_effect( effect_bite, bp.id() ) ) { + guy.remove_effect( effect_bite, bp ); } - if( guy.has_effect( effect_bleed, bp->token ) ) { - guy.remove_effect( effect_bleed, bp->token ); + if( guy.has_effect( effect_bleed, bp.id() ) ) { + guy.remove_effect( effect_bleed, bp ); } - if( guy.has_effect( effect_infected, bp->token ) ) { - guy.remove_effect( effect_infected, bp->token ); + if( guy.has_effect( effect_infected, bp.id() ) ) { + guy.remove_effect( effect_infected, bp ); } } } @@ -921,6 +921,7 @@ void talk_function::start_training( npc &p ) const skill_id &skill = p.chatbin.skill; const matype_id &style = p.chatbin.style; const spell_id &sp_id = p.chatbin.dialogue_spell; + const proficiency_id &proficiency = p.chatbin.proficiency; int expert_multiplier = 1; Character &you = get_player_character(); if( skill != skill_id() && @@ -929,19 +930,19 @@ void talk_function::start_training( npc &p ) time = calc_skill_training_time( p, skill ); name = skill.str(); } else if( p.chatbin.style != matype_id() && - !you.martial_arts_data.has_martialart( style ) ) { + !you.martial_arts_data->has_martialart( style ) ) { cost = calc_ma_style_training_cost( p, style ); time = calc_ma_style_training_time( p, style ); name = p.chatbin.style.str(); // already checked if can learn this spell in npctalk.cpp } else if( p.chatbin.dialogue_spell != spell_id() ) { - const spell &temp_spell = p.magic.get_spell( sp_id ); - const bool knows = you.magic.knows_spell( sp_id ); + const spell &temp_spell = p.magic->get_spell( sp_id ); + const bool knows = you.magic->knows_spell( sp_id ); cost = p.calc_spell_training_cost( knows, temp_spell.get_difficulty(), temp_spell.get_level() ); name = temp_spell.id().str(); expert_multiplier = knows ? temp_spell.get_level() - - you.magic.get_spell( sp_id ).get_level() : 1; + you.magic->get_spell( sp_id ).get_level() : 1; // quicker to learn with instruction as opposed to books. // if this is a known spell, then there is a set time to gain some exp. // if player doesn't know this spell, then the NPC will teach all of it @@ -951,9 +952,14 @@ void talk_function::start_training( npc &p ) if( knows ) { time = 1_hours; } else { - const int time_int = you.magic.time_to_learn_spell( you, sp_id ) / 50; + const int time_int = you.magic->time_to_learn_spell( you, sp_id ) / 50; time = time_duration::from_seconds( clamp( time_int, 7200, 21600 ) ); } + + } else if( proficiency != proficiency_id() ) { + name = proficiency.str(); + cost = calc_proficiency_training_cost( p, proficiency ); + time = calc_proficiency_training_time( p, proficiency ); } else { debugmsg( "start_training with no valid skill or style set" ); return; @@ -980,7 +986,7 @@ npc *pick_follower() std::vector locations; for( npc &guy : g->all_npcs() ) { - if( guy.is_player_ally() && get_player_character().sees( guy ) ) { + if( guy.is_player_ally() && get_player_view().sees( guy ) ) { followers.push_back( &guy ); locations.push_back( guy.pos() ); } diff --git a/src/npctrade.cpp b/src/npctrade.cpp index bb8fbc815ad6e..55741c00f98e9 100644 --- a/src/npctrade.cpp +++ b/src/npctrade.cpp @@ -35,6 +35,7 @@ #include "type_id.h" #include "ui_manager.h" #include "units.h" +#include "units_utility.h" #include "vehicle_selector.h" #include "visitable.h" diff --git a/src/options.cpp b/src/options.cpp index 346a647fb8788..7ed526ae58a7a 100644 --- a/src/options.cpp +++ b/src/options.cpp @@ -936,39 +936,41 @@ static std::vector build_resource_list( return resource_names; } -std::vector options_manager::load_tilesets_from( - const std::string &path ) -{ - // Use local map as build_resource_list will clear the first parameter - std::map local_tilesets; - auto tileset_names = build_resource_list( local_tilesets, "tileset", path, - PATH_INFO::tileset_conf() ); - - // Copy found tilesets - TILESETS.insert( local_tilesets.begin(), local_tilesets.end() ); - - return tileset_names; +void options_manager::search_resource( + std::map &storage, std::vector &option_list, + const std::vector &search_paths, const std::string &resource_name, + const std::string &resource_filename ) +{ + // Clear the result containers. + storage.clear(); + option_list.clear(); + + // Loop through each search path and add its resources. + for( const std::string &search_path : search_paths ) { + // Get the resource list from the search path. + std::map resources; + std::vector resource_names = build_resource_list( resources, resource_name, + search_path, resource_filename ); + + // Add any new resources from this path to the result containers. + // First, add to the resource mapping. + storage.insert( resources.begin(), resources.end() ); + // Next, add to the option list. + for( const id_and_option &name : resource_names ) { + // Only add if not a duplicate. + if( std::find( option_list.begin(), option_list.end(), name ) == option_list.end() ) { + option_list.emplace_back( name ); + } + } + } } std::vector options_manager::build_tilesets_list() { - // Clear tilesets - TILESETS.clear(); std::vector result; - // Load from data directory - std::vector data_tilesets = load_tilesets_from( - PATH_INFO::gfxdir() ); - result.insert( result.end(), data_tilesets.begin(), data_tilesets.end() ); - - // Load from user directory - std::vector user_tilesets = load_tilesets_from( - PATH_INFO::user_gfx() ); - for( const options_manager::id_and_option &id : user_tilesets ) { - if( std::find( result.begin(), result.end(), id ) == result.end() ) { - result.emplace_back( id ); - } - } + search_resource( TILESETS, result, { PATH_INFO::user_gfx(), PATH_INFO::gfxdir() }, "tileset", + PATH_INFO::tileset_conf() ); // Default values if( result.empty() ) { @@ -978,34 +980,12 @@ std::vector options_manager::build_tilesets_list return result; } -std::vector options_manager::load_soundpack_from( - const std::string &path ) -{ - // build_resource_list will clear &resource_option - first param - std::map local_soundpacks; - auto soundpack_names = build_resource_list( local_soundpacks, "soundpack", path, - PATH_INFO::soundpack_conf() ); - - // Copy over found soundpacks - SOUNDPACKS.insert( local_soundpacks.begin(), local_soundpacks.end() ); - - // Return found soundpack names for further processing - return soundpack_names; -} - std::vector options_manager::build_soundpacks_list() { - // Clear soundpacks before loading - SOUNDPACKS.clear(); std::vector result; - // Search data directory for sound packs - auto data_soundpacks = load_soundpack_from( PATH_INFO::data_sound() ); - result.insert( result.end(), data_soundpacks.begin(), data_soundpacks.end() ); - - // Search user directory for sound packs - auto user_soundpacks = load_soundpack_from( PATH_INFO::user_sound() ); - result.insert( result.end(), user_soundpacks.begin(), user_soundpacks.end() ); + search_resource( SOUNDPACKS, result, { PATH_INFO::user_sound(), PATH_INFO::data_sound() }, + "soundpack", PATH_INFO::soundpack_conf() ); // Select default built-in sound pack if( result.empty() ) { diff --git a/src/options.h b/src/options.h index b2a74849c35e6..3d1df56bac45a 100644 --- a/src/options.h +++ b/src/options.h @@ -32,12 +32,20 @@ class options_manager }; static std::vector get_lang_options(); private: + /** + * Search for resources. + * @p storage is the resource map (e.g. SOUNDPACKS) to fill from resources found. It will be cleared. + * @p option_list is the option list corresponding to the resources found. It will be cleared. + * @p search_paths are the paths to search for resources in, in order of priority. + * @p resource_name is the type of resource being searched for (e.g. "sound"). + * @p resource_filename is the name of the config file for the type of resource (e.g. path_info::soundpack_conf()). + */ + static void search_resource( + std::map &storage, std::vector &option_list, + const std::vector &search_paths, const std::string &resource_name, + const std::string &resource_filename ); static std::vector build_tilesets_list(); static std::vector build_soundpacks_list(); - static std::vector load_tilesets_from( - const std::string &path ); - static std::vector load_soundpack_from( - const std::string &path ); static std::unordered_set get_langs_with_translation_files(); bool load_legacy(); diff --git a/src/output.cpp b/src/output.cpp index d75dd1a0c9bcc..b73cc1e10479a 100644 --- a/src/output.cpp +++ b/src/output.cpp @@ -34,6 +34,7 @@ #include "string_input_popup.h" #include "ui_manager.h" #include "units.h" +#include "units_utility.h" #include "point.h" #include "wcwidth.h" diff --git a/src/output.h b/src/output.h index 74f8082135816..afdedb29e73b8 100644 --- a/src/output.h +++ b/src/output.h @@ -24,7 +24,7 @@ #include "point.h" #include "string_formatter.h" #include "translations.h" -#include "units.h" +#include "units_fwd.h" struct input_event; diff --git a/src/overmap.cpp b/src/overmap.cpp index 80fae3c6e719f..9c3cf1b28d879 100644 --- a/src/overmap.cpp +++ b/src/overmap.cpp @@ -1806,10 +1806,14 @@ void overmap::generate_bridgeheads( const std::vector &bridge_poin const oter_id oter_ground_south = ter( tripoint_om_omt( bp, 0 ) + tripoint_south ); const oter_id oter_ground_east = ter( tripoint_om_omt( bp, 0 ) + tripoint_east ); const oter_id oter_ground_west = ter( tripoint_om_omt( bp, 0 ) + tripoint_west ); - const bool is_bridge_north = is_ot_match( "bridge", oter_ground_north, ot_match_type::type ); - const bool is_bridge_south = is_ot_match( "bridge", oter_ground_south, ot_match_type::type ); - const bool is_bridge_east = is_ot_match( "bridge", oter_ground_east, ot_match_type::type ); - const bool is_bridge_west = is_ot_match( "bridge", oter_ground_west, ot_match_type::type ); + const bool is_bridge_north = is_ot_match( "bridge", oter_ground_north, ot_match_type::type ) + && ( oter_get_rotation( oter_ground_north ) % 2 == 0 ); + const bool is_bridge_south = is_ot_match( "bridge", oter_ground_south, ot_match_type::type ) + && ( oter_get_rotation( oter_ground_south ) % 2 == 0 ); + const bool is_bridge_east = is_ot_match( "bridge", oter_ground_east, ot_match_type::type ) + && ( oter_get_rotation( oter_ground_east ) % 2 == 1 ); + const bool is_bridge_west = is_ot_match( "bridge", oter_ground_west, ot_match_type::type ) + && ( oter_get_rotation( oter_ground_west ) % 2 == 1 ); if( is_bridge_north ^ is_bridge_south || is_bridge_east ^ is_bridge_west ) { std::string ramp_facing; diff --git a/src/panels.cpp b/src/panels.cpp index 99310672a9c8b..4f3e91c67a541 100644 --- a/src/panels.cpp +++ b/src/panels.cpp @@ -816,16 +816,16 @@ static std::pair mana_stat( const player &u ) { nc_color c_mana = c_red; std::string s_mana; - if( u.magic.max_mana( u ) <= 0 ) { + if( u.magic->max_mana( u ) <= 0 ) { s_mana = "--"; c_mana = c_light_gray; } else { - if( u.magic.available_mana() >= u.magic.max_mana( u ) / 2 ) { + if( u.magic->available_mana() >= u.magic->max_mana( u ) / 2 ) { c_mana = c_light_blue; - } else if( u.magic.available_mana() >= u.magic.max_mana( u ) / 3 ) { + } else if( u.magic->available_mana() >= u.magic->max_mana( u ) / 3 ) { c_mana = c_yellow; } - s_mana = to_string( u.magic.available_mana() ); + s_mana = to_string( u.magic->available_mana() ); } return std::make_pair( c_mana, s_mana ); } @@ -882,7 +882,7 @@ static void draw_limb_health( avatar &u, const catacurses::window &w, bodypart_i if( u.worn_with_flag( "SPLINT", bp ) ) { static const efftype_id effect_mending( "mending" ); - const auto &eff = u.get_effect( effect_mending, bp->token ); + const auto &eff = u.get_effect( effect_mending, bp ); const int mend_perc = eff.is_null() ? 0.0 : 100 * eff.get_duration() / eff.get_max_duration(); if( is_self_aware || u.has_effect( effect_got_checked ) ) { @@ -1401,7 +1401,7 @@ static void draw_weapon_labels( const avatar &u, const catacurses::window &w ) // NOLINTNEXTLINE(cata-use-named-point-constants) mvwprintz( w, point( 1, 1 ), c_light_gray, _( "Style:" ) ); trim_and_print( w, point( 8, 0 ), getmaxx( w ) - 8, c_light_gray, u.weapname() ); - mvwprintz( w, point( 8, 1 ), c_light_gray, "%s", u.martial_arts_data.selected_style_name( u ) ); + mvwprintz( w, point( 8, 1 ), c_light_gray, "%s", u.martial_arts_data->selected_style_name( u ) ); wnoutrefresh( w ); } @@ -1486,7 +1486,7 @@ static void draw_env_compact( avatar &u, const catacurses::window &w ) // wielded item trim_and_print( w, point( 8, 0 ), getmaxx( w ) - 8, c_light_gray, u.weapname() ); // style - mvwprintz( w, point( 8, 1 ), c_light_gray, "%s", u.martial_arts_data.selected_style_name( u ) ); + mvwprintz( w, point( 8, 1 ), c_light_gray, "%s", u.martial_arts_data->selected_style_name( u ) ); // location mvwprintz( w, point( 8, 2 ), c_white, utf8_truncate( overmap_buffer.ter( u.global_omt_location() )->get_name(), getmaxx( w ) - 8 ) ); @@ -1874,7 +1874,7 @@ static void draw_weapon_classic( const avatar &u, const catacurses::window &w ) trim_and_print( w, point( 10, 0 ), getmaxx( w ) - 24, c_light_gray, u.weapname() ); // Print in sidebar currently used martial style. - const std::string style = u.martial_arts_data.selected_style_name( u ); + const std::string style = u.martial_arts_data->selected_style_name( u ); if( !style.empty() ) { const auto style_color = u.is_armed() ? c_red : c_blue; @@ -1935,7 +1935,7 @@ static void print_mana( const player &u, const catacurses::window &w, const std: colorize( utf8_justify( mana_pair.second, j2 ), mana_pair.first ), //~ translation should not exceed 9 console cells utf8_justify( _( "Max Mana" ), j3 ), - colorize( utf8_justify( to_string( u.magic.max_mana( u ) ), j4 ), c_light_blue ) ); + colorize( utf8_justify( to_string( u.magic->max_mana( u ) ), j4 ), c_light_blue ) ); nc_color gray = c_light_gray; print_colored_text( w, point_zero, gray, gray, mana_string ); @@ -1968,7 +1968,7 @@ static void draw_mana_wide( const player &u, const catacurses::window &w ) static bool spell_panel() { - return get_avatar().magic.knows_spell(); + return get_avatar().magic->knows_spell(); } bool default_render() diff --git a/src/pickup.cpp b/src/pickup.cpp index 9db4ed057b06c..d101f525eb3e6 100644 --- a/src/pickup.cpp +++ b/src/pickup.cpp @@ -48,9 +48,11 @@ #include "ui.h" #include "ui_manager.h" #include "units.h" +#include "units_utility.h" #include "vehicle.h" #include "vehicle_selector.h" #include "vpart_position.h" +#include "sdltiles.h" using ItemCount = std::pair; using PickupMap = std::map; @@ -330,6 +332,10 @@ bool pick_one_up( item_location &loc, int quantity, bool &got_water, bool &offer picked_up = it.spill_contents( player_character ); if( !picked_up ) { break; + } else { + const int invlet = newit.invlet; + newit = it; + newit.invlet = invlet; } // Intentional fallthrough case STASH: { @@ -343,7 +349,7 @@ bool pick_one_up( item_location &loc, int quantity, bool &got_water, bool &offer // successfully added auto &entry = mapPickup[newit.tname()]; entry.second += newit.count(); - entry.first = added_it; + entry.first = newit; picked_up = true; } break; @@ -624,6 +630,7 @@ void Pickup::pick_up( const tripoint &p, int min, from_where get_items_from ) ctxt.register_action( "ANY_INPUT" ); ctxt.register_action( "HELP_KEYBINDINGS" ); ctxt.register_action( "FILTER" ); + ctxt.register_action( "SELECT" ); #if defined(__ANDROID__) ctxt.allow_text_entry = true; // allow user to specify pickup amount #endif @@ -670,6 +677,7 @@ void Pickup::pick_up( const tripoint &p, int min, from_where get_items_from ) const std::string pickup_chars = ctxt.get_available_single_char_hotkeys( all_pickup_chars ); werase( w_pickup ); + pickup_rect::list.clear(); for( int cur_it = start; cur_it < start + maxitems; cur_it++ ) { if( cur_it < static_cast( matches.size() ) ) { int true_it = matches[cur_it]; @@ -740,8 +748,11 @@ void Pickup::pick_up( const tripoint &p, int min, from_where get_items_from ) item_name = string_format( "! %s", item_name ); } - trim_and_print( w_pickup, point( 6, 1 + ( cur_it % maxitems ) ), pickupW - 4, icolor, - item_name ); + int y = 1 + ( cur_it % maxitems ); + trim_and_print( w_pickup, point( 6, y ), pickupW - 4, icolor, item_name ); + pickup_rect rect = pickup_rect( point( 6, y ), point( 6 + pickupW - 4 - 1, y ) ); + rect.cur_it = cur_it; + pickup_rect::list.push_back( rect ); } } @@ -795,6 +806,19 @@ void Pickup::pick_up( const tripoint &p, int min, from_where get_items_from ) if( itemcount < 0 ) { itemcount = 0; } + } else if( action == "SELECT" ) { + cata::optional pos = ctxt.get_coordinates_text( w_pickup ); + if( pos ) { + if( window_contains_point_relative( w_pickup, pos.value() ) ) { + pickup_rect *rect = pickup_rect::find_by_coordinate( pos.value() ); + if( rect != nullptr ) { + selected = rect->cur_it; + iScrollPos = 0; + idx = selected; + } + } + } + } else if( action == "SCROLL_UP" ) { iScrollPos--; } else if( action == "SCROLL_DOWN" ) { @@ -1040,6 +1064,8 @@ void show_pickup_message( const PickupMap &mapPickup ) if( entry.second.first.invlet != 0 ) { add_msg( _( "You pick up: %d %s [%c]" ), entry.second.second, entry.second.first.display_name( entry.second.second ), entry.second.first.invlet ); + } else if( entry.second.first.count_by_charges() ) { + add_msg( _( "You pick up: %s" ), entry.second.first.display_name( entry.second.second ) ); } else { add_msg( _( "You pick up: %d %s" ), entry.second.second, entry.second.first.display_name( entry.second.second ) ); @@ -1050,7 +1076,7 @@ void show_pickup_message( const PickupMap &mapPickup ) bool Pickup::handle_spillable_contents( Character &c, item &it, map &m ) { if( it.is_bucket_nonempty() ) { - it.contents.spill_open_pockets( c ); + it.contents.spill_open_pockets( c, /*avoid=*/&it ); // If bucket is still not empty then player opted not to handle the // rest of the contents @@ -1083,3 +1109,15 @@ int Pickup::cost_to_move_item( const Character &who, const item &it ) // Keep it sane - it's not a long activity return std::min( 400, ret ); } + +std::vector Pickup::pickup_rect::list; + +Pickup::pickup_rect *Pickup::pickup_rect::find_by_coordinate( const point &p ) +{ + for( pickup_rect &rect : pickup_rect::list ) { + if( rect.contains( p ) ) { + return ▭ + } + } + return nullptr; +} diff --git a/src/pickup.h b/src/pickup.h index 18601d9f20749..7c396481bba98 100644 --- a/src/pickup.h +++ b/src/pickup.h @@ -3,6 +3,8 @@ #define CATA_SRC_PICKUP_H #include +#include "point.h" +#include "ui.h" class item; class item_location; @@ -42,6 +44,14 @@ int cost_to_move_item( const Character &who, const item &it ); * @param m map they are on */ bool handle_spillable_contents( Character &c, item &it, map &m ); -} // namespace Pickup +struct pickup_rect : inclusive_rectangle { + pickup_rect() = default; + pickup_rect( const point &P_MIN, const point &P_MAX ) : inclusive_rectangle( P_MIN, P_MAX ) {} + int cur_it; + static std::vector list; + static pickup_rect *find_by_coordinate( const point &p ); +}; + +} // namespace Pickup #endif // CATA_SRC_PICKUP_H diff --git a/src/pixel_minimap.cpp b/src/pixel_minimap.cpp index 05fe6e6b6d449..51183a5c8c2ab 100644 --- a/src/pixel_minimap.cpp +++ b/src/pixel_minimap.cpp @@ -512,7 +512,7 @@ void pixel_minimap::render_critters( const tripoint ¢er ) Creature *critter = g->critter_at( p, true ); - if( critter == nullptr || !get_player_character().sees( *critter ) ) { + if( critter == nullptr || !get_player_view().sees( *critter ) ) { continue; } diff --git a/src/player.cpp b/src/player.cpp index 2d9cc1e51062c..7a5dde9781f68 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -377,8 +377,8 @@ void player::process_turn() for( auto &style : autolearn_martialart_types() ) { const matype_id &ma( style ); - if( !martial_arts_data.has_martialart( ma ) && can_autolearn( ma ) ) { - martial_arts_data.add_martialart( ma ); + if( !martial_arts_data->has_martialart( ma ) && can_autolearn( ma ) ) { + martial_arts_data->add_martialart( ma ); add_msg_if_player( m_info, _( "You have learned a new style: %s!" ), ma.obj().name ); } } @@ -484,7 +484,7 @@ void player::recalc_speed_bonus() mod_speed_bonus( kcal_speed_penalty() ); for( const auto &maps : *effects ) { - for( auto i : maps.second ) { + for( const auto &i : maps.second ) { bool reduced = resists_effect( i.second ); mod_speed_bonus( i.second.get_mod( "SPEED", reduced ) ); } @@ -666,7 +666,7 @@ std::string player::get_category_dream( const std::string &cat, std::list player::get_radio_items() { std::list rc_items; - const invslice &stacks = inv.slice(); + const invslice &stacks = inv->slice(); for( const auto &stack : stacks ) { item &stack_iter = stack->front(); if( stack_iter.has_flag( "RADIO_ACTIVATION" ) ) { @@ -691,7 +691,7 @@ std::list player::get_radio_items() std::list player::get_artifact_items() { std::list art_items; - const invslice &stacks = inv.slice(); + const invslice &stacks = inv->slice(); for( const auto &stack : stacks ) { item &stack_iter = stack->front(); if( stack_iter.is_artifact() ) { @@ -771,7 +771,7 @@ void player::pause() time_duration total_removed = 0_turns; time_duration total_left = 0_turns; bool on_ground = has_effect( effect_downed ); - for( const body_part bp : all_body_parts ) { + for( const bodypart_id &bp : get_all_body_parts() ) { effect &eff = get_effect( effect_onfire, bp ); if( eff.is_null() ) { continue; @@ -787,7 +787,7 @@ void player::pause() // Don't drop on the ground when the ground is on fire if( total_left > 1_minutes && !is_dangerous_fields( here.field_at( pos() ) ) ) { - add_effect( effect_downed, 2_turns, num_bp, false, 0, true ); + add_effect( effect_downed, 2_turns, false, 0, true ); add_msg_player_or_npc( m_warning, _( "You roll on the ground, trying to smother the fire!" ), _( " rolls on the ground!" ) ); @@ -801,13 +801,13 @@ void player::pause() if( !is_armed() && has_effect( effect_bleed ) ) { int most = 0; bodypart_id bp_id; - for( const body_part bp : all_body_parts ) { + for( const bodypart_id &bp : get_all_body_parts() ) { if( most <= get_effect_int( effect_bleed, bp ) ) { most = get_effect_int( effect_bleed, bp ); - bp_id = convert_bp( bp ); + bp_id = bp ; } } - effect &e = get_effect( effect_bleed, bp_id->token ); + effect &e = get_effect( effect_bleed, bp_id ); time_duration penalty = 1_turns * ( encumb( bodypart_id( "hand_r" ) ) + encumb( bodypart_id( "hand_l" ) ) ); time_duration benefit = 5_turns + 10_turns * get_skill_level( skill_firstaid ); @@ -831,7 +831,7 @@ void player::pause() } } // on-pause effects for martial arts - martial_arts_data.ma_onpause_effects( *this ); + martial_arts_data->ma_onpause_effects( *this ); if( is_npc() ) { // The stuff below doesn't apply to NPCs @@ -926,7 +926,7 @@ void player::on_dodge( Creature *source, float difficulty ) difficulty = std::max( difficulty, 0.0f ); practice( skill_dodge, difficulty * 2, difficulty ); - martial_arts_data.ma_ondodge_effects( *this ); + martial_arts_data->ma_ondodge_effects( *this ); // For adjacent attackers check for techniques usable upon successful dodge if( source && square_dist( pos(), source->pos() ) == 1 ) { @@ -950,7 +950,7 @@ void player::on_hit( Creature *source, bodypart_id bp_hit, return; } - bool u_see = get_player_character().sees( *this ); + bool u_see = get_player_view().sees( *this ); if( has_active_bionic( bionic_id( "bio_ods" ) ) && get_power_level() > 5_kJ ) { if( is_player() ) { add_msg( m_good, _( "Your offensive defense system shocks %s in mid-attack!" ), @@ -1040,7 +1040,7 @@ void player::on_hit( Creature *source, bodypart_id bp_hit, add_msg( m_bad, _( "You lose your balance while being hit!" ) ); } // This kind of downing is not subject to immunity. - add_effect( effect_downed, 2_turns, num_bp, false, 0, true ); + add_effect( effect_downed, 2_turns, false, 0, true ); } } Character::on_hit( source, bp_hit, 0.0f, proj ); @@ -1429,7 +1429,7 @@ void player::process_one_effect( effect &it, bool is_new ) { bool reduced = resists_effect( it ); double mod = 1; - const bodypart_id &bp = convert_bp( it.get_bp() ).id(); + const bodypart_id &bp = it.get_bp(); int val = 0; // Still hardcoded stuff, do this first since some modify their other traits @@ -1774,12 +1774,13 @@ void player::process_items() if( it->is_power_armor() && can_interface_armor() && has_power() ) { // Bionic power costs are handled elsewhere continue; - } else if( ch_UPS_used >= ch_UPS || ( it->active && it->ammo_required() > ch_UPS - ch_UPS_used ) ) { + //this is for UPS-modded items with no battery well + } else if( it->active && !it->ammo_sufficient() && + ( ch_UPS_used >= ch_UPS || + it->ammo_required() > ch_UPS - ch_UPS_used ) ) { it->deactivate(); - // this is for UPS-modded items which don't have a battery well - } else if( it->active && it->ammo_capacity( ammotype( "battery" ) ) == 0 ) { - ch_UPS_used += it->ammo_required(); - } else if( it->ammo_remaining() < it->ammo_capacity( ammotype( "battery" ) ) ) { + } else if( ch_UPS_used < ch_UPS && + it->ammo_remaining() < it->ammo_capacity( ammotype( "battery" ) ) ) { ch_UPS_used++; it->ammo_set( itype_battery, it->ammo_remaining() + 1 ); } @@ -2625,7 +2626,7 @@ bool player::takeoff( int pos ) bool player::add_or_drop_with_msg( item &it, const bool /*unloading*/, const item *avoid ) { if( it.made_of( phase_id::LIQUID ) ) { - liquid_handler::consume_liquid( it, 1 ); + liquid_handler::consume_liquid( it, 1, avoid ); return it.charges <= 0; } if( !this->can_pickVolume( it ) ) { @@ -2670,7 +2671,13 @@ bool player::unload( item_location &loc, bool bypass_activity ) for( item *contained : it.contents.all_items_top() ) { int old_charges = contained->charges; const bool consumed = this->add_or_drop_with_msg( *contained, true, &it ); - changed = changed || consumed || contained->charges != old_charges; + if( consumed || contained->charges != old_charges ) { + changed = true; + item_pocket *const parent_pocket = it.contained_where( *contained ); + if( parent_pocket ) { + parent_pocket->unseal(); + } + } if( consumed ) { this->mod_moves( -this->item_handling_cost( *contained ) ); it.remove_item( *contained ); @@ -2872,6 +2879,8 @@ void player::use( item_location loc ) } else { add_msg( m_info, need_splint.str() ); } + } else if( used.is_relic() ) { + invoke_item( &used, loc.position() ); } else { add_msg( m_info, _( "You can't do anything interesting with your %s." ), used.tname() ); @@ -2885,20 +2894,20 @@ void player::reassign_item( item &it, int invlet ) item *prev = invlet_to_item( invlet ); if( prev != nullptr ) { remove_old = it.typeId() != prev->typeId(); - inv.reassign_item( *prev, it.invlet, remove_old ); + inv->reassign_item( *prev, it.invlet, remove_old ); } } if( !invlet || inv_chars.valid( invlet ) ) { - const auto iter = inv.assigned_invlet.find( it.invlet ); - bool found = iter != inv.assigned_invlet.end(); + const auto iter = inv->assigned_invlet.find( it.invlet ); + bool found = iter != inv->assigned_invlet.end(); if( found ) { - inv.assigned_invlet.erase( iter ); + inv->assigned_invlet.erase( iter ); } if( invlet && ( !found || it.invlet != invlet ) ) { - inv.assigned_invlet[invlet] = it.typeId(); + inv->assigned_invlet[invlet] = it.typeId(); } - inv.reassign_item( it, invlet, remove_old ); + inv->reassign_item( it, invlet, remove_old ); } } @@ -3421,29 +3430,24 @@ bool player::wield_contents( item &container, item *internal_item, bool penaltie if( !unwield() ) { return false; } - inv.unsort(); + inv->unsort(); } + // for holsters, we should not include the cost of wielding the holster itself + // The cost of wielding the holster was already added earlier in avatar_action::use_item. + // As we couldn't make sure back then what action was going to be used, we remove the cost now. + item_location il = item_location( *this, &container ); + mv -= il.obtain_cost( *this ); + weapon = std::move( *internal_item ); container.remove_item( *internal_item ); container.on_contents_changed(); - inv.update_invlet( weapon ); - inv.update_cache_with_item( weapon ); + inv->update_invlet( weapon ); + inv->update_cache_with_item( weapon ); last_item = weapon.typeId(); - /** - * @EFFECT_PISTOL decreases time taken to draw pistols from holsters - * @EFFECT_SMG decreases time taken to draw smgs from holsters - * @EFFECT_RIFLE decreases time taken to draw rifles from holsters - * @EFFECT_SHOTGUN decreases time taken to draw shotguns from holsters - * @EFFECT_LAUNCHER decreases time taken to draw launchers from holsters - * @EFFECT_STABBING decreases time taken to draw stabbing weapons from sheathes - * @EFFECT_CUTTING decreases time taken to draw cutting weapons from scabbards - * @EFFECT_BASHING decreases time taken to draw bashing weapons from holsters - */ - int lvl = get_skill_level( weapon.is_gun() ? weapon.gun_skill() : weapon.melee_skill() ); - mv += item_handling_cost( weapon, penalties, base_cost ) / ( ( lvl + 10.0f ) / 10.0f ); + mv += item_retrieve_cost( weapon, container, penalties, base_cost ); moves -= mv; @@ -3487,7 +3491,7 @@ float player::get_melee() const bool player::uncanny_dodge() { bool is_u = is_avatar(); - bool seen = get_player_character().sees( *this ); + bool seen = get_player_view().sees( *this ); if( this->get_power_level() < 74_kJ || !this->has_active_bionic( bio_uncanny_dodge ) ) { return false; } diff --git a/src/player.h b/src/player.h index 82452dd55d218..395324ea26460 100644 --- a/src/player.h +++ b/src/player.h @@ -324,7 +324,7 @@ class player : public Character bool consume( item_location loc, bool force = false ); /** Used for eating a particular item that doesn't need to be in inventory. * Returns true if the item is to be removed (doesn't remove). */ - bool consume( item &target, bool force = false ); + bool consume( item &target, bool force = false, item_pocket *parent_pocket = nullptr ); /** Handles the enjoyability value for a book. **/ int book_fun_for( const item &book, const player &p ) const; diff --git a/src/player_display.cpp b/src/player_display.cpp index a3f4a3276e964..15b8655f99812 100644 --- a/src/player_display.cpp +++ b/src/player_display.cpp @@ -28,6 +28,7 @@ #include "translations.h" #include "ui_manager.h" #include "units.h" +#include "units_utility.h" #include "weather.h" static const skill_id skill_swimming( "swimming" ); @@ -43,6 +44,7 @@ static const std::string title_PROFICIENCIES = translate_marker( "PROFICIENCIES" // use this instead of having to type out 26 spaces like before static const std::string header_spaces( 26, ' ' ); +static const unsigned int grid_width = 26; // Rescale temperature value to one that the player sees static int temperature_print_rescaling( int temp ) @@ -314,22 +316,11 @@ static player_display_tab prev_tab( const player_display_tab tab ) } } -static std::vector> sorted_proficiencies( - const Character &guy ) -{ - std::vector> ret; - for( const proficiency_id &id : guy.proficiencies() ) { - ret.emplace_back( id, id->name() ); - } - std::sort( ret.begin(), ret.end(), localized_compare ); - return ret; -} - static void draw_proficiencies_tab( const catacurses::window &win, const unsigned line, const Character &guy, const player_display_tab curtab ) { werase( win ); - const std::vector> &profs = sorted_proficiencies( guy ); + const std::vector profs = guy.display_proficiencies(); bool focused = curtab == player_display_tab::proficiencies; const nc_color title_color = focused ? h_light_gray : c_light_gray; center_print( win, 0, title_color, _( title_PROFICIENCIES ) ); @@ -342,8 +333,17 @@ static void draw_proficiencies_tab( const catacurses::window &win, const unsigne if( y > height ) { break; } - const nc_color col = focused && i == line ? hilite( c_white ) : c_white; - y += fold_and_print( win, point( 1, y ), width, col, profs[i].second ); + std::string name; + const display_proficiency &cur = profs[i]; + if( !cur.known && cur.id->can_learn() ) { + static_assert( grid_width == 26, "Reminder to update formatting" + "for this string when grid width changes" ); + name = string_format( "%-22s%2.0f%%", cur.id->name(), cur.practice * 100 ); + } else { + name = cur.id->name(); + } + const nc_color col = focused && i == line ? hilite( cur.color ) : cur.color; + y += fold_and_print( win, point( 0, y ), width, col, name ); } if( draw_scrollbar ) { @@ -364,11 +364,24 @@ static void draw_proficiencies_info( const catacurses::window &w_info, const uns const Character &guy ) { werase( w_info ); - const std::vector> &profs = sorted_proficiencies( guy ); + const std::vector profs = guy.display_proficiencies(); if( line < profs.size() ) { - // NOLINTNEXTLINE(cata-use-named-point-constants) - fold_and_print( w_info, point( 1, 0 ), getmaxx( w_info ) - 1, - c_white, profs[line].first->description() ); + const display_proficiency &cur = profs[line]; + std::string progress; + if( cur.known ) { + progress = _( "You know this proficiency." ); + } else { + progress = string_format( _( "You are %2.1f%% of the way towards learning this proficiency." ), + cur.practice * 100 ); + if( debug_mode ) { + progress += string_format( "\nYou have spent %s practicing this proficiency.", + to_string( cur.spent ) ); + } + } + int y = 0; + y += fold_and_print( w_info, point( 1, y ), getmaxx( w_info ) - 1, cur.color, cur.id->name() ); + y += fold_and_print( w_info, point( 1, y ), getmaxx( w_info ) - 1, c_cyan, progress ); + fold_and_print( w_info, point( 1, y ), getmaxx( w_info ) - 1, c_white, cur.id->description() ); } wnoutrefresh( w_info ); } @@ -1068,7 +1081,7 @@ static bool handle_player_display_action( player &you, unsigned int &line, line_end = skillslist.size(); break; case player_display_tab::proficiencies: - line_end = sorted_proficiencies( you ).size(); + line_end = you.display_proficiencies().size(); break; case player_display_tab::num_tabs: abort(); @@ -1259,7 +1272,6 @@ void player::disp_info() const unsigned int skill_win_size_y_max = 1 + skillslist.size(); const unsigned int info_win_size_y = 6; - const unsigned int grid_width = 26; const unsigned int grid_height = 9; const unsigned int infooffsetytop = grid_height + 2; @@ -1314,7 +1326,7 @@ void player::disp_info() std::map speed_effects; for( auto &elem : *effects ) { - for( std::pair &_effect_it : elem.second ) { + for( std::pair &_effect_it : elem.second ) { effect &it = _effect_it.second; bool reduced = resists_effect( it ); int move_adjust = it.get_mod( "SPEED", reduced ); @@ -1456,7 +1468,7 @@ void player::disp_info() ui_adaptor ui_proficiencies; ui_proficiencies.on_screen_resize( [&]( ui_adaptor & ui_proficiencies ) { const unsigned int maxy = static_cast( TERMY ); - proficiency_win_size_y = std::min( _proficiencies.size(), + proficiency_win_size_y = std::min( display_proficiencies().size(), static_cast( maxy - ( infooffsetybottom + effect_win_size_y ) ) ) + 1; w_proficiencies = catacurses::newwin( proficiency_win_size_y, grid_width, profstart ); diff --git a/src/player_hardcoded_effects.cpp b/src/player_hardcoded_effects.cpp index 2f4a3af7fda2e..85fc5e9a07b2c 100644 --- a/src/player_hardcoded_effects.cpp +++ b/src/player_hardcoded_effects.cpp @@ -126,7 +126,7 @@ static const std::string flag_TOURNIQUET( "TOURNIQUET" ); static void eff_fun_onfire( player &u, effect &it ) { const int intense = it.get_intensity(); - u.deal_damage( nullptr, convert_bp( it.get_bp() ).id(), damage_instance( DT_HEAT, rng( intense, + u.deal_damage( nullptr, it.get_bp(), damage_instance( DT_HEAT, rng( intense, intense * 2 ) ) ); } static void eff_fun_spores( player &u, effect &it ) @@ -135,7 +135,7 @@ static void eff_fun_spores( player &u, effect &it ) const int intense = it.get_intensity(); if( ( !u.has_trait( trait_M_IMMUNE ) ) && ( one_in( 100 ) && x_in_y( intense, 900 + u.get_healthy() * 0.6 ) ) ) { - u.add_effect( effect_fungus, 1_turns, num_bp, true ); + u.add_effect( effect_fungus, 1_turns, true ); } } static void eff_fun_antifungal( player &u, effect & ) @@ -266,7 +266,7 @@ static void eff_fun_bleed( player &u, effect &it ) // QuikClot or bandages per the recipe.) const int intense = it.get_intensity(); // tourniquet reduces effective bleeding by 2/3 but doesn't modify the effect's intensity - bool tourniquet = u.worn_with_flag( flag_TOURNIQUET, convert_bp( it.get_bp() ) ); + bool tourniquet = u.worn_with_flag( flag_TOURNIQUET, it.get_bp() ); if( !( tourniquet && one_in( 3 ) ) && u.activity.id() != ACT_FIRSTAID ) { // Prolonged hemorrhage is a significant risk for developing anemia u.vitamin_mod( vitamin_redcells, -intense ); @@ -396,29 +396,29 @@ struct temperature_effect { static void eff_fun_cold( player &u, effect &it ) { // { body_part, intensity }, { str_pen, dex_pen, int_pen, per_pen, msg, msg_chance, miss_msg } - static const std::map, temperature_effect> effs = {{ - { { bp_head, 3 }, { 0, 0, 3, 0, translate_marker( "Your thoughts are unclear." ), 2400, "" } }, - { { bp_head, 2 }, { 0, 0, 1, 0, "", 0, "" } }, - { { bp_mouth, 3 }, { 0, 0, 0, 3, translate_marker( "Your face is stiff from the cold." ), 2400, "" } }, - { { bp_mouth, 2 }, { 0, 0, 0, 1, "", 0, "" } }, - { { bp_torso, 3 }, { 0, 4, 0, 0, translate_marker( "Your torso is freezing cold. You should put on a few more layers." ), 400, translate_marker( "You quiver from the cold." ) } }, - { { bp_torso, 2 }, { 0, 2, 0, 0, "", 0, translate_marker( "Your shivering makes you unsteady." ) } }, - { { bp_arm_l, 3 }, { 0, 2, 0, 0, translate_marker( "Your left arm is shivering." ), 4800, translate_marker( "Your left arm trembles from the cold." ) } }, - { { bp_arm_l, 2 }, { 0, 1, 0, 0, translate_marker( "Your left arm is shivering." ), 4800, translate_marker( "Your left arm trembles from the cold." ) } }, - { { bp_arm_r, 3 }, { 0, 2, 0, 0, translate_marker( "Your right arm is shivering." ), 4800, translate_marker( "Your right arm trembles from the cold." ) } }, - { { bp_arm_r, 2 }, { 0, 1, 0, 0, translate_marker( "Your right arm is shivering." ), 4800, translate_marker( "Your right arm trembles from the cold." ) } }, - { { bp_hand_l, 3 }, { 0, 2, 0, 0, translate_marker( "Your left hand feels like ice." ), 4800, translate_marker( "Your left hand quivers in the cold." ) } }, - { { bp_hand_l, 2 }, { 0, 1, 0, 0, translate_marker( "Your left hand feels like ice." ), 4800, translate_marker( "Your left hand quivers in the cold." ) } }, - { { bp_hand_r, 3 }, { 0, 2, 0, 0, translate_marker( "Your right hand feels like ice." ), 4800, translate_marker( "Your right hand quivers in the cold." ) } }, - { { bp_hand_r, 2 }, { 0, 1, 0, 0, translate_marker( "Your right hand feels like ice." ), 4800, translate_marker( "Your right hand quivers in the cold." ) } }, - { { bp_leg_l, 3 }, { 2, 2, 0, 0, translate_marker( "Your left leg trembles against the relentless cold." ), 4800, translate_marker( "Your legs uncontrollably shake from the cold." ) } }, - { { bp_leg_l, 2 }, { 1, 1, 0, 0, translate_marker( "Your left leg trembles against the relentless cold." ), 4800, translate_marker( "Your legs uncontrollably shake from the cold." ) } }, - { { bp_leg_r, 3 }, { 2, 2, 0, 0, translate_marker( "Your right leg trembles against the relentless cold." ), 4800, translate_marker( "Your legs uncontrollably shake from the cold." ) } }, - { { bp_leg_r, 2 }, { 1, 1, 0, 0, translate_marker( "Your right leg trembles against the relentless cold." ), 4800, translate_marker( "Your legs uncontrollably shake from the cold." ) } }, - { { bp_foot_l, 3 }, { 2, 2, 0, 0, translate_marker( "Your left foot feels frigid." ), 4800, translate_marker( "Your left foot is as nimble as a block of ice." ) } }, - { { bp_foot_l, 2 }, { 1, 1, 0, 0, translate_marker( "Your left foot feels frigid." ), 4800, translate_marker( "Your freezing left foot messes up your balance." ) } }, - { { bp_foot_r, 3 }, { 2, 2, 0, 0, translate_marker( "Your right foot feels frigid." ), 4800, translate_marker( "Your right foot is as nimble as a block of ice." ) } }, - { { bp_foot_r, 2 }, { 1, 1, 0, 0, translate_marker( "Your right foot feels frigid." ), 4800, translate_marker( "Your freezing right foot messes up your balance." ) } }, + static const std::map, temperature_effect> effs = {{ + { { bodypart_id( "head" ), 3 }, { 0, 0, 3, 0, translate_marker( "Your thoughts are unclear." ), 2400, "" } }, + { { bodypart_id( "head" ), 2 }, { 0, 0, 1, 0, "", 0, "" } }, + { { bodypart_id( "mouth" ), 3 }, { 0, 0, 0, 3, translate_marker( "Your face is stiff from the cold." ), 2400, "" } }, + { { bodypart_id( "mouth" ), 2 }, { 0, 0, 0, 1, "", 0, "" } }, + { { bodypart_id( "torso" ), 3 }, { 0, 4, 0, 0, translate_marker( "Your torso is freezing cold. You should put on a few more layers." ), 400, translate_marker( "You quiver from the cold." ) } }, + { { bodypart_id( "torso" ), 2 }, { 0, 2, 0, 0, "", 0, translate_marker( "Your shivering makes you unsteady." ) } }, + { { bodypart_id( "arm_l" ), 3 }, { 0, 2, 0, 0, translate_marker( "Your left arm is shivering." ), 4800, translate_marker( "Your left arm trembles from the cold." ) } }, + { { bodypart_id( "arm_l" ), 2 }, { 0, 1, 0, 0, translate_marker( "Your left arm is shivering." ), 4800, translate_marker( "Your left arm trembles from the cold." ) } }, + { { bodypart_id( "arm_r" ), 3 }, { 0, 2, 0, 0, translate_marker( "Your right arm is shivering." ), 4800, translate_marker( "Your right arm trembles from the cold." ) } }, + { { bodypart_id( "arm_r" ), 2 }, { 0, 1, 0, 0, translate_marker( "Your right arm is shivering." ), 4800, translate_marker( "Your right arm trembles from the cold." ) } }, + { { bodypart_id( "hand_l" ), 3 }, { 0, 2, 0, 0, translate_marker( "Your left hand feels like ice." ), 4800, translate_marker( "Your left hand quivers in the cold." ) } }, + { { bodypart_id( "hand_l" ), 2 }, { 0, 1, 0, 0, translate_marker( "Your left hand feels like ice." ), 4800, translate_marker( "Your left hand quivers in the cold." ) } }, + { { bodypart_id( "hand_r" ), 3 }, { 0, 2, 0, 0, translate_marker( "Your right hand feels like ice." ), 4800, translate_marker( "Your right hand quivers in the cold." ) } }, + { { bodypart_id( "hand_r" ), 2 }, { 0, 1, 0, 0, translate_marker( "Your right hand feels like ice." ), 4800, translate_marker( "Your right hand quivers in the cold." ) } }, + { { bodypart_id( "leg_l" ), 3 }, { 2, 2, 0, 0, translate_marker( "Your left leg trembles against the relentless cold." ), 4800, translate_marker( "Your legs uncontrollably shake from the cold." ) } }, + { { bodypart_id( "leg_l" ), 2 }, { 1, 1, 0, 0, translate_marker( "Your left leg trembles against the relentless cold." ), 4800, translate_marker( "Your legs uncontrollably shake from the cold." ) } }, + { { bodypart_id( "leg_r" ), 3 }, { 2, 2, 0, 0, translate_marker( "Your right leg trembles against the relentless cold." ), 4800, translate_marker( "Your legs uncontrollably shake from the cold." ) } }, + { { bodypart_id( "leg_r" ), 2 }, { 1, 1, 0, 0, translate_marker( "Your right leg trembles against the relentless cold." ), 4800, translate_marker( "Your legs uncontrollably shake from the cold." ) } }, + { { bodypart_id( "foot_l" ), 3 }, { 2, 2, 0, 0, translate_marker( "Your left foot feels frigid." ), 4800, translate_marker( "Your left foot is as nimble as a block of ice." ) } }, + { { bodypart_id( "foot_l" ), 2 }, { 1, 1, 0, 0, translate_marker( "Your left foot feels frigid." ), 4800, translate_marker( "Your freezing left foot messes up your balance." ) } }, + { { bodypart_id( "foot_r" ), 3 }, { 2, 2, 0, 0, translate_marker( "Your right foot feels frigid." ), 4800, translate_marker( "Your right foot is as nimble as a block of ice." ) } }, + { { bodypart_id( "foot_r" ), 2 }, { 1, 1, 0, 0, translate_marker( "Your right foot feels frigid." ), 4800, translate_marker( "Your freezing right foot messes up your balance." ) } }, } }; const auto iter = effs.find( { it.get_bp(), it.get_intensity() } ); @@ -430,34 +430,35 @@ static void eff_fun_cold( player &u, effect &it ) static void eff_fun_hot( player &u, effect &it ) { // { body_part, intensity }, { str_pen, dex_pen, int_pen, per_pen, msg, msg_chance, miss_msg } - static const std::map, temperature_effect> effs = {{ - { { bp_head, 3 }, { 0, 0, 0, 0, translate_marker( "Your head is pounding from the heat." ), 2400, "" } }, - { { bp_head, 2 }, { 0, 0, 0, 0, "", 0, "" } }, - { { bp_torso, 3 }, { 2, 0, 0, 0, translate_marker( "You are sweating profusely." ), 2400, "" } }, - { { bp_torso, 2 }, { 1, 0, 0, 0, "", 0, "" } }, - { { bp_hand_l, 3 }, { 0, 2, 0, 0, "", 0, translate_marker( "Your left hand's too sweaty to grip well." ) } }, - { { bp_hand_l, 2 }, { 0, 1, 0, 0, "", 0, translate_marker( "Your left hand's too sweaty to grip well." ) } }, - { { bp_hand_r, 3 }, { 0, 2, 0, 0, "", 0, translate_marker( "Your right hand's too sweaty to grip well." ) } }, - { { bp_hand_r, 2 }, { 0, 1, 0, 0, "", 0, translate_marker( "Your right hand's too sweaty to grip well." ) } }, - { { bp_leg_l, 3 }, { 0, 0, 0, 0, translate_marker( "Your left leg is cramping up." ), 4800, "" } }, - { { bp_leg_l, 2 }, { 0, 0, 0, 0, "", 0, "" } }, - { { bp_leg_r, 3 }, { 0, 0, 0, 0, translate_marker( "Your right leg is cramping up." ), 4800, "" } }, - { { bp_leg_r, 2 }, { 0, 0, 0, 0, "", 0, "" } }, - { { bp_foot_l, 3 }, { 0, 0, 0, 0, translate_marker( "Your left foot is swelling in the heat." ), 4800, "" } }, - { { bp_foot_l, 2 }, { 0, 0, 0, 0, "", 0, "" } }, - { { bp_foot_r, 3 }, { 0, 0, 0, 0, translate_marker( "Your right foot is swelling in the heat." ), 4800, "" } }, - { { bp_foot_r, 2 }, { 0, 0, 0, 0, "", 0, "" } }, + static const std::map, temperature_effect> effs = {{ + { { bodypart_id( "head" ), 3 }, { 0, 0, 0, 0, translate_marker( "Your head is pounding from the heat." ), 2400, "" } }, + { { bodypart_id( "head" ), 2 }, { 0, 0, 0, 0, "", 0, "" } }, + { { bodypart_id( "torso" ), 3 }, { 2, 0, 0, 0, translate_marker( "You are sweating profusely." ), 2400, "" } }, + { { bodypart_id( "torso" ), 2 }, { 1, 0, 0, 0, "", 0, "" } }, + { { bodypart_id( "hand_l" ), 3 }, { 0, 2, 0, 0, "", 0, translate_marker( "Your left hand's too sweaty to grip well." ) } }, + { { bodypart_id( "hand_l" ), 2 }, { 0, 1, 0, 0, "", 0, translate_marker( "Your left hand's too sweaty to grip well." ) } }, + { { bodypart_id( "hand_r" ), 3 }, { 0, 2, 0, 0, "", 0, translate_marker( "Your right hand's too sweaty to grip well." ) } }, + { { bodypart_id( "hand_r" ), 2 }, { 0, 1, 0, 0, "", 0, translate_marker( "Your right hand's too sweaty to grip well." ) } }, + { { bodypart_id( "leg_l" ), 3 }, { 0, 0, 0, 0, translate_marker( "Your left leg is cramping up." ), 4800, "" } }, + { { bodypart_id( "leg_l" ), 2 }, { 0, 0, 0, 0, "", 0, "" } }, + { { bodypart_id( "leg_r" ), 3 }, { 0, 0, 0, 0, translate_marker( "Your right leg is cramping up." ), 4800, "" } }, + { { bodypart_id( "leg_r" ), 2 }, { 0, 0, 0, 0, "", 0, "" } }, + { { bodypart_id( "foot_l" ), 3 }, { 0, 0, 0, 0, translate_marker( "Your left foot is swelling in the heat." ), 4800, "" } }, + { { bodypart_id( "foot_l" ), 2 }, { 0, 0, 0, 0, "", 0, "" } }, + { { bodypart_id( "foot_r" ), 3 }, { 0, 0, 0, 0, translate_marker( "Your right foot is swelling in the heat." ), 4800, "" } }, + { { bodypart_id( "foot_r" ), 2 }, { 0, 0, 0, 0, "", 0, "" } }, } }; - const body_part bp = it.get_bp(); + const bodypart_id bp = it.get_bp(); const int intense = it.get_intensity(); const auto iter = effs.find( { it.get_bp(), it.get_intensity() } ); if( iter != effs.end() ) { iter->second.apply( u ); } // Hothead effects are a special snowflake - if( bp == bp_head && intense >= 2 ) { + + if( bp == bodypart_id( "head" ) && intense >= 2 ) { if( one_in( std::max( 25, std::min( 89500, 90000 - u.get_part_temp_cur( bodypart_id( "head" ) ) ) ) ) ) { u.vomit(); @@ -471,15 +472,15 @@ static void eff_fun_hot( player &u, effect &it ) static void eff_fun_frostbite( player &u, effect &it ) { // { body_part, intensity }, { str_pen, dex_pen, int_pen, per_pen, msg, msg_chance, miss_msg } - static const std::map, temperature_effect> effs = {{ - { { bp_hand_l, 2 }, { 0, 2, 0, 0, "", 0, translate_marker( "You have trouble grasping with your numb fingers." ) } }, - { { bp_hand_r, 2 }, { 0, 2, 0, 0, "", 0, translate_marker( "You have trouble grasping with your numb fingers." ) } }, - { { bp_foot_l, 2 }, { 0, 0, 0, 0, translate_marker( "Your foot has gone numb." ), 4800, "" } }, - { { bp_foot_l, 1 }, { 0, 0, 0, 0, translate_marker( "Your foot has gone numb." ), 4800, "" } }, - { { bp_foot_r, 2 }, { 0, 0, 0, 0, translate_marker( "Your foot has gone numb." ), 4800, "" } }, - { { bp_foot_r, 1 }, { 0, 0, 0, 0, translate_marker( "Your foot has gone numb." ), 4800, "" } }, - { { bp_mouth, 2 }, { 0, 0, 0, 3, translate_marker( "Your face feels numb." ), 4800, "" } }, - { { bp_mouth, 1 }, { 0, 0, 0, 1, translate_marker( "Your face feels numb." ), 4800, "" } }, + static const std::map, temperature_effect> effs = {{ + { { bodypart_id( "hand_l" ), 2 }, { 0, 2, 0, 0, "", 0, translate_marker( "You have trouble grasping with your numb fingers." ) } }, + { { bodypart_id( "hand_r" ), 2 }, { 0, 2, 0, 0, "", 0, translate_marker( "You have trouble grasping with your numb fingers." ) } }, + { { bodypart_id( "foot_l" ), 2 }, { 0, 0, 0, 0, translate_marker( "Your foot has gone numb." ), 4800, "" } }, + { { bodypart_id( "foot_l" ), 1 }, { 0, 0, 0, 0, translate_marker( "Your foot has gone numb." ), 4800, "" } }, + { { bodypart_id( "foot_r" ), 2 }, { 0, 0, 0, 0, translate_marker( "Your foot has gone numb." ), 4800, "" } }, + { { bodypart_id( "foot_r" ), 1 }, { 0, 0, 0, 0, translate_marker( "Your foot has gone numb." ), 4800, "" } }, + { { bodypart_id( "mouth" ), 2 }, { 0, 0, 0, 3, translate_marker( "Your face feels numb." ), 4800, "" } }, + { { bodypart_id( "mouth" ), 1 }, { 0, 0, 0, 1, translate_marker( "Your face feels numb." ), 4800, "" } }, } }; const auto iter = effs.find( { it.get_bp(), it.get_intensity() } ); @@ -521,7 +522,7 @@ void player::hardcoded_effects( effect &it ) const time_duration dur = it.get_duration(); int intense = it.get_intensity(); - const bodypart_id &bp = convert_bp( it.get_bp() ).id(); + const bodypart_id &bp = it.get_bp(); bool sleeping = has_effect( effect_sleep ); map &here = get_map(); Character &player_character = get_player_character(); @@ -532,7 +533,7 @@ void player::hardcoded_effects( effect &it ) formication_chance += 14400 - to_turns( dur ); } if( one_in( formication_chance ) ) { - add_effect( effect_formication, 60_minutes, bp->token ); + add_effect( effect_formication, 60_minutes, bp ); } if( dur < 1_days && one_in( 14400 ) ) { vomit(); @@ -555,7 +556,7 @@ void player::hardcoded_effects( effect &it ) } } get_event_bus().send( getID() ); - remove_effect( effect_formication, bp->token ); + remove_effect( effect_formication, bp ); moves -= 600; triggered = true; } @@ -574,10 +575,10 @@ void player::hardcoded_effects( effect &it ) add_msg( m_warning, _( "You start scratching your %s!" ), body_part_name_accusative( bp ) ); player_character.cancel_activity(); - } else if( player_character.sees( pos() ) ) { + } else { //~ 1$s is NPC name, 2$s is bodypart in accusative. - add_msg( _( "%1$s starts scratching their %2$s!" ), name, - body_part_name_accusative( bp ) ); + add_msg_if_player_sees( pos(), _( "%1$s starts scratching their %2$s!" ), name, + body_part_name_accusative( bp ) ); } moves -= 150; apply_damage( nullptr, bp, 1 ); @@ -652,7 +653,7 @@ void player::hardcoded_effects( effect &it ) } else if( one_in( 3000 ) ) { add_msg_if_player( m_bad, _( "You notice a large abscess. You pick at it." ) ); body_part itch = random_body_part( true ); - add_effect( effect_formication, 60_minutes, itch ); + add_effect( effect_formication, 60_minutes, convert_bp( itch ).id() ); mod_pain( 1 ); } else if( one_in( 3000 ) ) { add_msg_if_player( m_bad, @@ -784,7 +785,7 @@ void player::hardcoded_effects( effect &it ) } if( one_in( 10000 ) ) { if( !has_trait( trait_M_IMMUNE ) ) { - add_effect( effect_fungus, 1_turns, num_bp, true ); + add_effect( effect_fungus, 1_turns, true ); } else { add_msg_if_player( m_info, _( "We have many colonists awaiting passage." ) ); } @@ -844,7 +845,7 @@ void player::hardcoded_effects( effect &it ) add_miss_reason( _( "Your muscles are locking up and you can't fight effectively." ), 4 ); if( one_in( 3072 ) ) { add_msg_if_player( m_bad, _( "Your muscles spasm." ) ); - add_effect( effect_downed, rng( 1_turns, 4_turns ), num_bp, false, 0, true ); + add_effect( effect_downed, rng( 1_turns, 4_turns ), false, 0, true ); add_effect( effect_stunned, rng( 1_turns, 4_turns ) ); if( one_in( 10 ) ) { mod_pain( rng( 1, 10 ) ); @@ -873,7 +874,7 @@ void player::hardcoded_effects( effect &it ) add_msg_if_player( m_bad, _( "You're experiencing loss of basic motor skills and blurred vision. Your mind recoils in horror, unable to communicate with your spinal column." ) ); add_msg_if_player( m_bad, _( "You stagger and fall!" ) ); - add_effect( effect_downed, rng( 1_turns, 4_turns ), num_bp, false, 0, true ); + add_effect( effect_downed, rng( 1_turns, 4_turns ), false, 0, true ); if( one_in( 8 ) || x_in_y( vomit_mod(), 10 ) ) { vomit(); } @@ -1156,7 +1157,7 @@ void player::hardcoded_effects( effect &it ) } if( zed_number > 0 ) { //If intensity isn't pass the cap, average it with # of zeds - add_effect( effect_grabbed, 2_turns, bp_torso, false, ( intense + zed_number ) / 2 ); + add_effect( effect_grabbed, 2_turns, bodypart_id( "torso" ), false, ( intense + zed_number ) / 2 ); } } else if( id == effect_bite ) { bool recovered = false; @@ -1214,7 +1215,7 @@ void player::hardcoded_effects( effect &it ) if( !recovered ) { // Move up to infection if( dur > 6_hours ) { - add_effect( effect_infected, 1_turns, bp->token, true ); + add_effect( effect_infected, 1_turns, bp, true ); // Set ourselves up for removal it.set_duration( 0_turns ); } else if( has_effect( effect_strong_antibiotic ) ) { @@ -1530,7 +1531,7 @@ void player::hardcoded_effects( effect &it ) } } else { if( !has_effect( effect_slept_through_alarm ) ) { - add_effect( effect_slept_through_alarm, 1_turns, num_bp, true ); + add_effect( effect_slept_through_alarm, 1_turns, true ); } // 10 minute cyber-snooze it.mod_duration( 10_minutes ); @@ -1539,7 +1540,7 @@ void player::hardcoded_effects( effect &it ) } else { if( asleep && dur == 1_turns ) { if( !has_effect( effect_slept_through_alarm ) ) { - add_effect( effect_slept_through_alarm, 1_turns, num_bp, true ); + add_effect( effect_slept_through_alarm, 1_turns, true ); } // 10 minute automatic snooze it.mod_duration( 10_minutes ); diff --git a/src/point.cpp b/src/point.cpp index a7aca2c7a701c..abe42c082a6c7 100644 --- a/src/point.cpp +++ b/src/point.cpp @@ -5,6 +5,7 @@ #include #include "cata_utility.h" +#include "units_utility.h" point point::from_string( const std::string &s ) { diff --git a/src/profession.cpp b/src/profession.cpp index 430e35af82fb8..37c83b0a5eb1c 100644 --- a/src/profession.cpp +++ b/src/profession.cpp @@ -518,8 +518,8 @@ std::map profession::spells() const void profession::learn_spells( avatar &you ) const { for( const std::pair spell_pair : spells() ) { - you.magic.learn_spell( spell_pair.first, you, true ); - spell &sp = you.magic.get_spell( spell_pair.first ); + you.magic->learn_spell( spell_pair.first, you, true ); + spell &sp = you.magic->get_spell( spell_pair.first ); while( sp.get_level() < spell_pair.second && !sp.is_max_level() ) { sp.gain_level(); } diff --git a/src/proficiency.cpp b/src/proficiency.cpp index 4031d2546661e..9ec71489e8bda 100644 --- a/src/proficiency.cpp +++ b/src/proficiency.cpp @@ -33,6 +33,15 @@ void proficiency::load( const JsonObject &jo, const std::string & ) { mandatory( jo, was_loaded, "name", _name ); mandatory( jo, was_loaded, "description", _description ); + mandatory( jo, was_loaded, "can_learn", _can_learn ); + + optional( jo, was_loaded, "time_to_learn", _time_to_learn ); + optional( jo, was_loaded, "required_proficiencies", _required ); +} + +bool proficiency::can_learn() const +{ + return _can_learn; } std::string proficiency::name() const @@ -44,3 +53,271 @@ std::string proficiency::description() const { return _description.translated(); } + +time_duration proficiency::time_to_learn() const +{ + return _time_to_learn; +} + +std::set proficiency::required_proficiencies() const +{ + return _required; +} + +learning_proficiency &proficiency_set::fetch_learning( const proficiency_id &target ) +{ + for( learning_proficiency &cursor : learning ) { + if( cursor.id == target ) { + return cursor; + } + } + + // This should _never_ happen + debugmsg( "Uh-oh! Requested proficiency that character does not know" + " - expect crash or undefined behavior" ); + return learning[0]; +} + +std::vector proficiency_set::display() const +{ + // The proficiencies are sorted by whether or not you know them + // and then alphabetically + std::vector> sorted_known; + std::vector> sorted_learning; + + for( const proficiency_id &cur : known ) { + sorted_known.push_back( { cur, cur->name() } ); + } + + for( const learning_proficiency &cur : learning ) { + sorted_learning.push_back( { cur.id, cur.id->name() } ); + } + + std::sort( sorted_known.begin(), sorted_known.end(), localized_compare ); + std::sort( sorted_learning.begin(), sorted_learning.end(), localized_compare ); + + // Our display_proficiencies, sorted in the order above + std::vector ret; + + for( const std::pair &cur : sorted_known ) { + display_proficiency disp; + disp.id = cur.first; + disp.color = c_white; + disp.practice = 1.0f; + disp.spent = cur.first->time_to_learn(); + disp.known = true; + ret.insert( ret.end(), disp ); + } + + for( const std::pair &cur : sorted_learning ) { + display_proficiency disp; + disp.id = cur.first; + disp.color = c_light_gray; + time_duration practiced; + for( const learning_proficiency &cursor : learning ) { + if( cursor.id == cur.first ) { + practiced = cursor.practiced; + break; + } + } + disp.spent = practiced; + disp.practice = practiced / cur.first->time_to_learn(); + disp.known = false; + ret.insert( ret.end(), disp ); + } + + return ret; +} + +bool proficiency_set::practice( const proficiency_id &practicing, const time_duration amount, + const cata::optional max ) +{ + if( has_learned( practicing ) || !practicing->can_learn() || !has_prereqs( practicing ) ) { + return false; + } + if( !has_practiced( practicing ) ) { + learning.push_back( learning_proficiency( practicing, 0_seconds ) ); + } + + learning_proficiency ¤t = fetch_learning( practicing ); + + if( max && current.practiced > *max ) { + return false; + } + + current.practiced += amount; + + if( current.practiced >= practicing->time_to_learn() ) { + for( std::vector::iterator it = learning.begin(); it != learning.end(); ) { + if( it->id == practicing ) { + it = learning.erase( it ); + } else { + ++it; + } + } + learn( practicing ); + + return true; + } + + return false; +} + +void proficiency_set::learn( const proficiency_id &learned ) +{ + for( const proficiency_id &req : learned->required_proficiencies() ) { + if( !has_learned( req ) ) { + return; + } + } + known.insert( learned ); +} + +// All the proficiencies in subjects that require one of the proficiencies in requirements +static std::set proficiencies_requiring( + const std::set &requirements, + const cata::flat_set &subjects ) +{ + std::set ret; + for( const proficiency_id &candidate : subjects ) { + for( const proficiency_id &selector : requirements ) { + if( candidate->required_proficiencies().count( selector ) ) { + ret.insert( candidate ); + break; + } + } + } + return ret; +} + +void proficiency_set::remove( const proficiency_id &lost ) +{ + // No unintended side effects + if( !known.count( lost ) ) { + return; + } + // Loop over all the proficiencies requiring lost, to remove them too + // Then the ones requiring it, etc. + std::set to_remove; + to_remove.insert( lost ); + size_t cached_size = 0; + // While we have new proficiencies we need to check for anything requiring them + while( to_remove.size() != cached_size ) { + cached_size = to_remove.size(); + std::set additional = proficiencies_requiring( to_remove, known ); + to_remove.insert( additional.begin(), additional.end() ); + } + + for( const proficiency_id &gone : to_remove ) { + known.erase( gone ); + } +} + +bool proficiency_set::has_learned( const proficiency_id &query ) const +{ + return known.count( query ); +} + +bool proficiency_set::has_practiced( const proficiency_id &query ) const +{ + for( const learning_proficiency &cursor : learning ) { + if( cursor.id == query ) { + return true; + } + } + return false; +} + +bool proficiency_set::has_prereqs( const proficiency_id &query ) const +{ + for( const proficiency_id &req : query->required_proficiencies() ) { + if( !has_learned( req ) ) { + return false; + } + } + return true; +} + +float proficiency_set::pct_practiced( const proficiency_id &query ) const +{ + for( const learning_proficiency &prof : learning ) { + if( prof.id == query ) { + return prof.practiced / query->time_to_learn(); + } + } + if( has_learned( query ) ) { + return 1.0f; + } + return 0.0f; +} + +time_duration proficiency_set::training_time_needed( const proficiency_id &query ) const +{ + for( const learning_proficiency &prof : learning ) { + if( prof.id == query ) { + return query->time_to_learn() - prof.practiced; + } + } + return query->time_to_learn(); +} + +std::vector proficiency_set::known_profs() const +{ + std::vector ret; + for( const proficiency_id &knows : known ) { + ret.push_back( knows ); + } + return ret; +} + +std::vector proficiency_set::learning_profs() const +{ + std::vector ret; + for( const learning_proficiency &subject : learning ) { + ret.push_back( subject.id ); + } + return ret; +} + +void proficiency_set::serialize( JsonOut &jsout ) const +{ + jsout.start_object(); + + jsout.member( "known", known ); + jsout.member( "learning", learning ); + + jsout.end_object(); +} + +void proficiency_set::deserialize( JsonIn &jsin ) +{ + JsonObject jsobj = jsin.get_object(); + + jsobj.read( "known", known ); + jsobj.read( "learning", learning ); +} + +void proficiency_set::deserialize_legacy( const JsonArray &jo ) +{ + for( const std::string &prof : jo ) { + known.insert( proficiency_id( prof ) ); + } +} + +void learning_proficiency::serialize( JsonOut &jsout ) const +{ + jsout.start_object(); + + jsout.member( "id", id ); + jsout.member( "practiced", practiced ); + + jsout.end_object(); +} + +void learning_proficiency::deserialize( JsonIn &jsin ) +{ + JsonObject jo = jsin.get_object(); + + jo.read( "id", id ); + jo.read( "practiced", practiced ); +} diff --git a/src/proficiency.h b/src/proficiency.h index dee692e295842..ea470973dfd03 100644 --- a/src/proficiency.h +++ b/src/proficiency.h @@ -2,6 +2,9 @@ #ifndef CATA_SRC_PROFICIENCY_H #define CATA_SRC_PROFICIENCY_H +#include "calendar.h" +#include "color.h" +#include "flat_set.h" #include "json.h" #include "translations.h" #include "type_id.h" @@ -9,6 +12,9 @@ template class generic_factory; +struct learning_proficiency; +struct display_proficiency; + class proficiency { friend class generic_factory; @@ -16,16 +22,89 @@ class proficiency proficiency_id id; bool was_loaded = false; + bool _can_learn; + translation _name; translation _description; + time_duration _time_to_learn = 9999_hours; + std::set _required; + public: static void load_proficiencies( const JsonObject &jo, const std::string &src ); static void reset(); void load( const JsonObject &jo, const std::string &src ); + bool can_learn() const; std::string name() const; std::string description() const; + time_duration time_to_learn() const; + std::set required_proficiencies() const; +}; + +// The proficiencies you know, and the ones you're learning. +class proficiency_set +{ + // No need for extra info, we just know these proficiencies + cata::flat_set known; + + // The proficiencies we're learning + std::vector learning; + + learning_proficiency &fetch_learning( const proficiency_id &target ); + + public: + std::vector display() const; + // True if the proficiency is learned; + bool practice( const proficiency_id &practicing, time_duration amount, + cata::optional max ); + void learn( const proficiency_id &learned ); + void remove( const proficiency_id &lost ); + + // Do we know this proficiency? + bool has_learned( const proficiency_id &query ) const; + bool has_practiced( const proficiency_id &query ) const; + bool has_prereqs( const proficiency_id &query ) const; + + float pct_practiced( const proficiency_id &query ) const; + time_duration training_time_needed( const proficiency_id &query ) const; + std::vector known_profs() const; + std::vector learning_profs() const; + + void serialize( JsonOut &jsout ) const; + void deserialize( JsonIn &jsin ); + void deserialize_legacy( const JsonArray &jo ); +}; + +struct learning_proficiency { + proficiency_id id; + + // How long we have practiced this proficiency + time_duration practiced; + + learning_proficiency() = default; + learning_proficiency( const proficiency_id &id, const time_duration practiced ) : id( id ), + practiced( practiced ) {} + + void serialize( JsonOut &jsout ) const; + void deserialize( JsonIn &jsin ); +}; + +struct display_proficiency { + // To grab the name, description, etc + proficiency_id id; + + // White if we know it, gray if we don't + nc_color color; + + // What percentage we are towards knowing it + float practice; + + // How much time we've spent practicing it + time_duration spent; + + // If we already know it + bool known; }; #endif // CATA_SRC_PROFICIENCY_H diff --git a/src/ranged.cpp b/src/ranged.cpp index ed10363e49f17..04054d4cca850 100644 --- a/src/ranged.cpp +++ b/src/ranged.cpp @@ -445,7 +445,7 @@ target_handler::trajectory target_handler::mode_spell( avatar &you, spell &casti target_handler::trajectory target_handler::mode_spell( avatar &you, const spell_id &sp, bool no_fail, bool no_mana ) { - return mode_spell( you, you.magic.get_spell( sp ), no_fail, no_mana ); + return mode_spell( you, you.magic->get_spell( sp ), no_fail, no_mana ); } static double occupied_tile_fraction( creature_size target_size ) @@ -680,9 +680,8 @@ bool player::handle_gun_damage( item &it ) void npc::pretend_fire( npc *source, int shots, item &gun ) { int curshot = 0; - Character &player_character = get_player_character(); - if( player_character.sees( *source ) && one_in( 50 ) ) { - add_msg( m_info, _( "%s shoots something." ), source->disp_name() ); + if( one_in( 50 ) ) { + add_msg_if_player_sees( *source, m_info, _( "%s shoots something." ), source->disp_name() ); } while( curshot != shots ) { if( gun.ammo_consume( gun.ammo_required(), pos() ) != gun.ammo_required() ) { @@ -693,9 +692,7 @@ void npc::pretend_fire( npc *source, int shots, item &gun ) item *weapon = &gun; const auto data = weapon->gun_noise( shots > 1 ); - if( player_character.sees( *source ) ) { - add_msg( m_warning, _( "You hear %s." ), data.sound ); - } + add_msg_if_player_sees( *source, m_warning, _( "You hear %s." ), data.sound ); curshot++; moves -= 100; } diff --git a/src/recipe.cpp b/src/recipe.cpp index ce04d325b8ddc..3816aeb285727 100644 --- a/src/recipe.cpp +++ b/src/recipe.cpp @@ -13,6 +13,7 @@ #include "debug.h" #include "flat_set.h" #include "game_constants.h" +#include "generic_factory.h" #include "item.h" #include "itype.h" #include "json.h" @@ -61,7 +62,7 @@ time_duration recipe::time_to_craft( const Character &guy, recipe_time_flag flag int recipe::time_to_craft_moves( const Character &guy, recipe_time_flag flags ) const { - if( flags == recipe_time_flag::none ) { + if( flags == recipe_time_flag::ignore_proficiencies ) { return time; } int ret = time; @@ -223,9 +224,12 @@ void recipe::load( const JsonObject &jo, const std::string &src ) if( jo.has_member( "book_learn" ) ) { booksets.clear(); - for( JsonArray arr : jo.get_array( "book_learn" ) ) { - booksets.emplace( itype_id( arr.get_string( 0 ) ), - arr.size() > 1 ? arr.get_int( 1 ) : -1 ); + if( jo.has_array( "book_learn" ) ) { + for( JsonArray arr : jo.get_array( "book_learn" ) ) { + booksets.emplace( itype_id( arr.get_string( 0 ) ), book_recipe_data{ arr.size() > 1 ? arr.get_int( 1 ) : -1 } ); + } + } else { + mandatory( jo, false, "book_learn", booksets ); } } @@ -397,6 +401,7 @@ void recipe::finalize() debugmsg( "proficiency %s provides a bonus for not being known in recipe %s", rpof.id.str(), ident_.str() ); } + // Now that we've done the error checking, log that a proficiency with this id is used if( rpof.required ) { required.insert( rpof.id ); @@ -463,7 +468,7 @@ std::string recipe::get_consistency_error() const return "uses invalid skill"; } - const auto is_invalid_book = []( const std::pair &elem ) { + const auto is_invalid_book = []( const std::pair &elem ) { return !item::find_type( elem.first )->book; }; @@ -933,4 +938,18 @@ void recipe_proficiency::load( const JsonObject &jo ) jo.read( "required", required ); jo.read( "time_multiplier", time_multiplier ); jo.read( "fail_multiplier", fail_multiplier ); + jo.read( "learning_time_multiplier", learning_time_mult ); + jo.read( "max_experience", max_experience ); +} + +void book_recipe_data::deserialize( JsonIn &jsin ) +{ + load( jsin.get_object() ); +} + +void book_recipe_data::load( const JsonObject &jo ) +{ + jo.read( "skill_level", skill_req ); + jo.read( "recipe_name", alt_name ); + jo.read( "hidden", hidden ); } diff --git a/src/recipe.h b/src/recipe.h index e292082c6cefe..301fc82cc0c63 100644 --- a/src/recipe.h +++ b/src/recipe.h @@ -10,6 +10,7 @@ #include #include +#include "calendar.h" #include "optional.h" #include "requirements.h" #include "translations.h" @@ -45,6 +46,17 @@ struct recipe_proficiency { bool required = false; float time_multiplier = 1.0f; float fail_multiplier = 2.5f; + float learning_time_mult = 1.0f; + cata::optional max_experience = cata::nullopt; + + void load( const JsonObject &jo ); + void deserialize( JsonIn &jsin ); +}; + +struct book_recipe_data { + int skill_req = -1; + cata::optional alt_name = cata::nullopt; + bool hidden = false; void load( const JsonObject &jo ); void deserialize( JsonIn &jsin ); @@ -130,7 +142,9 @@ class recipe std::map autolearn_requirements; // Skill levels required to autolearn std::map learn_by_disassembly; // Skill levels required to learn by disassembly - std::map booksets; // Books containing this recipe, and the skill level required + // Books containing this recipe, and the skill level required + std::map booksets; + std::set flags_to_delete; // Flags to delete from the resultant item. // Create a string list to describe the skill requirements for this recipe diff --git a/src/recipe_dictionary.cpp b/src/recipe_dictionary.cpp index 4e9ddf6837d16..5f789c0339290 100644 --- a/src/recipe_dictionary.cpp +++ b/src/recipe_dictionary.cpp @@ -423,8 +423,9 @@ void recipe_dictionary::finalize() for( const auto &bk : r.booksets ) { const itype *booktype = item::find_type( bk.first ); - int req = bk.second > 0 ? bk.second : std::max( booktype->book->req, r.difficulty ); - islot_book::recipe_with_description_t desc{ &r, req, r.result_name(), false }; + int req = bk.second.skill_req > 0 ? bk.second.skill_req : std::max( booktype->book->req, + r.difficulty ); + islot_book::recipe_with_description_t desc{ &r, req, bk.second.alt_name.has_value() ? bk.second.alt_name.value().translated() : r.result_name(), bk.second.hidden }; const_cast( *booktype->book ).recipes.insert( desc ); } diff --git a/src/relic.cpp b/src/relic.cpp index d1490421996cf..03d6975f5c14c 100644 --- a/src/relic.cpp +++ b/src/relic.cpp @@ -30,6 +30,19 @@ namespace io abort(); } // *INDENT-ON* +template<> +std::string enum_to_string( relic_recharge type ) +{ + // *INDENT-OFF* + switch( type ) { + case relic_recharge::none: return "none"; + case relic_recharge::periodic: return "periodic"; + case relic_recharge::num: break; + } + // *INDENT-ON* + debugmsg( "Invalid relic recharge type" ); + abort(); +} } // namespace io namespace @@ -139,6 +152,24 @@ void relic_procgen_data::load( const JsonObject &jo, const std::string & ) item_weights.add( it, weight ); } + + for( const JsonObject &jo_inner : jo.get_array( "active_procgen_values" ) ) { + int weight = 0; + mandatory( jo_inner, was_loaded, "weight", weight ); + relic_procgen_data::enchantment_active val; + val.load( jo_inner ); + + active_procgen_values.add( val, weight ); + } + + for( const JsonObject &jo_inner : jo.get_array( "charge_types" ) ) { + int weight = 0; + mandatory( jo_inner, was_loaded, "weight", weight ); + relic_charge_template charge; + charge.load( jo_inner ); + + charge_values.add( charge, weight ); + } } void relic_procgen_data::generation_rules::load( const JsonObject &jo ) @@ -160,6 +191,73 @@ void relic_procgen_data::deserialize( JsonIn &jsin ) load( jobj ); } +void relic_charge_template::deserialize( JsonIn &jsin ) +{ + load( jsin.get_object() ); +} + +void relic_charge_template::load( const JsonObject &jo ) +{ + int tmp_power = 0; + + const JsonObject max_charge = jo.get_object( "max_charges" ); + max_charge.read( "range", max_charges ); + max_charge.read( "power", tmp_power ); + power_level += tmp_power; + + const JsonObject charge = jo.get_object( "charges" ); + charge.read( "range", init_charges ); + charge.read( "power", tmp_power ); + power_level += tmp_power; + + const JsonObject init_charge = jo.get_object( "charges_per_use" ); + init_charge.read( "range", charges_per_use ); + init_charge.read( "power", tmp_power ); + power_level += tmp_power; + + jo.read( "recharge_type", type ); + jo.read( "time", time ); +} + +relic_charge_info relic_charge_template::generate() const +{ + relic_charge_info ret; + ret.max_charges = rng( max_charges.first, max_charges.second ); + ret.charges_per_use = rng( charges_per_use.first, charges_per_use.second ); + ret.charges = std::min( rng( init_charges.first, init_charges.second ), ret.max_charges ); + ret.activation_time = rng( time.first, time.second ); + ret.type = type; + ret.power = power_level; + return ret; +} + +void relic_charge_info::deserialize( JsonIn &jsin ) +{ + load( jsin.get_object() ); +} + +void relic_charge_info::load( const JsonObject &jo ) +{ + jo.read( "charges", charges ); + jo.read( "charges_per_use", charges_per_use ); + jo.read( "max_charges", max_charges ); + jo.read( "recharge_type", type ); + jo.read( "last_charge", last_charge ); + jo.read( "time", activation_time ); +} + +void relic_charge_info::serialize( JsonOut &jsout ) const +{ + jsout.start_object(); + jsout.member( "charges", charges ); + jsout.member( "charges_per_use", charges_per_use ); + jsout.member( "max_charges", max_charges ); + jsout.member( "recharge_type", type ); + jsout.member( "last_charge", last_charge ); + jsout.member( "time", activation_time ); + jsout.end_object(); +} + void relic::load( const JsonObject &jo ) { if( jo.has_array( "active_effects" ) ) { @@ -179,8 +277,11 @@ void relic::load( const JsonObject &jo ) add_passive_effect( ench ); } } + jo.read( "charge_info", charge ); + if( jo.has_member( "charges_per_activation" ) ) { + charge.charges_per_use = jo.get_int( "charges_per_activation", 1 ); + } jo.read( "name", item_name_override ); - charges_per_activation = jo.get_int( "charges_per_activation", 1 ); moves = jo.get_int( "moves", 100 ); } @@ -195,7 +296,6 @@ void relic::serialize( JsonOut &jsout ) const jsout.start_object(); jsout.member( "moves", moves ); - jsout.member( "charges_per_activation", charges_per_activation ); // item_name_override is not saved, in case the original json text changes: // in such case names read back from a save wouold no longer be properly translated. @@ -217,16 +317,81 @@ void relic::serialize( JsonOut &jsout ) const jsout.end_array(); } + jsout.member( "charge_info", charge ); + jsout.end_object(); } -int relic::activate( Creature &caster, const tripoint &target ) const +int relic::activate( Creature &caster, const tripoint &target ) { + if( charge.charges_per_use != 0 && charges() - charge.charges_per_use < 0 ) { + caster.add_msg_if_player( m_bad, _( "This artifact lacks the charges to activate." ) ); + return 0; + } caster.moves -= moves; for( const fake_spell &sp : active_effects ) { sp.get_spell( sp.level ).cast_all_effects( caster, target ); } - return charges_per_activation; + charge.charges -= charge.charges_per_use; + return charge.charges_per_use; +} + +int relic::charges() const +{ + return charge.charges; +} + +int relic::charges_per_use() const +{ + return charge.charges_per_use; +} + +int relic::max_charges() const +{ + return charge.max_charges; +} + +// Adds num charges to the relic, as long as it doesn't exceed max_charges +static void add_charges( relic_charge_info &rel, int num = 1 ) +{ + if( rel.charges + num <= rel.max_charges ) { + rel.charges += num; + } +} + +void relic::try_recharge() +{ + if( charge.charges == charge.max_charges ) { + return; + } + switch( charge.type ) { + case relic_recharge::none: { + return; + } + case relic_recharge::periodic: { + if( calendar::turn - charge.last_charge >= charge.activation_time ) { + add_charges( charge ); + break; + } + return; + } + case relic_recharge::num: { + debugmsg( "Attempted to recharge relic with invalid recharge type" ); + return; + } + } + + charge.last_charge = calendar::turn; +} + +relic_charge_info::relic_charge_info() +{ + last_charge = calendar::turn; +} + +void relic::overwrite_charge( const relic_charge_info &info ) +{ + charge = info; } int relic::modify_value( const enchant_vals::mod value_type, const int value ) const @@ -266,6 +431,7 @@ int relic::power_level( const relic_procgen_id &ruleset ) const for( const fake_spell &sp : active_effects ) { total_power_level += ruleset->power_level( sp ); } + total_power_level += charge.power; return total_power_level; } @@ -453,6 +619,10 @@ relic relic_procgen_data::generate( const relic_procgen_data::generation_rules & } } } + const relic_charge_template *charge = charge_values.pick(); + if( charge != nullptr ) { + ret.overwrite_charge( charge->generate() ); + } return ret; } diff --git a/src/relic.h b/src/relic.h index 1e0aba90dee15..61daca4080f38 100644 --- a/src/relic.h +++ b/src/relic.h @@ -15,6 +15,8 @@ class JsonIn; class JsonObject; class JsonOut; class relic; +struct relic_charge_info; +struct relic_charge_template; class relic_procgen_data; struct tripoint; @@ -98,6 +100,7 @@ class relic_procgen_data }; private: + weighted_int_list charge_values; weighted_int_list> passive_add_procgen_values; weighted_int_list> passive_mult_procgen_values; weighted_int_list passive_hit_you; @@ -123,6 +126,47 @@ class relic_procgen_data void deserialize( JsonIn &jsin ); }; +enum class relic_recharge : int { + none, + periodic, + num +}; + +struct relic_charge_template { + std::pair max_charges; + std::pair init_charges; + std::pair charges_per_use; + std::pair time; + relic_recharge type; + + int power_level = 0; + + void deserialize( JsonIn &jsin ); + void load( const JsonObject &jo ); + relic_charge_info generate() const; +}; + +struct relic_charge_info { + + int charges = 0; + int charges_per_use = 0; + int max_charges = 0; + relic_recharge type = relic_recharge::num; + + time_point last_charge; + time_duration activation_time = 0_seconds; + + relic_charge_info(); + + // Because multiple different charge types can overlap, cache the power + // level from the charge type we were generated from here to avoid confusion + int power = 0; + + void deserialize( JsonIn &jsin ); + void load( const JsonObject &jo ); + void serialize( JsonOut &jsout ) const; +}; + class relic { private: @@ -132,13 +176,18 @@ class relic // the item's name will be replaced with this if the string is not empty translation item_name_override; - int charges_per_activation = 0; + relic_charge_info charge; + // activating an artifact overrides all spell casting costs int moves = 0; public: std::string name() const; // returns number of charges that should be consumed - int activate( Creature &caster, const tripoint &target ) const; + int activate( Creature &caster, const tripoint &target ); + int charges() const; + int charges_per_use() const; + int max_charges() const; + void try_recharge(); void load( const JsonObject &jo ); @@ -151,6 +200,7 @@ class relic std::vector get_enchantments() const; int modify_value( enchant_vals::mod value_type, int value ) const; + void overwrite_charge( const relic_charge_info &info ); // what is the power level of this artifact, given a specific ruleset int power_level( const relic_procgen_id &ruleset ) const; @@ -163,4 +213,9 @@ struct enum_traits { static constexpr relic_procgen_data::type last = relic_procgen_data::type::last; }; +template<> +struct enum_traits { + static constexpr relic_recharge last = relic_recharge::num; +}; + #endif // CATA_SRC_RELIC_H diff --git a/src/savegame.cpp b/src/savegame.cpp index 96a9cf0502094..78287a564d6cf 100644 --- a/src/savegame.cpp +++ b/src/savegame.cpp @@ -53,7 +53,7 @@ extern std::map> quick_shortcuts_map; * Changes that break backwards compatibility should bump this number, so the game can * load a legacy format loader. */ -const int savegame_version = 30; +const int savegame_version = 31; /* * This is a global set by detected version header in .sav, maps.txt, or overmap. diff --git a/src/savegame_json.cpp b/src/savegame_json.cpp index 724487154fcfc..cb0527bae35c7 100644 --- a/src/savegame_json.cpp +++ b/src/savegame_json.cpp @@ -91,6 +91,7 @@ #include "player_activity.h" #include "point.h" #include "profession.h" +#include "proficiency.h" #include "recipe.h" #include "recipe_dictionary.h" #include "requirements.h" @@ -504,8 +505,8 @@ void Character::load( const JsonObject &data ) if( !temp_selected_style.is_valid() ) { temp_selected_style = matype_id( "style_none" ); } - martial_arts_data = character_martial_arts( temp_styles, temp_selected_style, - temp_keep_hands_free ); + *martial_arts_data = character_martial_arts( temp_styles, temp_selected_style, + temp_keep_hands_free ); } else { data.read( "martial_arts_data", martial_arts_data ); } @@ -547,9 +548,14 @@ void Character::load( const JsonObject &data ) // Remove check after 0.F if( savegame_loading_version >= 30 ) { - data.read( "proficiencies", _proficiencies ); + if( data.has_array( "proficiencies" ) ) { + _proficiencies->deserialize_legacy( data.get_array( "proficiencies" ) ); + } else { + data.read( "proficiencies", _proficiencies ); + } } + //energy data.read( "stim", stim ); data.read( "stamina", stamina ); @@ -754,10 +760,10 @@ void Character::load( const JsonObject &data ) set_part_frostbite_timer( bodypart_id( "foot_r" ), frostbite_timer[11] ); } - inv.clear(); + inv->clear(); if( data.has_member( "inv" ) ) { JsonIn *invin = data.get_raw( "inv" ); - inv.json_load_items( *invin ); + inv->json_load_items( *invin ); } // this is after inventory is loaded to make it more obvious that // it needs to be changed again when Character::i_at is removed for nested containers @@ -1009,7 +1015,7 @@ void player::store( JsonOut &json ) const json.member( "worn", worn ); // also saves contents json.member( "inv" ); - inv.json_save_items( json ); + inv->json_save_items( json ); if( !weapon.is_null() ) { json.member( "weapon", weapon ); // also saves contents @@ -1197,7 +1203,7 @@ void avatar::store( JsonOut &json ) const json.member( "assigned_invlet" ); json.start_array(); - for( const auto &iter : inv.assigned_invlet ) { + for( const auto &iter : inv->assigned_invlet ) { json.start_array(); json.write( iter.first ); json.write( iter.second ); @@ -1206,7 +1212,7 @@ void avatar::store( JsonOut &json ) const json.end_array(); json.member( "invcache" ); - inv.json_save_invcache( json ); + inv->json_save_invcache( json ); json.member( "calorie_diary", calorie_diary ); } @@ -1349,13 +1355,13 @@ void avatar::load( const JsonObject &data ) data.read( "show_map_memory", show_map_memory ); for( JsonArray pair : data.get_array( "assigned_invlet" ) ) { - inv.assigned_invlet[static_cast( pair.get_int( 0 ) )] = + inv->assigned_invlet[static_cast( pair.get_int( 0 ) )] = itype_id( pair.get_string( 1 ) ); } if( data.has_member( "invcache" ) ) { JsonIn *jip = data.get_raw( "invcache" ); - inv.json_load_invcache( *jip ); + inv->json_load_invcache( *jip ); } data.read( "calorie_diary", calorie_diary ); @@ -3211,16 +3217,7 @@ void Creature::store( JsonOut &jsout ) const // killer is not stored, it's temporary anyway, any creature that has a non-null // killer is dead (as per definition) and should not be stored. - // Because JSON requires string keys we need to convert our int keys - std::unordered_map> tmp_map; - for( const auto &maps : *effects ) { - for( const auto i : maps.second ) { - std::ostringstream convert; - convert << i.first; - tmp_map[maps.first.str()][convert.str()] = i.second; - } - } - jsout.member( "effects", tmp_map ); + jsout.member( "effects", *effects ); jsout.member( "damage_over_time_map", damage_over_time_map ); jsout.member( "values", values ); @@ -3262,9 +3259,8 @@ void Creature::load( const JsonObject &jsin ) killer = nullptr; // see Creature::load - // Just too many changes here to maintain compatibility, so older characters get a free - // effects wipe. Since most long lasting effects are bad, this shouldn't be too bad for them. - if( savegame_loading_version >= 23 ) { + // TEMPORARY until 0.F + if( savegame_loading_version < 31 ) { if( jsin.has_object( "effects" ) ) { // Because JSON requires string keys we need to convert back to our bp keys std::unordered_map> tmp_map; @@ -3280,7 +3276,7 @@ void Creature::load( const JsonObject &jsin ) if( !( std::istringstream( i.first ) >> key_num ) ) { key_num = 0; } - const body_part bp = static_cast( key_num ); + const bodypart_str_id &bp = convert_bp( static_cast( key_num ) ); const effect &e = i.second; ( *effects )[id][bp] = e; @@ -3288,6 +3284,8 @@ void Creature::load( const JsonObject &jsin ) } } } + } else { + jsin.read( "effects", *effects ); } jsin.read( "values", values ); diff --git a/src/sdltiles.cpp b/src/sdltiles.cpp index d2bb66f5c4866..4471868754c3d 100644 --- a/src/sdltiles.cpp +++ b/src/sdltiles.cpp @@ -1,7 +1,8 @@ -#if defined(TILES) - #include "cursesdef.h" // IWYU pragma: associated #include "sdltiles.h" // IWYU pragma: associated +#include "cuboid_rectangle.h" + +#if defined(TILES) #include #include @@ -4114,3 +4115,10 @@ HWND getWindowHandle() #endif #endif // TILES + +bool window_contains_point_relative( const catacurses::window &win, const point &p ) +{ + const point bound = point( catacurses::getmaxx( win ), catacurses::getmaxy( win ) ); + const half_open_rectangle win_bounds( point_zero, bound ); + return win_bounds.contains( p ); +} diff --git a/src/sdltiles.h b/src/sdltiles.h index 603953912416a..ebe3d5018eae2 100644 --- a/src/sdltiles.h +++ b/src/sdltiles.h @@ -3,13 +3,19 @@ #define CATA_SRC_SDLTILES_H #include +#include "point.h" + +namespace catacurses +{ +class window; +} // namespace catacurses + #if defined(TILES) #include #include #include "color_loader.h" -#include "point.h" #include "sdl_wrappers.h" class cata_tiles; @@ -41,4 +47,6 @@ window_dimensions get_window_dimensions( const point &pos, const point &size ); #endif // TILES +// Text level, valid only for a point relative to the window, not a point in overall space. +bool window_contains_point_relative( const catacurses::window &win, const point &p ); #endif // CATA_SRC_SDLTILES_H diff --git a/src/start_location.cpp b/src/start_location.cpp index 5e504c59d78ed..aa86d285945d1 100644 --- a/src/start_location.cpp +++ b/src/start_location.cpp @@ -208,7 +208,8 @@ tripoint_abs_omt start_location::find_player_initial_location() const } } // Should never happen, if it does we messed up. - popup( _( "Unable to generate a valid starting location, please report this failure." ) ); + popup( _( "Unable to generate a valid starting location %s [%s] in a radius of %d overmaps, please report this failure." ), + name(), id.str(), radius ); return overmap::invalid_tripoint; } diff --git a/src/suffer.cpp b/src/suffer.cpp index be7fdaf2460d7..9c09fa935aeaa 100644 --- a/src/suffer.cpp +++ b/src/suffer.cpp @@ -303,9 +303,9 @@ void Character::suffer_while_awake( const int current_stim ) if( !has_trait( trait_DEBUG_STORAGE ) && ( weight_carried() > 4 * weight_capacity() ) ) { if( has_effect( effect_downed ) ) { - add_effect( effect_downed, 1_turns, num_bp, false, 0, true ); + add_effect( effect_downed, 1_turns, false, 0, true ); } else { - add_effect( effect_downed, 2_turns, num_bp, false, 0, true ); + add_effect( effect_downed, 2_turns, false, 0, true ); } } if( has_trait( trait_CHEMIMBALANCE ) ) { @@ -456,7 +456,7 @@ void Character::suffer_from_schizophrenia() const translation snip = SNIPPET.random_from_category( "schizo_formication" ).value_or( translation() ); body_part bp = random_body_part( true ); - add_effect( effect_formication, 45_minutes, bp ); + add_effect( effect_formication, 45_minutes, convert_bp( bp ).id() ); add_msg_if_player( m_bad, "%s", snip ); return; } @@ -1246,7 +1246,7 @@ void Character::suffer_from_bad_bionics() _( "Your malfunctioning bionic causes you to spasm and fall to the floor!" ) ); mod_pain( 1 ); add_effect( effect_stunned, 1_turns ); - add_effect( effect_downed, 1_turns, num_bp, false, 0, true ); + add_effect( effect_downed, 1_turns, false, 0, true ); sfx::play_variant_sound( "bionics", "elec_crackle_high", 100 ); } if( has_bionic( bio_shakes ) && get_power_level() > 24_kJ && one_turn_in( 2_hours ) ) { @@ -1265,7 +1265,7 @@ void Character::suffer_from_bad_bionics() !has_effect( effect_narcosis ) ) { add_msg_if_player( m_bad, _( "Your malfunctioning bionic itches!" ) ); body_part bp = random_body_part( true ); - add_effect( effect_formication, 10_minutes, bp ); + add_effect( effect_formication, 10_minutes, convert_bp( bp ).id() ); } if( has_bionic( bio_glowy ) && !has_effect( effect_glowy_led ) && one_turn_in( 50_minutes ) && get_power_level() > 1_kJ ) { @@ -1467,7 +1467,7 @@ void Character::suffer() // TODO: Remove this section and encapsulate hp_cur for( const std::pair &elem : get_body() ) { if( elem.second.get_hp_cur() <= 0 ) { - add_effect( effect_disabled, 1_turns, elem.first->token, true ); + add_effect( effect_disabled, 1_turns, elem.first.id(), true ); get_event_bus().send( getID(), elem.first->token ); } } @@ -1572,7 +1572,7 @@ bool Character::irradiate( float rads, bool bypass ) it->irradiation += delta; // If in inventory (not worn), don't print anything. - if( inv.has_item( *it ) ) { + if( inv->has_item( *it ) ) { continue; } @@ -1677,9 +1677,9 @@ void Character::mend( int rate_multiplier ) } const time_duration dur_inc = 1_turns * roll_remainder( rate_multiplier * healing_factor ); - auto &eff = get_effect( effect_mending, bp->token ); + auto &eff = get_effect( effect_mending, bp ); if( eff.is_null() ) { - add_effect( effect_mending, dur_inc, bp->token, true ); + add_effect( effect_mending, dur_inc, bp, true ); continue; } @@ -1687,7 +1687,7 @@ void Character::mend( int rate_multiplier ) if( eff.get_duration() >= eff.get_max_duration() ) { set_part_hp_cur( bp, 1 ); - remove_effect( effect_mending, bp->token ); + remove_effect( effect_mending, bp ); get_event_bus().send( getID(), bp->token ); //~ %s is bodypart add_msg_if_player( m_good, _( "Your %s has started to mend!" ), @@ -1959,6 +1959,6 @@ int Character::addiction_level( add_type type ) const int Character::leak_level( const std::string &flag ) const { int leak_level = 0; - leak_level = inv.leak_level( flag ); + leak_level = inv->leak_level( flag ); return leak_level; } diff --git a/src/talker.h b/src/talker.h index c942cbe6bcf78..14910fb604343 100644 --- a/src/talker.h +++ b/src/talker.h @@ -114,12 +114,21 @@ class talker virtual bool knows_spell( const spell_id & ) const { return false; } + virtual bool knows_proficiency( const proficiency_id & ) const { + return false; + } virtual std::vector skills_offered_to( const talker & ) const { return {}; } virtual std::string skill_training_text( const talker &, const skill_id & ) const { return {}; } + virtual std::vector proficiencies_offered_to( const talker & ) const { + return {}; + } + virtual std::string proficiency_training_text( const talker &, const proficiency_id & ) const { + return {}; + } virtual std::vector styles_offered_to( const talker & ) const { return {}; } @@ -133,7 +142,7 @@ class talker return {}; } virtual void store_chosen_training( const skill_id &, const matype_id &, - const spell_id & ) { + const spell_id &, const proficiency_id & ) { } // effects and values diff --git a/src/talker_avatar.cpp b/src/talker_avatar.cpp index e552e18ee06b4..c7f9d526c32b3 100644 --- a/src/talker_avatar.cpp +++ b/src/talker_avatar.cpp @@ -107,10 +107,10 @@ void talker_avatar::buy_monster( talker &seller, const mtype_id &mtype, int cost monster &tmp = *mon_ptr; // Our monster is always a pet. tmp.friendly = -1; - tmp.add_effect( effect_pet, 1_turns, num_bp, true ); + tmp.add_effect( effect_pet, 1_turns, true ); if( pacified ) { - tmp.add_effect( effect_pacified, 1_turns, num_bp, true ); + tmp.add_effect( effect_pacified, 1_turns, true ); } if( !name.empty() ) { diff --git a/src/talker_character.cpp b/src/talker_character.cpp index dc2d40eebc151..28bc7074689ab 100644 --- a/src/talker_character.cpp +++ b/src/talker_character.cpp @@ -122,7 +122,7 @@ bool talker_character::has_bionic( const bionic_id &bionics_id ) const bool talker_character::knows_spell( const spell_id &sp ) const { - return me_chr->magic.knows_spell( sp ); + return me_chr->magic->knows_spell( sp ); } int talker_character::get_skill_level( const skill_id &skill ) const @@ -130,6 +130,11 @@ int talker_character::get_skill_level( const skill_id &skill ) const return me_chr->get_skill_level( skill ); } +bool talker_character::knows_proficiency( const proficiency_id &proficiency ) const +{ + return me_chr->has_proficiency( proficiency ); +} + bool talker_character::has_effect( const efftype_id &effect_id ) const { return me_chr->has_effect( effect_id ); @@ -138,12 +143,12 @@ bool talker_character::has_effect( const efftype_id &effect_id ) const void talker_character::add_effect( const efftype_id &new_effect, const time_duration &dur, bool permanent ) { - me_chr->add_effect( new_effect, dur, num_bp, permanent ); + me_chr->add_effect( new_effect, dur, permanent ); } void talker_character::remove_effect( const efftype_id &old_effect ) { - me_chr->remove_effect( old_effect, num_bp ); + me_chr->remove_effect( old_effect ); } std::string talker_character:: get_value( const std::string &var_name ) const diff --git a/src/talker_character.h b/src/talker_character.h index 06dcdc64ded16..fb574ce6afd6b 100644 --- a/src/talker_character.h +++ b/src/talker_character.h @@ -56,6 +56,7 @@ class talker_character: public talker bool has_bionic( const bionic_id &bionics_id ) const override; bool knows_spell( const spell_id &sp ) const override; int get_skill_level( const skill_id &skill ) const override; + bool knows_proficiency( const proficiency_id &proficiency ) const override; // effects and values bool has_effect( const efftype_id &effect_id ) const override; diff --git a/src/talker_npc.cpp b/src/talker_npc.cpp index e70f88e9777b1..7585a067eb9ab 100644 --- a/src/talker_npc.cpp +++ b/src/talker_npc.cpp @@ -12,12 +12,14 @@ #include "mission.h" #include "mission_companion.h" #include "player.h" +#include "proficiency.h" #include "npc.h" #include "npctalk.h" #include "npctrade.h" #include "skill.h" #include "talker_npc.h" #include "talker_character.h" +#include "units_utility.h" class Character; @@ -265,6 +267,40 @@ std::string talker_npc::skill_training_text( const talker &student, cur_level_exercise, next_level, next_level_exercise, cost / 100 ); } +std::vector talker_npc::proficiencies_offered_to( const talker &student ) const +{ + if( student.get_character() ) { + return me_npc->proficiencies_offered_to( *student.get_character() ); + } else { + return {}; + } +} + +std::string talker_npc::proficiency_training_text( const talker &student, + const proficiency_id &proficiency ) const +{ + const Character *pupil = student.get_character(); + if( !pupil ) { + return ""; + } + const time_duration time_needed = proficiency->time_to_learn(); + const time_duration current_time = time_needed - pupil->proficiency_training_needed( proficiency ); + + const int cost = calc_proficiency_training_cost( *me_npc, proficiency ); + const std::string name = proficiency->name(); + const float pct_before = current_time / time_needed * 100; + const float pct_after = ( current_time + 15_minutes ) / time_needed * 100; + const std::string after_str = pct_after >= 100.0f ? pgettext( "NPC training: proficiency learned", + "done" ) : string_format( "%2.0f%%", pct_after ); + + if( cost > 0 ) { + //~ Proficiency name: (current_practice) -> (next_practice) (cost in dollars) + return string_format( _( "%s: (%2.0f%%) -> (%s) (cost $%d)" ), name, pct_before, after_str, cost ); + } + //~ Proficiency name: (current_practice) -> (next_practice) + return string_format( _( "%s: (%2.0f%%) -> (%s)" ), name, pct_before, after_str ); +} + std::vector talker_npc::styles_offered_to( const talker &student ) const { if( student.get_character() ) { @@ -301,8 +337,8 @@ std::string talker_npc::spell_training_text( talker &student, const spell_id &sp if( !pupil ) { return ""; } - const spell &temp_spell = me_npc->magic.get_spell( sp ); - const bool knows = pupil->magic.knows_spell( sp ); + const spell &temp_spell = me_npc->magic->get_spell( sp ); + const bool knows = pupil->magic->knows_spell( sp ); const int cost = me_npc->calc_spell_training_cost( knows, temp_spell.get_difficulty(), temp_spell.get_level() ); std::string text; @@ -317,9 +353,9 @@ std::string talker_npc::spell_training_text( talker &student, const spell_id &sp } void talker_npc::store_chosen_training( const skill_id &c_skill, const matype_id &c_style, - const spell_id &c_spell ) + const spell_id &c_spell, const proficiency_id &c_proficiency ) { - me_npc->chatbin.store_chosen_training( c_skill, c_style, c_spell ); + me_npc->chatbin.store_chosen_training( c_skill, c_style, c_spell, c_proficiency ); } int talker_npc::debt() const diff --git a/src/talker_npc.h b/src/talker_npc.h index 0eba9cb4bb059..9edab35b14de6 100644 --- a/src/talker_npc.h +++ b/src/talker_npc.h @@ -44,15 +44,18 @@ class talker_npc : public talker_character int parse_mod( const std::string &attribute, int factor ) const override; int trial_chance_mod( const std::string &trial_type ) const override; - // stats, skills, traits, bionics, and magic + // stats, skills, traits, bionics, magic, and proficiencies std::vector skills_offered_to( const talker &student ) const override; std::string skill_training_text( const talker &, const skill_id & ) const override; + std::vector proficiencies_offered_to( const talker &student ) const override; + std::string proficiency_training_text( const talker &student, + const proficiency_id &proficiency ) const override; std::vector styles_offered_to( const talker &student ) const override; std::string style_training_text( const talker &, const matype_id & ) const override; std::vector spells_offered_to( talker &student ) override; std::string spell_training_text( talker &, const spell_id & ) override; void store_chosen_training( const skill_id &c_skill, const matype_id &c_style, - const spell_id &c_spell ) override; + const spell_id &c_spell, const proficiency_id &c_proficiency ) override; // inventory, buying, and selling void add_debt( int cost ) override; diff --git a/src/teleport.cpp b/src/teleport.cpp index 2a06bbb26ed38..f65641534e6cf 100644 --- a/src/teleport.cpp +++ b/src/teleport.cpp @@ -89,7 +89,7 @@ bool teleport::teleport( Creature &critter, int min_distance, int max_distance, poor_soul->disp_name() ); get_event_bus().send( p->getID(), poor_soul->get_name() ); } else { - if( get_player_character().sees( *poor_soul ) ) { + if( get_player_view().sees( *poor_soul ) ) { add_msg( m_good, _( "%1$s teleports into %2$s, killing them!" ), critter.disp_name(), poor_soul->disp_name() ); } diff --git a/src/trapfunc.cpp b/src/trapfunc.cpp index f5c9192c86a05..2f2cb94781de7 100644 --- a/src/trapfunc.cpp +++ b/src/trapfunc.cpp @@ -160,7 +160,7 @@ bool trapfunc::beartrap( const tripoint &p, Creature *c, item * ) add_msg( m_warning, _( "Your %s is caught by a beartrap!" ), c->get_name() ); } // Actual effects - c->add_effect( effect_beartrap, 1_turns, hit->token, true ); + c->add_effect( effect_beartrap, 1_turns, hit, true ); damage_instance d; d.add_damage( DT_BASH, 12 ); d.add_damage( DT_CUT, 18 ); @@ -169,10 +169,10 @@ bool trapfunc::beartrap( const tripoint &p, Creature *c, item * ) player *n = dynamic_cast( c ); if( n != nullptr ) { if( ( n->has_trait( trait_INFRESIST ) ) && ( one_in( 512 ) ) ) { - n->add_effect( effect_tetanus, 1_turns, num_bp, true ); + n->add_effect( effect_tetanus, 1_turns, true ); } else if( ( !n->has_trait( trait_INFIMMUNE ) || !n->has_trait( trait_INFRESIST ) ) && ( one_in( 128 ) ) ) { - n->add_effect( effect_tetanus, 1_turns, num_bp, true ); + n->add_effect( effect_tetanus, 1_turns, true ); } } c->check_dead_state(); @@ -208,10 +208,10 @@ bool trapfunc::board( const tripoint &, Creature *c, item * ) c->deal_damage( nullptr, bodypart_id( "foot_l" ), damage_instance( DT_CUT, rng( 6, 10 ) ) ); c->deal_damage( nullptr, bodypart_id( "foot_r" ), damage_instance( DT_CUT, rng( 6, 10 ) ) ); if( ( n->has_trait( trait_INFRESIST ) ) && ( one_in( 256 ) ) ) { - n->add_effect( effect_tetanus, 1_turns, num_bp, true ); + n->add_effect( effect_tetanus, 1_turns, true ); } else if( ( !n->has_trait( trait_INFIMMUNE ) || !n->has_trait( trait_INFRESIST ) ) && ( one_in( 35 ) ) ) { - n->add_effect( effect_tetanus, 1_turns, num_bp, true ); + n->add_effect( effect_tetanus, 1_turns, true ); } } c->check_dead_state(); @@ -268,7 +268,7 @@ bool trapfunc::caltrops_glass( const tripoint &p, Creature *c, item * ) c->deal_damage( nullptr, bodypart_id( "foot_r" ), damage_instance( DT_CUT, rng( 9, 30 ) ) ); } c->check_dead_state(); - if( get_player_character().sees( p ) ) { + if( get_player_view().sees( p ) ) { add_msg( _( "The shards shatter!" ) ); sounds::sound( p, 8, sounds::sound_t::combat, _( "glass cracking!" ), false, "trap", "glass_caltrops" ); @@ -391,7 +391,7 @@ bool trapfunc::crossbow( const tripoint &p, Creature *c, item * ) _( " dodges the shot!" ) ); } } else if( z != nullptr ) { - bool seen = get_player_character().sees( *z ); + bool seen = get_player_view().sees( *z ); int chance = 0; // adapted from shotgun code - chance of getting hit depends on size switch( z->type->size ) { @@ -492,7 +492,7 @@ bool trapfunc::shotgun( const tripoint &p, Creature *c, item * ) _( " dodges the shot!" ) ); } } else if( z != nullptr ) { - bool seen = get_player_character().sees( *z ); + bool seen = get_player_view().sees( *z ); int chance = 0; switch( z->type->size ) { case creature_size::tiny: @@ -565,7 +565,7 @@ bool trapfunc::snare_light( const tripoint &p, Creature *c, item * ) _( "A snare closes on s leg." ) ); // Actual effects - c->add_effect( effect_lightsnare, 1_turns, hit->token, true ); + c->add_effect( effect_lightsnare, 1_turns, hit, true ); monster *z = dynamic_cast( c ); if( z != nullptr && z->type->size == creature_size::tiny ) { z->deal_damage( nullptr, hit, damage_instance( DT_BASH, 10 ) ); @@ -591,7 +591,7 @@ bool trapfunc::snare_heavy( const tripoint &p, Creature *c, item * ) _( "A snare closes on s %s." ), body_part_name_accusative( hit ) ); // Actual effects - c->add_effect( effect_heavysnare, 1_turns, hit->token, true ); + c->add_effect( effect_heavysnare, 1_turns, hit, true ); monster *z = dynamic_cast( c ); player *n = dynamic_cast( c ); if( n != nullptr ) { @@ -653,9 +653,7 @@ bool trapfunc::telepad( const tripoint &p, Creature *c, item * ) if( c->is_avatar() ) { c->add_msg_if_player( m_warning, _( "The air shimmers around you…" ) ); } else { - if( get_player_character().sees( p ) ) { - add_msg( _( "The air shimmers around %s…" ), c->disp_name() ); - } + add_msg_if_player_sees( p, _( "The air shimmers around %s…" ), c->disp_name() ); } teleport::teleport( *c ); return false; @@ -672,8 +670,8 @@ bool trapfunc::goo( const tripoint &p, Creature *c, item * ) monster *z = dynamic_cast( c ); player *n = dynamic_cast( c ); if( n != nullptr ) { - n->add_env_effect( effect_slimed, bp_foot_l, 6, 2_minutes ); - n->add_env_effect( effect_slimed, bp_foot_r, 6, 2_minutes ); + n->add_env_effect( effect_slimed, bodypart_id( "foot_l" ), 6, 2_minutes ); + n->add_env_effect( effect_slimed, bodypart_id( "foot_r" ), 6, 2_minutes ); if( one_in( 3 ) ) { n->add_msg_if_player( m_bad, _( "The acidic goo eats away at your feet." ) ); n->deal_damage( nullptr, bodypart_id( "foot_l" ), damage_instance( DT_CUT, 5 ) ); @@ -709,7 +707,7 @@ bool trapfunc::dissector( const tripoint &p, Creature *c, item * ) return false; } monster *z = dynamic_cast( c ); - bool player_sees = get_player_character().sees( p ); + bool player_sees = get_player_view().sees( p ); if( z != nullptr ) { if( z->type->in_species( species_ROBOT ) ) { //The monster is a robot. So the dissector should not try to dissect the monsters flesh. @@ -772,7 +770,7 @@ bool trapfunc::pit( const tripoint &p, Creature *c, item * ) } const float eff = pit_effectiveness( p ); c->add_msg_player_or_npc( m_bad, _( "You fall in a pit!" ), _( " falls in a pit!" ) ); - c->add_effect( effect_in_pit, 1_turns, num_bp, true ); + c->add_effect( effect_in_pit, 1_turns, true ); monster *z = dynamic_cast( c ); player *n = dynamic_cast( c ); if( n != nullptr ) { @@ -819,7 +817,7 @@ bool trapfunc::pit_spikes( const tripoint &p, Creature *c, item * ) } c->add_msg_player_or_npc( m_bad, _( "You fall in a spiked pit!" ), _( " falls in a spiked pit!" ) ); - c->add_effect( effect_in_pit, 1_turns, num_bp, true ); + c->add_effect( effect_in_pit, 1_turns, true ); monster *z = dynamic_cast( c ); player *n = dynamic_cast( c ); Character &player_character = get_player_character(); @@ -863,10 +861,10 @@ bool trapfunc::pit_spikes( const tripoint &p, Creature *c, item * ) body_part_name_accusative( hit ) ); n->deal_damage( nullptr, hit, damage_instance( DT_CUT, damage ) ); if( ( n->has_trait( trait_INFRESIST ) ) && ( one_in( 256 ) ) ) { - n->add_effect( effect_tetanus, 1_turns, num_bp, true ); + n->add_effect( effect_tetanus, 1_turns, true ); } else if( ( !n->has_trait( trait_INFIMMUNE ) || !n->has_trait( trait_INFRESIST ) ) && ( one_in( 35 ) ) ) { - n->add_effect( effect_tetanus, 1_turns, num_bp, true ); + n->add_effect( effect_tetanus, 1_turns, true ); } } } else if( z != nullptr ) { @@ -878,9 +876,7 @@ bool trapfunc::pit_spikes( const tripoint &p, Creature *c, item * ) } c->check_dead_state(); if( one_in( 4 ) ) { - if( player_character.sees( p ) ) { - add_msg( _( "The spears break!" ) ); - } + add_msg_if_player_sees( p, _( "The spears break!" ) ); map &here = get_map(); here.ter_set( p, t_pit ); // 4 spears to a pit @@ -904,7 +900,7 @@ bool trapfunc::pit_glass( const tripoint &p, Creature *c, item * ) } c->add_msg_player_or_npc( m_bad, _( "You fall in a pit filled with glass shards!" ), _( " falls in pit filled with glass shards!" ) ); - c->add_effect( effect_in_pit, 1_turns, num_bp, true ); + c->add_effect( effect_in_pit, 1_turns, true ); monster *z = dynamic_cast( c ); player *n = dynamic_cast( c ); Character &player_character = get_player_character(); @@ -952,10 +948,10 @@ bool trapfunc::pit_glass( const tripoint &p, Creature *c, item * ) body_part_name_accusative( hit ) ); n->deal_damage( nullptr, hit, damage_instance( DT_CUT, damage ) ); if( ( n->has_trait( trait_INFRESIST ) ) && ( one_in( 256 ) ) ) { - n->add_effect( effect_tetanus, 1_turns, num_bp, true ); + n->add_effect( effect_tetanus, 1_turns, true ); } else if( ( !n->has_trait( trait_INFIMMUNE ) || !n->has_trait( trait_INFRESIST ) ) && ( one_in( 35 ) ) ) { - n->add_effect( effect_tetanus, 1_turns, num_bp, true ); + n->add_effect( effect_tetanus, 1_turns, true ); } } } else if( z != nullptr ) { @@ -967,9 +963,7 @@ bool trapfunc::pit_glass( const tripoint &p, Creature *c, item * ) } c->check_dead_state(); if( one_in( 5 ) ) { - if( player_character.sees( p ) ) { - add_msg( _( "The shards shatter!" ) ); - } + add_msg_if_player_sees( p, _( "The shards shatter!" ) ); map &here = get_map(); here.ter_set( p, t_pit ); // 20 shards in a pit. diff --git a/src/turret.cpp b/src/turret.cpp index 77c1760dc98a5..6d008fccfe1e5 100644 --- a/src/turret.cpp +++ b/src/turret.cpp @@ -620,8 +620,8 @@ int vehicle::automatic_fire_turret( vehicle_part &pt ) shots = gun.fire( cpu, targ ); - if( shots && u_see && !player_character.sees( targ ) ) { - add_msg( _( "The %1$s fires its %2$s!" ), name, pt.name() ); + if( shots && u_see ) { + add_msg_if_player_sees( targ, _( "The %1$s fires its %2$s!" ), name, pt.name() ); } return shots; diff --git a/src/ui.cpp b/src/ui.cpp index e245da9aa371f..7163f55e7146c 100644 --- a/src/ui.cpp +++ b/src/ui.cpp @@ -19,6 +19,7 @@ #include "string_input_popup.h" #include "translations.h" #include "ui_manager.h" +#include "sdltiles.h" #if defined(__ANDROID__) #include @@ -611,8 +612,11 @@ void uilist::show() // to be used. const auto entry = utf8_wrapper( ei == selected ? remove_color_tags( entries[ ei ].txt ) : entries[ ei ].txt ); - trim_and_print( window, point( pad_left + 4, estart + si ), - max_entry_len, co, "%s", entry.c_str() ); + int x = pad_left + 4; + int y = estart + si; + entries[ei].drawn_rect.p_min = point( x, y ); + entries[ei].drawn_rect.p_max = point( x + max_entry_len - 1, y ); + trim_and_print( window, point( x, y ), max_entry_len, co, "%s", entry.c_str() ); if( max_column_len && !entries[ ei ].ctxt.empty() ) { const auto centry = utf8_wrapper( ei == selected ? remove_color_tags( entries[ ei ].ctxt ) : @@ -788,6 +792,7 @@ void uilist::query( bool loop, int timeout ) if( allow_cancel ) { ctxt.register_action( "QUIT" ); } + ctxt.register_action( "SELECT" ); ctxt.register_action( "CONFIRM" ); ctxt.register_action( "FILTER" ); ctxt.register_action( "ANY_INPUT" ); @@ -829,6 +834,18 @@ void uilist::query( bool loop, int timeout ) if( callback != nullptr ) { callback->select( this ); } + } else if( !fentries.empty() && ret_act == "SELECT" ) { + cata::optional p = ctxt.get_coordinates_text( window ); + if( p ) { + if( window_contains_point_relative( window, p.value() ) ) { + uilist_entry *entry = find_entry_by_coordinate( p.value() ); + if( entry != nullptr ) { + if( entry->enabled ) { + ret = entry->retval; + } + } + } + } } else if( !fentries.empty() && ret_act == "CONFIRM" ) { if( entries[ selected ].enabled ) { ret = entries[ selected ].retval; // valid @@ -859,6 +876,17 @@ void uilist::query( bool loop, int timeout ) } while( loop && ret == UILIST_WAIT_INPUT ); } +uilist_entry *uilist::find_entry_by_coordinate( const point &p ) +{ + for( int i : fentries ) { + uilist_entry &entry = entries[i]; + if( entry.drawn_rect.contains( p ) ) { + return &entry; + } + } + return nullptr; +} + ///@} /** * cleanup @@ -958,4 +986,3 @@ void pointmenu_cb::select( uilist *const menu ) { impl->select( menu ); } - diff --git a/src/ui.h b/src/ui.h index 91c7b5dcc5c87..0eb6805f5be1e 100644 --- a/src/ui.h +++ b/src/ui.h @@ -11,11 +11,13 @@ #include #include "color.h" +#include "cuboid_rectangle.h" #include "cursesdef.h" #include "memory_fast.h" #include "pimpl.h" #include "point.h" #include "string_formatter.h" +#include "input.h" class translation; @@ -96,6 +98,8 @@ struct uilist_entry { uilist_entry( Enum e, Args && ... args ) : uilist_entry( static_cast( e ), std::forward( args )... ) {} + + inclusive_rectangle drawn_rect; }; /** @@ -338,13 +342,14 @@ class uilist // NOLINT(cata-xy) bool started = false; + uilist_entry *find_entry_by_coordinate( const point &p ); + public: // Results // TODO change to getters std::string ret_act; int ret = 0; int keypress = 0; - int selected = 0; }; diff --git a/src/units.h b/src/units.h index 32dd9c55d3d8a..5d7b3633989bd 100644 --- a/src/units.h +++ b/src/units.h @@ -2,6 +2,8 @@ #ifndef CATA_SRC_UNITS_H #define CATA_SRC_UNITS_H +#include "units_fwd.h" + #include #include #include @@ -278,12 +280,6 @@ operator%=( quantity &lhs, const quantity &rhs ) } /**@}*/ -class volume_in_milliliter_tag -{ -}; - -using volume = quantity; - const volume volume_min = units::volume( std::numeric_limits::min(), units::volume::unit_type{} ); @@ -318,12 +314,6 @@ inline constexpr double to_liter( const volume &v ) // Don't use in new code! Use one of the from_* functions instead. static constexpr volume legacy_volume_factor = from_milliliter( 250 ); -class mass_in_milligram_tag -{ -}; - -using mass = quantity; - const mass mass_min = units::mass( std::numeric_limits::min(), units::mass::unit_type{} ); @@ -368,12 +358,6 @@ inline constexpr double to_kilogram( const mass &v ) return v.value() / 1000000.0; } -class energy_in_millijoule_tag -{ -}; - -using energy = quantity; - const energy energy_min = units::energy( std::numeric_limits::min(), units::energy::unit_type{} ); @@ -426,12 +410,6 @@ inline constexpr value_type to_kilojoule( const quantity; - const money money_min = units::money( std::numeric_limits::min(), units::money::unit_type{} ); @@ -475,12 +453,6 @@ inline constexpr value_type to_kusd( const quantity; - const length length_min = units::length( std::numeric_limits::min(), units::length::unit_type{} ); diff --git a/src/units_fwd.h b/src/units_fwd.h new file mode 100644 index 0000000000000..dade6ab488254 --- /dev/null +++ b/src/units_fwd.h @@ -0,0 +1,45 @@ +#pragma once +#ifndef CATA_SRC_UNITS_FWD_H +#define CATA_SRC_UNITS_FWD_H + +#include + +namespace units +{ + +template +class quantity; + +class volume_in_milliliter_tag +{ +}; + +using volume = quantity; + +class mass_in_milligram_tag +{ +}; + +using mass = quantity; + +class energy_in_millijoule_tag +{ +}; + +using energy = quantity; + +class money_in_cent_tag +{ +}; + +using money = quantity; + +class length_in_millimeter_tag +{ +}; + +using length = quantity; + +} // namespace units + +#endif diff --git a/src/units_utility.cpp b/src/units_utility.cpp new file mode 100644 index 0000000000000..a251c1850cf91 --- /dev/null +++ b/src/units_utility.cpp @@ -0,0 +1,181 @@ +#include "units_utility.h" + +#include "cata_utility.h" +#include "options.h" + +const char *weight_units() +{ + return get_option( "USE_METRIC_WEIGHTS" ) == "lbs" ? _( "lbs" ) : _( "kg" ); +} + +const char *volume_units_abbr() +{ + const std::string vol_units = get_option( "VOLUME_UNITS" ); + if( vol_units == "c" ) { + return pgettext( "Volume unit", "c" ); + } else if( vol_units == "l" ) { + return pgettext( "Volume unit", "L" ); + } else { + return pgettext( "Volume unit", "qt" ); + } +} + +const char *volume_units_long() +{ + const std::string vol_units = get_option( "VOLUME_UNITS" ); + if( vol_units == "c" ) { + return _( "cup" ); + } else if( vol_units == "l" ) { + return _( "liter" ); + } else { + return _( "quart" ); + } +} + +double convert_velocity( int velocity, const units_type vel_units ) +{ + const std::string type = get_option( "USE_METRIC_SPEEDS" ); + // internal units to mph conversion + double ret = static_cast( velocity ) / 100; + + if( type == "km/h" ) { + switch( vel_units ) { + case VU_VEHICLE: + // mph to km/h conversion + ret *= 1.609f; + break; + case VU_WIND: + // mph to m/s conversion + ret *= 0.447f; + break; + } + } else if( type == "t/t" ) { + ret /= 4; + } + + return ret; +} +double convert_weight( const units::mass &weight ) +{ + double ret = to_gram( weight ); + if( get_option( "USE_METRIC_WEIGHTS" ) == "kg" ) { + ret /= 1000; + } else { + ret /= 453.6; + } + return ret; +} + +int convert_length( const units::length &length ) +{ + int ret = to_millimeter( length ); + const bool metric = get_option( "DISTANCE_UNITS" ) == "metric"; + if( metric ) { + if( ret % 1'000'000 == 0 ) { + // kilometers + ret /= 1'000'000; + } else if( ret % 1'000 == 0 ) { + // meters + ret /= 1'000; + } else if( ret % 10 == 0 ) { + // centimeters + ret /= 10; + } + } else { + // imperial's a doozy, we can only try to approximate + // so first we convert it to inches which are the smallest unit + ret /= 25.4; + if( ret % 63360 == 0 ) { + ret /= 63360; + } else if( ret % 36 == 0 ) { + ret /= 36; + } else if( ret % 12 == 0 ) { + ret /= 12; + } + } + return ret; +} + +std::string length_units( const units::length &length ) +{ + int length_mm = to_millimeter( length ); + const bool metric = get_option( "DISTANCE_UNITS" ) == "metric"; + if( metric ) { + if( length_mm % 1'000'000 == 0 ) { + //~ kilometers + return _( "km" ); + } else if( length_mm % 1'000 == 0 ) { + //~ meters + return _( "m" ); + } else if( length_mm % 10 == 0 ) { + //~ centimeters + return _( "cm" ); + } else { + //~ millimeters + return _( "mm" ); + } + } else { + // imperial's a doozy, we can only try to approximate + // so first we convert it to inches which are the smallest unit + length_mm /= 25.4; + if( length_mm == 0 ) { + //~ inches + return _( "in." ); + } + if( length_mm % 63360 == 0 ) { + //~ miles + return _( "mi" ); + } else if( length_mm % 36 == 0 ) { + //~ yards (length) + return _( "yd" ); + } else if( length_mm % 12 == 0 ) { + //~ feet (length) + return _( "ft" ); + } else { + //~ inches + return _( "in." ); + } + } +} + +std::string weight_to_string( const units::mass &weight ) +{ + const double converted_weight = convert_weight( weight ); + return string_format( "%.2f %s", converted_weight, weight_units() ); +} + +double convert_volume( int volume ) +{ + return convert_volume( volume, nullptr ); +} + +double convert_volume( int volume, int *out_scale ) +{ + double ret = volume; + int scale = 0; + const std::string vol_units = get_option( "VOLUME_UNITS" ); + if( vol_units == "c" ) { + ret *= 0.004; + scale = 1; + } else if( vol_units == "l" ) { + ret *= 0.001; + scale = 2; + } else { + ret *= 0.00105669; + scale = 2; + } + if( out_scale != nullptr ) { + *out_scale = scale; + } + return ret; +} + +std::string vol_to_string( const units::volume &vol ) +{ + int converted_volume_scale = 0; + const double converted_volume = + convert_volume( vol.value(), + &converted_volume_scale ); + + return string_format( "%.3f %s", converted_volume, volume_units_abbr() ); +} diff --git a/src/units_utility.h b/src/units_utility.h new file mode 100644 index 0000000000000..fbdb46ed5cafc --- /dev/null +++ b/src/units_utility.h @@ -0,0 +1,82 @@ +#pragma once +#ifndef CATA_SRC_UNITS_UTILITY_H +#define CATA_SRC_UNITS_UTILITY_H + +#include "units.h" + +/** Divide @p num by @p den, rounding up + * + * @p num must be non-negative, @p den must be positive, and @c num+den must not overflow. + */ +template +T divide_round_up( units::quantity num, units::quantity den ) +{ + return divide_round_up( num.value(), den.value() ); +} + +/** + * Create a units label for a weight value. + * + * Gives the name of the weight unit in the user selected unit system, either + * "kgs" or "lbs". Used to add unit labels to the output of @ref convert_weight. + * + * @return name of unit + */ +const char *weight_units(); + +/** + * Create an abbreviated units label for a volume value. + * + * Returns the abbreviated name for the volume unit for the user selected unit system, + * i.e. "c", "L", or "qt". Used to add unit labels to the output of @ref convert_volume. + * + * @return name of unit. + */ +const char *volume_units_abbr(); + +/** + * Create a units label for a volume value. + * + * Returns the abbreviated name for the volume unit for the user selected unit system, + * ie "cup", "liter", or "quart". Used to add unit labels to the output of @ref convert_volume. + * + * @return name of unit. + */ +const char *volume_units_long(); + +/** + * Convert weight in grams to units defined by user (kg or lbs) + * + * @param weight to be converted. + * + * @returns Weight converted to user selected unit + */ +double convert_weight( const units::mass &weight ); + +/** + * converts length to largest unit available + * 1000 mm = 1 meter for example + * assumed to be used in conjunction with unit string functions + * also works for imperial units + */ +int convert_length( const units::length &length ); +std::string length_units( const units::length &length ); + +/** convert a mass unit to a string readable by a human */ +std::string weight_to_string( const units::mass &weight ); + +/** + * Convert volume from ml to units defined by user. + */ +double convert_volume( int volume ); + +/** + * Convert volume from ml to units defined by user, + * optionally returning the units preferred scale. + */ +double convert_volume( int volume, int *out_scale ); + +/** convert a volume unit to a string readable by a human */ +std::string vol_to_string( const units::volume &vol ); + +#endif diff --git a/src/veh_interact.cpp b/src/veh_interact.cpp index e339d8dbdcc94..402d454582545 100644 --- a/src/veh_interact.cpp +++ b/src/veh_interact.cpp @@ -56,6 +56,7 @@ #include "ui.h" #include "ui_manager.h" #include "units.h" +#include "units_utility.h" #include "value_ptr.h" #include "veh_type.h" #include "veh_utils.h" diff --git a/src/veh_type.cpp b/src/veh_type.cpp index 0de5a1b87814c..bef9b854e7615 100644 --- a/src/veh_type.cpp +++ b/src/veh_type.cpp @@ -27,6 +27,7 @@ #include "string_id.h" #include "translations.h" #include "units.h" +#include "units_utility.h" #include "value_ptr.h" #include "vehicle.h" #include "vehicle_group.h" diff --git a/src/vehicle.cpp b/src/vehicle.cpp index 6154f6ca091d5..df6a3306b63dd 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -5115,19 +5115,18 @@ void vehicle::idle( bool on_map ) noise_and_smoke( idle_rate, 1_turns ); } } else { - if( engine_on && player_character.sees( global_pos3() ) && + if( engine_on && ( has_engine_type_not( fuel_type_muscle, true ) && has_engine_type_not( fuel_type_animal, true ) && has_engine_type_not( fuel_type_wind, true ) && has_engine_type_not( fuel_type_mana, true ) ) ) { - add_msg( _( "The %s's engine dies!" ), name ); + add_msg_if_player_sees( global_pos3(), _( "The %s's engine dies!" ), name ); } engine_on = false; } if( !warm_enough_to_plant( player_character.pos() ) ) { for( const vpart_reference &vp : get_enabled_parts( "PLANTER" ) ) { - if( player_character.sees( global_pos3() ) ) { - add_msg( _( "The %s's planter turns off due to low temperature." ), name ); - } + add_msg_if_player_sees( global_pos3(), _( "The %s's planter turns off due to low temperature." ), + name ); vp.part().enabled = false; } } @@ -5499,9 +5498,7 @@ bool vehicle::decrement_summon_timer() const size_t p = vp.part_index(); dump_items_from_part( p ); } - if( get_player_character().sees( global_pos3() ) ) { - add_msg( m_info, _( "Your %s winks out of existence." ), name ); - } + add_msg_if_player_sees( global_pos3(), m_info, _( "Your %s winks out of existence." ), name ); get_map().destroy_vehicle( this ); return true; } else { @@ -6449,7 +6446,6 @@ int vehicle::break_off( int p, int dmg ) } } }; - Character &player_character = get_player_character(); if( part_info( p ).location == part_location_structure ) { // For structural parts, remove other parts first std::vector parts_in_square = parts_at_relative( parts[p].mount, true ); @@ -6461,17 +6457,13 @@ int vehicle::break_off( int p, int dmg ) if( parts[ parts_in_square[ index ] ].is_broken() ) { // Tearing off a broken part - break it up - if( player_character.sees( pos ) ) { - add_msg( m_bad, _( "The %s's %s breaks into pieces!" ), name, - parts[ parts_in_square[ index ] ].name() ); - } + add_msg_if_player_sees( pos, m_bad, _( "The %s's %s breaks into pieces!" ), name, + parts[ parts_in_square[ index ] ].name() ); scatter_parts( parts[parts_in_square[index]] ); } else { // Intact (but possibly damaged) part - remove it in one piece - if( player_character.sees( pos ) ) { - add_msg( m_bad, _( "The %1$s's %2$s is torn off!" ), name, - parts[ parts_in_square[ index ] ].name() ); - } + add_msg_if_player_sees( pos, m_bad, _( "The %1$s's %2$s is torn off!" ), name, + parts[ parts_in_square[ index ] ].name() ); if( !magic ) { item part_as_item = parts[parts_in_square[index]].properties_to_item(); here.add_item_or_charges( pos, part_as_item ); @@ -6480,17 +6472,13 @@ int vehicle::break_off( int p, int dmg ) remove_part( parts_in_square[index] ); } // After clearing the frame, remove it. - if( player_character.sees( pos ) ) { - add_msg( m_bad, _( "The %1$s's %2$s is destroyed!" ), name, parts[ p ].name() ); - } + add_msg_if_player_sees( pos, m_bad, _( "The %1$s's %2$s is destroyed!" ), name, parts[ p ].name() ); scatter_parts( parts[p] ); remove_part( p ); find_and_split_vehicles( p ); } else { //Just break it off - if( player_character.sees( pos ) ) { - add_msg( m_bad, _( "The %1$s's %2$s is destroyed!" ), name, parts[ p ].name() ); - } + add_msg_if_player_sees( pos, m_bad, _( "The %1$s's %2$s is destroyed!" ), name, parts[ p ].name() ); scatter_parts( parts[p] ); remove_part( p ); diff --git a/src/vehicle_display.cpp b/src/vehicle_display.cpp index 6445b7cc234e7..c0543686f5092 100644 --- a/src/vehicle_display.cpp +++ b/src/vehicle_display.cpp @@ -8,9 +8,11 @@ #include "calendar.h" #include "cata_utility.h" #include "catacharset.h" +#include "color.h" #include "cursesdef.h" #include "debug.h" #include "itype.h" +#include "optional.h" #include "options.h" #include "output.h" #include "string_formatter.h" @@ -18,8 +20,7 @@ #include "veh_type.h" #include "vpart_position.h" #include "units.h" -#include "color.h" -#include "optional.h" +#include "units_utility.h" static const std::string part_location_structure( "structure" ); static const itype_id itype_battery( "battery" ); diff --git a/src/vehicle_move.cpp b/src/vehicle_move.cpp index 3f1ff4f43cf46..5e5a841621014 100644 --- a/src/vehicle_move.cpp +++ b/src/vehicle_move.cpp @@ -435,43 +435,41 @@ void vehicle::thrust( int thd, int z ) } return; } - int max_vel = traction * max_velocity(); - - // Get braking power - int brk = std::max( 1000, std::abs( max_vel ) * 3 / 10 ); - + const int max_vel = traction * max_velocity(); + // maximum braking is 20 mph/s, assumes high friction tires + const int max_brake = 20 * 100; //pos or neg if accelerator or brake - int vel_inc = ( ( thrusting ) ? accel : brk ) * thd; + int vel_inc = ( accel + ( thrusting ? 0 : max_brake ) ) * thd; // Reverse is only 60% acceleration, unless an electric motor is in use if( thd == -1 && thrusting && !has_engine_type( fuel_type_battery, true ) ) { vel_inc = .6 * vel_inc; } - //find power ratio used of engines max + //find ratio of used acceleration to maximum available, returned in tenths of a percent + //so 1000 = 100% and 453 = 45.3% int load; // Keep exact cruise control speed if( cruise_on ) { int effective_cruise = std::min( cruise_velocity, max_vel ); if( thd > 0 ) { vel_inc = std::min( vel_inc, effective_cruise - velocity ); - //find power ratio used of engines max - load = 1000 * std::max( 0, vel_inc ) / std::max( ( thrusting ? accel : brk ), 1 ); } else { vel_inc = std::max( vel_inc, effective_cruise - velocity ); - load = 1000 * std::min( 0, vel_inc ) / std::max( ( thrusting ? accel : brk ), 1 ); } - if( z != 0 ) { - // @TODO : actual engine strain / load for going up a z-level. - load = 1; - thrusting = true; - } - } else { - if( z != 0 ) { - load = 1; - thrusting = true; + if( thrusting ) { + load = 1000 * std::abs( vel_inc ) / accel; } else { - load = ( thrusting ? 1000 : 0 ); + // brakes provide 20 mph/s of slowdown and the rest is engine braking + // TODO: braking depends on wheels, traction, driver skill + load = 1000 * std::max( 0, std::abs( vel_inc ) - max_brake ) / accel; } + } else { + load = ( thrusting ? 1000 : 0 ); + } + // rotorcraft need to spend 15% of load to hover, 30% to change z + if( is_rotorcraft() && is_flying_in_air() ) { + load = std::max( load, z > 0 ? 300 : 150 ); + thrusting = true; } // only consume resources if engine accelerating @@ -2111,9 +2109,10 @@ int map::shake_vehicle( vehicle &veh, const int velocity_before, const int direc _( " is hurled from the %s's seat by " "the power of the impact!" ), veh.name ); unboard_vehicle( part_pos ); - } else if( get_player_character().sees( part_pos ) ) { - add_msg( m_bad, _( "The %s is hurled from %s's by the power of the impact!" ), - pet->disp_name(), veh.name ); + } else { + add_msg_if_player_sees( part_pos, m_bad, + _( "The %s is hurled from %s's by the power of the impact!" ), + pet->disp_name(), veh.name ); } ///\EFFECT_STR reduces distance thrown from seat in a vehicle impact g->fling_creature( rider, direction + rng( 0, 60 ) - 30, diff --git a/src/vehicle_part.cpp b/src/vehicle_part.cpp index a5dca53838a6b..b750f7c9c71a8 100644 --- a/src/vehicle_part.cpp +++ b/src/vehicle_part.cpp @@ -209,7 +209,7 @@ itype_id vehicle_part::ammo_current() const } if( is_fuel_store( false ) || is_turret() ) { - return base.ammo_current(); + return base.ammo_current() != itype_id::NULL_ID() ? base.ammo_current() : base.ammo_default(); } return itype_id::NULL_ID(); @@ -373,7 +373,7 @@ bool vehicle_part::can_reload( const item &obj ) const return true; } - return is_tank() && + return is_fuel_store() && ammo_remaining() <= ammo_capacity( item::find_type( ammo_current() )->ammo->type ); } diff --git a/src/vehicle_use.cpp b/src/vehicle_use.cpp index e3e41c8ff9733..80303bca2888c 100644 --- a/src/vehicle_use.cpp +++ b/src/vehicle_use.cpp @@ -1792,7 +1792,7 @@ void vehicle::use_harness( int part, const tripoint &pos ) return; } - m.add_effect( effect_harnessed, 1_turns, num_bp, true ); + m.add_effect( effect_harnessed, 1_turns, true ); m.setpos( pos ); //~ %1$s: monster name, %2$s: vehicle name add_msg( m_info, _( "You harness your %1$s to %2$s." ), m.get_name(), disp_name() ); diff --git a/src/viewer.h b/src/viewer.h new file mode 100644 index 0000000000000..107147d8a3cfe --- /dev/null +++ b/src/viewer.h @@ -0,0 +1,19 @@ +#pragma once +#ifndef CATA_SRC_VIEWER_H +#define CATA_SRC_VIEWER_H + +class Creature; +struct tripoint; + +// This is strictly an interface that provides access to a game entity's Field of View. +class viewer +{ + public: + virtual bool sees( const tripoint &target, bool is_avatar = false, int range_mod = 0 ) const = 0; + virtual bool sees( const Creature &target ) const = 0; + virtual ~viewer() = default; +}; + +viewer &get_player_view(); + +#endif // CATA_SRC_VIEWER_H diff --git a/src/visitable.cpp b/src/visitable.cpp index 155836ecde5d9..1ba6d3fe00763 100644 --- a/src/visitable.cpp +++ b/src/visitable.cpp @@ -459,7 +459,7 @@ VisitResponse visitable::visit_items( } } - return ch->inv.visit_items( func ); + return ch->inv->visit_items( func ); } /** @relates visitable */ @@ -623,7 +623,7 @@ std::list visitable::remove_items_with( const } // first try and remove items from the inventory - res = ch->inv.remove_items_with( filter, count ); + res = ch->inv->remove_items_with( filter, count ); count -= res.size(); if( count == 0 ) { return res; diff --git a/src/weather.cpp b/src/weather.cpp index 4e3418e8a1947..0f048352f59ee 100644 --- a/src/weather.cpp +++ b/src/weather.cpp @@ -46,8 +46,6 @@ static const efftype_id effect_sleep( "sleep" ); static const efftype_id effect_snow_glare( "snow_glare" ); static const itype_id itype_water( "water" ); -static const itype_id itype_water_acid( "water_acid" ); -static const itype_id itype_water_acid_weak( "water_acid_weak" ); static const trait_id trait_CEPH_VISION( "CEPH_VISION" ); static const trait_id trait_FEATHERS( "FEATHERS" ); @@ -114,7 +112,7 @@ void glare( weather_type_id w ) if( player_character.has_trait( trait_CEPH_VISION ) ) { dur = dur * 2; } - player_character.add_env_effect( *effect, bp_eyes, 2, dur ); + player_character.add_env_effect( *effect, bodypart_id( "eyes" ), 2, dur ); } } @@ -227,7 +225,7 @@ void item::add_rain_to_container( bool acid, int charges ) if( charges <= 0 ) { return; } - item ret( acid ? "water_acid" : "water", calendar::turn ); + item ret( "water", calendar::turn ); const int capa = get_remaining_capacity_for_liquid( ret, true ); ret.charges = std::min( charges, capa ); if( contents.can_contain( ret ).success() ) { @@ -239,9 +237,7 @@ void item::add_rain_to_container( bool acid, int charges ) put_in( ret, item_pocket::pocket_type::CONTAINER ); } else { static const std::set allowed_liquid_types{ - itype_water, - itype_water_acid, - itype_water_acid_weak + itype_water }; item *found_liq = contents.get_item_with( [&]( const item & liquid ) { return allowed_liquid_types.count( liquid.typeId() ); @@ -258,7 +254,7 @@ void item::add_rain_to_container( bool acid, int charges ) liq.charges += added; } - if( liq.typeId() == ret.typeId() || liq.typeId() == itype_water_acid_weak ) { + if( liq.typeId() == ret.typeId() || liq.typeId() == itype_water ) { // The container already contains this liquid or weakly acidic water. // Don't do anything special -- we already added liquid. } else { @@ -274,7 +270,7 @@ void item::add_rain_to_container( bool acid, int charges ) const bool transmute = x_in_y( 2 * added, liq.charges ); if( transmute ) { - liq = item( "water_acid_weak", calendar::turn, liq.charges ); + liq = item( "water", calendar::turn, liq.charges ); } else if( liq.typeId() == itype_water ) { // The container has water, and the acid rain didn't turn it // into weak acid. Poison the water instead, assuming 1 @@ -574,7 +570,7 @@ void handle_weather_effects( weather_type_id const w ) if( current_effect.effect_id.is_valid() ) { if( current_effect.target_part.is_valid() ) { player_character.add_effect( current_effect.effect_id, current_effect.effect_duration, - current_effect.target_part->token ); + current_effect.target_part ); } else { player_character.add_effect( current_effect.effect_id, current_effect.effect_duration ); } diff --git a/tests/cata_utility_test.cpp b/tests/cata_utility_test.cpp index ad3f2841188e3..c1f1aa69030e1 100644 --- a/tests/cata_utility_test.cpp +++ b/tests/cata_utility_test.cpp @@ -1,5 +1,6 @@ #include "catch/catch.hpp" #include "cata_utility.h" +#include "units_utility.h" #include "units.h" TEST_CASE( "string_starts_with", "[utility]" ) diff --git a/tests/char_biometrics_test.cpp b/tests/char_biometrics_test.cpp index affc991e633ad..44364e39e74b9 100644 --- a/tests/char_biometrics_test.cpp +++ b/tests/char_biometrics_test.cpp @@ -554,8 +554,8 @@ TEST_CASE( "basal metabolic rate with various size and metabolism", "[biometrics REQUIRE( dummy.get_size() == creature_size::medium ); SECTION( "normal metabolism" ) { - CHECK( 2087 == bmr_at_act_level( dummy, NO_EXERCISE ) ); - CHECK( 7825 == bmr_at_act_level( dummy, MODERATE_EXERCISE ) ); + CHECK( 1739 == bmr_at_act_level( dummy, NO_EXERCISE ) ); + CHECK( 6955 == bmr_at_act_level( dummy, MODERATE_EXERCISE ) ); CHECK( 17388 == bmr_at_act_level( dummy, EXTRA_EXERCISE ) ); } @@ -563,8 +563,8 @@ TEST_CASE( "basal metabolic rate with various size and metabolism", "[biometrics set_single_trait( dummy, "HUNGER2" ); REQUIRE( dummy.metabolic_rate_base() == 2.0f ); - CHECK( 4174 == bmr_at_act_level( dummy, NO_EXERCISE ) ); - CHECK( 15649 == bmr_at_act_level( dummy, MODERATE_EXERCISE ) ); + CHECK( 3478 == bmr_at_act_level( dummy, NO_EXERCISE ) ); + CHECK( 13910 == bmr_at_act_level( dummy, MODERATE_EXERCISE ) ); CHECK( 34775 == bmr_at_act_level( dummy, EXTRA_EXERCISE ) ); } @@ -572,8 +572,8 @@ TEST_CASE( "basal metabolic rate with various size and metabolism", "[biometrics set_single_trait( dummy, "COLDBLOOD3" ); REQUIRE( dummy.metabolic_rate_base() == 0.5f ); - CHECK( 1044 == bmr_at_act_level( dummy, NO_EXERCISE ) ); - CHECK( 3913 == bmr_at_act_level( dummy, MODERATE_EXERCISE ) ); + CHECK( 870 == bmr_at_act_level( dummy, NO_EXERCISE ) ); + CHECK( 3478 == bmr_at_act_level( dummy, MODERATE_EXERCISE ) ); CHECK( 8694 == bmr_at_act_level( dummy, EXTRA_EXERCISE ) ); } } @@ -582,8 +582,8 @@ TEST_CASE( "basal metabolic rate with various size and metabolism", "[biometrics set_single_trait( dummy, "SMALL" ); REQUIRE( dummy.get_size() == creature_size::small ); - CHECK( 1262 == bmr_at_act_level( dummy, NO_EXERCISE ) ); - CHECK( 4731 == bmr_at_act_level( dummy, MODERATE_EXERCISE ) ); + CHECK( 1052 == bmr_at_act_level( dummy, NO_EXERCISE ) ); + CHECK( 4205 == bmr_at_act_level( dummy, MODERATE_EXERCISE ) ); CHECK( 10513 == bmr_at_act_level( dummy, EXTRA_EXERCISE ) ); } @@ -591,8 +591,8 @@ TEST_CASE( "basal metabolic rate with various size and metabolism", "[biometrics set_single_trait( dummy, "LARGE" ); REQUIRE( dummy.get_size() == creature_size::large ); - CHECK( 3062 == bmr_at_act_level( dummy, NO_EXERCISE ) ); - CHECK( 11481 == bmr_at_act_level( dummy, MODERATE_EXERCISE ) ); + CHECK( 2552 == bmr_at_act_level( dummy, NO_EXERCISE ) ); + CHECK( 10205 == bmr_at_act_level( dummy, MODERATE_EXERCISE ) ); CHECK( 25513 == bmr_at_act_level( dummy, EXTRA_EXERCISE ) ); } } diff --git a/tests/char_healing_test.cpp b/tests/char_healing_test.cpp index e6d29ee69cab4..bf226d122da37 100644 --- a/tests/char_healing_test.cpp +++ b/tests/char_healing_test.cpp @@ -268,7 +268,7 @@ static float bandaged_rate( const std::string &bp_name, const float rest_quality { avatar dummy; const bodypart_id &bp = bodypart_id( bp_name ); - dummy.add_effect( effect_bandaged, 1_turns, bp->token ); + dummy.add_effect( effect_bandaged, 1_turns, bp ); return dummy.healing_rate_medicine( rest_quality, bp ); } @@ -277,7 +277,7 @@ static float disinfected_rate( const std::string &bp_name, const float rest_qual { avatar dummy; const bodypart_id &bp = bodypart_id( bp_name ); - dummy.add_effect( effect_disinfected, 1_turns, bp->token ); + dummy.add_effect( effect_disinfected, 1_turns, bp ); return dummy.healing_rate_medicine( rest_quality, bp ); } @@ -286,8 +286,8 @@ static float together_rate( const std::string &bp_name, const float rest_quality { avatar dummy; const bodypart_id &bp = bodypart_id( bp_name ); - dummy.add_effect( effect_bandaged, 1_turns, bp->token ); - dummy.add_effect( effect_disinfected, 1_turns, bp->token ); + dummy.add_effect( effect_bandaged, 1_turns, bp ); + dummy.add_effect( effect_disinfected, 1_turns, bp ); return dummy.healing_rate_medicine( rest_quality, bp ); } diff --git a/tests/creature_effect_test.cpp b/tests/creature_effect_test.cpp index ca8ca138564d6..33b9a9369d703 100644 --- a/tests/creature_effect_test.cpp +++ b/tests/creature_effect_test.cpp @@ -36,8 +36,8 @@ TEST_CASE( "character add_effect", "[creature][character][effect][add]" ) dummy.set_body(); const efftype_id effect_bleed( "bleed" ); const efftype_id effect_grabbed( "grabbed" ); - const body_part left_arm = bodypart_id( "arm_l" )->token; - const body_part right_arm = bodypart_id( "arm_r" )->token; + const bodypart_id left_arm( "arm_l" ); + const bodypart_id right_arm( "arm_r" ); GIVEN( "character is susceptible to effect" ) { REQUIRE_FALSE( dummy.is_immune_effect( effect_bleed ) ); @@ -60,14 +60,14 @@ TEST_CASE( "character add_effect", "[creature][character][effect][add]" ) // Left arm bleeding, right arm grabbed THEN( "they have the effect on that body part" ) { - CHECK( dummy.has_effect( effect_bleed, left_arm ) ); - CHECK( dummy.has_effect( effect_grabbed, right_arm ) ); + CHECK( dummy.has_effect( effect_bleed, left_arm.id() ) ); + CHECK( dummy.has_effect( effect_grabbed, right_arm.id() ) ); } // Left arm not grabbed, right arm not bleeding THEN( "they do not have the effect on another body part" ) { - CHECK_FALSE( dummy.has_effect( effect_grabbed, left_arm ) ); - CHECK_FALSE( dummy.has_effect( effect_bleed, right_arm ) ); + CHECK_FALSE( dummy.has_effect( effect_grabbed, left_arm.id() ) ); + CHECK_FALSE( dummy.has_effect( effect_bleed, right_arm.id() ) ); } } } @@ -97,14 +97,14 @@ TEST_CASE( "monster add_effect", "[creature][monster][effect][add]" ) REQUIRE( mummy.is_immune_effect( effect_bleed ) ); THEN( "monster add_effect is called with force = false" ) { - mummy.add_effect( effect_bleed, 1_minutes, num_bp, false, 1, false ); + mummy.add_effect( effect_bleed, 1_minutes, false, 1, false ); THEN( "they do not have the effect" ) { CHECK_FALSE( mummy.has_effect( effect_bleed ) ); } } WHEN( "monster add_effect is called with force = true" ) { - mummy.add_effect( effect_bleed, 1_minutes, num_bp, false, 1, true ); + mummy.add_effect( effect_bleed, 1_minutes, false, 1, true ); THEN( "they have the effect" ) { CHECK( mummy.has_effect( effect_bleed ) ); } @@ -118,10 +118,10 @@ TEST_CASE( "remove_effect", "[creature][effect][remove]" ) { avatar dummy; const efftype_id effect_grabbed( "grabbed" ); - const body_part left_arm = bodypart_id( "arm_l" )->token; - const body_part right_arm = bodypart_id( "arm_r" )->token; - const body_part left_leg = bodypart_id( "leg_l" )->token; - const body_part right_leg = bodypart_id( "leg_r" )->token; + const bodypart_id left_arm( "arm_l" ); + const bodypart_id right_arm( "arm_r" ); + const bodypart_id left_leg( "leg_l" ); + const bodypart_id right_leg( "leg_r" ); dummy.clear_effects(); @@ -135,7 +135,7 @@ TEST_CASE( "remove_effect", "[creature][effect][remove]" ) // Left arm grabbed WHEN( "character has effect on one body part" ) { dummy.add_effect( effect_grabbed, 1_minutes, left_arm ); - REQUIRE( dummy.has_effect( effect_grabbed, left_arm ) ); + REQUIRE( dummy.has_effect( effect_grabbed, left_arm.id() ) ); THEN( "remove_effect with no body part returns true" ) { // Release all grabs @@ -151,7 +151,7 @@ TEST_CASE( "remove_effect", "[creature][effect][remove]" ) CHECK( dummy.remove_effect( effect_grabbed, left_arm ) ); // Left arm is released AND_THEN( "effect is removed from that body part" ) { - CHECK_FALSE( dummy.has_effect( effect_grabbed, left_arm ) ); + CHECK_FALSE( dummy.has_effect( effect_grabbed, left_arm.id() ) ); } } @@ -160,7 +160,7 @@ TEST_CASE( "remove_effect", "[creature][effect][remove]" ) CHECK_FALSE( dummy.remove_effect( effect_grabbed, right_arm ) ); // Left arm is still grabbed AND_THEN( "effect still applies to original body part" ) { - CHECK( dummy.has_effect( effect_grabbed, left_arm ) ); + CHECK( dummy.has_effect( effect_grabbed, left_arm.id() ) ); } } } @@ -169,16 +169,16 @@ TEST_CASE( "remove_effect", "[creature][effect][remove]" ) WHEN( "character has effect on two body parts" ) { dummy.add_effect( effect_grabbed, 1_minutes, left_arm ); dummy.add_effect( effect_grabbed, 1_minutes, right_arm ); - REQUIRE( dummy.has_effect( effect_grabbed, left_arm ) ); - REQUIRE( dummy.has_effect( effect_grabbed, right_arm ) ); + REQUIRE( dummy.has_effect( effect_grabbed, left_arm.id() ) ); + REQUIRE( dummy.has_effect( effect_grabbed, right_arm.id() ) ); // Release all grabs THEN( "remove_effect with no body part returns true" ) { CHECK( dummy.remove_effect( effect_grabbed ) ); // Both arms are released AND_THEN( "effect is removed from all body parts" ) { - CHECK_FALSE( dummy.has_effect( effect_grabbed, left_arm ) ); - CHECK_FALSE( dummy.has_effect( effect_grabbed, right_arm ) ); + CHECK_FALSE( dummy.has_effect( effect_grabbed, left_arm.id() ) ); + CHECK_FALSE( dummy.has_effect( effect_grabbed, right_arm.id() ) ); } } @@ -187,11 +187,11 @@ TEST_CASE( "remove_effect", "[creature][effect][remove]" ) CHECK( dummy.remove_effect( effect_grabbed, left_arm ) ); // Left arm is released AND_THEN( "effect is removed from that body part" ) { - CHECK_FALSE( dummy.has_effect( effect_grabbed, left_arm ) ); + CHECK_FALSE( dummy.has_effect( effect_grabbed, left_arm.id() ) ); } // Right arm still grabbed AND_THEN( "effect still applies to other body part" ) { - CHECK( dummy.has_effect( effect_grabbed, right_arm ) ); + CHECK( dummy.has_effect( effect_grabbed, right_arm.id() ) ); } } @@ -201,8 +201,8 @@ TEST_CASE( "remove_effect", "[creature][effect][remove]" ) CHECK_FALSE( dummy.remove_effect( effect_grabbed, right_leg ) ); // Both arms still grabbed AND_THEN( "effect still applies to original body parts" ) { - CHECK( dummy.has_effect( effect_grabbed, left_arm ) ); - CHECK( dummy.has_effect( effect_grabbed, right_arm ) ); + CHECK( dummy.has_effect( effect_grabbed, left_arm.id() ) ); + CHECK( dummy.has_effect( effect_grabbed, right_arm.id() ) ); } } } @@ -258,8 +258,8 @@ TEST_CASE( "has_effect", "[creature][effect][has]" ) // For character, has_effect may apply to individual body parts SECTION( "character has_effect" ) { avatar dummy; - const body_part left_arm = bodypart_id( "arm_l" )->token; - const body_part right_arm = bodypart_id( "arm_r" )->token; + const bodypart_id left_arm( "arm_l" ); + const bodypart_id right_arm( "arm_r" ); dummy.clear_effects(); @@ -276,30 +276,30 @@ TEST_CASE( "has_effect", "[creature][effect][has]" ) dummy.add_effect( effect_grabbed, 1_minutes, left_arm ); THEN( "has_effect is true for affected body part" ) { - CHECK( dummy.has_effect( effect_grabbed, left_arm ) ); + CHECK( dummy.has_effect( effect_grabbed, left_arm.id() ) ); } THEN( "has_effect is false for an unaffected body part" ) { - CHECK_FALSE( dummy.has_effect( effect_grabbed, right_arm ) ); + CHECK_FALSE( dummy.has_effect( effect_grabbed, right_arm.id() ) ); } THEN( "has_effect is true when body part is not specified" ) { // num_bp (default) is any/all body parts CHECK( dummy.has_effect( effect_grabbed ) ); - CHECK( dummy.has_effect( effect_grabbed, num_bp ) ); + CHECK( dummy.has_effect( effect_grabbed ) ); } } // Downed WHEN( "character has effect on the whole body" ) { - dummy.add_effect( effect_downed, 1_minutes, num_bp ); + dummy.add_effect( effect_downed, 1_minutes ); THEN( "has_effect is false for any body part" ) { - CHECK_FALSE( dummy.has_effect( effect_downed, left_arm ) ); - CHECK_FALSE( dummy.has_effect( effect_downed, right_arm ) ); + CHECK_FALSE( dummy.has_effect( effect_downed, left_arm.id() ) ); + CHECK_FALSE( dummy.has_effect( effect_downed, right_arm.id() ) ); } THEN( "has_effect is true when body part is not specified" ) { CHECK( dummy.has_effect( effect_downed ) ); - CHECK( dummy.has_effect( effect_downed, num_bp ) ); + CHECK( dummy.has_effect( effect_downed ) ); } } } diff --git a/tests/effect_test.cpp b/tests/effect_test.cpp index 19ab734bad9dc..3f0a91c4715cc 100644 --- a/tests/effect_test.cpp +++ b/tests/effect_test.cpp @@ -21,12 +21,12 @@ static void check_effect_init( const std::string &eff_name, const time_duration { const efftype_id eff_id( eff_name ); const effect_type &type = eff_id.obj(); - const body_part bp = bodypart_id( bp_name )->token; + const bodypart_str_id bp( bp_name ); effect effect_obj( &type, dur, bp, permanent, intensity, start_time ); CHECK( dur == effect_obj.get_duration() ); - CHECK( bp == effect_obj.get_bp() ); + CHECK( bp.id() == effect_obj.get_bp() ); CHECK( permanent == effect_obj.is_permanent() ); CHECK( intensity == effect_obj.get_intensity() ); CHECK( start_time == effect_obj.get_start_time() ); @@ -54,7 +54,8 @@ TEST_CASE( "effect duration", "[effect][duration]" ) { // "debugged" and "intensified" effects come from JSON effect data (data/mods/TEST_DATA/effects.json) const efftype_id eff_id( "debugged" ); - effect eff_debugged( &eff_id.obj(), 1_turns, num_bp, false, 1, calendar::turn ); + effect eff_debugged( &eff_id.obj(), 1_turns, bodypart_str_id( "bp_null" ), false, 1, + calendar::turn ); // Current duration from effect initialization REQUIRE( eff_debugged.get_duration() == 1_turns ); @@ -83,7 +84,8 @@ TEST_CASE( "effect duration", "[effect][duration]" ) // a duration of 3000 or higher. SECTION( "set_duration modifies intensity if effect is duration-based" ) { const efftype_id eff_id( "intensified" ); - effect eff_intense( &eff_id.obj(), 1_turns, num_bp, false, 1, calendar::turn ); + effect eff_intense( &eff_id.obj(), 1_turns, bodypart_str_id( "bp_null" ), false, 1, + calendar::turn ); REQUIRE( eff_intense.get_int_dur_factor() == 1_minutes ); // At zero duration, intensity is minimum (1) @@ -119,7 +121,8 @@ TEST_CASE( "effect duration", "[effect][duration]" ) TEST_CASE( "effect intensity", "[effect][intensity]" ) { const efftype_id eff_id( "debugged" ); - effect eff_debugged( &eff_id.obj(), 3_turns, num_bp, false, 1, calendar::turn ); + effect eff_debugged( &eff_id.obj(), 3_turns, bodypart_str_id( "bp_null" ), false, 1, + calendar::turn ); REQUIRE( eff_debugged.get_intensity() == 1 ); REQUIRE( eff_debugged.get_max_intensity() == 10 ); @@ -159,10 +162,11 @@ TEST_CASE( "effect decay", "[effect][decay]" ) const efftype_id eff_id( "debugged" ); std::vector rem_ids; - std::vector rem_bps; + std::vector rem_bps; SECTION( "decay reduces effect duration by 1 turn" ) { - effect eff_debugged( &eff_id.obj(), 2_turns, num_bp, false, 1, calendar::turn ); + effect eff_debugged( &eff_id.obj(), 2_turns, bodypart_str_id( "bp_null" ), false, 1, + calendar::turn ); // Ensure it will last 2 turns, and is not permanent/paused REQUIRE( to_turns( eff_debugged.get_duration() ) == 2 ); REQUIRE_FALSE( eff_debugged.is_permanent() ); @@ -189,11 +193,12 @@ TEST_CASE( "effect decay", "[effect][decay]" ) CHECK( rem_bps.size() == 1 ); // Effect ID and body part are pushed to the arrays CHECK( rem_ids.front() == eff_debugged.get_id() ); - CHECK( rem_bps.front() == num_bp ); + CHECK( rem_bps.front() == bodypart_id( "bp_null" ) ); } SECTION( "decay does not reduce paused/permanent effect duration" ) { - effect eff_debugged( &eff_id.obj(), 2_turns, num_bp, true, 1, calendar::turn ); + effect eff_debugged( &eff_id.obj(), 2_turns, bodypart_str_id( "bp_null" ), true, 1, + calendar::turn ); // Ensure it will last 2 turns, and is permanent/paused REQUIRE( to_turns( eff_debugged.get_duration() ) == 2 ); REQUIRE( eff_debugged.is_permanent() ); @@ -221,7 +226,7 @@ TEST_CASE( "effect decay", "[effect][decay]" ) TEST_CASE( "display short description", "[effect][desc]" ) { const efftype_id eff_id( "debugged" ); - const body_part arm_r = bodypart_id( "arm_r" )->token; + const bodypart_str_id arm_r( "arm_r" ); effect eff_debugged( &eff_id.obj(), 1_turns, arm_r, false, 1, calendar::turn ); // TODO: Determine a case where `reduced` (true/false) makes a difference @@ -256,7 +261,8 @@ TEST_CASE( "effect display and speed name may vary with intensity", // "name": [ "Whoa", "Wut?", "Wow!" ] // "max_intensity": 3 const efftype_id eid_intensified( "intensified" ); - effect eff_intense( &eid_intensified.obj(), 1_turns, num_bp, false, 1, calendar::turn ); + effect eff_intense( &eid_intensified.obj(), 1_turns, bodypart_str_id( "bp_null" ), false, 1, + calendar::turn ); REQUIRE( eff_intense.get_max_intensity() == 3 ); // use_name_ints is true if there are names for each intensity @@ -289,7 +295,8 @@ TEST_CASE( "effect display and speed name may vary with intensity", // "name": [ "Debugged" ] // "speed_name": "Optimized" const efftype_id eid_debugged( "debugged" ); - effect eff_debugged( &eid_debugged.obj(), 1_minutes, num_bp, false, 1, calendar::turn ); + effect eff_debugged( &eid_debugged.obj(), 1_minutes, bodypart_str_id( "bp_null" ), false, 1, + calendar::turn ); THEN( "disp_name has the name, and current intensity if > 1" ) { eff_debugged.set_intensity( 1 ); @@ -320,7 +327,7 @@ TEST_CASE( "effect display and speed name may vary with intensity", TEST_CASE( "effect permanence", "[effect][permanent]" ) { const efftype_id eff_id( "grabbed" ); - const body_part arm_r = bodypart_id( "arm_r" )->token; + const bodypart_str_id arm_r( "arm_r" ); // Grab right arm, not permanent effect eff_grabbed( &eff_id.obj(), 1_turns, arm_r, false, 1, calendar::turn ); @@ -347,20 +354,20 @@ TEST_CASE( "effect permanence", "[effect][permanent]" ) TEST_CASE( "effect body part", "[effect][bodypart]" ) { const efftype_id eff_id( "grabbed" ); - const body_part arm_r = bodypart_id( "arm_r" )->token; - const body_part arm_l = bodypart_id( "arm_l" )->token; + const bodypart_str_id arm_r( "arm_r" ); + const bodypart_str_id arm_l( "arm_l" ); // Grab right arm, initially effect eff_grabbed( &eff_id.obj(), 1_turns, arm_r, false, 1, calendar::turn ); - CHECK( eff_grabbed.get_bp() == arm_r ); + CHECK( eff_grabbed.get_bp() == arm_r.id() ); // Switch to left arm eff_grabbed.set_bp( arm_l ); - CHECK( eff_grabbed.get_bp() == arm_l ); - CHECK_FALSE( eff_grabbed.get_bp() == arm_r ); + CHECK( eff_grabbed.get_bp() == arm_l.id() ); + CHECK_FALSE( eff_grabbed.get_bp() == arm_r.id() ); // Back to right arm eff_grabbed.set_bp( arm_r ); - CHECK( eff_grabbed.get_bp() == arm_r ); - CHECK_FALSE( eff_grabbed.get_bp() == arm_l ); + CHECK( eff_grabbed.get_bp() == arm_r.id() ); + CHECK_FALSE( eff_grabbed.get_bp() == arm_l.id() ); } // Effect modifiers @@ -376,7 +383,8 @@ TEST_CASE( "effect modifiers", "[effect][modifier]" ) { SECTION( "base_mods apply equally for any intensity" ) { const efftype_id eff_id( "debugged" ); - effect eff_debugged( &eff_id.obj(), 1_minutes, num_bp, false, 1, calendar::turn ); + effect eff_debugged( &eff_id.obj(), 1_minutes, bodypart_str_id( "bp_null" ), false, 1, + calendar::turn ); CHECK( eff_debugged.get_mod( "STR" ) == 1 ); CHECK( eff_debugged.get_mod( "DEX" ) == 2 ); @@ -390,7 +398,8 @@ TEST_CASE( "effect modifiers", "[effect][modifier]" ) // Scaling mods - vary based on intensity SECTION( "scaling_mods vary based on intensity" ) { const efftype_id eff_id( "intensified" ); - effect eff_intense( &eff_id.obj(), 1_turns, num_bp, false, 1, calendar::turn ); + effect eff_intense( &eff_id.obj(), 1_turns, bodypart_str_id( "bp_null" ), false, 1, + calendar::turn ); REQUIRE( eff_intense.get_max_intensity() == 3 ); // Subtracts 1 INT and 2 PER per intensity greater than 1 diff --git a/tests/fake_messages.cpp b/tests/fake_messages.cpp index 6bca667a402d7..5be2c9643fb11 100644 --- a/tests/fake_messages.cpp +++ b/tests/fake_messages.cpp @@ -41,3 +41,7 @@ void Messages::deserialize( const JsonObject & ) {} void add_msg( std::string ) {} void add_msg( const game_message_params &, std::string ) {} +void add_msg_if_player_sees( const tripoint &, std::string ) {} +void add_msg_if_player_sees( const Creature &, std::string ) {} +void add_msg_if_player_sees( const tripoint &, const game_message_params &, std::string ) {} +void add_msg_if_player_sees( const Creature &, const game_message_params &, std::string ) {} diff --git a/tests/invlet_test.cpp b/tests/invlet_test.cpp index e86b9d9d31c30..b1287f9a79ed0 100644 --- a/tests/invlet_test.cpp +++ b/tests/invlet_test.cpp @@ -228,8 +228,8 @@ static invlet_state check_invlet( player &p, item &it, const char invlet ) if( it.invlet == '\0' ) { return NONE; } else if( it.invlet == invlet ) { - if( p.inv.assigned_invlet.find( invlet ) != p.inv.assigned_invlet.end() && - p.inv.assigned_invlet[invlet] == it.typeId() ) { + if( p.inv->assigned_invlet.find( invlet ) != p.inv->assigned_invlet.end() && + p.inv->assigned_invlet[invlet] == it.typeId() ) { return ASSIGNED; } else { return CACHED; @@ -460,7 +460,7 @@ static void invlet_test( player &dummy, const inventory_location from, const inv invlet_state expected_second_invlet_state = second_invlet_state; // remove all items - dummy.inv.clear(); + dummy.inv->clear(); dummy.worn.clear(); dummy.remove_weapon(); get_map().i_clear( dummy.pos() ); @@ -542,7 +542,7 @@ static void stack_invlet_test( player &dummy, inventory_location from, inventory } // remove all items - dummy.inv.clear(); + dummy.inv->clear(); dummy.worn.clear(); dummy.remove_weapon(); get_map().i_clear( dummy.pos() ); @@ -594,7 +594,7 @@ static void swap_invlet_test( player &dummy, inventory_location loc ) REQUIRE( loc != GROUND ); // remove all items - dummy.inv.clear(); + dummy.inv->clear(); dummy.worn.clear(); dummy.remove_weapon(); get_map().i_clear( dummy.pos() ); @@ -678,7 +678,7 @@ static void merge_invlet_test( player &dummy, inventory_location from ) invlet_2 : 0; // remove all items - dummy.inv.clear(); + dummy.inv->clear(); dummy.worn.clear(); dummy.remove_weapon(); get_map().i_clear( dummy.pos() ); diff --git a/tests/iuse_actor_test.cpp b/tests/iuse_actor_test.cpp index eee5ee76887f7..23583ae00b33d 100644 --- a/tests/iuse_actor_test.cpp +++ b/tests/iuse_actor_test.cpp @@ -21,7 +21,7 @@ static player &get_sanitized_player( ) // Remove first worn item until there are none left. std::list temp; while( player_character.takeoff( player_character.i_at( -2 ), &temp ) ) {} - player_character.inv.clear(); + player_character.inv->clear(); player_character.remove_weapon(); return player_character; diff --git a/tests/magic_spell_test.cpp b/tests/magic_spell_test.cpp index 34a8959d22958..831feccd8de08 100644 --- a/tests/magic_spell_test.cpp +++ b/tests/magic_spell_test.cpp @@ -495,7 +495,7 @@ TEST_CASE( "spell effect - target_attack", "[magic][spell][effect][target_attack REQUIRE( pew_spell.range() >= 2 ); // Ensure avatar has enough mana to cast - REQUIRE( dummy.magic.has_enough_energy( dummy, pew_spell ) ); + REQUIRE( dummy.magic->has_enough_energy( dummy, pew_spell ) ); // Cast the spell and measure the defender's change in HP before_hp = mummy.get_hp(); @@ -525,7 +525,7 @@ TEST_CASE( "spell effect - summon", "[magic][spell][effect][summon]" ) spell_id mummy_id( "test_spell_tp_mummy" ); spell mummy_spell( mummy_id ); - REQUIRE( dummy.magic.has_enough_energy( dummy, mummy_spell ) ); + REQUIRE( dummy.magic->has_enough_energy( dummy, mummy_spell ) ); // Summon the mummy in the adjacent space mummy_spell.cast_spell_effect( dummy, mummy_loc ); diff --git a/tests/morale_test.cpp b/tests/morale_test.cpp index 04129fec437ff..500c70c5527dc 100644 --- a/tests/morale_test.cpp +++ b/tests/morale_test.cpp @@ -351,18 +351,18 @@ TEST_CASE( "player_morale" ) GIVEN( "tough temperature conditions" ) { WHEN( "chilly" ) { - m.on_effect_int_change( effect_cold, 1, bp_torso ); - m.on_effect_int_change( effect_cold, 1, bp_head ); - m.on_effect_int_change( effect_cold, 1, bp_eyes ); - m.on_effect_int_change( effect_cold, 1, bp_mouth ); - m.on_effect_int_change( effect_cold, 1, bp_arm_l ); - m.on_effect_int_change( effect_cold, 1, bp_arm_r ); - m.on_effect_int_change( effect_cold, 1, bp_leg_l ); - m.on_effect_int_change( effect_cold, 1, bp_leg_r ); - m.on_effect_int_change( effect_cold, 1, bp_hand_l ); - m.on_effect_int_change( effect_cold, 1, bp_hand_r ); - m.on_effect_int_change( effect_cold, 1, bp_foot_l ); - m.on_effect_int_change( effect_cold, 1, bp_foot_r ); + m.on_effect_int_change( effect_cold, 1, bodypart_id( "torso" ) ); + m.on_effect_int_change( effect_cold, 1, bodypart_id( "head" ) ); + m.on_effect_int_change( effect_cold, 1, bodypart_id( "eyes" ) ); + m.on_effect_int_change( effect_cold, 1, bodypart_id( "mouth" ) ); + m.on_effect_int_change( effect_cold, 1, bodypart_id( "arm_l" ) ); + m.on_effect_int_change( effect_cold, 1, bodypart_id( "arm_r" ) ); + m.on_effect_int_change( effect_cold, 1, bodypart_id( "leg_l" ) ); + m.on_effect_int_change( effect_cold, 1, bodypart_id( "leg_r" ) ); + m.on_effect_int_change( effect_cold, 1, bodypart_id( "hand_l" ) ); + m.on_effect_int_change( effect_cold, 1, bodypart_id( "hand_r" ) ); + m.on_effect_int_change( effect_cold, 1, bodypart_id( "foot_l" ) ); + m.on_effect_int_change( effect_cold, 1, bodypart_id( "foot_r" ) ); AND_WHEN( "no time has passed" ) { CHECK( m.get_level() == 0 ); @@ -386,18 +386,18 @@ TEST_CASE( "player_morale" ) } WHEN( "cold" ) { - m.on_effect_int_change( effect_cold, 2, bp_torso ); - m.on_effect_int_change( effect_cold, 2, bp_head ); - m.on_effect_int_change( effect_cold, 2, bp_eyes ); - m.on_effect_int_change( effect_cold, 2, bp_mouth ); - m.on_effect_int_change( effect_cold, 2, bp_arm_l ); - m.on_effect_int_change( effect_cold, 2, bp_arm_r ); - m.on_effect_int_change( effect_cold, 2, bp_leg_l ); - m.on_effect_int_change( effect_cold, 2, bp_leg_r ); - m.on_effect_int_change( effect_cold, 2, bp_hand_l ); - m.on_effect_int_change( effect_cold, 2, bp_hand_r ); - m.on_effect_int_change( effect_cold, 2, bp_foot_l ); - m.on_effect_int_change( effect_cold, 2, bp_foot_r ); + m.on_effect_int_change( effect_cold, 2, bodypart_id( "torso" ) ); + m.on_effect_int_change( effect_cold, 2, bodypart_id( "head" ) ); + m.on_effect_int_change( effect_cold, 2, bodypart_id( "eyes" ) ); + m.on_effect_int_change( effect_cold, 2, bodypart_id( "mouth" ) ); + m.on_effect_int_change( effect_cold, 2, bodypart_id( "arm_l" ) ); + m.on_effect_int_change( effect_cold, 2, bodypart_id( "arm_r" ) ); + m.on_effect_int_change( effect_cold, 2, bodypart_id( "leg_l" ) ); + m.on_effect_int_change( effect_cold, 2, bodypart_id( "leg_r" ) ); + m.on_effect_int_change( effect_cold, 2, bodypart_id( "hand_l" ) ); + m.on_effect_int_change( effect_cold, 2, bodypart_id( "hand_r" ) ); + m.on_effect_int_change( effect_cold, 2, bodypart_id( "foot_l" ) ); + m.on_effect_int_change( effect_cold, 2, bodypart_id( "foot_r" ) ); AND_WHEN( "no time has passed" ) { CHECK( m.get_level() == 0 ); @@ -419,18 +419,18 @@ TEST_CASE( "player_morale" ) CHECK( m.get_level() == -20 ); } AND_WHEN( "warmed up afterwards" ) { - m.on_effect_int_change( effect_cold, 0, bp_torso ); - m.on_effect_int_change( effect_cold, 0, bp_head ); - m.on_effect_int_change( effect_cold, 0, bp_eyes ); - m.on_effect_int_change( effect_cold, 0, bp_mouth ); - m.on_effect_int_change( effect_cold, 0, bp_arm_l ); - m.on_effect_int_change( effect_cold, 0, bp_arm_r ); - m.on_effect_int_change( effect_cold, 0, bp_leg_l ); - m.on_effect_int_change( effect_cold, 0, bp_leg_r ); - m.on_effect_int_change( effect_cold, 0, bp_hand_l ); - m.on_effect_int_change( effect_cold, 0, bp_hand_r ); - m.on_effect_int_change( effect_cold, 0, bp_foot_l ); - m.on_effect_int_change( effect_cold, 0, bp_foot_r ); + m.on_effect_int_change( effect_cold, 0, bodypart_id( "torso" ) ); + m.on_effect_int_change( effect_cold, 0, bodypart_id( "head" ) ); + m.on_effect_int_change( effect_cold, 0, bodypart_id( "eyes" ) ); + m.on_effect_int_change( effect_cold, 0, bodypart_id( "mouth" ) ); + m.on_effect_int_change( effect_cold, 0, bodypart_id( "arm_l" ) ); + m.on_effect_int_change( effect_cold, 0, bodypart_id( "arm_r" ) ); + m.on_effect_int_change( effect_cold, 0, bodypart_id( "leg_l" ) ); + m.on_effect_int_change( effect_cold, 0, bodypart_id( "leg_r" ) ); + m.on_effect_int_change( effect_cold, 0, bodypart_id( "hand_l" ) ); + m.on_effect_int_change( effect_cold, 0, bodypart_id( "hand_r" ) ); + m.on_effect_int_change( effect_cold, 0, bodypart_id( "foot_l" ) ); + m.on_effect_int_change( effect_cold, 0, bodypart_id( "foot_r" ) ); m.decay( 1_minutes ); CHECK( m.get_level() == 0 ); @@ -438,18 +438,18 @@ TEST_CASE( "player_morale" ) } WHEN( "warm" ) { - m.on_effect_int_change( effect_hot, 1, bp_torso ); - m.on_effect_int_change( effect_hot, 1, bp_head ); - m.on_effect_int_change( effect_hot, 1, bp_eyes ); - m.on_effect_int_change( effect_hot, 1, bp_mouth ); - m.on_effect_int_change( effect_hot, 1, bp_arm_l ); - m.on_effect_int_change( effect_hot, 1, bp_arm_r ); - m.on_effect_int_change( effect_hot, 1, bp_leg_l ); - m.on_effect_int_change( effect_hot, 1, bp_leg_r ); - m.on_effect_int_change( effect_hot, 1, bp_hand_l ); - m.on_effect_int_change( effect_hot, 1, bp_hand_r ); - m.on_effect_int_change( effect_hot, 1, bp_foot_l ); - m.on_effect_int_change( effect_hot, 1, bp_foot_r ); + m.on_effect_int_change( effect_hot, 1, bodypart_id( "torso" ) ); + m.on_effect_int_change( effect_hot, 1, bodypart_id( "head" ) ); + m.on_effect_int_change( effect_hot, 1, bodypart_id( "eyes" ) ); + m.on_effect_int_change( effect_hot, 1, bodypart_id( "mouth" ) ); + m.on_effect_int_change( effect_hot, 1, bodypart_id( "arm_l" ) ); + m.on_effect_int_change( effect_hot, 1, bodypart_id( "arm_r" ) ); + m.on_effect_int_change( effect_hot, 1, bodypart_id( "leg_l" ) ); + m.on_effect_int_change( effect_hot, 1, bodypart_id( "leg_r" ) ); + m.on_effect_int_change( effect_hot, 1, bodypart_id( "hand_l" ) ); + m.on_effect_int_change( effect_hot, 1, bodypart_id( "hand_r" ) ); + m.on_effect_int_change( effect_hot, 1, bodypart_id( "foot_l" ) ); + m.on_effect_int_change( effect_hot, 1, bodypart_id( "foot_r" ) ); AND_WHEN( "no time has passed" ) { CHECK( m.get_level() == 0 ); @@ -473,18 +473,18 @@ TEST_CASE( "player_morale" ) } WHEN( "hot" ) { - m.on_effect_int_change( effect_hot, 2, bp_torso ); - m.on_effect_int_change( effect_hot, 2, bp_head ); - m.on_effect_int_change( effect_hot, 2, bp_eyes ); - m.on_effect_int_change( effect_hot, 2, bp_mouth ); - m.on_effect_int_change( effect_hot, 2, bp_arm_l ); - m.on_effect_int_change( effect_hot, 2, bp_arm_r ); - m.on_effect_int_change( effect_hot, 2, bp_leg_l ); - m.on_effect_int_change( effect_hot, 2, bp_leg_r ); - m.on_effect_int_change( effect_hot, 2, bp_hand_l ); - m.on_effect_int_change( effect_hot, 2, bp_hand_r ); - m.on_effect_int_change( effect_hot, 2, bp_foot_l ); - m.on_effect_int_change( effect_hot, 2, bp_foot_r ); + m.on_effect_int_change( effect_hot, 2, bodypart_id( "torso" ) ); + m.on_effect_int_change( effect_hot, 2, bodypart_id( "head" ) ); + m.on_effect_int_change( effect_hot, 2, bodypart_id( "eyes" ) ); + m.on_effect_int_change( effect_hot, 2, bodypart_id( "mouth" ) ); + m.on_effect_int_change( effect_hot, 2, bodypart_id( "arm_l" ) ); + m.on_effect_int_change( effect_hot, 2, bodypart_id( "arm_r" ) ); + m.on_effect_int_change( effect_hot, 2, bodypart_id( "leg_l" ) ); + m.on_effect_int_change( effect_hot, 2, bodypart_id( "leg_r" ) ); + m.on_effect_int_change( effect_hot, 2, bodypart_id( "hand_l" ) ); + m.on_effect_int_change( effect_hot, 2, bodypart_id( "hand_r" ) ); + m.on_effect_int_change( effect_hot, 2, bodypart_id( "foot_l" ) ); + m.on_effect_int_change( effect_hot, 2, bodypart_id( "foot_r" ) ); AND_WHEN( "no time has passed" ) { CHECK( m.get_level() == 0 ); @@ -506,18 +506,18 @@ TEST_CASE( "player_morale" ) CHECK( m.get_level() == -20 ); } AND_WHEN( "cooled afterwards" ) { - m.on_effect_int_change( effect_hot, 0, bp_torso ); - m.on_effect_int_change( effect_hot, 0, bp_head ); - m.on_effect_int_change( effect_hot, 0, bp_eyes ); - m.on_effect_int_change( effect_hot, 0, bp_mouth ); - m.on_effect_int_change( effect_hot, 0, bp_arm_l ); - m.on_effect_int_change( effect_hot, 0, bp_arm_r ); - m.on_effect_int_change( effect_hot, 0, bp_leg_l ); - m.on_effect_int_change( effect_hot, 0, bp_leg_r ); - m.on_effect_int_change( effect_hot, 0, bp_hand_l ); - m.on_effect_int_change( effect_hot, 0, bp_hand_r ); - m.on_effect_int_change( effect_hot, 0, bp_foot_l ); - m.on_effect_int_change( effect_hot, 0, bp_foot_r ); + m.on_effect_int_change( effect_hot, 0, bodypart_id( "torso" ) ); + m.on_effect_int_change( effect_hot, 0, bodypart_id( "head" ) ); + m.on_effect_int_change( effect_hot, 0, bodypart_id( "eyes" ) ); + m.on_effect_int_change( effect_hot, 0, bodypart_id( "mouth" ) ); + m.on_effect_int_change( effect_hot, 0, bodypart_id( "arm_l" ) ); + m.on_effect_int_change( effect_hot, 0, bodypart_id( "arm_r" ) ); + m.on_effect_int_change( effect_hot, 0, bodypart_id( "leg_l" ) ); + m.on_effect_int_change( effect_hot, 0, bodypart_id( "leg_r" ) ); + m.on_effect_int_change( effect_hot, 0, bodypart_id( "hand_l" ) ); + m.on_effect_int_change( effect_hot, 0, bodypart_id( "hand_r" ) ); + m.on_effect_int_change( effect_hot, 0, bodypart_id( "foot_l" ) ); + m.on_effect_int_change( effect_hot, 0, bodypart_id( "foot_r" ) ); m.decay( 1_minutes ); CHECK( m.get_level() == 0 ); diff --git a/tests/new_character_test.cpp b/tests/new_character_test.cpp index dfc98a4ae9a6b..fb9fed14d456c 100644 --- a/tests/new_character_test.cpp +++ b/tests/new_character_test.cpp @@ -13,6 +13,7 @@ #include #include "avatar.h" +#include "inventory.h" #include "item.h" #include "item_contents.h" #include "itype.h" @@ -149,7 +150,7 @@ TEST_CASE( "starting_items", "[slow]" ) for( int i = 0; i < 2; i++ ) { player_character.worn.clear(); player_character.remove_weapon(); - player_character.inv.clear(); + player_character.inv->clear(); player_character.calc_encumbrance(); player_character.male = i == 0; @@ -160,7 +161,7 @@ TEST_CASE( "starting_items", "[slow]" ) return VisitResponse::NEXT; }; player_character.visit_items( visitable_counter ); - player_character.inv.visit_items( visitable_counter ); + player_character.inv->visit_items( visitable_counter ); const int num_items_pre_migration = items_visited.size(); items_visited.clear(); diff --git a/tests/player_helpers.cpp b/tests/player_helpers.cpp index 20a49b3ec58b7..5bcd71d45878e 100644 --- a/tests/player_helpers.cpp +++ b/tests/player_helpers.cpp @@ -11,6 +11,7 @@ #include "bionics.h" #include "character.h" #include "character_id.h" +#include "character_martial_arts.h" #include "game.h" #include "inventory.h" #include "item.h" @@ -41,7 +42,7 @@ int get_remaining_charges( const std::string &tool_id ) bool player_has_item_of_type( const std::string &type ) { - std::vector matching_items = get_player_character().inv.items_with( + std::vector matching_items = get_player_character().inv->items_with( [&]( const item & i ) { return i.type->get_id() == itype_id( type ); } ); @@ -57,7 +58,7 @@ void clear_character( player &dummy, bool debug_storage ) // delete all worn items. dummy.worn.clear(); dummy.calc_encumbrance(); - dummy.inv.clear(); + dummy.inv->clear(); dummy.remove_weapon(); dummy.clear_mutations(); @@ -74,7 +75,7 @@ void clear_character( player &dummy, bool debug_storage ) dummy.consume( food ); dummy.empty_skills(); - dummy.martial_arts_data.clear_styles(); + dummy.martial_arts_data->clear_styles(); dummy.clear_morale(); dummy.clear_bionics(); dummy.activity.set_to_null(); diff --git a/tests/ranged_balance_test.cpp b/tests/ranged_balance_test.cpp index 3ea9ba343b9a6..f258ae4bcf5e7 100644 --- a/tests/ranged_balance_test.cpp +++ b/tests/ranged_balance_test.cpp @@ -123,7 +123,7 @@ static void equip_shooter( npc &shooter, const std::vector &apparel { CHECK( !shooter.in_vehicle ); shooter.worn.clear(); - shooter.inv.clear(); + shooter.inv->clear(); for( const std::string &article : apparel ) { shooter.wear_item( item( article ) ); } diff --git a/tests/reading_test.cpp b/tests/reading_test.cpp index eaa73dfb7101f..3c9503ffe4300 100644 --- a/tests/reading_test.cpp +++ b/tests/reading_test.cpp @@ -271,7 +271,7 @@ TEST_CASE( "reasons for not being able to read", "[reading][reasons]" ) } SECTION( "you cannot read in darkness" ) { - dummy.add_env_effect( efftype_id( "darkness" ), bp_eyes, 3, 1_hours ); + dummy.add_env_effect( efftype_id( "darkness" ), bodypart_id( "eyes" ), 3, 1_hours ); REQUIRE( dummy.fine_detail_vision_mod() > 4 ); CHECK( dummy.get_book_reader( child, reasons ) == nullptr ); diff --git a/tests/reload_magazine_test.cpp b/tests/reload_magazine_test.cpp index b84b59208a47e..967bce4dec6e9 100644 --- a/tests/reload_magazine_test.cpp +++ b/tests/reload_magazine_test.cpp @@ -33,7 +33,7 @@ TEST_CASE( "reload_magazine", "[magazine] [visitable] [item] [item_location]" ) Character &player_character = get_player_character(); player_character.worn.clear(); - player_character.inv.clear(); + player_character.inv->clear(); player_character.remove_weapon(); player_character.wear_item( item( "backpack" ) ); // so we don't drop anything diff --git a/tests/requirements_test.cpp b/tests/requirements_test.cpp index bb883e2a901fd..89cc05512d1b4 100644 --- a/tests/requirements_test.cpp +++ b/tests/requirements_test.cpp @@ -6,7 +6,7 @@ #include #include -static const itype_id itype_acid( "acid" ); +static const itype_id itype_chem_sulphuric_acid( "chem_sulphuric_acid" ); static const itype_id itype_ash( "ash" ); static const itype_id itype_lye( "lye" ); static const itype_id itype_rock( "rock" ); @@ -87,12 +87,12 @@ TEST_CASE( "triple_overlap_2", "[requirement]" ) test_requirement_deduplication( { { { itype_rock, 1 }, { itype_soap, 1 } }, { { itype_rock, 1 }, { itype_yarn, 1 } }, - { { itype_soap, 1 }, { itype_acid, 1 } } + { { itype_soap, 1 }, { itype_chem_sulphuric_acid, 1 } } }, { - { { { itype_soap, 1 } }, { { itype_rock, 1 }, { itype_yarn, 1 } }, { { itype_acid, 1 } } }, + { { { itype_soap, 1 } }, { { itype_rock, 1 }, { itype_yarn, 1 } }, { { itype_chem_sulphuric_acid, 1 } } }, { { { itype_rock, 1 }, { itype_yarn, 1 } }, { { itype_soap, 2 } } }, - { { { itype_rock, 1 } }, { { itype_yarn, 1 } }, { { itype_acid, 1 }, { itype_soap, 1 } } }, - { { { itype_rock, 2 } }, { { itype_acid, 1 }, { itype_soap, 1 } } }, + { { { itype_rock, 1 } }, { { itype_yarn, 1 } }, { { itype_chem_sulphuric_acid, 1 }, { itype_soap, 1 } } }, + { { { itype_rock, 2 } }, { { itype_chem_sulphuric_acid, 1 }, { itype_soap, 1 } } }, } ); } diff --git a/tests/stomach_contents_test.cpp b/tests/stomach_contents_test.cpp index fc67460fcf5a9..d08ee4707d176 100644 --- a/tests/stomach_contents_test.cpp +++ b/tests/stomach_contents_test.cpp @@ -103,9 +103,9 @@ TEST_CASE( "starve_test", "[starve][slow]" ) // A specific BMR isn't the real target of this test, the number of days // is, but it helps to debug the test faster if this value is wrong. - REQUIRE( dummy.get_bmr() == 2087 ); + REQUIRE( dummy.get_bmr() == 1739 ); - constexpr int expected_day = 30; + constexpr int expected_day = 36; int day = 0; std::vector results; @@ -155,7 +155,7 @@ TEST_CASE( "starve_test_hunger3", "[starve][slow]" ) } while( dummy.get_stored_kcal() > 0 ); CAPTURE( results ); - CHECK( day <= 11 ); + CHECK( day <= 12 ); CHECK( day >= 10 ); } diff --git a/tests/throwing_test.cpp b/tests/throwing_test.cpp index 07649ce6a0784..d6ad93d9dcee0 100644 --- a/tests/throwing_test.cpp +++ b/tests/throwing_test.cpp @@ -69,7 +69,7 @@ static void reset_player( Character &p, const throw_test_pstats &pstats, const t p.set_per_bonus( 0 ); p.set_dex_bonus( 0 ); p.worn.clear(); - p.inv.clear(); + p.inv->clear(); p.remove_weapon(); p.set_skill_level( skill_throw, pstats.skill_lvl ); } diff --git a/tests/vehicle_drag_test.cpp b/tests/vehicle_drag_test.cpp index 6d5c45d6bc1eb..4e27613c71b9a 100644 --- a/tests/vehicle_drag_test.cpp +++ b/tests/vehicle_drag_test.cpp @@ -33,7 +33,7 @@ static void clear_game_drag( const ter_id &terrain ) CHECK( !player_character.in_vehicle ); player_character.setpos( tripoint_zero ); // Blind the player to avoid needless drawing-related overhead - player_character.add_effect( effect_blind, 1_turns, num_bp, true ); + player_character.add_effect( effect_blind, 1_turns, true ); // Make sure the ST is 8 so that muscle powered results are consistent player_character.str_cur = 8; diff --git a/tests/vehicle_efficiency_test.cpp b/tests/vehicle_efficiency_test.cpp index 45f925ff1cbf1..34de472019d62 100644 --- a/tests/vehicle_efficiency_test.cpp +++ b/tests/vehicle_efficiency_test.cpp @@ -48,7 +48,7 @@ static void clear_game( const ter_id &terrain ) REQUIRE_FALSE( player_character.in_vehicle ); player_character.setpos( tripoint_zero ); // Blind the player to avoid needless drawing-related overhead - player_character.add_effect( effect_blind, 1_turns, num_bp, true ); + player_character.add_effect( effect_blind, 1_turns, true ); build_test_map( terrain ); } @@ -166,7 +166,8 @@ const int cycle_limit = 100; static int test_efficiency( const vproto_id &veh_id, int &expected_mass, const ter_id &terrain, const int reset_velocity_turn, const int target_distance, - const bool smooth_stops = false, const bool test_mass = true ) + const bool smooth_stops = false, const bool test_mass = true, + const bool in_reverse = false ) { int min_dist = target_distance * 0.99; int max_dist = target_distance * 1.01; @@ -210,7 +211,8 @@ static int test_efficiency( const vproto_id &veh_id, int &expected_mass, veh.tags.insert( "IN_CONTROL_OVERRIDE" ); veh.engine_on = true; - const int target_velocity = std::min( 70 * 100, veh.safe_ground_velocity( false ) ); + const int sign = in_reverse ? -1 : 1; + const int target_velocity = sign * std::min( 50 * 100, veh.safe_ground_velocity( false ) ); veh.cruise_velocity = target_velocity; // If we aren't testing repeated cold starts, start the vehicle at cruising velocity. // Otherwise changing the amount of fuel in the tank perturbs the test results. @@ -268,12 +270,12 @@ static int test_efficiency( const vproto_id &veh_id, int &expected_mass, static efficiency_stat find_inner( const std::string &type, int &expected_mass, const std::string &terrain, const int delay, - const bool smooth, const bool test_mass = false ) + const bool smooth, const bool test_mass = false, const bool in_reverse = false ) { efficiency_stat efficiency; for( int i = 0; i < 10; i++ ) { efficiency.add( test_efficiency( vproto_id( type ), expected_mass, ter_id( terrain ), - delay, -1, smooth, test_mass ) ); + delay, -1, smooth, test_mass, in_reverse ) ); } return efficiency; } @@ -317,57 +319,64 @@ static int average_from_stat( const efficiency_stat &st ) } // Behold: power of laziness -static void print_test_strings( const std::string &type ) +static int print_test_strings( const std::string &type, const bool in_reverse = false ) { std::ostringstream ss; int expected_mass = 0; ss << " test_vehicle( \"" << type << "\", "; const int d_pave = average_from_stat( find_inner( type, expected_mass, "t_pavement", -1, - false, false ) ); + false, false, in_reverse ) ); ss << expected_mass << ", " << d_pave << ", "; ss << average_from_stat( find_inner( type, expected_mass, "t_dirt", -1, - false, false ) ) << ", "; + false, false, in_reverse ) ) << ", "; ss << average_from_stat( find_inner( type, expected_mass, "t_pavement", 5, - false, false ) ) << ", "; - ss << average_from_stat( find_inner( type, expected_mass, "t_dirt", 5, false, false ) ); + false, false, in_reverse ) ) << ", "; + ss << average_from_stat( find_inner( type, expected_mass, "t_dirt", 5, + false, false, in_reverse ) ); //ss << average_from_stat( find_inner( type, "t_pavement", 5, true ) ) << ", "; //ss << average_from_stat( find_inner( type, "t_dirt", 5, true ) ); + if( in_reverse ) { + ss << ", 0, 0, true"; + } ss << " );" << std::endl; printf( "%s", ss.str().c_str() ); fflush( stdout ); + return d_pave; } static void test_vehicle( const std::string &type, int expected_mass, const int pavement_target, const int dirt_target, const int pavement_target_w_stops, const int dirt_target_w_stops, - const int pavement_target_smooth_stops = 0, const int dirt_target_smooth_stops = 0 ) + const int pavement_target_smooth_stops = 0, const int dirt_target_smooth_stops = 0, + const bool in_reverse = false ) { SECTION( type + " on pavement" ) { test_efficiency( vproto_id( type ), expected_mass, ter_id( "t_pavement" ), -1, - pavement_target ); + pavement_target, false, true, in_reverse ); } SECTION( type + " on dirt" ) { - test_efficiency( vproto_id( type ), expected_mass, ter_id( "t_dirt" ), -1, dirt_target ); + test_efficiency( vproto_id( type ), expected_mass, ter_id( "t_dirt" ), -1, + dirt_target, false, true, in_reverse ); } SECTION( type + " on pavement, full stop every 5 turns" ) { test_efficiency( vproto_id( type ), expected_mass, ter_id( "t_pavement" ), 5, - pavement_target_w_stops ); + pavement_target_w_stops, false, true, in_reverse ); } SECTION( type + " on dirt, full stop every 5 turns" ) { test_efficiency( vproto_id( type ), expected_mass, ter_id( "t_dirt" ), 5, - dirt_target_w_stops ); + dirt_target_w_stops, false, true, in_reverse ); } if( pavement_target_smooth_stops > 0 ) { SECTION( type + " on pavement, alternating 5 turns of acceleration and 5 turns of decceleration" ) { test_efficiency( vproto_id( type ), expected_mass, ter_id( "t_pavement" ), 5, - pavement_target_smooth_stops, true ); + pavement_target_smooth_stops, true, true, in_reverse ); } } if( dirt_target_smooth_stops > 0 ) { SECTION( type + " on dirt, alternating 5 turns of acceleration and 5 turns of decceleration" ) { test_efficiency( vproto_id( type ), expected_mass, ter_id( "t_dirt" ), 5, - dirt_target_smooth_stops, true ); + dirt_target_smooth_stops, true, true, in_reverse ); } } } @@ -405,10 +414,18 @@ TEST_CASE( "vehicle_find_efficiency", "[.]" ) } /** This is even less of a test. It generates C++ lines for the actual test below */ -TEST_CASE( "vehicle_make_efficiency_case", "[.]" ) +TEST_CASE( "make_vehicle_efficiency_case", "[.]" ) { + const float acceptable = 1.25; + std::map forward_distance; + for( const std::string &veh : vehs_to_test ) { + const int in_forward = print_test_strings( veh ); + forward_distance[ veh ] = in_forward; + } + printf( "// in reverse\n" ); for( const std::string &veh : vehs_to_test ) { - print_test_strings( veh ); + const int in_reverse = print_test_strings( veh, true ); + CHECK( in_reverse < ( acceptable * forward_distance[ veh ] ) ); } } @@ -418,22 +435,41 @@ TEST_CASE( "vehicle_make_efficiency_case", "[.]" ) // Fix test for electric vehicles TEST_CASE( "vehicle_efficiency", "[vehicle] [engine]" ) { - test_vehicle( "beetle", 816469, 277800, 211800, 70490, 53160 ); - test_vehicle( "car", 1120618, 473700, 278400, 45440, 25170 ); - test_vehicle( "car_sports", 1155014, 360300, 260700, 36450, 20770 ); - test_vehicle( "electric_car", 1047135, 220900, 127900, 18490, 9907 ); - test_vehicle( "suv", 1320286, 902100, 451700, 67740, 31840 ); - test_vehicle( "motorcycle", 163085, 74030, 61250, 46200, 37970 ); - test_vehicle( "quad_bike", 265345, 73170, 73170, 34300, 34300 ); + test_vehicle( "beetle", 816469, 431300, 338700, 95610, 68060 ); + test_vehicle( "car", 1120618, 617500, 388600, 52730, 25170 ); + test_vehicle( "car_sports", 1155014, 352600, 267600, 36820, 22360 ); + test_vehicle( "electric_car", 1047135, 355300, 201600, 22400, 10780 ); + test_vehicle( "suv", 1320286, 1163000, 630000, 85540, 31840 ); + test_vehicle( "motorcycle", 163085, 120300, 100900, 63320, 50810 ); + test_vehicle( "quad_bike", 265345, 116100, 116100, 46770, 46770 ); test_vehicle( "scooter", 55941, 235900, 235900, 174700, 174700 ); - test_vehicle( "superbike", 242085, 68920, 45200, 33670, 21300 ); - test_vehicle( "ambulance", 1839299, 409800, 326700, 62500, 44030 ); - test_vehicle( "fire_engine", 2628611, 1136000, 927800, 242300, 209600 ); - test_vehicle( "fire_truck", 6314603, 288800, 180900, 19470, 4461 ); - test_vehicle( "truck_swat", 5959334, 483800, 323200, 29610, 7604 ); - test_vehicle( "tractor_plow", 723658, 482400, 482400, 114200, 114200 ); - test_vehicle( "apc", 5801619, 1069000, 923000, 130800, 85590 ); - test_vehicle( "humvee", 5503345, 574300, 325900, 25620, 9171 ); - test_vehicle( "road_roller", 8829220, 357200, 380200, 22760, 6925 ); - test_vehicle( "golf_cart", 444630, 52460, 105500, 27250, 14200 ); + test_vehicle( "superbike", 242085, 109800, 65300, 41780, 24070 ); + test_vehicle( "ambulance", 1839299, 623000, 511100, 78160, 58670 ); + test_vehicle( "fire_engine", 2628611, 1885000, 1566000, 335800, 259200 ); + test_vehicle( "fire_truck", 6314603, 410700, 83850, 19470, 4461 ); + test_vehicle( "truck_swat", 5959334, 682900, 131900, 29610, 7604 ); + test_vehicle( "tractor_plow", 723658, 681200, 681200, 132700, 132700 ); + test_vehicle( "apc", 5801619, 1626000, 1119000, 130800, 85590 ); + test_vehicle( "humvee", 5503345, 767900, 306900, 25620, 9171 ); + test_vehicle( "road_roller", 8829220, 602500, 147100, 22760, 6925 ); + test_vehicle( "golf_cart", 444630, 96000, 69390, 35490, 14200 ); + // in reverse + test_vehicle( "beetle", 816469, 58970, 58870, 44560, 43060, 0, 0, true ); + test_vehicle( "car", 1120618, 76060, 76060, 44230, 24920, 0, 0, true ); + test_vehicle( "car_sports", 1155014, 353200, 268000, 35220, 19540, 0, 0, true ); + test_vehicle( "electric_car", 1047135, 356400, 202300, 22450, 10810, 0, 0, true ); + test_vehicle( "suv", 1320286, 112000, 111700, 66880, 31640, 0, 0, true ); + test_vehicle( "motorcycle", 163085, 19980, 19030, 15490, 14890, 0, 0, true ); + test_vehicle( "quad_bike", 265345, 19650, 19650, 15440, 15440, 0, 0, true ); + test_vehicle( "scooter", 55941, 58790, 58790, 46320, 46320, 0, 0, true ); + test_vehicle( "superbike", 242085, 18320, 10570, 13100, 8497, 0, 0, true ); + test_vehicle( "ambulance", 1839299, 58510, 57740, 42480, 39080, 0, 0, true ); + test_vehicle( "fire_engine", 2628611, 258000, 257600, 181200, 173500, 0, 0, true ); + test_vehicle( "fire_truck", 6314603, 58440, 58720, 18920, 4480, 0, 0, true ); + test_vehicle( "truck_swat", 5959334, 129300, 130100, 29350, 7668, 0, 0, true ); + test_vehicle( "tractor_plow", 723658, 72490, 72490, 53700, 53700, 0, 0, true ); + test_vehicle( "apc", 5801619, 381500, 382100, 123600, 82000, 0, 0, true ); + test_vehicle( "humvee", 5503345, 89940, 89940, 25780, 9086, 0, 0, true ); + test_vehicle( "road_roller", 8829220, 97490, 97690, 22880, 6606, 0, 0, true ); + test_vehicle( "golf_cart", 444630, 96150, 28800, 35560, 11150, 0, 0, true ); } diff --git a/tests/vehicle_power_test.cpp b/tests/vehicle_power_test.cpp index 57224e0a02d48..9bba28db6987f 100644 --- a/tests/vehicle_power_test.cpp +++ b/tests/vehicle_power_test.cpp @@ -26,7 +26,7 @@ static void reset_player() REQUIRE( !player_character.in_vehicle ); player_character.setpos( tripoint_zero ); // Blind the player to avoid needless drawing-related overhead - player_character.add_effect( effect_blind, 1_turns, num_bp, true ); + player_character.add_effect( effect_blind, 1_turns, true ); } TEST_CASE( "vehicle power with reactor and solar panels", "[vehicle][power]" ) diff --git a/tests/visitable_remove_test.cpp b/tests/visitable_remove_test.cpp index 5d4bafe0cf891..8f8bcc57a63df 100644 --- a/tests/visitable_remove_test.cpp +++ b/tests/visitable_remove_test.cpp @@ -48,7 +48,7 @@ TEST_CASE( "visitable_remove", "[visitable]" ) Character &p = get_player_character(); p.worn.clear(); p.worn.push_back( item( "backpack" ) ); - p.inv.clear(); + p.inv->clear(); p.remove_weapon(); p.wear_item( item( "backpack" ) ); // so we don't drop anything map &here = get_map(); diff --git a/tests/wield_times_test.cpp b/tests/wield_times_test.cpp index 2685358c0ac28..79a690f16e1ed 100644 --- a/tests/wield_times_test.cpp +++ b/tests/wield_times_test.cpp @@ -81,7 +81,7 @@ TEST_CASE( "Wield time test", "[wield]" ) item_location knife_loc( sheath_loc, &sheath_loc->contents.only_item() ); const int knife_obtain_cost = knife_loc.obtain_cost( guy ); - REQUIRE( knife_obtain_cost == 1257 ); + REQUIRE( knife_obtain_cost == 112 ); } SECTION( "Wielding without hand encumbrance" ) { diff --git a/tools/copy_from.py b/tools/copy_from.py index b8dc3157a07c0..ad0699acbc99c 100755 --- a/tools/copy_from.py +++ b/tools/copy_from.py @@ -5,23 +5,24 @@ IGNORE_MISMATCH = ["id", "abstract"] + def get_data(argsDict, resource_name): - resource = [] - resource_sources = argsDict.get(resource_name, []) - if not isinstance(resource_sources, list): - resource_sources = [resource_sources] - for resource_filename in resource_sources: - if resource_filename.endswith(".json"): - try: - with open(resource_filename) as resource_file: - resource += json.load(resource_file) - except FileNotFoundError: - exit("Failed: could not find {}".format(resource_filename)) - else: - print("Invalid filename {}".format(resource_filename)) - if not resource: + resource = [] + resource_sources = argsDict.get(resource_name, []) + if not isinstance(resource_sources, list): + resource_sources = [resource_sources] + for resource_filename in resource_sources: + if resource_filename.endswith(".json"): + try: + with open(resource_filename) as resource_file: + resource += json.load(resource_file) + except FileNotFoundError: + exit("Failed: could not find {}".format(resource_filename)) + else: + print(("Invalid filename {}".format(resource_filename))) + if not resource: exit("Failed: {} was empty".format(resource_filename)) - return resource + return resource args = argparse.ArgumentParser(description="Make items use copy-from.") @@ -45,9 +46,9 @@ def get_data(argsDict, resource_name): del_keys = [] for key in item: if key == "type": - continue + continue if item[key] == base_item.get(key): - del_keys.append(key) + del_keys.append(key) can_copy = True for key in base_item: if key in del_keys: diff --git a/tools/dialogue_validator.py b/tools/dialogue_validator.py index 263e26db9f9f9..7557f744b67d3 100755 --- a/tools/dialogue_validator.py +++ b/tools/dialogue_validator.py @@ -22,6 +22,7 @@ "to validate the dialogue in the vanilla game.") argsDict = vars(args.parse_args()) + def get_dialogue_from_json(): dialogue = [] @@ -29,14 +30,14 @@ def get_dialogue_from_json(): if arg_path.endswith("/"): arg_path = arg_path[:-1] for subdir_path, dirnames, filenames in os.walk(arg_path): - for filename in filenames: - path = subdir_path + "/" + filename - if path == "data/json/npcs/TALK_TEST.json": - continue - if path.endswith(".json"): - with open(path) as dialogue_file: - dialogue += json.load(dialogue_file) - + for filename in filenames: + path = subdir_path + "/" + filename + if path == "data/json/npcs/TALK_TEST.json": + continue + if path.endswith(".json"): + with open(path) as dialogue_file: + dialogue += json.load(dialogue_file) + return dialogue @@ -88,7 +89,7 @@ def parse_response(topics, response, topic_branches=None, this_ids=None): failure_r = response.get("failure", {}) add_topic_by_response(topics, failure_r, topic_branches, this_ids) - + def validate(dialogue): topics = {} topic_branches = { @@ -97,25 +98,25 @@ def validate(dialogue): "TALK_SEDATED": {"responses": ["TALK_DONE"], "ends": True, "parent": None}, } # defined in src/npctalk.cpp - defined_ids = [ "TALK_NONE", "TALK_DONE", "TALK_TRAIN", "TALK_HOW_MUCH_FURTHER", - "TALK_SEDATED" ] + defined_ids = ["TALK_NONE", "TALK_DONE", "TALK_TRAIN", "TALK_HOW_MUCH_FURTHER", + "TALK_SEDATED"] for topic_id in defined_ids: add_topic_by_id(topics, topic_id) # referenced in src/npctalk.cpp - refered_ids = [ "TALK_WAKE_UP", "TALK_RADIO", "TALK_MISSION_DESCRIBE_URGENT", - "TALK_MISSION_DESCRIBE", "TALK_SHELTER", "TALK_SIZE_UP", "TALK_LOOK_AT", - "TALK_OPINION", "TALK_SHOUT", "TALK_STRANGER_AGGRESSIVE", "TALK_LEADER", - "TALK_TRAIN_START", "TALK_STOLE_ITEM", "TALK_SEDATED" ] + refered_ids = ["TALK_WAKE_UP", "TALK_RADIO", "TALK_MISSION_DESCRIBE_URGENT", + "TALK_MISSION_DESCRIBE", "TALK_SHELTER", "TALK_SIZE_UP", "TALK_LOOK_AT", + "TALK_OPINION", "TALK_SHOUT", "TALK_STRANGER_AGGRESSIVE", "TALK_LEADER", + "TALK_TRAIN_START", "TALK_STOLE_ITEM", "TALK_SEDATED"] for topic_id in refered_ids: add_topic_by_chat(topics, topic_id) # TALK_TRAIN_START is technically not a start id - start_topics = [ "TALK_RADIO", "TALK_LEADER", "TALK_FRIEND", "TALK_STOLE_ITEM", - "TALK_MISSION_DESCRIBE_URGENT", "TALK_SEDATED", "TALK_WAKE_UP", - "TALK_MUG", "TALK_STRANGER_AGGRESSIVE", "TALK_STRANGER_SCARED", - "TALK_STRANGER_WARY", "TALK_STRANGER_FRIENDLY", "TALK_STRANGER_NEUTRAL", - "TALK_SHELTER", "TALK_CAMP_OVERSEER" ] + start_topics = ["TALK_RADIO", "TALK_LEADER", "TALK_FRIEND", "TALK_STOLE_ITEM", + "TALK_MISSION_DESCRIBE_URGENT", "TALK_SEDATED", "TALK_WAKE_UP", + "TALK_MUG", "TALK_STRANGER_AGGRESSIVE", "TALK_STRANGER_SCARED", + "TALK_STRANGER_WARY", "TALK_STRANGER_FRIENDLY", "TALK_STRANGER_NEUTRAL", + "TALK_SHELTER", "TALK_CAMP_OVERSEER"] for talk_topic in dialogue: if not isinstance(talk_topic, dict): continue @@ -212,4 +213,5 @@ def validate(dialogue): if not branch_record["parent"] in start_topics: print("no path from a start topic to {}".format(topic_id)) + validate(get_dialogue_from_json()) diff --git a/tools/fix-compilation-database.py b/tools/fix-compilation-database.py index 8c8ee15a3f314..4189626bbb0fc 100755 --- a/tools/fix-compilation-database.py +++ b/tools/fix-compilation-database.py @@ -13,7 +13,7 @@ data = None with open(compile_db, 'r', encoding="utf-8") as fs: - data = json.load( fs ) + data = json.load(fs) for j in range(len(data)): directory = data[j]["directory"] @@ -24,7 +24,7 @@ rsp_path = os.path.join(directory, command[i][1:]) with open(rsp_path, 'r', encoding="utf-8") as rsp: newflags = shlex.split(rsp.read()) - command = command[:i] + newflags + command[i+1:] + command = command[:i] + newflags + command[i + 1:] i = i + len(newflags) else: match_result = starts_with_drive_letter.match(command[i]) diff --git a/tools/generate_changelog.py b/tools/generate_changelog.py index 3820749ef850f..48ba0c46aeb13 100755 --- a/tools/generate_changelog.py +++ b/tools/generate_changelog.py @@ -22,7 +22,8 @@ log = logging.getLogger('generate_changelog') -class MissingCommitException(Exception): pass +class MissingCommitException(Exception): + pass class JenkinsBuild: @@ -134,7 +135,7 @@ class SummaryType: class CDDAPullRequest(PullRequest): """A Pull Request with logic specific to CDDA Repository and their "Summary" descriptions""" - SUMMARY_REGEX = re.compile( r'^`*(?i:SUMMARY):\s+(?P\w+)\s*(?:"(?P.+)")?', re.MULTILINE ) + SUMMARY_REGEX = re.compile(r'^`*(?i:SUMMARY):\s+(?P\w+)\s*(?:"(?P.+)")?', re.MULTILINE) VALID_SUMMARY_CATEGORIES = ( 'Content', @@ -206,6 +207,7 @@ def create(self, number, last_hash, branch, build_dttm, is_building, build_resul return JenkinsBuild(number, last_hash, branch, build_dttm, is_building, build_result, block_ms, wait_ms, build_ms) + class CommitFactory: """Abstraction for instantiation of new Commit objects""" diff --git a/tools/gfx_tools/compose.py b/tools/gfx_tools/compose.py index 3ad7c50a89e9d..c5db91317cd6a 100755 --- a/tools/gfx_tools/compose.py +++ b/tools/gfx_tools/compose.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # compose.py # Split a gfx directory made of 1000s of little images and files into a set of tilesheets @@ -22,34 +22,31 @@ "file": "fallback.png", "tiles": [], "ascii": [ - { "offset": 0, "bold": False, "color": "BLACK" }, - { "offset": 256, "bold": True, "color": "WHITE" }, - { "offset": 512, "bold": False, "color": "WHITE" }, - { "offset": 768, "bold": True, "color": "BLACK" }, - { "offset": 1024, "bold": False, "color": "RED" }, - { "offset": 1280, "bold": False, "color": "GREEN" }, - { "offset": 1536, "bold": False, "color": "BLUE" }, - { "offset": 1792, "bold": False, "color": "CYAN" }, - { "offset": 2048, "bold": False, "color": "MAGENTA" }, - { "offset": 2304, "bold": False, "color": "YELLOW" }, - { "offset": 2560, "bold": True, "color": "RED" }, - { "offset": 2816, "bold": True, "color": "GREEN" }, - { "offset": 3072, "bold": True, "color": "BLUE" }, - { "offset": 3328, "bold": True, "color": "CYAN" }, - { "offset": 3584, "bold": True, "color": "MAGENTA" }, - { "offset": 3840, "bold": True, "color": "YELLOW" } + {"offset": 0, "bold": False, "color": "BLACK"}, + {"offset": 256, "bold": True, "color": "WHITE"}, + {"offset": 512, "bold": False, "color": "WHITE"}, + {"offset": 768, "bold": True, "color": "BLACK"}, + {"offset": 1024, "bold": False, "color": "RED"}, + {"offset": 1280, "bold": False, "color": "GREEN"}, + {"offset": 1536, "bold": False, "color": "BLUE"}, + {"offset": 1792, "bold": False, "color": "CYAN"}, + {"offset": 2048, "bold": False, "color": "MAGENTA"}, + {"offset": 2304, "bold": False, "color": "YELLOW"}, + {"offset": 2560, "bold": True, "color": "RED"}, + {"offset": 2816, "bold": True, "color": "GREEN"}, + {"offset": 3072, "bold": True, "color": "BLUE"}, + {"offset": 3328, "bold": True, "color": "CYAN"}, + {"offset": 3584, "bold": True, "color": "MAGENTA"}, + {"offset": 3840, "bold": True, "color": "YELLOW"} ] } error_logged = False -# stupid stinking Python 2 versus Python 3 syntax + def write_to_json(pathname, data): with open(pathname, "w") as fp: - try: - json.dump(data, fp) - except ValueError: - fp.write(json.dumps(data)) + json.dump(data, fp) json_formatter = "./tools/format/json_formatter.cgi" if os.path.isfile(json_formatter): @@ -67,9 +64,9 @@ def find_or_make_dir(pathname): class PngRefs(object): def __init__(self, tileset_dirname): # dict of pngnames to png numbers; used to control uniqueness - self.pngname_to_pngnum = { "null_image": 0 } + self.pngname_to_pngnum = {"null_image": 0} # dict of png absolute numbers to png names - self.pngnum_to_pngname = { 0: "null_image" } + self.pngnum_to_pngname = {0: "null_image"} self.pngnum = 0 self.referenced_pngnames = [] self.tileset_pathname = tileset_dirname @@ -206,7 +203,7 @@ def __init__(self, subdir_index, refs): self.null_image = Vips.Image.grey(self.width, self.height) self.row_pngs = ["null_image"] self.filler = False - self.fallback = False; + self.fallback = False if self.ts_specs.get("fallback"): self.fallback = True return @@ -229,7 +226,7 @@ def merge_row(self, refs): refs.pngnum += spacer in_list = [] - + for png_pathname in self.row_pngs: if png_pathname == "null_image": in_list.append(self.null_image) @@ -303,6 +300,7 @@ def finalize_merges(self, merge_pngs): out_image = Vips.Image.arrayjoin(merge_pngs, across=16) out_image.pngsave(self.ts_path) + args = argparse.ArgumentParser(description="Merge all the individal tile_entries and pngs in a tileset's directory into a tile_config.json and 1 or more tilesheet pngs.") args.add_argument("tileset_dir", action="store", help="local name of the tileset directory") @@ -351,7 +349,7 @@ def finalize_merges(self, merge_pngs): #print("pngnum to pngname {}".format(json.dumps(refs.pngnum_to_pngname, sort_keys=True, indent=2))) tiles_new = [] - + for ts_data in all_ts_data: if ts_data.fallback: fallback_name = ts_data.ts_name diff --git a/tools/gfx_tools/decompose.py b/tools/gfx_tools/decompose.py index 770ca0678b539..166dba093c9dd 100755 --- a/tools/gfx_tools/decompose.py +++ b/tools/gfx_tools/decompose.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # decompose.py # Split a gfx tile_config.json into 1000s of little directories, each with their own config @@ -9,6 +9,7 @@ import math import os import subprocess +import sys try: import pyvips @@ -18,13 +19,10 @@ gi.require_version('Vips', '8.0') from gi.repository import Vips -# stupid stinking Python 2 versus Python 3 syntax + def write_to_json(pathname, data, prettify=False): with open(pathname, "w") as fp: - try: - json.dump(data, fp) - except ValueError: - fp.write(json.dumps(data)) + json.dump(data, fp) json_formatter = "./tools/format/json_formatter.cgi" if prettify and os.path.isfile(json_formatter): @@ -214,6 +212,7 @@ def summarize(self, tile_info, refs): #print("{}: {}".format(self.ts_filename, json.dumps(ts_tile_info, indent=2))) tile_info.append({self.ts_filename: ts_tile_info}) + class ExtractionData(object): def __init__(self, ts_filename, refs): self.ts_data = refs.ts_data.get(ts_filename) @@ -225,7 +224,7 @@ def __init__(self, ts_filename, refs): ts_base = ts_filename.split(".png")[0] geometry_dim = "{}x{}".format(self.ts_data.sprite_width, self.ts_data.sprite_height) - pngs_dir = "/pngs_" + ts_base + "_{}".format(geometry_dim) + pngs_dir = "/pngs_" + ts_base + "_{}".format(geometry_dim) self.ts_dir_pathname = refs.tileset_pathname + pngs_dir find_or_make_dir(self.ts_dir_pathname) self.tilenum_in_dir = 256 @@ -261,7 +260,7 @@ def extract_image(self, png_index, refs): self.increment_dir() tile_data = refs.ts_data[ts_filename] file_index = png_index - tile_data.pngnum_min - y_index = math.floor( file_index / tile_data.ts_tiles_per_row ) + y_index = math.floor(file_index / tile_data.ts_tiles_per_row) x_index = file_index - y_index * tile_data.ts_tiles_per_row tile_off_x = max(0, tile_data.sprite_width * x_index) tile_off_y = max(0, tile_data.sprite_height * y_index) @@ -304,7 +303,7 @@ def get_all_data(self, tileset_dirname, delete_pathname): os.stat(self.tileset_pathname) except KeyError: print("cannot find a directory {}".format(self.tileset_pathname)) - exit -1 + sys.exit(-1) tileset_confname = refs.tileset_pathname + "/" + "tile_config.json" @@ -312,7 +311,7 @@ def get_all_data(self, tileset_dirname, delete_pathname): os.stat(tileset_confname) except KeyError: print("cannot find a directory {}".format(tileset_confname)) - exit -1 + sys.exit(-1) if delete_pathname: with open(delete_pathname) as del_file: @@ -328,7 +327,7 @@ def get_all_data(self, tileset_dirname, delete_pathname): self.delete_pngnums.append(i) with open(tileset_confname) as conf_file: - return(json.load(conf_file)) + return(json.load(conf_file)) def add_pngnum_to_tsfilepath(self, pngnum): if not isinstance(pngnum, int): diff --git a/tools/gfx_tools/png_update.py b/tools/gfx_tools/png_update.py index 0d01317271f1b..e044a3d682c21 100755 --- a/tools/gfx_tools/png_update.py +++ b/tools/gfx_tools/png_update.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # png_update.py # Rename a png and update all references to it. @@ -8,13 +8,10 @@ import os import subprocess -# stupid stinking Python 2 versus Python 3 syntax + def write_to_json(pathname, data): with open(pathname, "w") as fp: - try: - json.dump(data, fp) - except ValueError: - fp.write(json.dumps(data)) + json.dump(data, fp) json_formatter = "./tools/format/json_formatter.cgi" if os.path.isfile(json_formatter): @@ -84,7 +81,7 @@ def convert_tile_entry(tile_entry, old_name, new_name): changed |= add_changed if new_tile_entrys: tile_entry["additional_tiles"] = new_tile_entrys - return tile_entry, changed + return tile_entry, changed def convert_tile_entry_file(file_path, old_name, new_name): @@ -104,6 +101,7 @@ def convert_tile_entry_file(file_path, old_name, new_name): new_tile_data = new_tile_data[0] write_to_json(file_path, new_tile_data) + args = argparse.ArgumentParser(description="Rename a png file, its associated tile_entry.json, and update all other tile_entry.json in the tileset dir to reflect the new name.") args.add_argument("tileset_dir", action="store", help="local name of the tileset directory under gfx/") @@ -150,5 +148,3 @@ def convert_tile_entry_file(file_path, old_name, new_name): elif filename == old_name_json: new_path = subdir_fpath + "/" + new_name_json os.rename(old_path, new_path) - - diff --git a/tools/json_tools/adjust_values.py b/tools/json_tools/adjust_values.py index 8a9287f75e7c6..a874588af4176 100755 --- a/tools/json_tools/adjust_values.py +++ b/tools/json_tools/adjust_values.py @@ -26,7 +26,7 @@ def gen_new(path): path = os.path.join(root, filename) if path.endswith(".json"): new = gen_new(path) - if new != None: + if new is not None: with open(path, "w") as jf: json.dump(new, jf, ensure_ascii=False) os.system(f"./tools/format/json_formatter.cgi {path}") diff --git a/tools/json_tools/cddatags.py b/tools/json_tools/cddatags.py index 6cb61d9cf45ac..9705102145d2f 100755 --- a/tools/json_tools/cddatags.py +++ b/tools/json_tools/cddatags.py @@ -10,16 +10,18 @@ JSON_DIR = os.path.join(TOP_DIR, "data") TAGS_FILE = os.path.join(TOP_DIR, "tags") + def make_tags_line(id_key, id, filename): pattern = '/"{id_key}": "{id}"/'.format(id_key=id_key, id=id) return '\t'.join((id, filename, pattern)).encode('utf-8') + def is_json_tag_line(line): return b'.json\t' in line + def main(args): - parser = argparse.ArgumentParser(description= - """\ + parser = argparse.ArgumentParser(description=""" Update a tags file with locations of the definitions of CDDA json entities. If you already have a tags file with some data in, this will only replace tags @@ -41,15 +43,15 @@ def main(args): json_data = json.load(file) except Exception as err: sys.stderr.write( - "Problem reading file %s, reason: %s" % - (filename, err)) + "Problem reading file %s, reason: %s" % + (filename, err)) continue if type(json_data) == dict: json_data = [json_data] elif type(json_data) != list: sys.stderr.write( - "Problem parsing data from file %s, reason: " - "expected a list." % filename) + "Problem parsing data from file %s, reason: " + "expected a list." % filename) continue for obj in json_data: @@ -67,13 +69,15 @@ def main(args): except FileNotFoundError: pass - existing_tags_lines = [l.rstrip(b'\n') for l in existing_tags_lines if - not is_json_tag_line(l)] + existing_tags_lines = [ + l.rstrip(b'\n') for l in existing_tags_lines if + not is_json_tag_line(l)] all_tags_lines = sorted(json_tags_lines + existing_tags_lines) with open(TAGS_FILE, 'wb') as tags_file: tags_file.write(b'\n'.join(all_tags_lines)) + if __name__ == '__main__': main(sys.argv[1:]) diff --git a/tools/json_tools/keys.py b/tools/json_tools/keys.py index eb2e6660f9496..9634349761f1f 100755 --- a/tools/json_tools/keys.py +++ b/tools/json_tools/keys.py @@ -1,14 +1,12 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python3 """Run this script with -h for usage info and docs. """ -from __future__ import print_function - import sys import json import argparse from util import import_data, key_counter, ui_counts_to_columns,\ - WhereAction + WhereAction parser = argparse.ArgumentParser(description="""Count the number of times a specific key occurs. @@ -20,16 +18,18 @@ # List keys on JSON objects of type "bionic", output in JSON. %(prog)s type=bionic """, formatter_class=argparse.RawDescriptionHelpFormatter) -parser.add_argument("--fnmatch", - default="*.json", - help="override with glob expression to select a smaller fileset.") -parser.add_argument("--human", - action="store_true", - help="if set, makes output human readable. default is to return output in JSON.") -parser.add_argument("where", - action=WhereAction, nargs='*', type=str, - help="where exclusions of the form 'where_key=where_val', no quotes.") - +parser.add_argument( + "--fnmatch", + default="*.json", + help="override with glob expression to select a smaller fileset.") +parser.add_argument( + "--human", + action="store_true", + help="if set, makes output human readable. default is to return output in JSON.") +parser.add_argument( + "where", + action=WhereAction, nargs='*', type=str, + help="where exclusions of the form 'where_key=where_val', no quotes.") if __name__ == "__main__": diff --git a/tools/json_tools/lister.py b/tools/json_tools/lister.py index 487d35da41b62..fd0968d54e9ae 100755 --- a/tools/json_tools/lister.py +++ b/tools/json_tools/lister.py @@ -1,9 +1,7 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python3 """Run this script with -h for usage info and docs. """ -from __future__ import print_function - import argparse import os import stat @@ -24,10 +22,10 @@ values.py -k material | %(prog)s """, formatter_class=argparse.RawDescriptionHelpFormatter) -parser.add_argument("--human", - action="store_true", - help="if set, makes output human readable. default is to return output in JSON.") - +parser.add_argument( + "--human", + action="store_true", + help="if set, makes output human readable. default is to return output in JSON.") if __name__ == "__main__": @@ -56,7 +54,7 @@ keys = set() for item in json_data: # We assume only dictionaries here - keys.update(item.keys()) + keys.update(list(item.keys())) keys = sorted(list(keys)) diff --git a/tools/json_tools/pluck.py b/tools/json_tools/pluck.py index da47e97e2f7b4..69d15218f4990 100755 --- a/tools/json_tools/pluck.py +++ b/tools/json_tools/pluck.py @@ -1,9 +1,7 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python3 """Run this script with -h for usage info and docs. """ -from __future__ import print_function - import sys import argparse from util import import_data, matches_all_wheres, CDDAJSONWriter, WhereAction @@ -16,16 +14,18 @@ %(prog)s material=plastic material=steel """, formatter_class=argparse.RawDescriptionHelpFormatter) -parser.add_argument("--fnmatch", - default="*.json", - help="override with glob expression to select a smaller fileset.") -parser.add_argument("--all", - action="store_true", - help="if set, includes all matches. if not set, includes first match in the stream.") -parser.add_argument("where", - action=WhereAction, nargs='+', type=str, - help="where exclusions of the form 'where_key=where_val', no quotes.") - +parser.add_argument( + "--fnmatch", + default="*.json", + help="override with glob expression to select a smaller fileset.") +parser.add_argument( + "--all", + action="store_true", + help="if set, includes all matches. if not set, includes first match in the stream.") +parser.add_argument( + "where", + action=WhereAction, nargs='+', type=str, + help="where exclusions of the form 'where_key=where_val', no quotes.") if __name__ == "__main__": @@ -58,6 +58,6 @@ # TODO: get rid of ugh print("[") for i, p in enumerate(plucked): - eol = ",\n" if i < len(plucked)-1 else "\n" + eol = ",\n" if i < len(plucked) - 1 else "\n" print(CDDAJSONWriter(p, 1).dumps(), end=eol) print("]") diff --git a/tools/json_tools/pocket_mags.py b/tools/json_tools/pocket_mags.py index 7629eab596ed0..b974a2a0611a3 100755 --- a/tools/json_tools/pocket_mags.py +++ b/tools/json_tools/pocket_mags.py @@ -10,6 +10,7 @@ inheriting_item_ids = [] + def gen_new(path): change = False with open(path, "r") as json_file: diff --git a/tools/json_tools/splitter.py b/tools/json_tools/splitter.py index a16034740ca8a..3936b7fe73eaf 100755 --- a/tools/json_tools/splitter.py +++ b/tools/json_tools/splitter.py @@ -1,9 +1,7 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python3 """Run this script with -h for usage info and docs. """ -from __future__ import print_function - import sys import argparse from util import import_data, matches_all_wheres, CDDAJSONWriter, WhereAction @@ -18,13 +16,14 @@ # everything else goes to stderr %(prog)s --fnmatch=dreams.json type=dream strength=2 1>matched.json 2>not_matched.json """, formatter_class=argparse.RawDescriptionHelpFormatter) -parser.add_argument("--fnmatch", - default="*.json", - help="override with glob expression to select a smaller fileset.") -parser.add_argument("where", - action=WhereAction, nargs='+', type=str, - help="where exclusions of the form 'where_key=where_val', no quotes.") - +parser.add_argument( + "--fnmatch", + default="*.json", + help="override with glob expression to select a smaller fileset.") +parser.add_argument( + "where", + action=WhereAction, nargs='+', type=str, + help="where exclusions of the form 'where_key=where_val', no quotes.") if __name__ == "__main__": @@ -53,13 +52,13 @@ # matched first print("[") for i, p in enumerate(matched): - eol = ",\n" if i < len(matched)-1 else "\n" + eol = ",\n" if i < len(matched) - 1 else "\n" print(CDDAJSONWriter(p, 1).dumps(), end=eol) print("]") # not_matched second print("[", file=sys.stderr) for i, p in enumerate(not_matched): - eol = ",\n" if i < len(not_matched)-1 else "\n" + eol = ",\n" if i < len(not_matched) - 1 else "\n" print(CDDAJSONWriter(p, 1).dumps(), end=eol, file=sys.stderr) print("]", file=sys.stderr) diff --git a/tools/json_tools/table.py b/tools/json_tools/table.py index 2b4dbb6a0806b..a95169f531fbf 100755 --- a/tools/json_tools/table.py +++ b/tools/json_tools/table.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python3 """Print a Markdown or CSV table of JSON values from the given keys. Run this script with -h for full usage information. @@ -16,15 +16,8 @@ """ import argparse -import codecs -import sys import util -# Avoid (most) unicode frustrations -# https://pythonhosted.org/kitchen/unicode-frustrations.html -UTF8Writer = codecs.getwriter('utf8') -sys.stdout = UTF8Writer(sys.stdout) - # Command-line arguments parser = argparse.ArgumentParser( description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) @@ -61,7 +54,7 @@ def safe_value(value, format): """ if format == 'md': - return value.replace('|', '\|') + return value.replace('|', '\\|') elif format == 'csv': if ',' in value or '"' in value: @@ -153,7 +146,7 @@ def item_values(item, fields): # Make dict presentable if isinstance(it, dict): - values.append("%s" % it.items()) + values.append("%s" % list(it.items())) # Separate lists with slashes elif isinstance(it, list): values.append(" / ".join("%s" % i for i in it)) @@ -179,4 +172,3 @@ def item_values(item, fields): continue print_row(item_values(item, args.columns), args.format) - diff --git a/tools/json_tools/util.py b/tools/json_tools/util.py index 703d1cf5a8156..bb626ee474274 100755 --- a/tools/json_tools/util.py +++ b/tools/json_tools/util.py @@ -1,23 +1,19 @@ """Utility stuff for json tools. """ -from __future__ import print_function - import argparse from collections import Counter, OrderedDict from fnmatch import fnmatch import json import re import os -from StringIO import StringIO - +from io import StringIO SCRIPT_DIR = os.path.abspath(os.path.dirname(__file__)) JSON_DIR = os.path.normpath(os.path.join(SCRIPT_DIR, "..", "..", "data", "json")) JSON_FNMATCH = "*.json" - def import_data(json_dir=JSON_DIR, json_fmatch=JSON_FNMATCH): """Use a UNIX like file match expression to weed out the JSON files. @@ -47,13 +43,12 @@ def import_data(json_dir=JSON_DIR, json_fmatch=JSON_FNMATCH): return (data, errors) - def match_primitive_values(item_value, where_value): """Perform any odd logic on item matching. """ # Matching interpolation for keyboard constrained input. - if type(item_value) == str or type(item_value) == unicode: - # Direct match, and don't convert unicode in Python 2. + if type(item_value) == str: + # Direct match return bool(re.match(where_value, item_value)) elif type(item_value) == int or type(item_value) == float: # match after string conversion @@ -65,7 +60,6 @@ def match_primitive_values(item_value, where_value): return False - def matches_where(item, where_key, where_value): """True if: where_key exists AND @@ -102,7 +96,6 @@ def matches_where(item, where_key, where_value): return match_primitive_values(item_value, where_value) - def matches_all_wheres(item, where_fn_list): """Takes a list of where functions and attempts to match against them. @@ -122,7 +115,6 @@ def matches_all_wheres(item, where_fn_list): return True - class WhereAction(argparse.Action): """An argparse action callback. @@ -157,7 +149,6 @@ def __call__(self, parser, namespace, values, option_string=None): raise ValueError("Where options are strict. Must be in the form of 'where_key=where_value'") - def key_counter(data, where_fn_list): """Count occurences of keys found in data {list of dicts} that also match each where_fn_list {list of fns}. @@ -200,14 +191,14 @@ def item_value_counter(_value): """ stats = Counter() # String or unicode - if isinstance(_value, basestring): + if isinstance(_value, str): stats[_value] += 1 # Cast numbers to strings elif type(_value) == int or type(_value) == float: stats[str(_value)] += 1 # Pull all values from objects elif type(_value) == OrderedDict: - stats += list_value_counter(_value.values()) + stats += list_value_counter(list(_value.values())) # Pull values from list of objects or strings elif type(_value) == list: stats += list_value_counter(_value) @@ -216,6 +207,7 @@ def item_value_counter(_value): (_value, type(_value))) return stats + def list_value_counter(_list): """Return a Counter tallying all values in the given {list of dicts} or {list of strs}, recursing into nested dicts and lists. @@ -225,6 +217,7 @@ def list_value_counter(_list): stats += item_value_counter(elem) return stats + def value_counter(data, search_key, where_fn_list): """Takes a search_key {str}, and for values found in data {list of dicts} that also match each where_fn_list {list of fns} with those keys, @@ -246,7 +239,7 @@ def value_counter(data, search_key, where_fn_list): parent_key = search_key child_key = None else: - raise ArgumentError("Only one '.' allowed in search key") + raise argparse.ArgumentError("Only one '.' allowed in search key") for item in matching_data: if parent_key not in item: @@ -261,7 +254,7 @@ def value_counter(data, search_key, where_fn_list): # If this value is a list of objects, pull parent_key.child_key # values from all of them to include in stats if type(parent_val) == list and all(type(e) == OrderedDict - for e in parent_val): + for e in parent_val): for od in parent_val: if child_key in od: stat_vals.append(od[child_key]) @@ -281,12 +274,11 @@ def value_counter(data, search_key, where_fn_list): return stats, len(matching_data) - def ui_values_to_columns(values, screen_width=80): """Take a list of strings and output in fixed width columns. """ - max_val_len = len(max(values, key=len))+1 - cols = screen_width/max_val_len + max_val_len = len(max(values, key=len)) + 1 + cols = screen_width / max_val_len iters = 0 for v in values: print(v.ljust(max_val_len), end=' ') @@ -296,20 +288,18 @@ def ui_values_to_columns(values, screen_width=80): print("") - def ui_counts_to_columns(counts): """Take a Counter instance and display in single fixed width key:value column. """ # Values in left column, counts in right, left column as wide as longest string length. key_vals = counts.most_common() - key_field_len = len(max(list(counts.keys()), key=len))+1 + key_field_len = len(max(list(counts.keys()), key=len)) + 1 output_template = "%%-%ds: %%s" % key_field_len for k_v in key_vals: print(output_template % k_v) - class CDDAJSONWriter(object): """Essentially a one-off class used to write CDDA formatted JSON output. @@ -330,7 +320,7 @@ def __init__(self, d, indent_multiplier=0): # buf is initialized on a call to dumps def indented_write(self, s): - self.buf.write(self.indent*self.indent_multiplier + s) + self.buf.write(self.indent * self.indent_multiplier + s) def write_key(self, k): self.indented_write("\"%s\": " % k) @@ -361,7 +351,7 @@ def list_of_lists(self, k, lol): self.buf.write(",\n") else: self.buf.write("\n") - self.indent_multiplier -=1 + self.indent_multiplier -= 1 self.indented_write("]") def dumps(self): @@ -372,7 +362,7 @@ def dumps(self): self.buf = None self.buf = StringIO() - items = self.d.items() + items = list(self.d.items()) global indent_multiplier self.indented_write("{\n") self.indent_multiplier += 1 diff --git a/tools/json_tools/values.py b/tools/json_tools/values.py index 99567cceb7ff6..4a31f43eaa1f3 100755 --- a/tools/json_tools/values.py +++ b/tools/json_tools/values.py @@ -1,14 +1,12 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python3 """Run this script with -h for usage info and docs. """ -from __future__ import print_function - import argparse import sys import json from util import import_data, value_counter, ui_counts_to_columns,\ - WhereAction + WhereAction parser = argparse.ArgumentParser(description="""Count the number of times a specific values occurs for a specific key. The key may be a @@ -26,18 +24,22 @@ # What cost values are in bionics that are active? %(prog)s --key=cost type=bionic active=true """, formatter_class=argparse.RawDescriptionHelpFormatter) -parser.add_argument("--fnmatch", - default="*.json", - help="override with glob expression to select a smaller fileset.") -parser.add_argument("--human", - action="store_true", - help="if set, makes output human readable. default is to return output in JSON dictionary.") -parser.add_argument("-k", "--key", - required=True, type=str, - help="key on JSON objects from which to count values") -parser.add_argument("where", - action=WhereAction, nargs='*', type=str, - help="where exclusions of the form 'where_key=where_val', no quotes.") +parser.add_argument( + "--fnmatch", + default="*.json", + help="override with glob expression to select a smaller fileset.") +parser.add_argument( + "--human", + action="store_true", + help="if set, makes output human readable. default is to return output in JSON dictionary.") +parser.add_argument( + "-k", "--key", + required=True, type=str, + help="key on JSON objects from which to count values") +parser.add_argument( + "where", + action=WhereAction, nargs='*', type=str, + help="where exclusions of the form 'where_key=where_val', no quotes.") if __name__ == "__main__": diff --git a/tools/merge_maps.py b/tools/merge_maps.py index 5880db198eefa..48a4a136fe7d7 100755 --- a/tools/merge_maps.py +++ b/tools/merge_maps.py @@ -36,26 +36,25 @@ def x_y_sub(x, y, is_north): (y - MIN_Y - 1) % STRIDE_Y) - def x_y_simple(x, y): return "{}__{}".format(x, y) def get_data(argsDict, resource_name): - resource = [] - resource_sources = argsDict.get(resource_name, []) - if not isinstance(resource_sources, list): - resource_sources = [resource_sources] - for resource_filename in resource_sources: - if resource_filename.endswith(".json"): - try: - with open(resource_filename) as resource_file: - resource += json.load(resource_file) - except FileNotFoundError: - exit("Failed: could not find {}".format(resource_filename)) - else: - print("Invalid filename {}".format(resource_filename)) - return resource + resource = [] + resource_sources = argsDict.get(resource_name, []) + if not isinstance(resource_sources, list): + resource_sources = [resource_sources] + for resource_filename in resource_sources: + if resource_filename.endswith(".json"): + try: + with open(resource_filename) as resource_file: + resource += json.load(resource_file) + except FileNotFoundError: + exit("Failed: could not find {}".format(resource_filename)) + else: + print(("Invalid filename {}".format(resource_filename))) + return resource def adjacent_to_set(x, y, coord_set): @@ -87,7 +86,7 @@ def validate_old_map(old_map, entry): if entry["weight"] and old_map.get("weight") and entry["weight"] != old_map.get("weight"): return False if entry["object"].get("fill_ter") and old_obj.get("fill_ter") and \ - entry["object"]["fill_ter"] != old_obj.get("fill_ter"): + entry["object"]["fill_ter"] != old_obj.get("fill_ter"): return False new_palettes = entry.get("palettes", {}) @@ -106,7 +105,7 @@ def validate_old_map(old_map, entry): keysets[key_term] = new_keyset elif new_keyset != {}: return False - + if not entry["weight"]: entry["weight"] = old_map.get("weight", 0) if not entry["object"].get("fill_ter"): @@ -124,10 +123,10 @@ def adjust_place(term, old_obj, offset_x, offset_y): def adjust_coord(x_or_y, new_entry, old_entry, offset): val = old_entry.get(x_or_y, "False") if val == "False": - return False + return False if isinstance(val, list): - val[0] += offset - val[1] += offset + val[0] += offset + val[1] += offset else: val += offset new_entry[x_or_y] = val @@ -242,7 +241,7 @@ def adjust_coord(x_or_y, new_entry, old_entry, offset): for x_y, mapset in zlevel.items(): # first, split the mergeset into chunks with common KEYED_TERMS using a weird floodfill chunks = [] - chunks = [{ "maps": [], "entry": copy.deepcopy(basic_entry)}] + chunks = [{"maps": [], "entry": copy.deepcopy(basic_entry)}] for y in range(0, STRIDE_Y): for x in range(0, STRIDE_X): om_id = mapset.get(x_y_simple(x, y), "") @@ -260,10 +259,10 @@ def adjust_coord(x_or_y, new_entry, old_entry, offset): # check that this map's keyed terms match the other keyed terms in this chunk if validate_old_map(old_map, chunk_data["entry"]): chunk_data["maps"].append({"x": x, "y": y}) - validated = True + validated = True if not validated: new_entry = copy.deepcopy(basic_entry) - chunks.append({ "maps": [{"x": x, "y": y}], "entry": new_entry }) + chunks.append({"maps": [{"x": x, "y": y}], "entry": new_entry}) # then split up any irregular shapes that made it past the screen # T and L shapes are possible because every map is adjacent, for instance @@ -278,7 +277,7 @@ def adjust_coord(x_or_y, new_entry, old_entry, offset): min_x = maps[0]["x"] maps.sort(key=itemgetter("y")) max_y = maps[-1]["y"] - min_y = maps[0]["y"] + min_y = maps[0]["y"] # if this is a line, square, or rectangle, it's continguous if len(maps) == ((max_x - min_x + 1) * (max_y - min_y + 1)): final_chunks.append(chunk_data) @@ -303,7 +302,7 @@ def adjust_coord(x_or_y, new_entry, old_entry, offset): if not maps: continue first_x = maps[0]["x"] - first_y = maps[0]["y"] + first_y = maps[0]["y"] for coords in maps: x = coords["x"] y = coords["y"] diff --git a/tools/palettize.py b/tools/palettize.py index 18a34dd132918..fa245784da917 100755 --- a/tools/palettize.py +++ b/tools/palettize.py @@ -4,6 +4,7 @@ import argparse import copy + def hash_key(key): if isinstance(key, list): return "list_" + "".join(key) @@ -22,8 +23,8 @@ def parse_furnter(om_objs, palette, conflicts): map_hash = hash_key(map_val) pal_hash = hash_key(pal_val) conflicts.setdefault(map_key, {}) - conflicts[map_key].setdefault(map_hash, { "val": map_val, "count": 0 }) - conflicts[map_key].setdefault(pal_hash, { "val": pal_val, "count": 0 }) + conflicts[map_key].setdefault(map_hash, {"val": map_val, "count": 0}) + conflicts[map_key].setdefault(pal_hash, {"val": pal_val, "count": 0}) conflicts[map_key][map_hash]["count"] += 1 conflicts[map_key][pal_hash]["count"] += 1 @@ -66,13 +67,13 @@ def resolve_conflicts(om_objs, palette, conflicts): palette_name = argsDict.get("palette_name", "") palette_source = argsDict.get("palette_path", "") + "/" + palette_name + ".json" if mapgen_source.endswith(".json"): - try: - with open(mapgen_source) as mapgen_file: - mapgen += json.load(mapgen_file) - except FileNotFoundError: - exit("Failed: could not find {}".format(mapgen_source)) + try: + with open(mapgen_source) as mapgen_file: + mapgen += json.load(mapgen_file) + except FileNotFoundError: + exit("Failed: could not find {}".format(mapgen_source)) else: - exit("Failed: invalid mapgen file name {}".format(mapgen_source)) + exit("Failed: invalid mapgen file name {}".format(mapgen_source)) furn_pal = {} furn_conflicts = {} @@ -116,12 +117,12 @@ def resolve_conflicts(om_objs, palette, conflicts): if om_ter_final: om_object["terrain"] = om_ter_final else: - del om_object["terrain"] + del om_object["terrain"] else: del om_object["terrain"] with open(mapgen_source, 'w') as mapgen_file: - mapgen_file.write(json.dumps(mapgen, indent=2)) + mapgen_file.write(json.dumps(mapgen, indent=2)) palette_json = [ { @@ -133,9 +134,7 @@ def resolve_conflicts(om_objs, palette, conflicts): ] with open(palette_source, 'w') as palette_file: - palette_file.write(json.dumps(palette_json, indent=2)) + palette_file.write(json.dumps(palette_json, indent=2)) #print("furniture palette {}".format(json.dumps(furn_pal, indent=2))) #print("terrain palette {}".format(json.dumps(ter_pal, indent=2))) - - diff --git a/tools/update_blueprint_needs.py b/tools/update_blueprint_needs.py index b1ecd1dfb8c52..b303186aa949b 100755 --- a/tools/update_blueprint_needs.py +++ b/tools/update_blueprint_needs.py @@ -7,6 +7,7 @@ import subprocess import sys + def print_help(): print("\n" "Update faction camp blueprints with autocalculated requirements from unit test log.\n" @@ -18,6 +19,7 @@ def print_help(): " update: update with suggested requirements (default)\n" " suppress: suppress inconsistency warnings\n") + def main(argv): try: opts, args = getopt.getopt(argv, "", ["help", "logfile=", "action="]) @@ -39,7 +41,7 @@ def main(argv): elif arg == "suppress": suppress = True else: - print_help(); + print_help() return if not test_log: print_help() @@ -49,7 +51,7 @@ def main(argv): "data/core", "data/json", "data/mods", - }; + } auto_update_blueprint = re.compile("~~~ auto-update-blueprint: (.+)") auto_update_blueprint_end = re.compile("~~~ end-auto-update") @@ -78,7 +80,7 @@ def main(argv): else: reqs += line if complete: - update_blueprints[ident] = json.loads(reqs); + update_blueprints[ident] = json.loads(reqs) print("{} needs updating".format(ident)) if len(update_blueprints) == 0: @@ -98,10 +100,10 @@ def main(argv): if type(content) is list: for obj in content: if not (type(obj) is dict - and "type" in obj and obj["type"] == "recipe" - and ("result" in obj or "abstract" in obj)): + and "type" in obj and obj["type"] == "recipe" + and ("result" in obj or "abstract" in obj)): continue - ident = None; + ident = None if "abstract" in obj: ident = obj["abstract"] else: @@ -121,5 +123,6 @@ def main(argv): json.dump(content, fs, indent=2) subprocess.run(["tools/format/json_formatter", json_path], stdout=subprocess.DEVNULL) + if __name__ == "__main__": main(sys.argv[1:]) diff --git a/tools/vehicleDef.py b/tools/vehicleDef.py index 6978c34be671a..34b1420e61b1b 100755 --- a/tools/vehicleDef.py +++ b/tools/vehicleDef.py @@ -7,8 +7,8 @@ import os args = argparse.ArgumentParser( - description= - "Generate a json definition for a vehicle in a Cataclysm DDA save file.") + description="Generate a json definition for a vehicle " + "in a Cataclysm DDA save file.") args.add_argument( "save", action="store", help="specify save file containing vehicle") args.add_argument( @@ -33,7 +33,7 @@ def getVehicleTemplates(): allTemplates = [] for vehicle in vehicles: vehicleDef = buildVehicleDef(vehicle) - if not vehicleDef in allTemplates: + if vehicleDef not in allTemplates: allTemplates.append(vehicleDef) return allTemplates @@ -45,7 +45,7 @@ def getVehicleInstances(mapPath): mapData = json.load(mapFile) for i in range(0, len(mapData)): for vehicle in mapData[i]["vehicles"]: - if argsDict["vehicle"] != None: + if argsDict["vehicle"] is not None: if argsDict["vehicle"] == vehicle["name"]: vehicles.append(vehicle) print(f"Found \"{vehicle['name']}\"") @@ -76,11 +76,11 @@ def buildVehicleDef(vehicle): frames = [ p for p in partsDef - if re.match(r'(xl|hd|folding_)?frame', p["part"]) != None + if re.match(r'(xl|hd|folding_)?frame', p["part"]) is not None ] everythingElse = [ p for p in partsDef - if re.match(r'(xl|hd|folding_)?frame', p["part"]) == None + if re.match(r'(xl|hd|folding_)?frame', p["part"]) is None ] frames = sortFrames(frames) diff --git a/utilities/building-utility/deconstruct.py b/utilities/building-utility/deconstruct.py index 874f1dabdd6ad..7538903058c3b 100755 --- a/utilities/building-utility/deconstruct.py +++ b/utilities/building-utility/deconstruct.py @@ -1,12 +1,10 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 '''Tool to combine ascii map cells with json templates. Original design and implementation: acidia (https://github.com/acidia) Current design and implementation: wormingdead (https://github.com/wormingdead) ''' -from __future__ import division - import argparse import copy import json @@ -267,6 +265,6 @@ def main(parser): file_name=json_template.name, json_err=str(val_err))) + if __name__ == "__main__": main(cli_interface()) - diff --git a/utilities/make_iso.py b/utilities/make_iso.py index 66795a1c7c77c..92a1002308bbb 100755 --- a/utilities/make_iso.py +++ b/utilities/make_iso.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # pylint: disable=C0103 # pylint: disable=C0301 @@ -13,7 +13,7 @@ # offset=0 will align the bottom of the sprite with the bottom (southwest corner) of the square # offset<1 will be a fraction of the isometric tile height # offset>=1 will be an absolute number of pixels -SPRITE_OFFSET_FROM_BOTTOM = 1.0/8 +SPRITE_OFFSET_FROM_BOTTOM = 1.0 / 8 parser = argparse.ArgumentParser(description='Convert a Cataclysm-DDA tileset to isometric view.') @@ -23,19 +23,21 @@ args = parser.parse_args() + def iso_ize(tile_num, new_tile_num=-1, initial_rotation=0, override=False): - if override or (tile_num,initial_rotation) not in converted_tile_ids: - print " iso-izing " + str(tile_num) + if override or (tile_num, initial_rotation) not in converted_tile_ids: + print(" iso-izing " + str(tile_num)) if new_tile_num == -1: new_tile_num = tile_num - converted_tile_ids[(tile_num,initial_rotation)] = True - command = ('convert -background transparent ' + new_tileset_name + '/tiles/tile-' + "{:0>6d}".format(tile_num) + '.png ' + + converted_tile_ids[(tile_num, initial_rotation)] = True + command = ( + 'convert -background transparent ' + new_tileset_name + '/tiles/tile-' + "{:0>6d}".format(tile_num) + '.png ' + '-rotate ' + str(initial_rotation) + ' ' + '-rotate -45 +repage -resize 100%x50% ' + - '-crop ' + str(nwidth) + 'x' + str(int(nwidth/2)) + '+2+1 ' + #TODO: get correct offsets - '+repage -extent ' + str(nwidth) + 'x' + str(nheight) + '+0-' + str(nheight-int(nwidth/2)) + ' ' + + '-crop ' + str(nwidth) + 'x' + str(int(nwidth / 2)) + '+2+1 ' + # TODO: get correct offsets + '+repage -extent ' + str(nwidth) + 'x' + str(nheight) + '+0-' + str(nheight - int(nwidth / 2)) + ' ' + new_tileset_name + '/tiles/to_merge/tile-' + "{:0>6d}".format(new_tile_num) + '.png') - print command + print(command) if os.system(command): raise return True @@ -45,7 +47,7 @@ def iso_ize(tile_num, new_tile_num=-1, initial_rotation=0, override=False): # convert one old tile definition to one new tile definition # recursive for additional-tiles def tile_convert(otile, main_id, new_tile_number): - print 'tile_convert ' + main_id + ' ' + str(new_tile_number) + print('tile_convert ' + main_id + ' ' + str(new_tile_number)) ntile = dict() ntile['id'] = otile['id'] ntile['ntn'] = int(new_tile_number) @@ -58,7 +60,7 @@ def tile_convert(otile, main_id, new_tile_number): if 'multitile' in otile: ntile['multitile'] = otile['multitile'] - for g in ('fg','bg'): + for g in ('fg', 'bg'): if g not in otile: continue if type(otile[g]) == int: @@ -81,11 +83,11 @@ def tile_convert(otile, main_id, new_tile_number): # iso-ize? if ( ( - (main_id[0:2] == 't_' or main_id[0:9] == 'lighting_') and # terrain and lighting - (g == 'bg' or 'bg' not in otile) # rotate bg, fg iff there's no bg + (main_id[0:2] == 't_' or main_id[0:9] == 'lighting_') and # terrain and lighting + (g == 'bg' or 'bg' not in otile) # rotate bg, fg iff there's no bg ) or (main_id[0:2] == 'f_' and g == 'bg' and 'fg' in otile) or - main_id[0:3] == 'vp_' or main_id[0:3] == 'fd_' or # vehicle parts and fields + main_id[0:3] == 'vp_' or main_id[0:3] == 'fd_' or # vehicle parts and fields # additional_tiles: otile['id'] == 'broken' or otile['id'] == 'open' or @@ -95,40 +97,40 @@ def tile_convert(otile, main_id, new_tile_number): otile['id'] == 'edge' or otile['id'] == 'end_piece' or otile['id'] == 't_connection' or - ('rotates' in otile and otile['rotates'] == True) or + ('rotates' in otile and otile['rotates'] is True) or otile['id'] != main_id - ): + ): # iso-ize this tile iso_ize(otile[g][0], override=True) if ('rotates' in otile or - otile['id'] == 'broken' or - otile['id'] == 'open' or - otile['id'] == 'unconnected' or - otile['id'] == 'center' or - otile['id'] == 'corner' or - otile['id'] == 'edge' or - otile['id'] == 'end_piece' or - otile['id'] == 't_connection'): - print " and rotating " + str(otile[g][0]) + otile['id'] == 'broken' or + otile['id'] == 'open' or + otile['id'] == 'unconnected' or + otile['id'] == 'center' or + otile['id'] == 'corner' or + otile['id'] == 'edge' or + otile['id'] == 'end_piece' or + otile['id'] == 't_connection'): + print(" and rotating " + str(otile[g][0])) # create 3 new iso-ized tiles, as well - for rot in (270,180,90): + for rot in (270, 180, 90): if iso_ize(otile[g][0], ntile['ntn'], rot): ntile[g].append(ntile['ntn']) ntile['ntn'] += 1 - print "next tile number now " + str(ntile['ntn']) + print("next tile number now " + str(ntile['ntn'])) else: - if (ntile[g][0],0) not in converted_tile_ids: - print" offsetting " + str(ntile[g][0]) - converted_tile_ids[(ntile[g][0],0)] = True + if (ntile[g][0], 0) not in converted_tile_ids: + print(" offsetting " + str(ntile[g][0])) + converted_tile_ids[(ntile[g][0], 0)] = True # offset this flat tile command = ( 'convert -background transparent ' + new_tileset_name + '/tiles/tile-' + "{:0>6d}".format(otile[g][0]) + '.png' + (' -fill transparent -draw "color 0,0 floodfill"' if args.floodfill else '') + ' -extent ' + str(nwidth) + 'x' + str(nheight) + - '-' + str(int((nwidth-owidth)/2)) + '-' + str(int((nheight-oheight)-flat_sprite_offset)) + ' ' + + '-' + str(int((nwidth - owidth) / 2)) + '-' + str(int((nheight - oheight) - flat_sprite_offset)) + ' ' + '+repage ' + new_tileset_name + '/tiles/to_merge/tile-' + '{:0>6d}'.format(otile[g][0]) + '.png') - print command + print(command) if os.system(command): raise else: @@ -140,13 +142,13 @@ def tile_convert(otile, main_id, new_tile_number): if 'additional_tiles' in otile: nta = ntile['additional_tiles'] = list() for otile in otile['additional_tiles']: - print ' handling additional_tile ' + otile['id'] + print(' handling additional_tile ' + otile['id']) tile = tile_convert(otile, main_id, ntile['ntn']) ntile['ntn'] = tile['ntn'] del tile['ntn'] nta.append(tile) - print "returning tile, next tile number now " + str(ntile['ntn']) + print("returning tile, next tile number now " + str(ntile['ntn'])) return ntile @@ -165,14 +167,14 @@ def tile_convert(otile, main_id, new_tile_number): except: pass -os.system('rm -rf '+new_tileset_name+'/tiles/*') +os.system('rm -rf ' + new_tileset_name + '/tiles/*') try: os.mkdir(new_tileset_name + '/tiles/to_merge') except: pass -print 'reading ' + old_tileset_name + '/tile_config.json' +print('reading ' + old_tileset_name + '/tile_config.json') with open(old_tileset_name + '/tile_config.json') as old_tile_config_json_file: otc = json.load(old_tile_config_json_file) @@ -180,13 +182,13 @@ def tile_convert(otile, main_id, new_tile_number): owidth = otc['tile_info'][0]['width'] # iso tile width is enough to hold a 45 degree rotated original tile -nwidth = int(owidth * math.sqrt(2)/2)*2 +nwidth = int(owidth * math.sqrt(2) / 2) * 2 # iso tile height is enough to hold a vertical offset 2d tile if SPRITE_OFFSET_FROM_BOTTOM < 1: flat_sprite_offset = int(nwidth * SPRITE_OFFSET_FROM_BOTTOM / 2) else: flat_sprite_offset = int(SPRITE_OFFSET_FROM_BOTTOM / 2) -print "flat sprite offset " + str(flat_sprite_offset) +print("flat sprite offset " + str(flat_sprite_offset)) nheight = flat_sprite_offset + oheight # struct that will become the new tileset_config.json @@ -202,43 +204,44 @@ def tile_convert(otile, main_id, new_tile_number): tile_count = 0 new_tiles = list() -print 'processing tiles-new' +print('processing tiles-new') for otn in otc['tiles-new']: # need to add support for fallback tiles if os.path.basename(otn['file']).find('fallback') > -1: continue converted_tile_ids = dict() if first_filename == '': - first_filename = os.path.basename(otn['file']) # remember this for tileset.txt + first_filename = os.path.basename(otn['file']) # remember this for tileset.txt ntc['tiles-new'].append(dict()) ntn = ntc['tiles-new'][-1] ntn['file'] = 'gfx/' + new_tileset_name + '/' + os.path.basename(otn['file']) ntn['tiles'] = list() - print ' splitting ../'+otn['file'] + print(' splitting ../' + otn['file']) # split tile image sheet into individual tile images - command = 'convert -crop '+str(oheight)+'x'+str(owidth)+' ../'+otn['file']+' +repage '+new_tileset_name+'/tiles/tile-%06d.png' - print command + command = 'convert -crop ' + str(oheight) + 'x' + str(owidth) + ' ../' + otn['file'] + ' +repage ' + new_tileset_name + '/tiles/tile-%06d.png' + print(command) if os.system(command): raise - os.system('cp '+new_tileset_name+'/tiles/tile-*.png '+new_tileset_name+'/tiles/to_merge') + os.system('cp ' + new_tileset_name + '/tiles/tile-*.png ' + new_tileset_name + '/tiles/to_merge') # path joining version for other paths - TILEDIR = new_tileset_name+'/tiles' + TILEDIR = new_tileset_name + '/tiles' tile_count = len([name for name in os.listdir(TILEDIR) if os.path.isfile(os.path.join(TILEDIR, name))]) new_tile_number = tile_count for otile in otn['tiles']: - print ' handling ' + otile['id'] - tile = tile_convert(otile,otile['id'],new_tile_number) + print(' handling ' + otile['id']) + tile = tile_convert(otile, otile['id'], new_tile_number) new_tile_number = tile['ntn'] del tile['ntn'] ntn['tiles'].append(tile) - print 'Merging tiles to single image' - command = ('montage -background transparent "' + new_tileset_name + '/tiles/to_merge/tile-*.png" -tile 16x -geometry +0+0 ' + - new_tileset_name + '/' + os.path.basename(otn['file'])) - print command + print('Merging tiles to single image') + command = ( + 'montage -background transparent "' + new_tileset_name + '/tiles/to_merge/tile-*.png" -tile 16x -geometry +0+0 ' + + new_tileset_name + '/' + os.path.basename(otn['file'])) + print(command) if os.system(command): raise @@ -258,5 +261,4 @@ def tile_convert(otile, main_id, new_tile_number): 'JSON: ' + new_tileset_name + '/tile_config.json\n' + '#Tileset Path - Default of gfx/tinytile.png\n' + 'TILESET: ' + new_tileset_name + '/tiles.png\n' - ) - + )