diff --git a/.github/workflows/format_emscripten.yml b/.github/workflows/format_emscripten.yml index db8351147ce87..fb9e72d23afa0 100644 --- a/.github/workflows/format_emscripten.yml +++ b/.github/workflows/format_emscripten.yml @@ -48,7 +48,7 @@ jobs: run: ls -a - name: Create Pull Request - uses: peter-evans/create-pull-request@v4 + uses: peter-evans/create-pull-request@v6 with: token: ${{ secrets.TX_PR_CREATOR }} commit-message: JSON linter gh-pages file update diff --git a/.github/workflows/pull-translations.yml b/.github/workflows/pull-translations.yml index 0df16e6a56a21..7723463308728 100644 --- a/.github/workflows/pull-translations.yml +++ b/.github/workflows/pull-translations.yml @@ -44,7 +44,7 @@ jobs: - name: "Update stats" run: ./lang/update_stats.sh - name: Create Pull Request - uses: peter-evans/create-pull-request@v4 + uses: peter-evans/create-pull-request@v6 with: commit-message: Routine i18n updates on ${{ steps.current-date.outputs.formattedTime }} token: ${{ secrets.TX_PR_CREATOR }} diff --git a/.github/workflows/toc.yml b/.github/workflows/toc.yml index 1e0c4b352baf1..71165c1f522e6 100644 --- a/.github/workflows/toc.yml +++ b/.github/workflows/toc.yml @@ -17,7 +17,7 @@ jobs: - uses: actions/checkout@v4 - run: npx doctoc doc/JSON_INFO.md --github - name: Create Pull Request - uses: peter-evans/create-pull-request@v4 + uses: peter-evans/create-pull-request@v6 with: commit-message: Update the table of contents branch: update-toc diff --git a/.github/workflows/update-tilesets.yml b/.github/workflows/update-tilesets.yml index 315a9e44e159d..787fc8817e189 100644 --- a/.github/workflows/update-tilesets.yml +++ b/.github/workflows/update-tilesets.yml @@ -35,7 +35,7 @@ jobs: make tools/format/json_formatter.cgi find gfx/ -name "*.json" -print0 | xargs -0 -L 1 -P $(nproc) tools/format/json_formatter.cgi || exit 0 - name: Create Pull Request - uses: peter-evans/create-pull-request@v4 + uses: peter-evans/create-pull-request@v6 with: commit-message: | Routine tileset updates on ${{ steps.current-date.outputs.formattedTime }} diff --git a/.github/workflows/weekly-changelog.yml b/.github/workflows/weekly-changelog.yml index 1558002b9b3b5..a73f418894126 100644 --- a/.github/workflows/weekly-changelog.yml +++ b/.github/workflows/weekly-changelog.yml @@ -33,7 +33,7 @@ jobs: echo "date=$( date +"%Y-%m-%d" -d $CURR_DATE )" >> $GITHUB_OUTPUT echo "old_date=$LAST_WEEK" >> $GITHUB_OUTPUT - name: Create Pull Request - uses: peter-evans/create-pull-request@v4 + uses: peter-evans/create-pull-request@v6 with: commit-message: Weekly Changelog ${{ steps.getting-changes.outputs.old_date }} to ${{ steps.getting-changes.outputs.date }} committer: David Seguin diff --git a/data/json/construction.json b/data/json/construction.json index f2499188e1923..791582b1887d3 100644 --- a/data/json/construction.json +++ b/data/json/construction.json @@ -1120,7 +1120,7 @@ "category": "CONSTRUCT", "required_skills": [ [ "fabrication", 3 ] ], "time": "60 m", - "tools": [ [ [ "con_mix", 50 ] ] ], + "tools": [ [ [ "concrete_mix_tool", 50 ] ] ], "qualities": [ [ { "id": "SMOOTH", "level": 2 } ] ], "components": [ [ [ "concrete", 2 ] ], [ [ "water", 2 ], [ "water_clean", 2 ] ] ], "pre_terrain": "t_pit_shallow", @@ -1299,7 +1299,7 @@ "category": "CONSTRUCT", "required_skills": [ [ "fabrication", 4 ] ], "time": "180 m", - "tools": [ [ [ "con_mix", 50 ] ] ], + "tools": [ [ [ "concrete_mix_tool", 50 ] ] ], "qualities": [ [ { "id": "SMOOTH", "level": 2 } ] ], "components": [ [ [ "concrete", 4 ] ], [ [ "2x4", 12 ] ], [ [ "water", 4 ], [ "water_clean", 4 ] ] ], "pre_terrain": "t_pit_shallow", @@ -1313,7 +1313,7 @@ "category": "CONSTRUCT", "required_skills": [ [ "fabrication", 4 ] ], "time": "180 m", - "tools": [ [ [ "con_mix", 50 ] ] ], + "tools": [ [ [ "concrete_mix_tool", 50 ] ] ], "qualities": [ [ { "id": "SMOOTH", "level": 2 } ] ], "components": [ [ [ "concrete", 4 ] ], [ [ "2x4", 12 ] ], [ [ "water", 4 ], [ "water_clean", 4 ] ] ], "pre_terrain": "t_sconc_wall_halfway", @@ -1354,7 +1354,7 @@ "category": "CONSTRUCT", "required_skills": [ [ "fabrication", 6 ] ], "time": "120 m", - "tools": [ [ [ "con_mix", 50 ] ] ], + "tools": [ [ [ "concrete_mix_tool", 50 ] ] ], "qualities": [ [ { "id": "SMOOTH", "level": 2 } ] ], "components": [ [ [ "concrete", 6 ] ], [ [ "2x4", 12 ] ], [ [ "water", 4 ], [ "water_clean", 4 ] ] ], "pre_terrain": "t_reb_cage", @@ -1368,7 +1368,7 @@ "category": "CONSTRUCT", "required_skills": [ [ "fabrication", 6 ] ], "time": "120 m", - "tools": [ [ [ "con_mix", 50 ] ] ], + "tools": [ [ [ "concrete_mix_tool", 50 ] ] ], "qualities": [ [ { "id": "SMOOTH", "level": 2 } ] ], "components": [ [ [ "concrete", 6 ] ], [ [ "2x4", 12 ] ], [ [ "water", 4 ], [ "water_clean", 4 ] ] ], "pre_terrain": "t_strconc_wall_halfway", @@ -1382,7 +1382,7 @@ "category": "CONSTRUCT", "required_skills": [ [ "fabrication", 6 ] ], "time": "120 m", - "tools": [ [ [ "con_mix", 50 ] ] ], + "tools": [ [ [ "concrete_mix_tool", 50 ] ] ], "qualities": [ [ { "id": "SMOOTH", "level": 2 } ] ], "components": [ [ [ "concrete", 6 ] ], [ [ "2x4", 12 ] ], [ [ "rope_6", 8 ] ], [ [ "water", 4 ], [ "water_clean", 4 ] ] ], "pre_terrain": "t_strconc_wall_halfway", @@ -1410,7 +1410,7 @@ "category": "CONSTRUCT", "required_skills": [ [ "fabrication", 6 ] ], "time": "120 m", - "tools": [ [ [ "con_mix", 50 ] ] ], + "tools": [ [ [ "concrete_mix_tool", 50 ] ] ], "qualities": [ [ { "id": "SMOOTH", "level": 2 } ] ], "components": [ [ [ "concrete", 6 ] ], [ [ "2x4", 12 ] ], [ [ "water", 4 ], [ "water_clean", 4 ] ] ], "pre_terrain": "t_reb_cage", @@ -1424,7 +1424,7 @@ "category": "CONSTRUCT", "required_skills": [ [ "fabrication", 6 ] ], "time": "120 m", - "tools": [ [ [ "con_mix", 50 ] ] ], + "tools": [ [ [ "concrete_mix_tool", 50 ] ] ], "qualities": [ [ { "id": "SMOOTH", "level": 2 } ] ], "components": [ [ [ "concrete", 6 ] ], [ [ "water", 4 ], [ "water_clean", 4 ] ] ], "pre_terrain": "t_column_halfway", @@ -1465,7 +1465,7 @@ "category": "CONSTRUCT", "required_skills": [ [ "fabrication", 5 ] ], "time": "120 m", - "tools": [ [ [ "con_mix", 50 ] ] ], + "tools": [ [ [ "concrete_mix_tool", 50 ] ] ], "qualities": [ [ { "id": "SMOOTH", "level": 2 } ] ], "components": [ [ [ "concrete", 4 ] ], [ [ "water", 4 ], [ "water_clean", 4 ] ] ], "pre_terrain": "t_ov_smreb_cage", @@ -1493,7 +1493,7 @@ "category": "CONSTRUCT", "required_skills": [ [ "fabrication", 6 ] ], "time": "180 m", - "tools": [ [ [ "con_mix", 50 ] ] ], + "tools": [ [ [ "concrete_mix_tool", 50 ] ] ], "qualities": [ [ { "id": "SMOOTH", "level": 2 } ] ], "components": [ [ [ "concrete", 6 ] ], [ [ "water", 3 ], [ "water_clean", 3 ] ] ], "pre_terrain": "t_ov_reb_cage", @@ -1507,7 +1507,7 @@ "category": "CONSTRUCT", "required_skills": [ [ "fabrication", 6 ] ], "time": "180 m", - "tools": [ [ [ "con_mix", 50 ] ] ], + "tools": [ [ [ "concrete_mix_tool", 50 ] ] ], "qualities": [ [ { "id": "SMOOTH", "level": 2 } ] ], "components": [ [ [ "concrete", 6 ] ], [ [ "water", 3 ], [ "water_clean", 3 ] ] ], "pre_terrain": "t_strconc_floor_halfway", @@ -1997,7 +1997,7 @@ "required_skills": [ [ "fabrication", 4 ] ], "time": "180 m", "//": "The frame is used to keep the shape of the hole until the concrete is solid", - "tools": [ [ [ "con_mix", 50 ] ], [ [ "frame_wood", -1 ] ] ], + "tools": [ [ [ "concrete_mix_tool", 50 ] ], [ [ "frame_wood", -1 ] ] ], "qualities": [ [ { "id": "SMOOTH", "level": 2 } ] ], "components": [ [ [ "concrete", 4 ] ], [ [ "2x4", 12 ] ], [ [ "water", 4 ], [ "water_clean", 4 ] ] ], "pre_terrain": "t_sconc_wall_halfway", @@ -2011,7 +2011,7 @@ "required_skills": [ [ "fabrication", 6 ] ], "time": "120 m", "//": "The frame is used to keep the shape of the hole until the concrete is solid", - "tools": [ [ [ "con_mix", 50 ] ], [ [ "frame_wood", -1 ] ] ], + "tools": [ [ [ "concrete_mix_tool", 50 ] ], [ [ "frame_wood", -1 ] ] ], "qualities": [ [ { "id": "SMOOTH", "level": 2 } ] ], "components": [ [ [ "concrete", 6 ] ], [ [ "2x4", 12 ] ], [ [ "water", 4 ], [ "water_clean", 4 ] ] ], "pre_terrain": "t_strconc_wall_halfway", @@ -2732,7 +2732,7 @@ "qualities": [ [ { "id": "SAW_M", "level": 1 } ], [ { "id": "SCREW", "level": 1 } ], [ { "id": "SMOOTH", "level": 2 } ] ], "using": [ [ "welding_standard", 500 ], [ "welding_standard", 500 ] ], "//1": "lots of 1 meter square metal sheet and plating so very big weld", - "tools": [ [ [ "con_mix", 50 ] ] ], + "tools": [ [ [ "concrete_mix_tool", 50 ] ] ], "components": [ [ [ "hdframe", 1 ] ], [ [ "steel_lump", 2 ], [ "steel_chunk", 8 ], [ "scrap", 40 ] ], @@ -4947,7 +4947,7 @@ "category": "DIG", "required_skills": [ [ "fabrication", 3 ] ], "time": "150 m", - "tools": [ [ [ "con_mix", 125 ] ] ], + "tools": [ [ [ "concrete_mix_tool", 125 ] ] ], "qualities": [ [ { "id": "SMOOTH", "level": 2 } ] ], "components": [ [ [ "concrete", 5 ] ], [ [ "water", 5 ], [ "water_clean", 5 ] ] ], "pre_special": [ "check_empty", "check_stable", "check_up_OK", "check_nofloor_above" ], @@ -4963,7 +4963,7 @@ "category": "DIG", "required_skills": [ [ "fabrication", 3 ] ], "time": "150 m", - "tools": [ [ [ "con_mix", 125 ] ] ], + "tools": [ [ [ "concrete_mix_tool", 125 ] ] ], "qualities": [ [ { "id": "SMOOTH", "level": 2 } ] ], "components": [ [ [ "concrete", 5 ] ], [ [ "water", 5 ], [ "water_clean", 5 ] ] ], "pre_special": [ "check_empty", "check_stable", "check_up_OK", "check_nofloor_above", "check_ramp_high" ], diff --git a/data/json/effects.json b/data/json/effects.json index 502fe99469fb0..757f26c4b54db 100644 --- a/data/json/effects.json +++ b/data/json/effects.json @@ -3873,18 +3873,6 @@ "//": "Mood debuff is handled separately by bad_food_mood_debuff EoC.", "rating": "bad" }, - { - "type": "effect_type", - "id": "genetics_damaged", - "name": [ "Spent Phenotype", "Depleted Phenotype", "Bankrupt Phenotype" ], - "desc": [ - "Mutation has left you with a persistent mild discomfort. It seems harmless for now, but you can't predict if it'll get worse.", - "There's an enervating sense of dysmorphia throughout your whole body. It waxes and wanes, but never quite goes away. Mutating this much can't be good for you…", - "You're haunted by phantom pains across your entire body now. Everything aches from an exhaustion that never seems to fade. Any further mutation right now is very unlikely to have a happy ending." - ], - "max_intensity": 3, - "rating": "bad" - }, { "type": "effect_type", "id": "hypovolemia", diff --git a/data/json/effects_on_condition/melee_eocs.json b/data/json/effects_on_condition/melee_eocs.json deleted file mode 100644 index 33293186f9b54..0000000000000 --- a/data/json/effects_on_condition/melee_eocs.json +++ /dev/null @@ -1,986 +0,0 @@ -[ - { - "type": "effect_on_condition", - "id": "EOC_MELEE_PROF_ATTACK_MONSTER", - "//": "If the player attacks a monster, and hits, run EOC to check what weapon type they're using.", - "global": false, - "eoc_type": "EVENT", - "required_event": "character_melee_attacks_monster", - "condition": { "math": [ "_hits", "==", "1" ] }, - "effect": [ { "run_eocs": "EOC_MELEE_PROF_WHAT_CATEGORY" } ] - }, - { - "type": "effect_on_condition", - "id": "EOC_MELEE_PROF_ATTACK_CHARACTER", - "//": "If the player attacks a character, run EOC to check what weapon type they're using.", - "global": false, - "eoc_type": "EVENT", - "required_event": "character_melee_attacks_character", - "condition": { "math": [ "_hits", "==", "1" ] }, - "effect": [ { "run_eocs": "EOC_MELEE_PROF_WHAT_CATEGORY" } ] - }, - { - "type": "effect_on_condition", - "id": "EOC_MELEE_PROF_WHAT_CATEGORY", - "//": "Checks what weapon categories are held, each increments experience, and defines lowest proficiency level of held weapon in the sub-EoCs.", - "global": false, - "effect": [ - { "math": [ "u_prof_lowest", "=", "4" ] }, - { - "run_eocs": [ - "IS_AUTO_RIFLES", - "IS_AUTO_PISTOLS", - "IS_KNIVES", - "IS_BATONS", - "IS_FLAILS", - "IS_MACES", - "IS_MEDIUM_SWORDS", - "IS_SHORT_SWORDS", - "IS_LONG_SWORDS", - "IS_QUARTERSTAVES", - "IS_CLAWS", - "IS_SHIVS", - "IS_HOOKING", - "IS_SPEARS", - "IS_POLEARMS", - "IS_FENCING", - "IS_THRUSTING_SWORDS", - "IS_BIONICS", - "IS_BIONIC_SWORDS", - "IS_GREAT_SWORDS", - "IS_GREAT_HAMMERS", - "IS_GREAT_AXES", - "IS_HAND_AXES", - "IS_UNARMED" - ] - }, - { "run_eocs": "EOC_MELEE_PROF_BENEFIT" } - ] - }, - { - "type": "effect_on_condition", - "id": "IS_AUTO_RIFLES", - "global": false, - "condition": { "u_has_wielded_with_weapon_category": "AUTOMATIC_RIFLES" }, - "effect": [ - { - "if": { "math": [ "u_proficiency('prof_auto_rifles_familiar', 'format': 'percent')", ">=", "100" ] }, - "then": [ - { - "if": { "math": [ "u_proficiency('prof_auto_rifles_pro', 'format': 'percent')", ">=", "100" ] }, - "then": [ - { - "if": { "math": [ "u_proficiency('prof_auto_rifles_master', 'format': 'percent')", ">=", "100" ] }, - "then": [ { "math": [ "u_prof_level", "=", "3" ] }, { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } ], - "else": [ - { "math": [ "u_proficiency('prof_auto_rifles_master', 'format': 'percent')", "+=", "rand(4) / 64" ] }, - { "math": [ "u_prof_level", "=", "2" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ], - "else": [ - { "math": [ "u_proficiency('prof_auto_rifles_pro', 'format': 'percent')", "+=", "rand(4) / 32" ] }, - { "math": [ "u_prof_level", "=", "1" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ], - "else": [ - { "math": [ "u_proficiency('prof_auto_rifles_familiar', 'format': 'percent')", "+=", "rand(4) / 16" ] }, - { "math": [ "u_prof_level", "=", "0" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ] - }, - { - "type": "effect_on_condition", - "id": "IS_AUTO_PISTOLS", - "global": false, - "condition": { "u_has_wielded_with_weapon_category": "AUTOMATIC_PISTOLS" }, - "effect": [ - { - "if": { "math": [ "u_proficiency('prof_auto_pistols_familiar', 'format': 'percent')", ">=", "100" ] }, - "then": [ - { - "if": { "math": [ "u_proficiency('prof_auto_pistols_pro', 'format': 'percent')", ">=", "100" ] }, - "then": [ - { - "if": { "math": [ "u_proficiency('prof_auto_pistols_master', 'format': 'percent')", ">=", "100" ] }, - "then": [ { "math": [ "u_prof_level", "=", "3" ] }, { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } ], - "else": [ - { "math": [ "u_proficiency('prof_auto_pistols_master', 'format': 'percent')", "+=", "rand(4) / 64" ] }, - { "math": [ "u_prof_level", "=", "2" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ], - "else": [ - { "math": [ "u_proficiency('prof_auto_pistols_pro', 'format': 'percent')", "+=", "rand(4) / 32" ] }, - { "math": [ "u_prof_level", "=", "1" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ], - "else": [ - { "math": [ "u_proficiency('prof_auto_pistols_familiar', 'format': 'percent')", "+=", "rand(4) / 16" ] }, - { "math": [ "u_prof_level", "=", "0" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ] - }, - { - "type": "effect_on_condition", - "id": "IS_KNIVES", - "global": false, - "condition": { "u_has_wielded_with_weapon_category": "KNIVES" }, - "effect": [ - { - "if": { "math": [ "u_proficiency('prof_knives_familiar', 'format': 'percent')", ">=", "100" ] }, - "then": [ - { - "if": { "math": [ "u_proficiency('prof_knives_pro', 'format': 'percent')", ">=", "100" ] }, - "then": [ - { - "if": { "math": [ "u_proficiency('prof_knives_master', 'format': 'percent')", ">=", "100" ] }, - "then": [ { "math": [ "u_prof_level", "=", "3" ] }, { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } ], - "else": [ - { "math": [ "u_proficiency('prof_knives_master', 'format': 'percent')", "+=", "rand(4) / 64" ] }, - { "math": [ "u_prof_level", "=", "2" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ], - "else": [ - { "math": [ "u_proficiency('prof_knives_pro', 'format': 'percent')", "+=", "rand(4) / 32" ] }, - { "math": [ "u_prof_level", "=", "1" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ], - "else": [ - { "math": [ "u_proficiency('prof_knives_familiar', 'format': 'percent')", "+=", "rand(4) / 16" ] }, - { "math": [ "u_prof_level", "=", "0" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ] - }, - { - "type": "effect_on_condition", - "id": "IS_BATONS", - "global": false, - "condition": { "u_has_wielded_with_weapon_category": "BATONS" }, - "effect": [ - { - "if": { "math": [ "u_proficiency('prof_batons_familiar', 'format': 'percent')", ">=", "100" ] }, - "then": [ - { - "if": { "math": [ "u_proficiency('prof_batons_pro', 'format': 'percent')", ">=", "100" ] }, - "then": [ - { - "if": { "math": [ "u_proficiency('prof_batons_master', 'format': 'percent')", ">=", "100" ] }, - "then": [ { "math": [ "u_prof_level", "=", "3" ] }, { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } ], - "else": [ - { "math": [ "u_proficiency('prof_batons_master', 'format': 'percent')", "+=", "rand(4) / 64" ] }, - { "math": [ "u_prof_level", "=", "2" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ], - "else": [ - { "math": [ "u_proficiency('prof_batons_pro', 'format': 'percent')", "+=", "rand(4) / 32" ] }, - { "math": [ "u_prof_level", "=", "1" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ], - "else": [ - { "math": [ "u_proficiency('prof_batons_familiar', 'format': 'percent')", "+=", "rand(4) / 16" ] }, - { "math": [ "u_prof_level", "=", "0" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ] - }, - { - "type": "effect_on_condition", - "id": "IS_FLAILS", - "global": false, - "condition": { "u_has_wielded_with_weapon_category": "FLAILS" }, - "effect": [ - { - "if": { "math": [ "u_proficiency('prof_flails_familiar', 'format': 'percent')", ">=", "100" ] }, - "then": [ - { - "if": { "math": [ "u_proficiency('prof_flails_pro', 'format': 'percent')", ">=", "100" ] }, - "then": [ - { - "if": { "math": [ "u_proficiency('prof_flails_master', 'format': 'percent')", ">=", "100" ] }, - "then": [ { "math": [ "u_prof_level", "=", "3" ] }, { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } ], - "else": [ - { "math": [ "u_proficiency('prof_flails_master', 'format': 'percent')", "+=", "rand(4) / 64" ] }, - { "math": [ "u_prof_level", "=", "2" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ], - "else": [ - { "math": [ "u_proficiency('prof_flails_pro', 'format': 'percent')", "+=", "rand(4) / 32" ] }, - { "math": [ "u_prof_level", "=", "1" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ], - "else": [ - { "math": [ "u_proficiency('prof_flails_familiar', 'format': 'percent')", "+=", "rand(4) / 16" ] }, - { "math": [ "u_prof_level", "=", "0" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ] - }, - { - "type": "effect_on_condition", - "id": "IS_MACES", - "global": false, - "condition": { "u_has_wielded_with_weapon_category": "MACES" }, - "effect": [ - { - "if": { "math": [ "u_proficiency('prof_maces_familiar', 'format': 'percent')", ">=", "100" ] }, - "then": [ - { - "if": { "math": [ "u_proficiency('prof_maces_pro', 'format': 'percent')", ">=", "100" ] }, - "then": [ - { - "if": { "math": [ "u_proficiency('prof_maces_master', 'format': 'percent')", ">=", "100" ] }, - "then": [ { "math": [ "u_prof_level", "=", "3" ] }, { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } ], - "else": [ - { "math": [ "u_proficiency('prof_maces_master', 'format': 'percent')", "+=", "rand(4) / 64" ] }, - { "math": [ "u_prof_level", "=", "2" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ], - "else": [ - { "math": [ "u_proficiency('prof_maces_pro', 'format': 'percent')", "+=", "rand(4) / 32" ] }, - { "math": [ "u_prof_level", "=", "1" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ], - "else": [ - { "math": [ "u_proficiency('prof_maces_familiar', 'format': 'percent')", "+=", "rand(4) / 16" ] }, - { "math": [ "u_prof_level", "=", "0" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ] - }, - { - "type": "effect_on_condition", - "id": "IS_MEDIUM_SWORDS", - "global": false, - "condition": { "u_has_wielded_with_weapon_category": "MEDIUM_SWORDS" }, - "effect": [ - { - "if": { "math": [ "u_proficiency('prof_medium_swords_familiar', 'format': 'percent')", ">=", "100" ] }, - "then": [ - { - "if": { "math": [ "u_proficiency('prof_medium_swords_pro', 'format': 'percent')", ">=", "100" ] }, - "then": [ - { - "if": { "math": [ "u_proficiency('prof_medium_swords_master', 'format': 'percent')", ">=", "100" ] }, - "then": [ { "math": [ "u_prof_level", "=", "3" ] }, { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } ], - "else": [ - { "math": [ "u_proficiency('prof_medium_swords_master', 'format': 'percent')", "+=", "rand(4) / 64" ] }, - { "math": [ "u_prof_level", "=", "2" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ], - "else": [ - { "math": [ "u_proficiency('prof_medium_swords_pro', 'format': 'percent')", "+=", "rand(4) / 32" ] }, - { "math": [ "u_prof_level", "=", "1" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ], - "else": [ - { "math": [ "u_proficiency('prof_medium_swords_familiar', 'format': 'percent')", "+=", "rand(4) / 16" ] }, - { "math": [ "u_prof_level", "=", "0" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ] - }, - { - "type": "effect_on_condition", - "id": "IS_SHORT_SWORDS", - "global": false, - "condition": { "u_has_wielded_with_weapon_category": "SHORT_SWORDS" }, - "effect": [ - { - "if": { "math": [ "u_proficiency('prof_short_swords_familiar', 'format': 'percent')", ">=", "100" ] }, - "then": [ - { - "if": { "math": [ "u_proficiency('prof_short_swords_pro', 'format': 'percent')", ">=", "100" ] }, - "then": [ - { - "if": { "math": [ "u_proficiency('prof_short_swords_master', 'format': 'percent')", ">=", "100" ] }, - "then": [ { "math": [ "u_prof_level", "=", "3" ] }, { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } ], - "else": [ - { "math": [ "u_proficiency('prof_short_swords_master', 'format': 'percent')", "+=", "rand(4) / 64" ] }, - { "math": [ "u_prof_level", "=", "2" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ], - "else": [ - { "math": [ "u_proficiency('prof_short_swords_pro', 'format': 'percent')", "+=", "rand(4) / 32" ] }, - { "math": [ "u_prof_level", "=", "1" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ], - "else": [ - { "math": [ "u_proficiency('prof_short_swords_familiar', 'format': 'percent')", "+=", "rand(4) / 16" ] }, - { "math": [ "u_prof_level", "=", "0" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ] - }, - { - "type": "effect_on_condition", - "id": "IS_LONG_SWORDS", - "global": false, - "condition": { "u_has_wielded_with_weapon_category": "LONG_SWORDS" }, - "effect": [ - { - "if": { "math": [ "u_proficiency('prof_long_swords_familiar', 'format': 'percent')", ">=", "100" ] }, - "then": [ - { - "if": { "math": [ "u_proficiency('prof_long_swords_pro', 'format': 'percent')", ">=", "100" ] }, - "then": [ - { - "if": { "math": [ "u_proficiency('prof_long_swords_master', 'format': 'percent')", ">=", "100" ] }, - "then": [ { "math": [ "u_prof_level", "=", "3" ] }, { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } ], - "else": [ - { "math": [ "u_proficiency('prof_long_swords_master', 'format': 'percent')", "+=", "rand(4) / 64" ] }, - { "math": [ "u_prof_level", "=", "2" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ], - "else": [ - { "math": [ "u_proficiency('prof_long_swords_pro', 'format': 'percent')", "+=", "rand(4) / 32" ] }, - { "math": [ "u_prof_level", "=", "1" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ], - "else": [ - { "math": [ "u_proficiency('prof_long_swords_familiar', 'format': 'percent')", "+=", "rand(4) / 16" ] }, - { "math": [ "u_prof_level", "=", "0" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ] - }, - { - "type": "effect_on_condition", - "id": "IS_QUARTERSTAVES", - "global": false, - "condition": { "u_has_wielded_with_weapon_category": "QUARTERSTAVES" }, - "effect": [ - { - "if": { "math": [ "u_proficiency('prof_quarterstaves_familiar', 'format': 'percent')", ">=", "100" ] }, - "then": [ - { - "if": { "math": [ "u_proficiency('prof_quarterstaves_pro', 'format': 'percent')", ">=", "100" ] }, - "then": [ - { - "if": { "math": [ "u_proficiency('prof_quarterstaves_master', 'format': 'percent')", ">=", "100" ] }, - "then": [ { "math": [ "u_prof_level", "=", "3" ] }, { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } ], - "else": [ - { "math": [ "u_proficiency('prof_quarterstaves_master', 'format': 'percent')", "+=", "rand(4) / 64" ] }, - { "math": [ "u_prof_level", "=", "2" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ], - "else": [ - { "math": [ "u_proficiency('prof_quarterstaves_pro', 'format': 'percent')", "+=", "rand(4) / 32" ] }, - { "math": [ "u_prof_level", "=", "1" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ], - "else": [ - { "math": [ "u_proficiency('prof_quarterstaves_familiar', 'format': 'percent')", "+=", "rand(4) / 16" ] }, - { "math": [ "u_prof_level", "=", "0" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ] - }, - { - "type": "effect_on_condition", - "id": "IS_CLAWS", - "global": false, - "condition": { "u_has_wielded_with_weapon_category": "CLAWS" }, - "effect": [ - { - "if": { "math": [ "u_proficiency('prof_claws_familiar', 'format': 'percent')", ">=", "100" ] }, - "then": [ - { - "if": { "math": [ "u_proficiency('prof_claws_pro', 'format': 'percent')", ">=", "100" ] }, - "then": [ - { - "if": { "math": [ "u_proficiency('prof_claws_master', 'format': 'percent')", ">=", "100" ] }, - "then": [ { "math": [ "u_prof_level", "=", "3" ] }, { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } ], - "else": [ - { "math": [ "u_proficiency('prof_claws_master', 'format': 'percent')", "+=", "rand(4) / 64" ] }, - { "math": [ "u_prof_level", "=", "2" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ], - "else": [ - { "math": [ "u_proficiency('prof_claws_pro', 'format': 'percent')", "+=", "rand(4) / 32" ] }, - { "math": [ "u_prof_level", "=", "1" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ], - "else": [ - { "math": [ "u_proficiency('prof_claws_familiar', 'format': 'percent')", "+=", "rand(4) / 16" ] }, - { "math": [ "u_prof_level", "=", "0" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ] - }, - { - "type": "effect_on_condition", - "id": "IS_SHIVS", - "global": false, - "condition": { "u_has_wielded_with_weapon_category": "SHIVS" }, - "effect": [ - { - "if": { "math": [ "u_proficiency('prof_shivs_familiar', 'format': 'percent')", ">=", "100" ] }, - "then": [ - { - "if": { "math": [ "u_proficiency('prof_shivs_pro', 'format': 'percent')", ">=", "100" ] }, - "then": [ - { - "if": { "math": [ "u_proficiency('prof_shivs_master', 'format': 'percent')", ">=", "100" ] }, - "then": [ { "math": [ "u_prof_level", "=", "3" ] }, { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } ], - "else": [ - { "math": [ "u_proficiency('prof_shivs_master', 'format': 'percent')", "+=", "rand(4) / 64" ] }, - { "math": [ "u_prof_level", "=", "2" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ], - "else": [ - { "math": [ "u_proficiency('prof_shivs_pro', 'format': 'percent')", "+=", "rand(4) / 32" ] }, - { "math": [ "u_prof_level", "=", "1" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ], - "else": [ - { "math": [ "u_proficiency('prof_shivs_familiar', 'format': 'percent')", "+=", "rand(4) / 16" ] }, - { "math": [ "u_prof_level", "=", "0" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ] - }, - { - "type": "effect_on_condition", - "id": "IS_HOOKING", - "global": false, - "condition": { "u_has_wielded_with_weapon_category": "HOOKING_WEAPONRY" }, - "effect": [ - { - "if": { "math": [ "u_proficiency('prof_hooking_familiar', 'format': 'percent')", ">=", "100" ] }, - "then": [ - { - "if": { "math": [ "u_proficiency('prof_hooking_pro', 'format': 'percent')", ">=", "100" ] }, - "then": [ - { - "if": { "math": [ "u_proficiency('prof_hooking_master', 'format': 'percent')", ">=", "100" ] }, - "then": [ { "math": [ "u_prof_level", "=", "3" ] }, { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } ], - "else": [ - { "math": [ "u_proficiency('prof_hooking_master', 'format': 'percent')", "+=", "rand(4) / 64" ] }, - { "math": [ "u_prof_level", "=", "2" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ], - "else": [ - { "math": [ "u_proficiency('prof_hooking_pro', 'format': 'percent')", "+=", "rand(4) / 32" ] }, - { "math": [ "u_prof_level", "=", "1" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ], - "else": [ - { "math": [ "u_proficiency('prof_hooking_familiar', 'format': 'percent')", "+=", "rand(4) / 16" ] }, - { "math": [ "u_prof_level", "=", "0" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ] - }, - { - "type": "effect_on_condition", - "id": "IS_SPEARS", - "global": false, - "condition": { "u_has_wielded_with_weapon_category": "SPEARS" }, - "effect": [ - { - "if": { "math": [ "u_proficiency('prof_spears_familiar', 'format': 'percent')", ">=", "100" ] }, - "then": [ - { - "if": { "math": [ "u_proficiency('prof_spears_pro', 'format': 'percent')", ">=", "100" ] }, - "then": [ - { - "if": { "math": [ "u_proficiency('prof_spears_master', 'format': 'percent')", ">=", "100" ] }, - "then": [ { "math": [ "u_prof_level", "=", "3" ] }, { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } ], - "else": [ - { "math": [ "u_proficiency('prof_spears_master', 'format': 'percent')", "+=", "rand(4) / 64" ] }, - { "math": [ "u_prof_level", "=", "2" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ], - "else": [ - { "math": [ "u_proficiency('prof_spears_pro', 'format': 'percent')", "+=", "rand(4) / 32" ] }, - { "math": [ "u_prof_level", "=", "1" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ], - "else": [ - { "math": [ "u_proficiency('prof_spears_familiar', 'format': 'percent')", "+=", "rand(4) / 16" ] }, - { "math": [ "u_prof_level", "=", "0" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ] - }, - { - "type": "effect_on_condition", - "id": "IS_POLEARMS", - "global": false, - "condition": { "u_has_wielded_with_weapon_category": "POLEARMS" }, - "effect": [ - { - "if": { "math": [ "u_proficiency('prof_polearms_familiar', 'format': 'percent')", ">=", "100" ] }, - "then": [ - { - "if": { "math": [ "u_proficiency('prof_polearms_pro', 'format': 'percent')", ">=", "100" ] }, - "then": [ - { - "if": { "math": [ "u_proficiency('prof_polearms_master', 'format': 'percent')", ">=", "100" ] }, - "then": [ { "math": [ "u_prof_level", "=", "3" ] }, { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } ], - "else": [ - { "math": [ "u_proficiency('prof_polearms_master', 'format': 'percent')", "+=", "rand(4) / 64" ] }, - { "math": [ "u_prof_level", "=", "2" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ], - "else": [ - { "math": [ "u_proficiency('prof_polearms_pro', 'format': 'percent')", "+=", "rand(4) / 32" ] }, - { "math": [ "u_prof_level", "=", "1" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ], - "else": [ - { "math": [ "u_proficiency('prof_polearms_familiar', 'format': 'percent')", "+=", "rand(4) / 16" ] }, - { "math": [ "u_prof_level", "=", "0" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ] - }, - { - "type": "effect_on_condition", - "id": "IS_FENCING", - "global": false, - "condition": { "u_has_wielded_with_weapon_category": "FENCING_WEAPONRY" }, - "effect": [ - { - "if": { "math": [ "u_proficiency('prof_fencing_weapons_familiar', 'format': 'percent')", ">=", "100" ] }, - "then": [ - { - "if": { "math": [ "u_proficiency('prof_fencing_weapons_pro', 'format': 'percent')", ">=", "100" ] }, - "then": [ - { - "if": { "math": [ "u_proficiency('prof_fencing_weapons_master', 'format': 'percent')", ">=", "100" ] }, - "then": [ { "math": [ "u_prof_level", "=", "3" ] }, { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } ], - "else": [ - { "math": [ "u_proficiency('prof_fencing_weapons_master', 'format': 'percent')", "+=", "rand(4) / 64" ] }, - { "math": [ "u_prof_level", "=", "2" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ], - "else": [ - { "math": [ "u_proficiency('prof_fencing_weapons_pro', 'format': 'percent')", "+=", "rand(4) / 32" ] }, - { "math": [ "u_prof_level", "=", "1" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ], - "else": [ - { "math": [ "u_proficiency('prof_fencing_weapons_familiar', 'format': 'percent')", "+=", "rand(4) / 16" ] }, - { "math": [ "u_prof_level", "=", "0" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ] - }, - { - "type": "effect_on_condition", - "id": "IS_THRUSTING_SWORDS", - "global": false, - "condition": { "u_has_wielded_with_weapon_category": "LONG_THRUSTING_SWORD" }, - "effect": [ - { - "if": { "math": [ "u_proficiency('prof_thrusting_swords_familiar', 'format': 'percent')", ">=", "100" ] }, - "then": [ - { - "if": { "math": [ "u_proficiency('prof_thrusting_swords_pro', 'format': 'percent')", ">=", "100" ] }, - "then": [ - { - "if": { "math": [ "u_proficiency('prof_thrusting_swords_master', 'format': 'percent')", ">=", "100" ] }, - "then": [ { "math": [ "u_prof_level", "=", "3" ] }, { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } ], - "else": [ - { "math": [ "u_proficiency('prof_thrusting_swords_master', 'format': 'percent')", "+=", "rand(4) / 64" ] }, - { "math": [ "u_prof_level", "=", "2" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ], - "else": [ - { "math": [ "u_proficiency('prof_thrusting_swords_pro', 'format': 'percent')", "+=", "rand(4) / 32" ] }, - { "math": [ "u_prof_level", "=", "1" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ], - "else": [ - { "math": [ "u_proficiency('prof_thrusting_swords_familiar', 'format': 'percent')", "+=", "rand(4) / 16" ] }, - { "math": [ "u_prof_level", "=", "0" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ] - }, - { - "type": "effect_on_condition", - "id": "IS_BIONICS", - "global": false, - "condition": { "or": [ { "u_has_wielded_with_weapon_category": "BIONIC_WEAPONRY" }, { "u_using_martial_art": "style_biojutsu" } ] }, - "effect": [ - { - "if": { "math": [ "u_proficiency('prof_bionics_familiar', 'format': 'percent')", ">=", "100" ] }, - "then": [ - { - "if": { "math": [ "u_proficiency('prof_bionics_pro', 'format': 'percent')", ">=", "100" ] }, - "then": [ - { - "if": { "math": [ "u_proficiency('prof_bionics_master', 'format': 'percent')", ">=", "100" ] }, - "then": [ { "math": [ "u_prof_level", "=", "3" ] }, { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } ], - "else": [ - { "math": [ "u_proficiency('prof_bionics_master', 'format': 'percent')", "+=", "rand(4) / 64" ] }, - { "math": [ "u_prof_level", "=", "2" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ], - "else": [ - { "math": [ "u_proficiency('prof_bionics_pro', 'format': 'percent')", "+=", "rand(4) / 32" ] }, - { "math": [ "u_prof_level", "=", "1" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ], - "else": [ - { "math": [ "u_proficiency('prof_bionics_familiar', 'format': 'percent')", "+=", "rand(4) / 16" ] }, - { "math": [ "u_prof_level", "=", "0" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ] - }, - { - "type": "effect_on_condition", - "id": "IS_BIONIC_SWORDS", - "global": false, - "condition": { "u_has_wielded_with_weapon_category": "BIONIC_SWORDS" }, - "effect": [ - { - "if": { "math": [ "u_proficiency('prof_bionic_swords_familiar', 'format': 'percent')", ">=", "100" ] }, - "then": [ - { - "if": { "math": [ "u_proficiency('prof_bionic_swords_pro', 'format': 'percent')", ">=", "100" ] }, - "then": [ - { - "if": { "math": [ "u_proficiency('prof_bionic_swords_master', 'format': 'percent')", ">=", "100" ] }, - "then": [ { "math": [ "u_prof_level", "=", "3" ] }, { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } ], - "else": [ - { "math": [ "u_proficiency('prof_bionic_swords_master', 'format': 'percent')", "+=", "rand(4) / 64" ] }, - { "math": [ "u_prof_level", "=", "2" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ], - "else": [ - { "math": [ "u_proficiency('prof_bionic_swords_pro', 'format': 'percent')", "+=", "rand(4) / 32" ] }, - { "math": [ "u_prof_level", "=", "1" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ], - "else": [ - { "math": [ "u_proficiency('prof_bionic_swords_familiar', 'format': 'percent')", "+=", "rand(4) / 16" ] }, - { "math": [ "u_prof_level", "=", "0" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ] - }, - { - "type": "effect_on_condition", - "id": "IS_GREAT_SWORDS", - "global": false, - "condition": { "u_has_wielded_with_weapon_category": "GREAT_SWORDS" }, - "effect": [ - { - "if": { "math": [ "u_proficiency('prof_great_swords_familiar', 'format': 'percent')", ">=", "100" ] }, - "then": [ - { - "if": { "math": [ "u_proficiency('prof_great_swords_pro', 'format': 'percent')", ">=", "100" ] }, - "then": [ - { - "if": { "math": [ "u_proficiency('prof_great_swords_master', 'format': 'percent')", ">=", "100" ] }, - "then": [ { "math": [ "u_prof_level", "=", "3" ] }, { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } ], - "else": [ - { "math": [ "u_proficiency('prof_great_swords_master', 'format': 'percent')", "+=", "rand(4) / 64" ] }, - { "math": [ "u_prof_level", "=", "2" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ], - "else": [ - { "math": [ "u_proficiency('prof_great_swords_pro', 'format': 'percent')", "+=", "rand(4) / 32" ] }, - { "math": [ "u_prof_level", "=", "1" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ], - "else": [ - { "math": [ "u_proficiency('prof_great_swords_familiar', 'format': 'percent')", "+=", "rand(4) / 16" ] }, - { "math": [ "u_prof_level", "=", "0" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ] - }, - { - "type": "effect_on_condition", - "id": "IS_GREAT_HAMMERS", - "global": false, - "condition": { "u_has_wielded_with_weapon_category": "GREAT_HAMMERS" }, - "effect": [ - { - "if": { "math": [ "u_proficiency('prof_great_hammers_familiar', 'format': 'percent')", ">=", "100" ] }, - "then": [ - { - "if": { "math": [ "u_proficiency('prof_great_hammers_pro', 'format': 'percent')", ">=", "100" ] }, - "then": [ - { - "if": { "math": [ "u_proficiency('prof_great_hammers_master', 'format': 'percent')", ">=", "100" ] }, - "then": [ { "math": [ "u_prof_level", "=", "3" ] }, { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } ], - "else": [ - { "math": [ "u_proficiency('prof_great_hammers_master', 'format': 'percent')", "+=", "rand(4) / 64" ] }, - { "math": [ "u_prof_level", "=", "2" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ], - "else": [ - { "math": [ "u_proficiency('prof_great_hammers_pro', 'format': 'percent')", "+=", "rand(4) / 32" ] }, - { "math": [ "u_prof_level", "=", "1" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ], - "else": [ - { "math": [ "u_proficiency('prof_great_hammers_familiar', 'format': 'percent')", "+=", "rand(4) / 16" ] }, - { "math": [ "u_prof_level", "=", "0" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ] - }, - { - "type": "effect_on_condition", - "id": "IS_GREAT_AXES", - "global": false, - "condition": { "u_has_wielded_with_weapon_category": "GREAT_AXES" }, - "effect": [ - { - "if": { "math": [ "u_proficiency('prof_great_axes_familiar', 'format': 'percent')", ">=", "100" ] }, - "then": [ - { - "if": { "math": [ "u_proficiency('prof_great_axes_pro', 'format': 'percent')", ">=", "100" ] }, - "then": [ - { - "if": { "math": [ "u_proficiency('prof_great_axes_master', 'format': 'percent')", ">=", "100" ] }, - "then": [ { "math": [ "u_prof_level", "=", "3" ] }, { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } ], - "else": [ - { "math": [ "u_proficiency('prof_great_axes_master', 'format': 'percent')", "+=", "rand(4) / 64" ] }, - { "math": [ "u_prof_level", "=", "2" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ], - "else": [ - { "math": [ "u_proficiency('prof_great_axes_pro', 'format': 'percent')", "+=", "rand(4) / 32" ] }, - { "math": [ "u_prof_level", "=", "1" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ], - "else": [ - { "math": [ "u_proficiency('prof_great_axes_familiar', 'format': 'percent')", "+=", "rand(4) / 16" ] }, - { "math": [ "u_prof_level", "=", "0" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ] - }, - { - "type": "effect_on_condition", - "id": "IS_HAND_AXES", - "global": false, - "condition": { "u_has_wielded_with_weapon_category": "HAND_AXES" }, - "effect": [ - { - "if": { "math": [ "u_proficiency('prof_hand_axes_familiar', 'format': 'percent')", ">=", "100" ] }, - "then": [ - { - "if": { "math": [ "u_proficiency('prof_hand_axes_pro', 'format': 'percent')", ">=", "100" ] }, - "then": [ - { - "if": { "math": [ "u_proficiency('prof_hand_axes_master', 'format': 'percent')", ">=", "100" ] }, - "then": [ { "math": [ "u_prof_level", "=", "3" ] }, { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } ], - "else": [ - { "math": [ "u_proficiency('prof_hand_axes_master', 'format': 'percent')", "+=", "rand(4) / 64" ] }, - { "math": [ "u_prof_level", "=", "2" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ], - "else": [ - { "math": [ "u_proficiency('prof_hand_axes_pro', 'format': 'percent')", "+=", "rand(4) / 32" ] }, - { "math": [ "u_prof_level", "=", "1" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ], - "else": [ - { "math": [ "u_proficiency('prof_hand_axes_familiar', 'format': 'percent')", "+=", "rand(4) / 16" ] }, - { "math": [ "u_prof_level", "=", "0" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ] - }, - { - "type": "effect_on_condition", - "id": "IS_UNARMED", - "global": false, - "condition": { - "or": [ - { "and": [ { "not": "u_can_drop_weapon" }, { "not": { "u_has_wielded_with_weapon_category": "BIONIC_WEAPONS" } } ] }, - { "u_using_martial_art": "style_kicks" } - ] - }, - "effect": [ - { - "if": { "math": [ "u_proficiency('prof_unarmed_familiar', 'format': 'percent')", ">=", "100" ] }, - "then": [ - { - "if": { "math": [ "u_proficiency('prof_unarmed_pro', 'format': 'percent')", ">=", "100" ] }, - "then": [ - { - "if": { "math": [ "u_proficiency('prof_unarmed_master', 'format': 'percent')", ">=", "100" ] }, - "then": [ { "math": [ "u_prof_level", "=", "3" ] }, { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } ], - "else": [ - { "math": [ "u_proficiency('prof_unarmed_master', 'format': 'percent')", "+=", "rand(4) / 64" ] }, - { "math": [ "u_prof_level", "=", "2" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ], - "else": [ - { "math": [ "u_proficiency('prof_unarmed_pro', 'format': 'percent')", "+=", "rand(4) / 32" ] }, - { "math": [ "u_prof_level", "=", "1" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ], - "else": [ - { "math": [ "u_proficiency('prof_unarmed_familiar', 'format': 'percent')", "+=", "rand(4) / 16" ] }, - { "math": [ "u_prof_level", "=", "0" ] }, - { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } - ] - } - ] - }, - { - "type": "effect_on_condition", - "id": "EOC_MELEE_PROF_BENEFIT", - "//": "Refunds stamina based on the presumed model of stamina cost: [ (((Item Weight / 16) + 50 ) * -1) + Melee Skill ]. This excludes the stance modifier, due to not being able to detect if the character is crouching at time of writing. ", - "global": false, - "condition": { "not": { "or": [ { "math": [ "u_prof_lowest", "==", "4" ] }, { "math": [ "u_prof_lowest", "==", "0" ] } ] } }, - "effect": [ - { - "u_run_inv_eocs": "all", - "search_data": [ { "wielded_only": true } ], - "true_eocs": [ - { - "id": "EOC_GET_WIELD_WEIGHT", - "effect": [ { "math": [ "u_stamina_delta", "=", "max( 50, round(stamcost(n_val('weight'), u_skill('melee'))))" ] } ] - } - ] - }, - { "math": [ "u_stamina_delta", "=", "round(stamrefund( u_stamina_delta, u_prof_lowest))" ] }, - { "math": [ "u_val('stamina')", "+=", "u_stamina_delta" ] } - ] - }, - { - "type": "jmath_function", - "id": "stamcost", - "num_args": 2, - "return": "_0 / 1000 / 16 + 50 - _1" - }, - { - "type": "jmath_function", - "id": "stamrefund", - "num_args": 2, - "return": " _0 * ( .0125 * ( 2 ^ _1))" - } -] diff --git a/data/json/effects_on_condition/nether_eocs/portal_storm_effect_on_condition.json b/data/json/effects_on_condition/nether_eocs/portal_storm_effect_on_condition.json index cea3517386a31..487e0f39584a0 100644 --- a/data/json/effects_on_condition/nether_eocs/portal_storm_effect_on_condition.json +++ b/data/json/effects_on_condition/nether_eocs/portal_storm_effect_on_condition.json @@ -28,6 +28,12 @@ "global": true, "effect": { "run_eocs": "EOC_CAUSE_EARLY_PORTAL_STORM" } }, + { + "type": "effect_on_condition", + "id": "EOC_PORTAL_STORM_CONDITION_FLAG_PORTAL_PROOF", + "condition": { "not": { "u_has_worn_with_flag": "PORTAL_PROOF" } }, + "effect": [ ] + }, { "type": "effect_on_condition", "id": "EOC_PORTAL_EARLY_MESSAGES", @@ -368,7 +374,7 @@ }, { "math": [ "portal_dungeon_level", "==", "0" ] }, "u_is_outside", - { "not": { "u_has_worn_with_flag": "PORTAL_PROOF" } } + { "test_eoc": "EOC_PORTAL_STORM_CONDITION_FLAG_PORTAL_PROOF" } ] }, "deactivate_condition": { @@ -388,7 +394,7 @@ { "is_weather": "portal_storm" }, { "math": [ "portal_dungeon_level", "==", "0" ] }, "u_is_outside", - { "not": { "u_has_worn_with_flag": "PORTAL_PROOF" } }, + { "test_eoc": "EOC_PORTAL_STORM_CONDITION_FLAG_PORTAL_PROOF" }, { "math": [ "talked_to_storm", "!=", "1" ] }, { "x_in_y_chance": { "x": 7, "y": 10 } } ] @@ -400,7 +406,7 @@ "type": "effect_on_condition", "id": "EOC_PORTAL_MESSAGE", "//": "This displays messages depending on the storms strength.", - "condition": { "and": [ "u_can_see", { "not": { "u_has_worn_with_flag": "PORTAL_PROOF" } } ] }, + "condition": { "and": [ "u_can_see", { "test_eoc": "EOC_PORTAL_STORM_CONDITION_FLAG_PORTAL_PROOF" } ] }, "effect": { "switch": { "math": [ "distance('u', portal_storm_center)" ] }, "cases": [ @@ -460,7 +466,9 @@ { "type": "effect_on_condition", "id": "EOC_PORTAL_ARTIFACT_WEAK", - "condition": { "and": [ "u_is_outside", { "not": { "u_has_worn_with_flag": "PORTAL_PROOF" } }, { "math": [ "ps_str", "<", "2" ] } ] }, + "condition": { + "and": [ "u_is_outside", { "test_eoc": "EOC_PORTAL_STORM_CONDITION_FLAG_PORTAL_PROOF" }, { "math": [ "ps_str", "<", "2" ] } ] + }, "effect": [ { "u_spawn_monster": "mon_archunk_weak", @@ -480,7 +488,9 @@ { "type": "effect_on_condition", "id": "EOC_PORTAL_ARTIFACT_MEDIUM", - "condition": { "and": [ "u_is_outside", { "not": { "u_has_worn_with_flag": "PORTAL_PROOF" } }, { "math": [ "ps_str", "<", "5" ] } ] }, + "condition": { + "and": [ "u_is_outside", { "test_eoc": "EOC_PORTAL_STORM_CONDITION_FLAG_PORTAL_PROOF" }, { "math": [ "ps_str", "<", "5" ] } ] + }, "effect": [ { "u_spawn_monster": "mon_archunk_medium", @@ -500,7 +510,7 @@ { "type": "effect_on_condition", "id": "EOC_PORTAL_ARTIFACT_STRONG", - "condition": { "and": [ "u_is_outside", { "not": { "u_has_worn_with_flag": "PORTAL_PROOF" } } ] }, + "condition": { "and": [ "u_is_outside", { "test_eoc": "EOC_PORTAL_STORM_CONDITION_FLAG_PORTAL_PROOF" } ] }, "effect": [ { "u_spawn_monster": "mon_archunk_strong", @@ -564,7 +574,7 @@ { "type": "effect_on_condition", "id": "EOC_PORTAL_HALLUCINATOR", - "condition": { "or": [ { "not": { "u_has_effect": "sleep" } }, { "not": { "u_has_worn_with_flag": "PORTAL_PROOF" } } ] }, + "condition": { "or": [ { "not": { "u_has_effect": "sleep" } }, { "test_eoc": "EOC_PORTAL_STORM_CONDITION_FLAG_PORTAL_PROOF" } ] }, "//": "The hallucination itself is not related to portal, its kinda create nightmares, nothing more. but the monster's existing can be prevented due portaL_proof flag (let's say the entity can't see the flag's user)", "effect": [ { @@ -623,7 +633,7 @@ { "type": "effect_on_condition", "id": "EOC_PORTAL_PAIN", - "condition": { "and": [ "u_is_outside", { "not": { "u_has_worn_with_flag": "PORTAL_PROOF" } } ] }, + "condition": { "and": [ "u_is_outside", { "test_eoc": "EOC_PORTAL_STORM_CONDITION_FLAG_PORTAL_PROOF" } ] }, "effect": [ { "u_message": "You awake with a start from what must have been a violent and horrifying daydream. Your body aches as if the wounds were real.", @@ -654,7 +664,7 @@ { "type": "effect_on_condition", "id": "EOC_PORTAL_TELEPORT_STUCK_START", - "condition": { "and": [ { "not": { "u_has_worn_with_flag": "PORTAL_PROOF" } }, { "not": "u_driving" } ] }, + "condition": { "and": [ { "test_eoc": "EOC_PORTAL_STORM_CONDITION_FLAG_PORTAL_PROOF" }, { "not": "u_driving" } ] }, "effect": [ { "u_location_variable": { "u_val": "stuck_teleport" }, "min_radius": 0, "max_radius": 0 }, { "run_eocs": "EOC_PORTAL_TELEPORT_STUCK" }, @@ -675,7 +685,7 @@ "condition": { "and": [ { "not": "u_driving" }, - { "not": { "u_has_worn_with_flag": "PORTAL_PROOF" } }, + { "test_eoc": "EOC_PORTAL_STORM_CONDITION_FLAG_PORTAL_PROOF" }, { "math": [ "portal_dungeon_level", "==", "0" ] } ] }, @@ -716,7 +726,7 @@ { "type": "effect_on_condition", "id": "EOC_PORTAL_INCORPOREAL", - "condition": { "and": [ { "not": { "u_has_worn_with_flag": "PORTAL_PROOF" } }, { "not": "u_driving" } ] }, + "condition": { "and": [ { "test_eoc": "EOC_PORTAL_STORM_CONDITION_FLAG_PORTAL_PROOF" }, { "not": "u_driving" } ] }, "effect": [ { "u_message": "You feel stretched, as if part of you was elsewhere. You are not solid enough to affect matter, and your equipment falls through you.", @@ -791,7 +801,7 @@ "global": true, "condition": { "and": [ - { "not": { "u_has_worn_with_flag": "PORTAL_PROOF" } }, + { "test_eoc": "EOC_PORTAL_STORM_CONDITION_FLAG_PORTAL_PROOF" }, { "not": "u_is_outside" }, { "not": { "u_has_effect": "sleep" } }, { "x_in_y_chance": { "x": 1, "y": 250 } } @@ -810,7 +820,7 @@ "global": true, "condition": { "and": [ - { "not": { "u_has_worn_with_flag": "PORTAL_PROOF" } }, + { "test_eoc": "EOC_PORTAL_STORM_CONDITION_FLAG_PORTAL_PROOF" }, { "not": { "u_has_effect": "sleep" } }, { "x_in_y_chance": { "x": 1, "y": 30 } } ] @@ -823,7 +833,7 @@ "global": true, "condition": { "and": [ - { "not": { "u_has_worn_with_flag": "PORTAL_PROOF" } }, + { "test_eoc": "EOC_PORTAL_STORM_CONDITION_FLAG_PORTAL_PROOF" }, { "not": { "u_has_effect": "sleep" } }, { "x_in_y_chance": { "x": 1, "y": 30 } } ] @@ -836,7 +846,7 @@ "global": true, "condition": { "and": [ - { "not": { "u_has_worn_with_flag": "PORTAL_PROOF" } }, + { "test_eoc": "EOC_PORTAL_STORM_CONDITION_FLAG_PORTAL_PROOF" }, { "not": { "u_has_effect": "sleep" } }, { "x_in_y_chance": { "x": 1, "y": 30 } } ] @@ -849,7 +859,7 @@ "condition": { "and": [ { "math": [ "u_in_portal_cell", "==", "0" ] }, - { "not": { "u_has_worn_with_flag": "PORTAL_PROOF" } }, + { "test_eoc": "EOC_PORTAL_STORM_CONDITION_FLAG_PORTAL_PROOF" }, { "not": "u_driving" } ] }, @@ -1155,7 +1165,7 @@ { "type": "effect_on_condition", "id": "EOC_PORTAL_TELEPORT_UNSTABLE_RIFT", - "condition": { "and": [ { "not": { "u_has_worn_with_flag": "PORTAL_PROOF" } }, { "not": "u_driving" } ] }, + "condition": { "and": [ { "test_eoc": "EOC_PORTAL_STORM_CONDITION_FLAG_PORTAL_PROOF" }, { "not": "u_driving" } ] }, "effect": [ { "u_location_variable": { "u_val": "unstable_teleport" }, "min_radius": 30, "max_radius": 70 }, { "u_teleport": { "u_val": "unstable_teleport" } }, @@ -1211,7 +1221,7 @@ "and": [ { "is_weather": "portal_storm" }, { "u_has_trait": "MAKAYLA_MUTATOR" }, - { "not": { "u_has_worn_with_flag": "PORTAL_PROOF" } }, + { "test_eoc": "EOC_PORTAL_STORM_CONDITION_FLAG_PORTAL_PROOF" }, "u_is_outside" ] }, diff --git a/data/json/furniture_and_terrain/LIXA_furniture_and_terrain.json b/data/json/furniture_and_terrain/LIXA_furniture_and_terrain.json index 890fa40f341ca..9df1dd3316c97 100644 --- a/data/json/furniture_and_terrain/LIXA_furniture_and_terrain.json +++ b/data/json/furniture_and_terrain/LIXA_furniture_and_terrain.json @@ -104,7 +104,7 @@ "bash": { "str_min": 7, "str_max": 17, - "sound": "geometry crackling!", + "sound": "a hollow pop, followed by a sickly wet squelching as congealed light slowly leaks out of the tube.", "sound_fail": "nothing.", "ter_set": "t_LIXA_unfolded_tube_broken" }, diff --git a/data/json/hobbies.json b/data/json/hobbies.json index 767364b677998..c1a1e7709991c 100644 --- a/data/json/hobbies.json +++ b/data/json/hobbies.json @@ -836,7 +836,8 @@ "description": "You have been a vegetarian for so long that eating meat makes you feel sick. You like to supplement your diet with wild plants and mushrooms foraged in the woods.", "points": -1, "traits": [ "VEGETARIAN" ], - "skills": [ { "level": 2, "name": "cooking" }, { "level": 2, "name": "survival" } ] + "skills": [ { "level": 2, "name": "cooking" }, { "level": 2, "name": "survival" } ], + "proficiencies": [ "prof_food_prep", "prof_forage_cooking" ] }, { "type": "profession", diff --git a/data/json/itemgroups/Drugs_Tobacco_Alcohol/drugs.json b/data/json/itemgroups/Drugs_Tobacco_Alcohol/drugs.json index 5919a39976cdb..547f9f6136315 100644 --- a/data/json/itemgroups/Drugs_Tobacco_Alcohol/drugs.json +++ b/data/json/itemgroups/Drugs_Tobacco_Alcohol/drugs.json @@ -150,14 +150,14 @@ "type": "item_group", "subtype": "collection", "container-item": "box_small", - "items": [ { "item": "tampon", "prob": 100, "count": 24 } ] + "items": [ { "item": "tampon", "prob": 100, "container-item": "null", "count": 24 } ] }, { "id": "tampon_box_used", "type": "item_group", "subtype": "collection", "container-item": "box_small", - "items": [ { "item": "tampon", "prob": 100, "count": [ 1, 24 ] } ] + "items": [ { "item": "tampon", "prob": 100, "container-item": "null", "count": [ 1, 24 ] } ] }, { "id": "menstrual_pad_box_full", diff --git a/data/json/itemgroups/Food/food.json b/data/json/itemgroups/Food/food.json index 15dff392ac2ed..fb42101e97f15 100644 --- a/data/json/itemgroups/Food/food.json +++ b/data/json/itemgroups/Food/food.json @@ -116,7 +116,7 @@ "subtype": "distribution", "entries": [ { "prob": 50, "group": "yeast_bag_plastic_25" }, - { "prob": 40, "group": "sugar_box_small_71" }, + { "prob": 40, "group": "sugar_packed" }, { "prob": 10, "group": "artificial_sweetener_box_small_71" }, { "prob": 5, "group": "sprinkles_bottle_plastic_small_62" }, { "prob": 40, "group": "salt_bag_plastic_100" }, @@ -258,7 +258,7 @@ { "prob": 30, "group": "toastem2_box_small_8" }, { "prob": 35, "group": "toastem3_box_small_8" }, { "prob": 20, "group": "toasterpastryfrozen_box_snack_2" }, - { "prob": 20, "group": "sugar_box_small_71" }, + { "prob": 20, "group": "sugar_packed" }, { "prob": 5, "group": "artificial_sweetener_box_small_71" }, { "prob": 5, "group": "lemonade_powder_bottle_plastic_small_10" }, { "item": "molasses", "prob": 10 }, diff --git a/data/json/itemgroups/Locations_MapExtras/locations.json b/data/json/itemgroups/Locations_MapExtras/locations.json index 63b3ba7508b6e..a0f1f276b853d 100644 --- a/data/json/itemgroups/Locations_MapExtras/locations.json +++ b/data/json/itemgroups/Locations_MapExtras/locations.json @@ -2804,7 +2804,7 @@ [ "brew_moonshine", 5 ], { "prob": 35, "group": "cornbread_bag_plastic_6" }, { "prob": 25, "group": "yeast_bag_plastic_25" }, - { "prob": 20, "group": "sugar_box_small_71" }, + { "prob": 20, "group": "sugar_packed" }, [ "chem_ethanol", 5 ] ] }, diff --git a/data/json/itemgroups/Locations_MapExtras/locations_commercial.json b/data/json/itemgroups/Locations_MapExtras/locations_commercial.json index c8540810abee4..5e3c824f95575 100644 --- a/data/json/itemgroups/Locations_MapExtras/locations_commercial.json +++ b/data/json/itemgroups/Locations_MapExtras/locations_commercial.json @@ -783,8 +783,8 @@ "items": [ { "group": "salty_snacks", "prob": 121 }, [ "sandwich_t", 22 ], - [ "tea_raw", 50 ], - [ "tea_green_raw", 25 ], + { "group": "tea_raw_bag_plastic_33", "prob": 50 }, + { "group": "tea_green_raw_bag_plastic_33", "prob": 25 }, [ "cookies", 25 ], [ "brownie", 25 ], [ "coffee_raw", 90 ], diff --git a/data/json/itemgroups/SUS/alien.json b/data/json/itemgroups/SUS/alien.json index 828d0acbce64a..3ada88d79b470 100644 --- a/data/json/itemgroups/SUS/alien.json +++ b/data/json/itemgroups/SUS/alien.json @@ -121,7 +121,7 @@ { "collection": [ { "item": "salt", "prob": 100 }, - { "item": "sugar", "prob": 25 }, + { "group": "sugar_jar_glass_sealed_10_140", "prob": 25 }, { "item": "chem_saltpetre", "prob": 10 }, { "item": "yeast", "prob": 30 } ], diff --git a/data/json/itemgroups/SUS/domestic.json b/data/json/itemgroups/SUS/domestic.json index efa0d1642916d..d621249d3b9df 100644 --- a/data/json/itemgroups/SUS/domestic.json +++ b/data/json/itemgroups/SUS/domestic.json @@ -545,7 +545,7 @@ { "count": [ 1, 10 ], "prob": 40, "group": "tea_green_raw_bag_plastic_33" }, { "item": "teapot", "prob": 70 }, { "item": "kettle", "prob": 50 }, - { "prob": 90, "sealed": false, "group": "sugar_jar_glass_sealed_10_120" }, + { "prob": 90, "sealed": false, "group": "sugar_jar_glass_sealed_10_140" }, { "distribution": [ { @@ -732,7 +732,7 @@ { "group": "pepper_bag_plastic_100" }, { "prob": 75, "group": "cinnamon_bag_plastic_100" }, { "prob": 75, "group": "chilly-p_bag_plastic_100" }, - { "prob": 15, "group": "sugar_box_small_71" }, + { "prob": 15, "group": "sugar_packed" }, { "prob": 5, "group": "artificial_sweetener_box_small_71" }, { "prob": 25, "group": "curry_powder_bag_plastic_100" }, { "prob": 25, "group": "garlic_powder_bag_plastic_100" }, @@ -1126,15 +1126,6 @@ "container-item": "bottle_plastic_pill_prescription", "entries": [ { "item": "weak_antibiotic", "container-item": "null" } ] }, - { - "type": "item_group", - "id": "sugar_jar_glass_sealed_10_120", - "subtype": "collection", - "//": "This group was created automatically and may contain errors.", - "container-item": "jar_glass_sealed", - "on_overflow": "spill", - "entries": [ { "item": "sugar", "container-item": "null", "count": [ 10, 120 ] } ] - }, { "type": "item_group", "id": "garlic_powder_bag_plastic_100", diff --git a/data/json/itemgroups/food_service.json b/data/json/itemgroups/food_service.json index 0052b127dbc46..ab4b8ffb87c69 100644 --- a/data/json/itemgroups/food_service.json +++ b/data/json/itemgroups/food_service.json @@ -134,7 +134,7 @@ { "prob": 10, "group": "raw_dandelion_jar_glass_sealed_1_inf" }, { "prob": 30, "group": "milk_powder_jar_glass_sealed_1_8" }, { "prob": 20, "group": "cinnamon_jar_glass_sealed_1_inf" }, - { "prob": 40, "group": "sugar_jar_glass_sealed_10_142" } + { "prob": 40, "group": "sugar_jar_glass_sealed_10_140" } ] }, { @@ -145,7 +145,13 @@ { "id": "teashop_kitchen_counter", "type": "item_group", - "items": [ [ "sugar", 30 ], [ "tea_raw", 40 ], [ "tea_green_raw", 20 ], [ "teapot", 20 ], [ "spoon", 20 ] ] + "items": [ + { "group": "sugar_jar_glass_sealed_10_140", "prob": 30 }, + { "group": "tea_raw_bag_plastic_33", "prob": 40 }, + { "group": "tea_green_raw_bag_plastic_33", "prob": 20 }, + [ "teapot", 20 ], + [ "spoon", 20 ] + ] }, { "id": "bar_alcohol", @@ -292,7 +298,7 @@ { "prob": 13, "group": "seasoning_salt_bag_plastic_100" }, { "prob": 5, "group": "pepper_bag_plastic_100" }, { "prob": 10, "group": "yeast_bag_plastic_25" }, - { "prob": 9, "group": "sugar_box_small_71" }, + { "prob": 9, "group": "sugar_packed" }, [ "cornmeal", 8 ], { "prob": 5, "group": "flour_bag_paper_powder_1_70" }, { "prob": 20, "group": "flour_bag_plastic_1_175" }, @@ -430,7 +436,7 @@ { "item": "milk", "prob": 10 }, { "prob": 65, "group": "milk_powder_bag_plastic_4" }, { "prob": 15, "group": "salt_bag_plastic_100" }, - { "prob": 70, "group": "sugar_box_small_71" }, + { "prob": 70, "group": "sugar_packed" }, { "prob": 15, "group": "artificial_sweetener_box_small_71" }, { "prob": 15, "group": "tea_raw_bag_plastic_33" }, { "prob": 10, "group": "tea_green_raw_bag_plastic_33" }, @@ -591,7 +597,7 @@ { "prob": 50, "group": "seasoning_salt_bag_plastic_100" }, { "prob": 50, "group": "seasoning_italian_bag_plastic_100" }, { "prob": 30, "group": "can_chicken_can_medium_2" }, - { "prob": 40, "group": "sugar_box_small_71" }, + { "prob": 40, "group": "sugar_packed" }, { "prob": 10, "group": "artificial_sweetener_box_small_71" }, { "item": "soysauce", "prob": 10 }, { "item": "hot_sauce", "prob": 10 }, @@ -756,7 +762,7 @@ { "prob": 50, "group": "salt_bag_plastic_100" }, { "item": "soysauce", "prob": 25 }, { "item": "hot_sauce", "prob": 25 }, - { "prob": 60, "group": "sugar_box_small_71" }, + { "prob": 60, "group": "sugar_packed" }, { "prob": 15, "group": "artificial_sweetener_box_small_71" }, { "prob": 65, "group": "dry_rice_bag_plastic_3" }, { "prob": 5, "group": "dry_wild_rice_bag_plastic_3" }, @@ -1063,7 +1069,7 @@ [ "ghee", 15 ], { "prob": 15, "group": "pepper_bag_plastic_100" }, { "prob": 20, "group": "salt_bag_plastic_100" }, - { "prob": 5, "group": "sugar_box_small_71" }, + { "prob": 5, "group": "sugar_packed" }, { "prob": 4, "group": "flour_bag_paper_powder_1_70" }, { "prob": 13, "group": "flour_bag_plastic_1_175" }, [ "soysauce", 25 ], @@ -1103,7 +1109,7 @@ [ "ghee", 15 ], { "prob": 15, "group": "pepper_bag_plastic_100" }, { "prob": 20, "group": "salt_bag_plastic_100" }, - { "prob": 5, "group": "sugar_box_small_71" }, + { "prob": 5, "group": "sugar_packed" }, { "prob": 4, "group": "flour_bag_paper_powder_1_70" }, { "prob": 13, "group": "flour_bag_plastic_1_175" }, [ "soysauce", 25 ], @@ -1586,17 +1592,17 @@ "type": "item_group", "id": "tea_raw_bag_plastic_33", "subtype": "collection", - "//": "This group was created automatically and may contain errors.", + "//": "100 g of tea", "container-item": "bag_plastic", - "entries": [ { "item": "tea_raw", "container-item": "null", "count": 33 } ] + "entries": [ { "item": "tea_raw", "container-item": "null", "count-min": 2, "count-max": 33 } ] }, { "type": "item_group", "id": "tea_green_raw_bag_plastic_33", "subtype": "collection", - "//": "This group was created automatically and may contain errors.", + "//": "100 g of tea", "container-item": "bag_plastic", - "entries": [ { "item": "tea_green_raw", "container-item": "null", "count": 33 } ] + "entries": [ { "item": "tea_green_raw", "container-item": "null", "count-min": 2, "count": 33 } ] }, { "type": "item_group", @@ -1672,12 +1678,19 @@ }, { "type": "item_group", - "id": "sugar_jar_glass_sealed_10_142", + "id": "sugar_jar_glass_sealed_10_140", "subtype": "collection", "//": "This group was created automatically and may contain errors.", "container-item": "jar_glass_sealed", "on_overflow": "spill", - "entries": [ { "item": "sugar", "container-item": "null", "count-min": 10, "count-max": 142 } ] + "entries": [ { "item": "sugar", "container-item": "null", "count-min": 10, "count-max": 140 } ] + }, + { + "type": "item_group", + "id": "sugar_packed", + "subtype": "collection", + "container-item": "bag_paper_powder", + "entries": [ { "item": "sugar", "count-min": 10, "count-max": 90 } ] }, { "type": "item_group", @@ -1799,10 +1812,10 @@ }, { "type": "item_group", - "id": "sugar_box_small_71", + "id": "sugar_packed", "subtype": "collection", - "//": "This group was created automatically and may contain errors.", - "container-item": "box_small", + "//": "one pound of sugar in a paper bag.", + "container-item": "bag_paper_powder", "entries": [ { "item": "sugar", "container-item": "null", "count": 71 } ] }, { diff --git a/data/json/itemgroups/supplies.json b/data/json/itemgroups/supplies.json index 22717260b5308..ff1af58f32b75 100644 --- a/data/json/itemgroups/supplies.json +++ b/data/json/itemgroups/supplies.json @@ -499,7 +499,7 @@ { "item": "hydrogen_tank", "prob": 8, "charges": [ 12, 24 ] }, { "item": "polycarbonate_sheet", "prob": 7, "count": [ 1, 30 ] }, { "prob": 10, "group": "salt_bag_plastic_100" }, - { "prob": 10, "group": "sugar_box_small_71" }, + { "prob": 10, "group": "sugar_packed" }, { "item": "chem_ethanol", "prob": 10, "charges-min": 250 }, [ "oxygen_cylinder", 8 ], { "prob": 16, "group": "chem_citric_acid_bottle_glass_100_inf" }, diff --git a/data/json/itemgroups/tools.json b/data/json/itemgroups/tools.json index 8839012cb73b1..75bb6bf2d79ad 100644 --- a/data/json/itemgroups/tools.json +++ b/data/json/itemgroups/tools.json @@ -93,7 +93,7 @@ "items": [ { "item": "brick_kiln", "prob": 80, "charges": [ 0, 1000 ] }, { "item": "kiln", "prob": 40 }, - { "item": "con_mix", "prob": 120, "charges": [ 0, 500 ] }, + { "item": "con_mix_foldable", "prob": 120 }, { "item": "elec_jackhammer", "prob": 40, "charges": [ 0, 6600 ] }, { "item": "reciprocating_saw", "prob": 80, "charges": [ 0, 500 ] }, { "item": "cordless_impact_wrench", "prob": 20, "charges": [ 0, 500 ] }, diff --git a/data/json/items/basecamp.json b/data/json/items/basecamp.json index d1fe1f06c19e6..1412d4901b3e5 100644 --- a/data/json/items/basecamp.json +++ b/data/json/items/basecamp.json @@ -3,11 +3,10 @@ "id": "fake_char_kiln", "//": "The stationary object needs a larger capacity than the portable base object", "type": "TOOL", - "copy-from": "fake_item", + "copy-from": "fake_crafting_tool", "name": { "str": "basecamp kiln" }, "description": "A fake kiln used for basecamps.", "sub": "char_kiln", - "extend": { "flags": [ "ALLOWS_REMOTE_USE" ] }, "ammo": [ "charcoal" ], "//1": "250 liters of materials can produce 100 liters of charcoal.", "pocket_data": [ { "pocket_type": "MAGAZINE", "rigid": true, "ammo_restriction": { "charcoal": 20000 } } ] @@ -16,11 +15,10 @@ "id": "fake_char_smoker", "//": "The stationary object needs a larger capacity than the portable base object", "type": "TOOL", - "copy-from": "fake_item", + "copy-from": "fake_crafting_tool", "name": { "str": "basecamp charcoal smoker" }, "description": "A fake charcoal smoker used for basecamps.", "sub": "char_smoker", - "extend": { "flags": [ "ALLOWS_REMOTE_USE" ] }, "ammo": [ "charcoal" ], "//1": "holds 450 liters of charcoal. a full smoking rack cycle of 20L of stuff would consume 15,000 charcoal (75 liters, 15.6kg of charcoal)", "pocket_data": [ { "pocket_type": "MAGAZINE", "rigid": true, "ammo_restriction": { "charcoal": 90000 } } ] @@ -32,29 +30,27 @@ "name": { "str": "basecamp forge" }, "copy-from": "char_forge", "description": "A fake charcoal forge used for basecamps.", - "extend": { "flags": [ "ALLOWS_REMOTE_USE", "ZERO_WEIGHT" ] }, + "extend": { "flags": [ "ALLOWS_REMOTE_USE", "ZERO_WEIGHT", "PSEUDO" ] }, "pocket_data": [ { "pocket_type": "MAGAZINE", "rigid": true, "ammo_restriction": { "charcoal": 2000, "coal": 10000 } } ] }, { "id": "fake_clay_kiln", "//": "The stationary object needs a larger capacity than the portable base object", "type": "TOOL", - "copy-from": "fake_item", + "copy-from": "fake_crafting_tool", "name": { "str": "basecamp clay kiln" }, "description": "A fake clay kiln used for basecamps.", "sub": "brick_kiln", - "extend": { "flags": [ "ALLOWS_REMOTE_USE" ] }, "ammo": [ "charcoal", "coal" ], "pocket_data": [ { "pocket_type": "MAGAZINE", "ammo_restriction": { "charcoal": 2000, "coal": 10000 } } ] }, { "id": "fake_fireplace", "type": "TOOL", - "copy-from": "fake_item", + "copy-from": "fake_crafting_tool", "name": { "str": "basecamp fireplace" }, "description": "A fake fireplace used for basecamps.", "sub": "hotplate", - "extend": { "flags": [ "ALLOWS_REMOTE_USE" ] }, "ammo": [ "tinder" ], "pocket_data": [ { "pocket_type": "MAGAZINE", "rigid": true, "ammo_restriction": { "tinder": 50000 } } ], "charge_factor": 25 @@ -62,11 +58,10 @@ { "id": "fake_woodstove", "type": "TOOL", - "copy-from": "fake_item", + "copy-from": "fake_crafting_tool", "name": { "str": "basecamp stove" }, "description": "A fake stove used for basecamps.", "sub": "hotplate", - "extend": { "flags": [ "ALLOWS_REMOTE_USE" ] }, "ammo": [ "tinder" ], "pocket_data": [ { "pocket_type": "MAGAZINE", "rigid": true, "ammo_restriction": { "tinder": 50000 } } ], "charge_factor": 10 diff --git a/data/json/items/comestibles/junkfood.json b/data/json/items/comestibles/junkfood.json index 52bd388a31b5f..96d7267138555 100644 --- a/data/json/items/comestibles/junkfood.json +++ b/data/json/items/comestibles/junkfood.json @@ -56,13 +56,13 @@ "comestible_type": "FOOD", "symbol": "%", "calories": 200, - "description": "A delicious fruit-filled pastry that you can cook in your toaster. It even comes with frosting! Cook it to make it tasty.", + "description": "A delicious fruit-filled pastry that you can cook in your toaster. It even comes with frosting! Cook it to make it tastier.", "price": "2 USD", "price_postapoc": "62 cent", "material": [ "wheat", "junk" ], "volume": "125 ml", "flags": [ "EATEN_HOT" ], - "fun": -10, + "fun": 5, "vitamins": [ [ "iron", 10 ] ] }, { diff --git a/data/json/items/comestibles/spice.json b/data/json/items/comestibles/spice.json index e64ead9262500..7239171ca09ce 100644 --- a/data/json/items/comestibles/spice.json +++ b/data/json/items/comestibles/spice.json @@ -92,7 +92,6 @@ "name": { "str_sp": "sugar" }, "weight": "5 g", "color": "white", - "container": "box_small", "comestible_type": "FOOD", "symbol": "%", "description": "Sweet, sweet sugar. Bad for your teeth and surprisingly not very tasty on its own.", diff --git a/data/json/items/containers/containers.json b/data/json/items/containers/containers.json index 16e160642491a..dec805eae1879 100644 --- a/data/json/items/containers/containers.json +++ b/data/json/items/containers/containers.json @@ -43,15 +43,16 @@ "id": "30gal_barrel", "type": "GENERIC", "category": "container", - "name": { "str": "30 gallon barrel" }, + "name": { "str": "30 gallon plastic barrel" }, "looks_like": "55gal_drum", "description": "A huge plastic barrel with a watertight lid.", "ascii_picture": "30gal_barrel", "weight": "6800 g", - "volume": "118125 ml", - "price": 5000, + "volume": "165640 ml", + "longest_side": "72 cm", + "price": "71 USD", "price_postapoc": 250, - "to_hit": -5, + "to_hit": { "grip": "bad", "length": "long", "surface": "any", "balance": "clumsy" }, "material": [ "plastic" ], "symbol": "0", "color": "light_blue", @@ -60,13 +61,14 @@ "pocket_type": "CONTAINER", "watertight": true, "rigid": true, - "max_contains_volume": "112500 ml", + "max_contains_volume": "113560 ml", "max_contains_weight": "255 kg" } ], "qualities": [ [ "CONTAIN", 1 ] ], "flags": [ "COLLAPSE_CONTENTS" ], - "melee_damage": { "bash": 8 } + "melee_damage": { "bash": 8 }, + "//": "Based on https://www.amazon.com/dp/B0025QI4XC" }, { "id": "30gal_drum", diff --git a/data/json/items/fake.json b/data/json/items/fake.json index 385a191b48b68..b770cc0d96476 100644 --- a/data/json/items/fake.json +++ b/data/json/items/fake.json @@ -406,5 +406,12 @@ "pocket_data": [ { "pocket_type": "MAGAZINE_WELL", "default_magazine": "pseudo_battery" } ], "charges_per_use": 100, "charged_qualities": [ [ "PRESSURIZATION", 10 ] ] + }, + { + "id": "concrete_mix_tool", + "type": "TOOL", + "name": { "str": "concrete mixer" }, + "copy-from": "fake_appliance_tool", + "charges_per_use": 20 } ] diff --git a/data/json/items/tool/electronics.json b/data/json/items/tool/electronics.json index e22c32090d047..f20be4ce01fa6 100644 --- a/data/json/items/tool/electronics.json +++ b/data/json/items/tool/electronics.json @@ -734,7 +734,7 @@ "id": "UPS_off", "type": "TOOL", "name": { "str": "UPS", "str_pl": "UPSes" }, - "description": "A unified power supply, or UPS. It is a device developed jointly by military and scientific interests for use in combat and the field. The UPS is designed to power bionics, armor, and some guns, but drains batteries quickly.", + "description": "A unified power supply, or UPS. It is a device developed jointly by military and scientific interests for use in combat and the field. The UPS is designed to power tools, smartphones, armor, and some guns, but drains batteries quickly.", "weight": "680 g", "volume": "2500 ml", "price": 280000, @@ -758,7 +758,7 @@ "id": "UPS_ON", "type": "TOOL", "name": { "str": "UPS (on)", "str_pl": "UPSes (on)" }, - "description": "A unified power supply, or UPS. It is a device developed jointly by military and scientific interests for use in combat and the field. The UPS is designed to power bionics, armor, and some guns, but drains batteries quickly.", + "description": "A unified power supply, or UPS. It is a device developed jointly by military and scientific interests for use in combat and the field. The UPS is designed to power tools, smartphones, armor, and some guns, but drains batteries quickly.", "//": "Intended as an inverter that attaches to a battery, therefore it's volume will expand based on the size of battery attached.", "weight": "680 g", "volume": "2500 ml", @@ -791,7 +791,7 @@ "id": "UPS_OFF", "type": "TOOL", "name": { "str": "UPS (off)", "str_pl": "UPSes (off)" }, - "description": "A unified power supply, or UPS. It is a device developed jointly by military and scientific interests for use in combat and the field. The UPS is designed to power bionics, armor, and some guns, but drains batteries quickly. Use it to turn it on.", + "description": "A unified power supply, or UPS. It is a device developed jointly by military and scientific interests for use in combat and the field. The UPS is designed to power tools, smartphones, armor, and some guns, but drains batteries quickly. Use it to turn it on.", "//": "Intended as an inverter that attaches to a battery, therefore it's volume will expand based on the size of battery attached.", "weight": "680 g", "volume": "2500 ml", diff --git a/data/json/items/tool/workshop.json b/data/json/items/tool/workshop.json index 3568aa045d84c..8d299467bdb29 100644 --- a/data/json/items/tool/workshop.json +++ b/data/json/items/tool/workshop.json @@ -245,32 +245,39 @@ "//2": "Based on https://www.amazon.com/dp/B000A24RCA" }, { - "id": "con_mix", + "id": "con_mix_foldable", "type": "TOOL", "name": { "str": "concrete mixer" }, - "description": "A portable concrete mixer. It is still large and heavy, but it can be operated solo, and runs on batteries. It also has a heater built in.", - "weight": "9071 g", - "volume": "5 L", - "price": 50000, + "description": "A portable concrete mixer. It is large and heavy, but it can be operated solo. Unfold to use.", + "looks_like": "con_mix", + "weight": "40823 g", + "volume": "250 L", + "longest_side": "118 cm", + "//1": "Calculated by assuming a cylinder with dimensions taken from the drum opening (14.5in) and product length (46.5in) and then doubling it. Calculating volume from the product dimensions inflated it artifically as it counted all the free space inbetween the handles, wheels, etc resulting in 600+l of volume (a portable concrete mixer that can't be transported in a vehicle lmao).", + "price": "400 USD", "price_postapoc": 500, - "to_hit": -6, - "material": [ "steel" ], - "symbol": "$", - "color": "dark_gray", - "ammo": [ "battery" ], - "charges_per_use": 20, - "qualities": [ [ "CONTAIN", 1 ] ], - "flags": [ "ALLOWS_REMOTE_USE" ], - "use_action": [ "HOTPLATE", { "type": "link_up", "cable_length": 15, "charge_rate": "1500 W" } ], + "to_hit": { "grip": "bad", "length": "long", "surface": "line", "balance": "clumsy" }, + "material": [ "plastic", "steel" ], "pocket_data": [ { - "pocket_type": "MAGAZINE_WELL", - "rigid": true, - "flag_restriction": [ "BATTERY_MEDIUM" ], - "default_magazine": "medium_battery_cell" + "max_contains_volume": "100 L", + "max_contains_weight": "300 kg", + "watertight": true, + "open_container": true, + "rigid": true } ], - "melee_damage": { "bash": 15 } + "symbol": "$", + "color": "dark_gray", + "qualities": [ [ "CONTAIN", 1 ] ], + "flags": [ "NO_SALVAGE" ], + "use_action": [ "UNFOLD_GENERIC" ], + "variables": { + "vehicle_name": "Concrete mixer", + "folded_parts": "[{\"id\": \"frame_concrete_mix\",\"base\":{\"typeid\":\"frame_concrete_mix\",\"item_tags\":[\"VEHICLE\"]},\"mount_dx\":0,\"mount_dy\":0},{\"id\":\"wheel_mount_concrete_mix\",\"base\":{\"typeid\":\"wheel_mount_concrete_mix\",\"item_tags\":[\"VEHICLE\"]},\"mount_dx\": 0,\"mount_dy\": 0},{\"id\":\"wheel_set_concrete_mix\",\"base\":{\"typeid\":\"wheel_set_concrete_mix\",\"item_tags\":[\"VEHICLE\"]},\"mount_dx\": 0,\"mount_dy\":0},{\"id\":\"drum_concrete_mix\",\"base\":{\"typeid\":\"30gal_barrel\",\"item_tags\":[\"VEHICLE\"]},\"mount_dx\":0,\"mount_dy\":0},{\"id\":\"engine_electric_small\",\"base\":{\"typeid\":\"motor_small\",\"item_tags\":[\"VEHICLE\"]},\"mount_dx\":0,\"mount_dy\":0},{\"id\":\"small_storage_battery\",\"base\":{\"typeid\":\"small_storage_battery\",\"item_tags\":[\"VEHICLE\"]},\"mount_dx\":0,\"mount_dy\":0}]" + }, + "melee_damage": { "bash": 15 }, + "//2": "Based on https://www.amazon.com/dp/B01EGB6TJ4 - save for the numbers that the Amazon arcticle got straight up wrong (weight and drum opening) which were taken from the owner's manual - https://assets.northerntool.com/products/494/documents/manuals/49413.pdf" }, { "id": "cordless_drill", diff --git a/data/json/items/vehicle/frames.json b/data/json/items/vehicle/frames.json index ac304a2a55f39..3c5c677c0b4a3 100644 --- a/data/json/items/vehicle/frames.json +++ b/data/json/items/vehicle/frames.json @@ -118,5 +118,16 @@ "price": 1000, "price_postapoc": 50, "copy-from": "foldframe" + }, + { + "type": "GENERIC", + "id": "frame_concrete_mix", + "name": { "str_sp": "concrete mixer chassis" }, + "description": "The chassis of a concrete mixer.", + "weight": "9700 g", + "volume": "10 L", + "color": "light_gray", + "symbol": "]", + "category": "veh_parts" } ] diff --git a/data/json/items/vehicle/wheel.json b/data/json/items/vehicle/wheel.json index f2f3b9149b0be..9824ff3b4b147 100644 --- a/data/json/items/vehicle/wheel.json +++ b/data/json/items/vehicle/wheel.json @@ -778,5 +778,24 @@ "name": { "str": "banded wooden cart wheel" }, "description": "A handmade wooden cart wheel with metal bands for durability.", "relative": { "weight": "500 g" } + }, + { + "id": "wheel_mount_concrete_mix", + "type": "GENERIC", + "name": { "str_sp": "concrete mixer wheel mounts" }, + "description": "A set of two small wheel mounts from a concrete mixer.", + "copy-from": "wheel_mount_light", + "weight": "300 g", + "volume": "500 ml" + }, + { + "id": "wheel_set_concrete_mix", + "type": "WHEEL", + "name": { "str_sp": "concrete mixer wheels" }, + "description": "A set of two small wheels from a concrete mixer.", + "copy-from": "wheel_small", + "weight": "5444 g", + "volume": "5500 ml", + "width": 6 } ] diff --git a/data/json/mapgen/basecamps/base/bare_bones_basecamp/bare_bones_basecamp.json b/data/json/mapgen/basecamps/base/bare_bones_basecamp/bare_bones_basecamp.json index d0813d18555aa..60d5654a90a31 100644 --- a/data/json/mapgen/basecamps/base/bare_bones_basecamp/bare_bones_basecamp.json +++ b/data/json/mapgen/basecamps/base/bare_bones_basecamp/bare_bones_basecamp.json @@ -9,35 +9,6 @@ "type": "mapgen", "update_mapgen_id": "fbbb", "method": "json", - "object": { - "rows": [ - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " " - ], - "flags": [ "ALLOW_TERRAIN_UNDER_OTHER_DATA" ], - "palettes": [ "fbbb_palette" ] - } + "object": { "flags": [ "ALLOW_TERRAIN_UNDER_OTHER_DATA" ], "palettes": [ "fbbb_palette" ] } } ] diff --git a/data/json/mapgen/basecamps/expansion/modular_canteen/version_1/modular_canteen_common.json b/data/json/mapgen/basecamps/expansion/modular_canteen/version_1/modular_canteen_common.json index 392b78d5c1780..4339afa05ea8c 100644 --- a/data/json/mapgen/basecamps/expansion/modular_canteen/version_1/modular_canteen_common.json +++ b/data/json/mapgen/basecamps/expansion/modular_canteen/version_1/modular_canteen_common.json @@ -3,18 +3,7 @@ "type": "mapgen", "method": "json", "nested_mapgen_id": "fbmk_0", - "object": { - "mapgensize": [ 6, 6 ], - "rows": [ - " ", - " ", - " ", - " ", - " ", - " " - ], - "palettes": [ "fbmk_common_palette" ] - } + "object": { "mapgensize": [ 6, 6 ], "palettes": [ "fbmk_common_palette" ] } }, { "type": "mapgen", diff --git a/data/json/mapgen/basecamps/expansion/modular_farm/version_1/primitive_farm.json b/data/json/mapgen/basecamps/expansion/modular_farm/version_1/primitive_farm.json index 9ebdbe28e9c06..986466babcd96 100644 --- a/data/json/mapgen/basecamps/expansion/modular_farm/version_1/primitive_farm.json +++ b/data/json/mapgen/basecamps/expansion/modular_farm/version_1/primitive_farm.json @@ -3,18 +3,7 @@ "type": "mapgen", "method": "json", "nested_mapgen_id": "fbmf_0", - "object": { - "mapgensize": [ 6, 6 ], - "rows": [ - " ", - " ", - " ", - " ", - " ", - " " - ], - "palettes": [ "acidia_camp_palette" ] - } + "object": { "mapgensize": [ 6, 6 ], "palettes": [ "acidia_camp_palette" ] } }, { "type": "mapgen", diff --git a/data/json/mapgen/basecamps/expansion/modular_garage/version_1/primitive_garage.json b/data/json/mapgen/basecamps/expansion/modular_garage/version_1/primitive_garage.json index 6ff4e8c8712f5..f0b91b33e94c6 100644 --- a/data/json/mapgen/basecamps/expansion/modular_garage/version_1/primitive_garage.json +++ b/data/json/mapgen/basecamps/expansion/modular_garage/version_1/primitive_garage.json @@ -3,18 +3,7 @@ "type": "mapgen", "method": "json", "nested_mapgen_id": "fbmg_0", - "object": { - "mapgensize": [ 6, 6 ], - "rows": [ - " ", - " ", - " ", - " ", - " ", - " " - ], - "palettes": [ "acidia_camp_palette" ] - } + "object": { "mapgensize": [ 6, 6 ], "palettes": [ "acidia_camp_palette" ] } }, { "type": "mapgen", diff --git a/data/json/mapgen/basecamps/expansion/modular_livestock/version_1/modular_livestock_common.json b/data/json/mapgen/basecamps/expansion/modular_livestock/version_1/modular_livestock_common.json index 88b503b37dfe8..7440276afe109 100644 --- a/data/json/mapgen/basecamps/expansion/modular_livestock/version_1/modular_livestock_common.json +++ b/data/json/mapgen/basecamps/expansion/modular_livestock/version_1/modular_livestock_common.json @@ -3,18 +3,7 @@ "type": "mapgen", "method": "json", "nested_mapgen_id": "fbml_0", - "object": { - "mapgensize": [ 6, 6 ], - "rows": [ - " ", - " ", - " ", - " ", - " ", - " " - ], - "palettes": [ "fbml_common_palette" ] - } + "object": { "mapgensize": [ 6, 6 ], "palettes": [ "fbml_common_palette" ] } }, { "type": "mapgen", diff --git a/data/json/mapgen/basecamps/expansion/modular_saltworks/version_1/modular_saltworks_common.json b/data/json/mapgen/basecamps/expansion/modular_saltworks/version_1/modular_saltworks_common.json index a53c6cf3c9774..f4d42c740ae76 100644 --- a/data/json/mapgen/basecamps/expansion/modular_saltworks/version_1/modular_saltworks_common.json +++ b/data/json/mapgen/basecamps/expansion/modular_saltworks/version_1/modular_saltworks_common.json @@ -10,18 +10,7 @@ "type": "mapgen", "method": "json", "nested_mapgen_id": "fbmsw_0", - "object": { - "mapgensize": [ 6, 6 ], - "rows": [ - " ", - " ", - " ", - " ", - " ", - " " - ], - "palettes": [ "fbmsw_common_palette" ] - } + "object": { "mapgensize": [ 6, 6 ], "palettes": [ "fbmsw_common_palette" ] } }, { "type": "mapgen", diff --git a/data/json/mapgen/basecamps/expansion/modular_storehouse/version_1/modular_storehouse_common.json b/data/json/mapgen/basecamps/expansion/modular_storehouse/version_1/modular_storehouse_common.json index 3b7fe2594be5c..93a394a52794e 100644 --- a/data/json/mapgen/basecamps/expansion/modular_storehouse/version_1/modular_storehouse_common.json +++ b/data/json/mapgen/basecamps/expansion/modular_storehouse/version_1/modular_storehouse_common.json @@ -3,19 +3,7 @@ "type": "mapgen", "method": "json", "nested_mapgen_id": "fbms_0", - "object": { - "mapgensize": [ 6, 6 ], - "rows": [ - " ", - " ", - " ", - " ", - " ", - " " - ], - "flags": [ "ALLOW_TERRAIN_UNDER_OTHER_DATA" ], - "palettes": [ "fbms_common_palette" ] - } + "object": { "mapgensize": [ 6, 6 ], "flags": [ "ALLOW_TERRAIN_UNDER_OTHER_DATA" ], "palettes": [ "fbms_common_palette" ] } }, { "type": "mapgen", diff --git a/data/json/mapgen/basecamps/expansion/modular_workshop/version_1/modular_workshop_common.json b/data/json/mapgen/basecamps/expansion/modular_workshop/version_1/modular_workshop_common.json index 94c7efb0305b8..6e2f81600a474 100644 --- a/data/json/mapgen/basecamps/expansion/modular_workshop/version_1/modular_workshop_common.json +++ b/data/json/mapgen/basecamps/expansion/modular_workshop/version_1/modular_workshop_common.json @@ -3,18 +3,7 @@ "type": "mapgen", "method": "json", "nested_mapgen_id": "fbmw_0", - "object": { - "mapgensize": [ 6, 6 ], - "rows": [ - " ", - " ", - " ", - " ", - " ", - " " - ], - "palettes": [ "fbmw_common_palette" ] - } + "object": { "mapgensize": [ 6, 6 ], "palettes": [ "fbmw_common_palette" ] } }, { "type": "mapgen", diff --git a/data/json/mapgen/construction_site.json b/data/json/mapgen/construction_site.json index 582a05f596693..efb0c3a19bb84 100644 --- a/data/json/mapgen/construction_site.json +++ b/data/json/mapgen/construction_site.json @@ -33,7 +33,7 @@ " " ], "palettes": [ "construction_site_palette" ], - "place_loot": [ { "item": "con_mix", "x": [ 0, 8 ], "y": [ 5, 7 ] } ], + "place_loot": [ { "item": "con_mix_foldable", "x": [ 0, 8 ], "y": [ 5, 7 ] } ], "place_vehicles": [ { "vehicle": "small_utility_vehicles", "x": 12, "y": 4, "chance": 70, "rotation": 180 } ] } }, @@ -71,7 +71,7 @@ " " ], "palettes": [ "construction_site_palette" ], - "place_loot": [ { "item": "con_mix", "x": [ 5, 9 ], "y": [ 4, 7 ] } ], + "place_loot": [ { "item": "con_mix_foldable", "x": [ 5, 9 ], "y": [ 4, 7 ] } ], "place_vehicles": [ { "vehicle": "small_utility_vehicles", "x": 12, "y": 4, "chance": 70, "rotation": 0 } ] } }, @@ -109,7 +109,7 @@ " c ss " ], "palettes": [ "construction_site_palette" ], - "place_loot": [ { "item": "con_mix", "x": [ 0, 4 ], "y": [ 17, 19 ] } ], + "place_loot": [ { "item": "con_mix_foldable", "x": [ 0, 4 ], "y": [ 17, 19 ] } ], "place_vehicles": [ { "vehicle": "small_utility_vehicles", "x": 22, "y": 4, "chance": 66, "rotation": 270 }, { "vehicle": "small_utility_vehicles", "x": 12, "y": 21, "chance": 66, "rotation": 180 } @@ -150,7 +150,7 @@ " -- -- -- -- -- " ], "palettes": [ "construction_site_palette" ], - "place_loot": [ { "item": "con_mix", "x": [ 0, 17 ], "y": 1 } ], + "place_loot": [ { "item": "con_mix_foldable", "x": [ 0, 17 ], "y": 1 } ], "place_vehicles": [ { "vehicle": "small_utility_vehicles", "x": 20, "y": [ 6, 11 ], "chance": 70, "rotation": 270 } ] } }, @@ -188,7 +188,7 @@ " c c " ], "palettes": [ "construction_site_palette" ], - "place_loot": [ { "item": "con_mix", "x": [ 5, 11 ], "y": [ 20, 23 ] } ], + "place_loot": [ { "item": "con_mix_foldable", "x": [ 5, 11 ], "y": [ 20, 23 ] } ], "place_vehicles": [ { "vehicle": "small_utility_vehicles", "x": 15, "y": 21, "chance": 70, "rotation": 180 } ] } } diff --git a/data/json/mapgen/debug.json b/data/json/mapgen/debug.json index ee79ab754e166..c1317c8609029 100644 --- a/data/json/mapgen/debug.json +++ b/data/json/mapgen/debug.json @@ -2,37 +2,8 @@ { "type": "mapgen", "method": "json", - "om_terrain": [ "debug_itemgroup_test" ], - "object": { - "fill_ter": "t_pavement", - "rows": [ - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " " - ], - "items": { " ": [ { "item": "milspec_arsenal_group_only_ammo", "chance": 100 } ] } - } + "om_terrain": "debug_itemgroup_test", + "object": { "fill_ter": "t_pavement", "items": { " ": [ { "item": "milspec_arsenal_group_only_ammo", "chance": 100 } ] } } }, { "type": "overmap_terrain", diff --git a/data/json/mapgen/derelict_property.json b/data/json/mapgen/derelict_property.json index 3584e80e49453..deb3c755b4715 100644 --- a/data/json/mapgen/derelict_property.json +++ b/data/json/mapgen/derelict_property.json @@ -155,34 +155,7 @@ "type": "mapgen", "method": "json", "om_terrain": "derelict_property", - "//": "rows only defined bc otherwise palettes, needed for nest selection, throws an error", "object": { - "rows": [ - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " " - ], "fallback_predecessor_mapgen": "forest", "palettes": [ "derelict_variant_parameter_palette" ], "place_nested": [ { "chunks": [ { "param": "variant", "fallback": "derelict_property_1" } ], "x": 0, "y": 0 } ] @@ -192,35 +165,8 @@ "type": "mapgen", "method": "json", "om_terrain": "derelict_property_roof", - "//": "rows only defined bc otherwise palettes, needed for nest selection, throws an error", "object": { "fill_ter": "t_open_air", - "rows": [ - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " " - ], "palettes": [ "derelict_variant_parameter_palette" ], "place_nested": [ { diff --git a/data/json/mapgen/dummy/dummy.json b/data/json/mapgen/dummy/dummy.json index c8aa2e6406ba7..cb7347eeb3e08 100644 --- a/data/json/mapgen/dummy/dummy.json +++ b/data/json/mapgen/dummy/dummy.json @@ -2,43 +2,9 @@ { "type": "mapgen", "method": "json", - "//": "This mapgen exist only for suppressing 'No mapgen terrain exists for %s' type of errors on game start and shouldn't spawn ingame", - "om_terrain": [ "unexplored" ], - "object": { - "rows": [ - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " " - ], - "terrain": { " ": "t_null" } - } - }, - { - "type": "mapgen", - "om_terrain": [ "omt_obsolete" ], - "method": "json", - "//": "this mapgen is used for replacing obsoleted overmap terrain, normally it shouldn't spawn", + "//unexplored": "This mapgen exist only for suppressing 'No mapgen terrain exists for %s' type of errors on game start and shouldn't spawn ingame", + "//omt_obsolete": "This mapgen is used for replacing obsoleted overmap terrain, normally it shouldn't spawn", + "om_terrain": [ "unexplored", "omt_obsolete" ], "object": { "fill_ter": "t_nether_glass_floor" } } ] diff --git a/data/json/mapgen/house/house05.json b/data/json/mapgen/house/house05.json index bc9a03c05fa98..16ccf0d3fad27 100644 --- a/data/json/mapgen/house/house05.json +++ b/data/json/mapgen/house/house05.json @@ -135,32 +135,6 @@ "om_terrain": "house_05_basement", "object": { "fill_ter": "t_thconc_floor", - "rows": [ - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " " - ], "palettes": [ "house_05_variant_palette" ], "place_nested": [ { diff --git a/data/json/mapgen/house/house_vacant.json b/data/json/mapgen/house/house_vacant.json index 438488376341e..b5e824a27b455 100644 --- a/data/json/mapgen/house/house_vacant.json +++ b/data/json/mapgen/house/house_vacant.json @@ -34,7 +34,7 @@ " -- -- -- -- -- " ], "palettes": [ "construction_site_palette" ], - "place_loot": [ { "item": "con_mix", "x": [ 12, 22 ], "y": [ 19, 22 ] } ], + "place_loot": [ { "item": "con_mix_foldable", "x": [ 12, 22 ], "y": [ 19, 22 ] } ], "place_vehicles": [ { "vehicle": "small_utility_vehicles", "x": 11, "y": 2, "chance": 70, "rotation": 0 } ] } }, @@ -73,7 +73,7 @@ " @@ sss 11 22 22 " ], "palettes": [ "construction_site_palette" ], - "place_loot": [ { "item": "con_mix", "x": [ 1, 9 ], "y": [ 16, 19 ] } ], + "place_loot": [ { "item": "con_mix_foldable", "x": [ 1, 9 ], "y": [ 16, 19 ] } ], "place_vehicles": [ { "vehicle": "small_utility_vehicles", "x": 20, "y": 2, "chance": 70, "rotation": 0 } ] } }, @@ -112,7 +112,7 @@ " ss -- -- " ], "palettes": [ "construction_site_palette" ], - "place_loot": [ { "item": "con_mix", "x": [ 2, 8 ], "y": [ 19, 21 ] } ], + "place_loot": [ { "item": "con_mix_foldable", "x": [ 2, 8 ], "y": [ 19, 21 ] } ], "place_vehicles": [ { "vehicle": "small_utility_vehicles", "x": 5, "y": 2, "chance": 70, "rotation": 0 } ] } }, @@ -151,7 +151,7 @@ " " ], "palettes": [ "construction_site_palette" ], - "place_loot": [ { "item": "con_mix", "x": [ 7, 13 ], "y": [ 1, 5 ] } ], + "place_loot": [ { "item": "con_mix_foldable", "x": [ 7, 13 ], "y": [ 1, 5 ] } ], "place_vehicles": [ { "vehicle": "small_utility_vehicles", "x": 4, "y": 4, "chance": 70, "rotation": 90 } ] } } diff --git a/data/json/mapgen/lab/lab_modular/lab_nests_modular/lab_nested_maintenance.json b/data/json/mapgen/lab/lab_modular/lab_nests_modular/lab_nested_maintenance.json index 5ae228cb37a61..c09e1b91635bb 100644 --- a/data/json/mapgen/lab/lab_modular/lab_nests_modular/lab_nested_maintenance.json +++ b/data/json/mapgen/lab/lab_modular/lab_nests_modular/lab_nested_maintenance.json @@ -67,11 +67,6 @@ "nested_mapgen_id": "lab_maintenance_3x3_NS_open", "object": { "mapgensize": [ 3, 3 ], - "rows": [ - " ", - " ", - " " - ], "palettes": [ "lab_common_palette", "lab_maintenance_palette" ], "place_loot": [ { "group": "trash", "x": [ 1, 3 ], "y": [ 1, 3 ], "repeat": 3, "chance": 100 } ], "place_nested": [ { "chunks": [ [ "sub_fd_shock_vent", 30 ], [ "null", 70 ] ], "x": 1, "y": 1 } ] diff --git a/data/json/mapgen/map_extras/beehives.json b/data/json/mapgen/map_extras/beehives.json index 1ad8177776804..674366abf615a 100644 --- a/data/json/mapgen/map_extras/beehives.json +++ b/data/json/mapgen/map_extras/beehives.json @@ -13,34 +13,6 @@ "type": "mapgen", "method": "json", "update_mapgen_id": "mx_beehive_natural", - "object": { - "rows": [ - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " " - ], - "place_nested": [ { "chunks": [ [ "nested_beehive_natural", 100 ] ], "x": [ 0, 23 ], "y": [ 0, 23 ] } ] - } + "object": { "place_nested": [ { "chunks": [ [ "nested_beehive_natural", 100 ] ], "x": [ 0, 23 ], "y": [ 0, 23 ] } ] } } ] diff --git a/data/json/mapgen/map_extras/bugouts.json b/data/json/mapgen/map_extras/bugouts.json index b63dd17c7eaf1..1f8b87429c7d7 100644 --- a/data/json/mapgen/map_extras/bugouts.json +++ b/data/json/mapgen/map_extras/bugouts.json @@ -20,34 +20,6 @@ "type": "mapgen", "method": "json", "update_mapgen_id": "mx_bugout", - "object": { - "rows": [ - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " " - ], - "place_nested": [ { "chunks": [ [ "nested_bugout_bag", 100 ] ], "x": [ 0, 23 ], "y": [ 0, 23 ] } ] - } + "object": { "place_nested": [ { "chunks": [ [ "nested_bugout_bag", 100 ] ], "x": [ 0, 23 ], "y": [ 0, 23 ] } ] } } ] diff --git a/data/json/mapgen/map_extras/clearcut.json b/data/json/mapgen/map_extras/clearcut.json index 0e0ef92c0606a..7a92e6a731999 100644 --- a/data/json/mapgen/map_extras/clearcut.json +++ b/data/json/mapgen/map_extras/clearcut.json @@ -3,35 +3,7 @@ "type": "mapgen", "method": "json", "update_mapgen_id": "mx_clearcut", - "object": { - "rows": [ - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " " - ], - "ter_furn_transforms": { " ": { "transform": "clearcut" } } - } + "object": { "ter_furn_transforms": { " ": { "transform": "clearcut" } } } }, { "type": "ter_furn_transform", diff --git a/data/json/mapgen/map_extras/grave.json b/data/json/mapgen/map_extras/grave.json index b0f23a4f299ee..070762bfd2338 100644 --- a/data/json/mapgen/map_extras/grave.json +++ b/data/json/mapgen/map_extras/grave.json @@ -138,32 +138,6 @@ "method": "json", "update_mapgen_id": "mx_grave", "object": { - "rows": [ - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " " - ], "place_nested": [ { "chunks": [ [ "human_corpse", 95 ], [ "pet_corpse", 95 ], [ "grave_easter_egg", 5 ] ], diff --git a/data/json/mapgen/map_extras/house_wasp.json b/data/json/mapgen/map_extras/house_wasp.json index f518849169c32..a06368b2d9945 100644 --- a/data/json/mapgen/map_extras/house_wasp.json +++ b/data/json/mapgen/map_extras/house_wasp.json @@ -4,32 +4,6 @@ "method": "json", "update_mapgen_id": "mx_house_wasp", "object": { - "rows": [ - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " " - ], "ter_furn_transforms": { " ": { "transform": "remove_door" } }, "nested": { " ": [ diff --git a/data/json/mapgen/map_extras/mass_grave.json b/data/json/mapgen/map_extras/mass_grave.json index 27d15b42dd1b2..3256cad75cc08 100644 --- a/data/json/mapgen/map_extras/mass_grave.json +++ b/data/json/mapgen/map_extras/mass_grave.json @@ -10,32 +10,6 @@ "//": "This is the 'base' mass grave, and doesn't actually contain anything. Variants are generated via the place_nested field.", "update_mapgen_id": "mx_mass_grave", "object": { - "rows": [ - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " " - ], "place_nested": [ { "chunks": [ [ "mass_grave_abandoned", 30 ], [ "mass_grave_partial", 20 ], [ "mass_grave_finished", 10 ] ], diff --git a/data/json/mapgen/map_extras/portal.json b/data/json/mapgen/map_extras/portal.json index 45616126c6540..393f0d65f677d 100644 --- a/data/json/mapgen/map_extras/portal.json +++ b/data/json/mapgen/map_extras/portal.json @@ -5,11 +5,6 @@ "nested_mapgen_id": "portal_location", "object": { "mapgensize": [ 3, 3 ], - "rows": [ - " ", - " ", - " " - ], "flags": [ "ERASE_ALL_BEFORE_PLACING_TERRAIN" ], "terrain": { " ": "t_region_groundcover" }, "furniture": { " ": "f_rubble_rock" }, @@ -21,32 +16,6 @@ "method": "json", "update_mapgen_id": "mx_portal", "object": { - "rows": [ - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " " - ], "place_nested": [ { "chunks": [ "portal_location" ], "x": [ 2, 20 ], "y": [ 2, 20 ] } ], "monsters": { " ": { "monster": "GROUP_NETHER_PORTAL", "chance": 1, "density": 0.0001 } } } diff --git a/data/json/mapgen/map_extras/sand.json b/data/json/mapgen/map_extras/sand.json index a265d903dae59..0cc5a30182519 100644 --- a/data/json/mapgen/map_extras/sand.json +++ b/data/json/mapgen/map_extras/sand.json @@ -3,16 +3,7 @@ "type": "mapgen", "method": "json", "nested_mapgen_id": "sand_patch", - "object": { - "mapgensize": [ 3, 3 ], - "rows": [ - " ", - " ", - " " - ], - "terrain": { " ": [ "t_sand", "t_null" ] }, - "flags": [ "ALLOW_TERRAIN_UNDER_OTHER_DATA" ] - } + "object": { "mapgensize": [ 3, 3 ], "terrain": { " ": [ "t_sand", "t_null" ] }, "flags": [ "ALLOW_TERRAIN_UNDER_OTHER_DATA" ] } }, { "type": "mapgen", diff --git a/data/json/mapgen/military/mil_base/mil_base_z0.json b/data/json/mapgen/military/mil_base/mil_base_z0.json index 1c9afcde9f8a2..8ca69229e44ed 100644 --- a/data/json/mapgen/military/mil_base/mil_base_z0.json +++ b/data/json/mapgen/military/mil_base/mil_base_z0.json @@ -539,7 +539,7 @@ { "group": "cornmeal_box_small_10", "x": [ 41, 42 ], "y": 53, "chance": 75, "repeat": [ 50, 150 ] }, { "group": "coffee_raw_bag_plastic_20", "x": 40, "y": 53, "chance": 75, "repeat": [ 50, 150 ] }, { "group": "tea_raw_bag_plastic_33", "x": 39, "y": 53, "chance": 75, "repeat": [ 50, 150 ] }, - { "group": "sugar_box_small_71", "x": 38, "y": 53, "chance": 75, "repeat": [ 50, 150 ] }, + { "group": "sugar_packed", "x": 38, "y": 53, "chance": 75, "repeat": [ 50, 150 ] }, { "group": "salt_bag_plastic_100", "x": 37, "y": 53, "chance": 75, "repeat": [ 50, 150 ] }, { "item": "cooking_oil", "x": 36, "y": 53, "chance": 75, "repeat": [ 50, 150 ] }, { "item": "meat_salted", "x": [ 45, 46 ], "y": 48, "chance": 75, "repeat": [ 50, 150 ] }, diff --git a/data/json/mapgen/nether_monster_corpse/monster_head.json b/data/json/mapgen/nether_monster_corpse/monster_head.json index af0814b823c0f..ee3d9d73165cb 100644 --- a/data/json/mapgen/nether_monster_corpse/monster_head.json +++ b/data/json/mapgen/nether_monster_corpse/monster_head.json @@ -213,32 +213,6 @@ "om_terrain": "corpse_head", "object": { "fill_ter": "t_nm_floor_flesh", - "rows": [ - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " " - ], "palettes": [ "nether_monster_palette" ], "terrain": { " ": [ [ "t_nm_floor_flesh", 25 ], [ "t_nm_ichor_sh", 3 ] ] }, "furniture": { diff --git a/data/json/mapgen/robofaq_locs/robofac_hq_chunks.json b/data/json/mapgen/robofaq_locs/robofac_hq_chunks.json index dca7ec75deb3a..ab719f987eb7e 100644 --- a/data/json/mapgen/robofaq_locs/robofac_hq_chunks.json +++ b/data/json/mapgen/robofaq_locs/robofac_hq_chunks.json @@ -73,10 +73,6 @@ "object": { "faction_owner": [ { "id": "robofac_auxiliaries", "x": [ 0, 4 ], "y": [ 0, 4 ] } ], "mapgensize": [ 2, 2 ], - "rows": [ - " ", - " " - ], "place_npcs": [ { "class": "robofac_merc_1", "x": 1, "y": 1 } ] } }, diff --git a/data/json/mapgen/rock_border.json b/data/json/mapgen/rock_border.json index 3377ea4d15324..4252c8225be9d 100644 --- a/data/json/mapgen/rock_border.json +++ b/data/json/mapgen/rock_border.json @@ -2,35 +2,7 @@ { "type": "mapgen", "method": "json", - "om_terrain": [ "rock_border" ], - "object": { - "rows": [ - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " " - ], - "terrain": { " ": "t_rock" } - } + "om_terrain": "rock_border", + "object": { "fill_ter": "t_rock" } } ] diff --git a/data/json/mutations/mutations.json b/data/json/mutations/mutations.json index 96bccdd8dca94..57a20cd66c9f9 100644 --- a/data/json/mutations/mutations.json +++ b/data/json/mutations/mutations.json @@ -1190,11 +1190,10 @@ "id": "ROBUST", "name": { "str": "Robust Genetics" }, "points": 3, - "description": "Your genetics have rapidly adapted to the chaos of the Cataclysm, and the genetic damage caused by mutations will fade much quicker.", + "description": "Your genome has rapidly adapted to the Cataclysm and can handle the strain of mutation better. Taking different kinds of mutagen won't result in more defective mutations than normal.", "starting_trait": true, "cancels": [ "CHAOTIC_BAD" ], - "category": [ "FISH", "SLIME", "ALPHA", "MEDICAL", "PLANT" ], - "vitamin_rates": [ [ "instability", 7200 ] ] + "category": [ "FISH", "SLIME", "ALPHA", "MEDICAL", "PLANT" ] }, { "type": "mutation", diff --git a/data/json/npcs/NC_JUNK_SHOPKEEP.json b/data/json/npcs/NC_JUNK_SHOPKEEP.json index 1b9b9487d38e0..0a045b0ed7f92 100644 --- a/data/json/npcs/NC_JUNK_SHOPKEEP.json +++ b/data/json/npcs/NC_JUNK_SHOPKEEP.json @@ -242,7 +242,7 @@ { "item": "polisher", "prob": 20 }, { "item": "screwdriver", "prob": 40 }, { "item": "hammer", "prob": 35 }, - { "item": "con_mix", "prob": 10 }, + { "item": "con_mix_foldable", "prob": 10 }, { "item": "brick_kiln", "prob": 10 }, { "item": "kiln", "prob": 4 }, { "item": "g_shovel", "prob": 20 }, diff --git a/data/json/npcs/items_generic.json b/data/json/npcs/items_generic.json index fe35bb5f33490..933265881c620 100644 --- a/data/json/npcs/items_generic.json +++ b/data/json/npcs/items_generic.json @@ -1056,8 +1056,8 @@ [ "talking_doll", 3 ], [ "tall_tales", 1 ], [ "tazer", 5 ], - [ "tea_raw", 8 ], - [ "tea_green_raw", 4 ], + { "group": "tea_raw_bag_plastic_33", "prob": 8 }, + { "group": "tea_green_raw_bag_plastic_33", "prob": 4 }, [ "teapot", 8 ], [ "teleumbrella", 4 ], [ "tent_kit", 6 ], diff --git a/data/json/obsoletion_and_migration_0.I/migration_items.json b/data/json/obsoletion_and_migration_0.I/migration_items.json index 6c4b99f9b03c2..7a6f2bd7d7ab2 100644 --- a/data/json/obsoletion_and_migration_0.I/migration_items.json +++ b/data/json/obsoletion_and_migration_0.I/migration_items.json @@ -1238,5 +1238,11 @@ "id": "surv_hand_cannon", "type": "MIGRATION", "replace": "hptjhpmag" + }, + { + "id": "con_mix", + "type": "MIGRATION", + "replace": "con_mix_foldable", + "reset_item_vars": true } ] diff --git a/data/json/obsoletion_and_migration_0.I/migration_mutation.json b/data/json/obsoletion_and_migration_0.I/migration_mutation.json index 9b84bd7181881..5b34b460b6b8e 100644 --- a/data/json/obsoletion_and_migration_0.I/migration_mutation.json +++ b/data/json/obsoletion_and_migration_0.I/migration_mutation.json @@ -3,5 +3,29 @@ "type": "TRAIT_MIGRATION", "id": "BILE_STINK", "remove": true + }, + { + "id": "instability", + "type": "vitamin", + "vit_type": "counter", + "name": { "str": "Instability" }, + "excess": "genetics_damaged", + "min": 0, + "max": 8000, + "flags": [ "NO_DISPLAY" ], + "rate": "1 s", + "disease_excess": [ [ 1, 899 ], [ 900, 2799 ], [ 2800, 8000 ] ] + }, + { + "type": "effect_type", + "id": "genetics_damaged", + "name": [ "Spent Phenotype", "Depleted Phenotype", "Bankrupt Phenotype" ], + "desc": [ + "Mutation has left you with a persistent mild discomfort. It seems harmless for now, but you can't predict if it'll get worse.", + "There's an enervating sense of dysmorphia throughout your whole body. It waxes and wanes, but never quite goes away. Mutating this much can't be good for you…", + "You're haunted by phantom pains across your entire body now. Everything aches from an exhaustion that never seems to fade. Any further mutation right now is very unlikely to have a happy ending." + ], + "max_intensity": 3, + "rating": "bad" } ] diff --git a/data/json/proficiencies/melee_weapons.json b/data/json/proficiencies/melee_weapons.json index 15bb1a3b36933..b3fedac1e7790 100644 --- a/data/json/proficiencies/melee_weapons.json +++ b/data/json/proficiencies/melee_weapons.json @@ -8,7 +8,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "8 h" + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.025 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "800 s" }, { "type": "proficiency", @@ -19,7 +21,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "16 h", + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.025 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "1600 s", "required_proficiencies": [ "prof_auto_rifles_familiar" ] }, { @@ -31,7 +35,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "32 h", + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.05 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "3200 s", "required_proficiencies": [ "prof_auto_rifles_pro" ] }, { @@ -43,7 +49,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "8 h" + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.025 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "800 s" }, { "type": "proficiency", @@ -54,7 +62,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "16 h", + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.025 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "1600 s", "required_proficiencies": [ "prof_auto_pistols_familiar" ] }, { @@ -66,7 +76,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "32 h", + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.05 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "3200 s", "required_proficiencies": [ "prof_auto_pistols_pro" ] }, { @@ -78,7 +90,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "8 h" + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.025 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "800 s" }, { "type": "proficiency", @@ -89,7 +103,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "16 h", + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.025 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "1600 s", "required_proficiencies": [ "prof_knives_familiar" ] }, { @@ -101,7 +117,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "32 h", + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.05 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "3200 s", "required_proficiencies": [ "prof_knives_pro" ] }, { @@ -113,7 +131,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "8 h" + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.025 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "800 s" }, { "type": "proficiency", @@ -124,7 +144,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "16 h", + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.025 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "1600 s", "required_proficiencies": [ "prof_shivs_familiar" ] }, { @@ -136,7 +158,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "32 h", + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.05 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "3200 s", "required_proficiencies": [ "prof_shivs_pro" ] }, { @@ -148,7 +172,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "8 h" + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.025 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "800 s" }, { "type": "proficiency", @@ -159,7 +185,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "16 h", + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.025 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "1600 s", "required_proficiencies": [ "prof_batons_familiar" ] }, { @@ -171,7 +199,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "32 h", + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.05 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "3200 s", "required_proficiencies": [ "prof_batons_pro" ] }, { @@ -183,7 +213,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "8 h" + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.025 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "800 s" }, { "type": "proficiency", @@ -194,7 +226,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "16 h", + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.025 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "1600 s", "required_proficiencies": [ "prof_medium_swords_familiar" ] }, { @@ -206,7 +240,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "32 h", + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.05 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "3200 s", "required_proficiencies": [ "prof_medium_swords_pro" ] }, { @@ -218,7 +254,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "8 h" + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.025 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "800 s" }, { "type": "proficiency", @@ -229,7 +267,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "16 h", + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.025 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "1600 s", "required_proficiencies": [ "prof_short_swords_familiar" ] }, { @@ -241,7 +281,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "32 h", + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.05 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "3200 s", "required_proficiencies": [ "prof_short_swords_pro" ] }, { @@ -253,7 +295,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "8 h" + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.025 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "800 s" }, { "type": "proficiency", @@ -264,7 +308,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "16 h", + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.025 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "1600 s", "required_proficiencies": [ "prof_quarterstaves_familiar" ] }, { @@ -276,7 +322,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "32 h", + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.05 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "3200 s", "required_proficiencies": [ "prof_quarterstaves_pro" ] }, { @@ -288,7 +336,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "8 h" + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.025 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "800 s" }, { "type": "proficiency", @@ -299,7 +349,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "16 h", + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.025 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "1600 s", "required_proficiencies": [ "prof_fencing_weapons_familiar" ] }, { @@ -311,7 +363,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "32 h", + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.05 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "3200 s", "required_proficiencies": [ "prof_fencing_weapons_pro" ] }, { @@ -323,7 +377,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "8 h" + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.025 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "800 s" }, { "type": "proficiency", @@ -334,7 +390,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "16 h", + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.025 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "1600 s", "required_proficiencies": [ "prof_claws_familiar" ] }, { @@ -346,7 +404,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "32 h", + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.05 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "3200 s", "required_proficiencies": [ "prof_claws_pro" ] }, { @@ -358,7 +418,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "8 h" + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.025 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "800 s" }, { "type": "proficiency", @@ -369,7 +431,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "16 h", + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.025 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "1600 s", "required_proficiencies": [ "prof_hooking_familiar" ] }, { @@ -381,7 +445,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "32 h", + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.05 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "3200 s", "required_proficiencies": [ "prof_hooking_pro" ] }, { @@ -393,7 +459,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "8 h" + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.025 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "800 s" }, { "type": "proficiency", @@ -404,7 +472,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "16 h", + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.025 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "1600 s", "required_proficiencies": [ "prof_polearms_familiar" ] }, { @@ -416,7 +486,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "32 h", + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.05 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "3200 s", "required_proficiencies": [ "prof_polearms_pro" ] }, { @@ -428,7 +500,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "8 h" + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.025 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "800 s" }, { "type": "proficiency", @@ -439,7 +513,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "16 h", + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.025 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "1600 s", "required_proficiencies": [ "prof_bionics_familiar" ] }, { @@ -451,7 +527,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "32 h", + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.05 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "3200 s", "required_proficiencies": [ "prof_bionics_pro" ] }, { @@ -463,7 +541,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "8 h" + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.025 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "800 s" }, { "type": "proficiency", @@ -474,7 +554,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "16 h", + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.025 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "1600 s", "required_proficiencies": [ "prof_spears_familiar" ] }, { @@ -486,7 +568,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "32 h", + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.05 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "3200 s", "required_proficiencies": [ "prof_spears_pro" ] }, { @@ -498,7 +582,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "8 h" + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.025 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "800 s" }, { "type": "proficiency", @@ -509,7 +595,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "16 h", + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.025 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "1600 s", "required_proficiencies": [ "prof_thrusting_swords_familiar" ] }, { @@ -521,7 +609,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "32 h", + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.05 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "3200 s", "required_proficiencies": [ "prof_thrusting_swords_pro" ] }, { @@ -533,7 +623,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "8 h" + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.025 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "800 s" }, { "type": "proficiency", @@ -544,7 +636,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "16 h", + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.025 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "1600 s", "required_proficiencies": [ "prof_long_swords_familiar" ] }, { @@ -556,7 +650,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "32 h", + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.05 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "3200 s", "required_proficiencies": [ "prof_long_swords_pro" ] }, { @@ -568,7 +664,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "8 h" + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.025 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "800 s" }, { "type": "proficiency", @@ -579,7 +677,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "16 h", + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.025 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "1600 s", "required_proficiencies": [ "prof_bionic_swords_familiar" ] }, { @@ -591,7 +691,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "32 h", + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.05 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "3200 s", "required_proficiencies": [ "prof_bionic_swords_pro" ] }, { @@ -603,7 +705,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "8 h" + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.025 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "800 s" }, { "type": "proficiency", @@ -614,7 +718,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "16 h", + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.025 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "1600 s", "required_proficiencies": [ "prof_flails_familiar" ] }, { @@ -626,7 +732,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "32 h", + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.05 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "3200 s", "required_proficiencies": [ "prof_flails_pro" ] }, { @@ -638,7 +746,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "8 h" + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.025 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "800 s" }, { "type": "proficiency", @@ -649,7 +759,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "16 h", + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.025 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "1600 s", "required_proficiencies": [ "prof_maces_familiar" ] }, { @@ -661,7 +773,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "32 h", + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.05 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "3200 s", "required_proficiencies": [ "prof_maces_pro" ] }, { @@ -673,7 +787,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "8 h" + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.025 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "800 s" }, { "type": "proficiency", @@ -684,7 +800,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "16 h", + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.025 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "1600 s", "required_proficiencies": [ "prof_great_swords_familiar" ] }, { @@ -696,7 +814,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "32 h", + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.05 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "3200 s", "required_proficiencies": [ "prof_great_swords_pro" ] }, { @@ -708,7 +828,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "8 h" + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.025 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "800 s" }, { "type": "proficiency", @@ -719,7 +841,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "16 h", + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.025 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "1600 s", "required_proficiencies": [ "prof_great_hammers_familiar" ] }, { @@ -731,7 +855,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "32 h", + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.05 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "3200 s", "required_proficiencies": [ "prof_great_hammers_pro" ] }, { @@ -743,7 +869,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "8 h" + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.025 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "800 s" }, { "type": "proficiency", @@ -754,7 +882,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "16 h", + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.025 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "1600 s", "required_proficiencies": [ "prof_great_axes_familiar" ] }, { @@ -766,7 +896,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "32 h", + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.05 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "3200 s", "required_proficiencies": [ "prof_great_axes_pro" ] }, { @@ -778,7 +910,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "8 h" + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.025 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "800 s" }, { "type": "proficiency", @@ -789,7 +923,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "16 h", + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.025 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "1600 s", "required_proficiencies": [ "prof_hand_axes_familiar" ] }, { @@ -801,7 +937,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "32 h", + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.05 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "3200 s", "required_proficiencies": [ "prof_hand_axes_pro" ] }, { @@ -813,7 +951,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "8 h" + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.025 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "800 s" }, { "type": "proficiency", @@ -824,7 +964,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "16 h", + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.025 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "1600 s", "required_proficiencies": [ "prof_unarmed_familiar" ] }, { @@ -836,7 +978,9 @@ "can_learn": true, "default_time_multiplier": 1.5, "default_skill_penalty": 0.2, - "time_to_learn": "32 h", + "bonuses": { "melee_attack": [ { "type": "stamina", "value": 0.05 } ] }, + "//": "Code assumes each attack is 1s", + "time_to_learn": "3200 s", "required_proficiencies": [ "prof_unarmed_pro" ] } ] diff --git a/data/json/recipes/other/parts_construction.json b/data/json/recipes/other/parts_construction.json index 5aa7cf6e49584..10ee1e80ed8ef 100644 --- a/data/json/recipes/other/parts_construction.json +++ b/data/json/recipes/other/parts_construction.json @@ -666,7 +666,7 @@ "time": "10 m", "autolearn": false, "book_learn": [ [ "concrete_book", 2 ] ], - "tools": [ [ [ "con_mix", 50 ] ] ], + "tools": [ [ [ "concrete_mix_tool", 50 ] ] ], "components": [ [ [ "material_cement", 50 ] ], [ [ "material_sand", 150 ] ] ] }, { diff --git a/data/json/recipes/recipe_others.json b/data/json/recipes/recipe_others.json index 298fbc157fdd0..eb36776d1cb24 100644 --- a/data/json/recipes/recipe_others.json +++ b/data/json/recipes/recipe_others.json @@ -1536,7 +1536,7 @@ { "type": "recipe", "activity_level": "BRISK_EXERCISE", - "result": "con_mix", + "result": "con_mix_foldable", "category": "CC_OTHER", "subcategory": "CSC_OTHER_TOOLS", "skill_used": "fabrication", @@ -1545,28 +1545,27 @@ "time": "4 h 30 m", "reversible": true, "autolearn": true, - "//": "80 cm weld", + "//1": "338cm weld. 108cm from pipes making the base and handles, 20cm from welding four sheets for the blades on the inside of the drum, 200cm from welding six sheets around the motor.", "book_learn": [ [ "textbook_fabrication", 7 ], [ "manual_fabrication", 7 ] ], - "using": [ [ "soldering_standard", 25 ], [ "welding_standard", 80 ] ], - "proficiencies": [ - { "proficiency": "prof_metalworking" }, - { "proficiency": "prof_welding_basic", "skill_penalty": 0.5 }, - { "proficiency": "prof_welding" } - ], + "using": [ [ "soldering_standard", 25 ], [ "welding_standard", 338 ] ], + "proficiencies": [ { "proficiency": "prof_welding_basic", "skill_penalty": 0.5 }, { "proficiency": "prof_welding" } ], "qualities": [ { "id": "HAMMER", "level": 3 }, - { "id": "SAW_M", "level": 1 }, + { "id": "SAW_M", "level": 2 }, { "id": "SCREW", "level": 1 }, { "id": "WRENCH", "level": 1 } ], "components": [ - [ [ "steel_lump", 3 ], [ "steel_chunk", 9 ], [ "scrap", 36 ] ], - [ [ "metal_tank_little", 1 ] ], - [ [ "pipe", 4 ] ], - [ [ "motor_tiny", 1 ] ], - [ [ "element", 3 ], [ "crude_heating_element", 4 ] ], - [ [ "cable", 16 ] ] - ] + [ [ "pipe", 12 ] ], + [ [ "sheet_metal_small", 10 ] ], + [ [ "motor_small", 1 ] ], + [ [ "small_storage_battery", 1 ] ], + [ [ "wheel_small", 2 ] ], + [ [ "wheel_mount_light", 2 ] ], + [ [ "nuts_bolts", 8 ] ], + [ [ "30gal_barrel", 1 ] ] + ], + "//2": "The component list is by no means perfect - this craft still generates ~7.2kg of mass. I can't, however, improve it without adding nonexistant components to the recipe, so I think this is an acceptable state of things." }, { "type": "recipe", diff --git a/data/json/recipes/tools/containers.json b/data/json/recipes/tools/containers.json index 6806709906b81..c65292d393ee5 100644 --- a/data/json/recipes/tools/containers.json +++ b/data/json/recipes/tools/containers.json @@ -400,12 +400,12 @@ "category": "CC_OTHER", "subcategory": "CSC_OTHER_CONTAINERS", "skill_used": "fabrication", - "difficulty": 8, - "time": "30 m", + "difficulty": 6, + "time": "1 h", "autolearn": true, - "using": [ [ "soldering_standard", 40 ] ], - "qualities": [ { "id": "CUT", "level": 2 } ], - "components": [ [ [ "duct_tape", 200 ], [ "superglue", 4 ] ], [ [ "jerrycan", 12 ] ] ] + "proficiencies": [ { "proficiency": "prof_plasticworking" } ], + "using": [ [ "plastic_molding", 98 ] ], + "components": [ [ [ "plastic_chunk", 136 ] ] ] }, { "type": "recipe", diff --git a/data/json/regional_map_settings.json b/data/json/regional_map_settings.json index 4f21304f24c21..ac5aea1bf0526 100644 --- a/data/json/regional_map_settings.json +++ b/data/json/regional_map_settings.json @@ -353,154 +353,53 @@ }, "forest_thick": { "terrains": [ - "forest_thick", - "forest_trail_isolated", - "forest_trail_end_north", - "forest_trail_end_east", - "forest_trail_end_south", - "forest_trail_end_west", - "forest_trail_ns", - "forest_trail_ew", - "forest_trail_ne", - "forest_trail_es", - "forest_trail_sw", - "forest_trail_wn", - "forest_trail_new", - "forest_trail_nsw", - "forest_trail_esw", - "forest_trail_nes", - "forest_trail_nesw", - "campsite_north", - "campsite_south", - "campsite_east", - "campsite_west", - "campsite_cabin_incomplete_north", - "campsite_cabin_incomplete_south", - "campsite_cabin_incomplete_east", - "campsite_cabin_incomplete_west", - "campsite_field_biker_north", - "campsite_field_biker_south", - "campsite_field_biker_east", - "campsite_field_biker_west", - "campsite_field_biker_destroyed_north", - "campsite_field_biker_destroyed_south", - "campsite_field_biker_destroyed_east", - "campsite_field_biker_destroyed_west", - "campsite_a_north", - "campsite_a_south", - "campsite_a_east", - "campsite_a_west", - "desolatebarn_north", - "desolatebarn_south", - "desolatebarn_east", - "desolatebarn_west", - "derelict_property_north", - "derelict_property_south", - "derelict_property_east", - "derelict_property_west", - "homelesscamp_north", - "homelesscamp_south", - "homelesscamp_east", - "homelesscamp_west", - "spider_pit_north", - "spider_pit_south", - "spider_pit_east", - "spider_pit_west", - "survivor_forest_camp_north", - "survivor_forest_camp_south", - "survivor_forest_camp_east", - "survivor_forest_camp_west", - "central_lab_entrance", - "moonshine_still_north", - "moonshine_still_south", - "moonshine_still_east", - "moonshine_still_west", - "moonshine_still_1_north", - "moonshine_still_1_south", - "moonshine_still_1_east", - "moonshine_still_1_west", - "moonshine_still_2_north", - "moonshine_still_2_south", - "moonshine_still_2_east", - "moonshine_still_2_west", - "standing_stones", - "ws_survivor_bunker_f0_north", - "ws_survivor_bunker_f0_south", - "ws_survivor_bunker_f0_east", - "ws_survivor_bunker_f0_west", - "bandit_cabin_north", - "bandit_cabin_south", - "bandit_cabin_east", - "bandit_cabin_west", - "bandit_garage_1_north", - "bandit_garage_1_south", - "bandit_garage_1_east", - "bandit_garage_1_west", - "bandit_garage_2_north", - "bandit_garage_2_south", - "bandit_garage_2_east", - "bandit_garage_2_west", - "natural_spring_north", - "natural_spring_south", - "natural_spring_east", - "natural_spring_west", + "anthill", + "bandit_cabin", + "bandit_garage_1", + "bandit_garage_2", + "campsite", + "campsite_a", + "campsite_cabin_incomplete", + "campsite_field_biker", + "campsite_field_biker_destroyed", "cave", - "special_forest_thick", - "island_forest_north", - "island_forest_east", - "island_forest_south", - "island_forest_west", - "island_forest_thick_north", - "island_forest_thick_east", - "island_forest_thick_south", - "island_forest_thick_west", + "central_lab_entrance", + "corpse_tentacle_surface_entry", + "derelict_property", + "desolatebarn", + "forest_thick", + "forest_trail", + "forest_trail_intersection", + "homelesscamp", + "island_forest", + "island_forest_thick", "lake_shore", + "moonshine_still", + "moonshine_still_1", + "moonshine_still_2", + "natural_spring", + "river", + "river_c_not_ne", + "river_c_not_nw", + "river_c_not_se", + "river_c_not_sw", "river_center", - "river_north", - "river_east", - "river_south", - "river_west", "river_ne", + "river_nw", "river_se", "river_sw", - "river_nw", - "river_c_not_ne", - "river_c_not_se", - "river_c_not_sw", - "river_c_not_nw", - "stream_north", - "stream_east", - "stream_south", - "stream_west", - "stream_corner_north", - "stream_corner_east", - "stream_corner_south", - "stream_corner_west", - "stream_end_north", - "stream_end_east", - "stream_end_south", - "stream_end_west", "slimepit_top", - "anthill_north", - "anthill_east", - "anthill_south", - "anthill_west", - "corpse_tentacle_surface_entry_north", - "corpse_tentacle_surface_entry_east", - "corpse_tentacle_surface_entry_south", - "corpse_tentacle_surface_entry_west", - "ws_giant_sinkhole_1_north", - "ws_giant_sinkhole_1_east", - "ws_giant_sinkhole_1_south", - "ws_giant_sinkhole_1_west", - "triffid_grove_north", - "triffid_grove_east", - "triffid_grove_south", - "triffid_grove_west", - "triffid_field_north", - "triffid_field_east", - "triffid_field_south", - "triffid_field_west" + "special_forest_thick", + "spider_pit", + "standing_stones", + "stream", + "stream_corner", + "stream_end", + "survivor_forest_camp", + "triffid_grove", + "triffid_field", + "ws_giant_sinkhole_1", + "ws_survivor_bunker_f0" ], "sparseness_adjacency_factor": 4, "item_group": "forest", @@ -538,25 +437,7 @@ "terrain_furniture": { } }, "forest_water": { - "terrains": [ - "forest_water", - "hunter_shack_north", - "hunter_shack_south", - "hunter_shack_east", - "hunter_shack_west", - "hunter_shack_1_north", - "hunter_shack_1_south", - "hunter_shack_1_east", - "hunter_shack_1_west", - "shipwreck_river_1_north", - "shipwreck_river_1_south", - "shipwreck_river_1_east", - "shipwreck_river_1_west", - "shipwreck_river_2_north", - "shipwreck_river_2_south", - "shipwreck_river_2_east", - "shipwreck_river_2_west" - ], + "terrains": [ "forest_water", "hunter_shack", "hunter_shack_1", "shipwreck_river_1", "shipwreck_river_2" ], "sparseness_adjacency_factor": 2, "item_group": "forest", "item_group_chance": 60, diff --git a/data/json/scenarios.json b/data/json/scenarios.json index dfd9adf6119be..65e31c8740cb4 100644 --- a/data/json/scenarios.json +++ b/data/json/scenarios.json @@ -849,7 +849,7 @@ "id": "presort", "name": "Crazy Party", "points": -2, - "description": "You'd been unsurprised when your vacation — a hastily arranged holiday to a remote resort to maintain distance from the riots — had been put out of its misery when state-wide evacuation was ordered after weeks of worsening violence, and the complex had been placed on a shortlist for civilian gathering sights. After days of waiting for a non-existent rescue and refugees bringing tales of monsters and the dead, the remaining staff had taken steps to keep spirits up, and last evening, they did that in the best way they knew — hosting a party. Considering that it lured scores of zombies, you could probably classify that decision as a 'road to literal hell paved with good intentions.'", + "description": "You'd been unsurprised when your vacation — a hastily arranged holiday to a remote resort to maintain distance from the riots — had been put out of its misery when state-wide evacuation was ordered after weeks of worsening violence, and the complex had been placed on a shortlist for civilian gathering sites. After days of waiting for a non-existent rescue and refugees bringing tales of monsters and the dead, the remaining staff had taken steps to keep spirits up, and last evening, they did that in the best way they knew — hosting a party. Considering that it lured scores of zombies, you could probably classify that decision as a 'road to literal hell paved with good intentions.'", "start_name": "Private resort", "allowed_locs": [ "sloc_private_resort" ], "professions": [ diff --git a/data/json/vehicleparts/frames.json b/data/json/vehicleparts/frames.json index 3e774995252e0..c60ed0271d6c7 100644 --- a/data/json/vehicleparts/frames.json +++ b/data/json/vehicleparts/frames.json @@ -279,5 +279,18 @@ "repair": { "skills": [ [ "mechanics", 2 ] ], "time": "9 m", "using": [ [ "repair_welding_alloys", 5 ] ] } }, "damage_reduction": { "all": 7 } + }, + { + "id": "frame_concrete_mix", + "type": "vehicle_part", + "copy-from": "frame_abstract", + "name": { "str": "concrete mixer chassis" }, + "item": "frame_concrete_mix", + "durability": 150, + "description": "The chassis of a concrete mixer.", + "folded_volume": "10 L", + "breaks_into": [ { "item": "steel_chunk", "count": [ 1, 4 ] }, { "item": "scrap", "count": [ 5, 25 ] } ], + "extend": { "flags": [ "NO_INSTALL_HIDDEN", "CABLE_PORTS" ] }, + "damage_reduction": { "all": 7 } } ] diff --git a/data/json/vehicleparts/modular_tools.json b/data/json/vehicleparts/modular_tools.json index 2fbfdcf7fd367..de9b352f0c0f0 100644 --- a/data/json/vehicleparts/modular_tools.json +++ b/data/json/vehicleparts/modular_tools.json @@ -104,7 +104,6 @@ "angle_grinder", "atomic_coffeepot", "coffeemaker", - "con_mix", "copper_pan", "cordless_drill", "corded_powerdrill", diff --git a/data/json/vehicleparts/utilities.json b/data/json/vehicleparts/utilities.json index fb7ef63154e81..9369547273e04 100644 --- a/data/json/vehicleparts/utilities.json +++ b/data/json/vehicleparts/utilities.json @@ -134,5 +134,22 @@ }, "breaks_into": [ { "item": "plastic_chunk", "count": [ 2, 5 ] } ], "variants": [ { "symbols": "8", "symbols_broken": "x" } ] + }, + { + "id": "drum_concrete_mix", + "type": "vehicle_part", + "name": { "str": "concrete mixer drum" }, + "item": "30gal_barrel", + "description": "A plastic 100-liter drum of a portable concrete mixer.", + "categories": [ "utility" ], + "location": "center", + "folded_volume": "113560 ml", + "color": "light_blue", + "broken_color": "light_blue", + "durability": 150, + "flags": [ "OBSTACLE", "NO_INSTALL_HIDDEN" ], + "pseudo_tools": [ { "id": "concrete_mix_tool" } ], + "breaks_into": [ { "item": "plastic_chunk", "count": [ 10, 100 ] } ], + "variants": [ { "symbols": "U", "symbols_broken": "u" } ] } ] diff --git a/data/json/vehicleparts/vp_flags.json b/data/json/vehicleparts/vp_flags.json index 36b696f9b3279..b5d0b44897dc3 100644 --- a/data/json/vehicleparts/vp_flags.json +++ b/data/json/vehicleparts/vp_flags.json @@ -694,5 +694,14 @@ { "id": "IGNORE_HEIGHT_REQUIREMENT", "type": "json_flag" + }, + { + "id": "WHEEL_MOUNT_CONCRETE_MIX", + "type": "json_flag" + }, + { + "id": "NEEDS_WHEEL_MOUNT_CONCRETE_MIX", + "type": "json_flag", + "requires_flag": "WHEEL_MOUNT_CONCRETE_MIX" } ] diff --git a/data/json/vehicleparts/wheel.json b/data/json/vehicleparts/wheel.json index 5102e4633bf6e..0d343b1a92e1e 100644 --- a/data/json/vehicleparts/wheel.json +++ b/data/json/vehicleparts/wheel.json @@ -723,5 +723,42 @@ "rolling_resistance": 2.05, "proportional": { "durability": 2, "damage_modifier": 2 }, "damage_reduction": { "all": 20 } + }, + { + "type": "vehicle_part", + "id": "wheel_mount_concrete_mix", + "name": { "str": "concrete mixer wheel mounts" }, + "categories": [ "movement" ], + "location": "axle", + "damage_modifier": 80, + "folded_volume": "500 ml", + "durability": 240, + "description": "A set of two small wheel mounts from a concrete mixer.", + "item": "wheel_mount_concrete_mix", + "flags": [ "WHEEL_MOUNT_CONCRETE_MIX", "NEEDS_JACKING", "NO_INSTALL_HIDDEN" ], + "breaks_into": [ { "item": "scrap", "count": [ 1, 8 ] } ], + "damage_reduction": { "all": 10 }, + "variants": [ { "symbols": "-", "symbols_broken": "X" } ] + }, + { + "id": "wheel_set_concrete_mix", + "type": "vehicle_part", + "name": { "str": "concrete mixer wheels" }, + "looks_like": "wheel", + "item": "wheel_set_concrete_mix", + "location": "under", + "categories": [ "movement" ], + "color": "dark_gray", + "durability": 140, + "description": "A small wheel.", + "damage_modifier": 50, + "folded_volume": "5500 ml", + "breaks_into": [ { "item": "steel_lump" }, { "item": "steel_chunk", "count": [ 1, 3 ] }, { "item": "scrap", "count": [ 1, 6 ] } ], + "rolling_resistance": 1.5, + "wheel_offroad_rating": 0.3, + "wheel_terrain_modifiers": { "FLAT": [ 0, 5 ], "ROAD": [ 0, 2 ] }, + "contact_area": 60, + "flags": [ "WHEEL", "UNSTABLE_WHEEL", "NEEDS_WHEEL_MOUNT_CONCRETE_MIX", "NO_INSTALL_HIDDEN" ], + "variants": [ { "symbols": "o", "symbols_broken": "x" } ] } ] diff --git a/data/json/vitamin.json b/data/json/vitamin.json index 8a6f7199ac09c..4b7dac5429ca6 100644 --- a/data/json/vitamin.json +++ b/data/json/vitamin.json @@ -125,7 +125,6 @@ [ "mutagen_troglobite", 1 ], [ "mutagen_chiropteran", 1 ], [ "mutagen_ursine", 1 ], - [ "instability", 1 ], [ "mutant_toxin", 2 ] ] }, @@ -477,18 +476,6 @@ "rate": "1 h", "disease_excess": [ [ 100, 500 ], [ 501, 2199 ], [ 2200, 2500 ] ] }, - { - "id": "instability", - "type": "vitamin", - "vit_type": "counter", - "name": { "str": "Instability" }, - "excess": "genetics_damaged", - "min": 0, - "max": 8000, - "flags": [ "NO_DISPLAY" ], - "rate": "2 h", - "disease_excess": [ [ 1, 899 ], [ 900, 2799 ], [ 2800, 8000 ] ] - }, { "id": "bad_food", "type": "vitamin", diff --git a/data/json/weapon_categories.json b/data/json/weapon_categories.json index b79f6ebeb0d9a..53688ccab77c0 100644 --- a/data/json/weapon_categories.json +++ b/data/json/weapon_categories.json @@ -2,122 +2,152 @@ { "type": "weapon_category", "id": "AUTOMATIC_RIFLES", - "name": "AUTOMATIC RIFLES" + "name": "AUTOMATIC RIFLES", + "proficiencies": [ "prof_auto_rifles_familiar", "prof_auto_rifles_pro", "prof_auto_rifles_master" ] }, { "type": "weapon_category", "id": "AUTOMATIC_PISTOLS", - "name": "AUTOMATIC PISTOLS" + "name": "AUTOMATIC PISTOLS", + "proficiencies": [ "prof_auto_pistols_familiar", "prof_auto_pistols_pro", "prof_auto_pistols_master" ] }, { "type": "weapon_category", "id": "KNIVES", - "name": "KNIVES" + "name": "KNIVES", + "proficiencies": [ "prof_knives_familiar", "prof_knives_pro", "prof_knives_master" ] }, { "type": "weapon_category", "id": "BATONS", - "name": "BATONS" + "name": "BATONS", + "proficiencies": [ "prof_batons_familiar", "prof_batons_pro", "prof_batons_master" ] }, { "type": "weapon_category", "id": "FLAILS", - "name": "FLAILS" + "name": "FLAILS", + "proficiencies": [ "prof_flails_familiar", "prof_flails_pro", "prof_flails_master" ] }, { "type": "weapon_category", "id": "MACES", - "name": "MACES" + "name": "MACES", + "proficiencies": [ "prof_maces_familiar", "prof_maces_pro", "prof_maces_master" ] }, { "type": "weapon_category", "id": "MEDIUM_SWORDS", "//": "One-handed swords above 60cm in length with a cutting edge.", - "name": "MEDIUM SWORDS" + "name": "MEDIUM SWORDS", + "proficiencies": [ "prof_medium_swords_familiar", "prof_medium_swords_pro", "prof_medium_swords_master" ] }, { "type": "weapon_category", "id": "LONG_SWORDS", "//": "Hand-and-a-half swords, i.e. any sword that can be used one or two-handed fairly easily with a cutting edge.", - "name": "LONG SWORDS" + "name": "LONG SWORDS", + "proficiencies": [ "prof_long_swords_familiar", "prof_long_swords_pro", "prof_long_swords_master" ] }, { "type": "weapon_category", "id": "SHORT_SWORDS", "//": "One-handed swords at or below 60cm in length with a cutting edge, such as machetes.", - "name": "SHORT SWORDS" + "name": "SHORT SWORDS", + "proficiencies": [ "prof_short_swords_familiar", "prof_short_swords_pro", "prof_short_swords_master" ] }, { "type": "weapon_category", "id": "QUARTERSTAVES", - "name": "QUARTERSTAVES" + "name": "QUARTERSTAVES", + "proficiencies": [ "prof_quarterstaves_familiar", "prof_quarterstaves_pro", "prof_quarterstaves_master" ] }, { "type": "weapon_category", "id": "CLAWS", - "name": "CLAWS" + "name": "CLAWS", + "proficiencies": [ "prof_claws_familiar", "prof_claws_pro", "prof_claws_master" ] }, { "type": "weapon_category", "id": "SHIVS", - "name": "SHIVS" + "name": "SHIVS", + "proficiencies": [ "prof_shivs_familiar", "prof_shivs_pro", "prof_shivs_master" ] }, { "type": "weapon_category", "id": "HOOKING_WEAPONRY", - "name": "HOOKING WEAPONRY" + "name": "HOOKING WEAPONRY", + "proficiencies": [ "prof_hooking_familiar", "prof_hooking_pro", "prof_hooking_master" ] }, { "type": "weapon_category", "id": "SPEARS", - "name": "SPEARS" + "name": "SPEARS", + "proficiencies": [ "prof_spears_familiar", "prof_spears_pro", "prof_spears_master" ] + }, + { + "//": "Fake category for unarmed - don't apply to any weapons", + "type": "weapon_category", + "id": "UNARMED", + "name": "UNARMED", + "proficiencies": [ "prof_unarmed_familiar", "prof_unarmed_pro", "prof_unarmed_master" ] }, { "type": "weapon_category", "id": "POLEARMS", - "name": "POLEARMS" + "name": "POLEARMS", + "proficiencies": [ "prof_polearms_familiar", "prof_polearms_pro", "prof_polearms_master" ] }, { "type": "weapon_category", "id": "FENCING_WEAPONRY", "//": "One-handed straight swords built for thrusting or lightly curved agile sabers. Cutting edge optional for the former.", - "name": "FENCING WEAPONRY" + "name": "FENCING WEAPONRY", + "proficiencies": [ "prof_fencing_weapons_familiar", "prof_fencing_weapons_pro", "prof_fencing_weapons_master" ] }, { "type": "weapon_category", "id": "LONG_THRUSTING_SWORDS", "//": "Hand-and-a-half or two-handed straight swords built for thrusting. Cutting edge optional.", - "name": "LONG THRUSTING SWORDS" + "name": "LONG THRUSTING SWORDS", + "proficiencies": [ "prof_thrusting_swords_familiar", "prof_thrusting_swords_pro", "prof_thrusting_swords_master" ] }, { "type": "weapon_category", "id": "BIONIC_WEAPONRY", - "name": "BIONIC WEAPONRY" + "name": "BIONIC WEAPONRY", + "proficiencies": [ "prof_bionics_familiar", "prof_bionics_pro", "prof_bionics_master" ] }, { "type": "weapon_category", "id": "BIONIC_SWORDS", - "name": "BIONIC SWORDS" + "name": "BIONIC SWORDS", + "proficiencies": [ "prof_bionic_swords_familiar", "prof_bionic_swords_pro", "prof_bionic_swords_master" ] }, { "type": "weapon_category", "id": "GREAT_SWORDS", "//": "Swords with cutting edges that require two hands to use effectively.", - "name": "GREAT SWORDS" + "name": "GREAT SWORDS", + "proficiencies": [ "prof_great_swords_familiar", "prof_great_swords_pro", "prof_great_swords_master" ] }, { "type": "weapon_category", "id": "GREAT_HAMMERS", - "name": "GREAT HAMMERS" + "name": "GREAT HAMMERS", + "proficiencies": [ "prof_great_hammers_familiar", "prof_great_hammers_pro", "prof_great_hammers_master" ] }, { "type": "weapon_category", "id": "GREAT_AXES", - "name": "GREAT AXES" + "name": "GREAT AXES", + "proficiencies": [ "prof_great_axes_familiar", "prof_great_axes_pro", "prof_great_axes_master" ] }, { "type": "weapon_category", "id": "HAND_AXES", - "name": "HAND AXES" + "name": "HAND AXES", + "proficiencies": [ "prof_hand_axes_familiar", "prof_hand_axes_pro", "prof_hand_axes_master" ] } ] diff --git a/data/mods/Aftershock/items/armor/exosuit/exosuit_frame.json b/data/mods/Aftershock/items/armor/exosuit/exosuit_frame.json index b508cfa98fcb1..328b41533edbc 100644 --- a/data/mods/Aftershock/items/armor/exosuit/exosuit_frame.json +++ b/data/mods/Aftershock/items/armor/exosuit/exosuit_frame.json @@ -310,18 +310,7 @@ } ], "ammo": "battery", - "flags": [ - "USE_UPS", - "IS_UPS", - "STURDY", - "WATERPROOF", - "ELECTRIC_IMMUNE", - "COMBAT_TOGGLEABLE", - "OUTER", - "MUNDANE", - "DEAF", - "TARDIS" - ], + "flags": [ "USE_UPS", "STURDY", "WATERPROOF", "ELECTRIC_IMMUNE", "COMBAT_TOGGLEABLE", "OUTER", "MUNDANE", "DEAF", "TARDIS" ], "relic_data": { "passive_effects": [ { "condition": "ACTIVE", "values": [ { "value": "STRENGTH", "add": 10 }, { "value": "CARRY_WEIGHT", "add": 20000 } ] } @@ -349,7 +338,6 @@ "description": "This is a standard exosuit frame. Designed to be modular, it can accept a variety of power supplies, defensive and offensive systems, and utility tools. Slots exist for the torso, back, arms, and legs. It is turned on and continually drawing power. Use it to turn it off.", "flags": [ "USE_UPS", - "IS_UPS", "STURDY", "WATERPROOF", "ELECTRIC_IMMUNE", @@ -541,18 +529,7 @@ } ], "ammo": "battery", - "flags": [ - "USE_UPS", - "IS_UPS", - "STURDY", - "WATERPROOF", - "ELECTRIC_IMMUNE", - "COMBAT_TOGGLEABLE", - "OUTER", - "MUNDANE", - "DEAF", - "TARDIS" - ], + "flags": [ "USE_UPS", "STURDY", "WATERPROOF", "ELECTRIC_IMMUNE", "COMBAT_TOGGLEABLE", "OUTER", "MUNDANE", "DEAF", "TARDIS" ], "relic_data": { "passive_effects": [ { "id": "ench_exo_strength" } ] }, "use_action": [ { @@ -576,7 +553,6 @@ "description": "This is a light duty exosuit frame. This lighter version of the exosuit draws less power but has less capacity for equipment and uses a fixed cage for collision protection instead of modular armor. It is turned on and continually drawing power. Use it to turn it off.", "flags": [ "USE_UPS", - "IS_UPS", "STURDY", "WATERPROOF", "ELECTRIC_IMMUNE", @@ -600,7 +576,7 @@ ], "covers": [ "eyes" ], "coverage": 100, - "encumbrance": 100, + "encumbrance": 5, "layers": [ "OUTER" ] }, { diff --git a/data/mods/Aftershock/maps/mapgen/port_augustmoon/port_augustmoon_main.json b/data/mods/Aftershock/maps/mapgen/port_augustmoon/port_augustmoon_main.json index 0a10aa4f15e28..786312520b61f 100644 --- a/data/mods/Aftershock/maps/mapgen/port_augustmoon/port_augustmoon_main.json +++ b/data/mods/Aftershock/maps/mapgen/port_augustmoon/port_augustmoon_main.json @@ -32,7 +32,7 @@ ".||||||__ ,, _ ,, =.", ".|1111=Ăş______ |.", ".|1111= ||::|::||||", - ".|1111= | |Ă‘|566|665||.", + ".|1111=ò| |Ă‘|566|665||.", "|||||||||]]|||666|666||.", "|qqq ], ,||||||||||.", "| ,, ] %||Ă‘Ă‘Ă‘ = ||", @@ -76,6 +76,7 @@ "=": "t_afs_augustmoon_diamond_glass", "w": "t_carpet_metal_red", "|": "t_afs_augustmoon_hull_wall", + "ò": "t_atm", "1": "t_underbrush", "2": "t_nanofab_body", "3": "t_nanofab", diff --git a/data/mods/Backrooms/overmap_terrain.json b/data/mods/Backrooms/overmap_terrain.json index 3883c28cd5751..706fd1d082dca 100644 --- a/data/mods/Backrooms/overmap_terrain.json +++ b/data/mods/Backrooms/overmap_terrain.json @@ -20,32 +20,6 @@ "om_terrain": [ "backfloorchamber" ], "object": { "fill_ter": "t_carpet_backrooms", - "rows": [ - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " " - ], "place_nested": [ { "chunks": [ [ "mx_backrooms_whole", 100 ] ], "x": 0, "y": 0 }, { diff --git a/data/mods/DinoMod/mapgen/map_extras/mass_grave.json b/data/mods/DinoMod/mapgen/map_extras/mass_grave.json index c15d0264e5b9d..b3f8a91efc0c3 100644 --- a/data/mods/DinoMod/mapgen/map_extras/mass_grave.json +++ b/data/mods/DinoMod/mapgen/map_extras/mass_grave.json @@ -5,32 +5,6 @@ "//": "This is the 'base' mass grave, and doesn't actually contain anything. Variants are generated via the place_nested field.", "update_mapgen_id": "mx_mass_grave_dino", "object": { - "rows": [ - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " " - ], "place_nested": [ { "chunks": [ diff --git a/data/mods/DinoMod/mapgen/map_extras/portal.json b/data/mods/DinoMod/mapgen/map_extras/portal.json index fa3362dab9af5..de67f9db179ff 100644 --- a/data/mods/DinoMod/mapgen/map_extras/portal.json +++ b/data/mods/DinoMod/mapgen/map_extras/portal.json @@ -4,32 +4,6 @@ "method": "json", "update_mapgen_id": "mx_portal_dino_south_america", "object": { - "rows": [ - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " " - ], "place_nested": [ { "chunks": [ "portal_location" ], "x": [ 2, 20 ], "y": [ 2, 20 ] } ], "monsters": { " ": { "monster": "GROUP_DINOSAUR_SOUTH_AMERICA", "chance": 1, "density": 0.0001 } } } @@ -39,32 +13,6 @@ "method": "json", "update_mapgen_id": "mx_portal_dino_asia", "object": { - "rows": [ - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " " - ], "place_nested": [ { "chunks": [ "portal_location" ], "x": [ 2, 20 ], "y": [ 2, 20 ] } ], "monsters": { " ": { "monster": "GROUP_DINOSAUR_ASIA", "chance": 1, "density": 0.0001 } } } @@ -74,32 +22,6 @@ "method": "json", "update_mapgen_id": "mx_portal_dino_europe", "object": { - "rows": [ - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " " - ], "place_nested": [ { "chunks": [ "portal_location" ], "x": [ 2, 20 ], "y": [ 2, 20 ] } ], "monsters": { " ": { "monster": "GROUP_DINOSAUR_EUROPE", "chance": 1, "density": 0.0001 } } } diff --git a/data/mods/Magiclysm/Spells/animist.json b/data/mods/Magiclysm/Spells/animist.json index 8c4667e8d1149..0dc49a8105b12 100644 --- a/data/mods/Magiclysm/Spells/animist.json +++ b/data/mods/Magiclysm/Spells/animist.json @@ -32,9 +32,9 @@ "name": "Life Conversion", "description": "You channel lifeforce itself into your spiritual energy. You consume a rune to regain mana.", "valid_targets": [ "self" ], - "min_damage": { "math": [ "channeling_proficiency_bonus_calculate(75)" ] }, - "damage_increment": { "math": [ "channeling_proficiency_bonus_calculate(15)" ] }, - "max_damage": { "math": [ "channeling_proficiency_bonus_calculate(600)" ] }, + "min_damage": { "math": [ "channeling_proficiency_bonus_calculate(75, 1)" ] }, + "damage_increment": { "math": [ "channeling_proficiency_bonus_calculate(15, 0.03)" ] }, + "max_damage": { "math": [ "channeling_proficiency_bonus_calculate(600, 1)" ] }, "max_level": 35, "effect": "recover_energy", "effect_str": "MANA", @@ -42,7 +42,7 @@ "spell_class": "ANIMIST", "energy_source": "MANA", "components": "spell_components_rune_animist", - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(500)" ] }, + "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(500, 4)" ] }, "flags": [ "SOMATIC", "VERBAL", "SILENT", "NO_LEGS", "CONSUMES_RUNES" ], "extra_effects": [ { "id": "eoc_channeling_setup" } ], "difficulty": 3 @@ -53,16 +53,16 @@ "name": "Mind over Pain", "description": "With an intense ritual that resembles crossfit, you manage to put some of your pain at bay.", "valid_targets": [ "self" ], - "min_damage": { "math": [ "channeling_proficiency_bonus_calculate(10)" ] }, - "max_damage": { "math": [ "channeling_proficiency_bonus_calculate(100)" ] }, - "damage_increment": 2.0, + "min_damage": { "math": [ "channeling_proficiency_bonus_calculate(10, 1)" ] }, + "max_damage": { "math": [ "channeling_proficiency_bonus_calculate(100, 1)" ] }, + "damage_increment": { "math": [ "channeling_proficiency_bonus_calculate(2.0, 0.022)" ] }, "max_level": 45, "spell_class": "ANIMIST", "effect": "recover_energy", "effect_str": "PAIN", "shape": "blast", "energy_source": "STAMINA", - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(50000)" ] }, + "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(50000, 100)" ] }, "base_energy_cost": 5000, "energy_increment": 500.0, "flags": [ "SOMATIC", "VERBAL", "PAIN_NORESIST" ], @@ -423,7 +423,7 @@ "effect": "spawn_item", "effect_str": "rune_animist", "shape": "blast", - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(5000)" ] }, + "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(5000, 10)" ] }, "base_energy_cost": 5, "min_duration": 1, "max_duration": 2, @@ -454,7 +454,7 @@ "min_range": 4, "max_range": 26, "range_increment": 1.1, - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(400)" ] }, + "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(400, 1)" ] }, "spell_class": "ANIMIST", "difficulty": 6, "max_level": 20, @@ -464,9 +464,9 @@ "min_duration": 36000, "max_duration": 1080000, "duration_increment": 36000, - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(300)" ] }, - "final_casting_time": { "math": [ "channeling_proficiency_negate_calculate(30)" ] }, - "casting_time_increment": { "math": [ "channeling_proficiency_negate_calculate(-14)" ] }, + "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(300, 1)" ] }, + "final_casting_time": { "math": [ "channeling_proficiency_negate_calculate(30, 1)" ] }, + "casting_time_increment": { "math": [ "channeling_proficiency_negate_calculate(-14, 0.051)" ] }, "extra_effects": [ { "id": "eoc_channeling_setup" } ], "energy_source": "MANA" }, @@ -510,7 +510,7 @@ "//": "would be cool to make it deal damage the same as hp of the monster, but not possible sadly", "min_damage": { "math": [ "evocation_proficiency_bonus_calculate(20)" ] }, "max_damage": { "math": [ "evocation_proficiency_bonus_calculate(180)" ] }, - "damage_increment": 6.4, + "damage_increment": { "math": [ "evocation_proficiency_bonus_calculate(6.4)" ] }, "spell_class": "ANIMIST", "difficulty": 5, "max_level": 25, @@ -536,9 +536,9 @@ "spell_class": "ANIMIST", "difficulty": 4, "max_level": 10, - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(30000)" ] }, - "final_casting_time": { "math": [ "channeling_proficiency_negate_calculate(1000)" ] }, - "casting_time_increment": { "math": [ "channeling_proficiency_negate_calculate(-200)" ] }, + "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(30000, 10)" ] }, + "final_casting_time": { "math": [ "channeling_proficiency_negate_calculate(1000, 10)" ] }, + "casting_time_increment": { "math": [ "channeling_proficiency_negate_calculate(-200, 0.007)" ] }, "energy_source": "MANA", "extra_effects": [ { "id": "create_rune_animist", "hit_self": true }, { "id": "eoc_channeling_setup" } ] }, @@ -1047,8 +1047,8 @@ "difficulty": 5, "max_level": 15, "energy_source": "MANA", - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(550)" ] }, - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(90000)" ] } + "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(550, 5)" ] }, + "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(90000, 100)" ] } }, { "type": "effect_on_condition", diff --git a/data/mods/Magiclysm/Spells/attunements/Artificer.json b/data/mods/Magiclysm/Spells/attunements/Artificer.json index b5295545486c3..4c8ba07ea5bea 100644 --- a/data/mods/Magiclysm/Spells/attunements/Artificer.json +++ b/data/mods/Magiclysm/Spells/attunements/Artificer.json @@ -21,7 +21,7 @@ "min_duration": 1500, "duration_increment": 115, "max_duration": 5500, - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(140)" ] }, + "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(140, 1.5)" ] }, "components": "spy_wasp", "field_id": "fd_clairvoyant", "min_field_intensity": 1, @@ -29,7 +29,7 @@ "spell_class": "ARTIFICER", "difficulty": 3, "max_level": 35, - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(700)" ] }, + "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(700, 1.5)" ] }, "energy_source": "MANA" }, { diff --git a/data/mods/Magiclysm/Spells/attunements/Biotek.json b/data/mods/Magiclysm/Spells/attunements/Biotek.json index 9c2389ade4e4f..92e1b2d729df4 100644 --- a/data/mods/Magiclysm/Spells/attunements/Biotek.json +++ b/data/mods/Magiclysm/Spells/attunements/Biotek.json @@ -43,10 +43,10 @@ "max_level": 35, "effect": "attack", "shape": "blast", - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(500)" ] }, - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(800)" ] }, - "energy_increment": { "math": [ "channeling_proficiency_negate_calculate(-20)" ] }, - "final_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(100)" ] }, + "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(500, 1)" ] }, + "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(800, 1)" ] }, + "energy_increment": { "math": [ "channeling_proficiency_negate_calculate(-20, 0.03)" ] }, + "final_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(100, 1)" ] }, "components": "jury_rig", "flags": [ "SOMATIC", "VERBAL", "NO_LEGS", "CONCENTRATE", "MUST_HAVE_CLASS_TO_LEARN" ], "spell_class": "BIOTEK", diff --git a/data/mods/Magiclysm/Spells/attunements/Cleansing_Flame.json b/data/mods/Magiclysm/Spells/attunements/Cleansing_Flame.json index 459ba548d5ee5..443fdb69f2b58 100644 --- a/data/mods/Magiclysm/Spells/attunements/Cleansing_Flame.json +++ b/data/mods/Magiclysm/Spells/attunements/Cleansing_Flame.json @@ -18,7 +18,7 @@ "max_level": 1, "base_casting_time": { "math": [ - "u_effect_intensity('effect_burning_trail') > -1 ? 0 : 50 - ((u_proficiency('prof_magic_enhancement_beginner', 'format': 'percent') * 1) / 10) + ((u_proficiency('prof_magic_enhancement_apprentice', 'format': 'percent') * 1) / 10) + ((u_proficiency('prof_magic_enhancement_master', 'format': 'percent') * 1) / 10)" + "u_effect_intensity('effect_burning_trail') > -1 ? 0 : 50 - ((u_proficiency('prof_magic_enhancement_beginner', 'format': 'percent') * 1) / 10) - ((u_proficiency('prof_magic_enhancement_apprentice', 'format': 'percent') * 1) / 10) - ((u_proficiency('prof_magic_enhancement_master', 'format': 'percent') * 1) / 10)" ] }, "base_energy_cost": 25 @@ -155,8 +155,8 @@ "valid_targets": [ "self" ], "effect": "attack", "shape": "blast", - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(350)" ] }, - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(800)" ] }, + "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(350, 1.5)" ] }, + "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(800, 1.5)" ] }, "energy_source": "MANA", "difficulty": 10, "min_damage": -20, diff --git a/data/mods/Magiclysm/Spells/attunements/Gaias_Chosen.json b/data/mods/Magiclysm/Spells/attunements/Gaias_Chosen.json index 5138e8b9e027a..8f48b284d490f 100644 --- a/data/mods/Magiclysm/Spells/attunements/Gaias_Chosen.json +++ b/data/mods/Magiclysm/Spells/attunements/Gaias_Chosen.json @@ -10,8 +10,8 @@ "effect": "attack", "effect_str": "cureall", "shape": "blast", - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(60000)" ] }, - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(800)" ] }, + "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(60000, 100)" ] }, + "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(800, 10)" ] }, "energy_source": "MANA", "difficulty": 8, "min_damage": -20, @@ -30,8 +30,8 @@ "effect_str": "EOC_DUST_REBORN_INITIAL", "extra_effects": [ { "id": "eoc_channeling_setup" } ], "shape": "blast", - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(2160000)" ] }, - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(1000)" ] }, + "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(2160000, 1000)" ] }, + "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(1000, 20)" ] }, "energy_source": "MANA", "flags": [ "SOMATIC", "VERBAL", "CONCENTRATE", "MUST_HAVE_CLASS_TO_LEARN" ], "spell_class": "GAIAS_CHOSEN", diff --git a/data/mods/Magiclysm/Spells/attunements/Permafrost_Mage.json b/data/mods/Magiclysm/Spells/attunements/Permafrost_Mage.json index de910eeddeba7..3b464b3a80a19 100644 --- a/data/mods/Magiclysm/Spells/attunements/Permafrost_Mage.json +++ b/data/mods/Magiclysm/Spells/attunements/Permafrost_Mage.json @@ -14,12 +14,12 @@ "energy_source": "MANA", "difficulty": 9, "max_level": 35, - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(600)" ] }, - "casting_time_increment": { "math": [ "channeling_proficiency_negate_calculate(-15)" ] }, - "final_casting_time": { "math": [ "channeling_proficiency_negate_calculate(200)" ] }, - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(800)" ] }, - "energy_increment": { "math": [ "channeling_proficiency_negate_calculate(-15)" ] }, - "final_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(400)" ] }, + "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(600, 5)" ] }, + "casting_time_increment": { "math": [ "channeling_proficiency_negate_calculate(-15, 0.0375)" ] }, + "final_casting_time": { "math": [ "channeling_proficiency_negate_calculate(200, 5)" ] }, + "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(800, 5)" ] }, + "energy_increment": { "math": [ "channeling_proficiency_negate_calculate(-15, 0.0375)" ] }, + "final_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(400, 5)" ] }, "min_damage": 1, "max_damage": 1, "min_duration": 10000, diff --git a/data/mods/Magiclysm/Spells/biomancer.json b/data/mods/Magiclysm/Spells/biomancer.json index ef5e8329cdce9..fd288f3ef7af1 100644 --- a/data/mods/Magiclysm/Spells/biomancer.json +++ b/data/mods/Magiclysm/Spells/biomancer.json @@ -14,8 +14,8 @@ "range_increment": 0.75, "effect": "attack", "shape": "blast", - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(300)" ] }, - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(800)" ] }, + "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(300, 3)" ] }, + "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(800, 10)" ] }, "extra_effects": [ { "id": "eoc_channeling_setup" } ], "flags": [ "SOMATIC", "VERBAL", "NO_PROJECTILE" ], "spell_class": "BIOMANCER", @@ -30,8 +30,8 @@ "valid_targets": [ "self" ], "effect": "pain_split", "shape": "blast", - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(100)" ] }, - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(800)" ] }, + "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(100, 1)" ] }, + "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(800, 10)" ] }, "extra_effects": [ { "id": "eoc_channeling_setup" } ], "energy_source": "MANA", "flags": [ "SOMATIC", "NO_LEGS", "CONCENTRATE" ], @@ -229,7 +229,7 @@ "effect": "spawn_item", "effect_str": "rune_biomancer", "shape": "blast", - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(5000)" ] }, + "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(5000, 15)" ] }, "extra_effects": [ { "id": "eoc_channeling_setup" } ], "base_energy_cost": 5, "min_duration": 1, @@ -521,12 +521,12 @@ "max_level": 15, "energy_source": "MANA", "min_range": 1, - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(1500)" ] }, - "base_casting_time": { "math": [ "channeling_proficiency_bonus_calculate(180000)" ] }, - "min_duration": { "math": [ "channeling_proficiency_bonus_calculate(4500000)" ] }, - "max_duration": { "math": [ "channeling_proficiency_bonus_calculate(45000000)" ] }, + "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(1500, 10)" ] }, + "base_casting_time": { "math": [ "channeling_proficiency_bonus_calculate(180000, 1000)" ] }, + "min_duration": { "math": [ "channeling_proficiency_bonus_calculate(4500000, 10000)" ] }, + "max_duration": { "math": [ "channeling_proficiency_bonus_calculate(45000000, 10000)" ] }, "extra_effects": [ { "id": "eoc_channeling_setup" } ], - "duration_increment": { "math": [ "channeling_proficiency_bonus_calculate(2700000)" ] } + "duration_increment": { "math": [ "channeling_proficiency_bonus_calculate(2700000, 10000)" ] } }, { "id": "biomancer_carrion_feast", diff --git a/data/mods/Magiclysm/Spells/classless.json b/data/mods/Magiclysm/Spells/classless.json index a9fc0e73a6424..e5e76f5a77826 100644 --- a/data/mods/Magiclysm/Spells/classless.json +++ b/data/mods/Magiclysm/Spells/classless.json @@ -15,10 +15,10 @@ "effect_str": "eoc_crystal_spawn", "shape": "blast", "energy_source": "MANA", - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(1000)" ] }, - "final_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(1000)" ] }, - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(600000)" ] }, - "final_casting_time": { "math": [ "channeling_proficiency_negate_calculate(600000)" ] }, + "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(1000, 10)" ] }, + "final_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(1000, 10)" ] }, + "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(600000, 4000)" ] }, + "final_casting_time": { "math": [ "channeling_proficiency_negate_calculate(600000, 4000)" ] }, "extra_effects": [ { "id": "mana_fatigue" }, { "id": "eoc_channeling_setup" } ] }, { @@ -125,7 +125,7 @@ "min_damage": { "math": [ "evocation_proficiency_bonus_calculate(30)" ] }, "max_damage": { "math": [ "evocation_proficiency_bonus_calculate(100)" ] }, "extra_effects": [ { "id": "eoc_evocation_setup" } ], - "damage_increment": 3.5, + "damage_increment": { "math": [ "evocation_proficiency_bonus_calculate(3.5)" ] }, "min_range": 3, "max_range": 12, "range_increment": 0.45, @@ -432,13 +432,13 @@ "shape": "blast", "sound_description": "a loud, high pitched sound", "damage_type": "sonic", - "min_damage": { "math": [ "channeling_proficiency_bonus_calculate(12)" ] }, - "max_damage": { "math": [ "channeling_proficiency_bonus_calculate(120)" ] }, + "min_damage": { "math": [ "channeling_proficiency_bonus_calculate(12, 0.5)" ] }, + "max_damage": { "math": [ "channeling_proficiency_bonus_calculate(120, 0.5)" ] }, "damage_increment": 5, "min_range": 5, "max_range": 55, "range_increment": 2, - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(125)" ] }, + "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(125, 1)" ] }, "spell_class": "NONE", "difficulty": 3, "max_level": 25, @@ -469,8 +469,8 @@ "duration_increment": 720000, "extra_effects": [ { "id": "eoc_channeling_setup" } ], "energy_source": "MANA", - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(50)" ] }, - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(6000)" ] } + "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(50, 0.5)" ] }, + "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(6000, 15)" ] } }, { "id": "classless_clean_clothing_and_self", @@ -486,9 +486,9 @@ "difficulty": 2, "max_level": 15, "energy_source": "MANA", - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(75)" ] }, + "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(75, 0.5)" ] }, "extra_effects": [ { "id": "eoc_channeling_setup" } ], - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(3000)" ] } + "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(3000, 12)" ] } }, { "type": "effect_on_condition", diff --git a/data/mods/Magiclysm/Spells/druid.json b/data/mods/Magiclysm/Spells/druid.json index f63aec94ba97e..c373f66382c84 100644 --- a/data/mods/Magiclysm/Spells/druid.json +++ b/data/mods/Magiclysm/Spells/druid.json @@ -220,15 +220,15 @@ "effect": "recover_energy", "effect_str": "FATIGUE", "shape": "blast", - "base_casting_time": { "math": [ "channeling_proficiency_bonus_calculate(10000)" ] }, + "base_casting_time": { "math": [ "channeling_proficiency_bonus_calculate(10000, 100)" ] }, "min_damage": 50, "damage_increment": 10.0, "max_damage": 300, "max_level": 25, "extra_effects": [ { "id": "eoc_channeling_setup" } ], - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(500)" ] }, - "energy_increment": { "math": [ "channeling_proficiency_negate_calculate(25)" ] }, - "final_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(1125)" ] }, + "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(500, 5)" ] }, + "energy_increment": { "math": [ "channeling_proficiency_negate_calculate(25, 0.04)" ] }, + "final_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(1125, 5)" ] }, "difficulty": 4 }, { @@ -303,8 +303,8 @@ "max_level": 20, "difficulty": 4, "energy_source": "MANA", - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(175)" ] }, - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(550)" ] }, + "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(175, 1)" ] }, + "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(550, 2)" ] }, "extra_effects": [ { "id": "eoc_channeling_setup" } ], "flags": [ "CONCENTRATE", "VERBAL", "SOMATIC", "NO_LEGS", "NO_HANDS", "NO_PROJECTILE" ] }, @@ -319,7 +319,7 @@ "effect": "spawn_item", "effect_str": "rune_druid", "shape": "blast", - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(5000)" ] }, + "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(5000, 10)" ] }, "base_energy_cost": 5, "min_duration": 1, "max_duration": 2, @@ -369,8 +369,8 @@ "spell_class": "DRUID", "energy_source": "HP", "difficulty": 6, - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(600)" ] }, - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(25)" ] }, + "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(600, 4)" ] }, + "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(25, 0.5)" ] }, "extra_effects": [ { "id": "eoc_channeling_setup" } ], "max_level": 20, "min_aoe": 1, @@ -392,10 +392,10 @@ "spell_class": "DRUID", "energy_source": "HP", "difficulty": 5, - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(400)" ] }, - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(35)" ] }, - "final_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(20)" ] }, - "energy_increment": { "math": [ "channeling_proficiency_negate_calculate(-1.5)" ] }, + "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(400, 3.5)" ] }, + "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(35, 0.5)" ] }, + "final_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(20, 0.5)" ] }, + "energy_increment": { "math": [ "channeling_proficiency_negate_calculate(-1.5, 0.1)" ] }, "extra_effects": [ { "id": "eoc_channeling_setup" } ], "max_level": 10, "min_damage": -4, @@ -541,10 +541,10 @@ "energy_source": "MANA", "spell_class": "DRUID", "difficulty": 4, - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(12000)" ] }, - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(250)" ] }, - "final_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(400)" ] }, - "energy_increment": { "math": [ "channeling_proficiency_negate_calculate(10)" ] }, + "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(12000, 100)" ] }, + "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(250, 4)" ] }, + "final_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(400, 4)" ] }, + "energy_increment": { "math": [ "channeling_proficiency_negate_calculate(10, 0.07)" ] }, "extra_effects": [ { "id": "eoc_channeling_setup" } ], "max_level": 20, "min_duration": 30000, @@ -631,12 +631,12 @@ "energy_source": "MANA", "difficulty": 8, "damage_type": "necrotic", - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(10000)" ] }, - "final_casting_time": { "math": [ "channeling_proficiency_negate_calculate(500)" ] }, - "casting_time_increment": { "math": [ "channeling_proficiency_negate_calculate(-380)" ] }, - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(1000)" ] }, - "final_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(400)" ] }, - "energy_increment": { "math": [ "channeling_proficiency_negate_calculate(-24)" ] }, + "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(10000, 10)" ] }, + "final_casting_time": { "math": [ "channeling_proficiency_negate_calculate(500, 10)" ] }, + "casting_time_increment": { "math": [ "channeling_proficiency_negate_calculate(-380, 0.04)" ] }, + "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(1000, 5)" ] }, + "final_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(400, 5)" ] }, + "energy_increment": { "math": [ "channeling_proficiency_negate_calculate(-24, 0.04)" ] }, "min_aoe": 5, "max_aoe": 50, "aoe_increment": 1.8, @@ -696,12 +696,12 @@ "energy_source": "MANA", "spell_class": "DRUID", "difficulty": 8, - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(12000)" ] }, - "final_casting_time": { "math": [ "channeling_proficiency_negate_calculate(3000)" ] }, - "casting_time_increment": { "math": [ "channeling_proficiency_negate_calculate(-360)" ] }, - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(800)" ] }, - "final_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(500)" ] }, - "energy_increment": { "math": [ "channeling_proficiency_negate_calculate(-12)" ] }, + "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(12000, 15)" ] }, + "final_casting_time": { "math": [ "channeling_proficiency_negate_calculate(3000, 15)" ] }, + "casting_time_increment": { "math": [ "channeling_proficiency_negate_calculate(-360, 0.04)" ] }, + "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(800, 5)" ] }, + "final_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(500, 5)" ] }, + "energy_increment": { "math": [ "channeling_proficiency_negate_calculate(-12, 0.04)" ] }, "extra_effects": [ { "id": "eoc_channeling_setup" } ], "max_level": 25, "//": "each 3000 (30 second) heal 1 hp. 5 hp on level 0 (2.5m), 30 hp on level 25 (15 m)", @@ -756,10 +756,10 @@ "max_damage": -20, "damage_increment": -1, "difficulty": 5, - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(800)" ] }, - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(400)" ] }, - "final_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(150)" ] }, - "energy_increment": { "math": [ "channeling_proficiency_negate_calculate(-16.7)" ] }, + "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(800, 5)" ] }, + "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(400, 2)" ] }, + "final_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(150, 2)" ] }, + "energy_increment": { "math": [ "channeling_proficiency_negate_calculate(-16.7, 0.07)" ] }, "extra_effects": [ { "id": "eoc_channeling_setup" } ], "max_level": 15 }, @@ -776,8 +776,8 @@ "effect_str": "druid_bandages", "components": "spell_components_druid_bandage", "shape": "blast", - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(400)" ] }, - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(450)" ] }, + "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(400, 5)" ] }, + "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(450, 5)" ] }, "extra_effects": [ { "id": "eoc_channeling_setup" } ], "min_duration": 48000, "max_duration": 720000, @@ -801,12 +801,12 @@ "spell_class": "DRUID", "difficulty": 6, "max_level": 15, - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(6000)" ] }, - "final_casting_time": { "math": [ "channeling_proficiency_negate_calculate(1000)" ] }, - "casting_time_increment": { "math": [ "channeling_proficiency_negate_calculate(-350)" ] }, - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(800)" ] }, - "final_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(500)" ] }, - "energy_increment": { "math": [ "channeling_proficiency_negate_calculate(-40)" ] }, + "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(6000, 10)" ] }, + "final_casting_time": { "math": [ "channeling_proficiency_negate_calculate(1000, 10)" ] }, + "casting_time_increment": { "math": [ "channeling_proficiency_negate_calculate(-350, 0.07)" ] }, + "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(800, 5)" ] }, + "final_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(500, 5)" ] }, + "energy_increment": { "math": [ "channeling_proficiency_negate_calculate(-40, 0.133)" ] }, "extra_effects": [ { "id": "eoc_channeling_setup" } ], "min_duration": 6000, "max_duration": 6000 @@ -853,10 +853,10 @@ "final_casting_time": 600, "casting_time_increment": -360, "energy_source": "MANA", - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(250)" ] }, - "min_duration": { "math": [ "channeling_proficiency_bonus_calculate(180000)" ] }, - "max_duration": { "math": [ "channeling_proficiency_bonus_calculate(1440000)" ] }, - "duration_increment": { "math": [ "channeling_proficiency_bonus_calculate(84000)" ] }, + "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(250, 4)" ] }, + "min_duration": { "math": [ "channeling_proficiency_bonus_calculate(180000, 1000)" ] }, + "max_duration": { "math": [ "channeling_proficiency_bonus_calculate(1440000, 1000)" ] }, + "duration_increment": { "math": [ "channeling_proficiency_bonus_calculate(84000, 0.07)" ] }, "extra_effects": [ { "id": "eoc_channeling_setup" } ] }, { @@ -1076,8 +1076,8 @@ "effect": "effect_on_condition", "effect_str": "EOC_DRUID_RENEW_FOREST_SPELL", "energy_source": "MANA", - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(1500)" ] }, - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(6000)" ] }, + "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(1500, 10)" ] }, + "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(6000, 10)" ] }, "extra_effects": [ { "id": "eoc_channeling_setup" } ] }, { @@ -1126,8 +1126,8 @@ "effect_str": "EOC_EOC_DRUID_SHAPE_WOOD", "shape": "blast", "energy_source": "MANA", - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(180000)" ] }, - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(600)" ] }, + "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(180000, 1000)" ] }, + "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(600, 5)" ] }, "extra_effects": [ { "id": "eoc_channeling_setup" } ] }, { @@ -1216,8 +1216,8 @@ "difficulty": 4, "max_level": 15, "energy_source": "MANA", - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(200)" ] }, - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(1000)" ] }, + "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(200, 1)" ] }, + "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(1000, 10)" ] }, "extra_effects": [ { "id": "eoc_channeling_setup" } ] }, { diff --git a/data/mods/Magiclysm/Spells/earthshaper.json b/data/mods/Magiclysm/Spells/earthshaper.json index 7322e7459e0a4..08602035c8c9b 100644 --- a/data/mods/Magiclysm/Spells/earthshaper.json +++ b/data/mods/Magiclysm/Spells/earthshaper.json @@ -93,13 +93,13 @@ "damage_increment": 750, "max_level": 12, "spell_class": "EARTHSHAPER", - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(500)" ] }, - "final_casting_time": { "math": [ "channeling_proficiency_negate_calculate(300)" ] }, - "casting_time_increment": { "math": [ "channeling_proficiency_negate_calculate(-17)" ] }, + "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(500, 3)" ] }, + "final_casting_time": { "math": [ "channeling_proficiency_negate_calculate(300, 3)" ] }, + "casting_time_increment": { "math": [ "channeling_proficiency_negate_calculate(-17, 0.085)" ] }, "energy_source": "MANA", - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(150)" ] }, - "energy_increment": { "math": [ "channeling_proficiency_negate_calculate(75)" ] }, - "final_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(1000)" ] }, + "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(150, 5)" ] }, + "energy_increment": { "math": [ "channeling_proficiency_negate_calculate(75, 0.09)" ] }, + "final_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(1000, 5)" ] }, "difficulty": 5, "extra_effects": [ { "id": "eoc_channeling_setup" } ] }, @@ -220,15 +220,15 @@ "max_damage": 1, "damage_increment": -5, "aoe_increment": 0.25, - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(200)" ] }, + "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(200, 2)" ] }, "spell_class": "EARTHSHAPER", "difficulty": 4, "max_level": 20, "min_range": 5, "max_range": 5, - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(1200)" ] }, - "final_casting_time": { "math": [ "channeling_proficiency_negate_calculate(200)" ] }, - "casting_time_increment": { "math": [ "channeling_proficiency_negate_calculate(-50)" ] }, + "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(1200, 3)" ] }, + "final_casting_time": { "math": [ "channeling_proficiency_negate_calculate(200, 3)" ] }, + "casting_time_increment": { "math": [ "channeling_proficiency_negate_calculate(-50, 0.05)" ] }, "energy_source": "MANA", "shape": "blast", "effect": "ter_transform", @@ -245,7 +245,7 @@ "effect": "spawn_item", "effect_str": "rune_earthshaper", "shape": "blast", - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(5000)" ] }, + "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(5000, 10)" ] }, "extra_effects": [ { "id": "eoc_channeling_setup" } ], "base_energy_cost": 5, "min_duration": 1, @@ -272,8 +272,8 @@ "max_aoe": 13, "aoe_increment": 0.5, "spell_class": "EARTHSHAPER", - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(350)" ] }, - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(750)" ] }, + "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(350, 5)" ] }, + "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(750, 5)" ] }, "energy_source": "MANA", "difficulty": 4, "field_id": "fd_clairvoyant", @@ -345,10 +345,10 @@ "spell_class": "EARTHSHAPER", "energy_source": "MANA", "difficulty": 3, - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(30000)" ] }, - "final_casting_time": { "math": [ "channeling_proficiency_negate_calculate(6000)" ] }, - "casting_time_increment": { "math": [ "channeling_proficiency_negate_calculate(-2400)" ] }, - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(500)" ] }, + "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(30000, 50)" ] }, + "final_casting_time": { "math": [ "channeling_proficiency_negate_calculate(6000, 50)" ] }, + "casting_time_increment": { "math": [ "channeling_proficiency_negate_calculate(-2400, 0.1)" ] }, + "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(500, 5)" ] }, "max_level": 10, "min_range": 3, "max_range": 6, @@ -939,8 +939,8 @@ "energy_source": "MANA", "difficulty": 3, "max_level": 10, - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(400)" ] }, - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(350)" ] }, + "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(400, 5)" ] }, + "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(350, 3)" ] }, "min_duration": 0, "max_duration": 300000, "duration_increment": 30000 @@ -1007,10 +1007,10 @@ "difficulty": 2, "effect": "ter_transform", "effect_str": "earthshaper_turning_earth", - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(1500)" ] }, - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(800)" ] }, - "final_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(350)" ] }, - "energy_increment": { "math": [ "channeling_proficiency_negate_calculate(-37.5)" ] }, + "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(1500, 5)" ] }, + "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(800, 3)" ] }, + "final_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(350, 3)" ] }, + "energy_increment": { "math": [ "channeling_proficiency_negate_calculate(-37.5, 0.083)" ] }, "min_range": 3, "max_range": 20, "range_increment": 1.2 @@ -1128,8 +1128,8 @@ "max_range": 20, "range_increment": 1, "energy_source": "MANA", - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(200)" ] }, - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(1500)" ] } + "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(200, 2.5)" ] }, + "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(1500, 10)" ] } }, { "id": "earthshaper_sleep_in_earth", @@ -1234,10 +1234,10 @@ "difficulty": 4, "max_level": 20, "energy_source": "MANA", - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(600)" ] }, - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(360000)" ] }, - "final_casting_time": { "math": [ "channeling_proficiency_negate_calculate(90000)" ] }, - "casting_time_increment": { "math": [ "channeling_proficiency_negate_calculate(-13500)" ] } + "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(600, 5)" ] }, + "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(360000, 400)" ] }, + "final_casting_time": { "math": [ "channeling_proficiency_negate_calculate(90000, 400)" ] }, + "casting_time_increment": { "math": [ "channeling_proficiency_negate_calculate(-13500, 0.05)" ] } }, { "type": "effect_on_condition", diff --git a/data/mods/Magiclysm/Spells/kelvinist.json b/data/mods/Magiclysm/Spells/kelvinist.json index 115c48234f453..f73b7405816d5 100644 --- a/data/mods/Magiclysm/Spells/kelvinist.json +++ b/data/mods/Magiclysm/Spells/kelvinist.json @@ -428,7 +428,7 @@ "effect_str": "rune_kelvinist", "extra_effects": [ { "id": "eoc_channeling_setup" } ], "shape": "blast", - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(5000)" ] }, + "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(5000, 70)" ] }, "base_energy_cost": 5, "min_duration": 1, "max_duration": 2, @@ -682,8 +682,8 @@ "max_duration": 327240000, "duration_increment": 18360000, "energy_source": "MANA", - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(400)" ] }, - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(1500)" ] } + "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(400, 5)" ] }, + "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(1500, 10)" ] } }, { "id": "kelvinist_no_emotion_spell", @@ -751,10 +751,10 @@ "difficulty": 1, "max_level": 15, "energy_source": "MANA", - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(200)" ] }, - "final_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(50)" ] }, - "energy_increment": { "math": [ "channeling_proficiency_negate_calculate(-10)" ] }, - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(750)" ] } + "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(200, 0.5)" ] }, + "final_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(50, 0.5)" ] }, + "energy_increment": { "math": [ "channeling_proficiency_negate_calculate(-10, 0.07)" ] }, + "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(750, 5)" ] } }, { "type": "effect_on_condition", diff --git a/data/mods/Magiclysm/Spells/magus.json b/data/mods/Magiclysm/Spells/magus.json index 541a38e0bbf63..77a1d9b1d1b7e 100644 --- a/data/mods/Magiclysm/Spells/magus.json +++ b/data/mods/Magiclysm/Spells/magus.json @@ -288,7 +288,7 @@ "effect_str": "rune_magus", "shape": "blast", "extra_effects": [ { "id": "eoc_channeling_setup" } ], - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(5000)" ] }, + "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(5000, 10)" ] }, "base_energy_cost": 5, "min_duration": 1, "max_duration": 2, @@ -688,8 +688,8 @@ "difficulty": 8, "max_level": 15, "energy_source": "MANA", - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(900)" ] }, - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(180000)" ] } + "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(900, 5)" ] }, + "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(180000, 1500)" ] } }, { "type": "effect_on_condition", diff --git a/data/mods/Magiclysm/Spells/mana_upgrades.json b/data/mods/Magiclysm/Spells/mana_upgrades.json index 94241cfe0d12d..5a16770849dc6 100644 --- a/data/mods/Magiclysm/Spells/mana_upgrades.json +++ b/data/mods/Magiclysm/Spells/mana_upgrades.json @@ -14,8 +14,8 @@ "difficulty": 6, "max_level": 15, "energy_source": "MANA", - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(800)" ] }, - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(2520000)" ] } + "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(800, 10)" ] }, + "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(2520000, 2000)" ] } }, { "type": "effect_on_condition", @@ -72,8 +72,8 @@ "difficulty": 9, "max_level": 15, "energy_source": "MANA", - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(1400)" ] }, - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(3960000)" ] } + "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(1400, 10)" ] }, + "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(3960000, 2000)" ] } }, { "type": "effect_on_condition", @@ -137,8 +137,8 @@ "difficulty": 6, "max_level": 15, "energy_source": "MANA", - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(800)" ] }, - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(2520000)" ] } + "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(800, 10)" ] }, + "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(2520000, 2000)" ] } }, { "type": "effect_on_condition", @@ -207,8 +207,8 @@ "difficulty": 9, "max_level": 15, "energy_source": "MANA", - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(1400)" ] }, - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(3960000)" ] } + "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(1400, 10)" ] }, + "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(3960000, 2000)" ] } }, { "type": "effect_on_condition", @@ -294,8 +294,8 @@ "difficulty": 6, "max_level": 15, "energy_source": "MANA", - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(800)" ] }, - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(2520000)" ] } + "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(800, 10)" ] }, + "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(2520000, 2000)" ] } }, { "type": "effect_on_condition", @@ -372,8 +372,8 @@ "difficulty": 9, "max_level": 15, "energy_source": "MANA", - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(1400)" ] }, - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(3960000)" ] } + "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(1400, 10)" ] }, + "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(3960000, 2000)" ] } }, { "type": "effect_on_condition", diff --git a/data/mods/Magiclysm/Spells/stormshaper.json b/data/mods/Magiclysm/Spells/stormshaper.json index a586fbf96c6d2..a4f4a46dc9f91 100644 --- a/data/mods/Magiclysm/Spells/stormshaper.json +++ b/data/mods/Magiclysm/Spells/stormshaper.json @@ -231,7 +231,7 @@ "effect_str": "rune_stormshaper", "extra_effects": [ { "id": "eoc_channeling_setup" } ], "shape": "blast", - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(5000)" ] }, + "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(5000, 15)" ] }, "base_energy_cost": 5, "min_duration": 1, "max_duration": 2, @@ -259,7 +259,7 @@ "min_range": 6, "max_range": 12, "range_increment": 0.2, - "damage_increment": 3, + "damage_increment": { "math": [ "evocation_proficiency_bonus_calculate(3)" ] }, "difficulty": 10, "spell_class": "STORMSHAPER", "energy_source": "MANA", @@ -288,7 +288,7 @@ "min_range": 6, "max_range": 8, "range_increment": 0.01, - "damage_increment": 4, + "damage_increment": { "math": [ "evocation_proficiency_bonus_calculate(4)" ] }, "difficulty": 20, "spell_class": "STORMSHAPER", "energy_source": "MANA", diff --git a/data/mods/Magiclysm/Spells/technomancer.json b/data/mods/Magiclysm/Spells/technomancer.json index bdc9f9b1d641f..027d2a7e3bbc4 100644 --- a/data/mods/Magiclysm/Spells/technomancer.json +++ b/data/mods/Magiclysm/Spells/technomancer.json @@ -192,9 +192,9 @@ "min_damage": 250, "damage_increment": 50.0, "max_damage": 15000, - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(250)" ] }, - "energy_increment": { "math": [ "channeling_proficiency_negate_calculate(50.0)" ] }, - "final_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(15000)" ] }, + "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(250, 3)" ] }, + "energy_increment": { "math": [ "channeling_proficiency_negate_calculate(50.0, 0.0034)" ] }, + "final_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(15000, 3)" ] }, "max_level": 25, "spell_class": "TECHNOMANCER", "effect": "recover_energy", @@ -202,7 +202,7 @@ "shape": "blast", "energy_source": "MANA", "difficulty": 6, - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(1000)" ] } + "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(1000, 10)" ] } }, { "id": "create_rune_technomancer", @@ -216,7 +216,7 @@ "effect_str": "rune_technomancer", "extra_effects": [ { "id": "eoc_channeling_setup" } ], "shape": "blast", - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(5000)" ] }, + "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(5000, 10)" ] }, "base_energy_cost": 5, "min_duration": 1, "max_duration": 2, @@ -572,10 +572,10 @@ "flags": [ "NO_LEGS", "SOMATIC", "CONCENTRATE", "NO_PROJECTILE" ], "extra_effects": [ { "id": "eoc_channeling_setup" } ], "max_level": 15, - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(1200)" ] }, - "final_casting_time": { "math": [ "channeling_proficiency_negate_calculate(1050)" ] }, - "casting_time_increment": { "math": [ "channeling_proficiency_negate_calculate(-10)" ] }, - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(350)" ] }, + "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(1200, 6)" ] }, + "final_casting_time": { "math": [ "channeling_proficiency_negate_calculate(1050, 6)" ] }, + "casting_time_increment": { "math": [ "channeling_proficiency_negate_calculate(-10, 0.07)" ] }, + "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(350, 5)" ] }, "difficulty": 3, "min_range": 1, "max_range": 4, @@ -595,10 +595,10 @@ "flags": [ "NO_LEGS", "SOMATIC", "CONCENTRATE", "NO_PROJECTILE" ], "extra_effects": [ { "id": "eoc_channeling_setup" } ], "max_level": 15, - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(2600)" ] }, - "final_casting_time": { "math": [ "channeling_proficiency_negate_calculate(2375)" ] }, - "casting_time_increment": { "math": [ "channeling_proficiency_negate_calculate(-15)" ] }, - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(800)" ] }, + "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(2600, 6)" ] }, + "final_casting_time": { "math": [ "channeling_proficiency_negate_calculate(2375, 6)" ] }, + "casting_time_increment": { "math": [ "channeling_proficiency_negate_calculate(-15, 0.07)" ] }, + "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(800, 5)" ] }, "difficulty": 7, "min_range": 6, "max_range": 6, @@ -802,8 +802,8 @@ "damage_increment": 2350, "min_range": 1, "energy_source": "MANA", - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(500)" ] }, - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(6000)" ] } + "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(500, 5)" ] }, + "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(6000, 12)" ] } }, { "id": "technomancer_gain_electronics_computer_spell", @@ -843,8 +843,8 @@ "difficulty": 6, "max_level": 15, "energy_source": "MANA", - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(600)" ] }, - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(720000)" ] } + "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(600, 5)" ] }, + "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(720000, 500)" ] } }, { "type": "effect_on_condition", diff --git a/data/mods/Magiclysm/jmath.json b/data/mods/Magiclysm/jmath.json index 180e8901e8694..a13d2415b6c14 100644 --- a/data/mods/Magiclysm/jmath.json +++ b/data/mods/Magiclysm/jmath.json @@ -14,14 +14,14 @@ { "type": "jmath_function", "id": "channeling_proficiency_negate_calculate", - "num_args": 1, - "return": "_0 - ((u_proficiency('prof_magic_channel_beginner', 'format': 'percent') * 1) / 10) - ((u_proficiency('prof_magic_channel_apprentice', 'format': 'percent') * 1) / 10) - ((u_proficiency('prof_magic_channel_master', 'format': 'percent') * 1) / 10)" + "num_args": 2, + "return": "_0 - (((((u_proficiency('prof_magic_channel_beginner', 'format': 'percent') * 1) / 10) + ((u_proficiency('prof_magic_channel_apprentice', 'format': 'percent') * 1) / 10) + ((u_proficiency('prof_magic_channel_master', 'format': 'percent') * 1) / 10))) * _1 )" }, { "type": "jmath_function", "id": "channeling_proficiency_bonus_calculate", - "num_args": 1, - "return": "_0 + ((u_proficiency('prof_magic_channel_beginner', 'format': 'percent') * 1) / 10) + ((u_proficiency('prof_magic_channel_apprentice', 'format': 'percent') * 1) / 10) + ((u_proficiency('prof_magic_channel_master', 'format': 'percent') * 1) / 10)" + "num_args": 2, + "return": "_0 + (((((u_proficiency('prof_magic_channel_beginner', 'format': 'percent') * 1) / 10) + ((u_proficiency('prof_magic_channel_apprentice', 'format': 'percent') * 1) / 10) + ((u_proficiency('prof_magic_channel_master', 'format': 'percent') * 1) / 10))) * _1 )" }, { "type": "jmath_function", diff --git a/data/mods/Magiclysm/worldgen/regional_overlay.json b/data/mods/Magiclysm/worldgen/regional_overlay.json index 37c152463fbef..961b518c91c18 100644 --- a/data/mods/Magiclysm/worldgen/regional_overlay.json +++ b/data/mods/Magiclysm/worldgen/regional_overlay.json @@ -62,150 +62,52 @@ "forest_mapgen_settings": { "forest_thick": { "terrains": [ - "forest_thick", - "forest_trail_isolated", - "forest_trail_end_north", - "forest_trail_end_east", - "forest_trail_end_south", - "forest_trail_end_west", - "forest_trail_ns", - "forest_trail_ew", - "forest_trail_ne", - "forest_trail_es", - "forest_trail_sw", - "forest_trail_wn", - "forest_trail_new", - "forest_trail_nsw", - "forest_trail_esw", - "forest_trail_nes", - "forest_trail_nesw", - "campsite_north", - "campsite_south", - "campsite_east", - "campsite_west", - "campsite_cabin_incomplete_north", - "campsite_cabin_incomplete_south", - "campsite_cabin_incomplete_east", - "campsite_cabin_incomplete_west", - "campsite_field_biker_north", - "campsite_field_biker_south", - "campsite_field_biker_east", - "campsite_field_biker_west", - "campsite_field_biker_destroyed_north", - "campsite_field_biker_destroyed_south", - "campsite_field_biker_destroyed_east", - "campsite_field_biker_destroyed_west", - "campsite_a_north", - "campsite_a_south", - "campsite_a_east", - "campsite_a_west", - "desolatebarn_north", - "desolatebarn_south", - "desolatebarn_east", - "desolatebarn_west", - "derelict_property_north", - "derelict_property_south", - "derelict_property_east", - "derelict_property_west", - "druid_ritual_home_z0_north", - "druid_ritual_home_z0_west", - "druid_ritual_home_z0_east", - "druid_ritual_home_z0_south", - "homelesscamp_north", - "homelesscamp_south", - "homelesscamp_east", - "homelesscamp_west", - "spider_pit_north", - "spider_pit_south", - "spider_pit_east", - "spider_pit_west", - "survivor_forest_camp_north", - "survivor_forest_camp_south", - "survivor_forest_camp_east", - "survivor_forest_camp_west", - "central_lab_entrance", - "moonshine_still_north", - "moonshine_still_south", - "moonshine_still_east", - "moonshine_still_west", - "moonshine_still_1_north", - "moonshine_still_1_south", - "moonshine_still_1_east", - "moonshine_still_1_west", - "moonshine_still_2_north", - "moonshine_still_2_south", - "moonshine_still_2_east", - "moonshine_still_2_west", - "standing_stones", - "ws_survivor_bunker_f0_north", - "ws_survivor_bunker_f0_south", - "ws_survivor_bunker_f0_east", - "ws_survivor_bunker_f0_west", - "bandit_cabin_north", - "bandit_cabin_south", - "bandit_cabin_east", - "bandit_cabin_west", - "bandit_garage_1_north", - "bandit_garage_1_south", - "bandit_garage_1_east", - "bandit_garage_1_west", - "bandit_garage_2_north", - "bandit_garage_2_south", - "bandit_garage_2_east", - "bandit_garage_2_west", - "natural_spring_north", - "natural_spring_south", - "natural_spring_east", - "natural_spring_west", + "anthill", + "bandit_cabin", + "bandit_garage_1", + "bandit_garage_2", + "campsite", + "campsite_a", + "campsite_cabin_incomplete", + "campsite_field_biker", + "campsite_field_biker_destroyed", "cave", - "special_forest_thick", - "island_forest_north", - "island_forest_east", - "island_forest_south", - "island_forest_west", - "island_forest_thick_north", - "island_forest_thick_east", - "island_forest_thick_south", - "island_forest_thick_west", + "central_lab_entrance", + "corpse_tentacle_surface_entry", + "derelict_property", + "desolatebarn", + "druid_ritual_home_z0", + "forest_thick", + "forest_trail", + "forest_trail_intersection", + "homelesscamp", + "island_forest", + "island_forest_thick", "lake_shore", + "moonshine_still", + "moonshine_still_1", + "moonshine_still_2", + "natural_spring", + "river", + "river_c_not_ne", + "river_c_not_nw", + "river_c_not_se", + "river_c_not_sw", "river_center", - "river_north", - "river_east", - "river_south", - "river_west", "river_ne", + "river_nw", "river_se", "river_sw", - "river_nw", - "river_c_not_ne", - "river_c_not_se", - "river_c_not_sw", - "river_c_not_nw", - "stream_north", - "stream_east", - "stream_south", - "stream_west", - "stream_corner_north", - "stream_corner_east", - "stream_corner_south", - "stream_corner_west", - "stream_end_north", - "stream_end_east", - "stream_end_south", - "stream_end_west", "slimepit_top", - "anthill_north", - "anthill_east", - "anthill_south", - "anthill_west", - "corpse_tentacle_surface_entry_north", - "corpse_tentacle_surface_entry_east", - "corpse_tentacle_surface_entry_south", - "corpse_tentacle_surface_entry_west", - "ws_giant_sinkhole_1_north", - "ws_giant_sinkhole_1_east", - "ws_giant_sinkhole_1_south", - "ws_giant_sinkhole_1_west" + "special_forest_thick", + "spider_pit", + "standing_stones", + "stream", + "stream_corner", + "stream_end", + "survivor_forest_camp", + "ws_giant_sinkhole_1", + "ws_survivor_bunker_f0" ] } } diff --git a/data/mods/MindOverMatter/effectoncondition/eoc_misc.json b/data/mods/MindOverMatter/effectoncondition/eoc_misc.json index 48177d540379a..46719a620c99a 100644 --- a/data/mods/MindOverMatter/effectoncondition/eoc_misc.json +++ b/data/mods/MindOverMatter/effectoncondition/eoc_misc.json @@ -1,4 +1,28 @@ [ + { + "type": "effect_on_condition", + "id": "EOC_PORTAL_STORM_CONDITION_FLAG_PORTAL_PROOF", + "condition": { + "and": [ + { "not": { "u_has_worn_with_flag": "PORTAL_PROOF" } }, + { + "not": { + "and": [ + { "u_has_effect": "effect_telepathic_psi_armor" }, + { + "math": [ + "u_spell_level('telepathic_shield')", + ">=", + "(u_vitamin('vitamin_psionic_drain') / 10) + (max(u_school_level('BIOKINETIC'), u_school_level('CLAIRSENTIENT'), u_school_level('ELECTROKINETIC'), u_school_level('PHOTOKINETIC'), u_school_level('PYROKINETIC'), u_school_level('TELEPATH'), u_school_level('TELEKINETIC'), u_school_level('TELEPORTER'), u_school_level('VITAKINETIC')) / 3) + (u_awakening_countup / 3)" + ] + } + ] + } + } + ] + }, + "effect": [ ] + }, { "type": "effect_on_condition", "id": "EOC_RESET_TELEPATHIC_STEALING_TIMER", diff --git a/data/mods/MindOverMatter/effectoncondition/eoc_power_effects.json b/data/mods/MindOverMatter/effectoncondition/eoc_power_effects.json index 1218117a6270d..8ba59b53f691e 100644 --- a/data/mods/MindOverMatter/effectoncondition/eoc_power_effects.json +++ b/data/mods/MindOverMatter/effectoncondition/eoc_power_effects.json @@ -1,4 +1,37 @@ [ + { + "type": "effect_on_condition", + "id": "EOC_PAIN_DISABLES_PSI", + "eoc_type": "EVENT", + "required_event": "opens_spellbook", + "condition": { + "and": [ + { + "u_has_any_trait": [ + "BIOKINETIC", + "CLAIRSENTIENT", + "ELECTROKINETIC", + "PHOTOKINETIC", + "PYROKINETIC", + "TELEKINETIC", + "TELEPATH", + "TELEPORTER", + "VITAKINETIC" + ] + }, + { "not": { "u_has_flag": "PAIN_IMMUNE" } }, + { "not": { "u_has_effect": "effect_psi_too_much_pain_cant_channel" } }, + { + "math": [ + "u_pain()", + ">=", + "40 + ( 15 * ((u_has_trait('CONCENTRATION_GOOD')) + (u_has_trait('CONCENTRATION_BAD') ? -1 : 0) + (u_has_trait('INT_ALPHA')) + (u_has_trait('CONCENTRATION_DEBUG') ? 50 : 0) + (u_has_proficiency('prof_concentration_basic') ? 1 : 0) + (u_has_proficiency('prof_concentration_intermediate') ? 2 : 0) + (u_has_proficiency('prof_concentration_master') ? 3 : 0)))" + ] + } + ] + }, + "effect": [ { "u_add_effect": "effect_psi_too_much_pain_cant_channel", "duration": "0 seconds" } ] + }, { "type": "effect_on_condition", "id": "EOC_BIOKIN_MATRIX_BOOST", diff --git a/data/mods/MindOverMatter/effects/effects_penalty.json b/data/mods/MindOverMatter/effects/effects_penalty.json index 9278bf316eb93..211d019f3cd15 100644 --- a/data/mods/MindOverMatter/effects/effects_penalty.json +++ b/data/mods/MindOverMatter/effects/effects_penalty.json @@ -42,10 +42,11 @@ "per_mod": [ -1 ], "pain_chance": [ 100 ], "pain_min": [ 1 ], - "pain_max": [ 2 ], - "pain_max_val": [ 40 ], + "pain_max": [ 1 ], + "pain_max_val": [ 20 ], "pain_tick": [ 200 ], "vomit_chance": [ 100 ], + "vomit_tick": [ 200 ], "hurt_chance": [ 300 ], "hurt_amount": [ 0 ], "hurt_tick": [ 200 ] @@ -55,7 +56,7 @@ "int_mod": [ -0.6 ], "pain_min": [ 0 ], "pain_max": [ 0 ], - "pain_max_val": [ 20 ], + "pain_max_val": [ 5 ], "vomit_chance": [ -2 ], "hurt_chance": [ -5 ], "hurt_amount": [ 2, 1 ], @@ -213,6 +214,15 @@ "max_duration": "24 hours", "flags": [ "NO_PSIONICS" ] }, + { + "type": "effect_type", + "id": "effect_psi_too_much_pain_cant_channel", + "name": [ "Can't Concentrate" ], + "desc": [ "You can't use your powers." ], + "apply_message": "You're in so much pain you can't concentrate to use your powers!", + "rating": "bad", + "flags": [ "NO_PSIONICS" ] + }, { "type": "effect_type", "id": "effect_psi_reduced_breathing", diff --git a/data/mods/MindOverMatter/effects/effects_psionic.json b/data/mods/MindOverMatter/effects/effects_psionic.json index 97e4049e218bc..95380921acd45 100644 --- a/data/mods/MindOverMatter/effects/effects_psionic.json +++ b/data/mods/MindOverMatter/effects/effects_psionic.json @@ -1657,7 +1657,7 @@ "psi_stunned", "telepathic_ignorance" ], - "flags": [ "PORTAL_PROOF", "TEEPSHIELD" ] + "flags": [ "TEEPSHIELD" ] }, { "type": "effect_type", diff --git a/data/mods/MindOverMatter/items/ammo.json b/data/mods/MindOverMatter/items/ammo.json index f61901a14d53c..4ce33cbb18284 100644 --- a/data/mods/MindOverMatter/items/ammo.json +++ b/data/mods/MindOverMatter/items/ammo.json @@ -11,6 +11,12 @@ "name": "matrix charge", "default": "psionic_charge_power" }, + { + "type": "ammunition_type", + "id": "noetic_charge_power", + "name": "noetic energy", + "default": "noetic_charge_power" + }, { "id": "mom_pulse_rifle_ammo", "type": "AMMO", @@ -46,5 +52,13 @@ "ammo_type": "psionic_charge_power", "material": [ "nether_crystal" ], "count": 100 + }, + { + "type": "AMMO", + "id": "noetic_charge_power", + "copy-from": "psionic_charge_power", + "name": { "str_sp": "noetic energy" }, + "ammo_type": "noetic_charge_power", + "description": "Power charge for psychic phenomena." } ] diff --git a/data/mods/MindOverMatter/items/armor/head.json b/data/mods/MindOverMatter/items/armor/head.json index 794fd0cd9e8f4..abe3ecb261c46 100644 --- a/data/mods/MindOverMatter/items/armor/head.json +++ b/data/mods/MindOverMatter/items/armor/head.json @@ -35,6 +35,6 @@ "armor": [ { "encumbrance": 4, "coverage": 100, "covers": [ "head" ], "specifically_covers": [ "head_crown", "head_forehead" ] } ], - "flags": [ "PADDED" ] + "flags": [ "PADDED", "PORTAL_PROOF" ] } ] diff --git a/data/mods/MindOverMatter/items/armor/overrides.json b/data/mods/MindOverMatter/items/armor/overrides.json new file mode 100644 index 0000000000000..c5293464404ff --- /dev/null +++ b/data/mods/MindOverMatter/items/armor/overrides.json @@ -0,0 +1,18 @@ +[ + { + "id": "dimensional_anchor", + "copy-from": "dimensional_anchor", + "type": "TOOL_ARMOR", + "category": "clothing", + "name": { "str": "5-point anchor" }, + "relic_data": { "passive_effects": [ { "has": "WORN", "condition": "ACTIVE", "mutations": [ "ANCHORCROWN_NOSPELL" ] } ] } + }, + { + "id": "dimensional_anchor_on", + "copy-from": "dimensional_anchor_on", + "type": "TOOL_ARMOR", + "category": "clothing", + "name": { "str": "5-point anchor (on)", "str_pl": "5-point anchors (on)" }, + "relic_data": { "passive_effects": [ { "has": "WORN", "condition": "ACTIVE", "mutations": [ "ANCHORCROWN_NOSPELL" ] } ] } + } +] diff --git a/data/mods/MindOverMatter/items/psions_summon_items.json b/data/mods/MindOverMatter/items/psions_summon_items.json index c9b053e879d46..d1ad1b6ef5a6d 100644 --- a/data/mods/MindOverMatter/items/psions_summon_items.json +++ b/data/mods/MindOverMatter/items/psions_summon_items.json @@ -310,9 +310,55 @@ "price_postapoc": 1, "symbol": "$", "color": "red", - "flags": [ "PERSONAL", "PADDED", "UNBREAKABLE", "INTEGRATED", "SEMITANGIBLE", "ZERO_WEIGHT", "LIGHT_50", "FIRE", "NO_DROP" ], + "flags": [ + "PERSONAL", + "PADDED", + "UNBREAKABLE", + "INTEGRATED", + "SEMITANGIBLE", + "ZERO_WEIGHT", + "LIGHT_50", + "FIRE", + "NO_DROP", + "NO_UNLOAD", + "NO_RELOAD" + ], + "pocket_data": [ { "pocket_type": "MAGAZINE", "ammo_restriction": { "noetic_charge_power": 1 } } ], + "charges_per_use": 0, "qualities": [ [ "WELD", 2 ] ], - "use_action": [ { "type": "firestarter", "moves": 10 }, { "type": "OXYTORCH" } ], + "use_action": [ + { "type": "firestarter", "moves": 10 }, + { "type": "OXYTORCH" }, + { + "type": "repair_item", + "item_action_type": "repair_metal", + "materials": [ + "iron", + "steel", + "aluminum", + "copper", + "bronze", + "fancy_bronze", + "silver", + "gold", + "budget_steel", + "lc_steel", + "mc_steel", + "hc_steel", + "ch_steel", + "lc_steel_chain", + "mc_steel_chain", + "hc_steel_chain", + "ch_steel_chain", + "platinum", + "superalloy" + ], + "skill": "fabrication", + "tool_quality": 10, + "cost_scaling": 0, + "move_cost": 500 + } + ], "armor": [ { "encumbrance": 0, "coverage": 0, "covers": [ "hand_l", "hand_r" ] } ] }, { @@ -1321,31 +1367,6 @@ "name": { "str": "[Ψ]telekinetic jack" }, "qualities": [ [ "JACK", 20 ], [ "LIFT", 20 ] ] }, - { - "id": "telepath_mind_shield_item", - "type": "TOOL_ARMOR", - "name": { "str_sp": "[Ψ]telepathic shield" }, - "description": "Your mind is like a fortress.", - "weight": "0 g", - "volume": "0 L", - "price": 1, - "price_postapoc": 1, - "symbol": "[", - "color": "pink", - "flags": [ - "PERSONAL", - "UNBREAKABLE", - "ZERO_WEIGHT", - "ALLOWS_NATURAL_ATTACKS", - "INTEGRATED", - "PADDED", - "SEMITANGIBLE", - "PORTAL_PROOF", - "WATER_FRIENDLY", - "ONLY_ONE", - "NO_DROP" - ] - }, { "id": "vita_bandage_01", "type": "GENERIC", diff --git a/data/mods/MindOverMatter/mapgen/map_extras/alien_flora_varieties.json b/data/mods/MindOverMatter/mapgen/map_extras/alien_flora_varieties.json index 54f7db6d6bc20..bbcad8604f25b 100644 --- a/data/mods/MindOverMatter/mapgen/map_extras/alien_flora_varieties.json +++ b/data/mods/MindOverMatter/mapgen/map_extras/alien_flora_varieties.json @@ -4,32 +4,6 @@ "method": "json", "update_mapgen_id": "mx_alien_grass", "object": { - "rows": [ - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " " - ], "flags": [ "ALLOW_TERRAIN_UNDER_OTHER_DATA" ], "place_nested": [ { "chunks": [ "grass_location_1" ], "x": [ 2, 13 ], "y": [ 2, 13 ] } ] } @@ -60,32 +34,6 @@ "method": "json", "update_mapgen_id": "mx_alien_grass_2", "object": { - "rows": [ - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " " - ], "flags": [ "ALLOW_TERRAIN_UNDER_OTHER_DATA" ], "place_nested": [ { "chunks": [ "grass_location_2" ], "x": [ 2, 10 ], "y": [ 2, 10 ] } ] } @@ -119,32 +67,6 @@ "method": "json", "update_mapgen_id": "mx_alien_grass_3", "object": { - "rows": [ - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " " - ], "flags": [ "ALLOW_TERRAIN_UNDER_OTHER_DATA" ], "place_nested": [ { "chunks": [ "grass_location_3" ], "x": [ 2, 13 ], "y": [ 2, 13 ] } ] } @@ -175,32 +97,6 @@ "method": "json", "update_mapgen_id": "mx_alien_grass_4", "object": { - "rows": [ - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " " - ], "flags": [ "ALLOW_TERRAIN_UNDER_OTHER_DATA" ], "place_nested": [ { "chunks": [ "grass_location_4" ], "x": [ 2, 12 ], "y": [ 2, 12 ] } ] } @@ -232,32 +128,6 @@ "method": "json", "update_mapgen_id": "mx_alien_grass_5", "object": { - "rows": [ - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " " - ], "flags": [ "ALLOW_TERRAIN_UNDER_OTHER_DATA" ], "place_nested": [ { "chunks": [ "grass_location_5" ], "x": [ 2, 10 ], "y": [ 2, 10 ] } ] } diff --git a/data/mods/MindOverMatter/mapgen/map_extras/glass_and_crystal.json b/data/mods/MindOverMatter/mapgen/map_extras/glass_and_crystal.json index 1b8ff8acd8e0a..1bb6dedd02647 100644 --- a/data/mods/MindOverMatter/mapgen/map_extras/glass_and_crystal.json +++ b/data/mods/MindOverMatter/mapgen/map_extras/glass_and_crystal.json @@ -4,32 +4,6 @@ "method": "json", "update_mapgen_id": "mx_glass_and_crystal", "object": { - "rows": [ - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " " - ], "flags": [ "ALLOW_TERRAIN_UNDER_OTHER_DATA" ], "place_nested": [ { "chunks": [ "glass_and_crystal_chunk" ], "x": [ 2, 15 ], "y": [ 2, 15 ] } ], "monsters": { " ": { "monster": "GROUP_CRYSTAL_FIELD", "chance": 1, "density": 0.0001 } } diff --git a/data/mods/MindOverMatter/mapgen/map_extras/nether_pond.json b/data/mods/MindOverMatter/mapgen/map_extras/nether_pond.json index 85e7308a61357..be30ea6b0d1e8 100644 --- a/data/mods/MindOverMatter/mapgen/map_extras/nether_pond.json +++ b/data/mods/MindOverMatter/mapgen/map_extras/nether_pond.json @@ -4,32 +4,6 @@ "method": "json", "update_mapgen_id": "mx_nether_pond", "object": { - "rows": [ - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " " - ], "flags": [ "ALLOW_TERRAIN_UNDER_OTHER_DATA" ], "place_nested": [ { "chunks": [ "nether_pond_chunk" ], "x": [ 2, 11 ], "y": [ 2, 11 ] } ] } diff --git a/data/mods/MindOverMatter/mapgen/psi_surface_lab/psi_lab_surface_nested.json b/data/mods/MindOverMatter/mapgen/psi_surface_lab/psi_lab_surface_nested.json index d9255a262e98e..501e4cdd51a9b 100644 --- a/data/mods/MindOverMatter/mapgen/psi_surface_lab/psi_lab_surface_nested.json +++ b/data/mods/MindOverMatter/mapgen/psi_surface_lab/psi_lab_surface_nested.json @@ -283,12 +283,6 @@ "object": { "mapgensize": [ 4, 4 ], "rotation": [ 0, 3 ], - "rows": [ - " ", - " ", - " ", - " " - ], "terrain": { " ": "t_nether_water_sh" }, "palettes": [ "lab_surface_palette" ] } @@ -1307,20 +1301,7 @@ "object": { "mapgensize": [ 11, 11 ], "rotation": [ 0, 3 ], - "rows": [ - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " " - ], - "terrain": { " ": "t_nether_water_sh", "X": "t_nether_water_sh" }, + "terrain": { " ": "t_nether_water_sh" }, "palettes": [ "lab_surface_palette" ] } }, diff --git a/data/mods/MindOverMatter/mutations/temporary.json b/data/mods/MindOverMatter/mutations/temporary.json index 9c80bf4697145..715239bf57cd1 100644 --- a/data/mods/MindOverMatter/mutations/temporary.json +++ b/data/mods/MindOverMatter/mutations/temporary.json @@ -381,7 +381,7 @@ "points": 5, "visibility": 0, "ugliness": 0, - "player_display": true, + "player_display": false, "valid": false, "flags": [ "NO_PSIONICS" ] }, @@ -395,6 +395,6 @@ "ugliness": 0, "player_display": true, "valid": false, - "flags": [ "TEEPSHIELD", "PORTAL_PROOF" ] + "flags": [ "TEEPSHIELD" ] } ] diff --git a/data/mods/MindOverMatter/obsolete/items.json b/data/mods/MindOverMatter/obsolete/items.json index e2846de806480..f8b1962211c0b 100644 --- a/data/mods/MindOverMatter/obsolete/items.json +++ b/data/mods/MindOverMatter/obsolete/items.json @@ -8,7 +8,8 @@ "biokin_enhance_mobility_item_3", "biokin_enhance_mobility_item_4", "biokin_enhance_mobility_item_5", - "biokin_enhance_mobility_item_6" + "biokin_enhance_mobility_item_6", + "telepath_mind_shield_item" ], "replace": "manual_swimming" } diff --git a/data/mods/MindOverMatter/overmap/nether_crystal_field.json b/data/mods/MindOverMatter/overmap/nether_crystal_field.json index 6a0f72faad39d..0271883874441 100644 --- a/data/mods/MindOverMatter/overmap/nether_crystal_field.json +++ b/data/mods/MindOverMatter/overmap/nether_crystal_field.json @@ -59,11 +59,6 @@ "nested_mapgen_id": "crystal_moss_or_trees_3x3", "object": { "mapgensize": [ 3, 3 ], - "rows": [ - " ", - " ", - " " - ], "flags": [ "ERASE_ALL_BEFORE_PLACING_TERRAIN" ], "terrain": { " ": [ [ "t_grass_alien_2", 2 ], [ "t_tree_small_alien_1", 1 ], [ "t_null", 1 ] ] } } @@ -74,11 +69,6 @@ "nested_mapgen_id": "crystal_moss_or_trees_3x3", "object": { "mapgensize": [ 3, 3 ], - "rows": [ - " ", - " ", - " " - ], "flags": [ "ERASE_ALL_BEFORE_PLACING_TERRAIN" ], "terrain": { " ": [ [ "t_grass_alien_3", 1 ], [ "t_moss_alien_1", 1 ], [ "t_null", 1 ] ] } } @@ -89,11 +79,6 @@ "nested_mapgen_id": "crystal_moss_or_trees_3x3", "object": { "mapgensize": [ 3, 3 ], - "rows": [ - " ", - " ", - " " - ], "flags": [ "ERASE_ALL_BEFORE_PLACING_TERRAIN" ], "terrain": { " ": [ [ "t_tree_small_alien_2", 1 ], [ "t_moss_alien_2", 1 ], [ "t_null", 1 ] ] } } @@ -104,11 +89,6 @@ "nested_mapgen_id": "crystal_moss_or_trees_3x3", "object": { "mapgensize": [ 3, 3 ], - "rows": [ - " ", - " ", - " " - ], "flags": [ "ERASE_ALL_BEFORE_PLACING_TERRAIN" ], "terrain": { " ": [ [ "t_tree_small_alien_3", 1 ], [ "t_vines_alien_1", 1 ], [ "t_null", 1 ] ] } } @@ -191,12 +171,7 @@ "weight": 1000, "object": { "mapgensize": [ 2, 2 ], - "rows": [ - " ", - " " - ], "flags": [ "ERASE_ALL_BEFORE_PLACING_TERRAIN" ], - "furniture": { "N": [ [ "f_nether_crystal_structure", 1 ], [ "f_null", 1 ] ] }, "place_monsters": [ { "monster": "GROUP_CRYSTAL_FIELD_PSYCHOACTIVE", "x": [ 0, 1 ], "y": [ 0, 1 ], "chance": 50, "repeat": [ 1, 3 ] } ] } }, diff --git a/data/mods/MindOverMatter/powers/telepathy_concentration_eoc.json b/data/mods/MindOverMatter/powers/telepathy_concentration_eoc.json index 11607d78c77b3..fd0ad669af03a 100644 --- a/data/mods/MindOverMatter/powers/telepathy_concentration_eoc.json +++ b/data/mods/MindOverMatter/powers/telepathy_concentration_eoc.json @@ -68,7 +68,6 @@ { "u_message": "You begin shielding your thoughts.", "type": "good" }, { "run_eocs": "EOC_POWER_MAINTENANCE_PLUS_ONE" }, { "u_add_effect": "effect_telepathic_psi_armor", "duration": "PERMANENT" }, - { "u_spawn_item": "telepath_mind_shield_item", "suppress_message": true, "force_equip": true }, { "queue_eocs": "EOC_TELEPATH_SHIELD_DRAIN", "time_in_future": [ @@ -91,11 +90,7 @@ "type": "effect_on_condition", "id": "EOC_TELEPATH_REMOVE_TELEPATHIC_SHIELD", "condition": { "u_has_effect": "effect_telepathic_psi_armor" }, - "effect": [ - { "run_eocs": "EOC_POWER_MAINTENANCE_MINUS_ONE" }, - { "u_lose_effect": "effect_telepathic_psi_armor" }, - { "u_remove_item_with": "telepath_mind_shield_item" } - ] + "effect": [ { "run_eocs": "EOC_POWER_MAINTENANCE_MINUS_ONE" }, { "u_lose_effect": "effect_telepathic_psi_armor" } ] }, { "type": "effect_on_condition", diff --git a/data/mods/No_Hope/Mapgen/mil_base_z0.json b/data/mods/No_Hope/Mapgen/mil_base_z0.json index 68f35d7c11c46..b8b18ce962915 100644 --- a/data/mods/No_Hope/Mapgen/mil_base_z0.json +++ b/data/mods/No_Hope/Mapgen/mil_base_z0.json @@ -531,8 +531,8 @@ { "item": "flour", "x": [ 43, 44 ], "y": 53, "chance": 75, "repeat": [ 50, 150 ] }, { "item": "cornmeal", "x": [ 41, 42 ], "y": 53, "chance": 75, "repeat": [ 50, 150 ] }, { "item": "coffee_raw", "x": 40, "y": 53, "chance": 75, "repeat": [ 50, 150 ] }, - { "item": "tea_raw", "x": 39, "y": 53, "chance": 75, "repeat": [ 50, 150 ] }, - { "item": "sugar", "x": 38, "y": 53, "chance": 75, "repeat": [ 50, 150 ] }, + { "group": "tea_raw_bag_plastic_33", "x": 39, "y": 53, "chance": 75, "repeat": [ 50, 150 ] }, + { "group": "sugar_packed", "x": 38, "y": 53, "chance": 75, "repeat": [ 50, 150 ] }, { "item": "salt", "x": 37, "y": 53, "chance": 75, "repeat": [ 50, 150 ] }, { "item": "cooking_oil", "x": 36, "y": 53, "chance": 75, "repeat": [ 50, 150 ] }, { "item": "meat_salted", "x": [ 45, 46 ], "y": 48, "chance": 75, "repeat": [ 50, 150 ] }, diff --git a/data/mods/No_Hope/regional_map_settings.json b/data/mods/No_Hope/regional_map_settings.json index 7f10f07d8860a..b79a0a5ca5870 100644 --- a/data/mods/No_Hope/regional_map_settings.json +++ b/data/mods/No_Hope/regional_map_settings.json @@ -326,95 +326,30 @@ }, "forest_thick": { "terrains": [ - "forest_thick", - "forest_trail_isolated", - "forest_trail_end_north", - "forest_trail_end_east", - "forest_trail_end_south", - "forest_trail_end_west", - "forest_trail_ns", - "forest_trail_ew", - "forest_trail_ne", - "forest_trail_es", - "forest_trail_sw", - "forest_trail_wn", - "forest_trail_new", - "forest_trail_nsw", - "forest_trail_esw", - "forest_trail_nes", - "forest_trail_nesw", - "campsite_north", - "campsite_south", - "campsite_east", - "campsite_west", - "campsite_cabin_incomplete_north", - "campsite_cabin_incomplete_south", - "campsite_cabin_incomplete_east", - "campsite_cabin_incomplete_west", - "campsite_field_biker_north", - "campsite_field_biker_south", - "campsite_field_biker_east", - "campsite_field_biker_west", - "campsite_field_biker_destroyed_north", - "campsite_field_biker_destroyed_south", - "campsite_field_biker_destroyed_east", - "campsite_field_biker_destroyed_west", - "campsite_a_north", - "campsite_a_south", - "campsite_a_east", - "campsite_a_west", - "desolatebarn_north", - "desolatebarn_south", - "desolatebarn_east", - "desolatebarn_west", - "derelict_property_north", - "derelict_property_south", - "derelict_property_east", - "derelict_property_west", - "homelesscamp_north", - "homelesscamp_south", - "homelesscamp_east", - "homelesscamp_west", - "spider_pit_north", - "spider_pit_south", - "spider_pit_east", - "spider_pit_west", + "bandit_cabin", + "bandit_garage_1", + "bandit_garage_2", + "campsite", + "campsite_a", + "campsite_cabin_incomplete", + "campsite_field_biker", + "campsite_field_biker_destroyed", + "cave", "central_lab_entrance", - "moonshine_still_north", - "moonshine_still_south", - "moonshine_still_east", - "moonshine_still_west", - "moonshine_still_1_north", - "moonshine_still_1_south", - "moonshine_still_1_east", - "moonshine_still_1_west", - "moonshine_still_2_north", - "moonshine_still_2_south", - "moonshine_still_2_east", - "moonshine_still_2_west", + "derelict_property", + "desolatebarn", + "forest_thick", + "forest_trail", + "forest_trail_intersection", + "homelesscamp", + "moonshine_still", + "moonshine_still_1", + "moonshine_still_2", + "natural_spring", + "special_forest_thick", + "spider_pit", "standing_stones", - "ws_survivor_bunker_f0_north", - "ws_survivor_bunker_f0_south", - "ws_survivor_bunker_f0_east", - "ws_survivor_bunker_f0_west", - "bandit_cabin_north", - "bandit_cabin_south", - "bandit_cabin_east", - "bandit_cabin_west", - "bandit_garage_1_north", - "bandit_garage_1_south", - "bandit_garage_1_east", - "bandit_garage_1_west", - "bandit_garage_2_north", - "bandit_garage_2_south", - "bandit_garage_2_east", - "bandit_garage_2_west", - "natural_spring_north", - "natural_spring_south", - "natural_spring_east", - "natural_spring_west", - "cave", - "special_forest_thick" + "ws_survivor_bunker_f0" ], "sparseness_adjacency_factor": 4, "item_group": "forest", @@ -447,25 +382,7 @@ "terrain_furniture": { } }, "forest_water": { - "terrains": [ - "forest_water", - "hunter_shack_north", - "hunter_shack_south", - "hunter_shack_east", - "hunter_shack_west", - "hunter_shack_1_north", - "hunter_shack_1_south", - "hunter_shack_1_east", - "hunter_shack_1_west", - "shipwreck_river_1_north", - "shipwreck_river_1_south", - "shipwreck_river_1_east", - "shipwreck_river_1_west", - "shipwreck_river_2_north", - "shipwreck_river_2_south", - "shipwreck_river_2_east", - "shipwreck_river_2_west" - ], + "terrains": [ "forest_water", "hunter_shack", "hunter_shack_1", "shipwreck_river_1", "shipwreck_river_2" ], "sparseness_adjacency_factor": 2, "item_group": "forest", "item_group_chance": 60, diff --git a/data/mods/Sky_Island/island_upgrades.json b/data/mods/Sky_Island/island_upgrades.json index 4b700a14bcfd3..0074125e8c9ed 100644 --- a/data/mods/Sky_Island/island_upgrades.json +++ b/data/mods/Sky_Island/island_upgrades.json @@ -135,36 +135,7 @@ "type": "mapgen", "method": "json", "update_mapgen_id": "mx_skyisland_solidstoneoverride", - "object": { - "rows": [ - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " " - ], - "flags": [ "NO_UNDERLYING_ROTATE", "ALLOW_TERRAIN_UNDER_OTHER_DATA" ], - "terrain": { " ": "t_warprock" } - } + "object": { "flags": [ "NO_UNDERLYING_ROTATE", "ALLOW_TERRAIN_UNDER_OTHER_DATA" ], "terrain": { " ": "t_warprock" } } }, { "type": "mapgen", diff --git a/data/mods/Sky_Island/missions_and_mapgen.json b/data/mods/Sky_Island/missions_and_mapgen.json index adfcde8b4d4ac..873e0c37648bc 100644 --- a/data/mods/Sky_Island/missions_and_mapgen.json +++ b/data/mods/Sky_Island/missions_and_mapgen.json @@ -1085,33 +1085,6 @@ "method": "json", "update_mapgen_id": "mapgen_dummyplace", "//": "This is a stopgap. If revert_location is called without a mapgen update, the game crashes. So this is a blank map update that does nothing but still prevents the crash. To be removed if the bug gets patched.", - "object": { - "rows": [ - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " " - ] - } + "object": { } } ] diff --git a/data/mods/TEST_DATA/items.json b/data/mods/TEST_DATA/items.json index 5e976c1367e05..db870a59126d5 100644 --- a/data/mods/TEST_DATA/items.json +++ b/data/mods/TEST_DATA/items.json @@ -4919,5 +4919,15 @@ "//": "Do not use calcium, iron or vitamin C! Those are calculated as RDAs, and you only get 96% of the listed value! No, that doesn't make any sense! But that's how it is. So use a normal vitamin. This is for a camp test, not a vitamin test...", "vitamins": [ [ "mutant_toxin", 100 ], [ "mutagen", 200 ] ], "melee_damage": { "bash": 1 } + }, + { + "type": "COMESTIBLE", + "id": "toastem_test", + "name": { "str": "toast-em" }, + "copy-from": "toastem", + "//": "toastem copy with a different material + manual values so monotony penalty is sure to apply", + "material": [ "foodplace_foodstuff" ], + "fun": 20, + "monotony_penalty": 4 } ] diff --git a/data/mods/TEST_DATA/mapgen-test.json b/data/mods/TEST_DATA/mapgen-test.json index 9a9843f3a4791..71bd1d0db5ff1 100644 --- a/data/mods/TEST_DATA/mapgen-test.json +++ b/data/mods/TEST_DATA/mapgen-test.json @@ -39,15 +39,7 @@ "type": "mapgen", "method": "json", "nested_mapgen_id": "mapgen_test_nested", - "object": { - "mapgensize": [ 2, 2 ], - "rows": [ - " ", - " " - ], - "terrain": { " ": "t_region_groundcover" }, - "furniture": { " ": "f_armchair" } - } + "object": { "mapgensize": [ 2, 2 ], "terrain": { " ": "t_region_groundcover" }, "furniture": { " ": "f_armchair" } } }, { "type": "mapgen", diff --git a/data/mods/TropiCataclysm/tropical_regional_map_settings.json b/data/mods/TropiCataclysm/tropical_regional_map_settings.json index ea4740528731d..62e7572754d02 100644 --- a/data/mods/TropiCataclysm/tropical_regional_map_settings.json +++ b/data/mods/TropiCataclysm/tropical_regional_map_settings.json @@ -379,95 +379,30 @@ }, "forest_thick": { "terrains": [ - "forest_thick", - "forest_trail_isolated", - "forest_trail_end_north", - "forest_trail_end_east", - "forest_trail_end_south", - "forest_trail_end_west", - "forest_trail_ns", - "forest_trail_ew", - "forest_trail_ne", - "forest_trail_es", - "forest_trail_sw", - "forest_trail_wn", - "forest_trail_new", - "forest_trail_nsw", - "forest_trail_esw", - "forest_trail_nes", - "forest_trail_nesw", - "campsite_north", - "campsite_south", - "campsite_east", - "campsite_west", - "campsite_cabin_incomplete_north", - "campsite_cabin_incomplete_south", - "campsite_cabin_incomplete_east", - "campsite_cabin_incomplete_west", - "campsite_field_biker_north", - "campsite_field_biker_south", - "campsite_field_biker_east", - "campsite_field_biker_west", - "campsite_field_biker_destroyed_north", - "campsite_field_biker_destroyed_south", - "campsite_field_biker_destroyed_east", - "campsite_field_biker_destroyed_west", - "campsite_a_north", - "campsite_a_south", - "campsite_a_east", - "campsite_a_west", - "desolatebarn_north", - "desolatebarn_south", - "desolatebarn_east", - "desolatebarn_west", - "derelict_property_north", - "derelict_property_south", - "derelict_property_east", - "derelict_property_west", - "homelesscamp_north", - "homelesscamp_south", - "homelesscamp_east", - "homelesscamp_west", - "spider_pit_north", - "spider_pit_south", - "spider_pit_east", - "spider_pit_west", + "bandit_cabin", + "bandit_garage_1", + "bandit_garage_2", + "campsite", + "campsite_a", + "campsite_cabin_incomplete", + "campsite_field_biker", + "campsite_field_biker_destroyed", + "cave", "central_lab_entrance", - "moonshine_still_north", - "moonshine_still_south", - "moonshine_still_east", - "moonshine_still_west", - "moonshine_still_1_north", - "moonshine_still_1_south", - "moonshine_still_1_east", - "moonshine_still_1_west", - "moonshine_still_2_north", - "moonshine_still_2_south", - "moonshine_still_2_east", - "moonshine_still_2_west", + "derelict_property", + "desolatebarn", + "forest_thick", + "forest_trail", + "forest_trail_intersection", + "homelesscamp", + "moonshine_still", + "moonshine_still_1", + "moonshine_still_2", + "natural_spring", + "special_forest_thick", + "spider_pit", "standing_stones", - "ws_survivor_bunker_f0_north", - "ws_survivor_bunker_f0_south", - "ws_survivor_bunker_f0_east", - "ws_survivor_bunker_f0_west", - "bandit_cabin_north", - "bandit_cabin_south", - "bandit_cabin_east", - "bandit_cabin_west", - "bandit_garage_1_north", - "bandit_garage_1_south", - "bandit_garage_1_east", - "bandit_garage_1_west", - "bandit_garage_2_north", - "bandit_garage_2_south", - "bandit_garage_2_east", - "bandit_garage_2_west", - "natural_spring_north", - "natural_spring_south", - "natural_spring_east", - "natural_spring_west", - "cave", - "special_forest_thick" + "ws_survivor_bunker_f0" ], "sparseness_adjacency_factor": 4, "item_group": "forest", @@ -515,25 +450,7 @@ "terrain_furniture": { } }, "forest_water": { - "terrains": [ - "forest_water", - "hunter_shack_north", - "hunter_shack_south", - "hunter_shack_east", - "hunter_shack_west", - "hunter_shack_1_north", - "hunter_shack_1_south", - "hunter_shack_1_east", - "hunter_shack_1_west", - "shipwreck_river_1_north", - "shipwreck_river_1_south", - "shipwreck_river_1_east", - "shipwreck_river_1_west", - "shipwreck_river_2_north", - "shipwreck_river_2_south", - "shipwreck_river_2_east", - "shipwreck_river_2_west" - ], + "terrains": [ "forest_water", "hunter_shack", "hunter_shack_1", "shipwreck_river_1", "shipwreck_river_2" ], "sparseness_adjacency_factor": 2, "item_group": "forest", "item_group_chance": 60, diff --git a/data/mods/Xedra_Evolved/eocs/give_a_class_eoc.json b/data/mods/Xedra_Evolved/eocs/give_a_class_eoc.json index 4f7df6ce4c265..c3c93dc80847b 100644 --- a/data/mods/Xedra_Evolved/eocs/give_a_class_eoc.json +++ b/data/mods/Xedra_Evolved/eocs/give_a_class_eoc.json @@ -7,8 +7,18 @@ "and": [ { "and": [ - { "or": [ { "not": { "u_has_trait": "EATER" } }, { "not": { "u_has_trait": "DREAMER" } } ] }, - { "or": [ { "not": { "u_has_trait": "INVENTOR" } }, { "not": { "u_has_trait": "DREAMSMITH" } } ] } + { + "and": [ + { "or": [ { "not": { "u_has_trait": "EATER" } }, { "not": { "u_has_trait": "DREAMER" } } ] }, + { "not": { "u_has_trait": "DREAMLESS" } } + ] + }, + { + "and": [ + { "or": [ { "not": { "u_has_trait": "INVENTOR" } }, { "not": { "u_has_trait": "DREAMSMITH" } } ] }, + { "not": { "u_has_trait": "DREAMLESS" } } + ] + } ] }, { "math": [ "magic_potential", ">", "0" ] } diff --git a/data/mods/Xedra_Evolved/mapgen/nested/vampires.json b/data/mods/Xedra_Evolved/mapgen/nested/vampires.json index 09c9508d250bc..5b3ee79b38124 100644 --- a/data/mods/Xedra_Evolved/mapgen/nested/vampires.json +++ b/data/mods/Xedra_Evolved/mapgen/nested/vampires.json @@ -44,13 +44,6 @@ "nested_mapgen_id": "5x5_corpse_pile_W", "object": { "mapgensize": [ 5, 5 ], - "rows": [ - " ", - " ", - " ", - " ", - " " - ], "palettes": [ "standard_domestic_palette" ], "flags": [ "ALLOW_TERRAIN_UNDER_OTHER_DATA" ], "place_item": [ { "item": "corpse_generic_human", "x": [ 0, 4 ], "y": [ 0, 4 ], "chance": 65 } ], diff --git a/data/mods/Xedra_Evolved/mutations/mutations.json b/data/mods/Xedra_Evolved/mutations/mutations.json index cbb82129422a4..4074ddb39bf10 100644 --- a/data/mods/Xedra_Evolved/mutations/mutations.json +++ b/data/mods/Xedra_Evolved/mutations/mutations.json @@ -21,6 +21,14 @@ "valid": false, "description": "You don't feel very well. On an existential level." }, + { + "type": "mutation", + "id": "DREAMLESS", + "name": { "str": "Dreamless" }, + "points": 0, + "valid": false, + "description": "You live firmly in reality and never experience extremely vivid dreams about choices that have real world consequences. ( You will be unable to gain Dream magicks from sleeping after strange events)" + }, { "type": "mutation", "id": "MANIFEST_DESTINY_GOBLIN", diff --git a/data/mods/Xedra_Evolved/mutations/paraclesians/arvore_eocs.json b/data/mods/Xedra_Evolved/mutations/paraclesians/arvore_eocs.json index 2974967f199a8..b76aca09d8e25 100644 --- a/data/mods/Xedra_Evolved/mutations/paraclesians/arvore_eocs.json +++ b/data/mods/Xedra_Evolved/mutations/paraclesians/arvore_eocs.json @@ -701,15 +701,68 @@ { "type": "effect_on_condition", "id": "EOC_ARVORE_VERDANT_IMPRISONMENT", + "condition": "u_is_outside", + "effect": [ { "run_eocs": "EOC_ARVORE_VERDANT_IMPRISONMENT_2" } ], + "false_effect": [ { "npc_message": "Your target must be outdoors to transform them into a tree." } ] + }, + { + "type": "effect_on_condition", + "id": "EOC_ARVORE_VERDANT_IMPRISONMENT_2", + "condition": { "not": "u_is_npc" }, "effect": [ + { "math": [ "u_arvore_turn_into_tree_intelligence", "=", "( ( n_val('intelligence') + 10) / 20 )" ] }, + { "math": [ "u_arvore_turn_into_tree_spell_level", "=", "n_spell_level('arvore_turn_into_tree')" ] }, { - "npc_location_variable": { "global_val": "arvore_tree_transform_target" }, + "u_location_variable": { "global_val": "arvore_tree_transform_target" }, "x_adjust": 0, "y_adjust": 0, - "z_adjust": 0, - "monster": "", + "z_adjust": 0 + }, + { "u_cast_spell": { "id": "arvore_turn_into_tree_banish", "message": "" } }, + { + "run_eoc_with": "EOC_NULL", + "beta_loc": { "global_val": "arvore_tree_transform_target" }, "false_eocs": "EOC_ARVORE_VERDANT_IMPRISONMENT_SUCCESS" } + ], + "false_effect": [ + { + "math": [ + "u_arvore_turn_into_tree_damage", + "=", + "rng(((25 + (n_spell_level('arvore_turn_into_tree') * 5)) * ( ( n_val('intelligence') + 10) / 20 )),((100 + (n_spell_level('arvore_turn_into_tree') * 15)) * ( ( n_val('intelligence') + 10) / 20 )))" + ] + }, + { + "math": [ + "u_health_comparison", + "=", + "(u_hp('arm_l') + u_hp('arm_r') + u_hp('leg_l') + u_hp('leg_r') + u_hp('torso') + u_hp('head')) / 3" + ] + }, + { + "u_location_variable": { "global_val": "arvore_tree_transform_target" }, + "x_adjust": 0, + "y_adjust": 0, + "z_adjust": 0 + }, + { + "if": { "math": [ "u_arvore_turn_into_tree_damage", ">", "u_health_comparison" ] }, + "then": [ + "u_die", + { + "u_map_run_item_eocs": "all", + "min_radius": 0, + "max_radius": 0, + "true_eocs": [ { "id": "EOC_ARVORE_VERDANT_IMPRISONMENT_DELETE_NPC_ITEMS", "effect": [ "npc_die" ] } ] + }, + { + "run_eoc_with": "EOC_NULL", + "beta_loc": { "global_val": "arvore_tree_transform_target" }, + "false_eocs": "EOC_ARVORE_VERDANT_IMPRISONMENT_SUCCESS" + } + ] + } ] }, { @@ -718,7 +771,7 @@ "effect": [ { "u_transform_radius": 0, - "ter_furn_transform": "ter_arvore_tree_transform", + "ter_furn_transform": "ter_arvore_verdant_tree_transform", "target_var": { "global_val": "arvore_tree_transform_target" } } ] diff --git a/data/mods/Xedra_Evolved/mutations/paraclesians/arvore_mutation_spells.json b/data/mods/Xedra_Evolved/mutations/paraclesians/arvore_mutation_spells.json index e0ba29db70261..060769744f9b0 100644 --- a/data/mods/Xedra_Evolved/mutations/paraclesians/arvore_mutation_spells.json +++ b/data/mods/Xedra_Evolved/mutations/paraclesians/arvore_mutation_spells.json @@ -301,7 +301,7 @@ "min_duration": 30000, "max_duration": 1080000, "duration_increment": 16500, - "learn_spells": { "arvore_summon_preservation_container": 9 } + "learn_spells": { "arvore_summon_preservation_container": 9, "arvore_turn_into_tree": 18 } }, { "id": "arvore_roots_crack_the_foundation", @@ -506,7 +506,8 @@ "energy_increment": -10, "base_casting_time": 200, "final_casting_time": 100, - "casting_time_increment": -5 + "casting_time_increment": -5, + "learn_spells": { "arvore_turn_into_tree": 15 } }, { "id": "arvore_anti_plant_spell_fungicide", @@ -591,7 +592,7 @@ "base_energy_cost": 600, "final_energy_cost": 350, "energy_increment": -15, - "learn_spells": { "arvore_tree_singing_spell": 6 } + "learn_spells": { "arvore_tree_singing_spell": 6, "arvore_turn_into_tree": 12 } }, { "id": "arvore_growing_wood_walls_wall", @@ -759,7 +760,7 @@ "base_casting_time": 500, "final_casting_time": 250, "casting_time_increment": -8, - "learn_spells": { "arvore_tree_singing_spell": 5, "arvore_damage_zombies_heal_living": 8 } + "learn_spells": { "arvore_tree_singing_spell": 5, "arvore_turn_into_tree": 9, "arvore_damage_zombies_heal_living": 12 } }, { "id": "arvore_overgrowth_spell_real", @@ -936,6 +937,50 @@ "shape": "blast", "min_range": 1 }, + { + "id": "arvore_turn_into_tree", + "type": "SPELL", + "name": "Verdant Imprisonment", + "description": "The ultimate expression of nature's power, you can turn your target into a tree that might have stood for a century or more. It works best on an already-weakened target, and does not work at all on non-organic targets.", + "valid_targets": [ "hostile" ], + "skill": "deduction", + "flags": [ "VERBAL", "SOMATIC", "SILENT", "RANDOM_DAMAGE" ], + "effect": "effect_on_condition", + "effect_str": "EOC_ARVORE_VERDANT_IMPRISONMENT", + "shape": "blast", + "difficulty": 10, + "spell_class": "ARVORE", + "teachable": false, + "max_level": { "math": [ "int_to_level(1)" ] }, + "min_range": { "math": [ "(3 + (u_spell_level('arvore_turn_into_tree') * 1.2) * (scaling_factor(u_val('perception') ) ) )" ] }, + "max_range": 70, + "energy_source": "MANA", + "base_energy_cost": 1750, + "energy_increment": -50, + "final_energy_cost": 850, + "base_casting_time": 200, + "casting_time_increment": -5, + "final_casting_time": 100, + "ignored_monster_species": [ "NETHER_EMANATION", "ROBOT" ] + }, + { + "id": "arvore_turn_into_tree_banish", + "type": "SPELL", + "name": "Verdant Imprisonment Self", + "description": "This is the banishment that the target casts on themselves.", + "valid_targets": [ "self" ], + "skill": "deduction", + "flags": [ "VERBAL", "SOMATIC", "SILENT", "RANDOM_DAMAGE" ], + "effect": "banishment", + "shape": "blast", + "spell_class": "ARVORE", + "teachable": false, + "min_damage": { "math": [ "(25 + (u_arvore_turn_into_tree_spell_level * 5)) * u_arvore_turn_into_tree_intelligence" ] }, + "max_damage": { "math": [ "(100 + (u_arvore_turn_into_tree_spell_level * 15)) * u_arvore_turn_into_tree_intelligence" ] }, + "min_range": 0, + "max_range": 0, + "ignored_monster_species": [ "NETHER_EMANATION", "ROBOT" ] + }, { "id": "arvore_reduce_thirst_spell", "type": "SPELL", diff --git a/data/mods/Xedra_Evolved/mutations/paraclesians/arvore_spell_learning_eocs.json b/data/mods/Xedra_Evolved/mutations/paraclesians/arvore_spell_learning_eocs.json index 688def9c0e8e9..56f357b7a3ee9 100644 --- a/data/mods/Xedra_Evolved/mutations/paraclesians/arvore_spell_learning_eocs.json +++ b/data/mods/Xedra_Evolved/mutations/paraclesians/arvore_spell_learning_eocs.json @@ -116,6 +116,7 @@ { "math": [ "u_spell_level('arvore_climbing_vine_spell')", "<", "int_to_level(1)" ] }, { "math": [ "u_spell_level('arvore_anti_plant_spell')", "<", "per_to_level(1)" ] }, { "math": [ "u_spell_level('arvore_damage_zombies_heal_living')", "<", "per_to_level(1)" ] }, + { "math": [ "u_spell_level('arvore_turn_into_tree')", "<", "int_to_level(1)" ] }, { "math": [ "u_spell_level('arvore_tree_singing_spell')", "<", "int_to_level(1)" ] }, { "math": [ "u_spell_level('arvore_cultivate_goblin_fruit')", "<", "int_to_level(1)" ] }, { "math": [ "u_spell_level('paraclesian_spell_dodge_bonus')", "<", "25" ] }, @@ -140,6 +141,7 @@ [ "EOC_LEVELER_ARVORE_CLIMBING_VINE_SPELL", 8 ], [ "EOC_LEVELER_ARVORE_ANTI_PLANT_SPELL", 7 ], [ "EOC_LEVELER_ARVORE_DAMAGE_ZOMBIES_HEAL_LIVING", 1 ], + [ "EOC_LEVELER_ARVORE_TREE_TRANSFORM", 1 ], [ "EOC_LEVELER_ARVORE_TREE_SINGING_SPELL", 5 ], [ "EOC_LEVELER_ARVORE_CULTIVATE_GOBLIN_FRUIT", 3 ], [ "EOC_LEVELER_ARVORE_WIND_BLOWS_WILLOW_BENDS", 6 ], @@ -435,6 +437,24 @@ ], "false_effect": [ { "run_eocs": "EOC_ARVORE_SPELL_EXPERIENCE_INCREASER_SELECTOR" } ] }, + { + "type": "effect_on_condition", + "id": "EOC_LEVELER_ARVORE_TREE_TRANSFORM", + "condition": { + "and": [ + { "math": [ "u_spell_level('arvore_turn_into_tree')", ">=", "0" ] }, + { "math": [ "u_spell_level('arvore_turn_into_tree')", "<", "int_to_level(1)" ] } + ] + }, + "effect": [ + { + "u_message": "Your time spent under the shadows of the trees has increased your facility with your fae magicks.", + "type": "good" + }, + { "math": [ "u_spell_exp('arvore_turn_into_tree')", "+=", "paraclesian_passive_spell_exp(1)" ] } + ], + "false_effect": [ { "run_eocs": "EOC_ARVORE_SPELL_EXPERIENCE_INCREASER_SELECTOR" } ] + }, { "type": "effect_on_condition", "id": "EOC_LEVELER_ARVORE_TREE_SINGING_SPELL", diff --git a/data/mods/Xedra_Evolved/npc/trait_groups.json b/data/mods/Xedra_Evolved/npc/trait_groups.json index 0bd27a85756a4..20319619e61d2 100644 --- a/data/mods/Xedra_Evolved/npc/trait_groups.json +++ b/data/mods/Xedra_Evolved/npc/trait_groups.json @@ -1,4 +1,10 @@ [ + { + "type": "trait_group", + "id": "NPC_starting_traits", + "subtype": "collection", + "traits": [ { "trait": "DREAMLESS", "prob": 75 } ] + }, { "type": "trait_group", "id": "trait_group_spider_victim_eggsac", diff --git a/data/mods/Xedra_Evolved/ter_transforms/arvore_ter_transforms.json b/data/mods/Xedra_Evolved/ter_transforms/arvore_ter_transforms.json index 4f8d78dca8da4..172cdbf1a9e31 100644 --- a/data/mods/Xedra_Evolved/ter_transforms/arvore_ter_transforms.json +++ b/data/mods/Xedra_Evolved/ter_transforms/arvore_ter_transforms.json @@ -333,5 +333,40 @@ } ], "furniture": [ { "result": "f_null", "valid_flags": [ "MOUNTABLE", "BLOCK_WIND", "ORGANIC" ] } ] + }, + { + "type": "ter_furn_transform", + "id": "ter_arvore_verdant_tree_transform", + "terrain": [ + { + "result": [ + [ "t_tree_birch", 32 ], + [ "t_tree_elm", 32 ], + [ "t_tree_cottonwood", 32 ], + [ "t_tree_basswood", 32 ], + [ "t_tree_alder", 32 ], + [ "t_tree_pine", 64 ], + [ "t_tree_maple", 64 ], + [ "t_tree_willow", 64 ], + [ "t_tree_hickory", 32 ], + [ "t_tree_walnut", 16 ], + [ "t_tree_butternut", 4 ], + [ "t_tree_chestnut", 8 ], + [ "t_tree_hazelnut", 2 ], + [ "t_tree_beech", 4 ], + [ "t_tree_blackjack", 8 ], + [ "t_tree_apple", 2 ], + [ "t_tree_cherry", 2 ], + [ "t_tree_juniper", 2 ], + [ "t_tree_pear", 2 ], + [ "t_tree_plum", 2 ], + [ "t_tree_elderberry", 2 ], + [ "t_tree_mulberry", 2 ], + [ "t_tree_sassafras", 3 ] + ], + "valid_flags": [ "BURROWABLE", "DIGGABLE", "COLLAPSES", "DOOR", "FLAT_SURF", "FUNGUS", "PLANTABLE", "ROAD", "ROUGH", "SHALLOW_WATER" ], + "message": "The target's limbs begin stretching and spreading toward the sky as their body elongates, and in moments, a tree that could have stood for a hundred years stands in their place." + } + ] } ] diff --git a/data/mods/classic_zombies/alberta_regional_map_settings.json b/data/mods/classic_zombies/alberta_regional_map_settings.json index 1fc6ad7171e28..1158c1d3a545d 100644 --- a/data/mods/classic_zombies/alberta_regional_map_settings.json +++ b/data/mods/classic_zombies/alberta_regional_map_settings.json @@ -312,95 +312,30 @@ }, "forest_thick": { "terrains": [ - "forest_thick", - "forest_trail_isolated", - "forest_trail_end_north", - "forest_trail_end_east", - "forest_trail_end_south", - "forest_trail_end_west", - "forest_trail_ns", - "forest_trail_ew", - "forest_trail_ne", - "forest_trail_es", - "forest_trail_sw", - "forest_trail_wn", - "forest_trail_new", - "forest_trail_nsw", - "forest_trail_esw", - "forest_trail_nes", - "forest_trail_nesw", - "campsite_north", - "campsite_south", - "campsite_east", - "campsite_west", - "campsite_cabin_incomplete_north", - "campsite_cabin_incomplete_south", - "campsite_cabin_incomplete_east", - "campsite_cabin_incomplete_west", - "campsite_field_biker_north", - "campsite_field_biker_south", - "campsite_field_biker_east", - "campsite_field_biker_west", - "campsite_field_biker_destroyed_north", - "campsite_field_biker_destroyed_south", - "campsite_field_biker_destroyed_east", - "campsite_field_biker_destroyed_west", - "campsite_a_north", - "campsite_a_south", - "campsite_a_east", - "campsite_a_west", - "desolatebarn_north", - "desolatebarn_south", - "desolatebarn_east", - "desolatebarn_west", - "derelict_property_north", - "derelict_property_south", - "derelict_property_east", - "derelict_property_west", - "homelesscamp_north", - "homelesscamp_south", - "homelesscamp_east", - "homelesscamp_west", - "spider_pit_north", - "spider_pit_south", - "spider_pit_east", - "spider_pit_west", + "bandit_cabin", + "bandit_garage_1", + "bandit_garage_2", + "campsite", + "campsite_a", + "campsite_cabin_incomplete", + "campsite_field_biker", + "campsite_field_biker_destroyed", + "cave", "central_lab_entrance", - "moonshine_still_north", - "moonshine_still_south", - "moonshine_still_east", - "moonshine_still_west", - "moonshine_still_1_north", - "moonshine_still_1_south", - "moonshine_still_1_east", - "moonshine_still_1_west", - "moonshine_still_2_north", - "moonshine_still_2_south", - "moonshine_still_2_east", - "moonshine_still_2_west", + "derelict_property", + "desolatebarn", + "forest_thick", + "forest_trail", + "forest_trail_intersection", + "homelesscamp", + "moonshine_still", + "moonshine_still_1", + "moonshine_still_2", + "natural_spring", + "special_forest_thick", + "spider_pit", "standing_stones", - "ws_survivor_bunker_f0_north", - "ws_survivor_bunker_f0_south", - "ws_survivor_bunker_f0_east", - "ws_survivor_bunker_f0_west", - "bandit_cabin_north", - "bandit_cabin_south", - "bandit_cabin_east", - "bandit_cabin_west", - "bandit_garage_1_north", - "bandit_garage_1_south", - "bandit_garage_1_east", - "bandit_garage_1_west", - "bandit_garage_2_north", - "bandit_garage_2_south", - "bandit_garage_2_east", - "bandit_garage_2_west", - "natural_spring_north", - "natural_spring_south", - "natural_spring_east", - "natural_spring_west", - "cave", - "special_forest_thick" + "ws_survivor_bunker_f0" ], "sparseness_adjacency_factor": 4, "item_group": "forest", @@ -433,25 +368,7 @@ "terrain_furniture": { } }, "forest_water": { - "terrains": [ - "forest_water", - "hunter_shack_north", - "hunter_shack_south", - "hunter_shack_east", - "hunter_shack_west", - "hunter_shack_1_north", - "hunter_shack_1_south", - "hunter_shack_1_east", - "hunter_shack_1_west", - "shipwreck_river_1_north", - "shipwreck_river_1_south", - "shipwreck_river_1_east", - "shipwreck_river_1_west", - "shipwreck_river_2_north", - "shipwreck_river_2_south", - "shipwreck_river_2_east", - "shipwreck_river_2_west" - ], + "terrains": [ "forest_water", "hunter_shack", "hunter_shack_1", "shipwreck_river_1", "shipwreck_river_2" ], "sparseness_adjacency_factor": 2, "item_group": "forest", "item_group_chance": 60, diff --git a/data/mods/innawood/region_overlay.json b/data/mods/innawood/region_overlay.json index d90fb06d24aab..3d0305d548591 100644 --- a/data/mods/innawood/region_overlay.json +++ b/data/mods/innawood/region_overlay.json @@ -14,46 +14,17 @@ "forest_mapgen_settings": { "forest_thick": { "terrains": [ - "forest_thick", - "forest_trail_isolated", - "forest_trail_end_north", - "forest_trail_end_east", - "forest_trail_end_south", - "forest_trail_end_west", - "forest_trail_ns", - "forest_trail_ew", - "forest_trail_ne", - "forest_trail_es", - "forest_trail_sw", - "forest_trail_wn", - "forest_trail_new", - "forest_trail_nsw", - "forest_trail_esw", - "forest_trail_nes", - "forest_trail_nesw", - "spider_pit_north", - "spider_pit_south", - "spider_pit_east", - "spider_pit_west", - "standing_stones", - "natural_spring_north", - "natural_spring_south", - "natural_spring_east", - "natural_spring_west", "cave_innawood", + "forest_thick", + "forest_trail", + "forest_trail_intersection", + "natural_spring", "special_forest", - "stream_north", - "stream_east", - "stream_south", - "stream_west", - "stream_corner_north", - "stream_corner_east", - "stream_corner_south", - "stream_corner_west", - "stream_end_north", - "stream_end_east", - "stream_end_south", - "stream_end_west" + "spider_pit", + "standing_stones", + "stream", + "stream_corner", + "stream_end" ] }, "forest_water": { "terrains": [ "forest_water" ] } diff --git a/doc/JSON_INFO.md b/doc/JSON_INFO.md index ac0ca36402e73..3ee26b191f035 100644 --- a/doc/JSON_INFO.md +++ b/doc/JSON_INFO.md @@ -3933,7 +3933,8 @@ CBMs can be defined like this: "healthy" : -2, // Health effects (used for sickness chances) "addiction_potential" : 80, // Default strength for this item to cause addictions "addiction_type" : [ "crack", { "addiction": "cocaine", "potential": 5 } ], // Addiction types (if no potential is given, the "addiction_potential" field is used to determine the strength of that addiction) -"monotony_penalty" : 0, // (Optional, default: 2) Fun is reduced by this number for each one you've consumed in the last 48 hours. +"monotony_penalty" : 0, // (Optional, default: 2 or 0 depending on material) Fun is reduced by this number for each one you've consumed in the last 48 hours. + // Comestibles with any material of junk food (id: "junk") default to 0. All other comestibles default to 2 when unspecified. // Can't drop fun below 0, unless the comestible also has the "NEGATIVE_MONOTONY_OK" flag. "calories" : 0, // Hunger satisfied (in kcal) "nutrition" : 0, // Hunger satisfied (OBSOLETE) @@ -4856,10 +4857,13 @@ Harvest drop types are used in harvest drop entries to control how the drop is p { "type": "weapon_category", "id": "WEAP_CAT" - "name": "Weapon Category" + "name": "Weapon Category", + "proficiencies": [ "prof_baz" ] } ``` +`proficiencies` is a list of proficiencies that may apply bonuses when using weapons with this category. See the proficiency documentation for more details. + ### Connect group definitions Connect groups can be used by id in terrain and furniture `connect_groups`, `connects_to` and `rotates_to` properties. diff --git a/doc/MAPGEN.md b/doc/MAPGEN.md index 08cb991c38567..0d4ae390b601a 100644 --- a/doc/MAPGEN.md +++ b/doc/MAPGEN.md @@ -289,7 +289,7 @@ optional. ## Fill terrain using "fill_ter" -*required if "rows" is unset* Fill with the given terrain. +Fill with the given terrain. Value: `"string"`: Valid terrain id from data/json/terrain.json @@ -297,10 +297,11 @@ Example: `"fill_ter": "t_region_groundcover"` ## ASCII map using "rows" array -*required if "fill_ter" is unset* -Nested array of 24 (or 48) strings, each 24 (or 48) characters long, where each character is defined by "terrain" and -optionally "furniture" or other entries below. +Nested array usually of 24 strings, each 24 characters long but can vary for nests (in which case between 1 and 24) +and defining multiple overmap terrains maps at once (in which case a multiple of 24), +where each character is defined by "terrain" and optionally "furniture" or other entries below. +Defaults to all spaces " " if unset. Usage: diff --git a/doc/PROFICIENCY.md b/doc/PROFICIENCY.md index 471dcdda006a2..fed2fd65ff0d5 100644 --- a/doc/PROFICIENCY.md +++ b/doc/PROFICIENCY.md @@ -172,3 +172,4 @@ Field | Mandatory | Type | Description `type` | Mandatory | String | Where this bonus applies. Valid values are `"strength"`, `"dexterity"`, `"intelligence"`, `"perception"`. `value` | Mandatory | Float | What the bonus is. This can be any numeric value representable as a floating point number. Values of the same type from all available proficiencies are summed together to produce the final bonus for a proficiency. +For the `melee_attack` key, only `"type": "stamina"` is valid, and when an attack is performed using a weapon category that points to this proficiency, the final stamina cost of the attack will be multiplied by 1 - (the sum of stamina bonuses). This does not stack across categories, and only the lowest resulting stamina value will be used. diff --git a/src/activity_actor.cpp b/src/activity_actor.cpp index c203b6452e966..5e906a3d71b2b 100644 --- a/src/activity_actor.cpp +++ b/src/activity_actor.cpp @@ -225,6 +225,15 @@ static const skill_id skill_traps( "traps" ); static const species_id species_ZOMBIE( "ZOMBIE" ); +static const ter_str_id ter_t_card_reader_broken( "t_card_reader_broken" ); +static const ter_str_id ter_t_dirt( "t_dirt" ); +static const ter_str_id ter_t_dirtmound( "t_dirtmound" ); +static const ter_str_id ter_t_door_c( "t_door_c" ); +static const ter_str_id ter_t_door_locked_alarm( "t_door_locked_alarm" ); +static const ter_str_id ter_t_door_metal_c( "t_door_metal_c" ); +static const ter_str_id ter_t_door_metal_locked( "t_door_metal_locked" ); +static const ter_str_id ter_t_stump( "t_stump" ); +static const ter_str_id ter_t_trunk( "t_trunk" ); static const ter_str_id ter_t_underbrush_harvested_autumn( "t_underbrush_harvested_autumn" ); static const ter_str_id ter_t_underbrush_harvested_spring( "t_underbrush_harvested_spring" ); static const ter_str_id ter_t_underbrush_harvested_summer( "t_underbrush_harvested_summer" ); @@ -814,10 +823,10 @@ void hacking_activity_actor::finish( player_activity &act, Character &who ) } else if( type == hack_type::DOOR ) { who.add_msg_if_player( _( "You activate the panel!" ) ); who.add_msg_if_player( m_good, _( "The nearby doors unlock." ) ); - here.ter_set( examp, t_card_reader_broken ); + here.ter_set( examp, ter_t_card_reader_broken ); for( const tripoint &tmp : here.points_in_radius( examp, 3 ) ) { - if( here.ter( tmp ) == t_door_metal_locked ) { - here.ter_set( tmp, t_door_metal_c ); + if( here.ter( tmp ) == ter_t_door_metal_locked ) { + here.ter_set( tmp, ter_t_door_metal_c ); } } } @@ -2811,7 +2820,7 @@ void lockpick_activity_actor::finish( player_activity &act, Character &who ) you->practice( skill_traps, xp_gain ); } - if( !perfect && ter_type == t_door_locked_alarm && ( lock_roll + dice( 1, 30 ) ) > pick_roll ) { + if( !perfect && ter_type == ter_t_door_locked_alarm && ( lock_roll + dice( 1, 30 ) ) > pick_roll ) { sounds::sound( who.pos(), 40, sounds::sound_t::alarm, _( "an alarm sound!" ), true, "environment", "alarm" ); } @@ -2858,7 +2867,7 @@ std::optional lockpick_activity_actor::select_location( avatar &you ) } else if( get_creature_tracker().creature_at( *target ) ) { you.add_msg_if_player( m_info, _( "You can pick your friends, and you can\npick your nose, but you can't pick\nyour friend's nose." ) ); - } else if( terr_type == t_door_c ) { + } else if( terr_type == ter_t_door_c ) { you.add_msg_if_player( m_info, _( "That door isn't locked." ) ); } else { you.add_msg_if_player( m_info, _( "That cannot be picked." ) ); @@ -6213,11 +6222,11 @@ void chop_logs_activity_actor::finish( player_activity &act, Character &who ) int log_quan; int stick_quan; int splint_quan; - if( here.ter( pos ) == t_trunk ) { + if( here.ter( pos ) == ter_t_trunk ) { log_quan = rng( 2, 3 ); stick_quan = rng( 0, 3 ); splint_quan = 0; - } else if( here.ter( pos ) == t_stump ) { + } else if( here.ter( pos ) == ter_t_stump ) { log_quan = rng( 0, 2 ); stick_quan = 0; splint_quan = rng( 5, 15 ); @@ -6241,7 +6250,7 @@ void chop_logs_activity_actor::finish( player_activity &act, Character &who ) obj.set_var( "activity_var", who.name ); here.add_item_or_charges( pos, obj ); } - here.ter_set( pos, t_dirt ); + here.ter_set( pos, ter_t_dirt ); who.add_msg_if_player( m_good, _( "You finish chopping wood." ) ); act.set_to_null(); @@ -6399,10 +6408,10 @@ void chop_tree_activity_actor::finish( player_activity &act, Character &who ) std::vector tree = line_to( pos, to, rng( 1, 8 ) ); for( const tripoint &elem : tree ) { here.batter( elem, 300, 5 ); - here.ter_set( elem, t_trunk ); + here.ter_set( elem, ter_t_trunk ); } - here.ter_set( pos, t_stump ); + here.ter_set( pos, ter_t_stump ); who.add_msg_if_player( m_good, _( "You finish chopping down a tree." ) ); // sound of falling tree here.collapse_at( pos, false, true, false ); @@ -6445,7 +6454,7 @@ void churn_activity_actor::finish( player_activity &act, Character &who ) { map &here = get_map(); who.add_msg_if_player( _( "You finish churning up the earth here." ) ); - here.ter_set( here.getlocal( act.placement ), t_dirtmound ); + here.ter_set( here.getlocal( act.placement ), ter_t_dirtmound ); // Go back to what we were doing before // could be player zone activity, or could be NPC multi-farming act.set_to_null(); diff --git a/src/activity_handlers.cpp b/src/activity_handlers.cpp index 669bdb58b40f4..62f4a4d7e7be0 100644 --- a/src/activity_handlers.cpp +++ b/src/activity_handlers.cpp @@ -228,6 +228,9 @@ static const species_id species_FERAL( "FERAL" ); static const species_id species_HUMAN( "HUMAN" ); static const species_id species_ZOMBIE( "ZOMBIE" ); +static const ter_str_id ter_t_dirt( "t_dirt" ); +static const ter_str_id ter_t_tree( "t_tree" ); + static const trait_id trait_DEBUG_HS( "DEBUG_HS" ); static const trait_id trait_SPIRITUAL( "SPIRITUAL" ); static const trait_id trait_STOCKY_TROGLO( "STOCKY_TROGLO" ); @@ -1670,7 +1673,7 @@ void activity_handlers::pickaxe_finish( player_activity *act, Character *you ) if( you->is_avatar() ) { const int helpersize = get_player_character().get_num_crafting_helpers( 3 ); if( here.is_bashable( pos ) && here.has_flag( ter_furn_flag::TFLAG_SUPPORTS_ROOF, pos ) && - here.ter( pos ) != t_tree ) { + here.ter( pos ) != ter_t_tree ) { // Tunneling through solid rock is sweaty, backbreaking work // Betcha wish you'd opted for the J-Hammer if( you->has_trait( trait_STOCKY_TROGLO ) ) { @@ -3273,7 +3276,7 @@ void activity_handlers::plant_seed_finish( player_activity *act, Character *you if( here.has_flag_furn( seed_id->seed->required_terrain_flag, examp ) ) { here.furn_set( examp, furn_str_id( here.furn( examp )->plant->transform ) ); } else if( seed_id->seed->required_terrain_flag == ter_furn_flag::TFLAG_PLANTABLE ) { - here.set( examp, t_dirt, f_plant_seed ); + here.set( examp, ter_t_dirt, f_plant_seed ); } else { here.furn_set( examp, f_plant_seed ); } diff --git a/src/activity_item_handling.cpp b/src/activity_item_handling.cpp index 7de946961128e..abc53d671cd3b 100644 --- a/src/activity_item_handling.cpp +++ b/src/activity_item_handling.cpp @@ -118,6 +118,9 @@ static const quality_id qual_WELD( "WELD" ); static const requirement_id requirement_data_mining_standard( "mining_standard" ); +static const ter_str_id ter_t_stump( "t_stump" ); +static const ter_str_id ter_t_trunk( "t_trunk" ); + static const trait_id trait_SAPROPHAGE( "SAPROPHAGE" ); static const trait_id trait_SAPROVORE( "SAPROVORE" ); @@ -1167,8 +1170,8 @@ static activity_reason_info can_do_activity_there( const activity_id &act, Chara } } if( act == ACT_MULTIPLE_CHOP_TREES ) { - if( here.has_flag( ter_furn_flag::TFLAG_TREE, src_loc ) || here.ter( src_loc ) == t_trunk || - here.ter( src_loc ) == t_stump ) { + if( here.has_flag( ter_furn_flag::TFLAG_TREE, src_loc ) || here.ter( src_loc ) == ter_t_trunk || + here.ter( src_loc ) == ter_t_stump ) { if( you.has_quality( qual_AXE ) ) { return activity_reason_info::ok( do_activity_reason::NEEDS_TREE_CHOPPING ); } else { @@ -2456,7 +2459,7 @@ static bool chop_tree_activity( Character &you, const tripoint_bub_ms &src_loc ) you.assign_activity( chop_tree_activity_actor( moves, item_location( you, &best_qual ) ) ); you.activity.placement = here.getglobal( src_loc ); return true; - } else if( ter == t_trunk || ter == t_stump ) { + } else if( ter == ter_t_trunk || ter == ter_t_stump ) { you.assign_activity( chop_logs_activity_actor( moves, item_location( you, &best_qual ) ) ); you.activity.placement = here.getglobal( src_loc ); return true; diff --git a/src/avatar.cpp b/src/avatar.cpp index f84ab64bf4b84..a3eaff6ba6bbd 100644 --- a/src/avatar.cpp +++ b/src/avatar.cpp @@ -121,6 +121,13 @@ static const move_mode_id move_mode_walk( "walk" ); static const string_id monfaction_player( "player" ); +static const ter_str_id ter_t_dirt( "t_dirt" ); +static const ter_str_id ter_t_dirtmound( "t_dirtmound" ); +static const ter_str_id ter_t_floor( "t_floor" ); +static const ter_str_id ter_t_grass( "t_grass" ); +static const ter_str_id ter_t_pit( "t_pit" ); +static const ter_str_id ter_t_pit_shallow( "t_pit_shallow" ); + static const trait_id trait_ARACHNID_ARMS( "ARACHNID_ARMS" ); static const trait_id trait_ARACHNID_ARMS_OK( "ARACHNID_ARMS_OK" ); static const trait_id trait_CENOBITE( "CENOBITE" ); @@ -1929,10 +1936,8 @@ void avatar::try_to_sleep( const time_duration &dur ) bool watersleep = false; if( has_trait( trait_CHLOROMORPH ) ) { plantsleep = true; - if( ( ter_at_pos == t_dirt || ter_at_pos == t_pit || - ter_at_pos == t_dirtmound || ter_at_pos == t_pit_shallow || - ter_at_pos == t_grass ) && !vp && - furn_at_pos == f_null ) { + const std::unordered_set comfy_ters = { ter_t_dirt, ter_t_dirtmound, ter_t_grass, ter_t_pit, ter_t_pit_shallow }; + if( comfy_ters.find( ter_at_pos.id() ) != comfy_ters.end() && !vp && furn_at_pos == f_null ) { add_msg_if_player( m_good, _( "You relax as your roots embrace the soil." ) ); } else if( vp ) { add_msg_if_player( m_bad, _( "It's impossible to sleep in this wheeled pot!" ) ); @@ -2004,7 +2009,7 @@ void avatar::try_to_sleep( const time_duration &dur ) vp.part_with_feature( "BED", true ) ) ) { add_msg_if_player( m_good, _( "This is a comfortable place to sleep." ) ); } else if( !plantsleep && !fungaloid_cosplay && !watersleep ) { - if( !vp && ter_at_pos != t_floor ) { + if( !vp && ter_at_pos != ter_t_floor ) { add_msg_if_player( ter_at_pos.obj().movecost <= 2 ? _( "It's a little hard to get to sleep on this %s." ) : _( "It's hard to get to sleep on this %s." ), diff --git a/src/avatar_action.cpp b/src/avatar_action.cpp index 84d35e46e8bbe..010703d79e61f 100644 --- a/src/avatar_action.cpp +++ b/src/avatar_action.cpp @@ -78,6 +78,18 @@ static const move_mode_id move_mode_prone( "prone" ); static const skill_id skill_swimming( "swimming" ); +static const ter_str_id ter_t_door_bar_locked( "t_door_bar_locked" ); +static const ter_str_id ter_t_door_locked( "t_door_locked" ); +static const ter_str_id ter_t_door_locked_alarm( "t_door_locked_alarm" ); +static const ter_str_id ter_t_door_locked_interior( "t_door_locked_interior" ); +static const ter_str_id ter_t_door_locked_peep( "t_door_locked_peep" ); +static const ter_str_id ter_t_fault( "t_fault" ); +static const ter_str_id ter_t_grass( "t_grass" ); +static const ter_str_id ter_t_grass_alien( "t_grass_alien" ); +static const ter_str_id ter_t_grass_dead( "t_grass_dead" ); +static const ter_str_id ter_t_grass_golf( "t_grass_golf" ); +static const ter_str_id ter_t_grass_white( "t_grass_white" ); + static const trait_id trait_GRAZER( "GRAZER" ); static const trait_id trait_RUMINANT( "RUMINANT" ); static const trait_id trait_SHELL2( "SHELL2" ); @@ -294,7 +306,7 @@ bool avatar_action::move( avatar &you, map &m, const tripoint &d ) const tripoint minp = tripoint( 0, 0, you.posz() ); const tripoint maxp = tripoint( MAPSIZE_X, MAPSIZE_Y, you.posz() ); for( const tripoint &pt : m.points_in_rectangle( minp, maxp ) ) { - if( m.ter( pt ) == t_fault ) { + if( m.ter( pt ) == ter_t_fault ) { int dist = rl_dist( pt, you.pos() ); if( dist < curdist ) { curdist = dist; @@ -534,12 +546,12 @@ bool avatar_action::move( avatar &you, map &m, const tripoint &d ) if( waste_moves ) { you.mod_moves( -you.get_speed() ); } - } else if( m.ter( dest_loc ) == t_door_locked || m.ter( dest_loc ) == t_door_locked_peep || - m.ter( dest_loc ) == t_door_locked_alarm || m.ter( dest_loc ) == t_door_locked_interior ) { + } else if( m.ter( dest_loc ) == ter_t_door_bar_locked ) { + add_msg( _( "You rattle the bars but the door is locked!" ) ); + } else if( const std::unordered_set locked_doors = { ter_t_door_locked, ter_t_door_locked_peep, ter_t_door_locked_alarm, ter_t_door_locked_interior }; + locked_doors.find( m.ter( dest_loc ).id() ) != locked_doors.end() ) { // Don't drain move points for learning something you could learn just by looking add_msg( _( "That door is locked!" ) ); - } else if( m.ter( dest_loc ) == t_door_bar_locked ) { - add_msg( _( "You rattle the bars but the door is locked!" ) ); } return false; } @@ -876,7 +888,7 @@ bool avatar_action::eat_here( avatar &you ) add_msg( _( "You're too full to eat the leaves from the %s." ), here.ter( you.pos() )->name() ); return true; } else { - here.ter_set( you.pos(), t_grass ); + here.ter_set( you.pos(), ter_t_grass ); item food( "underbrush", calendar::turn, 1 ); you.assign_activity( consume_activity_actor( food ) ); return true; @@ -909,16 +921,17 @@ bool avatar_action::eat_here( avatar &you ) } } if( you.has_active_mutation( trait_GRAZER ) ) { - if( here.ter( you.pos() ) == t_grass_golf || here.ter( you.pos() ) == t_grass ) { + const ter_id &ter_underfoot = here.ter( you.pos() ); + if( ter_underfoot == ter_t_grass_golf || ter_underfoot == ter_t_grass ) { add_msg( _( "This grass is too short to graze." ) ); return true; - } else if( here.ter( you.pos() ) == t_grass_dead ) { + } else if( ter_underfoot == ter_t_grass_dead ) { add_msg( _( "This grass is dead and too mangled for you to graze." ) ); return true; - } else if( here.ter( you.pos() ) == t_grass_white ) { + } else if( ter_underfoot == ter_t_grass_white ) { add_msg( _( "This grass is tainted with paint and thus inedible." ) ); return true; - } else if( here.ter( you.pos() ) == t_grass_alien ) { + } else if( ter_underfoot == ter_t_grass_alien ) { add_msg( _( "This grass is razor sharp and would probably shred your mouth." ) ); return true; } diff --git a/src/build_reqs.h b/src/build_reqs.h index 66fe94fe69db0..6b08bbf2a3b6e 100644 --- a/src/build_reqs.h +++ b/src/build_reqs.h @@ -40,6 +40,6 @@ struct parameterized_build_reqs { build_reqs get_build_reqs_for_furn_ter_ids( const std::pair, std::map> &changed_ids, - ter_id const &base_ter = t_dirt ); + ter_id const &base_ter = ter_str_id( "t_dirt" ).id() ); #endif // CATA_SRC_BUILD_REQS_H diff --git a/src/cata_imgui.cpp b/src/cata_imgui.cpp index a090b75ff23c4..40439cb2b087e 100644 --- a/src/cata_imgui.cpp +++ b/src/cata_imgui.cpp @@ -266,6 +266,16 @@ void cataimgui::client::process_input( void *input ) #endif +bool cataimgui::client::auto_size_frame_active() +{ + for( const ImGuiWindow *window : GImGui->Windows ) { + if( window->AutoFitFramesX > 0 || window->AutoFitFramesY > 0 ) { + return true; + } + } + return false; +} + static ImGuiKey cata_key_to_imgui( int cata_key ) { switch( cata_key ) { diff --git a/src/cata_imgui.h b/src/cata_imgui.h index a299e35b60c5c..9f5e2b077ad37 100644 --- a/src/cata_imgui.h +++ b/src/cata_imgui.h @@ -68,6 +68,7 @@ class client const SDL_Window_Ptr &sdl_window; const GeometryRenderer_Ptr &sdl_geometry; #endif + bool auto_size_frame_active(); }; void point_to_imvec2( point *src, ImVec2 *dest ); diff --git a/src/cata_tiles.cpp b/src/cata_tiles.cpp index 96578807bdfd6..76e7a986ca918 100644 --- a/src/cata_tiles.cpp +++ b/src/cata_tiles.cpp @@ -79,7 +79,9 @@ static const efftype_id effect_ridden( "ridden" ); static const itype_id itype_corpse( "corpse" ); + static const trait_id trait_INATTENTIVE( "INATTENTIVE" ); + static const trap_str_id tr_unfinished_construction( "tr_unfinished_construction" ); static const std::string ITEM_HIGHLIGHT( "highlight_item" ); @@ -4839,15 +4841,15 @@ void cata_tiles::get_terrain_orientation( const tripoint &p, int &rota, int &sub { map &here = get_map(); const bool overridden = ter_override.find( p ) != ter_override.end(); - const auto ter = [&]( const tripoint & q, const bool invis ) -> ter_id { - const auto override = ter_override.find( q ); - return override != ter_override.end() ? override->second : - ( !overridden || !invis ) ? here.ter( q ) : t_null; + const auto ter = [&]( const tripoint & q, const bool invis ) -> ter_str_id { + const auto override_it = ter_override.find( q ); + return override_it != ter_override.end() ? override_it->second.id() : + ( !overridden || !invis ) ? here.ter( q ).id() : ter_str_id::NULL_ID(); }; // get terrain at x,y const ter_id tid = ter( p, invisible[0] ); - if( tid == t_null ) { + if( tid == ter_str_id::NULL_ID() ) { subtile = 0; rota = 0; return; diff --git a/src/character.cpp b/src/character.cpp index ee91b6d6d7690..8bb54a086dd00 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -388,6 +388,12 @@ static const species_id species_HUMAN( "HUMAN" ); static const start_location_id start_location_sloc_shelter_a( "sloc_shelter_a" ); +static const ter_str_id ter_t_dirt( "t_dirt" ); +static const ter_str_id ter_t_dirtmound( "t_dirtmound" ); +static const ter_str_id ter_t_grass( "t_grass" ); +static const ter_str_id ter_t_pit( "t_pit" ); +static const ter_str_id ter_t_pit_shallow( "t_pit_shallow" ); + static const trait_id trait_ADRENALINE( "ADRENALINE" ); static const trait_id trait_ANTENNAE( "ANTENNAE" ); static const trait_id trait_BADBACK( "BADBACK" ); @@ -5647,12 +5653,12 @@ Character::comfort_response_t Character::base_comfort_value( const tripoint_bub_ comfort = static_cast( comfort_level::impossible ); } else { // It's very easy for Chloromorphs to get to sleep on soil! - if( ter_at_pos == t_dirt || ter_at_pos == t_pit || ter_at_pos == t_dirtmound || - ter_at_pos == t_pit_shallow ) { + const std::unordered_set very_comfy_ters = { ter_t_dirt, ter_t_dirtmound, ter_t_pit, ter_t_pit_shallow }; + if( very_comfy_ters.find( ter_at_pos.id() ) != very_comfy_ters.end() ) { comfort += static_cast( comfort_level::very_comfortable ); } // Not as much if you have to dig through stuff first - else if( ter_at_pos == t_grass ) { + else if( ter_at_pos == ter_t_grass ) { comfort += static_cast( comfort_level::comfortable ); } // Sleep ain't happening @@ -7586,7 +7592,7 @@ std::string get_stat_name( character_stat Stat ) return pgettext( "fake stat there's an error", "ERR" ); } -int Character::mutation_height( const trait_id &mut ) +int Character::mutation_height( const trait_id &mut ) const { const mutation_branch &mdata = mut.obj(); int height_prereqs = 0; diff --git a/src/character.h b/src/character.h index 751374d2f7c4a..dffa4b0c53683 100644 --- a/src/character.h +++ b/src/character.h @@ -1042,6 +1042,25 @@ class Character : public Creature, public visitable steed_type get_steed_type() const; virtual void set_movement_mode( const move_mode_id &mode ) = 0; + /** + * Generates an integer based on how many times we've gained non-negative mutations. + * This is asked for any given tree, but counts all of our mutations in total. + * Different than mutation_category_level[] in many ways: + * - Does not count base traits, even if those are mutable, whereas mutation_category_level[] does. + * - Does not count negative mutations, whereas mutation_category_level[] does. + * - Assigns 1 point to each level of mutation in our category, and 2 for each level out of it. + * - Individually counts each step of a multi level mutation (it counts Strong *and* Very Strong as their own mutations). + * - mutation_category_level[] ignores Strong and counts Very Strong as slightly more than 1 mutation, but not 2 mutations. + * - Meanwhile this counts Very Strong as 2 mutations, since you had to mutate Strong and then mutate that into Very Strong. + * - This is to mimic the behavior of the old instability vitamin, which increased by 100 each time you mutated (so Very Strong was 200 instability). + * The final result is used to calculate our current instability (influences chance of a negative mutation) + * so each mutation we have that belongs to a different tree than the one we specified counts double. + * Example: you start with Trog and mutate Slimy and Night Vision. Within Trog you have 2 points. + * You then go to mutate Rat. Rat has Night Vision but not Slimy, so you have 1+2=3 points. + * Having the Robust Genetics trait lets you "negate" this penalty, and makes all traits worth just 1 instability whether in/out of tree. + */ + int get_instability_per_category( const mutation_category_id &categ ) const; + /**Determine if character is susceptible to dis_type and if so apply the symptoms*/ void expose_to_disease( const diseasetype_id &dis_type ); /** @@ -1584,8 +1603,8 @@ class Character : public Creature, public visitable const vitamin_id &mut_vit ) const; bool mutation_ok( const trait_id &mutation, bool allow_good, bool allow_bad, bool allow_neutral ) const; - /** Roll, based on instability, whether next mutation should be good or bad */ - bool roll_bad_mutation() const; + /** Roll, based on category and total mutations in/out of it, whether next mutation should be good or bad */ + bool roll_bad_mutation( const mutation_category_id &categ ) const; /** Opens a menu which allows players to choose from a list of mutations */ bool mutation_selector( const std::vector &prospective_traits, const mutation_category_id &cat, const bool &use_vitamins ); @@ -1610,7 +1629,7 @@ class Character : public Creature, public visitable /** Try to cross The Threshold */ void test_crossing_threshold( const mutation_category_id &mutation_category ); /** Returns how many steps are required to reach a mutation */ - int mutation_height( const trait_id &mut ); + int mutation_height( const trait_id &mut ) const; /** Recalculates mutation_category_level[] values for the player */ void calc_mutation_levels(); /** Returns a weighted list of mutation categories based on blood vitamin levels */ diff --git a/src/character_proficiency.cpp b/src/character_proficiency.cpp index e0d8218138048..76121e0681702 100644 --- a/src/character_proficiency.cpp +++ b/src/character_proficiency.cpp @@ -60,11 +60,13 @@ bool Character::practice_proficiency( const proficiency_id &prof, const time_dur { // Proficiencies can ignore focus using the `ignore_focus` JSON property const bool ignore_focus = prof->ignore_focus(); + float focus_adjusted = adjust_for_focus( to_seconds( amount ) ); const time_duration &focused_amount = ignore_focus ? amount : time_duration::from_seconds( - adjust_for_focus( to_seconds( amount ) ) ); + focus_adjusted ); const float pct_before = _proficiencies->pct_practiced( prof ); - const bool learned = _proficiencies->practice( prof, focused_amount, max ); + const bool learned = _proficiencies->practice( prof, focused_amount, + ignore_focus ? 0.f : std::fmod( focus_adjusted, 1.f ), max ); const float pct_after = _proficiencies->pct_practiced( prof ); // Drain focus if necessary @@ -106,7 +108,7 @@ void Character::set_proficiency_practice( const proficiency_id &id, const time_d return; } - _proficiencies->practice( id, amount, std::nullopt ); + _proficiencies->practice( id, amount, 0.f, std::nullopt ); } std::vector Character::proficiencies_offered_to( const Character *guy ) const diff --git a/src/computer_session.cpp b/src/computer_session.cpp index 63299c8b3867a..1a8ac82cb7931 100644 --- a/src/computer_session.cpp +++ b/src/computer_session.cpp @@ -65,6 +65,7 @@ static const efftype_id effect_amigara( "amigara" ); static const furn_str_id furn_f_centrifuge( "f_centrifuge" ); static const furn_str_id furn_f_console_broken( "f_console_broken" ); +static const furn_str_id furn_f_rubble_rock( "f_rubble_rock" ); static const itype_id itype_black_box( "black_box" ); static const itype_id itype_blood( "blood" ); @@ -101,6 +102,35 @@ static const skill_id skill_computer( "computer" ); static const species_id species_HUMAN( "HUMAN" ); static const species_id species_ZOMBIE( "ZOMBIE" ); +static const ter_str_id ter_t_concrete( "t_concrete" ); +static const ter_str_id ter_t_concrete_wall( "t_concrete_wall" ); +static const ter_str_id ter_t_door_metal_c( "t_door_metal_c" ); +static const ter_str_id ter_t_door_metal_locked( "t_door_metal_locked" ); +static const ter_str_id ter_t_elevator( "t_elevator" ); +static const ter_str_id ter_t_elevator_control( "t_elevator_control" ); +static const ter_str_id ter_t_elevator_control_off( "t_elevator_control_off" ); +static const ter_str_id ter_t_floor( "t_floor" ); +static const ter_str_id ter_t_floor_blue( "t_floor_blue" ); +static const ter_str_id ter_t_floor_green( "t_floor_green" ); +static const ter_str_id ter_t_floor_red( "t_floor_red" ); +static const ter_str_id ter_t_grate( "t_grate" ); +static const ter_str_id ter_t_hole( "t_hole" ); +static const ter_str_id ter_t_metal_floor( "t_metal_floor" ); +static const ter_str_id ter_t_missile( "t_missile" ); +static const ter_str_id ter_t_rad_platform( "t_rad_platform" ); +static const ter_str_id ter_t_radio_tower( "t_radio_tower" ); +static const ter_str_id ter_t_reinforced_glass( "t_reinforced_glass" ); +static const ter_str_id ter_t_reinforced_glass_shutter( "t_reinforced_glass_shutter" ); +static const ter_str_id ter_t_reinforced_glass_shutter_open( "t_reinforced_glass_shutter_open" ); +static const ter_str_id ter_t_sewage( "t_sewage" ); +static const ter_str_id ter_t_sewage_pipe( "t_sewage_pipe" ); +static const ter_str_id ter_t_sewage_pump( "t_sewage_pump" ); +static const ter_str_id ter_t_thconc_floor( "t_thconc_floor" ); +static const ter_str_id ter_t_vat( "t_vat" ); +static const ter_str_id ter_t_wall_glass( "t_wall_glass" ); +static const ter_str_id ter_t_wall_metal( "t_wall_metal" ); +static const ter_str_id ter_t_water_pool( "t_water_pool" ); + static catacurses::window init_window() { const int width = FULL_SCREEN_WIDTH; @@ -345,14 +375,14 @@ bool computer_session::can_activate( computer_action action ) { switch( action ) { case COMPACT_LOCK: - return get_map().has_nearby_ter( get_player_character().pos(), t_door_metal_c, 8 ); + return get_map().has_nearby_ter( get_player_character().pos(), ter_t_door_metal_c, 8 ); case COMPACT_RELEASE: case COMPACT_RELEASE_DISARM: - return get_map().has_nearby_ter( get_player_character().pos(), t_reinforced_glass, 25 ); + return get_map().has_nearby_ter( get_player_character().pos(), ter_t_reinforced_glass, 25 ); case COMPACT_RELEASE_BIONICS: - return get_map().has_nearby_ter( get_player_character().pos(), t_reinforced_glass, 3 ); + return get_map().has_nearby_ter( get_player_character().pos(), ter_t_reinforced_glass, 3 ); case COMPACT_TERMINATE: { map &here = get_map(); @@ -362,10 +392,10 @@ bool computer_session::can_activate( computer_action action ) if( !mon ) { continue; } - if( ( here.ter( p + tripoint_north ) == t_reinforced_glass && - here.ter( p + tripoint_south ) == t_concrete_wall ) || - ( here.ter( p + tripoint_south ) == t_reinforced_glass && - here.ter( p + tripoint_north ) == t_concrete_wall ) ) { + if( ( here.ter( p + tripoint_north ) == ter_t_reinforced_glass && + here.ter( p + tripoint_south ) == ter_t_concrete_wall ) || + ( here.ter( p + tripoint_south ) == ter_t_reinforced_glass && + here.ter( p + tripoint_north ) == ter_t_concrete_wall ) ) { return true; } } @@ -374,7 +404,7 @@ bool computer_session::can_activate( computer_action action ) case COMPACT_UNLOCK: case COMPACT_UNLOCK_DISARM: - return get_map().has_nearby_ter( get_player_character().pos(), t_door_metal_locked, 8 ); + return get_map().has_nearby_ter( get_player_character().pos(), ter_t_door_metal_locked, 8 ); default: return true; @@ -399,21 +429,22 @@ void computer_session::action_open_disarm() void computer_session::action_open() { - get_map().translate_radius( t_door_metal_locked, t_floor, 25.0, get_player_character().pos(), + get_map().translate_radius( ter_t_door_metal_locked, ter_t_floor, 25.0, + get_player_character().pos(), true ); query_any( _( "Doors opened. Press any key…" ) ); } void computer_session::action_open_gate() { - get_map().translate_radius( t_wall_metal, t_metal_floor, 8.0, get_player_character().pos(), + get_map().translate_radius( ter_t_wall_metal, ter_t_metal_floor, 8.0, get_player_character().pos(), true ); query_any( _( "Gates opened. Press any key…" ) ); } void computer_session::action_close_gate() { - get_map().translate_radius( t_metal_floor, t_wall_metal, 8.0, get_player_character().pos(), + get_map().translate_radius( ter_t_metal_floor, ter_t_wall_metal, 8.0, get_player_character().pos(), true ); query_any( _( "Gates closed. Press any key…" ) ); } @@ -425,7 +456,8 @@ void computer_session::action_close_gate() // player position to determine which terrain tiles to edit. void computer_session::action_lock() { - get_map().translate_radius( t_door_metal_c, t_door_metal_locked, 8.0, get_player_character().pos(), + get_map().translate_radius( ter_t_door_metal_c, ter_t_door_metal_locked, 8.0, + get_player_character().pos(), true ); query_any( _( "Lock enabled. Press any key…" ) ); } @@ -438,7 +470,8 @@ void computer_session::action_unlock_disarm() void computer_session::action_unlock() { - get_map().translate_radius( t_door_metal_locked, t_door_metal_c, 8.0, get_player_character().pos(), + get_map().translate_radius( ter_t_door_metal_locked, ter_t_door_metal_c, 8.0, + get_player_character().pos(), true ); query_any( _( "Lock disabled. Press any key…" ) ); } @@ -465,7 +498,7 @@ void computer_session::action_sample() get_player_character().mod_moves( -to_moves( 1_seconds ) * 0.3 ); map &here = get_map(); for( const tripoint &p : here.points_on_zlevel() ) { - if( here.ter( p ) != t_sewage_pump ) { + if( here.ter( p ) != ter_t_sewage_pump ) { continue; } for( const tripoint &n : here.points_in_radius( p, 1 ) ) { @@ -500,7 +533,8 @@ void computer_session::action_release() sounds::sound( player_character.pos(), 40, sounds::sound_t::alarm, _( "an alarm sound!" ), false, "environment", "alarm" ); - get_map().translate_radius( t_reinforced_glass, t_thconc_floor, 25.0, player_character.pos(), + get_map().translate_radius( ter_t_reinforced_glass, ter_t_thconc_floor, 25.0, + player_character.pos(), true ); query_any( _( "Containment shields opened. Press any key…" ) ); } @@ -517,7 +551,8 @@ void computer_session::action_release_bionics() sounds::sound( player_character.pos(), 40, sounds::sound_t::alarm, _( "an alarm sound!" ), false, "environment", "alarm" ); - get_map().translate_radius( t_reinforced_glass, t_thconc_floor, 3.0, player_character.pos(), true ); + get_map().translate_radius( ter_t_reinforced_glass, ter_t_thconc_floor, 3.0, player_character.pos(), + true ); query_any( _( "Containment shields opened. Press any key…" ) ); } @@ -532,10 +567,10 @@ void computer_session::action_terminate() if( !mon ) { continue; } - if( ( here.ter( p + tripoint_north ) == t_reinforced_glass && - here.ter( p + tripoint_south ) == t_concrete_wall ) || - ( here.ter( p + tripoint_south ) == t_reinforced_glass && - here.ter( p + tripoint_north ) == t_concrete_wall ) ) { + if( ( here.ter( p + tripoint_north ) == ter_t_reinforced_glass && + here.ter( p + tripoint_south ) == ter_t_concrete_wall ) || + ( here.ter( p + tripoint_south ) == ter_t_reinforced_glass && + here.ter( p + tripoint_north ) == ter_t_concrete_wall ) ) { mon->die( &player_character ); } } @@ -549,7 +584,7 @@ void computer_session::action_portal() for( const tripoint &tmp : here.points_on_zlevel() ) { int numtowers = 0; for( const tripoint &tmp2 : here.points_in_radius( tmp, 2 ) ) { - if( here.ter( tmp2 ) == t_radio_tower ) { + if( here.ter( tmp2 ) == ter_t_radio_tower ) { numtowers++; } } @@ -573,7 +608,7 @@ void computer_session::action_cascade() map &here = get_map(); std::vector cascade_points; for( const tripoint &dest : here.points_in_radius( player_pos, 10 ) ) { - if( here.ter( dest ) == t_radio_tower ) { + if( here.ter( dest ) == ter_t_radio_tower ) { cascade_points.push_back( dest ); } } @@ -725,9 +760,9 @@ void computer_session::action_miss_launch() false ); if( level < 0 ) { - tmpmap.translate( t_missile, t_hole ); + tmpmap.translate( ter_t_missile, ter_t_hole ); } else { - tmpmap.translate( t_metal_floor, t_hole ); + tmpmap.translate( ter_t_metal_floor, ter_t_hole ); } tmpmap.save(); } @@ -843,8 +878,8 @@ void computer_session::action_elevator_on() { map &here = get_map(); for( const tripoint &p : here.points_on_zlevel() ) { - if( here.ter( p ) == t_elevator_control_off ) { - here.ter_set( p, t_elevator_control ); + if( here.ter( p ) == ter_t_elevator_control_off ) { + here.ter_set( p, ter_t_elevator_control ); } } query_any( _( "Elevator activated. Press any key…" ) ); @@ -1049,7 +1084,7 @@ void computer_session::action_data_anal() player_character.mod_moves( -to_moves( 1_seconds ) * 0.3 ); map &here = get_map(); for( const tripoint &dest : here.points_in_radius( player_character.pos(), 2 ) ) { - if( here.ter( dest ) == t_floor_blue ) { + if( here.ter( dest ) == ter_t_floor_blue ) { print_error( _( "PROCESSING DATA" ) ); map_stack items = here.i_at( dest ); if( items.empty() ) { @@ -1183,18 +1218,19 @@ void computer_session::action_srcf_seal() add_msg( m_warning, _( "Evacuate Immediately!" ) ); map &here = get_map(); for( const tripoint &p : here.points_on_zlevel() ) { - if( here.ter( p ) == t_elevator || here.ter( p ) == t_vat ) { - here.make_rubble( p, f_rubble_rock, true ); + if( here.ter( p ) == ter_t_elevator || here.ter( p ) == ter_t_vat ) { + here.make_rubble( p, furn_f_rubble_rock, true ); explosion_handler::explosion( &get_player_character(), p, 40, 0.7, true ); } - if( here.ter( p ) == t_wall_glass ) { - here.make_rubble( p, f_rubble_rock, true ); + if( here.ter( p ) == ter_t_wall_glass ) { + here.make_rubble( p, furn_f_rubble_rock, true ); } - if( here.ter( p ) == t_sewage_pipe || here.ter( p ) == t_sewage || here.ter( p ) == t_grate ) { - here.make_rubble( p, f_rubble_rock, true ); + if( here.ter( p ) == ter_t_sewage_pipe || here.ter( p ) == ter_t_sewage || + here.ter( p ) == ter_t_grate ) { + here.make_rubble( p, furn_f_rubble_rock, true ); } - if( here.ter( p ) == t_sewage_pump ) { - here.make_rubble( p, f_rubble_rock, true ); + if( here.ter( p ) == ter_t_sewage_pump ) { + here.make_rubble( p, furn_f_rubble_rock, true ); explosion_handler::explosion( &get_player_character(), p, 50, 0.7, true ); } } @@ -1214,16 +1250,16 @@ void computer_session::action_srcf_elevator() bool is_underground_elevator_exist = false; for( const tripoint &p : here.points_on_zlevel( 0 ) ) { - if( here.ter( p ) == t_elevator_control_off || here.ter( p ) == t_elevator_control ) { + if( here.ter( p ) == ter_t_elevator_control_off || here.ter( p ) == ter_t_elevator_control ) { surface_elevator = p; - is_surface_elevator_on = here.ter( p ) == t_elevator_control; + is_surface_elevator_on = here.ter( p ) == ter_t_elevator_control; is_surface_elevator_exist = true; } } for( const tripoint &p : here.points_on_zlevel( -2 ) ) { - if( here.ter( p ) == t_elevator_control_off || here.ter( p ) == t_elevator_control ) { + if( here.ter( p ) == ter_t_elevator_control_off || here.ter( p ) == ter_t_elevator_control ) { underground_elevator = p; - is_underground_elevator_on = here.ter( p ) == t_elevator_control; + is_underground_elevator_on = here.ter( p ) == ter_t_elevator_control; is_underground_elevator_exist = true; } } @@ -1241,21 +1277,21 @@ void computer_session::action_srcf_elevator() print_error( _( "Access code required!\n\n" ) ); } else { player_character.use_amount( itype_sarcophagus_access_code, 1 ); - here.ter_set( surface_elevator, t_elevator_control ); + here.ter_set( surface_elevator, ter_t_elevator_control ); is_surface_elevator_on = true; - here.ter_set( underground_elevator, t_elevator_control ); + here.ter_set( underground_elevator, ter_t_elevator_control ); is_underground_elevator_on = true; } } //If only one is enabled, enable the other one. Fix for before this change else if( is_surface_elevator_on && !is_underground_elevator_on && is_underground_elevator_exist ) { - here.ter_set( underground_elevator, t_elevator_control ); + here.ter_set( underground_elevator, ter_t_elevator_control ); is_underground_elevator_on = true; } else if( is_underground_elevator_on && !is_surface_elevator_on && is_surface_elevator_exist ) { - here.ter_set( surface_elevator, t_elevator_control ); + here.ter_set( surface_elevator, ter_t_elevator_control ); is_surface_elevator_on = true; } @@ -1269,7 +1305,7 @@ void computer_session::action_srcf_elevator() query_any( _( "Press any key…" ) ); } -//irradiates food at t_rad_platform, adds radiation +//irradiates food at ter_t_rad_platform, adds radiation void computer_session::action_irradiator() { Character &player_character = get_player_character(); @@ -1278,7 +1314,7 @@ void computer_session::action_irradiator() bool platform_exists = false; map &here = get_map(); for( const tripoint &dest : here.points_in_radius( player_character.pos(), 10 ) ) { - if( here.ter( dest ) == t_rad_platform ) { + if( here.ter( dest ) == ter_t_rad_platform ) { platform_exists = true; if( here.i_at( dest ).empty() ) { print_error( _( "ERROR: Processing platform empty." ) ); @@ -1305,7 +1341,7 @@ void computer_session::action_irradiator() here.i_rem( dest, it ); here.make_rubble( dest ); here.propagate_field( dest, fd_nuke_gas, 100, 3 ); - here.translate_radius( t_water_pool, t_sewage, 8.0, dest, true ); + here.translate_radius( ter_t_water_pool, ter_t_sewage, 8.0, dest, true ); here.adjust_radiation( dest, rng( 50, 500 ) ); for( const tripoint &radorigin : here.points_in_radius( dest, 5 ) ) { here.adjust_radiation( radorigin, rng( 50, 500 ) / ( rl_dist( radorigin, @@ -1348,7 +1384,7 @@ void computer_session::action_irradiator() } } -// geiger counter for irradiator, primary measurement at t_rad_platform, secondary at player location +// geiger counter for irradiator, primary measurement at ter_t_rad_platform, secondary at player location void computer_session::action_geiger() { Character &player_character = get_player_character(); @@ -1361,7 +1397,7 @@ void computer_session::action_geiger() map &here = get_map(); print_error( _( "RADIATION MEASUREMENTS:" ) ); for( const tripoint &dest : here.points_in_radius( player_character.pos(), 10 ) ) { - if( here.ter( dest ) == t_rad_platform ) { + if( here.ter( dest ) == ter_t_rad_platform ) { source_exists = true; platform = dest; } @@ -1404,13 +1440,13 @@ void computer_session::action_conveyor() bool p_exists = false; map &here = get_map(); for( const tripoint &dest : here.points_in_radius( player_character.pos(), 10 ) ) { - if( here.ter( dest ) == t_rad_platform ) { + if( here.ter( dest ) == ter_t_rad_platform ) { platform = dest; p_exists = true; - } else if( here.ter( dest ) == t_floor_red ) { + } else if( here.ter( dest ) == ter_t_floor_red ) { loading = dest; l_exists = true; - } else if( here.ter( dest ) == t_floor_green ) { + } else if( here.ter( dest ) == ter_t_floor_green ) { unloading = dest; u_exists = true; } @@ -1450,7 +1486,8 @@ void computer_session::action_shutters() { Character &player_character = get_player_character(); player_character.mod_moves( -to_moves( 3_seconds ) ); - get_map().translate_radius( t_reinforced_glass_shutter_open, t_reinforced_glass_shutter, 8.0, + get_map().translate_radius( ter_t_reinforced_glass_shutter_open, ter_t_reinforced_glass_shutter, + 8.0, player_character.pos(), true, true ); query_any( _( "Toggling shutters. Press any key…" ) ); @@ -1466,14 +1503,14 @@ void computer_session::action_extract_rad_source() bool p_exists = false; map &here = get_map(); for( const tripoint &dest : here.points_in_radius( player_character.pos(), 10 ) ) { - if( here.ter( dest ) == t_rad_platform ) { + if( here.ter( dest ) == ter_t_rad_platform ) { platform = dest; p_exists = true; } } if( p_exists ) { here.spawn_item( platform, itype_cobalt_60, rng( 8, 15 ) ); - here.translate_radius( t_rad_platform, t_concrete, 8.0, player_character.pos(), true ); + here.translate_radius( ter_t_rad_platform, ter_t_concrete, 8.0, player_character.pos(), true ); comp.remove_option( COMPACT_IRRADIATOR ); comp.remove_option( COMPACT_EXTRACT_RAD_SOURCE ); query_any( _( "Extraction sequence complete… Press any key." ) ); @@ -1613,7 +1650,7 @@ void computer_session::failure_pump_explode() add_msg( m_warning, _( "The pump explodes!" ) ); map &here = get_map(); for( const tripoint &p : here.points_on_zlevel() ) { - if( here.ter( p ) == t_sewage_pump ) { + if( here.ter( p ) == ter_t_sewage_pump ) { here.make_rubble( p ); explosion_handler::explosion( &get_player_character(), p, 10 ); } @@ -1625,7 +1662,7 @@ void computer_session::failure_pump_leak() add_msg( m_warning, _( "Sewage leaks!" ) ); map &here = get_map(); for( const tripoint &p : here.points_on_zlevel() ) { - if( here.ter( p ) != t_sewage_pump ) { + if( here.ter( p ) != ter_t_sewage_pump ) { continue; } const int leak_size = rng( 4, 10 ); @@ -1646,7 +1683,7 @@ void computer_session::failure_pump_leak() if( next_move.empty() ) { break; } - here.ter_set( random_entry( next_move ), t_sewage ); + here.ter_set( random_entry( next_move ), ter_t_sewage ); } } } @@ -1695,7 +1732,7 @@ void computer_session::failure_destroy_data() print_error( _( "ERROR: ACCESSING DATA MALFUNCTION" ) ); map &here = get_map(); for( const tripoint &p : here.points_in_radius( get_player_character().pos(), 2 ) ) { - if( here.ter( p ) == t_floor_blue ) { + if( here.ter( p ) == ter_t_floor_blue ) { map_stack items = here.i_at( p ); if( items.empty() ) { print_error( _( "ERROR: Please place memory bank in scan area." ) ); diff --git a/src/construction.cpp b/src/construction.cpp index 20d8662c67436..7f1cdb17b7443 100644 --- a/src/construction.cpp +++ b/src/construction.cpp @@ -98,6 +98,21 @@ static const quality_id qual_CUT( "CUT" ); static const skill_id skill_fabrication( "fabrication" ); +static const ter_str_id ter_t_clay( "t_clay" ); +static const ter_str_id ter_t_dirt( "t_dirt" ); +static const ter_str_id ter_t_hole( "t_hole" ); +static const ter_str_id ter_t_ladder_up( "t_ladder_up" ); +static const ter_str_id ter_t_lava( "t_lava" ); +static const ter_str_id ter_t_open_air( "t_open_air" ); +static const ter_str_id ter_t_pit( "t_pit" ); +static const ter_str_id ter_t_ramp_down_high( "t_ramp_down_high" ); +static const ter_str_id ter_t_ramp_down_low( "t_ramp_down_low" ); +static const ter_str_id ter_t_rock_floor( "t_rock_floor" ); +static const ter_str_id ter_t_sand( "t_sand" ); +static const ter_str_id ter_t_stairs_down( "t_stairs_down" ); +static const ter_str_id ter_t_stairs_up( "t_stairs_up" ); +static const ter_str_id ter_t_wood_stairs_down( "t_wood_stairs_down" ); + static const trait_id trait_DEBUG_HS( "DEBUG_HS" ); static const trait_id trait_EATDEAD( "EATDEAD" ); static const trait_id trait_NUMB( "NUMB" ); @@ -1121,7 +1136,7 @@ void complete_construction( Character *you ) const int_id post_terrain = ter_id( built.post_terrain ); if( post_terrain->roof ) { const tripoint_bub_ms top = terp + tripoint_above; - if( here.ter( top ) == t_open_air ) { + if( here.ter( top ) == ter_t_open_air ) { here.ter_set( top, ter_id( post_terrain->roof ) ); } } @@ -1548,14 +1563,14 @@ void construct::done_digormine_stair( const tripoint_bub_ms &p, bool dig, player_character.mod_thirst( 5 + mine_penalty + no_mut_penalty ); player_character.mod_fatigue( 10 + mine_penalty + no_mut_penalty ); - if( tmpmap.ter( local_tmp ) == t_lava ) { + if( tmpmap.ter( local_tmp ) == ter_t_lava ) { if( !query_yn( _( "The rock feels much warmer than normal. Proceed?" ) ) ) { - here.ter_set( p, t_pit ); // You dug down a bit before detecting the problem + here.ter_set( p, ter_t_pit ); // You dug down a bit before detecting the problem unroll_digging( dig ? 8 : 12 ); } else { add_msg( m_warning, _( "You just tunneled into lava!" ) ); get_event_bus().send(); - here.ter_set( p, t_hole ); + here.ter_set( p, ter_t_hole ); } return; @@ -1569,9 +1584,10 @@ void construct::done_digormine_stair( const tripoint_bub_ms &p, bool dig, } else { add_msg( _( "You drill out a passage, heading deeper underground." ) ); } - here.ter_set( p, t_stairs_down ); // There's the top half + here.ter_set( p, ter_t_stairs_down ); // There's the top half // Again, need to use submap-local coordinates. - tmpmap.ter_set( local_tmp, impassable ? t_stairs_up : t_ladder_up ); // and there's the bottom half. + tmpmap.ter_set( local_tmp, impassable ? ter_t_stairs_up : + ter_t_ladder_up ); // and there's the bottom half. // And save to the center coordinate of the current active map. tmpmap.save(); } @@ -1632,8 +1648,8 @@ void construct::done_mine_upstair( const tripoint_bub_ms &p, Character &player_c tmpmap.load( pos_omt + tripoint_above, false ); const tripoint local_tmp = tmpmap.getlocal( abs_pos ); - if( tmpmap.ter( local_tmp ) == t_lava ) { - here.ter_set( p.xy(), t_rock_floor ); // You dug a bit before discovering the problem + if( tmpmap.ter( local_tmp ) == ter_t_lava ) { + here.ter_set( p.xy(), ter_t_rock_floor ); // You dug a bit before discovering the problem add_msg( m_warning, _( "The rock overhead feels hot. You decide *not* to mine magma." ) ); unroll_digging( 12 ); return; @@ -1641,7 +1657,7 @@ void construct::done_mine_upstair( const tripoint_bub_ms &p, Character &player_c if( tmpmap.has_flag_ter( ter_furn_flag::TFLAG_SHALLOW_WATER, local_tmp ) || tmpmap.has_flag_ter( ter_furn_flag::TFLAG_DEEP_WATER, local_tmp ) ) { - here.ter_set( p.xy(), t_rock_floor ); // You dug a bit before discovering the problem + here.ter_set( p.xy(), ter_t_rock_floor ); // You dug a bit before discovering the problem add_msg( m_warning, _( "The rock above is rather damp. You decide *not* to mine water." ) ); unroll_digging( 12 ); return; @@ -1656,16 +1672,16 @@ void construct::done_mine_upstair( const tripoint_bub_ms &p, Character &player_c player_character.mod_fatigue( 25 + no_mut_penalty ); add_msg( _( "You drill out a passage, heading for the surface." ) ); - here.ter_set( p.xy(), t_stairs_up ); // There's the bottom half + here.ter_set( p.xy(), ter_t_stairs_up ); // There's the bottom half // We need to write to submap-local coordinates. - tmpmap.ter_set( local_tmp, t_stairs_down ); // and there's the top half. + tmpmap.ter_set( local_tmp, ter_t_stairs_down ); // and there's the top half. tmpmap.save(); } void construct::done_wood_stairs( const tripoint_bub_ms &p, Character &/*who*/ ) { const tripoint_bub_ms top = p + tripoint_above; - get_map().ter_set( top, ter_id( "t_wood_stairs_down" ) ); + get_map().ter_set( top, ter_t_wood_stairs_down ); } void construct::done_window_curtains( const tripoint_bub_ms &, Character &who ) @@ -1684,12 +1700,12 @@ void construct::done_extract_maybe_revert_to_dirt( const tripoint_bub_ms &p, Cha { map &here = get_map(); if( one_in( 10 ) ) { - here.ter_set( p, t_dirt ); + here.ter_set( p, ter_t_dirt ); } - if( here.ter( p ) == t_clay ) { + if( here.ter( p ) == ter_t_clay ) { add_msg( _( "You gather some clay." ) ); - } else if( here.ter( p ) == t_sand ) { + } else if( here.ter( p ) == ter_t_sand ) { add_msg( _( "You gather some sand." ) ); } else { // Fall through to an undefined material. @@ -1710,13 +1726,13 @@ void construct::done_mark_practice_target( const tripoint_bub_ms &p, Character & void construct::done_ramp_low( const tripoint_bub_ms &p, Character &/*who*/ ) { const tripoint_bub_ms top = p + tripoint_above; - get_map().ter_set( top, ter_id( "t_ramp_down_low" ) ); + get_map().ter_set( top, ter_t_ramp_down_low ); } void construct::done_ramp_high( const tripoint_bub_ms &p, Character &/*who*/ ) { const tripoint_bub_ms top = p + tripoint_above; - get_map().ter_set( top, ter_id( "t_ramp_down_high" ) ); + get_map().ter_set( top, ter_t_ramp_down_high ); } void construct::do_turn_shovel( const tripoint_bub_ms &p, Character &who ) diff --git a/src/editmap.cpp b/src/editmap.cpp index bb6de87f5f7c2..4d343c7556e98 100644 --- a/src/editmap.cpp +++ b/src/editmap.cpp @@ -66,6 +66,8 @@ static constexpr half_open_cuboid editmap_boundaries( // NOLINTNEXTLINE(cata-static-int_id-constants) static const ter_id undefined_ter_id( -1 ); +static const ter_str_id ter_t_grave_new( "t_grave_new" ); + static std::vector fld_string( const std::string &str, int width ) { std::vector lines; @@ -825,7 +827,7 @@ void editmap::update_view_with_help( const std::string &txt, const std::string & if( here.has_graffiti_at( target ) ) { mvwprintw( w_info, point( 1, off ), - here.ter( target ) == t_grave_new ? _( "Graffiti: %s" ) : _( "Inscription: %s" ), + here.ter( target ) == ter_t_grave_new ? _( "Graffiti: %s" ) : _( "Inscription: %s" ), here.graffiti_at( target ) ); } diff --git a/src/explosion.cpp b/src/explosion.cpp index a0da1844e3eec..53753ae020497 100644 --- a/src/explosion.cpp +++ b/src/explosion.cpp @@ -88,6 +88,13 @@ static const mongroup_id GROUP_NETHER( "GROUP_NETHER" ); static const species_id species_ROBOT( "ROBOT" ); +static const ter_str_id ter_t_card_industrial( "t_card_industrial" ); +static const ter_str_id ter_t_card_military( "t_card_military" ); +static const ter_str_id ter_t_card_reader_broken( "t_card_reader_broken" ); +static const ter_str_id ter_t_card_science( "t_card_science" ); +static const ter_str_id ter_t_door_metal_locked( "t_door_metal_locked" ); +static const ter_str_id ter_t_floor( "t_floor" ); + static const trait_id trait_LEG_TENT_BRACE( "LEG_TENT_BRACE" ); static const trait_id trait_PER_SLIME( "PER_SLIME" ); static const trait_id trait_PER_SLIME_OK( "PER_SLIME_OK" ); @@ -658,14 +665,14 @@ void emp_blast( const tripoint &p ) return; } // TODO: More terrain effects. - if( here.ter( p ) == t_card_science || here.ter( p ) == t_card_military || - here.ter( p ) == t_card_industrial ) { + if( here.ter( p ) == ter_t_card_science || here.ter( p ) == ter_t_card_military || + here.ter( p ) == ter_t_card_industrial ) { int rn = rng( 1, 100 ); if( rn > 92 || rn < 40 ) { if( sight ) { add_msg( _( "The card reader is rendered non-functional." ) ); } - here.ter_set( p, t_card_reader_broken ); + here.ter_set( p, ter_t_card_reader_broken ); } if( rn > 80 ) { if( sight ) { @@ -673,8 +680,8 @@ void emp_blast( const tripoint &p ) } for( int i = -3; i <= 3; i++ ) { for( int j = -3; j <= 3; j++ ) { - if( here.ter( p + tripoint( i, j, 0 ) ) == t_door_metal_locked ) { - here.ter_set( p + tripoint( i, j, 0 ), t_floor ); + if( here.ter( p + tripoint( i, j, 0 ) ) == ter_t_door_metal_locked ) { + here.ter_set( p + tripoint( i, j, 0 ), ter_t_floor ); } } } diff --git a/src/faction_camp.cpp b/src/faction_camp.cpp index c93c92346b068..3f190defe405a 100644 --- a/src/faction_camp.cpp +++ b/src/faction_camp.cpp @@ -158,6 +158,20 @@ static const skill_id skill_swimming( "swimming" ); static const skill_id skill_traps( "traps" ); static const skill_id skill_unarmed( "unarmed" ); +static const ter_str_id ter_t_clay( "t_clay" ); +static const ter_str_id ter_t_dirt( "t_dirt" ); +static const ter_str_id ter_t_dirtmound( "t_dirtmound" ); +static const ter_str_id ter_t_grass( "t_grass" ); +static const ter_str_id ter_t_grass_dead( "t_grass_dead" ); +static const ter_str_id ter_t_grass_golf( "t_grass_golf" ); +static const ter_str_id ter_t_grass_long( "t_grass_long" ); +static const ter_str_id ter_t_grass_tall( "t_grass_tall" ); +static const ter_str_id ter_t_improvised_shelter( "t_improvised_shelter" ); +static const ter_str_id ter_t_moss( "t_moss" ); +static const ter_str_id ter_t_sand( "t_sand" ); +static const ter_str_id ter_t_tree_young( "t_tree_young" ); +static const ter_str_id ter_t_trunk( "t_trunk" ); + static const trait_id trait_DEBUG_HS( "DEBUG_HS" ); static const update_mapgen_id update_mapgen_faction_wall_level_E_1( "faction_wall_level_E_1" ); @@ -2552,7 +2566,7 @@ void basecamp::start_cut_logs( const mission_id &miss_id, float exertion_level ) sample_npc.set_fake( true ); int tree_est = om_cutdown_trees_est( forest, 50 ); int tree_young_est = om_harvest_ter_est( sample_npc, forest, - ter_id( "t_tree_young" ), 50 ); + ter_t_tree_young, 50 ); int dist = rl_dist( forest.xy(), omt_pos.xy() ); //Very roughly what the player does + 6 hours for prep, clean up, breaks time_duration chop_time = 6_hours + 1_hours * tree_est + 7_minutes * tree_young_est; @@ -2571,7 +2585,7 @@ void basecamp::start_cut_logs( const mission_id &miss_id, float exertion_level ) skill_fabrication, 2, exertion_level ); if( comp != nullptr ) { om_cutdown_trees_logs( forest, 50 ); - om_harvest_ter( *comp, forest, ter_id( "t_tree_young" ), 50 ); + om_harvest_ter( *comp, forest, ter_t_tree_young, 50 ); om_harvest_itm( comp, forest, 95 ); comp->companion_mission_time_ret = calendar::turn + work_time; change_cleared_terrain( forest ); @@ -2591,7 +2605,7 @@ void basecamp::start_clearcut( const mission_id &miss_id, float exertion_level ) sample_npc.set_fake( true ); int tree_est = om_cutdown_trees_est( forest, 95 ); int tree_young_est = om_harvest_ter_est( sample_npc, forest, - ter_id( "t_tree_young" ), 95 ); + ter_t_tree_young, 95 ); int dist = rl_dist( forest.xy(), omt_pos.xy() ); //Very roughly what the player does + 6 hours for prep, clean up, breaks time_duration chop_time = 6_hours + 1_hours * tree_est + 7_minutes * tree_young_est; @@ -2608,7 +2622,7 @@ void basecamp::start_clearcut( const mission_id &miss_id, float exertion_level ) skill_fabrication, 1, exertion_level ); if( comp != nullptr ) { om_cutdown_trees_trunks( forest, 95 ); - om_harvest_ter_break( *comp, forest, ter_id( "t_tree_young" ), 95 ); + om_harvest_ter_break( *comp, forest, ter_t_tree_young, 95 ); change_cleared_terrain( forest ); } } @@ -3531,7 +3545,7 @@ static std::pair farm_action( const tripoint_abs_omt &omt_t std::string crops; const auto is_dirtmound = []( const tripoint & pos, tinymap & bay1, tinymap & bay2 ) { - return ( bay1.ter( pos ) == t_dirtmound ) && ( !bay2.has_furn( pos ) ); + return ( bay1.ter( pos ) == ter_t_dirtmound ) && ( !bay2.has_furn( pos ) ); }; const auto is_unplowed = []( const tripoint & pos, tinymap & farm_map ) { const ter_id &farm_ter = farm_map.ter( pos ); @@ -3572,7 +3586,7 @@ static std::pair farm_action( const tripoint_abs_omt &omt_t if( is_dirtmound( pos, *farm_json, farm_map ) && is_unplowed( pos, farm_map ) ) { plots_cnt += 1; if( comp ) { - farm_map.ter_set( pos, t_dirtmound ); + farm_map.ter_set( pos, ter_t_dirtmound ); } } break; @@ -3597,7 +3611,7 @@ static std::pair farm_action( const tripoint_abs_omt &omt_t } used_seed.front().set_age( 0_turns ); farm_map.add_item_or_charges( pos, used_seed.front() ); - farm_map.set( pos, t_dirt, f_plant_seed ); + farm_map.set( pos, ter_t_dirt, f_plant_seed ); if( !tmp_seed->count_by_charges() ) { comp->companion_mission_inv.remove_item( tmp_seed ); } @@ -3626,7 +3640,7 @@ static std::pair farm_action( const tripoint_abs_omt &omt_t } farm_map.i_clear( pos ); farm_map.furn_set( pos, f_null ); - farm_map.ter_set( pos, t_dirt ); + farm_map.ter_set( pos, ter_t_dirt ); } else { plant_names.insert( item::nname( itype_id( seed->type->seed->fruit_id ) ) ); } @@ -4451,11 +4465,9 @@ bool basecamp::survey_field_return( const mission_id &miss_id ) int mismatch_tiles = 0; tripoint mapmin = tripoint( 0, 0, where.z() ); tripoint mapmax = tripoint( 2 * SEEX - 1, 2 * SEEY - 1, where.z() ); + const std::unordered_set match_terrains = { ter_t_clay, ter_t_dirt, ter_t_dirtmound, ter_t_grass, ter_t_grass_dead, ter_t_grass_golf, ter_t_grass_long, ter_t_grass_tall, ter_t_moss, ter_t_sand }; for( const tripoint &p : target.points_in_rectangle( mapmin, mapmax ) ) { - if( target.ter( p ) != t_dirt && target.ter( p ) != t_sand && target.ter( p ) != t_clay && - target.ter( p ) != t_dirtmound && target.ter( p ) != t_grass && target.ter( p ) != t_grass_dead && - target.ter( p ) != t_grass_golf && target.ter( p ) != t_grass_long && - target.ter( p ) != t_grass_tall && target.ter( p ) != t_moss ) { + if( match_terrains.find( target.ter( p ).id() ) == match_terrains.end() ) { mismatch_tiles++; } } @@ -4819,9 +4831,9 @@ int om_cutdown_trees( const tripoint_abs_omt &omt_tgt, int chance, bool estimate std::vector tree = line_to( p, to, rng( 1, 8 ) ); for( tripoint &elem : tree ) { target_bay.destroy( elem ); - target_bay.ter_set( elem, t_trunk ); + target_bay.ter_set( elem, ter_t_trunk ); } - target_bay.ter_set( p, t_dirt ); + target_bay.ter_set( p, ter_t_dirt ); harvested++; } } @@ -4834,8 +4846,8 @@ int om_cutdown_trees( const tripoint_abs_omt &omt_tgt, int chance, bool estimate } // having cut down the trees, cut the trunks into logs for( const tripoint &p : target_bay.points_in_rectangle( mapmin, mapmax ) ) { - if( target_bay.ter( p ) == ter_id( "t_trunk" ) ) { - target_bay.ter_set( p, t_dirt ); + if( target_bay.ter( p ) == ter_t_trunk ) { + target_bay.ter_set( p, ter_t_dirt ); target_bay.spawn_item( p, itype_log, rng( 2, 3 ), 0, calendar::turn ); harvested++; } @@ -5024,9 +5036,8 @@ bool om_set_hide_site( npc &comp, const tripoint_abs_omt &omt_tgt, const drop_locations &itms_rem ) { tinymap target_bay; - target_bay.load( omt_tgt, false ); - target_bay.ter_set( relay_site_stash, t_improvised_shelter ); + target_bay.ter_set( relay_site_stash, ter_t_improvised_shelter ); for( drop_location it : itms_rem ) { item *i = it.first.get_item(); item split_item; diff --git a/src/fungal_effects.cpp b/src/fungal_effects.cpp index 4c418144c46f3..e148f72f9f009 100644 --- a/src/fungal_effects.cpp +++ b/src/fungal_effects.cpp @@ -36,6 +36,18 @@ static const skill_id skill_melee( "melee" ); static const species_id species_FUNGUS( "FUNGUS" ); +static const ter_str_id ter_t_fungus( "t_fungus" ); +static const ter_str_id ter_t_fungus_floor_in( "t_fungus_floor_in" ); +static const ter_str_id ter_t_fungus_floor_out( "t_fungus_floor_out" ); +static const ter_str_id ter_t_fungus_floor_sup( "t_fungus_floor_sup" ); +static const ter_str_id ter_t_fungus_mound( "t_fungus_mound" ); +static const ter_str_id ter_t_fungus_wall( "t_fungus_wall" ); +static const ter_str_id ter_t_marloss( "t_marloss" ); +static const ter_str_id ter_t_marloss_tree( "t_marloss_tree" ); +static const ter_str_id ter_t_shrub_fungal( "t_shrub_fungal" ); +static const ter_str_id ter_t_tree_fungal( "t_tree_fungal" ); +static const ter_str_id ter_t_tree_fungal_young( "t_tree_fungal_young" ); + static const trait_id trait_TAIL_CATTLE( "TAIL_CATTLE" ); static const trait_id trait_THRESH_MYCUS( "THRESH_MYCUS" ); @@ -113,7 +125,7 @@ void fungal_effects::marlossify( const tripoint &p ) if( one_in( 25 ) && terrain.movecost != 0 && !here.has_furn( p ) && !terrain.has_flag( ter_furn_flag::TFLAG_DEEP_WATER ) && !terrain.has_flag( ter_furn_flag::TFLAG_NO_FLOOR ) ) { - here.ter_set( p, t_marloss ); + here.ter_set( p, ter_t_marloss ); return; } for( int i = 0; i < 25; i++ ) { @@ -132,52 +144,52 @@ void fungal_effects::spread_fungus_one_tile( const tripoint &p, const int growth // Terrain conversion if( here.has_flag_ter( ter_furn_flag::TFLAG_DIGGABLE, p ) ) { if( x_in_y( growth * 10, 100 ) ) { - here.ter_set( p, t_fungus ); + here.ter_set( p, ter_t_fungus ); converted = true; } } else if( here.has_flag( ter_furn_flag::TFLAG_FLAT, p ) ) { if( here.has_flag( ter_furn_flag::TFLAG_INDOORS, p ) ) { if( x_in_y( growth * 10, 500 ) ) { - here.ter_set( p, t_fungus_floor_in ); + here.ter_set( p, ter_t_fungus_floor_in ); converted = true; } } else if( here.has_flag( ter_furn_flag::TFLAG_SUPPORTS_ROOF, p ) ) { if( x_in_y( growth * 10, 1000 ) ) { - here.ter_set( p, t_fungus_floor_sup ); + here.ter_set( p, ter_t_fungus_floor_sup ); converted = true; } } else { if( x_in_y( growth * 10, 2500 ) ) { - here.ter_set( p, t_fungus_floor_out ); + here.ter_set( p, ter_t_fungus_floor_out ); converted = true; } } } else if( here.has_flag( ter_furn_flag::TFLAG_SHRUB, p ) ) { if( x_in_y( growth * 10, 200 ) ) { - here.ter_set( p, t_shrub_fungal ); + here.ter_set( p, ter_t_shrub_fungal ); converted = true; } else if( x_in_y( growth, 1000 ) ) { - here.ter_set( p, t_marloss ); + here.ter_set( p, ter_t_marloss ); converted = true; } } else if( here.has_flag( ter_furn_flag::TFLAG_THIN_OBSTACLE, p ) ) { if( x_in_y( growth * 10, 150 ) ) { - here.ter_set( p, t_fungus_mound ); + here.ter_set( p, ter_t_fungus_mound ); converted = true; } } else if( here.has_flag( ter_furn_flag::TFLAG_YOUNG, p ) ) { if( x_in_y( growth * 10, 500 ) ) { if( here.get_field_intensity( p, fd_fungal_haze ) != 0 ) { if( x_in_y( growth * 10, 800 ) ) { // young trees are vulnerable - here.ter_set( p, t_fungus ); + here.ter_set( p, ter_t_fungus ); if( g->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 ) ) { - here.ter_set( p, t_marloss_tree ); + here.ter_set( p, ter_t_marloss_tree ); } } else { - here.ter_set( p, t_tree_fungal_young ); + here.ter_set( p, ter_t_tree_fungal_young ); } converted = true; } @@ -185,22 +197,22 @@ void fungal_effects::spread_fungus_one_tile( const tripoint &p, const int growth if( one_in( 10 ) ) { if( here.get_field_intensity( p, fd_fungal_haze ) != 0 ) { if( x_in_y( growth * 10, 100 ) ) { - here.ter_set( p, t_fungus ); + here.ter_set( p, ter_t_fungus ); if( g->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 ) ) { - here.ter_set( p, t_marloss_tree ); + here.ter_set( p, ter_t_marloss_tree ); } } else { - here.ter_set( p, t_tree_fungal ); + here.ter_set( p, ter_t_tree_fungal ); } converted = true; } } else if( here.has_flag( ter_furn_flag::TFLAG_WALL, p ) && here.has_flag( ter_furn_flag::TFLAG_FLAMMABLE, p ) ) { if( x_in_y( growth * 10, 5000 ) ) { - here.ter_set( p, t_fungus_wall ); + here.ter_set( p, ter_t_fungus_wall ); converted = true; } } diff --git a/src/game.cpp b/src/game.cpp index e420bdfc96f79..50aa25f451b6b 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -308,6 +308,14 @@ static const species_id species_PLANT( "PLANT" ); static const string_id npc_template_cyborg_rescued( "cyborg_rescued" ); +static const ter_str_id ter_t_elevator( "t_elevator" ); +static const ter_str_id ter_t_grave_new( "t_grave_new" ); +static const ter_str_id ter_t_lava( "t_lava" ); +static const ter_str_id ter_t_manhole( "t_manhole" ); +static const ter_str_id ter_t_manhole_cover( "t_manhole_cover" ); +static const ter_str_id ter_t_pit( "t_pit" ); +static const ter_str_id ter_t_pit_shallow( "t_pit_shallow" ); + static const trait_id trait_BADKNEES( "BADKNEES" ); static const trait_id trait_CANNIBAL( "CANNIBAL" ); static const trait_id trait_CENOBITE( "CENOBITE" ); @@ -852,6 +860,7 @@ bool game::start_game() const start_location &start_loc = u.random_start_location ? scen->random_start_location().obj() : u.start_location.obj(); tripoint_abs_omt omtstart = overmap::invalid_tripoint; + std::unordered_map associated_parameters; const bool select_starting_city = get_option( "SELECT_STARTING_CITY" ); do { if( select_starting_city ) { @@ -859,9 +868,13 @@ bool game::start_game() u.starting_city = random_entry( city::get_all() ); u.world_origin = u.starting_city->pos_om; } - omtstart = start_loc.find_player_initial_location( u.starting_city.value() ); + auto ret = start_loc.find_player_initial_location( u.starting_city.value() ); + omtstart = ret.first; + associated_parameters = ret.second; } else { - omtstart = start_loc.find_player_initial_location( u.world_origin.value_or( point_abs_om() ) ); + auto ret = start_loc.find_player_initial_location( u.world_origin.value_or( point_abs_om() ) ); + omtstart = ret.first; + associated_parameters = ret.second; } if( omtstart == overmap::invalid_tripoint ) { @@ -875,6 +888,9 @@ bool game::start_game() } } while( omtstart == overmap::invalid_tripoint ); + // Set parameter(s) if specified in chosen start_loc + start_loc.set_parameters( omtstart, associated_parameters ); + start_loc.prepare_map( omtstart ); if( scen->has_map_extra() ) { @@ -6564,7 +6580,7 @@ void game::print_terrain_info( const tripoint &lp, const catacurses::window &w_l print_furniture_info( lp, w_look, column, line ); // Cover percentage from terrain and furniture next. - fold_and_print( w_look, point( column, ++line ), max_width, c_light_gray, _( "Cover: %d%%" ), + fold_and_print( w_look, point( column, ++line ), max_width, c_light_gray, _( "Concealment: %d%%" ), m.coverage( lp ) ); if( m.has_flag( ter_furn_flag::TFLAG_TREE, lp ) ) { @@ -6675,7 +6691,7 @@ void game::print_fields_info( const tripoint &lp, const catacurses::window &w_lo for( const auto &fld : tmpfield ) { const field_entry &cur = fld.second; if( fld.first.obj().has_fire && ( m.has_flag( ter_furn_flag::TFLAG_FIRE_CONTAINER, lp ) || - m.ter( lp ) == t_pit_shallow || m.ter( lp ) == t_pit ) ) { + m.ter( lp ) == ter_t_pit_shallow || m.ter( lp ) == ter_t_pit ) ) { const int max_width = getmaxx( w_look ) - column - 2; int lines = fold_and_print( w_look, point( column, ++line ), max_width, cur.color(), get_fire_fuel_string( lp ) ) - 1; @@ -6803,7 +6819,7 @@ void game::print_graffiti_info( const tripoint &lp, const catacurses::window &w_ const int max_width = getmaxx( w_look ) - column - 2; if( m.has_graffiti_at( lp ) ) { const int lines = fold_and_print( w_look, point( column, ++line ), max_width, c_light_gray, - m.ter( lp ) == t_grave_new ? _( "Graffiti: %s" ) : _( "Inscription: %s" ), + m.ter( lp ) == ter_t_grave_new ? _( "Graffiti: %s" ) : _( "Inscription: %s" ), m.graffiti_at( lp ) ); line += lines - 1; } @@ -12188,9 +12204,9 @@ void game::vertical_move( int movez, bool force, bool peeking ) } } - if( here.ter( stairs ) == t_manhole_cover ) { + if( here.ter( stairs ) == ter_t_manhole_cover ) { here.spawn_item( stairs + point( rng( -1, 1 ), rng( -1, 1 ) ), itype_manhole_cover ); - here.ter_set( stairs, t_manhole ); + here.ter_set( stairs, ter_t_manhole ); } if( u.is_hauling() ) { @@ -12286,8 +12302,8 @@ std::optional game::find_or_make_stairs( map &mp, const int z_after, b if( rl_dist( u.pos(), dest ) <= best && ( ( going_down_1 && mp.has_flag( ter_furn_flag::TFLAG_GOES_UP, dest ) ) || ( going_up_1 && ( mp.has_flag( ter_furn_flag::TFLAG_GOES_DOWN, dest ) || - mp.ter( dest ) == t_manhole_cover ) ) || - ( ( movez == 2 || movez == -2 ) && mp.ter( dest ) == t_elevator ) ) ) { + mp.ter( dest ) == ter_t_manhole_cover ) ) || + ( ( movez == 2 || movez == -2 ) && mp.ter( dest ) == ter_t_elevator ) ) ) { stairs.emplace( dest ); best = rl_dist( u.pos(), dest ); } @@ -12332,7 +12348,7 @@ std::optional game::find_or_make_stairs( map &mp, const int z_after, b stairs.emplace( pos ); stairs->z = z_after; // Check the destination area for lava. - if( mp.ter( *stairs ) == t_lava ) { + if( mp.ter( *stairs ) == ter_t_lava ) { if( movez < 0 && !query_yn( _( "There is a LOT of heat coming out of there, even the stairs have melted away. Jump down? You won't be able to get back up." ) ) ) { diff --git a/src/gamemode_tutorial.cpp b/src/gamemode_tutorial.cpp index 8110839819f30..d0d708a492342 100644 --- a/src/gamemode_tutorial.cpp +++ b/src/gamemode_tutorial.cpp @@ -39,6 +39,13 @@ static const skill_id skill_gun( "gun" ); static const skill_id skill_melee( "melee" ); static const skill_id skill_throwing( "throwing" ); +static const ter_str_id ter_t_door_c( "t_door_c" ); +static const ter_str_id ter_t_door_locked_interior( "t_door_locked_interior" ); +static const ter_str_id ter_t_door_o( "t_door_o" ); +static const ter_str_id ter_t_stairs_down( "t_stairs_down" ); +static const ter_str_id ter_t_water_dispenser( "t_water_dispenser" ); +static const ter_str_id ter_t_window( "t_window" ); + static const trap_str_id tr_bubblewrap( "tr_bubblewrap" ); static const trap_str_id tr_tutorial_1( "tr_tutorial_1" ); static const trap_str_id tr_tutorial_10( "tr_tutorial_10" ); @@ -210,25 +217,25 @@ void tutorial_game::per_turn() } for( const tripoint &p : here.points_in_radius( player_character.pos(), 1 ) ) { - if( here.ter( p ) == t_door_c ) { + if( here.ter( p ) == ter_t_door_c ) { add_message( tut_lesson::LESSON_OPEN ); break; - } else if( here.ter( p ) == t_door_o ) { + } else if( here.ter( p ) == ter_t_door_o ) { add_message( tut_lesson::LESSON_CLOSE ); break; - } else if( here.ter( p ) == t_door_locked_interior ) { + } else if( here.ter( p ) == ter_t_door_locked_interior ) { add_message( tut_lesson::LESSON_LOCKED_DOOR ); break; - } else if( here.ter( p ) == t_window ) { + } else if( here.ter( p ) == ter_t_window ) { add_message( tut_lesson::LESSON_WINDOW ); break; } else if( here.furn( p ) == f_rack ) { add_message( tut_lesson::LESSON_EXAMINE ); break; - } else if( here.ter( p ) == t_stairs_down ) { + } else if( here.ter( p ) == ter_t_stairs_down ) { add_message( tut_lesson::LESSON_STAIRS ); break; - } else if( here.ter( p ) == ter_id( "t_water_dispenser" ) ) { + } else if( here.ter( p ) == ter_t_water_dispenser ) { add_message( tut_lesson::LESSON_PICKUP_WATER ); break; } else if( here.tr_at( p ).id == tr_bubblewrap ) { diff --git a/src/iexamine.cpp b/src/iexamine.cpp index fed39ce2b5f08..9a92b7e59b835 100644 --- a/src/iexamine.cpp +++ b/src/iexamine.cpp @@ -221,10 +221,41 @@ static const skill_id skill_fabrication( "fabrication" ); static const skill_id skill_survival( "survival" ); static const skill_id skill_traps( "traps" ); +static const ter_str_id ter_t_card_reader_broken( "t_card_reader_broken" ); static const ter_str_id ter_t_diesel_pump( "t_diesel_pump" ); static const ter_str_id ter_t_diesel_pump_a( "t_diesel_pump_a" ); +static const ter_str_id ter_t_dirt( "t_dirt" ); +static const ter_str_id ter_t_door_metal_c( "t_door_metal_c" ); +static const ter_str_id ter_t_door_metal_locked( "t_door_metal_locked" ); +static const ter_str_id ter_t_door_metal_o( "t_door_metal_o" ); +static const ter_str_id ter_t_floor_blue( "t_floor_blue" ); +static const ter_str_id ter_t_floor_green( "t_floor_green" ); +static const ter_str_id ter_t_floor_red( "t_floor_red" ); +static const ter_str_id ter_t_fungus( "t_fungus" ); static const ter_str_id ter_t_gas_pump( "t_gas_pump" ); static const ter_str_id ter_t_gas_pump_a( "t_gas_pump_a" ); +static const ter_str_id ter_t_marloss( "t_marloss" ); +static const ter_str_id ter_t_marloss_tree( "t_marloss_tree" ); +static const ter_str_id ter_t_orifice( "t_orifice" ); +static const ter_str_id ter_t_pit( "t_pit" ); +static const ter_str_id ter_t_pit_covered( "t_pit_covered" ); +static const ter_str_id ter_t_pit_glass( "t_pit_glass" ); +static const ter_str_id ter_t_pit_glass_covered( "t_pit_glass_covered" ); +static const ter_str_id ter_t_pit_spiked( "t_pit_spiked" ); +static const ter_str_id ter_t_pit_spiked_covered( "t_pit_spiked_covered" ); +static const ter_str_id ter_t_rock_blue( "t_rock_blue" ); +static const ter_str_id ter_t_rock_floor( "t_rock_floor" ); +static const ter_str_id ter_t_rock_green( "t_rock_green" ); +static const ter_str_id ter_t_rock_red( "t_rock_red" ); +static const ter_str_id ter_t_shrub_fungal( "t_shrub_fungal" ); +static const ter_str_id ter_t_switch_even( "t_switch_even" ); +static const ter_str_id ter_t_switch_gb( "t_switch_gb" ); +static const ter_str_id ter_t_switch_rb( "t_switch_rb" ); +static const ter_str_id ter_t_switch_rg( "t_switch_rg" ); +static const ter_str_id ter_t_tree_fungal( "t_tree_fungal" ); +static const ter_str_id ter_t_tree_hickory_dead( "t_tree_hickory_dead" ); +static const ter_str_id ter_t_tree_maple( "t_tree_maple" ); +static const ter_str_id ter_t_tree_maple_tapped( "t_tree_maple_tapped" ); static const trait_id trait_AMORPHOUS( "AMORPHOUS" ); static const trait_id trait_ARACHNID_ARMS_OK( "ARACHNID_ARMS_OK" ); @@ -1363,7 +1394,7 @@ void iexamine::cardreader_robofac( Character &you, const tripoint &examp ) you.mod_moves( -100 ); you.use_amount( card_type, 1 ); add_msg( m_bad, _( "The card reader short circuits!" ) ); - get_map().ter_set( examp, t_card_reader_broken ); + get_map().ter_set( examp, ter_t_card_reader_broken ); intercom( you, examp ); } else { add_msg( _( "You have never seen this card reader model before. Hacking it seems impossible." ) ); @@ -1379,8 +1410,8 @@ void iexamine::cardreader_foodplace( Character &you, const tripoint &examp ) you.mod_moves( -100 ); map &here = get_map(); for( const tripoint &tmp : here.points_in_radius( examp, 3 ) ) { - if( here.ter( tmp ) == t_door_metal_locked ) { - here.ter_set( tmp, t_door_metal_c ); + if( here.ter( tmp ) == ter_t_door_metal_locked ) { + here.ter_set( tmp, ter_t_door_metal_c ); open = true; } } @@ -1393,11 +1424,11 @@ void iexamine::cardreader_foodplace( Character &you, const tripoint &examp ) add_msg( _( "The nearby doors are already unlocked." ) ); if( query_yn( _( "Lock doors?" ) ) ) { for( const tripoint &tmp : here.points_in_radius( examp, 3 ) ) { - if( here.ter( tmp ) == t_door_metal_o || here.ter( tmp ) == t_door_metal_c ) { + if( here.ter( tmp ) == ter_t_door_metal_o || here.ter( tmp ) == ter_t_door_metal_c ) { if( you.pos() == tmp ) { you.add_msg_if_player( m_bad, _( "You are in the way of the door, move before trying again." ) ); } else { - here.ter_set( tmp, t_door_metal_locked ); + here.ter_set( tmp, ter_t_door_metal_locked ); } } } @@ -1675,12 +1706,13 @@ void iexamine::pit( Character &you, const tripoint &examp ) map &here = get_map(); if( query_yn( _( "Place a plank over the pit?" ) ) ) { you.consume_items( planks, 1, is_crafting_component ); - if( here.ter( examp ) == t_pit ) { - here.ter_set( examp, t_pit_covered ); - } else if( here.ter( examp ) == t_pit_spiked ) { - here.ter_set( examp, t_pit_spiked_covered ); - } else if( here.ter( examp ) == t_pit_glass ) { - here.ter_set( examp, t_pit_glass_covered ); + const ter_id &ter_pit = here.ter( examp ); + if( ter_pit == ter_t_pit ) { + here.ter_set( examp, ter_t_pit_covered ); + } else if( ter_pit == ter_t_pit_spiked ) { + here.ter_set( examp, ter_t_pit_spiked_covered ); + } else if( ter_pit == ter_t_pit_glass ) { + here.ter_set( examp, ter_t_pit_glass_covered ); } add_msg( _( "You place a plank of wood over the pit." ) ); you.mod_moves( -to_moves( 1_seconds ) ); @@ -1701,13 +1733,13 @@ void iexamine::pit_covered( Character &you, const tripoint &examp ) item plank( "2x4", calendar::turn ); add_msg( _( "You remove the plank." ) ); here.add_item_or_charges( you.pos(), plank ); - - if( here.ter( examp ) == t_pit_covered ) { - here.ter_set( examp, t_pit ); - } else if( here.ter( examp ) == t_pit_spiked_covered ) { - here.ter_set( examp, t_pit_spiked ); - } else if( here.ter( examp ) == t_pit_glass_covered ) { - here.ter_set( examp, t_pit_glass ); + const ter_id &ter_pit = here.ter( examp ); + if( ter_pit == ter_t_pit_covered ) { + here.ter_set( examp, ter_t_pit ); + } else if( ter_pit == ter_t_pit_spiked_covered ) { + here.ter_set( examp, ter_t_pit_spiked ); + } else if( ter_pit == ter_t_pit_glass_covered ) { + here.ter_set( examp, ter_t_pit_glass ); } you.mod_moves( -to_moves( 1_seconds ) ); } @@ -1961,7 +1993,7 @@ void iexamine::pedestal_wyrm( Character &you, const tripoint &examp ) // Send in a few wyrms to start things off. get_event_bus().send(); for( const tripoint &p : here.points_on_zlevel() ) { - if( here.ter( p ) == ter_id( "t_orifice" ) ) { + if( here.ter( p ) == ter_t_orifice ) { g->place_critter_around( mon_dark_wyrm, p, 1 ); } } @@ -1969,7 +2001,7 @@ void iexamine::pedestal_wyrm( Character &you, const tripoint &examp ) sounds::sound( examp, 80, sounds::sound_t::combat, _( "an ominous grinding noise…" ), true, "misc", "stones_grinding" ); add_msg( _( "The pedestal sinks into the ground…" ) ); - here.ter_set( examp, t_rock_floor ); + here.ter_set( examp, ter_t_rock_floor ); get_timed_events().add( timed_event_type::SPAWN_WYRMS, calendar::turn + rng( 30_seconds, 60_seconds ) ); } else { @@ -1989,14 +2021,14 @@ void iexamine::pedestal_temple( Character &you, const tripoint &examp ) map_stack items = here.i_at( examp ); if( !items.empty() && items.only_item().typeId() == itype_petrified_eye ) { add_msg( _( "The pedestal sinks into the ground…" ) ); - here.ter_set( examp, t_dirt ); + here.ter_set( examp, ter_t_dirt ); here.i_clear( examp ); get_timed_events().add( timed_event_type::TEMPLE_OPEN, calendar::turn + 10_seconds ); } else if( you.has_amount( itype_petrified_eye, 1 ) && query_yn( _( "Place your petrified eye on the pedestal?" ) ) ) { you.use_amount( itype_petrified_eye, 1 ); add_msg( _( "The pedestal sinks into the ground…" ) ); - here.ter_set( examp, t_dirt ); + here.ter_set( examp, ter_t_dirt ); get_timed_events().add( timed_event_type::TEMPLE_OPEN, calendar::turn + 10_seconds ); } else { add_msg( _( "This pedestal is engraved in eye-shaped diagrams, and has a " @@ -2051,50 +2083,51 @@ void iexamine::fswitch( Character &you, const tripoint &examp ) tmp.z = examp.z; for( tmp.y = examp.y; tmp.y <= examp.y + 5; tmp.y++ ) { for( tmp.x = 0; tmp.x < MAPSIZE_X; tmp.x++ ) { - if( terid == t_switch_rg ) { - if( here.ter( tmp ) == t_rock_red ) { - here.ter_set( tmp, t_floor_red ); - } else if( here.ter( tmp ) == t_floor_red ) { - here.ter_set( tmp, t_rock_red ); - } else if( here.ter( tmp ) == t_rock_green ) { - here.ter_set( tmp, t_floor_green ); - } else if( here.ter( tmp ) == t_floor_green ) { - here.ter_set( tmp, t_rock_green ); + const ter_id &nearby_ter = here.ter( tmp ); + if( terid == ter_t_switch_rg ) { + if( nearby_ter == ter_t_rock_red ) { + here.ter_set( tmp, ter_t_floor_red ); + } else if( nearby_ter == ter_t_floor_red ) { + here.ter_set( tmp, ter_t_rock_red ); + } else if( nearby_ter == ter_t_rock_green ) { + here.ter_set( tmp, ter_t_floor_green ); + } else if( nearby_ter == ter_t_floor_green ) { + here.ter_set( tmp, ter_t_rock_green ); } - } else if( terid == t_switch_gb ) { - if( here.ter( tmp ) == t_rock_blue ) { - here.ter_set( tmp, t_floor_blue ); - } else if( here.ter( tmp ) == t_floor_blue ) { - here.ter_set( tmp, t_rock_blue ); - } else if( here.ter( tmp ) == t_rock_green ) { - here.ter_set( tmp, t_floor_green ); - } else if( here.ter( tmp ) == t_floor_green ) { - here.ter_set( tmp, t_rock_green ); + } else if( terid == ter_t_switch_gb ) { + if( nearby_ter == ter_t_rock_blue ) { + here.ter_set( tmp, ter_t_floor_blue ); + } else if( nearby_ter == ter_t_floor_blue ) { + here.ter_set( tmp, ter_t_rock_blue ); + } else if( nearby_ter == ter_t_rock_green ) { + here.ter_set( tmp, ter_t_floor_green ); + } else if( nearby_ter == ter_t_floor_green ) { + here.ter_set( tmp, ter_t_rock_green ); } - } else if( terid == t_switch_rb ) { - if( here.ter( tmp ) == t_rock_blue ) { - here.ter_set( tmp, t_floor_blue ); - } else if( here.ter( tmp ) == t_floor_blue ) { - here.ter_set( tmp, t_rock_blue ); - } else if( here.ter( tmp ) == t_rock_red ) { - here.ter_set( tmp, t_floor_red ); - } else if( here.ter( tmp ) == t_floor_red ) { - here.ter_set( tmp, t_rock_red ); + } else if( terid == ter_t_switch_rb ) { + if( nearby_ter == ter_t_rock_blue ) { + here.ter_set( tmp, ter_t_floor_blue ); + } else if( nearby_ter == ter_t_floor_blue ) { + here.ter_set( tmp, ter_t_rock_blue ); + } else if( nearby_ter == ter_t_rock_red ) { + here.ter_set( tmp, ter_t_floor_red ); + } else if( nearby_ter == ter_t_floor_red ) { + here.ter_set( tmp, ter_t_rock_red ); } - } else if( terid == t_switch_even ) { + } else if( terid == ter_t_switch_even ) { if( ( tmp.y - examp.y ) % 2 == 1 ) { - if( here.ter( tmp ) == t_rock_red ) { - here.ter_set( tmp, t_floor_red ); - } else if( here.ter( tmp ) == t_floor_red ) { - here.ter_set( tmp, t_rock_red ); - } else if( here.ter( tmp ) == t_rock_green ) { - here.ter_set( tmp, t_floor_green ); - } else if( here.ter( tmp ) == t_floor_green ) { - here.ter_set( tmp, t_rock_green ); - } else if( here.ter( tmp ) == t_rock_blue ) { - here.ter_set( tmp, t_floor_blue ); - } else if( here.ter( tmp ) == t_floor_blue ) { - here.ter_set( tmp, t_rock_blue ); + if( nearby_ter == ter_t_rock_red ) { + here.ter_set( tmp, ter_t_floor_red ); + } else if( nearby_ter == ter_t_floor_red ) { + here.ter_set( tmp, ter_t_rock_red ); + } else if( nearby_ter == ter_t_rock_green ) { + here.ter_set( tmp, ter_t_floor_green ); + } else if( nearby_ter == ter_t_floor_green ) { + here.ter_set( tmp, ter_t_rock_green ); + } else if( nearby_ter == ter_t_rock_blue ) { + here.ter_set( tmp, ter_t_floor_blue ); + } else if( nearby_ter == ter_t_floor_blue ) { + here.ter_set( tmp, ter_t_rock_blue ); } } } @@ -2627,7 +2660,7 @@ void iexamine::harvest_plant( Character &you, const tripoint &examp, bool from_a here.i_clear( examp ); if( you.has_trait( trait_M_DEPENDENT ) && ( you.get_kcal_percent() < 0.8f || you.get_thirst() > 300 ) ) { - here.ter_set( examp, t_marloss ); + here.ter_set( examp, ter_t_marloss ); add_msg( m_info, _( "We have altered this unit's configuration to extract and provide local nutriment. The Mycus provides." ) ); } else if( you.has_trait( trait_M_DEFENDER ) || ( ( you.has_trait( trait_M_SPORES ) || @@ -3946,7 +3979,7 @@ void iexamine::tree_hickory( Character &you, const tripoint &examp ) round( 3 + you.get_skill_level( skill_survival ) ) ), 0, calendar::turn ); - here.ter_set( examp, t_tree_hickory_dead ); + here.ter_set( examp, ter_t_tree_hickory_dead ); /** @EFFECT_SURVIVAL speeds up hickory root digging */ you.mod_moves( -to_moves( 20_seconds ) / ( you.get_skill_level( skill_survival ) + 1 ) + 100 ); } @@ -3988,7 +4021,7 @@ void iexamine::tree_maple( Character &you, const tripoint &examp ) map &here = get_map(); item_location spile_loc = g->inv_map_splice( [&here]( const item_location & it ) { return it->get_quality_nonrecursive( qual_TREE_TAP ) > 0 && - t_tree_maple_tapped != here.ter( it.position() ); + !( here.ter( it.position() ) == ter_t_tree_maple_tapped ); }, _( "Use which tapping tool?" ), PICKUP_RANGE, _( "You don't have a tapping tool at hand." ) ); item *spile = spile_loc.get_item(); @@ -3998,7 +4031,7 @@ void iexamine::tree_maple( Character &you, const tripoint &examp ) std::string spile_name = spile->tname(); you.mod_moves( -to_moves( 20_seconds ) ); - here.ter_set( examp, t_tree_maple_tapped ); + here.ter_set( examp, ter_t_tree_maple_tapped ); here.add_item_or_charges( examp, *spile, false ); spile_loc.remove_item(); add_msg( m_info, _( "You drill the maple tree crust and tap a %s into the prepared hole." ), @@ -4084,7 +4117,7 @@ void iexamine::tree_maple_tapped( Character &you, const tripoint &examp ) here.i_clear( examp ); you.mod_moves( -to_moves( 20_seconds ) ); - here.ter_set( examp, t_tree_maple ); + here.ter_set( examp, ter_t_tree_maple ); return; } @@ -4125,14 +4158,14 @@ void iexamine::tree_maple_tapped( Character &you, const tripoint &examp ) void iexamine::shrub_marloss( Character &you, const tripoint &examp ) { if( you.has_trait( trait_THRESH_MYCUS ) ) { - pick_plant( you, examp, itype_mycus_fruit, t_shrub_fungal ); + pick_plant( you, examp, itype_mycus_fruit, ter_t_shrub_fungal ); } else if( you.has_trait( trait_THRESH_MARLOSS ) ) { map &here = get_map(); here.spawn_item( you.pos(), itype_mycus_fruit, 1, 0, calendar::turn ); - here.ter_set( examp, t_fungus ); + here.ter_set( examp, ter_t_fungus ); add_msg( m_info, _( "The shrub offers up a fruit, then crumbles into a fungal bed." ) ); } else { - pick_plant( you, examp, itype_marloss_berry, t_shrub_fungal ); + pick_plant( you, examp, itype_marloss_berry, ter_t_shrub_fungal ); } } @@ -4140,20 +4173,20 @@ void iexamine::tree_marloss( Character &you, const tripoint &examp ) { map &here = get_map(); if( you.has_trait( trait_THRESH_MYCUS ) ) { - pick_plant( you, examp, itype_mycus_fruit, t_tree_fungal ); + pick_plant( you, examp, itype_mycus_fruit, ter_t_tree_fungal ); if( you.has_trait( trait_M_DEPENDENT ) && one_in( 3 ) ) { // Folks have a better shot at keeping fed. add_msg( m_info, _( "We have located a particularly vital nutrient deposit underneath this location." ) ); add_msg( m_good, _( "Additional nourishment is available." ) ); - here.ter_set( examp, t_marloss_tree ); + here.ter_set( examp, ter_t_marloss_tree ); } } else if( you.has_trait( trait_THRESH_MARLOSS ) ) { here.spawn_item( you.pos(), itype_mycus_fruit, 1, 0, calendar::turn ); - here.ter_set( examp, t_tree_fungal ); + here.ter_set( examp, ter_t_tree_fungal ); add_msg( m_info, _( "The tree offers up a fruit, then shrivels into a fungal tree." ) ); } else { - pick_plant( you, examp, itype_marloss_berry, t_tree_fungal ); + pick_plant( you, examp, itype_marloss_berry, ter_t_tree_fungal ); } } @@ -4329,13 +4362,19 @@ const itype *furn_t::crafting_pseudo_item_type() const return item::find_type( crafting_pseudo_item ); } -const itype *furn_t::crafting_ammo_item_type() const +std::vector furn_t::crafting_ammo_item_types() const { const itype *pseudo = crafting_pseudo_item_type(); + std::vector output; if( pseudo && pseudo->tool && !pseudo->tool->ammo_id.empty() ) { - return item::find_type( ammotype( *pseudo->tool->ammo_id.begin() )->default_ammotype() ); + for( const ammotype &atype : pseudo->tool->ammo_id ) { + const itype *itype = item::find_type( atype->default_ammotype() ); + if( itype != nullptr ) { + output.push_back( itype ); + } + } } - return nullptr; + return output; } /** @@ -4382,47 +4421,62 @@ static void reload_furniture( Character &you, const tripoint &examp, bool allow_ map &here = get_map(); const furn_t &f = here.furn( examp ).obj(); const itype *pseudo_type = f.crafting_pseudo_item_type(); - const itype *ammo = f.crafting_ammo_item_type(); + const std::vector ammo_list = f.crafting_ammo_item_types(); bool use_ammotype = f.has_flag( ter_furn_flag::TFLAG_AMMOTYPE_RELOAD ); - if( pseudo_type == nullptr || ammo == nullptr || !ammo->ammo ) { + auto can_be_reloaded = []( const std::vector &lst ) { + for( const itype *atype : lst ) { + if( atype != nullptr && atype->ammo ) { + return true; + } + } + return false; + }; + if( pseudo_type == nullptr || !can_be_reloaded( ammo_list ) ) { add_msg( m_info, _( "This %s can not be reloaded!" ), f.name() ); return; } - itype_id ammo_itypeID( ammo->get_id() ); - int amount_in_furn = use_ammotype ? + const itype *ammo_loaded = nullptr; + int amount_in_furn = 0; + for( const itype *ammo : ammo_list ) { + itype_id ammo_itypeID( ammo->get_id() ); + int amount_tmp = use_ammotype ? count_charges_in_list( &ammo->ammo->type, here.i_at( examp ), ammo_itypeID ) : count_charges_in_list( ammo, here.i_at( examp ) ); - if( allow_unload && amount_in_furn > 0 ) { - if( you.query_yn( _( "The %1$s contains %2$d %3$s. Unload?" ), f.name(), amount_in_furn, - ammo_itypeID->nname( amount_in_furn ) ) ) { - map_stack items = here.i_at( examp ); - for( map_stack::iterator itm = items.begin(); itm != items.end(); ) { - if( itm->typeId() == ammo_itypeID ) { - if( you.can_stash( *itm ) ) { - std::vector target_items{ item_location( map_cursor( examp ), &*itm ) }; - you.assign_activity( pickup_activity_actor( target_items, { 0 }, you.pos(), false ) ); - return; + if( allow_unload && amount_tmp > 0 ) { + ammo_loaded = ammo; + amount_in_furn = amount_tmp; + if( you.query_yn( _( "The %1$s contains %2$d %3$s. Unload?" ), f.name(), amount_in_furn, + ammo_itypeID->nname( amount_in_furn ) ) ) { + map_stack items = here.i_at( examp ); + for( map_stack::iterator itm = items.begin(); itm != items.end(); ) { + if( itm->typeId() == ammo_itypeID ) { + if( you.can_stash( *itm ) ) { + std::vector target_items{ item_location( map_cursor( examp ), &*itm ) }; + you.assign_activity( pickup_activity_actor( target_items, { 0 }, you.pos(), false ) ); + return; + } else { + // get handling cost before the item reference is invalidated + const int handling_cost = -you.item_handling_cost( *itm ); + + add_msg( _( "You remove %1$s from the %2$s." ), itm->tname(), f.name() ); + here.add_item_or_charges( you.pos(), *itm ); + itm = items.erase( itm ); + you.mod_moves( handling_cost ); + return; + } } else { - // get handling cost before the item reference is invalidated - const int handling_cost = -you.item_handling_cost( *itm ); - - add_msg( _( "You remove %1$s from the %2$s." ), itm->tname(), f.name() ); - here.add_item_or_charges( you.pos(), *itm ); - itm = items.erase( itm ); - you.mod_moves( handling_cost ); - return; + itm++; } - } else { - itm++; } } } } - - const int max_amount_in_furn = item( pseudo_type ).ammo_capacity( ammo->ammo->type ); - const int max_reload_amount = max_amount_in_furn - amount_in_furn; - if( max_reload_amount <= 0 ) { - return; + if( ammo_loaded ) { + const int max_amount_in_furn = item( pseudo_type ).ammo_capacity( ammo_loaded->ammo->type ); + if( amount_in_furn >= max_amount_in_furn ) { + add_msg( m_info, _( "The %s is full, cannot reload." ), f.name() ); + return; + } } item pseudo( pseudo_type ); // maybe at some point we need a pseudo item_location or something @@ -4436,6 +4490,13 @@ static void reload_furniture( Character &you, const tripoint &examp, bool allow_ if( !opt ) { return; } + + if( ammo_loaded && opt.ammo->type != ammo_loaded ) { + add_msg( m_info, _( "This %s is already loaded with %s!" ), f.name(), ammo_loaded->nname( 0 ) ); + return; + } + const int max_reload_amount = item( pseudo_type ).ammo_capacity( + opt.ammo->ammo_type() ) - amount_in_furn; const itype *opt_type = opt.ammo->type; const int max_amount = std::min( opt.qty(), max_reload_amount ); const std::string popupmsg = string_format( _( "Put how many of the %1$s into the %2$s?" ), @@ -6600,7 +6661,7 @@ void iexamine::smoker_options( Character &you, const tripoint &examp ) const furn_t &f = here.furn( examp ).obj(); const itype *type = f.crafting_pseudo_item_type(); - const itype *ammo = f.crafting_ammo_item_type(); + std::vector ammo_list = f.crafting_ammo_item_types(); const bool empty = f_volume == 0_ml; const bool full = f_volume >= sm_rack::MAX_FOOD_VOLUME; const bool full_portable = f_volume >= sm_rack::MAX_FOOD_VOLUME_PORTABLE; @@ -6609,8 +6670,8 @@ void iexamine::smoker_options( Character &you, const tripoint &examp ) const bool has_coal_in_inventory = you.crafting_inventory().charges_of( itype_charcoal ) > 0; const int coal_charges = count_charges_in_list( item::find_type( itype_charcoal ), items_here ); const int need_charges = get_charcoal_charges( f_volume ); - const int max_charges = type == nullptr || ammo == nullptr || - !ammo->ammo ? 0 : item( type ).ammo_capacity( ammo->ammo->type ); + const int max_charges = type == nullptr || ammo_list.empty() || + !ammo_list[0]->ammo ? 0 : item( type ).ammo_capacity( ammo_list[0]->ammo->type ); const bool has_coal = coal_charges > 0; const bool has_enough_coal = coal_charges >= need_charges; diff --git a/src/init.cpp b/src/init.cpp index 4ae5739825e05..39535da183d40 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -793,6 +793,7 @@ void DynamicDataLoader::check_consistency( loading_ui &ui ) }, { _( "Vitamins" ), &vitamin::check_consistency }, { _( "Weather types" ), &weather_types::check_consistency }, + { _( "Weapon Categories" ), &weapon_category::verify_weapon_categories }, { _( "Effect on conditions" ), &effect_on_conditions::check_consistency }, { _( "Field types" ), &field_types::check_consistency }, { _( "Ammo effects" ), &ammo_effects::check_consistency }, diff --git a/src/inventory.cpp b/src/inventory.cpp index f13ca9dfab2c2..7819185bc0752 100644 --- a/src/inventory.cpp +++ b/src/inventory.cpp @@ -535,20 +535,24 @@ void inventory::form_from_map( map &m, std::vector pts, const Characte } const furn_t &f = m.furn( p ).obj(); if( item *furn_item = provide_pseudo_item( f.crafting_pseudo_item ) ) { - const itype *ammo = f.crafting_ammo_item_type(); - if( furn_item->has_pocket_type( pocket_type::MAGAZINE ) ) { - // NOTE: This only works if the pseudo item has a MAGAZINE pocket, not a MAGAZINE_WELL! - const bool using_ammotype = f.has_flag( ter_furn_flag::TFLAG_AMMOTYPE_RELOAD ); - int amount = 0; - itype_id ammo_id = ammo->get_id(); - // Some furniture can consume more than one item type. - if( using_ammotype ) { - amount = count_charges_in_list( &ammo->ammo->type, m.i_at( p ), ammo_id ); - } else { - amount = count_charges_in_list( ammo, m.i_at( p ) ); + for( const itype *ammo : f.crafting_ammo_item_types() ) { + if( furn_item->has_pocket_type( pocket_type::MAGAZINE ) ) { + // NOTE: This only works if the pseudo item has a MAGAZINE pocket, not a MAGAZINE_WELL! + const bool using_ammotype = f.has_flag( ter_furn_flag::TFLAG_AMMOTYPE_RELOAD ); + int amount = 0; + itype_id ammo_id = ammo->get_id(); + // Some furniture can consume more than one item type. + // This might be redundant now that we iterate over the ammotypes. + if( using_ammotype ) { + amount = count_charges_in_list( &ammo->ammo->type, m.i_at( p ), ammo_id ); + } else { + amount = count_charges_in_list( ammo, m.i_at( p ) ); + } + if( amount > 0 ) { + item furn_ammo( ammo_id, calendar::turn, amount ); + furn_item->put_in( furn_ammo, pocket_type::MAGAZINE ); + } } - item furn_ammo( ammo_id, calendar::turn, amount ); - furn_item->put_in( furn_ammo, pocket_type::MAGAZINE ); } } if( m.accessible_items( p ) ) { diff --git a/src/item.cpp b/src/item.cpp index 62fcc802f15ac..aa0b135f107a6 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -510,12 +510,14 @@ static void inherit_rot_from_components( item &it ) const time_duration shortest_lifespan = get_shortest_lifespan_from_components( it ); if( shortest_lifespan > 0_turns && shortest_lifespan < it.get_shelf_life() ) { it.set_rot( it.get_shelf_life() - shortest_lifespan ); + return; } - } else { - const item *most_rotten = get_most_rotten_component( it ); - if( most_rotten ) { - it.set_relative_rot( most_rotten->get_relative_rot() ); - } + // Fallthrough: shortest_lifespan <= 0_turns (all components are rotten) + } + + const item *most_rotten = get_most_rotten_component( it ); + if( most_rotten ) { + it.set_relative_rot( most_rotten->get_relative_rot() ); } } diff --git a/src/iuse.cpp b/src/iuse.cpp index 0057bb1dbe528..c834c78944c27 100644 --- a/src/iuse.cpp +++ b/src/iuse.cpp @@ -338,6 +338,7 @@ static const species_id species_ROBOT( "ROBOT" ); static const ter_str_id ter_t_grave( "t_grave" ); static const ter_str_id ter_t_grave_new( "t_grave_new" ); +static const ter_str_id ter_t_marloss( "t_marloss" ); static const ter_str_id ter_t_pit( "t_pit" ); static const ter_str_id ter_t_pit_corpsed( "t_pit_corpsed" ); static const ter_str_id ter_t_pit_covered( "t_pit_covered" ); @@ -345,6 +346,8 @@ static const ter_str_id ter_t_pit_glass( "t_pit_glass" ); static const ter_str_id ter_t_pit_shallow( "t_pit_shallow" ); static const ter_str_id ter_t_pit_spiked( "t_pit_spiked" ); static const ter_str_id ter_t_pit_spiked_covered( "t_pit_spiked_covered" ); +static const ter_str_id ter_t_stump( "t_stump" ); +static const ter_str_id ter_t_trunk( "t_trunk" ); static const ter_str_id ter_t_utility_light( "t_utility_light" ); static const trait_id trait_ACIDBLOOD( "ACIDBLOOD" ); @@ -1336,7 +1339,7 @@ static void marloss_common( Character &p, item &it, const trait_id ¤t_colo } p.set_mutation( trait_THRESH_MARLOSS ); - get_map().ter_set( p.pos(), t_marloss ); + get_map().ter_set( p.pos(), ter_t_marloss ); get_event_bus().send( p.getID() ); p.add_msg_if_player( m_good, _( "You wake up in a Marloss bush. Almost *cradled* in it, actually, as though it grew there for you." ) ); @@ -4592,14 +4595,14 @@ std::optional iuse::chop_logs( Character *p, item *it, const tripoint & ) return std::nullopt; } - const std::set allowed_ter_id { - t_trunk, - t_stump + const std::set allowed_ter_id { + ter_t_trunk, + ter_t_stump }; map &here = get_map(); const std::function f = [&allowed_ter_id, &here]( const tripoint & pnt ) { const ter_id type = here.ter( pnt ); - const bool is_allowed_terrain = allowed_ter_id.find( type ) != allowed_ter_id.end(); + const bool is_allowed_terrain = allowed_ter_id.find( type.id() ) != allowed_ter_id.end(); return is_allowed_terrain; }; @@ -4825,7 +4828,7 @@ std::optional iuse::handle_ground_graffiti( Character &p, item *it, const s return std::nullopt; } - bool grave = here.ter( where ) == t_grave_new; + bool grave = here.ter( where ) == ter_t_grave_new; int move_cost; if( message.empty() ) { if( here.has_graffiti_at( where ) ) { diff --git a/src/magic_spell_effect.cpp b/src/magic_spell_effect.cpp index 78f39a104eb72..35b524271c4dd 100644 --- a/src/magic_spell_effect.cpp +++ b/src/magic_spell_effect.cpp @@ -1518,10 +1518,10 @@ void spell_effect::guilt( const spell &sp, Creature &caster, const tripoint &tar std::string msg; game_message_type msgtype = m_bad; // default guilt message type std::map guilt_thresholds; - guilt_thresholds[ ceil( max_kills * 0.25 ) ] = _( "You feel guilty for killing %s." ); + guilt_thresholds[ ceil( max_kills * 0.25 ) ] = _( "You feel awful about killing %s." ); guilt_thresholds[ ceil( max_kills * 0.5 ) ] = _( "You feel remorse for killing %s." ); - guilt_thresholds[ ceil( max_kills * 0.75 ) ] = _( "You regret killing %s." ); - guilt_thresholds[max_kills] = _( "You feel ashamed for killing %s." ); + guilt_thresholds[ ceil( max_kills * 0.75 ) ] = _( "You feel guilty for killing %s." ); + guilt_thresholds[max_kills] = _( "You feel uneasy about killing %s." ); Character &guy = *guilt_target; if( guy.has_trait( trait_PSYCHOPATH ) || guy.has_trait( trait_KILLER ) || diff --git a/src/map.cpp b/src/map.cpp index 48419b6f26e02..459681f0435d1 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -147,13 +147,55 @@ static const oter_str_id oter_solid_earth( "solid_earth" ); static const species_id species_FERAL( "FERAL" ); +static const ter_str_id ter_t_bars( "t_bars" ); +static const ter_str_id ter_t_card_industrial( "t_card_industrial" ); +static const ter_str_id ter_t_card_military( "t_card_military" ); +static const ter_str_id ter_t_card_reader_broken( "t_card_reader_broken" ); +static const ter_str_id ter_t_card_science( "t_card_science" ); static const ter_str_id ter_t_dirt( "t_dirt" ); +static const ter_str_id ter_t_dirtmound( "t_dirtmound" ); +static const ter_str_id ter_t_door_b( "t_door_b" ); +static const ter_str_id ter_t_door_bar_c( "t_door_bar_c" ); +static const ter_str_id ter_t_door_bar_locked( "t_door_bar_locked" ); +static const ter_str_id ter_t_door_bar_o( "t_door_bar_o" ); +static const ter_str_id ter_t_door_c( "t_door_c" ); +static const ter_str_id ter_t_door_frame( "t_door_frame" ); +static const ter_str_id ter_t_door_locked( "t_door_locked" ); +static const ter_str_id ter_t_door_locked_alarm( "t_door_locked_alarm" ); +static const ter_str_id ter_t_door_locked_peep( "t_door_locked_peep" ); +static const ter_str_id ter_t_floor( "t_floor" ); +static const ter_str_id ter_t_floor_wax( "t_floor_wax" ); +static const ter_str_id ter_t_gas_pump( "t_gas_pump" ); +static const ter_str_id ter_t_gas_pump_smashed( "t_gas_pump_smashed" ); +static const ter_str_id ter_t_grass( "t_grass" ); +static const ter_str_id ter_t_open_air( "t_open_air" ); +static const ter_str_id ter_t_reb_cage( "t_reb_cage" ); +static const ter_str_id ter_t_rock( "t_rock" ); +static const ter_str_id ter_t_rock_floor( "t_rock_floor" ); +static const ter_str_id ter_t_rootcellar( "t_rootcellar" ); +static const ter_str_id ter_t_sewage( "t_sewage" ); static const ter_str_id ter_t_soil( "t_soil" ); +static const ter_str_id ter_t_tree_birch( "t_tree_birch" ); static const ter_str_id ter_t_tree_birch_harvested( "t_tree_birch_harvested" ); static const ter_str_id ter_t_tree_dead( "t_tree_dead" ); static const ter_str_id ter_t_tree_deadpine( "t_tree_deadpine" ); +static const ter_str_id ter_t_tree_hickory( "t_tree_hickory" ); static const ter_str_id ter_t_tree_hickory_dead( "t_tree_hickory_dead" ); +static const ter_str_id ter_t_tree_hickory_harvested( "t_tree_hickory_harvested" ); +static const ter_str_id ter_t_tree_maple_tapped( "t_tree_maple_tapped" ); +static const ter_str_id ter_t_tree_pine( "t_tree_pine" ); +static const ter_str_id ter_t_tree_willow( "t_tree_willow" ); static const ter_str_id ter_t_tree_willow_harvested( "t_tree_willow_harvested" ); +static const ter_str_id ter_t_tree_young( "t_tree_young" ); +static const ter_str_id ter_t_vat( "t_vat" ); +static const ter_str_id ter_t_wall_glass( "t_wall_glass" ); +static const ter_str_id ter_t_wall_glass_alarm( "t_wall_glass_alarm" ); +static const ter_str_id ter_t_water_sh( "t_water_sh" ); +static const ter_str_id ter_t_wax( "t_wax" ); +static const ter_str_id ter_t_window( "t_window" ); +static const ter_str_id ter_t_window_alarm( "t_window_alarm" ); +static const ter_str_id ter_t_window_empty( "t_window_empty" ); +static const ter_str_id ter_t_window_no_curtains( "t_window_no_curtains" ); static const trait_id trait_SCHIZOPHRENIC( "SCHIZOPHRENIC" ); @@ -835,8 +877,8 @@ vehicle *map::move_vehicle( vehicle &veh, const tripoint &dp, const tileray &fac veh.velocity -= std::clamp( veh.velocity, -2000, 2000 ); // extra drag for( const tripoint &p : veh.get_points() ) { const ter_id &pter = ter( p ); - if( pter == t_dirt || pter == t_grass ) { - ter_set( p, t_dirtmound ); + if( pter == ter_t_dirt || pter == ter_t_grass ) { + ter_set( p, ter_t_dirtmound ); } } } @@ -1611,8 +1653,8 @@ bool map::displace_water( const tripoint &p ) continue; } if( pass != 0 && dis_places == sel_place ) { - ter_set( temp, t_water_sh ); - ter_set( temp, t_dirt ); + ter_set( temp, ter_t_water_sh ); + ter_set( temp, ter_t_dirt ); return true; } @@ -1737,8 +1779,8 @@ bool map::furn_set( const tripoint &p, const furn_id &new_furniture, const bool } if( new_f.has_flag( ter_furn_flag::TFLAG_PLANT ) ) { - if( current_submap->get_ter( l ) == t_dirtmound ) { - ter_set( p, t_dirt ); + if( current_submap->get_ter( l ) == ter_t_dirtmound ) { + ter_set( p, ter_t_dirt ); } } @@ -1871,14 +1913,14 @@ std::string map::furnname( const tripoint_bub_ms &p ) ter_id map::ter( const tripoint &p ) const { if( !inbounds( p ) ) { - return t_null; + return ter_str_id::NULL_ID().id(); } point l; const submap *const current_submap = unsafe_get_submap_at( p, l ); if( current_submap == nullptr ) { debugmsg( "Tried to process terrain at (%d,%d) but the submap is not loaded", l.x, l.y ); - return t_null; + return ter_str_id::NULL_ID().id(); } return current_submap->get_ter( l ); @@ -3766,7 +3808,7 @@ void map::collapse_at( const tripoint &p, const bool silent, const bool was_supp // a wall which doesn't make sense. if( !has_flag( ter_furn_flag::TFLAG_WALL, t ) ) { furn_set( tz, f_null ); - ter_set( tz, t_open_air ); + ter_set( tz, ter_t_open_air ); Creature *critter = get_creature_tracker().creature_at( tz ); if( critter != nullptr ) { creature_on_trap( *critter ); @@ -3900,7 +3942,7 @@ void map::smash_items( const tripoint &p, const int power, const std::string &ca } } -ter_id map::get_roof( const tripoint &p, const bool allow_air ) const +ter_str_id map::get_roof( const tripoint &p, const bool allow_air ) const { // This function should not be called from the 2D mode // Just use t_dirt instead @@ -3908,7 +3950,7 @@ ter_id map::get_roof( const tripoint &p, const bool allow_air ) const if( p.z <= -OVERMAP_DEPTH ) { // Could be magma/"void" instead - return t_rock_floor; + return ter_t_rock_floor; } const ter_t &ter_there = ter( p ).obj(); @@ -3917,25 +3959,23 @@ ter_id map::get_roof( const tripoint &p, const bool allow_air ) const // No roof // Not acceptable if the tile is not passable if( !allow_air ) { - return t_dirt; + return ter_t_dirt; } - return t_open_air; + return ter_t_open_air; } - - ter_id new_ter = roof.id(); - if( new_ter == t_null ) { + if( roof == ter_str_id::NULL_ID() ) { debugmsg( "map::get_new_floor: %d,%d,%d has invalid roof type %s", p.x, p.y, p.z, roof.c_str() ); - return t_dirt; + return ter_t_dirt; } - if( p.z == -1 && new_ter == t_rock_floor ) { + if( p.z == -1 && roof == ter_t_rock_floor ) { // HACK: A hack to work around not having a "solid earth" tile - new_ter = t_dirt; + return ter_t_dirt; } - return new_ter; + return roof; } // Check if there is supporting furniture cardinally adjacent to the bashed furniture @@ -3988,12 +4028,12 @@ void map::bash_ter_furn( const tripoint &p, bash_params ¶ms ) // HACK: A hack for destroy && !bash_floor // We have to check what would we create and cancel if it is what we have now tripoint below( p.xy(), p.z - 1 ); - const ter_id roof = get_roof( below, false ); - if( roof == ter( p ) ) { + const ter_str_id roof = get_roof( below, false ); + if( ter( p ) == roof ) { smash_ter = false; bash = nullptr; } - } else if( !bash->ter_set && ter( p ) == t_dirt ) { + } else if( !bash->ter_set && ter( p ) == ter_t_dirt ) { // As above, except for no-z-levels case smash_ter = false; bash = nullptr; @@ -4194,16 +4234,16 @@ void map::bash_ter_furn( const tripoint &p, bash_params ¶ms ) } furn_set( p, f_null ); - ter_set( p, t_open_air ); + ter_set( p, ter_t_open_air ); } if( !tent ) { spawn_items( p, item_group::items_from( bash->drop_group, calendar::turn ) ); } - if( smash_ter && ter( p ) == t_open_air && zlevels ) { + if( smash_ter && ter( p ) == ter_t_open_air && zlevels ) { tripoint below( p.xy(), p.z - 1 ); - const ter_id roof = get_roof( below, params.bash_floor && ter( below ).obj().movecost != 0 ); + const ter_str_id roof = get_roof( below, params.bash_floor && ter( below ).obj().movecost != 0 ); ter_set( p, roof ); } @@ -4568,32 +4608,33 @@ bool map::hit_with_acid( const tripoint &p ) return false; // Didn't hit the tile! } const ter_id t = ter( p ); - if( t == t_wall_glass || t == t_wall_glass_alarm || - t == t_vat ) { - ter_set( p, t_floor ); - } else if( t == t_door_c || t == t_door_locked || t == t_door_locked_peep || - t == t_door_locked_alarm ) { + if( t == ter_t_wall_glass || t == ter_t_wall_glass_alarm || + t == ter_t_vat ) { + ter_set( p, ter_t_floor ); + } else if( t == ter_t_door_c || t == ter_t_door_locked || t == ter_t_door_locked_peep || + t == ter_t_door_locked_alarm ) { if( one_in( 3 ) ) { - ter_set( p, t_door_b ); + ter_set( p, ter_t_door_b ); } - } else if( t == t_door_bar_c || t == t_door_bar_o || t == t_door_bar_locked || t == t_bars || - t == t_reb_cage ) { - ter_set( p, t_floor ); + } else if( t == ter_t_door_bar_c || t == ter_t_door_bar_o || t == ter_t_door_bar_locked || + t == ter_t_bars || + t == ter_t_reb_cage ) { + ter_set( p, ter_t_floor ); add_msg_if_player_sees( p, m_warning, _( "The metal bars melt!" ) ); - } else if( t == t_door_b ) { + } else if( t == ter_t_door_b ) { if( one_in( 4 ) ) { - ter_set( p, t_door_frame ); + ter_set( p, ter_t_door_frame ); } else { return false; } - } else if( t == t_window || t == t_window_alarm || t == t_window_no_curtains ) { - ter_set( p, t_window_empty ); - } else if( t == t_wax ) { - ter_set( p, t_floor_wax ); - } else if( t == t_gas_pump || t == t_gas_pump_smashed ) { + } else if( t == ter_t_window || t == ter_t_window_alarm || t == ter_t_window_no_curtains ) { + ter_set( p, ter_t_window_empty ); + } else if( t == ter_t_wax ) { + ter_set( p, ter_t_floor_wax ); + } else if( t == ter_t_gas_pump || t == ter_t_gas_pump_smashed ) { return false; - } else if( t == t_card_science || t == t_card_military || t == t_card_industrial ) { - ter_set( p, t_card_reader_broken ); + } else if( t == ter_t_card_science || t == ter_t_card_military || t == ter_t_card_industrial ) { + ter_set( p, ter_t_card_reader_broken ); } return true; } @@ -5364,7 +5405,7 @@ item map::water_from( const tripoint &p ) } const ter_id terrain_id = ter( p ); - if( terrain_id == t_sewage ) { + if( terrain_id == ter_t_sewage ) { item ret( "water_sewage", calendar::turn, item::INFINITE_CHARGES ); ret.set_item_temperature( std::max( weather.get_temperature( p ), temperatures::cold ) ); @@ -5640,7 +5681,7 @@ void map::process_items_in_submap( submap ¤t_submap, const tripoint &gridp } // root cellars are special temperature_flag flag = temperature_flag::NORMAL; - if( ter( map_location ) == t_rootcellar ) { + if( ter( map_location ) == ter_t_rootcellar ) { flag = temperature_flag::ROOT_CELLAR; } @@ -5960,28 +6001,30 @@ static void use_charges_from_furn( const furn_t &f, const itype_id &type, int &q const itype *itt = f.crafting_pseudo_item_type(); if( itt != nullptr && itt->tool && !itt->tool->ammo_id.empty() ) { - const itype_id ammo = ammotype( *itt->tool->ammo_id.begin() )->default_ammotype(); const bool using_ammotype = f.has_flag( ter_furn_flag::TFLAG_AMMOTYPE_RELOAD ); map_stack stack = m->i_at( p ); - auto iter = std::find_if( stack.begin(), stack.end(), - [ammo, using_ammotype]( const item & i ) { - if( using_ammotype && i.type->ammo && ammo->ammo ) { - return i.type->ammo->type == ammo->ammo->type; - } else { - return i.typeId() == ammo; - } - } ); - if( iter != stack.end() ) { - item furn_item( itt, calendar::turn_zero ); - furn_item.ammo_set( ammo, iter->charges ); + for( const itype *ammo_itype : f.crafting_ammo_item_types() ) { + itype_id ammo = ammo_itype->get_id(); + auto iter = std::find_if( stack.begin(), stack.end(), + [ammo, using_ammotype]( const item & i ) { + if( using_ammotype && i.type->ammo && ammo->ammo ) { + return i.type->ammo->type == ammo->ammo->type; + } else { + return i.typeId() == ammo; + } + } ); + if( iter != stack.end() ) { + item furn_item( itt, calendar::turn_zero ); + furn_item.ammo_set( ammo, iter->charges ); - if( !filter( furn_item ) ) { - return; - } - if( furn_item.use_charges( type, quantity, ret, p, return_true, nullptr, in_tools ) ) { - stack.erase( iter ); - } else { - iter->charges = furn_item.ammo_remaining(); + if( !filter( furn_item ) ) { + return; + } + if( furn_item.use_charges( type, quantity, ret, p, return_true, nullptr, in_tools ) ) { + stack.erase( iter ); + } else { + iter->charges = furn_item.ammo_remaining(); + } } } } @@ -8092,7 +8135,7 @@ void map::saven( const tripoint &grid ) debugmsg( "Tried to save submap node (%d) but it's not loaded", gridn ); return; } - if( submap_to_save->get_ter( point_zero ) == t_null ) { + if( submap_to_save->get_ter( point_zero ) == ter_str_id::NULL_ID() ) { // This is a serious error and should be signaled as soon as possible debugmsg( "map::saven grid %s uninitialized!", grid.to_string() ); return; @@ -8117,9 +8160,9 @@ bool generate_uniform( const tripoint_abs_sm &p, const oter_id &oter ) { std::unique_ptr sm = std::make_unique(); if( oter == oter_open_air ) { - sm->set_all_ter( t_open_air, true ); + sm->set_all_ter( ter_t_open_air, true ); } else if( oter == oter_empty_rock || oter == oter_deep_rock ) { - sm->set_all_ter( t_rock, true ); + sm->set_all_ter( ter_t_rock, true ); } else if( oter == oter_solid_earth ) { sm->set_all_ter( ter_t_soil, true ); } else { @@ -8412,7 +8455,7 @@ void map::produce_sap( const tripoint &p, const time_duration &time_since_last_a return; } - if( t_tree_maple_tapped != ter( p ) ) { + if( !( ter( p ) == ter_t_tree_maple_tapped ) ) { return; } @@ -8524,13 +8567,13 @@ void map::rad_scorch( const tripoint &p, const time_duration &time_since_last_ac const ter_id tid = ter( p ); // TODO: De-hardcode this static const std::map dies_into {{ - {t_grass, ter_t_dirt}, - {t_tree_young, ter_t_dirt}, - {t_tree_pine, ter_t_tree_deadpine}, - {t_tree_birch, ter_t_tree_birch_harvested}, - {t_tree_willow, ter_t_tree_willow_harvested}, - {t_tree_hickory, ter_t_tree_hickory_dead}, - {t_tree_hickory_harvested, ter_t_tree_hickory_dead}, + {ter_t_grass, ter_t_dirt}, + {ter_t_tree_young, ter_t_dirt}, + {ter_t_tree_pine, ter_t_tree_deadpine}, + {ter_t_tree_birch, ter_t_tree_birch_harvested}, + {ter_t_tree_willow, ter_t_tree_willow_harvested}, + {ter_t_tree_hickory, ter_t_tree_hickory_dead}, + {ter_t_tree_hickory_harvested, ter_t_tree_hickory_dead}, }}; const auto iter = dies_into.find( tid ); @@ -8541,7 +8584,7 @@ void map::rad_scorch( const tripoint &p, const time_duration &time_since_last_ac const ter_t &tr = tid.obj(); if( tr.has_flag( ter_furn_flag::TFLAG_SHRUB ) ) { - ter_set( p, t_dirt ); + ter_set( p, ter_t_dirt ); } else if( tr.has_flag( ter_furn_flag::TFLAG_TREE ) ) { ter_set( p, ter_t_tree_dead ); } @@ -8661,13 +8704,13 @@ void map::add_roofs( const tripoint &grid ) for( int x = 0; x < SEEX; x++ ) { for( int y = 0; y < SEEY; y++ ) { const ter_id ter_here = sub_here->get_ter( { x, y } ); - if( ter_here != t_open_air ) { + if( ter_here != ter_t_open_air ) { continue; } if( !check_roof ) { // Make sure we don't have open air at lowest z-level - sub_here->set_ter( { x, y }, t_rock_floor ); + sub_here->set_ter( { x, y }, ter_t_rock_floor ); continue; } @@ -9762,7 +9805,7 @@ void map::draw_square_ter( const weighted_int_list &f, const point &p1, { draw_square( [this, f, avoid_creatures]( const point & p ) { const ter_id *tid = f.pick(); - this->ter_set( p, tid != nullptr ? *tid : t_null, avoid_creatures ); + this->ter_set( p, tid != nullptr ? *tid : ter_str_id::NULL_ID(), avoid_creatures ); }, p1, p2 ); } diff --git a/src/map.h b/src/map.h index 647b6489deeaf..34a7ae9bab8c3 100644 --- a/src/map.h +++ b/src/map.h @@ -1083,10 +1083,10 @@ class map void make_rubble( const tripoint &p, const furn_id &rubble_type, bool items, const ter_id &floor_type, bool overwrite = false ); void make_rubble( const tripoint &p, const furn_id &rubble_type, bool items ) { - make_rubble( p, rubble_type, items, t_dirt, false ); + make_rubble( p, rubble_type, items, ter_str_id( "t_dirt" ).id(), false ); } void make_rubble( const tripoint &p ) { - make_rubble( p, f_rubble, false, t_dirt, false ); + make_rubble( p, f_rubble, false, ter_str_id( "t_dirt" ).id(), false ); } bool is_outside( const tripoint &p ) const; @@ -2206,7 +2206,7 @@ class map // Gets the roof type of the tile at p // Second argument refers to whether we have to get a roof (we're over an unpassable tile) // or can just return air because we bashed down an entire floor tile - ter_id get_roof( const tripoint &p, bool allow_air ) const; + ter_str_id get_roof( const tripoint &p, bool allow_air ) const; public: void process_items(); @@ -2396,6 +2396,9 @@ bool generate_uniform_omt( const tripoint_abs_sm &p, const oter_id &terrain_type class tinymap : private map { friend class editmap; + protected: + tinymap( int mapsize, bool zlev ) : map( mapsize, zlev ) {}; + public: tinymap() : map( 2, false ) {} bool inbounds( const tripoint &p ) const override; @@ -2633,8 +2636,22 @@ class fake_map : public tinymap private: std::vector> temp_submaps_; public: - explicit fake_map( const ter_id &ter_type = t_dirt ); + explicit fake_map( const ter_id &ter_type = ter_str_id( "t_dirt" ).id() ); ~fake_map() override; static constexpr int fake_map_z = -OVERMAP_DEPTH; }; + +/** +* Smallmap is similar to tinymap in that it covers a single overmap terrain (OMT) tile, but differs +* from it in that it covers all Z levels, not just a single one. It's intended usage is for cases +* where you need to operate on an OMT, but cannot guarantee you needs are restricted to a single +* Z level. +* The smallmap's natural relative reference system is the tripoint_omt_ms one. +*/ +class smallmap : public tinymap +{ + public: + smallmap() : tinymap( 2, true ) {} + void add_roofs(); +}; #endif // CATA_SRC_MAP_H diff --git a/src/map_extras.cpp b/src/map_extras.cpp index 023bd89a4b5fa..8b054beb0acc4 100644 --- a/src/map_extras.cpp +++ b/src/map_extras.cpp @@ -136,14 +136,38 @@ static const oter_type_str_id oter_type_road( "road" ); static const relic_procgen_id relic_procgen_data_alien_reality( "alien_reality" ); +static const ter_str_id ter_t_clay( "t_clay" ); static const ter_str_id ter_t_dirt( "t_dirt" ); +static const ter_str_id ter_t_dirtmound( "t_dirtmound" ); +static const ter_str_id ter_t_fence_barbed( "t_fence_barbed" ); +static const ter_str_id ter_t_fungus( "t_fungus" ); +static const ter_str_id ter_t_grass( "t_grass" ); static const ter_str_id ter_t_grass_dead( "t_grass_dead" ); +static const ter_str_id ter_t_grass_golf( "t_grass_golf" ); +static const ter_str_id ter_t_grass_long( "t_grass_long" ); +static const ter_str_id ter_t_grass_tall( "t_grass_tall" ); +static const ter_str_id ter_t_grass_white( "t_grass_white" ); +static const ter_str_id ter_t_lava( "t_lava" ); +static const ter_str_id ter_t_moss( "t_moss" ); +static const ter_str_id ter_t_pavement( "t_pavement" ); +static const ter_str_id ter_t_pavement_y( "t_pavement_y" ); +static const ter_str_id ter_t_pit( "t_pit" ); +static const ter_str_id ter_t_pit_shallow( "t_pit_shallow" ); static const ter_str_id ter_t_stump( "t_stump" ); +static const ter_str_id ter_t_tree_birch( "t_tree_birch" ); static const ter_str_id ter_t_tree_birch_harvested( "t_tree_birch_harvested" ); static const ter_str_id ter_t_tree_dead( "t_tree_dead" ); static const ter_str_id ter_t_tree_deadpine( "t_tree_deadpine" ); +static const ter_str_id ter_t_tree_hickory( "t_tree_hickory" ); static const ter_str_id ter_t_tree_hickory_dead( "t_tree_hickory_dead" ); +static const ter_str_id ter_t_tree_hickory_harvested( "t_tree_hickory_harvested" ); +static const ter_str_id ter_t_tree_pine( "t_tree_pine" ); +static const ter_str_id ter_t_tree_willow( "t_tree_willow" ); static const ter_str_id ter_t_trunk( "t_trunk" ); +static const ter_str_id ter_t_water_dp( "t_water_dp" ); +static const ter_str_id ter_t_water_moving_dp( "t_water_moving_dp" ); +static const ter_str_id ter_t_water_moving_sh( "t_water_moving_sh" ); +static const ter_str_id ter_t_water_sh( "t_water_sh" ); static const trap_str_id tr_engine( "tr_engine" ); @@ -231,17 +255,17 @@ static void dead_vegetation_parser( map &m, const tripoint &loc ) // terrain specific conversions const ter_id tid = m.ter( loc ); static const std::map dies_into {{ - {t_grass, ter_t_grass_dead}, - {t_grass_long, ter_t_grass_dead}, - {t_grass_tall, ter_t_grass_dead}, - {t_moss, ter_t_grass_dead}, - {t_tree_pine, ter_t_tree_deadpine}, - {t_tree_birch, ter_t_tree_birch_harvested}, - {t_tree_willow, ter_t_tree_dead}, - {t_tree_hickory, ter_t_tree_hickory_dead}, - {t_tree_hickory_harvested, ter_t_tree_hickory_dead}, - {t_grass_golf, ter_t_grass_dead}, - {t_grass_white, ter_t_grass_dead}, + {ter_t_grass, ter_t_grass_dead}, + {ter_t_grass_long, ter_t_grass_dead}, + {ter_t_grass_tall, ter_t_grass_dead}, + {ter_t_moss, ter_t_grass_dead}, + {ter_t_tree_pine, ter_t_tree_deadpine}, + {ter_t_tree_birch, ter_t_tree_birch_harvested}, + {ter_t_tree_willow, ter_t_tree_dead}, + {ter_t_tree_hickory, ter_t_tree_hickory_dead}, + {ter_t_tree_hickory_harvested, ter_t_tree_hickory_dead}, + {ter_t_grass_golf, ter_t_grass_dead}, + {ter_t_grass_white, ter_t_grass_dead}, }}; const auto iter = dies_into.find( tid ); @@ -251,7 +275,7 @@ static void dead_vegetation_parser( map &m, const tripoint &loc ) // non-specific small vegetation falls into sticks, large dies and randomly falls const ter_t &tr = tid.obj(); if( tr.has_flag( ter_furn_flag::TFLAG_SHRUB ) ) { - m.ter_set( loc, t_dirt ); + m.ter_set( loc, ter_t_dirt ); if( one_in( 2 ) ) { m.spawn_item( loc, itype_stick ); } @@ -287,13 +311,13 @@ static bool mx_helicopter( map &m, const tripoint &abs_sub ) for( int y = 0; y < SEEY * 2; y++ ) { if( m.veh_at( tripoint( x, y, abs_sub.z ) ) && m.ter( tripoint( x, y, abs_sub.z ) )->has_flag( ter_furn_flag::TFLAG_DIGGABLE ) ) { - m.ter_set( tripoint( x, y, abs_sub.z ), t_dirtmound ); + m.ter_set( tripoint( x, y, abs_sub.z ), ter_t_dirtmound ); } else { if( x >= c.x - dice( 1, 5 ) && x <= c.x + dice( 1, 5 ) && y >= c.y - dice( 1, 5 ) && y <= c.y + dice( 1, 5 ) ) { if( one_in( 7 ) && m.ter( tripoint( x, y, abs_sub.z ) )->has_flag( ter_furn_flag::TFLAG_DIGGABLE ) ) { - m.ter_set( tripoint( x, y, abs_sub.z ), t_dirtmound ); + m.ter_set( tripoint( x, y, abs_sub.z ), ter_t_dirtmound ); } } if( x >= c.x - dice( 1, 6 ) && x <= c.x + dice( 1, 6 ) && y >= c.y - dice( 1, 6 ) && @@ -301,12 +325,12 @@ static bool mx_helicopter( map &m, const tripoint &abs_sub ) if( !one_in( 5 ) ) { m.make_rubble( tripoint( x, y, abs_sub.z ), f_wreckage, true ); if( m.ter( tripoint( x, y, abs_sub.z ) )->has_flag( ter_furn_flag::TFLAG_DIGGABLE ) ) { - m.ter_set( tripoint( x, y, abs_sub.z ), t_dirtmound ); + m.ter_set( tripoint( x, y, abs_sub.z ), ter_t_dirtmound ); } } else if( m.is_bashable( point( x, y ) ) ) { m.destroy( tripoint( x, y, abs_sub.z ), true ); if( m.ter( tripoint( x, y, abs_sub.z ) )->has_flag( ter_furn_flag::TFLAG_DIGGABLE ) ) { - m.ter_set( tripoint( x, y, abs_sub.z ), t_dirtmound ); + m.ter_set( tripoint( x, y, abs_sub.z ), ter_t_dirtmound ); } } @@ -315,7 +339,7 @@ static bool mx_helicopter( map &m, const tripoint &abs_sub ) m.make_rubble( tripoint( x, y, abs_sub.z ), f_wreckage, true ); if( !one_in( 3 ) ) { if( m.ter( tripoint( x, y, abs_sub.z ) )->has_flag( ter_furn_flag::TFLAG_DIGGABLE ) ) { - m.ter_set( tripoint( x, y, abs_sub.z ), t_dirtmound ); + m.ter_set( tripoint( x, y, abs_sub.z ), ter_t_dirtmound ); } } } @@ -501,7 +525,7 @@ static bool mx_minefield( map &, const tripoint &abs_sub ) } //Horizontal line of barbed wire fence - line( &m, t_fence_barbed, point( 3, 9 ), point( SEEX * 2 - 4, 9 ) ); + line( &m, ter_t_fence_barbed, point( 3, 9 ), point( SEEX * 2 - 4, 9 ) ); std::vector barbed_wire = line_to( point( 3, 9 ), point( SEEX * 2 - 4, 9 ) ); for( point &i : barbed_wire ) { @@ -559,7 +583,7 @@ static bool mx_minefield( map &, const tripoint &abs_sub ) line_furn( &m, f_sandbag_half, point( 13, 15 ), point( 18, 15 ) ); //Section of barbed wire fence - line( &m, t_fence_barbed, point( 3, 13 ), point( SEEX * 2 - 4, 13 ) ); + line( &m, ter_t_fence_barbed, point( 3, 13 ), point( SEEX * 2 - 4, 13 ) ); std::vector barbed_wire = line_to( point( 3, 13 ), point( SEEX * 2 - 4, 13 ) ); for( point &i : barbed_wire ) { @@ -725,9 +749,9 @@ static bool mx_minefield( map &, const tripoint &abs_sub ) } //Add sandbags and barbed wire fence barricades - line( &m, t_fence_barbed, point( 12, 3 ), point( 12, 13 ) ); + line( &m, ter_t_fence_barbed, point( 12, 3 ), point( 12, 13 ) ); line_furn( &m, f_sandbag_half, point( 10, 16 ), point( 10, 20 ) ); - line( &m, t_fence_barbed, point( 12, 16 ), point( 12, 20 ) ); + line( &m, ter_t_fence_barbed, point( 12, 16 ), point( 12, 20 ) ); //Place second tent square_furn( &m, f_canvas_wall, point( 0, 16 ), point( 4, 20 ) ); @@ -952,7 +976,7 @@ static void place_fumarole( map &m, const point &p1, const point &p2, std::set

fumarole = line_to( p1, p2, 0 ); for( point &i : fumarole ) { - m.ter_set( i, t_lava ); + m.ter_set( i, ter_t_lava ); // Add all adjacent tiles (even on diagonals) for possible ignition // Since they're being added to a set, duplicates won't occur @@ -1014,7 +1038,7 @@ static bool mx_portal_in( map &m, const tripoint &abs_sub ) tripoint end_location = { rng( 0, SEEX * 2 - 1 ), rng( 0, SEEY * 2 - 1 ), abs_sub.z }; std::vector failure = line_to( portal_location, end_location ); for( tripoint &i : failure ) { - m.ter_set( { i.xy(), abs_sub.z }, t_pit ); + m.ter_set( { i.xy(), abs_sub.z }, ter_t_pit ); } } break; @@ -1071,7 +1095,7 @@ static bool mx_portal_in( map &m, const tripoint &abs_sub ) for( const point &i : ignited ) { // Don't need to do anything to tiles that already have lava on them - if( m.ter( i ) != t_lava ) { + if( m.ter( i ) != ter_t_lava ) { // Spawn an intense but short-lived fire // Any furniture or buildings will catch fire, otherwise it will burn out quickly m.add_field( tripoint( i, abs_sub.z ), fd_fire, 15, 1_minutes ); @@ -1208,17 +1232,17 @@ static bool mx_pond( map &m, const tripoint &abs_sub ) switch( lake_type ) { case 1: - m.ter_set( location, t_water_sh ); + m.ter_set( location, ter_t_water_sh ); break; case 2: - m.ter_set( location, t_water_dp ); + m.ter_set( location, ter_t_water_dp ); break; case 3: const int neighbors = CellularAutomata::neighbor_count( current, width, height, point( i, j ) ); if( neighbors == 8 ) { - m.ter_set( location, t_water_dp ); + m.ter_set( location, ter_t_water_dp ); } else { - m.ter_set( location, t_water_sh ); + m.ter_set( location, ter_t_water_sh ); } break; } @@ -1263,7 +1287,7 @@ static bool mx_clay_deposit( map &m, const tripoint &abs_sub ) if( current[i][j] == 1 ) { const tripoint location( i, j, abs_sub.z ); m.furn_set( location, f_null ); - m.ter_set( location, t_clay ); + m.ter_set( location, ter_t_clay ); } } } @@ -1359,19 +1383,19 @@ static void burned_ground_parser( map &m, const tripoint &loc ) // this method is deliberate to allow adding new post-terrains // (TODO: expand this list when new destroyed terrain is added) static const std::map dies_into {{ - {t_grass, ter_t_grass_dead}, - {t_grass_long, ter_t_grass_dead}, - {t_grass_tall, ter_t_grass_dead}, - {t_moss, ter_t_grass_dead}, - {t_fungus, ter_t_dirt}, - {t_grass_golf, ter_t_grass_dead}, - {t_grass_white, ter_t_grass_dead}, + {ter_t_grass, ter_t_grass_dead}, + {ter_t_grass_long, ter_t_grass_dead}, + {ter_t_grass_tall, ter_t_grass_dead}, + {ter_t_moss, ter_t_grass_dead}, + {ter_t_fungus, ter_t_dirt}, + {ter_t_grass_golf, ter_t_grass_dead}, + {ter_t_grass_white, ter_t_grass_dead}, }}; const auto iter = dies_into.find( tid ); if( iter != dies_into.end() ) { if( one_in( 6 ) ) { - m.ter_set( loc, t_dirt ); + m.ter_set( loc, ter_t_dirt ); m.spawn_item( loc, itype_ash, 1, rng( 10, 50 ) ); } else if( one_in( 10 ) ) { // do nothing, save some spots from fire @@ -1387,7 +1411,7 @@ static void burned_ground_parser( map &m, const tripoint &loc ) } } if( tr.has_flag( ter_furn_flag::TFLAG_FUNGUS ) ) { - m.ter_set( loc, t_dirt ); + m.ter_set( loc, ter_t_dirt ); if( one_in( 5 ) ) { m.spawn_item( loc, itype_ash, 1, rng( 10, 50 ) ); } @@ -1516,8 +1540,8 @@ static bool mx_reed( map &m, const tripoint &abs_sub ) if( p == loc ) { continue; } - if( m.ter( p ) == t_water_moving_sh || m.ter( p ) == t_water_sh || - m.ter( p ) == t_water_moving_dp || m.ter( p ) == t_water_dp ) { + if( m.ter( p ) == ter_t_water_moving_sh || m.ter( p ) == ter_t_water_sh || + m.ter( p ) == ter_t_water_moving_dp || m.ter( p ) == ter_t_water_dp ) { return true; } } @@ -1532,14 +1556,15 @@ static bool mx_reed( map &m, const tripoint &abs_sub ) for( int i = 0; i < SEEX * 2; i++ ) { for( int j = 0; j < SEEY * 2; j++ ) { const tripoint loc( i, j, abs_sub.z ); - if( ( m.ter( loc ) == t_water_sh || m.ter( loc ) == t_water_moving_sh ) && + const ter_id &ter_loc = m.ter( loc ); + if( ( ter_loc == ter_t_water_sh || ter_loc == ter_t_water_moving_sh ) && one_in( intensity ) ) { m.furn_set( loc, vegetation.pick()->id() ); } // tall grass imitates reed - if( ( m.ter( loc ) == t_dirt || m.ter( loc ) == t_grass ) && + if( ( ter_loc == ter_t_dirt || ter_loc == ter_t_grass ) && one_in( near_water( loc ) ? intensity : 7 ) ) { - m.ter_set( loc, t_grass_tall ); + m.ter_set( loc, ter_t_grass_tall ); } } } @@ -1567,10 +1592,10 @@ static bool mx_roadworks( map &m, const tripoint &abs_sub ) // defect types weighted_int_list road_defects; - road_defects.add( t_pit_shallow, 15 ); - road_defects.add( t_dirt, 15 ); - road_defects.add( t_dirtmound, 15 ); - road_defects.add( t_pavement, 55 ); + road_defects.add( ter_t_pit_shallow, 15 ); + road_defects.add( ter_t_dirt, 15 ); + road_defects.add( ter_t_dirtmound, 15 ); + road_defects.add( ter_t_pavement, 55 ); const weighted_int_list defects = road_defects; // location holders @@ -1810,16 +1835,16 @@ static bool mx_roadworks( map &m, const tripoint &abs_sub ) defects_to ); break; case 2: - rough_circle( &m, t_pit_shallow, defects_centered, rng( 2, 4 ) ); + rough_circle( &m, ter_t_pit_shallow, defects_centered, rng( 2, 4 ) ); break; case 3: - circle( &m, t_pit_shallow, defects_centered, rng( 2, 4 ) ); + circle( &m, ter_t_pit_shallow, defects_centered, rng( 2, 4 ) ); break; case 4: - rough_circle( &m, t_dirtmound, defects_centered, rng( 2, 4 ) ); + rough_circle( &m, ter_t_dirtmound, defects_centered, rng( 2, 4 ) ); break; case 5: - circle( &m, t_dirtmound, defects_centered, rng( 2, 4 ) ); + circle( &m, ter_t_dirtmound, defects_centered, rng( 2, 4 ) ); break; } // soil generator @@ -2098,7 +2123,7 @@ static bool mx_city_trap( map &/*m*/, const tripoint &abs_sub ) //Then find an empty 3x3 pavement square (no other traps, furniture, or vehicles) for( const tripoint &p : points_in_radius( trap_center, 1 ) ) { - if( ( compmap.ter( p ) == t_pavement || compmap.ter( p ) == t_pavement_y ) && + if( ( compmap.ter( p ) == ter_t_pavement || compmap.ter( p ) == ter_t_pavement_y ) && compmap.tr_at( p ).is_null() && compmap.furn( p ) == f_null && !compmap.veh_at( p ) ) { diff --git a/src/map_field.cpp b/src/map_field.cpp index 29efc38bb945b..a207063e43c55 100644 --- a/src/map_field.cpp +++ b/src/map_field.cpp @@ -92,6 +92,11 @@ static const material_id material_veggy( "veggy" ); static const species_id species_FUNGUS( "FUNGUS" ); +static const ter_str_id ter_t_dirt( "t_dirt" ); +static const ter_str_id ter_t_open_air( "t_open_air" ); +static const ter_str_id ter_t_pit( "t_pit" ); +static const ter_str_id ter_t_rock_floor( "t_rock_floor" ); + static const trait_id trait_ACIDPROOF( "ACIDPROOF" ); static const trait_id trait_GASTROPOD_FOOT( "GASTROPOD_FOOT" ); static const trait_id trait_M_IMMUNE( "M_IMMUNE" ); @@ -910,7 +915,7 @@ static void field_processor_fd_fungicidal_gas( const tripoint &p, field_entry &c const furn_t &frn = pd.map_tile.get_furn_t(); const int intensity = cur.get_field_intensity(); if( ter.has_flag( ter_furn_flag::TFLAG_FUNGUS ) && one_in( 10 / intensity ) ) { - pd.here.ter_set( p, t_dirt ); + pd.here.ter_set( p, ter_t_dirt ); } if( frn.has_flag( ter_furn_flag::TFLAG_FUNGUS ) && one_in( 10 / intensity ) ) { pd.here.furn_set( p, f_null ); @@ -1054,14 +1059,14 @@ void field_processor_fd_fire( const tripoint &p, field_entry &cur, field_proc_da if( p.z > 0 ) { // We're in the air. Need to invalidate the furniture otherwise it'll cause problems here.furn_set( p, f_null ); - here.ter_set( p, t_open_air ); + here.ter_set( p, ter_t_open_air ); } else if( p.z < -1 ) { // We're deep underground, in bedrock. Whatever terrain was here is burned to the ground, leaving only the carved out rock (including ceiling) - here.ter_set( p, t_rock_floor ); + here.ter_set( p, ter_t_rock_floor ); } else { // Need to invalidate the furniture otherwise it'll cause problems when supporting terrain collapses here.furn_set( p, f_null ); - here.ter_set( p, t_dirt ); + here.ter_set( p, ter_t_dirt ); } } @@ -1140,7 +1145,7 @@ void field_processor_fd_fire( const tripoint &p, field_entry &cur, field_proc_da } } // If the flames are in a pit, it can't spread to non-pit - const bool in_pit = ter.id.id() == t_pit; + const bool in_pit = ter.id.id() == ter_t_pit; // Count adjacent fires, to optimize out needless smoke and hot air int adjacent_fires = 0; @@ -1163,7 +1168,7 @@ void field_processor_fd_fire( const tripoint &p, field_entry &cur, field_proc_da if( dstfld && ( dstfld->get_field_intensity() <= cur.get_field_intensity() || dstfld->get_field_age() > cur.get_field_age() ) && - ( in_pit == ( dst.get_ter() == t_pit ) ) ) { + ( in_pit == ( dst.get_ter() == ter_t_pit ) ) ) { if( dstfld->get_field_intensity() < 2 ) { // HACK: ignoring all map field caches, since field already exists // and intensity is increased, not decreased @@ -1188,7 +1193,7 @@ void field_processor_fd_fire( const tripoint &p, field_entry &cur, field_proc_da if( dstfld && ( dstfld->get_field_intensity() <= cur.get_field_intensity() || dstfld->get_field_age() > cur.get_field_age() ) && - ( in_pit == ( dst.get_ter() == t_pit ) ) ) { + ( in_pit == ( dst.get_ter() == ter_t_pit ) ) ) { if( dstfld->get_field_intensity() < 2 ) { // HACK: ignoring all map field caches, since field already exists // and intensity is increased, not decreased @@ -1297,7 +1302,7 @@ void field_processor_fd_fire( const tripoint &p, field_entry &cur, field_proc_da // Allow weaker fires to spread occasionally const int power = cur.get_field_intensity() + one_in( 5 ); if( can_spread && rng( 1, 100 ) < spread_chance && - ( in_pit == ( dster.id.id() == t_pit ) ) && + ( in_pit == ( dster.id.id() == ter_t_pit ) ) && ( ( power >= 2 && ( ter_furn_has_flag( dster, dsfrn, ter_furn_flag::TFLAG_FLAMMABLE ) && one_in( 2 ) ) ) || @@ -1357,7 +1362,7 @@ void field_processor_fd_fire( const tripoint &p, field_entry &cur, field_proc_da // Allow weaker fires to spread occasionally const int power = cur.get_field_intensity() + one_in( 5 ); if( can_spread && rng( 1, 100 ) < spread_chance && - ( in_pit == ( dster.id.id() == t_pit ) ) && + ( in_pit == ( dster.id.id() == ter_t_pit ) ) && ( ( power >= 2 && ( ter_furn_has_flag( dster, dsfrn, ter_furn_flag::TFLAG_FLAMMABLE ) && one_in( 2 ) ) ) || diff --git a/src/mapdata.cpp b/src/mapdata.cpp index 77efe7cafe4b9..1356494697264 100644 --- a/src/mapdata.cpp +++ b/src/mapdata.cpp @@ -742,423 +742,12 @@ void map_data_common_t::set_groups( std::bitset &bits, } } -ter_id t_null, - t_hole, // Real nothingness; makes you fall a z-level - // Ground - t_dirt, t_sand, t_clay, t_dirtmound, t_pit_shallow, t_pit, t_grave, t_grave_new, - t_pit_corpsed, t_pit_covered, t_pit_spiked, t_pit_spiked_covered, t_pit_glass, t_pit_glass_covered, - t_rock_floor, - t_grass, t_grass_long, t_grass_tall, t_grass_golf, t_grass_dead, t_grass_white, t_moss, - t_grass_alien, - t_metal_floor, - t_pavement, t_pavement_y, t_sidewalk, t_concrete, t_zebra, - t_thconc_floor, t_thconc_floor_olight, t_strconc_floor, - t_floor, t_floor_waxed, - t_dirtfloor,//Dirt floor(Has roof) - t_carpet_red, t_carpet_yellow, t_carpet_purple, t_carpet_green, - t_linoleum_white, t_linoleum_gray, - t_grate, - t_slime, - t_bridge, - t_covered_well, - // Lighting related - t_utility_light, - // Walls - t_wall_log_half, t_wall_log, t_wall_log_chipped, t_wall_log_broken, t_palisade, t_palisade_gate, - t_palisade_gate_o, - t_wall_half, t_wall_wood, t_wall_wood_chipped, t_wall_wood_broken, - t_wall, t_concrete_wall, t_brick_wall, - t_wall_metal, - t_scrap_wall, - t_scrap_wall_halfway, - t_wall_glass, - t_wall_glass_alarm, - t_reinforced_glass, t_reinforced_glass_shutter, t_reinforced_glass_shutter_open, - t_laminated_glass, t_ballistic_glass, - t_reinforced_door_glass_o, t_reinforced_door_glass_c, - t_bars, - t_reb_cage, - t_door_c, t_door_c_peep, t_door_b, t_door_b_peep, t_door_o, t_door_o_peep, t_rdoor_c, t_rdoor_b, - t_rdoor_o, t_door_locked_interior, t_door_locked, t_door_locked_peep, t_door_locked_alarm, - t_door_frame, - t_chaingate_l, t_fencegate_c, t_fencegate_o, t_chaingate_c, t_chaingate_o, - t_retractable_gate_c, t_retractable_gate_l, t_retractable_gate_o, - t_door_boarded, t_door_boarded_damaged, t_door_boarded_peep, t_rdoor_boarded, - t_rdoor_boarded_damaged, t_door_boarded_damaged_peep, - t_door_metal_c, t_door_metal_o, t_door_metal_locked, t_door_metal_pickable, t_mdoor_frame, - t_door_bar_c, t_door_bar_o, t_door_bar_locked, - t_door_glass_c, t_door_glass_o, t_door_glass_frosted_c, t_door_glass_frosted_o, - t_portcullis, - t_recycler, t_window, t_window_taped, t_window_domestic, t_window_domestic_taped, t_window_open, - t_curtains, t_window_bars_curtains, t_window_bars_domestic, - t_window_alarm, t_window_alarm_taped, t_window_empty, t_window_frame, t_window_boarded, - t_window_boarded_noglass, t_window_reinforced, t_window_reinforced_noglass, t_window_enhanced, - t_window_enhanced_noglass, t_window_bars_alarm, t_window_bars, - t_metal_grate_window, t_metal_grate_window_with_curtain, t_metal_grate_window_with_curtain_open, - t_metal_grate_window_noglass, t_metal_grate_window_with_curtain_noglass, - t_metal_grate_window_with_curtain_open_noglass, - t_window_stained_green, t_window_stained_red, t_window_stained_blue, - t_window_no_curtains, t_window_no_curtains_open, t_window_no_curtains_taped, - t_rock, t_fault, - t_paper, - t_rock_wall, t_rock_wall_half, - // Tree - t_tree, t_tree_young, t_tree_apple, t_tree_apple_harvested, t_tree_coffee, t_tree_coffee_harvested, - t_tree_pear, t_tree_pear_harvested, t_tree_cherry, t_tree_cherry_harvested, - t_tree_peach, t_tree_peach_harvested, t_tree_apricot, t_tree_apricot_harvested, t_tree_plum, - t_tree_plum_harvested, - t_tree_pine, t_tree_blackjack, t_tree_birch, t_tree_willow, t_tree_maple, t_tree_maple_tapped, - t_tree_hickory, t_tree_hickory_dead, t_tree_hickory_harvested, t_tree_deadpine, t_underbrush, - t_shrub, t_shrub_blueberry, t_shrub_strawberry, t_trunk, t_stump, - t_root_wall, - t_wax, t_floor_wax, - t_fence, t_chainfence, t_chainfence_posts, - t_fence_post, t_fence_wire, t_fence_barbed, t_fence_rope, - t_railing, - // Nether - t_marloss, t_fungus_floor_in, t_fungus_floor_sup, t_fungus_floor_out, t_fungus_wall, - t_fungus_mound, t_fungus, t_shrub_fungal, t_tree_fungal, t_tree_fungal_young, t_marloss_tree, - // Water, lava, etc. - t_water_moving_dp, t_water_moving_sh, t_water_sh, t_water_dp, t_swater_sh, t_swater_dp, - t_swater_surf, t_water_pool, t_sewage, - t_lava, - // More embellishments than you can shake a stick at. - t_sandbox, t_slide, t_monkey_bars, t_backboard, - t_gas_pump, t_gas_pump_smashed, - t_diesel_pump, t_diesel_pump_smashed, - t_atm, - t_missile, t_missile_exploded, - t_radio_tower, t_radio_controls, - t_gates_mech_control, t_gates_control_concrete, t_gates_control_brick, - t_barndoor, t_palisade_pulley, - t_gates_control_metal, - t_sewage_pipe, t_sewage_pump, - t_column, - t_vat, - t_rootcellar, - t_cvdbody, t_cvdmachine, - t_water_pump, - t_conveyor, - t_improvised_shelter, - // Staircases etc. - t_stairs_down, t_stairs_up, t_manhole, t_ladder_up, t_ladder_down, t_slope_down, - t_slope_up, t_rope_up, - t_manhole_cover, - // Special - t_card_science, t_card_military, t_card_industrial, t_card_reader_broken, t_slot_machine, - t_elevator_control, t_elevator_control_off, t_elevator, t_pedestal_wyrm, - t_pedestal_temple, - // Temple tiles - t_rock_red, t_rock_green, t_rock_blue, t_floor_red, t_floor_green, t_floor_blue, - t_switch_rg, t_switch_gb, t_switch_rb, t_switch_even, t_open_air, - t_pavement_bg_dp, t_pavement_y_bg_dp, t_sidewalk_bg_dp, t_guardrail_bg_dp, - t_rad_platform, - // Railroad and subway - t_railroad_rubble, - t_buffer_stop, t_railroad_crossing_signal, t_crossbuck_wood, t_crossbuck_metal, - t_railroad_tie, t_railroad_tie_h, t_railroad_tie_v, t_railroad_tie_d, - t_railroad_track, t_railroad_track_h, t_railroad_track_v, t_railroad_track_d, t_railroad_track_d1, - t_railroad_track_d2, - t_railroad_track_on_tie, t_railroad_track_h_on_tie, t_railroad_track_v_on_tie, - t_railroad_track_d_on_tie; - -// TODO: Put this crap into an inclusion, which should be generated automatically using JSON data +ter_id t_null; void set_ter_ids() { t_null = ter_id( "t_null" ); - t_hole = ter_id( "t_hole" ); - t_dirt = ter_id( "t_dirt" ); - t_sand = ter_id( "t_sand" ); - t_clay = ter_id( "t_clay" ); - t_dirtmound = ter_id( "t_dirtmound" ); - t_grave = ter_id( "t_grave" ); - t_grave_new = ter_id( "t_grave_new" ); - t_pit_shallow = ter_id( "t_pit_shallow" ); - t_pit = ter_id( "t_pit" ); - t_pit_corpsed = ter_id( "t_pit_corpsed" ); - t_pit_covered = ter_id( "t_pit_covered" ); - t_pit_spiked = ter_id( "t_pit_spiked" ); - t_pit_spiked_covered = ter_id( "t_pit_spiked_covered" ); - t_pit_glass = ter_id( "t_pit_glass" ); - t_pit_glass_covered = ter_id( "t_pit_glass_covered" ); - t_rock_floor = ter_id( "t_rock_floor" ); - t_grass = ter_id( "t_grass" ); - t_grass_dead = ter_id( "t_grass_dead" ); - t_grass_long = ter_id( "t_grass_long" ); - t_grass_tall = ter_id( "t_grass_tall" ); - t_moss = ter_id( "t_moss" ); - t_metal_floor = ter_id( "t_metal_floor" ); - t_pavement = ter_id( "t_pavement" ); - t_pavement_y = ter_id( "t_pavement_y" ); - t_zebra = ter_id( "t_zebra" ); - t_sidewalk = ter_id( "t_sidewalk" ); - t_concrete = ter_id( "t_concrete" ); - t_thconc_floor = ter_id( "t_thconc_floor" ); - t_thconc_floor_olight = ter_id( "t_thconc_floor_olight" ); - t_strconc_floor = ter_id( "t_strconc_floor" ); - t_floor = ter_id( "t_floor" ); - t_floor_waxed = ter_id( "t_floor_waxed" ); - t_dirtfloor = ter_id( "t_dirtfloor" ); - t_carpet_red = ter_id( "t_carpet_red" ); - t_carpet_yellow = ter_id( "t_carpet_yellow" ); - t_carpet_purple = ter_id( "t_carpet_purple" ); - t_carpet_green = ter_id( "t_carpet_green" ); - t_linoleum_white = ter_id( "t_linoleum_white" ); - t_linoleum_gray = ter_id( "t_linoleum_gray" ); - t_grate = ter_id( "t_grate" ); - t_slime = ter_id( "t_slime" ); - t_bridge = ter_id( "t_bridge" ); - t_utility_light = ter_id( "t_utility_light" ); - t_wall_log_half = ter_id( "t_wall_log_half" ); - t_wall_log = ter_id( "t_wall_log" ); - t_wall_log_chipped = ter_id( "t_wall_log_chipped" ); - t_wall_log_broken = ter_id( "t_wall_log_broken" ); - t_palisade = ter_id( "t_palisade" ); - t_palisade_gate = ter_id( "t_palisade_gate" ); - t_palisade_gate_o = ter_id( "t_palisade_gate_o" ); - t_wall_half = ter_id( "t_wall_half" ); - t_wall_wood = ter_id( "t_wall_wood" ); - t_wall_wood_chipped = ter_id( "t_wall_wood_chipped" ); - t_wall_wood_broken = ter_id( "t_wall_wood_broken" ); - t_wall = ter_id( "t_wall" ); - t_concrete_wall = ter_id( "t_concrete_wall" ); - t_brick_wall = ter_id( "t_brick_wall" ); - t_wall_metal = ter_id( "t_wall_metal" ); - t_scrap_wall = ter_id( "t_scrap_wall" ); - t_scrap_wall_halfway = ter_id( "t_scrap_wall_halfway" ); - t_wall_glass = ter_id( "t_wall_glass" ); - t_wall_glass_alarm = ter_id( "t_wall_glass_alarm" ); - t_reinforced_glass = ter_id( "t_reinforced_glass" ); - t_reinforced_glass_shutter = ter_id( "t_reinforced_glass_shutter" ); - t_reinforced_glass_shutter_open = ter_id( "t_reinforced_glass_shutter_open" ); - t_laminated_glass = ter_id( "t_laminated_glass" ); - t_ballistic_glass = ter_id( "t_ballistic_glass" ); - t_reinforced_door_glass_c = ter_id( "t_reinforced_door_glass_c" ); - t_reinforced_door_glass_o = ter_id( "t_reinforced_door_glass_o" ); - t_bars = ter_id( "t_bars" ); - t_reb_cage = ter_id( "t_reb_cage" ); - t_door_c = ter_id( "t_door_c" ); - t_door_c_peep = ter_id( "t_door_c_peep" ); - t_door_b = ter_id( "t_door_b" ); - t_door_b_peep = ter_id( "t_door_b_peep" ); - t_door_o = ter_id( "t_door_o" ); - t_door_o_peep = ter_id( "t_door_o_peep" ); - t_rdoor_c = ter_id( "t_rdoor_c" ); - t_rdoor_b = ter_id( "t_rdoor_b" ); - t_rdoor_o = ter_id( "t_rdoor_o" ); - t_door_locked_interior = ter_id( "t_door_locked_interior" ); - t_door_locked = ter_id( "t_door_locked" ); - t_door_locked_peep = ter_id( "t_door_locked_peep" ); - t_door_locked_alarm = ter_id( "t_door_locked_alarm" ); - t_door_frame = ter_id( "t_door_frame" ); - t_mdoor_frame = ter_id( "t_mdoor_frame" ); - t_chaingate_l = ter_id( "t_chaingate_l" ); - t_fencegate_c = ter_id( "t_fencegate_c" ); - t_fencegate_o = ter_id( "t_fencegate_o" ); - t_chaingate_c = ter_id( "t_chaingate_c" ); - t_chaingate_o = ter_id( "t_chaingate_o" ); - t_retractable_gate_l = ter_id( "t_retractable_gate_l" ); - t_retractable_gate_c = ter_id( "t_retractable_gate_c" ); - t_retractable_gate_o = ter_id( "t_retractable_gate_o" ); - t_door_boarded = ter_id( "t_door_boarded" ); - t_door_boarded_damaged = ter_id( "t_door_boarded_damaged" ); - t_door_boarded_peep = ter_id( "t_door_boarded_peep" ); - t_rdoor_boarded = ter_id( "t_rdoor_boarded" ); - t_rdoor_boarded_damaged = ter_id( "t_rdoor_boarded_damaged" ); - t_door_boarded_damaged_peep = ter_id( "t_door_boarded_damaged_peep" ); - t_door_metal_c = ter_id( "t_door_metal_c" ); - t_door_metal_o = ter_id( "t_door_metal_o" ); - t_door_metal_locked = ter_id( "t_door_metal_locked" ); - t_door_metal_pickable = ter_id( "t_door_metal_pickable" ); - t_door_bar_c = ter_id( "t_door_bar_c" ); - t_door_bar_o = ter_id( "t_door_bar_o" ); - t_door_bar_locked = ter_id( "t_door_bar_locked" ); - t_door_glass_c = ter_id( "t_door_glass_c" ); - t_door_glass_o = ter_id( "t_door_glass_o" ); - t_door_glass_frosted_c = ter_id( "t_door_glass_frosted_c" ); - t_door_glass_frosted_o = ter_id( "t_door_glass_frosted_o" ); - t_portcullis = ter_id( "t_portcullis" ); - t_recycler = ter_id( "t_recycler" ); - t_window = ter_id( "t_window" ); - t_window_taped = ter_id( "t_window_taped" ); - t_window_domestic = ter_id( "t_window_domestic" ); - t_window_domestic_taped = ter_id( "t_window_domestic_taped" ); - t_window_bars_domestic = ter_id( "t_window_bars_domestic" ); - t_window_open = ter_id( "t_window_open" ); - t_curtains = ter_id( "t_curtains" ); - t_window_bars_curtains = ter_id( "t_window_bars_curtains" ); - t_window_alarm = ter_id( "t_window_alarm" ); - t_window_alarm_taped = ter_id( "t_window_alarm_taped" ); - t_window_empty = ter_id( "t_window_empty" ); - t_window_frame = ter_id( "t_window_frame" ); - t_window_boarded = ter_id( "t_window_boarded" ); - t_window_boarded_noglass = ter_id( "t_window_boarded_noglass" ); - t_window_reinforced = ter_id( "t_window_reinforced" ); - t_window_reinforced_noglass = ter_id( "t_window_reinforced_noglass" ); - t_window_enhanced = ter_id( "t_window_enhanced" ); - t_window_enhanced_noglass = ter_id( "t_window_enhanced_noglass" ); - t_window_bars_alarm = ter_id( "t_window_bars_alarm" ); - t_window_bars = ter_id( "t_window_bars" ); - t_window_stained_green = ter_id( "t_window_stained_green" ); - t_window_stained_red = ter_id( "t_window_stained_red" ); - t_window_stained_blue = ter_id( "t_window_stained_blue" ); - t_window_no_curtains = ter_id( "t_window_no_curtains" ); - t_window_no_curtains_open = ter_id( "t_window_no_curtains_open" ); - t_window_no_curtains_taped = ter_id( "t_window_no_curtains_taped" ); - t_rock = ter_id( "t_rock" ); - t_fault = ter_id( "t_fault" ); - t_paper = ter_id( "t_paper" ); - t_rock_wall = ter_id( "t_rock_wall" ); - t_rock_wall_half = ter_id( "t_rock_wall_half" ); - t_tree = ter_id( "t_tree" ); - t_tree_young = ter_id( "t_tree_young" ); - t_tree_apple = ter_id( "t_tree_apple" ); - t_tree_apple_harvested = ter_id( "t_tree_apple_harvested" ); - t_tree_coffee = ter_id( "t_tree_coffee" ); - t_tree_coffee_harvested = ter_id( "t_tree_coffee_harvested" ); - t_tree_pear = ter_id( "t_tree_pear" ); - t_tree_pear_harvested = ter_id( "t_tree_pear_harvested" ); - t_tree_cherry = ter_id( "t_tree_cherry" ); - t_tree_cherry_harvested = ter_id( "t_tree_cherry_harvested" ); - t_tree_peach = ter_id( "t_tree_peach" ); - t_tree_peach_harvested = ter_id( "t_tree_peach_harvested" ); - t_tree_apricot = ter_id( "t_tree_apricot" ); - t_tree_apricot_harvested = ter_id( "t_tree_apricot_harvested" ); - t_tree_plum = ter_id( "t_tree_plum" ); - t_tree_plum_harvested = ter_id( "t_tree_plum_harvested" ); - t_tree_pine = ter_id( "t_tree_pine" ); - t_tree_blackjack = ter_id( "t_tree_blackjack" ); - t_tree_birch = ter_id( "t_tree_birch" ); - t_tree_willow = ter_id( "t_tree_willow" ); - t_tree_maple = ter_id( "t_tree_maple" ); - t_tree_maple_tapped = ter_id( "t_tree_maple_tapped" ); - t_tree_deadpine = ter_id( "t_tree_deadpine" ); - t_tree_hickory = ter_id( "t_tree_hickory" ); - t_tree_hickory_dead = ter_id( "t_tree_hickory_dead" ); - t_tree_hickory_harvested = ter_id( "t_tree_hickory_harvested" ); - t_underbrush = ter_id( "t_underbrush" ); - t_shrub = ter_id( "t_shrub" ); - t_shrub_blueberry = ter_id( "t_shrub_blueberry" ); - t_shrub_strawberry = ter_id( "t_shrub_strawberry" ); - t_trunk = ter_id( "t_trunk" ); - t_stump = ter_id( "t_stump" ); - t_root_wall = ter_id( "t_root_wall" ); - t_wax = ter_id( "t_wax" ); - t_floor_wax = ter_id( "t_floor_wax" ); - t_fence = ter_id( "t_fence" ); - t_chainfence = ter_id( "t_chainfence" ); - t_chainfence_posts = ter_id( "t_chainfence_posts" ); - t_fence_post = ter_id( "t_fence_post" ); - t_fence_wire = ter_id( "t_fence_wire" ); - t_fence_barbed = ter_id( "t_fence_barbed" ); - t_fence_rope = ter_id( "t_fence_rope" ); - t_railing = ter_id( "t_railing" ); - t_marloss = ter_id( "t_marloss" ); - t_fungus_floor_in = ter_id( "t_fungus_floor_in" ); - t_fungus_floor_sup = ter_id( "t_fungus_floor_sup" ); - t_fungus_floor_out = ter_id( "t_fungus_floor_out" ); - t_fungus_wall = ter_id( "t_fungus_wall" ); - t_fungus_mound = ter_id( "t_fungus_mound" ); - t_fungus = ter_id( "t_fungus" ); - t_shrub_fungal = ter_id( "t_shrub_fungal" ); - t_tree_fungal = ter_id( "t_tree_fungal" ); - t_tree_fungal_young = ter_id( "t_tree_fungal_young" ); - t_marloss_tree = ter_id( "t_marloss_tree" ); - t_water_moving_dp = ter_id( "t_water_moving_dp" ); - t_water_moving_sh = ter_id( "t_water_moving_sh" ); - t_water_sh = ter_id( "t_water_sh" ); - t_water_dp = ter_id( "t_water_dp" ); - t_swater_sh = ter_id( "t_swater_sh" ); - t_swater_dp = ter_id( "t_swater_dp" ); - t_swater_surf = ter_id( "t_swater_surf" ); - t_water_pool = ter_id( "t_water_pool" ); - t_sewage = ter_id( "t_sewage" ); - t_lava = ter_id( "t_lava" ); - t_sandbox = ter_id( "t_sandbox" ); - t_slide = ter_id( "t_slide" ); - t_monkey_bars = ter_id( "t_monkey_bars" ); - t_backboard = ter_id( "t_backboard" ); - t_gas_pump = ter_id( "t_gas_pump" ); - t_gas_pump_smashed = ter_id( "t_gas_pump_smashed" ); - t_diesel_pump = ter_id( "t_diesel_pump" ); - t_diesel_pump_smashed = ter_id( "t_diesel_pump_smashed" ); - t_atm = ter_id( "t_atm" ); - t_missile = ter_id( "t_missile" ); - t_missile_exploded = ter_id( "t_missile_exploded" ); - t_radio_tower = ter_id( "t_radio_tower" ); - t_radio_controls = ter_id( "t_radio_controls" ); - t_gates_mech_control = ter_id( "t_gates_mech_control" ); - t_gates_control_brick = ter_id( "t_gates_control_brick" ); - t_gates_control_concrete = ter_id( "t_gates_control_concrete" ); - t_barndoor = ter_id( "t_barndoor" ); - t_palisade_pulley = ter_id( "t_palisade_pulley" ); - t_gates_control_metal = ter_id( "t_gates_control_metal" ); - t_sewage_pipe = ter_id( "t_sewage_pipe" ); - t_sewage_pump = ter_id( "t_sewage_pump" ); - t_column = ter_id( "t_column" ); - t_vat = ter_id( "t_vat" ); - t_rootcellar = ter_id( "t_rootcellar" ); - t_cvdbody = ter_id( "t_cvdbody" ); - t_cvdmachine = ter_id( "t_cvdmachine" ); - t_stairs_down = ter_id( "t_stairs_down" ); - t_stairs_up = ter_id( "t_stairs_up" ); - t_manhole = ter_id( "t_manhole" ); - t_ladder_up = ter_id( "t_ladder_up" ); - t_ladder_down = ter_id( "t_ladder_down" ); - t_slope_down = ter_id( "t_slope_down" ); - t_slope_up = ter_id( "t_slope_up" ); - t_rope_up = ter_id( "t_rope_up" ); - t_manhole_cover = ter_id( "t_manhole_cover" ); - t_card_science = ter_id( "t_card_science" ); - t_card_military = ter_id( "t_card_military" ); - t_card_industrial = ter_id( "t_card_industrial" ); - t_card_reader_broken = ter_id( "t_card_reader_broken" ); - t_slot_machine = ter_id( "t_slot_machine" ); - t_elevator_control = ter_id( "t_elevator_control" ); - t_elevator_control_off = ter_id( "t_elevator_control_off" ); - t_elevator = ter_id( "t_elevator" ); - t_pedestal_wyrm = ter_id( "t_pedestal_wyrm" ); - t_pedestal_temple = ter_id( "t_pedestal_temple" ); - t_rock_red = ter_id( "t_rock_red" ); - t_rock_green = ter_id( "t_rock_green" ); - t_rock_blue = ter_id( "t_rock_blue" ); - t_floor_red = ter_id( "t_floor_red" ); - t_floor_green = ter_id( "t_floor_green" ); - t_floor_blue = ter_id( "t_floor_blue" ); - t_switch_rg = ter_id( "t_switch_rg" ); - t_switch_gb = ter_id( "t_switch_gb" ); - t_switch_rb = ter_id( "t_switch_rb" ); - t_switch_even = ter_id( "t_switch_even" ); - t_covered_well = ter_id( "t_covered_well" ); - t_water_pump = ter_id( "t_water_pump" ); - t_conveyor = ter_id( "t_conveyor" ); - t_open_air = ter_id( "t_open_air" ); - t_pavement_bg_dp = ter_id( "t_pavement_bg_dp" ); - t_pavement_y_bg_dp = ter_id( "t_pavement_y_bg_dp" ); - t_sidewalk_bg_dp = ter_id( "t_sidewalk_bg_dp" ); - t_guardrail_bg_dp = ter_id( "t_guardrail_bg_dp" ); - t_rad_platform = ter_id( "t_rad_platform" ); - t_improvised_shelter = ter_id( "t_improvised_shelter" ); - t_railroad_rubble = ter_id( "t_railroad_rubble" ); - t_buffer_stop = ter_id( "t_buffer_stop" ); - t_railroad_crossing_signal = ter_id( "t_railroad_crossing_signal" ); - t_crossbuck_metal = ter_id( "t_crossbuck_metal" ); - t_crossbuck_wood = ter_id( "t_crossbuck_wood" ); - t_railroad_tie = ter_id( "t_railroad_tie" ); - t_railroad_tie_h = ter_id( "t_railroad_tie_h" ); - t_railroad_tie_v = ter_id( "t_railroad_tie_v" ); - t_railroad_tie_d = ter_id( "t_railroad_tie_d" ); - t_railroad_track = ter_id( "t_railroad_track" ); - t_railroad_track_h = ter_id( "t_railroad_track_h" ); - t_railroad_track_v = ter_id( "t_railroad_track_v" ); - t_railroad_track_d = ter_id( "t_railroad_track_d" ); - t_railroad_track_d1 = ter_id( "t_railroad_track_d1" ); - t_railroad_track_d2 = ter_id( "t_railroad_track_d2" ); - t_railroad_track_on_tie = ter_id( "t_railroad_track_on_tie" ); - t_railroad_track_h_on_tie = ter_id( "t_railroad_track_h_on_tie" ); - t_railroad_track_v_on_tie = ter_id( "t_railroad_track_v_on_tie" ); - t_railroad_track_d_on_tie = ter_id( "t_railroad_track_d_on_tie" ); + for( const ter_t &elem : terrain_data.get_all() ) { ter_t &ter = const_cast( elem ); if( ter.trap_id_str.empty() ) { diff --git a/src/mapdata.h b/src/mapdata.h index e2140b89de39b..a75cf4e6d6663 100644 --- a/src/mapdata.h +++ b/src/mapdata.h @@ -669,8 +669,8 @@ struct furn_t : map_data_common_t { // May return NULL const itype *crafting_pseudo_item_type() const; - // May return NULL - const itype *crafting_ammo_item_type() const; + // May return an empty container if no valid ammotype + std::vector crafting_ammo_item_types() const; furn_t(); @@ -698,126 +698,7 @@ t_basalt "t_basalt" */ // NOLINTNEXTLINE(cata-static-int_id-constants) -extern ter_id t_null, - t_hole, // Real nothingness; makes you fall a z-level - // Ground - t_dirt, t_sand, t_clay, t_dirtmound, t_pit_shallow, t_pit, t_grave, t_grave_new, - t_pit_corpsed, t_pit_covered, t_pit_spiked, t_pit_spiked_covered, t_pit_glass, t_pit_glass_covered, - t_rock_floor, - t_grass, t_grass_long, t_grass_tall, t_grass_golf, t_grass_dead, t_grass_white, t_moss, - t_grass_alien, - t_metal_floor, - t_pavement, t_pavement_y, t_sidewalk, t_concrete, t_zebra, - t_thconc_floor, t_thconc_floor_olight, t_strconc_floor, - t_floor, t_floor_waxed, - t_dirtfloor,//Dirt floor(Has roof) - t_carpet_red, t_carpet_yellow, t_carpet_purple, t_carpet_green, - t_grate, - t_slime, - t_bridge, - t_covered_well, - // Lighting related - t_utility_light, - // Walls - t_wall_log_half, t_wall_log, t_wall_log_chipped, t_wall_log_broken, t_palisade, t_palisade_gate, - t_palisade_gate_o, - t_wall_half, t_wall_wood, t_wall_wood_chipped, t_wall_wood_broken, - t_wall, t_concrete_wall, t_brick_wall, - t_wall_metal, - t_scrap_wall, - t_scrap_wall_halfway, - t_wall_glass, - t_wall_glass_alarm, - t_reinforced_glass, t_reinforced_glass_shutter, t_reinforced_glass_shutter_open, - t_laminated_glass, t_ballistic_glass, - t_reinforced_door_glass_o, t_reinforced_door_glass_c, - t_bars, - t_reb_cage, - t_door_c, t_door_c_peep, t_door_b, t_door_b_peep, t_door_o, t_door_o_peep, - t_door_locked_interior, t_door_locked, t_door_locked_peep, t_door_locked_alarm, t_door_frame, - t_chaingate_l, t_fencegate_c, t_fencegate_o, t_chaingate_c, t_chaingate_o, - t_retractable_gate_l, t_retractable_gate_c, t_retractable_gate_o, - t_door_boarded, t_door_boarded_damaged, t_door_boarded_peep, t_rdoor_boarded, - t_rdoor_boarded_damaged, t_door_boarded_damaged_peep, - t_door_metal_c, t_door_metal_o, t_door_metal_locked, t_door_metal_pickable, - t_door_bar_c, t_door_bar_o, t_door_bar_locked, - t_door_glass_c, t_door_glass_o, t_door_glass_frosted_c, t_door_glass_frosted_o, - t_portcullis, - t_recycler, t_window, t_window_taped, t_window_domestic, t_window_domestic_taped, t_window_open, - t_curtains, t_window_bars_curtains, t_window_bars_domestic, - t_window_alarm, t_window_alarm_taped, t_window_empty, t_window_frame, t_window_boarded, - t_window_boarded_noglass, t_window_bars_alarm, t_window_bars, - t_metal_grate_window, t_metal_grate_window_with_curtain, t_metal_grate_window_with_curtain_open, - t_metal_grate_window_noglass, t_metal_grate_window_with_curtain_noglass, - t_metal_grate_window_with_curtain_open_noglass, - t_window_stained_green, t_window_stained_red, t_window_stained_blue, - t_window_no_curtains, t_window_no_curtains_open, t_window_no_curtains_taped, - t_rock, t_fault, - t_paper, - t_rock_wall, t_rock_wall_half, - // Tree - t_tree, t_tree_young, t_tree_apple, t_tree_apple_harvested, t_tree_coffee, t_tree_coffee_harvested, - t_tree_pear, t_tree_pear_harvested, - t_tree_cherry, t_tree_cherry_harvested, t_tree_peach, t_tree_peach_harvested, t_tree_apricot, - t_tree_apricot_harvested, - t_tree_plum, t_tree_plum_harvested, t_tree_pine, t_tree_blackjack, t_tree_birch, - t_tree_birch_harvested, t_tree_willow, t_tree_willow_harvested, t_tree_maple, t_tree_maple_tapped, - t_tree_deadpine, t_tree_hickory, t_tree_hickory_dead, t_tree_hickory_harvested, t_underbrush, - t_shrub, t_shrub_blueberry, t_shrub_strawberry, t_trunk, t_stump, - t_root_wall, - t_wax, t_floor_wax, - t_fence, t_chainfence, t_chainfence_posts, - t_fence_post, t_fence_wire, t_fence_barbed, t_fence_rope, - t_railing, - // Nether - t_marloss, t_fungus_floor_in, t_fungus_floor_sup, t_fungus_floor_out, t_fungus_wall, - t_fungus_mound, t_fungus, t_shrub_fungal, t_tree_fungal, t_tree_fungal_young, t_marloss_tree, - // Water, lava, etc. - t_water_moving_dp, t_water_moving_sh, t_water_sh, t_swater_sh, t_water_dp, t_swater_dp, - t_swater_surf, t_water_pool, t_sewage, - t_lava, - // More embellishments than you can shake a stick at. - t_sandbox, t_slide, t_monkey_bars, t_backboard, - t_gas_pump, t_gas_pump_smashed, - t_diesel_pump, t_diesel_pump_smashed, - t_atm, - t_missile, t_missile_exploded, - t_radio_tower, t_radio_controls, - t_gates_mech_control, t_gates_control_concrete, t_gates_control_brick, - t_barndoor, t_palisade_pulley, - t_gates_control_metal, - t_sewage_pipe, t_sewage_pump, - t_column, - t_vat, - t_rootcellar, - t_cvdbody, t_cvdmachine, - t_water_pump, - t_conveyor, - t_improvised_shelter, - // Staircases etc. - t_stairs_down, t_stairs_up, t_manhole, t_ladder_up, t_ladder_down, t_slope_down, - t_slope_up, t_rope_up, - t_manhole_cover, - // Special - t_card_science, t_card_military, t_card_industrial, t_card_reader_broken, t_slot_machine, - t_elevator_control, t_elevator_control_off, t_elevator, t_pedestal_wyrm, - t_pedestal_temple, - // Temple tiles - t_rock_red, t_rock_green, t_rock_blue, t_floor_red, t_floor_green, t_floor_blue, - t_switch_rg, t_switch_gb, t_switch_rb, t_switch_even, - t_rdoor_c, t_rdoor_b, t_rdoor_o, t_mdoor_frame, t_window_reinforced, t_window_reinforced_noglass, - t_window_enhanced, t_window_enhanced_noglass, t_open_air, - t_pavement_bg_dp, t_pavement_y_bg_dp, t_sidewalk_bg_dp, t_guardrail_bg_dp, - t_linoleum_white, t_linoleum_gray, t_rad_platform, - // Railroad and subway - t_railroad_rubble, - t_buffer_stop, t_railroad_crossing_signal, t_crossbuck_wood, t_crossbuck_metal, - t_railroad_tie, t_railroad_tie_h, t_railroad_tie_v, t_railroad_tie_d, - t_railroad_track, t_railroad_track_h, t_railroad_track_v, t_railroad_track_d, t_railroad_track_d1, - t_railroad_track_d2, - t_railroad_track_on_tie, t_railroad_track_h_on_tie, t_railroad_track_v_on_tie, - t_railroad_track_d_on_tie; - +extern ter_id t_null; /* runtime index: furn_id furn_id refers to a position in the furnlist[] where the furn_t struct is stored. See note diff --git a/src/mapgen.cpp b/src/mapgen.cpp index 5a9ca709bbd73..45479046169e5 100644 --- a/src/mapgen.cpp +++ b/src/mapgen.cpp @@ -151,6 +151,36 @@ static const oter_str_id oter_tower_lab_stairs( "tower_lab_stairs" ); static const oter_type_str_id oter_type_road( "road" ); static const oter_type_str_id oter_type_sewer( "sewer" ); +static const ter_str_id ter_t_bars( "t_bars" ); +static const ter_str_id ter_t_card_science( "t_card_science" ); +static const ter_str_id ter_t_concrete_wall( "t_concrete_wall" ); +static const ter_str_id ter_t_cvdbody( "t_cvdbody" ); +static const ter_str_id ter_t_cvdmachine( "t_cvdmachine" ); +static const ter_str_id ter_t_dirt( "t_dirt" ); +static const ter_str_id ter_t_door_glass_frosted_c( "t_door_glass_frosted_c" ); +static const ter_str_id ter_t_door_metal_c( "t_door_metal_c" ); +static const ter_str_id ter_t_door_metal_locked( "t_door_metal_locked" ); +static const ter_str_id ter_t_floor( "t_floor" ); +static const ter_str_id ter_t_fungus_floor_in( "t_fungus_floor_in" ); +static const ter_str_id ter_t_fungus_wall( "t_fungus_wall" ); +static const ter_str_id ter_t_grass( "t_grass" ); +static const ter_str_id ter_t_marloss( "t_marloss" ); +static const ter_str_id ter_t_radio_tower( "t_radio_tower" ); +static const ter_str_id ter_t_reinforced_door_glass_c( "t_reinforced_door_glass_c" ); +static const ter_str_id ter_t_reinforced_glass( "t_reinforced_glass" ); +static const ter_str_id ter_t_rock_floor( "t_rock_floor" ); +static const ter_str_id ter_t_sewage( "t_sewage" ); +static const ter_str_id ter_t_slime( "t_slime" ); +static const ter_str_id ter_t_slope_down( "t_slope_down" ); +static const ter_str_id ter_t_slope_up( "t_slope_up" ); +static const ter_str_id ter_t_stairs_down( "t_stairs_down" ); +static const ter_str_id ter_t_stairs_up( "t_stairs_up" ); +static const ter_str_id ter_t_strconc_floor( "t_strconc_floor" ); +static const ter_str_id ter_t_thconc_floor( "t_thconc_floor" ); +static const ter_str_id ter_t_thconc_floor_olight( "t_thconc_floor_olight" ); +static const ter_str_id ter_t_vat( "t_vat" ); +static const ter_str_id ter_t_water_sh( "t_water_sh" ); + static const trait_id trait_NPC_STATIC_NPC( "NPC_STATIC_NPC" ); static const vproto_id vehicle_prototype_shopping_cart( "shopping_cart" ); @@ -3009,7 +3039,7 @@ class jmapgen_make_rubble : public jmapgen_piece public: mapgen_value rubble_type = mapgen_value( f_rubble ); bool items = false; - mapgen_value floor_type = mapgen_value( t_dirt ); + mapgen_value floor_type = mapgen_value( ter_t_dirt ); bool overwrite = false; jmapgen_make_rubble( const JsonObject &jsi, const std::string_view/*context*/ ) { if( jsi.has_member( "rubble_type" ) ) { @@ -3030,7 +3060,7 @@ class jmapgen_make_rubble : public jmapgen_piece } if( chosen_floor_type.id().is_null() ) { debugmsg( "null floor type when making rubble" ); - chosen_floor_type = t_dirt; + chosen_floor_type = ter_t_dirt; } dat.m.make_rubble( tripoint( x.get(), y.get(), dat.m.get_abs_sub().z() ), chosen_rubble_type, items, chosen_floor_type, overwrite ); @@ -4462,25 +4492,15 @@ bool mapgen_function_json_base::setup_common( const JsonObject &jo ) jo.read( "flags", flags_ ); - // just like mapf::basic_bind("stuff",blargle("foo", etc) ), only json input and faster when applying - if( jo.has_array( "rows" ) ) { - mapgen_palette palette = mapgen_palette::load_temp( jo, "dda", context_ ); - auto &keys_with_terrain = palette.keys_with_terrain; - mapgen_palette::placing_map &format_placings = palette.format_placings; - - if( palette.keys_with_terrain.empty() && !fallback_terrain_exists ) { - return false; - } - - parameters = palette.get_parameters(); - - // mandatory: mapgensize rows of mapgensize character lines, each of which must have a - // matching key in "terrain", unless fill_ter is set - // "rows:" [ "aaaajustlikeinmapgen.cpp", "this.must!be!exactly.24!", "and_must_match_terrain_", .... ] - point expected_dim = mapgensize + m_offset; - cata_assert( expected_dim.x >= 0 ); - cata_assert( expected_dim.y >= 0 ); - + // mandatory: mapgensize rows of mapgensize character lines, each of which must have a + // matching key in "terrain", unless fill_ter is set + // "rows:" [ "aaaajustlikeinmapgen.cpp", "this.must!be!exactly.24!", "and_must_match_terrain_", .... ] + point expected_dim = mapgensize + m_offset; + cata_assert( expected_dim.x >= 0 ); + cata_assert( expected_dim.y >= 0 ); + const std::string default_row( expected_dim.x, ' ' ); + const bool default_rows = !jo.has_array( "rows" ); + if( !default_rows ) { parray = jo.get_array( "rows" ); if( static_cast( parray.size() ) < expected_dim.y ) { parray.throw_error( string_format( "format: rows: must have at least %d rows, not %d", @@ -4491,64 +4511,77 @@ bool mapgen_function_json_base::setup_common( const JsonObject &jo ) string_format( "format: rows: must have %d rows, not %d; check mapgensize if applicable", total_size.y, parray.size() ) ); } - for( int c = m_offset.y; c < expected_dim.y; c++ ) { - const std::string row = parray.get_string( c ); - static std::vector row_keys; - row_keys.clear(); - row_keys.reserve( total_size.x ); - utf8_display_split_into( row, row_keys ); - if( row_keys.size() < static_cast( expected_dim.x ) ) { - parray.throw_error( - string_format( " format: row %d must have at least %d columns, not %d", - c + 1, expected_dim.x, row_keys.size() ) ); - } - if( row_keys.size() != static_cast( total_size.x ) ) { - parray.throw_error( - string_format( " format: row %d must have %d columns, not %d; check mapgensize if applicable", - c + 1, total_size.x, row_keys.size() ) ); - } - for( int i = m_offset.x; i < expected_dim.x; i++ ) { - const point p = point( i, c ) - m_offset; - const map_key key{ std::string( row_keys[i] ) }; - const auto iter_ter = keys_with_terrain.find( key ); - const auto fpi = format_placings.find( key ); - - const bool has_terrain = iter_ter != keys_with_terrain.end(); - const bool has_placing = fpi != format_placings.end(); - - if( !has_terrain && !fallback_terrain_exists ) { - parray.string_error( - c, i + 1, - string_format( "format: rows: row %d column %d: " - "'%s' is not in 'terrain', and no 'fill_ter' is set!", - c + 1, i + 1, key.str ) ); - } - if( !has_terrain && !has_placing && key.str != " " && key.str != "." ) { - try { - parray.string_error( - c, i + 1, - string_format( "format: rows: row %d column %d: " - "'%s' has no terrain, furniture, or other definition", - c + 1, i + 1, key.str ) ); - } catch( const JsonError &e ) { - debugmsg( "(json-error)\n%s", e.what() ); - } + } + + // just like mapf::basic_bind("stuff",blargle("foo", etc) ), only json input and faster when applying + mapgen_palette palette = mapgen_palette::load_temp( jo, "dda", context_ ); + auto &keys_with_terrain = palette.keys_with_terrain; + mapgen_palette::placing_map &format_placings = palette.format_placings; + + if( palette.keys_with_terrain.empty() && !fallback_terrain_exists ) { + return false; + } + + parameters = palette.get_parameters(); + + for( int c = m_offset.y; c < expected_dim.y; c++ ) { + const std::string row = default_rows ? default_row : parray.get_string( c ); + static std::vector row_keys; + row_keys.clear(); + row_keys.reserve( total_size.x ); + utf8_display_split_into( row, row_keys ); + if( row_keys.size() < static_cast( expected_dim.x ) ) { + cata_assert( !default_rows ); + parray.throw_error( + string_format( "format: row %d must have at least %d columns, not %d", + c + 1, expected_dim.x, row_keys.size() ) ); + } + if( row_keys.size() != static_cast( total_size.x ) ) { + cata_assert( !default_rows ); + parray.throw_error( + string_format( "format: row %d must have %d columns, not %d; check mapgensize if applicable", + c + 1, total_size.x, row_keys.size() ) ); + } + for( int i = m_offset.x; i < expected_dim.x; i++ ) { + const point p = point( i, c ) - m_offset; + const map_key key{ std::string( row_keys[i] ) }; + const auto iter_ter = keys_with_terrain.find( key ); + const auto fpi = format_placings.find( key ); + + const bool has_terrain = iter_ter != keys_with_terrain.end(); + const bool has_placing = fpi != format_placings.end(); + + if( !has_terrain && !fallback_terrain_exists ) { + cata_assert( !default_rows ); + parray.string_error( c, i + 1, + string_format( "format: rows: row %d column %d: '%s' is not in 'terrain'," + "and no 'fill_ter', 'predecessor_mapgen' or 'fallback_predecessor_mapgen' is set!", + c + 1, i + 1, key.str ) ); + } + if( !has_terrain && !has_placing && key.str != " " && key.str != "." ) { + try { + cata_assert( !default_rows ); + parray.string_error( c, i + 1, + string_format( "format: rows: row %d column %d: '%s' has no terrain, furniture, or other definition", + c + 1, i + 1, key.str ) ); + } catch( const JsonError &e ) { + debugmsg( "(json-error)\n%s", e.what() ); } - if( has_placing ) { - jmapgen_place where( p ); - for( auto &what : fpi->second ) { - objects.add( where, what ); - } + } + if( has_placing ) { + jmapgen_place where( p ); + for( auto &what : fpi->second ) { + objects.add( where, what ); } } } - fallback_terrain_exists = true; } + fallback_terrain_exists = true; // No fill_ter? No format? GTFO. if( !fallback_terrain_exists ) { jo.throw_error( - "Need one of 'fill_terrain' or 'predecessor_mapgen' or 'rows' + 'terrain'" ); + "Need one of 'fill_terrain', 'predecessor_mapgen', 'fallback_predecessor_mapgen', 'terrain' or a palette providing 'terrain'." ); // TODO: write TFM. } @@ -5280,7 +5313,7 @@ void map::draw_map( mapgendata &dat ) // load from JSON??? debugmsg( "Error: tried to generate map for omtype %s, \"%s\" (id_mapgen %s)", terrain_type.id().c_str(), terrain_type->get_name(), function_key.c_str() ); - fill_background( this, t_floor ); + fill_background( this, ter_t_floor ); } resolve_regional_terrain_and_furniture( dat ); @@ -5352,23 +5385,23 @@ void map::draw_lab( mapgendata &dat ) if( i <= 1 || i >= SEEX * 2 - 2 || j <= 1 || j >= SEEY * 2 - 2 || i == SEEX - 2 || i == SEEX + 1 ) { - ter_set( point( i, j ), t_concrete_wall ); + ter_set( point( i, j ), ter_t_concrete_wall ); } else { - ter_set( point( i, j ), t_floor ); + ter_set( point( i, j ), ter_t_floor ); } } } - ter_set( point( SEEX - 1, 0 ), t_door_metal_locked ); - ter_set( point( SEEX - 1, 1 ), t_floor ); - ter_set( point( SEEX, 0 ), t_door_metal_locked ); - ter_set( point( SEEX, 1 ), t_floor ); - ter_set( point( SEEX - 2 + rng( 0, 1 ) * 3, 0 ), t_card_science ); - ter_set( point( SEEX - 2, SEEY ), t_door_metal_c ); - ter_set( point( SEEX + 1, SEEY ), t_door_metal_c ); - ter_set( point( SEEX - 2, SEEY - 1 ), t_door_metal_c ); - ter_set( point( SEEX + 1, SEEY - 1 ), t_door_metal_c ); - ter_set( point( SEEX - 1, SEEY * 2 - 3 ), t_stairs_down ); - ter_set( point( SEEX, SEEY * 2 - 3 ), t_stairs_down ); + ter_set( point( SEEX - 1, 0 ), ter_t_door_metal_locked ); + ter_set( point( SEEX - 1, 1 ), ter_t_floor ); + ter_set( point( SEEX, 0 ), ter_t_door_metal_locked ); + ter_set( point( SEEX, 1 ), ter_t_floor ); + ter_set( point( SEEX - 2 + rng( 0, 1 ) * 3, 0 ), ter_t_card_science ); + ter_set( point( SEEX - 2, SEEY ), ter_t_door_metal_c ); + ter_set( point( SEEX + 1, SEEY ), ter_t_door_metal_c ); + ter_set( point( SEEX - 2, SEEY - 1 ), ter_t_door_metal_c ); + ter_set( point( SEEX + 1, SEEY - 1 ), ter_t_door_metal_c ); + ter_set( point( SEEX - 1, SEEY * 2 - 3 ), ter_t_stairs_down ); + ter_set( point( SEEX, SEEY * 2 - 3 ), ter_t_stairs_down ); science_room( this, point( 2, 2 ), point( SEEX - 3, SEEY * 2 - 3 ), dat.zlevel(), 1 ); science_room( this, point( SEEX + 2, 2 ), point( SEEX * 2 - 3, SEEY * 2 - 3 ), dat.zlevel(), 3 ); @@ -5384,27 +5417,27 @@ void map::draw_lab( mapgendata &dat ) } else if( tw != 0 || rw != 0 || lw != 0 || bw != 0 ) { // Sewers! for( int i = 0; i < SEEX * 2; i++ ) { for( int j = 0; j < SEEY * 2; j++ ) { - ter_set( point( i, j ), t_thconc_floor ); + ter_set( point( i, j ), ter_t_thconc_floor ); if( ( ( i < lw || i > EAST_EDGE - rw ) && j > SEEY - 3 && j < SEEY + 2 ) || ( ( j < tw || j > SOUTH_EDGE - bw ) && i > SEEX - 3 && i < SEEX + 2 ) ) { - ter_set( point( i, j ), t_sewage ); + ter_set( point( i, j ), ter_t_sewage ); } if( ( i == 0 && is_ot_match( "lab", dat.east(), ot_match_type::contains ) ) || i == EAST_EDGE ) { - if( ter( point( i, j ) ) == t_sewage ) { - ter_set( point( i, j ), t_bars ); + if( ter( point( i, j ) ) == ter_t_sewage ) { + ter_set( point( i, j ), ter_t_bars ); } else if( j == SEEY - 1 || j == SEEY ) { - ter_set( point( i, j ), t_door_metal_c ); + ter_set( point( i, j ), ter_t_door_metal_c ); } else { - ter_set( point( i, j ), t_concrete_wall ); + ter_set( point( i, j ), ter_t_concrete_wall ); } } else if( ( j == 0 && is_ot_match( "lab", dat.north(), ot_match_type::contains ) ) || j == SOUTH_EDGE ) { - if( ter( point( i, j ) ) == t_sewage ) { - ter_set( point( i, j ), t_bars ); + if( ter( point( i, j ) ) == ter_t_sewage ) { + ter_set( point( i, j ), ter_t_bars ); } else if( i == SEEX - 1 || i == SEEX ) { - ter_set( point( i, j ), t_door_metal_c ); + ter_set( point( i, j ), ter_t_door_metal_c ); } else { - ter_set( point( i, j ), t_concrete_wall ); + ter_set( point( i, j ), ter_t_concrete_wall ); } } } @@ -5437,7 +5470,7 @@ void map::draw_lab( mapgendata &dat ) const auto maybe_insert_stairs = [this]( const oter_id & terrain, const ter_id & t_stair_type ) { if( is_ot_match( "stairs", terrain, ot_match_type::contains ) ) { const auto predicate = [this]( const tripoint & p ) { - return ter( p ) == t_thconc_floor && furn( p ) == f_null && tr_at( p ).is_null(); + return ter( p ) == ter_t_thconc_floor && furn( p ) == f_null && tr_at( p ).is_null(); }; const auto range = points_in_rectangle( { 0, 0, abs_sub.z() }, @@ -5465,8 +5498,8 @@ void map::draw_lab( mapgendata &dat ) } else { debugmsg( "Error: Tried to generate 1-sided lab but no lab_1side json exists." ); } - maybe_insert_stairs( dat.above(), t_stairs_up ); - maybe_insert_stairs( terrain_type, t_stairs_down ); + maybe_insert_stairs( dat.above(), ter_t_stairs_up ); + maybe_insert_stairs( terrain_type, ter_t_stairs_down ); } else { const int hardcoded_4side_map_weight = 1500; // weight of all hardcoded maps. // If you remove the usage of "lab_4side" here, remove it from mapgen_factory::get_usages above as well. @@ -5480,12 +5513,12 @@ void map::draw_lab( mapgendata &dat ) !has_flag_ter( ter_furn_flag::TFLAG_DOOR, east_border ) ) { // TODO: create a ter_reset function that does ter_set, // furn_set, and i_clear? - ter_id lw_type = tower_lab ? t_reinforced_glass : t_concrete_wall; - ter_id tw_type = tower_lab ? t_reinforced_glass : t_concrete_wall; - ter_id rw_type = tower_lab && rw == 2 ? t_reinforced_glass : - t_concrete_wall; - ter_id bw_type = tower_lab && bw == 2 ? t_reinforced_glass : - t_concrete_wall; + ter_str_id lw_type = tower_lab ? ter_t_reinforced_glass : ter_t_concrete_wall; + ter_str_id tw_type = tower_lab ? ter_t_reinforced_glass : ter_t_concrete_wall; + ter_str_id rw_type = tower_lab && rw == 2 ? ter_t_reinforced_glass : + ter_t_concrete_wall; + ter_str_id bw_type = tower_lab && bw == 2 ? ter_t_reinforced_glass : + ter_t_concrete_wall; for( int i = 0; i < SEEX * 2; i++ ) { ter_set( point( 23, i ), rw_type ); furn_set( point( 23, i ), f_null ); @@ -5507,17 +5540,17 @@ void map::draw_lab( mapgendata &dat ) } } if( rw != 2 ) { - ter_set( point( 23, 11 ), t_door_metal_c ); - ter_set( point( 23, 12 ), t_door_metal_c ); + ter_set( point( 23, 11 ), ter_t_door_metal_c ); + ter_set( point( 23, 12 ), ter_t_door_metal_c ); } if( bw != 2 ) { - ter_set( point( 11, 23 ), t_door_metal_c ); - ter_set( point( 12, 23 ), t_door_metal_c ); + ter_set( point( 11, 23 ), ter_t_door_metal_c ); + ter_set( point( 12, 23 ), ter_t_door_metal_c ); } } - maybe_insert_stairs( dat.above(), t_stairs_up ); - maybe_insert_stairs( terrain_type, t_stairs_down ); + maybe_insert_stairs( dat.above(), ter_t_stairs_up ); + maybe_insert_stairs( terrain_type, ter_t_stairs_down ); } else { // then no json maps for lab_4side were found switch( rng( 1, 3 ) ) { case 1: @@ -5530,61 +5563,61 @@ void map::draw_lab( mapgendata &dat ) ( j < tw || j > SOUTH_EDGE - bw ) || ( ( i < SEEX - 1 || i > SEEX ) && ( j == SEEY - 2 || j == SEEY + 1 ) ) ) { - ter_set( point( i, j ), t_concrete_wall ); + ter_set( point( i, j ), ter_t_concrete_wall ); } else { - ter_set( point( i, j ), t_thconc_floor ); + ter_set( point( i, j ), ter_t_thconc_floor ); } } } if( is_ot_match( "stairs", dat.above(), ot_match_type::contains ) ) { ter_set( point( rng( SEEX - 1, SEEX ), rng( SEEY - 1, SEEY ) ), - t_stairs_up ); + ter_t_stairs_up ); } // Top left if( one_in( 2 ) ) { - ter_set( point( SEEX - 2, static_cast( SEEY / 2 ) ), t_door_glass_frosted_c ); + ter_set( point( SEEX - 2, static_cast( SEEY / 2 ) ), ter_t_door_glass_frosted_c ); science_room( this, point( lw, tw ), point( SEEX - 3, SEEY - 3 ), dat.zlevel(), 1 ); } else { - ter_set( point( SEEX / 2, SEEY - 2 ), t_door_glass_frosted_c ); + ter_set( point( SEEX / 2, SEEY - 2 ), ter_t_door_glass_frosted_c ); science_room( this, point( lw, tw ), point( SEEX - 3, SEEY - 3 ), dat.zlevel(), 2 ); } // Top right if( one_in( 2 ) ) { - ter_set( point( SEEX + 1, static_cast( SEEY / 2 ) ), t_door_glass_frosted_c ); + ter_set( point( SEEX + 1, static_cast( SEEY / 2 ) ), ter_t_door_glass_frosted_c ); science_room( this, point( SEEX + 2, tw ), point( EAST_EDGE - rw, SEEY - 3 ), dat.zlevel(), 3 ); } else { - ter_set( point( SEEX + static_cast( SEEX / 2 ), SEEY - 2 ), t_door_glass_frosted_c ); + ter_set( point( SEEX + static_cast( SEEX / 2 ), SEEY - 2 ), ter_t_door_glass_frosted_c ); science_room( this, point( SEEX + 2, tw ), point( EAST_EDGE - rw, SEEY - 3 ), dat.zlevel(), 2 ); } // Bottom left if( one_in( 2 ) ) { - ter_set( point( SEEX / 2, SEEY + 1 ), t_door_glass_frosted_c ); + ter_set( point( SEEX / 2, SEEY + 1 ), ter_t_door_glass_frosted_c ); science_room( this, point( lw, SEEY + 2 ), point( SEEX - 3, SOUTH_EDGE - bw ), dat.zlevel(), 0 ); } else { - ter_set( point( SEEX - 2, SEEY + static_cast( SEEY / 2 ) ), t_door_glass_frosted_c ); + ter_set( point( SEEX - 2, SEEY + static_cast( SEEY / 2 ) ), ter_t_door_glass_frosted_c ); science_room( this, point( lw, SEEY + 2 ), point( SEEX - 3, SOUTH_EDGE - bw ), dat.zlevel(), 1 ); } // Bottom right if( one_in( 2 ) ) { - ter_set( point( SEEX + static_cast( SEEX / 2 ), SEEY + 1 ), t_door_glass_frosted_c ); + ter_set( point( SEEX + static_cast( SEEX / 2 ), SEEY + 1 ), ter_t_door_glass_frosted_c ); science_room( this, point( SEEX + 2, SEEY + 2 ), point( EAST_EDGE - rw, SOUTH_EDGE - bw ), dat.zlevel(), 0 ); } else { - ter_set( point( SEEX + 1, SEEY + static_cast( SEEY / 2 ) ), t_door_glass_frosted_c ); + ter_set( point( SEEX + 1, SEEY + static_cast( SEEY / 2 ) ), ter_t_door_glass_frosted_c ); science_room( this, point( SEEX + 2, SEEY + 2 ), point( EAST_EDGE - rw, SOUTH_EDGE - bw ), dat.zlevel(), 3 ); } if( rw == 1 ) { - ter_set( point( EAST_EDGE, SEEY - 1 ), t_door_metal_c ); - ter_set( point( EAST_EDGE, SEEY ), t_door_metal_c ); + ter_set( point( EAST_EDGE, SEEY - 1 ), ter_t_door_metal_c ); + ter_set( point( EAST_EDGE, SEEY ), ter_t_door_metal_c ); } if( bw == 1 ) { - ter_set( point( SEEX - 1, SOUTH_EDGE ), t_door_metal_c ); - ter_set( point( SEEX, SOUTH_EDGE ), t_door_metal_c ); + ter_set( point( SEEX - 1, SOUTH_EDGE ), ter_t_door_metal_c ); + ter_set( point( SEEX, SOUTH_EDGE ), ter_t_door_metal_c ); } if( is_ot_match( "stairs", terrain_type, ot_match_type::contains ) ) { // Stairs going down std::vector stair_points; @@ -5621,7 +5654,7 @@ void map::draw_lab( mapgendata &dat ) stair_points.emplace_back( SEEX, static_cast( SEEY / 2 ) + SEEY ); stair_points.emplace_back( SEEX + 2, static_cast( SEEY / 2 ) + SEEY ); const point p = random_entry( stair_points ); - ter_set( p, t_stairs_down ); + ter_set( p, ter_t_stairs_down ); } break; @@ -5634,30 +5667,30 @@ void map::draw_lab( mapgendata &dat ) i == SEEX - 4 || i == SEEX + 3 || j < tw || j > SOUTH_EDGE - bw || j == SEEY - 4 || j == SEEY + 3 ) { - ter_set( point( i, j ), t_concrete_wall ); + ter_set( point( i, j ), ter_t_concrete_wall ); } else { - ter_set( point( i, j ), t_thconc_floor ); + ter_set( point( i, j ), ter_t_thconc_floor ); } } } if( is_ot_match( "stairs", dat.above(), ot_match_type::contains ) ) { - ter_set( point( SEEX - 1, SEEY - 1 ), t_stairs_up ); - ter_set( point( SEEX, SEEY - 1 ), t_stairs_up ); - ter_set( point( SEEX - 1, SEEY ), t_stairs_up ); - ter_set( point( SEEX, SEEY ), t_stairs_up ); + ter_set( point( SEEX - 1, SEEY - 1 ), ter_t_stairs_up ); + ter_set( point( SEEX, SEEY - 1 ), ter_t_stairs_up ); + ter_set( point( SEEX - 1, SEEY ), ter_t_stairs_up ); + ter_set( point( SEEX, SEEY ), ter_t_stairs_up ); } - ter_set( point( SEEX - rng( 0, 1 ), SEEY - 4 ), t_door_glass_frosted_c ); - ter_set( point( SEEX - rng( 0, 1 ), SEEY + 3 ), t_door_glass_frosted_c ); - ter_set( point( SEEX - 4, SEEY + rng( 0, 1 ) ), t_door_glass_frosted_c ); - ter_set( point( SEEX + 3, SEEY + rng( 0, 1 ) ), t_door_glass_frosted_c ); - ter_set( point( SEEX - 4, static_cast( SEEY / 2 ) ), t_door_glass_frosted_c ); - ter_set( point( SEEX + 3, static_cast( SEEY / 2 ) ), t_door_glass_frosted_c ); - ter_set( point( SEEX / 2, SEEY - 4 ), t_door_glass_frosted_c ); - ter_set( point( SEEX / 2, SEEY + 3 ), t_door_glass_frosted_c ); - ter_set( point( SEEX + static_cast( SEEX / 2 ), SEEY - 4 ), t_door_glass_frosted_c ); - ter_set( point( SEEX + static_cast( SEEX / 2 ), SEEY + 3 ), t_door_glass_frosted_c ); - ter_set( point( SEEX - 4, SEEY + static_cast( SEEY / 2 ) ), t_door_glass_frosted_c ); - ter_set( point( SEEX + 3, SEEY + static_cast( SEEY / 2 ) ), t_door_glass_frosted_c ); + ter_set( point( SEEX - rng( 0, 1 ), SEEY - 4 ), ter_t_door_glass_frosted_c ); + ter_set( point( SEEX - rng( 0, 1 ), SEEY + 3 ), ter_t_door_glass_frosted_c ); + ter_set( point( SEEX - 4, SEEY + rng( 0, 1 ) ), ter_t_door_glass_frosted_c ); + ter_set( point( SEEX + 3, SEEY + rng( 0, 1 ) ), ter_t_door_glass_frosted_c ); + ter_set( point( SEEX - 4, static_cast( SEEY / 2 ) ), ter_t_door_glass_frosted_c ); + ter_set( point( SEEX + 3, static_cast( SEEY / 2 ) ), ter_t_door_glass_frosted_c ); + ter_set( point( SEEX / 2, SEEY - 4 ), ter_t_door_glass_frosted_c ); + ter_set( point( SEEX / 2, SEEY + 3 ), ter_t_door_glass_frosted_c ); + ter_set( point( SEEX + static_cast( SEEX / 2 ), SEEY - 4 ), ter_t_door_glass_frosted_c ); + ter_set( point( SEEX + static_cast( SEEX / 2 ), SEEY + 3 ), ter_t_door_glass_frosted_c ); + ter_set( point( SEEX - 4, SEEY + static_cast( SEEY / 2 ) ), ter_t_door_glass_frosted_c ); + ter_set( point( SEEX + 3, SEEY + static_cast( SEEY / 2 ) ), ter_t_door_glass_frosted_c ); science_room( this, point( lw, tw ), point( SEEX - 5, SEEY - 5 ), dat.zlevel(), rng( 1, 2 ) ); science_room( this, point( SEEX - 3, tw ), point( SEEX + 2, SEEY - 5 ), dat.zlevel(), 2 ); @@ -5673,16 +5706,16 @@ void map::draw_lab( mapgendata &dat ) science_room( this, point( SEEX + 4, SEEX + 4 ), point( EAST_EDGE - rw, SOUTH_EDGE - bw ), dat.zlevel(), 3 * rng( 0, 1 ) ); if( rw == 1 ) { - ter_set( point( EAST_EDGE, SEEY - 1 ), t_door_metal_c ); - ter_set( point( EAST_EDGE, SEEY ), t_door_metal_c ); + ter_set( point( EAST_EDGE, SEEY - 1 ), ter_t_door_metal_c ); + ter_set( point( EAST_EDGE, SEEY ), ter_t_door_metal_c ); } if( bw == 1 ) { - ter_set( point( SEEX - 1, SOUTH_EDGE ), t_door_metal_c ); - ter_set( point( SEEX, SOUTH_EDGE ), t_door_metal_c ); + ter_set( point( SEEX - 1, SOUTH_EDGE ), ter_t_door_metal_c ); + ter_set( point( SEEX, SOUTH_EDGE ), ter_t_door_metal_c ); } if( is_ot_match( "stairs", terrain_type, ot_match_type::contains ) ) { ter_set( point( SEEX - 3 + 5 * rng( 0, 1 ), SEEY - 3 + 5 * rng( 0, 1 ) ), - t_stairs_down ); + ter_t_stairs_down ); } break; @@ -5692,9 +5725,9 @@ void map::draw_lab( mapgendata &dat ) for( int j = 0; j < SEEY * 2; j++ ) { if( i < lw || i >= EAST_EDGE - rw || j < tw || j >= SOUTH_EDGE - bw ) { - ter_set( point( i, j ), t_concrete_wall ); + ter_set( point( i, j ), ter_t_concrete_wall ); } else { - ter_set( point( i, j ), t_thconc_floor ); + ter_set( point( i, j ), ter_t_thconc_floor ); } } } @@ -5702,15 +5735,15 @@ void map::draw_lab( mapgendata &dat ) dat.zlevel(), rng( 0, 3 ) ); if( rw == 1 ) { - ter_set( point( EAST_EDGE, SEEY - 1 ), t_door_metal_c ); - ter_set( point( EAST_EDGE, SEEY ), t_door_metal_c ); + ter_set( point( EAST_EDGE, SEEY - 1 ), ter_t_door_metal_c ); + ter_set( point( EAST_EDGE, SEEY ), ter_t_door_metal_c ); } if( bw == 1 ) { - ter_set( point( SEEX - 1, SOUTH_EDGE ), t_door_metal_c ); - ter_set( point( SEEX, SOUTH_EDGE ), t_door_metal_c ); + ter_set( point( SEEX - 1, SOUTH_EDGE ), ter_t_door_metal_c ); + ter_set( point( SEEX, SOUTH_EDGE ), ter_t_door_metal_c ); } - maybe_insert_stairs( dat.above(), t_stairs_up ); - maybe_insert_stairs( terrain_type, t_stairs_down ); + maybe_insert_stairs( dat.above(), ter_t_stairs_up ); + maybe_insert_stairs( terrain_type, ter_t_stairs_down ); break; } } // endif use_hardcoded_4side_map @@ -5732,7 +5765,7 @@ void map::draw_lab( mapgendata &dat ) one_in( 4 ) ) { // bash and usually remove the rubble. make_rubble( { i, j, abs_sub.z() } ); - ter_set( point( i, j ), t_rock_floor ); + ter_set( point( i, j ), ter_t_rock_floor ); if( !one_in( 3 ) ) { furn_set( point( i, j ), f_null ); } @@ -5743,8 +5776,9 @@ void map::draw_lab( mapgendata &dat ) !has_flag_ter( ter_furn_flag::TFLAG_GOES_UP, p2 ) ) { destroy( { i, j, abs_sub.z() } ); // bashed squares can create dirt & floors, but we want rock floors. - if( t_dirt == ter( point( i, j ) ) || t_floor == ter( point( i, j ) ) ) { - ter_set( point( i, j ), t_rock_floor ); + const ter_id &floor_to_check_ter = ter( point( i, j ) ); + if( floor_to_check_ter == ter_t_dirt || floor_to_check_ter == ter_t_floor ) { + ter_set( point( i, j ), ter_t_rock_floor ); } } } @@ -5764,9 +5798,9 @@ void map::draw_lab( mapgendata &dat ) ( ( j >= bw || i <= lw ) && i <= j && ( SOUTH_EDGE - j ) <= i ) ) { if( one_in( 5 ) ) { make_rubble( tripoint( i, j, abs_sub.z() ), f_rubble_rock, true, - t_slime ); + ter_t_slime ); } else if( !one_in( 5 ) ) { - ter_set( point( i, j ), t_slime ); + ter_set( point( i, j ), ter_t_slime ); } } } @@ -5786,8 +5820,9 @@ void map::draw_lab( mapgendata &dat ) for( int i = 0; i < SEEX * 2; i++ ) { for( int j = 0; j < SEEY * 2; j++ ) { if( !( ( i * j ) % 2 || ( i + j ) % 4 ) && one_in( light_odds ) ) { - if( t_thconc_floor == ter( point( i, j ) ) || t_strconc_floor == ter( point( i, j ) ) ) { - ter_set( point( i, j ), t_thconc_floor_olight ); + const ter_id &nearby_ter = ter( point( i, j ) ); + if( nearby_ter == ter_t_thconc_floor || nearby_ter == ter_t_strconc_floor ) { + ter_set( point( i, j ), ter_t_thconc_floor_olight ); } } } @@ -5811,13 +5846,14 @@ void map::draw_lab( mapgendata &dat ) // liquid floors. break; } - ter_id fluid_type = one_in( 3 ) ? t_sewage : t_water_sh; + ter_id fluid_type = one_in( 3 ) ? ter_t_sewage : ter_t_water_sh; for( int i = 0; i < EAST_EDGE; i++ ) { for( int j = 0; j < SOUTH_EDGE; j++ ) { // We spare some terrain to make it look better visually. - if( !one_in( 10 ) && ( t_thconc_floor == ter( point( i, j ) ) || - t_strconc_floor == ter( point( i, j ) ) || - t_thconc_floor_olight == ter( point( i, j ) ) ) ) { + const ter_id &nearby_ter = ter( point( i, j ) ); + if( !one_in( 10 ) && ( nearby_ter == ter_t_thconc_floor || + nearby_ter == ter_t_strconc_floor || + nearby_ter == ter_t_thconc_floor_olight ) ) { ter_set( point( i, j ), fluid_type ); } else if( has_flag_ter( ter_furn_flag::TFLAG_DOOR, point( i, j ) ) && !one_in( 3 ) ) { // We want the actual debris, but not the rubble marker or dirt. @@ -5838,11 +5874,12 @@ void map::draw_lab( mapgendata &dat ) // liquid floors. break; } - ter_id fluid_type = one_in( 3 ) ? t_sewage : t_water_sh; + ter_id fluid_type = one_in( 3 ) ? ter_t_sewage : ter_t_water_sh; for( int i = 0; i < 2; ++i ) { draw_rough_circle( [this, fluid_type]( const point & p ) { - if( t_thconc_floor == ter( p ) || t_strconc_floor == ter( p ) || - t_thconc_floor_olight == ter( p ) ) { + const ter_id &maybe_flood_ter = ter( p ); + if( maybe_flood_ter == ter_t_thconc_floor || maybe_flood_ter == ter_t_strconc_floor || + maybe_flood_ter == ter_t_thconc_floor_olight ) { ter_set( p, fluid_type ); } else if( has_flag_ter( ter_furn_flag::TFLAG_DOOR, p ) ) { // We want the actual debris, but not the rubble marker or dirt. @@ -5860,8 +5897,9 @@ void map::draw_lab( mapgendata &dat ) bool is_toxic = one_in( 3 ); for( int i = 0; i < SEEX * 2; i++ ) { for( int j = 0; j < SEEY * 2; j++ ) { - if( one_in( 200 ) && ( t_thconc_floor == ter( point( i, j ) ) || - t_strconc_floor == ter( point( i, j ) ) ) ) { + const ter_id &nearby_ter = ter( point( i, j ) ); + if( one_in( 200 ) && ( nearby_ter == ter_t_thconc_floor || + nearby_ter == ter_t_strconc_floor ) ) { if( is_toxic ) { add_field( tripoint_bub_ms{i, j, abs_sub.z()}, fd_gas_vent, 1 ); } else { @@ -5899,7 +5937,7 @@ void map::draw_lab( mapgendata &dat ) return; // spare stairs and consoles. } make_rubble( {p, abs_sub.z() } ); - ter_set( p, t_thconc_floor ); + ter_set( p, ter_t_thconc_floor ); }, center->xy(), 4 ); furn_set( center->xy(), f_null ); if( !is_open_air( *center ) ) { @@ -5914,14 +5952,14 @@ void map::draw_lab( mapgendata &dat ) for( int j = 0; j < SOUTH_EDGE; j++ ) { // Create a mostly spread fungal area throughout entire lab. if( !one_in( 5 ) && has_flag( ter_furn_flag::TFLAG_FLAT, point( i, j ) ) ) { - ter_set( point( i, j ), t_fungus_floor_in ); + ter_set( point( i, j ), ter_t_fungus_floor_in ); if( has_flag_furn( ter_furn_flag::TFLAG_ORGANIC, point( i, j ) ) ) { furn_set( point( i, j ), f_fungal_clump ); } } else if( has_flag_ter( ter_furn_flag::TFLAG_DOOR, point( i, j ) ) && !one_in( 5 ) ) { - ter_set( point( i, j ), t_fungus_floor_in ); + ter_set( point( i, j ), ter_t_fungus_floor_in ); } else if( has_flag_ter( ter_furn_flag::TFLAG_WALL, point( i, j ) ) && one_in( 3 ) ) { - ter_set( point( i, j ), t_fungus_wall ); + ter_set( point( i, j ), ter_t_fungus_wall ); } } } @@ -5935,17 +5973,17 @@ void map::draw_lab( mapgendata &dat ) return; // spare stairs and consoles. } if( has_flag_ter( ter_furn_flag::TFLAG_WALL, p ) ) { - ter_set( p, t_fungus_wall ); + ter_set( p, ter_t_fungus_wall ); } else { - ter_set( p, t_fungus_floor_in ); + ter_set( p, ter_t_fungus_floor_in ); if( one_in( 3 ) ) { furn_set( p, f_flower_fungal ); } else if( one_in( 10 ) ) { - ter_set( p, t_marloss ); + ter_set( p, ter_t_marloss ); } } }, center.xy(), 3 ); - ter_set( center.xy(), t_fungus_floor_in ); + ter_set( center.xy(), ter_t_fungus_floor_in ); furn_set( center.xy(), f_null ); trap_set( center, tr_portal ); place_spawns( GROUP_FUNGI_FUNGALOID, 1, center.xy() + point( -2, -2 ), @@ -5990,10 +6028,10 @@ void map::draw_lab( mapgendata &dat ) if( !has_flag_ter( ter_furn_flag::TFLAG_WALL, east_border ) && !has_flag_ter( ter_furn_flag::TFLAG_DOOR, east_border ) ) { // TODO: create a ter_reset function that does ter_set, furn_set, and i_clear? - ter_id lw_type = tower_lab ? t_reinforced_glass : t_concrete_wall; - ter_id tw_type = tower_lab ? t_reinforced_glass : t_concrete_wall; - ter_id rw_type = tower_lab && rw == 2 ? t_reinforced_glass : t_concrete_wall; - ter_id bw_type = tower_lab && bw == 2 ? t_reinforced_glass : t_concrete_wall; + ter_str_id lw_type = tower_lab ? ter_t_reinforced_glass : ter_t_concrete_wall; + ter_str_id tw_type = tower_lab ? ter_t_reinforced_glass : ter_t_concrete_wall; + ter_str_id rw_type = tower_lab && rw == 2 ? ter_t_reinforced_glass : ter_t_concrete_wall; + ter_str_id bw_type = tower_lab && bw == 2 ? ter_t_reinforced_glass : ter_t_concrete_wall; for( int i = 0; i < SEEX * 2; i++ ) { ter_set( point( 23, i ), rw_type ); furn_set( point( 23, i ), f_null ); @@ -6015,12 +6053,12 @@ void map::draw_lab( mapgendata &dat ) } } if( rw != 2 ) { - ter_set( point( 23, 11 ), t_door_metal_c ); - ter_set( point( 23, 12 ), t_door_metal_c ); + ter_set( point( 23, 11 ), ter_t_door_metal_c ); + ter_set( point( 23, 12 ), ter_t_door_metal_c ); } if( bw != 2 ) { - ter_set( point( 11, 23 ), t_door_metal_c ); - ter_set( point( 12, 23 ), t_door_metal_c ); + ter_set( point( 11, 23 ), ter_t_door_metal_c ); + ter_set( point( 12, 23 ), ter_t_door_metal_c ); } } } else { // then no json maps for lab_finale_1level were found @@ -6028,19 +6066,19 @@ void map::draw_lab( mapgendata &dat ) for( int i = 0; i < SEEX * 2; i++ ) { for( int j = 0; j < SEEY * 2; j++ ) { if( i < lw || i > EAST_EDGE - rw || j < tw || j > SOUTH_EDGE - bw ) { - ter_set( point( i, j ), t_concrete_wall ); + ter_set( point( i, j ), ter_t_concrete_wall ); } else { - ter_set( point( i, j ), t_thconc_floor ); + ter_set( point( i, j ), ter_t_thconc_floor ); } } } if( rw == 1 ) { - ter_set( point( EAST_EDGE, SEEY - 1 ), t_door_metal_c ); - ter_set( point( EAST_EDGE, SEEY ), t_door_metal_c ); + ter_set( point( EAST_EDGE, SEEY - 1 ), ter_t_door_metal_c ); + ter_set( point( EAST_EDGE, SEEY ), ter_t_door_metal_c ); } if( bw == 1 ) { - ter_set( point( SEEX - 1, SOUTH_EDGE ), t_door_metal_c ); - ter_set( point( SEEX, SOUTH_EDGE ), t_door_metal_c ); + ter_set( point( SEEX - 1, SOUTH_EDGE ), ter_t_door_metal_c ); + ter_set( point( SEEX, SOUTH_EDGE ), ter_t_door_metal_c ); } int loot_variant; //only used for weapons testing variant. @@ -6063,11 +6101,11 @@ void map::draw_lab( mapgendata &dat ) mtrap_set( this, point( SEEX + 2, SEEY - 3 ), tr_dissector ); mtrap_set( this, point( SEEX - 3, SEEY + 2 ), tr_dissector ); mtrap_set( this, point( SEEX + 2, SEEY + 2 ), tr_dissector ); - line( this, t_reinforced_glass, point( SEEX + 1, SEEY + 1 ), point( SEEX - 2, SEEY + 1 ) ); - line( this, t_reinforced_glass, point( SEEX - 2, SEEY ), point( SEEX - 2, SEEY - 2 ) ); - line( this, t_reinforced_glass, point( SEEX - 1, SEEY - 2 ), point( SEEX + 1, SEEY - 2 ) ); - ter_set( point( SEEX + 1, SEEY - 1 ), t_reinforced_glass ); - ter_set( point( SEEX + 1, SEEY ), t_reinforced_door_glass_c ); + line( this, ter_t_reinforced_glass, point( SEEX + 1, SEEY + 1 ), point( SEEX - 2, SEEY + 1 ) ); + line( this, ter_t_reinforced_glass, point( SEEX - 2, SEEY ), point( SEEX - 2, SEEY - 2 ) ); + line( this, ter_t_reinforced_glass, point( SEEX - 1, SEEY - 2 ), point( SEEX + 1, SEEY - 2 ) ); + ter_set( point( SEEX + 1, SEEY - 1 ), ter_t_reinforced_glass ); + ter_set( point( SEEX + 1, SEEY ), ter_t_reinforced_door_glass_c ); furn_set( point( SEEX - 1, SEEY - 1 ), f_table ); furn_set( point( SEEX, SEEY - 1 ), f_table ); furn_set( point( SEEX - 1, SEEY ), f_table ); @@ -6104,12 +6142,12 @@ void map::draw_lab( mapgendata &dat ) furn_set( point( SEEX - 1, SEEY ), f_rack ); furn_set( point( SEEX, SEEY ), f_rack ); furn_set( point( SEEX + 1, SEEY ), f_rack ); - line( this, t_reinforced_door_glass_c, point( SEEX - 2, SEEY - 2 ), + line( this, ter_t_reinforced_door_glass_c, point( SEEX - 2, SEEY - 2 ), point( SEEX + 1, SEEY - 2 ) ); - line( this, t_reinforced_door_glass_c, point( SEEX - 2, SEEY + 1 ), + line( this, ter_t_reinforced_door_glass_c, point( SEEX - 2, SEEY + 1 ), point( SEEX + 1, SEEY + 1 ) ); - line( this, t_reinforced_glass, point( SEEX - 3, SEEY - 2 ), point( SEEX - 3, SEEY + 1 ) ); - line( this, t_reinforced_glass, point( SEEX + 2, SEEY - 2 ), point( SEEX + 2, SEEY + 1 ) ); + line( this, ter_t_reinforced_glass, point( SEEX - 3, SEEY - 2 ), point( SEEX - 3, SEEY + 1 ) ); + line( this, ter_t_reinforced_glass, point( SEEX + 2, SEEY - 2 ), point( SEEX + 2, SEEY + 1 ) ); place_items( Item_spawn_data_ammo_rare, 96, point( SEEX - 2, SEEY - 1 ), point( SEEX + 1, SEEY - 1 ), false, @@ -6133,12 +6171,12 @@ void map::draw_lab( mapgendata &dat ) for( int j = tw; j <= bw; j++ ) { if( j == tw || j == bw ) { if( ( i - lw ) % 2 == 0 ) { - ter_set( point( i, j ), t_concrete_wall ); + ter_set( point( i, j ), ter_t_concrete_wall ); } else { - ter_set( point( i, j ), t_reinforced_glass ); + ter_set( point( i, j ), ter_t_reinforced_glass ); } } else if( ( i - lw ) % 2 == 0 || j == tw + 2 ) { - ter_set( point( i, j ), t_concrete_wall ); + ter_set( point( i, j ), ter_t_concrete_wall ); } else { // Empty space holds monsters! place_spawns( GROUP_NETHER, 1, point( i, j ), point( i, j ), 1, true ); } @@ -6159,10 +6197,10 @@ void map::draw_lab( mapgendata &dat ) tmpcomp->add_failure( COMPFAIL_SECUBOTS ); tmpcomp->set_access_denied_msg( _( "ERROR! Access denied! Unauthorized access will be met with lethal force!" ) ); - ter_set( point( SEEX - 2, 4 ), t_radio_tower ); - ter_set( point( SEEX + 1, 4 ), t_radio_tower ); - ter_set( point( SEEX - 2, 7 ), t_radio_tower ); - ter_set( point( SEEX + 1, 7 ), t_radio_tower ); + ter_set( point( SEEX - 2, 4 ), ter_t_radio_tower ); + ter_set( point( SEEX + 1, 4 ), ter_t_radio_tower ); + ter_set( point( SEEX - 2, 7 ), ter_t_radio_tower ); + ter_set( point( SEEX + 1, 7 ), ter_t_radio_tower ); } break; @@ -6187,10 +6225,10 @@ void map::draw_lab( mapgendata &dat ) Item_spawn_data_bionics, 75, point( SEEX - 1, SEEY - 1 ), point( SEEX, SEEY ), false, calendar::start_of_cataclysm ).size(); } - line( this, t_reinforced_glass, point( SEEX - 2, SEEY - 2 ), point( SEEX + 1, SEEY - 2 ) ); - line( this, t_reinforced_glass, point( SEEX - 2, SEEY + 1 ), point( SEEX + 1, SEEY + 1 ) ); - line( this, t_reinforced_glass, point( SEEX - 2, SEEY - 1 ), point( SEEX - 2, SEEY ) ); - line( this, t_reinforced_glass, point( SEEX + 1, SEEY - 1 ), point( SEEX + 1, SEEY ) ); + line( this, ter_t_reinforced_glass, point( SEEX - 2, SEEY - 2 ), point( SEEX + 1, SEEY - 2 ) ); + line( this, ter_t_reinforced_glass, point( SEEX - 2, SEEY + 1 ), point( SEEX + 1, SEEY + 1 ) ); + line( this, ter_t_reinforced_glass, point( SEEX - 2, SEEY - 1 ), point( SEEX - 2, SEEY ) ); + line( this, ter_t_reinforced_glass, point( SEEX + 1, SEEY - 1 ), point( SEEX + 1, SEEY ) ); spawn_item( point( SEEX - 4, SEEY - 3 ), "id_science" ); furn_set( point( SEEX - 3, SEEY - 3 ), furn_f_console ); tmpcomp = add_computer( tripoint( SEEX - 3, SEEY - 3, abs_sub.z() ), @@ -6213,11 +6251,11 @@ void map::draw_lab( mapgendata &dat ) point( 6, SEEY * 2 - 7 ), 1, true ); place_spawns( GROUP_ROBOT_SECUBOT, 1, point( SEEX * 2 - 7, SEEY * 2 - 7 ), point( SEEX * 2 - 7, SEEY * 2 - 7 ), 1, true ); - line( this, t_cvdbody, point( SEEX - 2, SEEY - 2 ), point( SEEX - 2, SEEY + 1 ) ); - line( this, t_cvdbody, point( SEEX - 1, SEEY - 2 ), point( SEEX - 1, SEEY + 1 ) ); - line( this, t_cvdbody, point( SEEX, SEEY - 1 ), point( SEEX, SEEY + 1 ) ); - line( this, t_cvdbody, point( SEEX + 1, SEEY - 2 ), point( SEEX + 1, SEEY + 1 ) ); - ter_set( point( SEEX, SEEY - 2 ), t_cvdmachine ); + line( this, ter_t_cvdbody, point( SEEX - 2, SEEY - 2 ), point( SEEX - 2, SEEY + 1 ) ); + line( this, ter_t_cvdbody, point( SEEX - 1, SEEY - 2 ), point( SEEX - 1, SEEY + 1 ) ); + line( this, ter_t_cvdbody, point( SEEX, SEEY - 1 ), point( SEEX, SEEY + 1 ) ); + line( this, ter_t_cvdbody, point( SEEX + 1, SEEY - 2 ), point( SEEX + 1, SEEY + 1 ) ); + ter_set( point( SEEX, SEEY - 2 ), ter_t_cvdmachine ); spawn_item( point( SEEX, SEEY - 3 ), "id_science" ); break; } @@ -6225,10 +6263,11 @@ void map::draw_lab( mapgendata &dat ) // Handle stairs in the unlikely case they are needed. - const auto maybe_insert_stairs = [this]( const oter_id & terrain, const ter_id & t_stair_type ) { + const auto maybe_insert_stairs = [this]( const oter_id & terrain, + const ter_str_id & t_stair_type ) { if( is_ot_match( "stairs", terrain, ot_match_type::contains ) ) { const auto predicate = [this]( const tripoint & p ) { - return ter( p ) == t_thconc_floor && furn( p ) == f_null && + return ter( p ) == ter_t_thconc_floor && furn( p ) == f_null && tr_at( p ).is_null(); }; const auto range = points_in_rectangle( { 0, 0, abs_sub.z() }, @@ -6238,8 +6277,8 @@ void map::draw_lab( mapgendata &dat ) } } }; - maybe_insert_stairs( dat.above(), t_stairs_up ); - maybe_insert_stairs( terrain_type, t_stairs_down ); + maybe_insert_stairs( dat.above(), ter_t_stairs_up ); + maybe_insert_stairs( terrain_type, ter_t_stairs_down ); int light_odds = 0; // central labs are always fully lit, other labs have half chance of some lights. @@ -6252,8 +6291,9 @@ void map::draw_lab( mapgendata &dat ) for( int i = 0; i < SEEX * 2; i++ ) { for( int j = 0; j < SEEY * 2; j++ ) { if( !( ( i * j ) % 2 || ( i + j ) % 4 ) && one_in( light_odds ) ) { - if( t_thconc_floor == ter( point( i, j ) ) || t_strconc_floor == ter( point( i, j ) ) ) { - ter_set( point( i, j ), t_thconc_floor_olight ); + const ter_id &nearby_ter = ter( point( i, j ) ); + if( nearby_ter == ter_t_thconc_floor || nearby_ter == ter_t_strconc_floor ) { + ter_set( point( i, j ), ter_t_thconc_floor_olight ); } } } @@ -6272,36 +6312,36 @@ void map::draw_slimepit( const mapgendata &dat ) i < dat.w_fac * SEEX || j > SEEY * 2 - dat.s_fac * SEEY || i > SEEX * 2 - dat.e_fac * SEEX ) ) { - ter_set( point( i, j ), ( !one_in( 10 ) ? t_slime : t_rock_floor ) ); + ter_set( point( i, j ), ( !one_in( 10 ) ? ter_t_slime : ter_t_rock_floor ) ); } else if( rng( 0, SEEX ) > std::abs( i - SEEX ) && rng( 0, SEEY ) > std::abs( j - SEEY ) ) { - ter_set( point( i, j ), t_slime ); + ter_set( point( i, j ), ter_t_slime ); } else if( dat.zlevel() == 0 ) { - ter_set( point( i, j ), t_dirt ); + ter_set( point( i, j ), ter_t_dirt ); } else { - ter_set( point( i, j ), t_rock_floor ); + ter_set( point( i, j ), ter_t_rock_floor ); } } } if( terrain_type == oter_slimepit_down ) { - ter_set( point( rng( 3, SEEX * 2 - 4 ), rng( 3, SEEY * 2 - 4 ) ), t_slope_down ); + ter_set( point( rng( 3, SEEX * 2 - 4 ), rng( 3, SEEY * 2 - 4 ) ), ter_t_slope_down ); } if( dat.above() == oter_slimepit_down ) { switch( rng( 1, 4 ) ) { case 1: - ter_set( point( rng( 0, 2 ), rng( 0, 2 ) ), t_slope_up ); + ter_set( point( rng( 0, 2 ), rng( 0, 2 ) ), ter_t_slope_up ); break; case 2: - ter_set( point( rng( 0, 2 ), SEEY * 2 - rng( 1, 3 ) ), t_slope_up ); + ter_set( point( rng( 0, 2 ), SEEY * 2 - rng( 1, 3 ) ), ter_t_slope_up ); break; case 3: - ter_set( point( SEEX * 2 - rng( 1, 3 ), rng( 0, 2 ) ), t_slope_up ); + ter_set( point( SEEX * 2 - rng( 1, 3 ), rng( 0, 2 ) ), ter_t_slope_up ); break; case 4: - ter_set( point( SEEX * 2 - rng( 1, 3 ), SEEY * 2 - rng( 1, 3 ) ), t_slope_up ); + ter_set( point( SEEX * 2 - rng( 1, 3 ), SEEY * 2 - rng( 1, 3 ) ), ter_t_slope_up ); } } else if( dat.above() == oter_slimepit_bottom ) { // Align the stairs - ter_set( point( 7, 9 ), t_slope_up ); + ter_set( point( 7, 9 ), ter_t_slope_up ); } place_spawns( GROUP_SLIME, 1, point( SEEX, SEEY ), point( SEEX, SEEY ), 0.15 ); place_items( Item_spawn_data_sewer, 40, point_zero, point( EAST_EDGE, SOUTH_EDGE ), true, @@ -7074,7 +7114,7 @@ void science_room( map *m, const point &p1, const point &p2, int z, int rotate ) } for( int i = p1.x; i <= p2.x; i++ ) { for( int j = p1.y; j <= p2.y; j++ ) { - m->ter_set( point( i, j ), t_thconc_floor ); + m->ter_set( point( i, j ), ter_t_thconc_floor ); } } int area = height * width; @@ -7235,7 +7275,7 @@ void science_room( map *m, const point &p1, const point &p2, int z, int rotate ) for( int x = p1.x + 1; x <= p2.x - 1; x++ ) { for( int y = p1.y + 1; y <= p2.y - 1; y++ ) { if( x % 3 == 0 && y % 3 == 0 ) { - m->ter_set( point( x, y ), t_vat ); + m->ter_set( point( x, y ), ter_t_vat ); m->place_items( Item_spawn_data_cloning_vat, 20, point( x, y ), point( x, y ), false, calendar::start_of_cataclysm ); } @@ -7284,7 +7324,7 @@ void science_room( map *m, const point &p1, const point &p2, int z, int rotate ) "---\n" "|c|\n" "-=-\n", - mapf::ter_bind( "- | =", t_concrete_wall, t_concrete_wall, t_reinforced_glass ), + mapf::ter_bind( "- | =", ter_t_concrete_wall, ter_t_concrete_wall, ter_t_reinforced_glass ), mapf::furn_bind( "c", f_counter ) ); m->place_items( Item_spawn_data_bionics_common, 70, bio, bio, false, calendar::start_of_cataclysm ); @@ -7303,7 +7343,7 @@ void science_room( map *m, const point &p1, const point &p2, int z, int rotate ) "-=-\n" "|c|\n" "---\n", - mapf::ter_bind( "- | =", t_concrete_wall, t_concrete_wall, t_reinforced_glass ), + mapf::ter_bind( "- | =", ter_t_concrete_wall, ter_t_concrete_wall, ter_t_reinforced_glass ), mapf::furn_bind( "c", f_counter ) ); m->place_items( Item_spawn_data_bionics_common, 70, bio, bio, false, calendar::start_of_cataclysm ); @@ -7323,7 +7363,7 @@ void science_room( map *m, const point &p1, const point &p2, int z, int rotate ) "|-|\n" "|c=\n" "|-|\n", - mapf::ter_bind( "- | =", t_concrete_wall, t_concrete_wall, t_reinforced_glass ), + mapf::ter_bind( "- | =", ter_t_concrete_wall, ter_t_concrete_wall, ter_t_reinforced_glass ), mapf::furn_bind( "c", f_counter ) ); m->place_items( Item_spawn_data_bionics_common, 70, point( biox, bioy ), point( biox, bioy ), false, calendar::start_of_cataclysm ); @@ -7342,7 +7382,7 @@ void science_room( map *m, const point &p1, const point &p2, int z, int rotate ) "|-|\n" "=c|\n" "|-|\n", - mapf::ter_bind( "- | =", t_concrete_wall, t_concrete_wall, t_reinforced_glass ), + mapf::ter_bind( "- | =", ter_t_concrete_wall, ter_t_concrete_wall, ter_t_reinforced_glass ), mapf::furn_bind( "c", f_counter ) ); m->place_items( Item_spawn_data_bionics_common, 70, point( biox, bioy ), point( biox, bioy ), false, calendar::turn_zero ); @@ -7409,22 +7449,22 @@ void science_room( map *m, const point &p1, const point &p2, int z, int rotate ) int w1 = static_cast( ( p1.x + p2.x ) / 2 ) - 2; int w2 = static_cast( ( p1.x + p2.x ) / 2 ) + 2; for( int y = p1.y; y <= p2.y; y++ ) { - m->ter_set( point( w1, y ), t_concrete_wall ); - m->ter_set( point( w2, y ), t_concrete_wall ); + m->ter_set( point( w1, y ), ter_t_concrete_wall ); + m->ter_set( point( w2, y ), ter_t_concrete_wall ); } - m->ter_set( point( w1, static_cast( ( p1.y + p2.y ) / 2 ) ), t_door_glass_frosted_c ); - m->ter_set( point( w2, static_cast( ( p1.y + p2.y ) / 2 ) ), t_door_glass_frosted_c ); + m->ter_set( point( w1, static_cast( ( p1.y + p2.y ) / 2 ) ), ter_t_door_glass_frosted_c ); + m->ter_set( point( w2, static_cast( ( p1.y + p2.y ) / 2 ) ), ter_t_door_glass_frosted_c ); science_room( m, p1, point( w1 - 1, p2.y ), z, 1 ); science_room( m, point( w2 + 1, p1.y ), p2, z, 3 ); } else { int w1 = static_cast( ( p1.y + p2.y ) / 2 ) - 2; int w2 = static_cast( ( p1.y + p2.y ) / 2 ) + 2; for( int x = p1.x; x <= p2.x; x++ ) { - m->ter_set( point( x, w1 ), t_concrete_wall ); - m->ter_set( point( x, w2 ), t_concrete_wall ); + m->ter_set( point( x, w1 ), ter_t_concrete_wall ); + m->ter_set( point( x, w2 ), ter_t_concrete_wall ); } - m->ter_set( point( ( p1.x + p2.x ) / 2, w1 ), t_door_glass_frosted_c ); - m->ter_set( point( ( p1.x + p2.x ) / 2, w2 ), t_door_glass_frosted_c ); + m->ter_set( point( ( p1.x + p2.x ) / 2, w1 ), ter_t_door_glass_frosted_c ); + m->ter_set( point( ( p1.x + p2.x ) / 2, w2 ), ter_t_door_glass_frosted_c ); science_room( m, p1, point( p2.x, w1 - 1 ), z, 2 ); science_room( m, point( p1.x, w2 + 1 ), p2, z, 0 ); } @@ -7439,7 +7479,7 @@ void map::create_anomaly( const tripoint &cp, artifact_natural_property prop, bo // TODO: Z point c( cp.xy() ); if( create_rubble ) { - rough_circle( this, t_dirt, c, 11 ); + rough_circle( this, ter_t_dirt, c, 11 ); rough_circle_furn( this, f_rubble, c, 5 ); furn_set( c, f_null ); } @@ -7688,27 +7728,36 @@ bool update_mapgen_function_json::update_map( return false; } - std::unique_ptr p_update_tmap = std::make_unique(); - tinymap &update_tmap = *p_update_tmap; + std::unique_ptr p_update_smap = std::make_unique(); + smallmap &update_smap = *p_update_smap; - update_tmap.load( omt_pos, true ); - update_tmap.rotate( 4 - rotation ); - update_tmap.mirror( mirror_horizontal, mirror_vertical ); + update_smap.load( omt_pos, true ); + update_smap.rotate( 4 - rotation ); + update_smap.mirror( mirror_horizontal, mirror_vertical ); - mapgendata md_base( omt_pos, *update_tmap.cast_to_map(), 0.0f, calendar::start_of_cataclysm, miss ); + mapgendata md_base( omt_pos, *update_smap.cast_to_map(), 0.0f, calendar::start_of_cataclysm, miss ); mapgendata md( md_base, args ); bool const u = update_map( md, offset, verify ); - update_tmap.mirror( mirror_horizontal, mirror_vertical ); - update_tmap.rotate( rotation ); + update_smap.mirror( mirror_horizontal, mirror_vertical ); + update_smap.rotate( rotation ); if( get_map().inbounds( project_to( omt_pos ) ) ) { // trigger main map cleanup - p_update_tmap.reset(); + p_update_smap.reset(); // trigger new traps, etc g->place_player( get_avatar().pos(), true ); } + // Trigger magic to add roofs (within load) if needed. + if( omt_pos.z() < OVERMAP_HEIGHT ) { + std::unique_ptr p_roof_smap = std::make_unique(); + smallmap &roof_smap = *p_roof_smap; + // The loading of the Z level above is not necessary, but looks better. + const tripoint_abs_omt omt_above = { omt_pos.x(), omt_pos.y(), omt_pos.z() + 1 }; + roof_smap.load( omt_above, false ); + } + return u; } @@ -7820,7 +7869,7 @@ bool apply_construction_marker( const update_mapgen_id &update_mapgen_id, return false; } - fake_map tmp_map( t_grass ); + fake_map tmp_map( ter_t_grass ); mapgendata base_fake_md( *tmp_map.cast_to_map(), mapgendata::dummy_settings ); mapgendata fake_md( base_fake_md, args ); @@ -7846,10 +7895,8 @@ bool apply_construction_marker( const update_mapgen_id &update_mapgen_id, if( update_function->second.funcs()[0]->update_map( fake_md ) ) { for( const tripoint &pos : tmp_map.points_on_zlevel( fake_map::fake_map_z ) ) { - ter_id ter_at_pos = tmp_map.ter( pos ); const tripoint level_pos = tripoint( pos.xy(), omt_pos.z() ); - - if( ter_at_pos != t_grass || tmp_map.has_furn( level_pos ) ) { + if( tmp_map.ter( pos ) != ter_t_grass || tmp_map.has_furn( level_pos ) ) { if( apply ) { update_tmap.add_field( level_pos, fd_construction_site, 1, time_duration::from_turns( 0 ), false ); } else { diff --git a/src/mapgen_functions.cpp b/src/mapgen_functions.cpp index fad9837baf020..c00cdf9830f7b 100644 --- a/src/mapgen_functions.cpp +++ b/src/mapgen_functions.cpp @@ -52,6 +52,30 @@ static const oter_str_id oter_river_west( "river_west" ); static const oter_str_id oter_slimepit( "slimepit" ); static const oter_str_id oter_slimepit_down( "slimepit_down" ); +static const ter_str_id ter_t_buffer_stop( "t_buffer_stop" ); +static const ter_str_id ter_t_clay( "t_clay" ); +static const ter_str_id ter_t_dirt( "t_dirt" ); +static const ter_str_id ter_t_grass( "t_grass" ); +static const ter_str_id ter_t_lava( "t_lava" ); +static const ter_str_id ter_t_open_air( "t_open_air" ); +static const ter_str_id ter_t_railroad_rubble( "t_railroad_rubble" ); +static const ter_str_id ter_t_railroad_tie( "t_railroad_tie" ); +static const ter_str_id ter_t_railroad_tie_d( "t_railroad_tie_d" ); +static const ter_str_id ter_t_railroad_track( "t_railroad_track" ); +static const ter_str_id ter_t_railroad_track_d( "t_railroad_track_d" ); +static const ter_str_id ter_t_railroad_track_on_tie( "t_railroad_track_on_tie" ); +static const ter_str_id ter_t_rock( "t_rock" ); +static const ter_str_id ter_t_rock_floor( "t_rock_floor" ); +static const ter_str_id ter_t_sand( "t_sand" ); +static const ter_str_id ter_t_slope_down( "t_slope_down" ); +static const ter_str_id ter_t_swater_dp( "t_swater_dp" ); +static const ter_str_id ter_t_swater_sh( "t_swater_sh" ); +static const ter_str_id ter_t_swater_surf( "t_swater_surf" ); +static const ter_str_id ter_t_water_dp( "t_water_dp" ); +static const ter_str_id ter_t_water_moving_dp( "t_water_moving_dp" ); +static const ter_str_id ter_t_water_moving_sh( "t_water_moving_sh" ); +static const ter_str_id ter_t_water_sh( "t_water_sh" ); + static const vspawn_id VehicleSpawn_default_subway_deadend( "default_subway_deadend" ); class npc_template; @@ -121,20 +145,20 @@ building_gen_pointer get_mapgen_cfunction( const std::string &ident ) return iter == pointers.end() ? nullptr : iter->second; } -ter_id grass_or_dirt() +ter_str_id grass_or_dirt() { if( one_in( 4 ) ) { - return t_grass; + return ter_t_grass; } - return t_dirt; + return ter_t_dirt; } -ter_id clay_or_sand() +ter_str_id clay_or_sand() { if( one_in( 16 ) ) { - return t_sand; + return ter_t_sand; } - return t_clay; + return ter_t_clay; } ///////////////////////////////////////////////////////////////////////////////////////////////// @@ -146,7 +170,7 @@ void mapgen_null( mapgendata &dat ) debugmsg( "Generating null terrain, please report this as a bug" ); for( int i = 0; i < SEEX * 2; i++ ) { for( int j = 0; j < SEEY * 2; j++ ) { - dat.m.ter_set( point( i, j ), t_null ); + dat.m.ter_set( point( i, j ), ter_str_id::NULL_ID() ); dat.m.set_radiation( point( i, j ), 0 ); } } @@ -361,12 +385,12 @@ void mapgen_subway( mapgendata &dat ) ".^/DX^/DX......XD/^XD/^.\n" "..^/D^^/D^....^D/^^D/^..", mapf::ter_bind( ". # ^ / D X", - t_rock_floor, - t_rock, - t_railroad_rubble, - t_railroad_tie_d, - t_railroad_track_d, - t_railroad_track ), + ter_t_rock_floor, + ter_t_rock, + ter_t_railroad_rubble, + ter_t_railroad_tie_d, + ter_t_railroad_track_d, + ter_t_railroad_track ), mapf::furn_bind( ". # ^ / D X", f_null, f_null, @@ -403,14 +427,14 @@ void mapgen_subway( mapgendata &dat ) "........................\n" "........................", mapf::ter_bind( ". # ^ | X x / D", - t_rock_floor, - t_rock, - t_railroad_rubble, - t_railroad_tie, - t_railroad_track, - t_railroad_track_on_tie, - t_railroad_tie_d, - t_railroad_track_d ), + ter_t_rock_floor, + ter_t_rock, + ter_t_railroad_rubble, + ter_t_railroad_tie, + ter_t_railroad_track, + ter_t_railroad_track_on_tie, + ter_t_railroad_tie_d, + ter_t_railroad_track_d ), mapf::furn_bind( ". # ^ | X x / D", f_null, f_null, @@ -450,10 +474,10 @@ void mapgen_subway( mapgendata &dat ) "##################......\n" "###################.....", mapf::ter_bind( ". # ^ D", - t_rock_floor, - t_rock, - t_railroad_rubble, - t_railroad_track_d ), + ter_t_rock_floor, + ter_t_rock, + ter_t_railroad_rubble, + ter_t_railroad_track_d ), mapf::furn_bind( ". # ^ D", f_null, f_null, @@ -486,12 +510,12 @@ void mapgen_subway( mapgendata &dat ) "...-x---x-....-x---x-...\n" "...^X^^^X^....^X^^^X^...", mapf::ter_bind( ". # ^ - X x", - t_rock_floor, - t_rock, - t_railroad_rubble, - t_railroad_tie, - t_railroad_track, - t_railroad_track_on_tie ), + ter_t_rock_floor, + ter_t_rock, + ter_t_railroad_rubble, + ter_t_railroad_tie, + ter_t_railroad_track, + ter_t_railroad_track_on_tie ), mapf::furn_bind( ". # ^ - X x", f_null, f_null, @@ -529,15 +553,15 @@ void mapgen_subway( mapgendata &dat ) "##....................##\n" "########################", mapf::ter_bind( ". # S ^ - / D X x", - t_rock_floor, - t_rock, - t_buffer_stop, - t_railroad_rubble, - t_railroad_tie, - t_railroad_tie_d, - t_railroad_track_d, - t_railroad_track, - t_railroad_track_on_tie ), + ter_t_rock_floor, + ter_t_rock, + ter_t_buffer_stop, + ter_t_railroad_rubble, + ter_t_railroad_tie, + ter_t_railroad_tie_d, + ter_t_railroad_track_d, + ter_t_railroad_track, + ter_t_railroad_track_on_tie ), mapf::furn_bind( ". # S ^ - / D X x", f_null, f_null, @@ -558,13 +582,13 @@ void mapgen_subway( mapgendata &dat ) void mapgen_river_center( mapgendata &dat ) { - fill_background( &dat.m, t_water_moving_dp ); + fill_background( &dat.m, ter_t_water_moving_dp ); } void mapgen_river_curved_not( mapgendata &dat ) { map *const m = &dat.m; - fill_background( m, t_water_moving_dp ); + fill_background( m, ter_t_water_moving_dp ); // this is not_ne, so deep on all sides except ne corner, which is shallow // shallow is 20,0, 23,4 int north_edge = rng( 16, 18 ); @@ -579,7 +603,7 @@ void mapgen_river_curved_not( mapgendata &dat ) if( circle_edge == 9 && one_in( 25 ) ) { m->ter_set( point( x, y ), clay_or_sand() ); } else if( circle_edge <= 36 ) { - m->ter_set( point( x, y ), t_water_moving_sh ); + m->ter_set( point( x, y ), ter_t_water_moving_sh ); } } } @@ -598,7 +622,7 @@ void mapgen_river_curved_not( mapgendata &dat ) void mapgen_river_straight( mapgendata &dat ) { map *const m = &dat.m; - fill_background( m, t_water_moving_dp ); + fill_background( m, ter_t_water_moving_dp ); for( int x = 0; x < SEEX * 2; x++ ) { int ground_edge = rng( 1, 3 ); @@ -607,7 +631,7 @@ void mapgen_river_straight( mapgendata &dat ) if( one_in( 25 ) ) { m->ter_set( point( x, ++ground_edge ), clay_or_sand() ); } - line( m, t_water_moving_sh, point( x, ++ground_edge ), point( x, shallow_edge ) ); + line( m, ter_t_water_moving_sh, point( x, ++ground_edge ), point( x, shallow_edge ) ); } if( dat.terrain_type() == oter_river_east ) { @@ -624,7 +648,7 @@ void mapgen_river_straight( mapgendata &dat ) void mapgen_river_curved( mapgendata &dat ) { map *const m = &dat.m; - fill_background( m, t_water_moving_dp ); + fill_background( m, ter_t_water_moving_dp ); // NE corner deep, other corners are shallow. do 2 passes: one x, one y for( int x = 0; x < SEEX * 2; x++ ) { int ground_edge = rng( 1, 3 ); @@ -633,7 +657,7 @@ void mapgen_river_curved( mapgendata &dat ) if( one_in( 25 ) ) { m->ter_set( point( x, ++ground_edge ), clay_or_sand() ); } - line( m, t_water_moving_sh, point( x, ++ground_edge ), point( x, shallow_edge ) ); + line( m, ter_t_water_moving_sh, point( x, ++ground_edge ), point( x, shallow_edge ) ); } for( int y = 0; y < SEEY * 2; y++ ) { int ground_edge = rng( 19, 21 ); @@ -642,7 +666,7 @@ void mapgen_river_curved( mapgendata &dat ) if( one_in( 25 ) ) { m->ter_set( point( --ground_edge, y ), clay_or_sand() ); } - line( m, t_water_moving_sh, point( shallow_edge, y ), point( --ground_edge, y ) ); + line( m, ter_t_water_moving_sh, point( shallow_edge, y ), point( --ground_edge, y ) ); } if( dat.terrain_type() == oter_river_se ) { @@ -659,7 +683,7 @@ void mapgen_river_curved( mapgendata &dat ) void mapgen_rock_partial( mapgendata &dat ) { map *const m = &dat.m; - fill_background( m, t_rock ); + fill_background( m, ter_t_rock ); for( int i = 0; i < 4; i++ ) { if( dat.t_nesw[i] == oter_slimepit || dat.t_nesw[i] == oter_slimepit_down ) { dat.dir( i ) = 6; @@ -672,7 +696,7 @@ void mapgen_rock_partial( mapgendata &dat ) for( int j = 0; j < SEEY * 2; j++ ) { if( rng( 0, dat.n_fac ) > j || rng( 0, dat.s_fac ) > SEEY * 2 - 1 - j || rng( 0, dat.w_fac ) > i || rng( 0, dat.e_fac ) > SEEX * 2 - 1 - i ) { - m->ter_set( point( i, j ), t_rock_floor ); + m->ter_set( point( i, j ), ter_t_rock_floor ); } } } @@ -680,12 +704,12 @@ void mapgen_rock_partial( mapgendata &dat ) void mapgen_rock( mapgendata &dat ) { - fill_background( &dat.m, t_rock ); + fill_background( &dat.m, ter_t_rock ); } void mapgen_open_air( mapgendata &dat ) { - fill_background( &dat.m, t_open_air ); + fill_background( &dat.m, ter_t_open_air ); } void mapgen_rift( mapgendata &dat ) @@ -727,12 +751,12 @@ void mapgen_rift( mapgendata &dat ) for( int j = 0; j < SEEY * 2; j++ ) { if( ( dat.n_fac < 0 && j < dat.n_fac * -1 ) || ( dat.s_fac < 0 && j >= SEEY * 2 - dat.s_fac ) || ( dat.w_fac < 0 && i < dat.w_fac * -1 ) || ( dat.e_fac < 0 && i >= SEEX * 2 - dat.e_fac ) ) { - m->ter_set( point( i, j ), t_rock_floor ); + m->ter_set( point( i, j ), ter_t_rock_floor ); } else if( j < dat.n_fac || j >= SEEY * 2 - dat.s_fac || i < dat.w_fac || i >= SEEX * 2 - dat.e_fac ) { - m->ter_set( point( i, j ), t_rock ); + m->ter_set( point( i, j ), ter_t_rock ); } else { - m->ter_set( point( i, j ), t_lava ); + m->ter_set( point( i, j ), ter_t_lava ); } } } @@ -754,90 +778,90 @@ void mapgen_hellmouth( mapgendata &dat ) for( int j = 0; j < SEEY * 2; j++ ) { if( j < dat.n_fac || j >= SEEY * 2 - dat.s_fac || i < dat.w_fac || i >= SEEX * 2 - dat.e_fac || ( i >= 6 && i < SEEX * 2 - 6 && j >= 6 && j < SEEY * 2 - 6 ) ) { - m->ter_set( point( i, j ), t_rock_floor ); + m->ter_set( point( i, j ), ter_t_rock_floor ); } else { - m->ter_set( point( i, j ), t_lava ); + m->ter_set( point( i, j ), ter_t_lava ); } if( i >= SEEX - 1 && i <= SEEX && j >= SEEY - 1 && j <= SEEY ) { - m->ter_set( point( i, j ), t_slope_down ); + m->ter_set( point( i, j ), ter_t_slope_down ); } } } switch( rng( 0, 4 ) ) { // Randomly chosen "altar" design case 0: for( int i = 7; i <= 16; i += 3 ) { - m->ter_set( point( i, 6 ), t_rock ); - m->ter_set( point( i, 17 ), t_rock ); - m->ter_set( point( 6, i ), t_rock ); - m->ter_set( point( 17, i ), t_rock ); + m->ter_set( point( i, 6 ), ter_t_rock ); + m->ter_set( point( i, 17 ), ter_t_rock ); + m->ter_set( point( 6, i ), ter_t_rock ); + m->ter_set( point( 17, i ), ter_t_rock ); if( i > 7 && i < 16 ) { - m->ter_set( point( i, 10 ), t_rock ); - m->ter_set( point( i, 13 ), t_rock ); + m->ter_set( point( i, 10 ), ter_t_rock ); + m->ter_set( point( i, 13 ), ter_t_rock ); } else { - m->ter_set( point( i - 1, 6 ), t_rock ); - m->ter_set( point( i - 1, 10 ), t_rock ); - m->ter_set( point( i - 1, 13 ), t_rock ); - m->ter_set( point( i - 1, 17 ), t_rock ); + m->ter_set( point( i - 1, 6 ), ter_t_rock ); + m->ter_set( point( i - 1, 10 ), ter_t_rock ); + m->ter_set( point( i - 1, 13 ), ter_t_rock ); + m->ter_set( point( i - 1, 17 ), ter_t_rock ); } } break; case 1: for( int i = 6; i < 11; i++ ) { - m->ter_set( point( i, i ), t_lava ); - m->ter_set( point( SEEX * 2 - 1 - i, i ), t_lava ); - m->ter_set( point( i, SEEY * 2 - 1 - i ), t_lava ); - m->ter_set( point( SEEX * 2 - 1 - i, SEEY * 2 - 1 - i ), t_lava ); + m->ter_set( point( i, i ), ter_t_lava ); + m->ter_set( point( SEEX * 2 - 1 - i, i ), ter_t_lava ); + m->ter_set( point( i, SEEY * 2 - 1 - i ), ter_t_lava ); + m->ter_set( point( SEEX * 2 - 1 - i, SEEY * 2 - 1 - i ), ter_t_lava ); if( i < 10 ) { - m->ter_set( point( i + 1, i ), t_lava ); - m->ter_set( point( SEEX * 2 - i, i ), t_lava ); - m->ter_set( point( i + 1, SEEY * 2 - 1 - i ), t_lava ); - m->ter_set( point( SEEX * 2 - i, SEEY * 2 - 1 - i ), t_lava ); - - m->ter_set( point( i, i + 1 ), t_lava ); - m->ter_set( point( SEEX * 2 - 1 - i, i + 1 ), t_lava ); - m->ter_set( point( i, SEEY * 2 - i ), t_lava ); - m->ter_set( point( SEEX * 2 - 1 - i, SEEY * 2 - i ), t_lava ); + m->ter_set( point( i + 1, i ), ter_t_lava ); + m->ter_set( point( SEEX * 2 - i, i ), ter_t_lava ); + m->ter_set( point( i + 1, SEEY * 2 - 1 - i ), ter_t_lava ); + m->ter_set( point( SEEX * 2 - i, SEEY * 2 - 1 - i ), ter_t_lava ); + + m->ter_set( point( i, i + 1 ), ter_t_lava ); + m->ter_set( point( SEEX * 2 - 1 - i, i + 1 ), ter_t_lava ); + m->ter_set( point( i, SEEY * 2 - i ), ter_t_lava ); + m->ter_set( point( SEEX * 2 - 1 - i, SEEY * 2 - i ), ter_t_lava ); } if( i < 9 ) { - m->ter_set( point( i + 2, i ), t_rock ); - m->ter_set( point( SEEX * 2 - i + 1, i ), t_rock ); - m->ter_set( point( i + 2, SEEY * 2 - 1 - i ), t_rock ); - m->ter_set( point( SEEX * 2 - i + 1, SEEY * 2 - 1 - i ), t_rock ); - - m->ter_set( point( i, i + 2 ), t_rock ); - m->ter_set( point( SEEX * 2 - 1 - i, i + 2 ), t_rock ); - m->ter_set( point( i, SEEY * 2 - i + 1 ), t_rock ); - m->ter_set( point( SEEX * 2 - 1 - i, SEEY * 2 - i + 1 ), t_rock ); + m->ter_set( point( i + 2, i ), ter_t_rock ); + m->ter_set( point( SEEX * 2 - i + 1, i ), ter_t_rock ); + m->ter_set( point( i + 2, SEEY * 2 - 1 - i ), ter_t_rock ); + m->ter_set( point( SEEX * 2 - i + 1, SEEY * 2 - 1 - i ), ter_t_rock ); + + m->ter_set( point( i, i + 2 ), ter_t_rock ); + m->ter_set( point( SEEX * 2 - 1 - i, i + 2 ), ter_t_rock ); + m->ter_set( point( i, SEEY * 2 - i + 1 ), ter_t_rock ); + m->ter_set( point( SEEX * 2 - 1 - i, SEEY * 2 - i + 1 ), ter_t_rock ); } } break; case 2: for( int i = 7; i < 17; i++ ) { - m->ter_set( point( i, 6 ), t_rock ); - m->ter_set( point( 6, i ), t_rock ); - m->ter_set( point( i, 17 ), t_rock ); - m->ter_set( point( 17, i ), t_rock ); + m->ter_set( point( i, 6 ), ter_t_rock ); + m->ter_set( point( 6, i ), ter_t_rock ); + m->ter_set( point( i, 17 ), ter_t_rock ); + m->ter_set( point( 17, i ), ter_t_rock ); if( i != 7 && i != 16 && i != 11 && i != 12 ) { - m->ter_set( point( i, 8 ), t_rock ); - m->ter_set( point( 8, i ), t_rock ); - m->ter_set( point( i, 15 ), t_rock ); - m->ter_set( point( 15, i ), t_rock ); + m->ter_set( point( i, 8 ), ter_t_rock ); + m->ter_set( point( 8, i ), ter_t_rock ); + m->ter_set( point( i, 15 ), ter_t_rock ); + m->ter_set( point( 15, i ), ter_t_rock ); } if( i == 11 || i == 12 ) { - m->ter_set( point( i, 10 ), t_rock ); - m->ter_set( point( 10, i ), t_rock ); - m->ter_set( point( i, 13 ), t_rock ); - m->ter_set( point( 13, i ), t_rock ); + m->ter_set( point( i, 10 ), ter_t_rock ); + m->ter_set( point( 10, i ), ter_t_rock ); + m->ter_set( point( i, 13 ), ter_t_rock ); + m->ter_set( point( 13, i ), ter_t_rock ); } } break; case 3: for( int i = 6; i < 11; i++ ) { for( int j = 6; j < 11; j++ ) { - m->ter_set( point( i, j ), t_lava ); - m->ter_set( point( SEEX * 2 - 1 - i, j ), t_lava ); - m->ter_set( point( i, SEEY * 2 - 1 - j ), t_lava ); - m->ter_set( point( SEEX * 2 - 1 - i, SEEY * 2 - 1 - j ), t_lava ); + m->ter_set( point( i, j ), ter_t_lava ); + m->ter_set( point( SEEX * 2 - 1 - i, j ), ter_t_lava ); + m->ter_set( point( i, SEEY * 2 - 1 - j ), ter_t_lava ); + m->ter_set( point( SEEX * 2 - 1 - i, SEEY * 2 - 1 - j ), ter_t_lava ); } } break; @@ -873,10 +897,7 @@ void mapgen_forest( mapgendata &dat ) // being placed by the relative density of the current terrain to its // neighbors. For example, a forest_thick surrounded by forest_thick on // all sides can be much more dense than a forest_water surrounded by - // fields on all sides. The properties of this density and blending would - // do well to be encoded in JSON for the regional and biome settings, but - // for now use the general hardcoded pattern from previous generations of the - // algorithm. + // fields on all sides. // "Sparsity Factor" is a misnomer carried over from JSON; the value reflects // the density of the terrain, not the sparsity. @@ -894,7 +915,7 @@ void mapgen_forest( mapgendata &dat ) * @return A discrete scale of the density of natural features occurring in \p ot. */ const auto get_sparseness_adjacency_factor = [&dat]( const oter_id & ot ) { - const auto biome = dat.region.forest_composition.biomes.find( ot ); + const auto biome = dat.region.forest_composition.biomes.find( ot->get_type_id() ); if( biome == dat.region.forest_composition.biomes.end() ) { return 0; } @@ -936,7 +957,7 @@ void mapgen_forest( mapgendata &dat ) // This can be calculated once from dat.t_nesw, and stored here: std::array adjacent_biomes; for( int d = 0; d < 7; d++ ) { - auto lookup = dat.region.forest_composition.biomes.find( dat.t_nesw[d] ); + auto lookup = dat.region.forest_composition.biomes.find( dat.t_nesw[d]->get_type_id() ); if( lookup != dat.region.forest_composition.biomes.end() ) { adjacent_biomes[d] = &( lookup->second ); } else { @@ -1036,7 +1057,8 @@ void mapgen_forest( mapgendata &dat ) } // Get the current biome definition for this terrain. - const auto current_biome_def_it = dat.region.forest_composition.biomes.find( dat.terrain_type() ); + const auto current_biome_def_it = dat.region.forest_composition.biomes.find( + dat.terrain_type()->get_type_id() ); // If there is no biome definition for this terrain, fill in with the region's default ground cover // and bail--nothing more to be done. Should not continue with terrain feathering if there is @@ -1690,7 +1712,7 @@ void mapgen_lake_shore( mapgendata &dat ) } // Use t_null for now instead of t_water_sh, because sometimes our extended terrain // has put down a t_water_sh, and we need to be able to flood-fill over that. - m->ter_set( bp, t_null ); + m->ter_set( bp, ter_str_id::NULL_ID() ); m->furn_set( bp, f_null ); } } @@ -1728,14 +1750,14 @@ void mapgen_lake_shore( mapgendata &dat ) if( !map_boundaries.contains( p ) ) { return false; } - return m->ter( p ) != t_null; + return m->ter( p ) != ter_str_id::NULL_ID(); }; const auto fill_deep_water = [&]( const point & starting_point ) { std::vector water_points = ff::point_flood_fill_4_connected( starting_point, visited, should_fill ); for( point &wp : water_points ) { - m->ter_set( wp, t_water_dp ); + m->ter_set( wp, ter_t_water_dp ); m->furn_set( wp, f_null ); } }; @@ -1760,7 +1782,7 @@ void mapgen_lake_shore( mapgendata &dat ) // We previously placed our shallow water but actually did a t_null instead to make sure that we didn't // pick up shallow water from our extended terrain. Now turn those nulls into t_water_sh. - m->translate( t_null, t_water_sh ); + m->translate( ter_str_id::NULL_ID(), ter_t_water_sh ); } void mapgen_ocean_shore( mapgendata &dat ) @@ -2126,7 +2148,7 @@ void mapgen_ocean_shore( mapgendata &dat ) if( !map_boundaries.contains( bp ) ) { continue; } - m->ter_set( bp, t_swater_sh ); + m->ter_set( bp, ter_t_swater_sh ); m->furn_set( bp, f_null ); } } @@ -2141,15 +2163,15 @@ void mapgen_ocean_shore( mapgendata &dat ) } // Use t_null for now instead of t_sand, because sometimes our extended terrain // has put down a t_sand, and we need to be able to flood-fill over that. - m->ter_set( bp, t_null ); + m->ter_set( bp, ter_str_id::NULL_ID() ); m->furn_set( bp, f_null ); } for( const point &bp : closest_points_first( p, sand_margin + 1 ) ) { if( !map_boundaries.contains( bp ) ) { continue; } - if( m->ter( bp ) == t_swater_sh ) { - m->ter_set( bp, t_swater_surf ); + if( m->ter( bp ) == ter_t_swater_sh ) { + m->ter_set( bp, ter_t_swater_surf ); } } } @@ -2193,14 +2215,15 @@ void mapgen_ocean_shore( mapgendata &dat ) if( !map_boundaries.contains( p ) ) { return false; } - return m->ter( p ) != t_null && m->ter( p ) != t_swater_sh && m->ter( p ) != t_swater_surf; + return m->ter( p ) != ter_str_id::NULL_ID() && m->ter( p ) != ter_t_swater_sh && + m->ter( p ) != ter_t_swater_surf; }; const auto fill_deep_water = [&]( const point & starting_point ) { std::vector water_points = ff::point_flood_fill_4_connected( starting_point, visited, should_fill ); for( point &wp : water_points ) { - m->ter_set( wp, t_swater_dp ); + m->ter_set( wp, ter_t_swater_dp ); m->furn_set( wp, f_null ); } }; @@ -2225,7 +2248,7 @@ void mapgen_ocean_shore( mapgendata &dat ) // We previously placed our sand but actually did a t_null instead to make sure that we didn't // pick up sand from our extended terrain. Now turn those nulls into t_sand. - m->translate( t_null, t_sand ); + m->translate( ter_str_id::NULL_ID(), ter_t_sand ); } void mapgen_ravine_edge( mapgendata &dat ) @@ -2274,7 +2297,7 @@ void mapgen_ravine_edge( mapgendata &dat ) if( straight ) { for( int x = 0; x < SEEX * 2; x++ ) { int ground_edge = 12 + rng( 1, 3 ); - line( m, t_null, point( x, ++ground_edge ), point( x, SEEY * 2 ) ); + line( m, ter_str_id::NULL_ID(), point( x, ++ground_edge ), point( x, SEEY * 2 ) ); } if( w_ravine ) { m->rotate( 1 ); @@ -2288,7 +2311,7 @@ void mapgen_ravine_edge( mapgendata &dat ) } else if( interior_corner ) { for( int x = 0; x < SEEX * 2; x++ ) { int ground_edge = 12 + rng( 1, 3 ) + x; - line( m, t_null, point( x, ++ground_edge ), point( x, SEEY * 2 ) ); + line( m, ter_str_id::NULL_ID(), point( x, ++ground_edge ), point( x, SEEY * 2 ) ); } if( nw_ravine ) { m->rotate( 1 ); @@ -2302,7 +2325,7 @@ void mapgen_ravine_edge( mapgendata &dat ) } else if( exterior_corner ) { for( int x = 0; x < SEEX * 2; x++ ) { int ground_edge = 12 + rng( 1, 3 ) - x; - line( m, t_null, point( x, --ground_edge ), point( x, SEEY * 2 - 1 ) ); + line( m, ter_str_id::NULL_ID(), point( x, --ground_edge ), point( x, SEEY * 2 - 1 ) ); } if( w_ravine && s_ravine ) { m->rotate( 1 ); @@ -2317,9 +2340,9 @@ void mapgen_ravine_edge( mapgendata &dat ) // The placed t_null terrains are converted into the regional groundcover in the ravine's bottom level, // in the other levels they are converted into open air to generate the cliffside. if( dat.zlevel() == dat.region.overmap_ravine.ravine_depth ) { - m->translate( t_null, dat.groundcover() ); + m->translate( ter_str_id::NULL_ID(), dat.groundcover() ); } else { - m->translate( t_null, t_open_air ); + m->translate( ter_str_id::NULL_ID(), ter_t_open_air ); } } diff --git a/src/mapgen_functions.h b/src/mapgen_functions.h index face8a8ee8da6..0c4b0939a88f6 100644 --- a/src/mapgen_functions.h +++ b/src/mapgen_functions.h @@ -33,8 +33,8 @@ int terrain_type_to_nesw_array( oter_id terrain_type, std::array &array using building_gen_pointer = void ( * )( mapgendata & ); building_gen_pointer get_mapgen_cfunction( const std::string &ident ); -ter_id grass_or_dirt(); -ter_id clay_or_sand(); +ter_str_id grass_or_dirt(); +ter_str_id clay_or_sand(); // helper functions for mapgen.cpp, so that we can avoid having a massive switch statement (sorta) void mapgen_null( mapgendata &dat ); @@ -75,10 +75,9 @@ bool apply_construction_marker( const update_mapgen_id &update_mapgen_id, const tripoint_abs_omt &omt_pos, const mapgen_arguments &args, bool mirror_horizontal, bool mirror_vertical, int rotation, bool apply ); -std::pair, std::map> - get_changed_ids_from_update( +std::pair, std::map> get_changed_ids_from_update( const update_mapgen_id &, const mapgen_arguments &, - ter_id const &base_ter = t_dirt ); + ter_id const &base_ter = ter_str_id( "t_dirt" ).id() ); mapgen_parameters get_map_special_params( const std::string &mapgen_id ); void resolve_regional_terrain_and_furniture( const mapgendata &dat ); diff --git a/src/mapgendata.cpp b/src/mapgendata.cpp index c56f9f96aa1fa..a15148a79abff 100644 --- a/src/mapgendata.cpp +++ b/src/mapgendata.cpp @@ -79,14 +79,20 @@ mapgendata::mapgendata( const tripoint_abs_omt &over, map &mp, const float densi set_neighbour( 6, direction::SOUTHWEST ); set_neighbour( 7, direction::NORTHWEST ); if( std::optional *maybe_args = overmap_buffer.mapgen_args( over ) ) { - if( *maybe_args ) { + if( *maybe_args && !overmap_buffer.externally_set_args ) { mapgen_args_ = **maybe_args; } else { // We are the first omt from this overmap_special to be generated, // so now is the time to generate the arguments if( std::optional s = overmap_buffer.overmap_special_at( over ) ) { const overmap_special &special = **s; - *maybe_args = special.get_args( *this ); + mapgen_arguments internally_set_args = special.get_args( *this ); + if( overmap_buffer.externally_set_args ) { + maybe_args->value().map.merge( internally_set_args.map ); + overmap_buffer.externally_set_args = false; + } else { + *maybe_args = internally_set_args; + } mapgen_args_ = **maybe_args; } else { debugmsg( "mapgen params expected but no overmap special found for terrain %s", @@ -241,7 +247,7 @@ bool mapgendata::has_flag( jmapgen_flags f ) const ter_id mapgendata::groundcover() const { const ter_id *tid = default_groundcover.pick(); - return tid != nullptr ? *tid : t_null; + return tid != nullptr ? *tid : ter_str_id::NULL_ID().id(); } const oter_id &mapgendata::neighbor_at( om_direction::type dir ) const diff --git a/src/mapgenformat.cpp b/src/mapgenformat.cpp index efab36943045c..3b133a928d792 100644 --- a/src/mapgenformat.cpp +++ b/src/mapgenformat.cpp @@ -21,7 +21,7 @@ void formatted_set_simple( map *m, const point &start, const char *cstr, } else { const ter_id ter = ter_b.translate( *p ); const furn_id furn = furn_b.translate( *p ); - if( ter != t_null ) { + if( ter != ter_str_id::NULL_ID() ) { m->ter_set( p2, ter ); } if( furn != f_null ) { diff --git a/src/martialarts.cpp b/src/martialarts.cpp index 307cb497ddc06..9bc38fc73f74f 100644 --- a/src/martialarts.cpp +++ b/src/martialarts.cpp @@ -83,6 +83,21 @@ void weapon_category::reset() void weapon_category::load( const JsonObject &jo, const std::string_view ) { mandatory( jo, was_loaded, "name", name_ ); + optional( jo, was_loaded, "proficiencies", proficiencies_ ); +} + +void weapon_category::verify_weapon_categories() +{ + weapon_category_factory.check(); +} + +void weapon_category::check() const +{ + for( const proficiency_id &prof : proficiencies_ ) { + if( !prof.is_valid() ) { + debugmsg( "Proficiency %s does not exist in weapon category %s", prof.str(), id.str() ); + } + } } const std::vector &weapon_category::get_all() diff --git a/src/martialarts.h b/src/martialarts.h index 3abaa9ef72143..221ec84002a11 100644 --- a/src/martialarts.h +++ b/src/martialarts.h @@ -32,9 +32,11 @@ class weapon_category { public: static void load_weapon_categories( const JsonObject &jo, const std::string &src ); + static void verify_weapon_categories(); static void reset(); void load( const JsonObject &jo, std::string_view src ); + void check() const; static const std::vector &get_all(); @@ -46,12 +48,17 @@ class weapon_category return name_; } + const std::vector &category_proficiencies() const { + return proficiencies_; + } + private: friend class generic_factory; friend struct mod_tracker; weapon_category_id id; std::vector> src; + std::vector proficiencies_; bool was_loaded = false; translation name_; @@ -431,4 +438,4 @@ std::string martialart_difficulty( const matype_id &mstyle ); std::vector all_martialart_types(); std::vector autolearn_martialart_types(); -#endif // CATA_SRC_MARTIALARTS_H \ No newline at end of file +#endif // CATA_SRC_MARTIALARTS_H diff --git a/src/melee.cpp b/src/melee.cpp index cfca573150bb5..333f31e78ef2b 100644 --- a/src/melee.cpp +++ b/src/melee.cpp @@ -160,6 +160,8 @@ static const trait_id trait_PROF_SKATER( "PROF_SKATER" ); static const trait_id trait_VINES2( "VINES2" ); static const trait_id trait_VINES3( "VINES3" ); +static const weapon_category_id weapon_category_UNARMED( "UNARMED" ); + static void player_hit_message( Character *attacker, const std::string &message, Creature &t, int dam, bool crit = false, bool technique = false, const std::string &wp_hit = {} ); static int stumble( Character &u, const item_location &weap ); @@ -579,6 +581,15 @@ bool Character::melee_attack( Creature &t, bool allow_special, const matec_id &f return melee_attack_abstract( t, allow_special, force_technique, allow_unarmed, forced_movecost ); } +static const std::set &wielded_weapon_categories( const Character &c ) +{ + static const std::set unarmed{ weapon_category_UNARMED }; + if( c.get_wielded_item() ) { + return c.get_wielded_item()->typeId()->weapon_category; + } + return unarmed; +} + bool Character::melee_attack_abstract( Creature &t, bool allow_special, const matec_id &force_technique, bool allow_unarmed, int forced_movecost ) @@ -943,6 +954,13 @@ bool Character::melee_attack_abstract( Creature &t, bool allow_special, enchant_vals::mod::MELEE_STAMINA_CONSUMPTION, get_total_melee_stamina_cost() ); + // Train weapon proficiencies + for( const weapon_category_id &cat : wielded_weapon_categories( *this ) ) { + for( const proficiency_id &prof : cat->category_proficiencies() ) { + practice_proficiency( prof, 1_seconds ); + } + } + burn_energy_arms( std::min( -50, total_stam + deft_bonus ) ); add_msg_debug( debugmode::DF_MELEE, "Stamina burn base/total (capped at -50): %d/%d", base_stam, total_stam + deft_bonus ); @@ -975,7 +993,23 @@ int Character::get_total_melee_stamina_cost( const item *weap ) const !has_flag( json_flag_PSEUDOPOD_GRASP ) ) ? 50 : ( !has_flag( json_flag_PSEUDOPOD_GRASP ) && ( !has_effect( effect_natural_stance ) && ( !unarmed_attack() ) ) && is_crouching() ? 20 : 0 ); - return std::min( -50, mod_sta + melee - stance_malus ); + float proficiency_multiplier = 1.f; + for( const weapon_category_id &cat : wielded_weapon_categories( *this ) ) { + float loss = 0.f; + for( const proficiency_id &prof : cat->category_proficiencies() ) { + if( !has_proficiency( prof ) ) { + continue; + } + std::optional bonus = prof->bonus_for( "melee_attack", proficiency_bonus_type::stamina ); + if( !bonus.has_value() ) { + continue; + } + loss += bonus.value(); + } + proficiency_multiplier = std::clamp( 1.f - loss, 0.f, proficiency_multiplier ); + } + + return std::min( -50, proficiency_multiplier * ( mod_sta + melee - stance_malus ) ); } void Character::reach_attack( const tripoint &p, int forced_movecost ) diff --git a/src/mission_companion.cpp b/src/mission_companion.cpp index 1ab21b58aeca8..4aa0198a503d1 100644 --- a/src/mission_companion.cpp +++ b/src/mission_companion.cpp @@ -100,6 +100,42 @@ static const string_id npc_template_commune_guard( "commune_ static const string_id npc_template_thug( "thug" ); +static const ter_str_id ter_t_curtains( "t_curtains" ); +static const ter_str_id ter_t_dirt( "t_dirt" ); +static const ter_str_id ter_t_dirtmound( "t_dirtmound" ); +static const ter_str_id ter_t_door_b( "t_door_b" ); +static const ter_str_id ter_t_door_boarded( "t_door_boarded" ); +static const ter_str_id ter_t_door_boarded_damaged( "t_door_boarded_damaged" ); +static const ter_str_id ter_t_door_boarded_damaged_peep( "t_door_boarded_damaged_peep" ); +static const ter_str_id ter_t_door_boarded_peep( "t_door_boarded_peep" ); +static const ter_str_id ter_t_door_c( "t_door_c" ); +static const ter_str_id ter_t_door_c_peep( "t_door_c_peep" ); +static const ter_str_id ter_t_door_glass_c( "t_door_glass_c" ); +static const ter_str_id ter_t_door_glass_o( "t_door_glass_o" ); +static const ter_str_id ter_t_door_locked( "t_door_locked" ); +static const ter_str_id ter_t_door_locked_alarm( "t_door_locked_alarm" ); +static const ter_str_id ter_t_door_locked_peep( "t_door_locked_peep" ); +static const ter_str_id ter_t_door_metal_c( "t_door_metal_c" ); +static const ter_str_id ter_t_door_metal_locked( "t_door_metal_locked" ); +static const ter_str_id ter_t_door_metal_o( "t_door_metal_o" ); +static const ter_str_id ter_t_door_metal_pickable( "t_door_metal_pickable" ); +static const ter_str_id ter_t_door_o( "t_door_o" ); +static const ter_str_id ter_t_rdoor_boarded( "t_rdoor_boarded" ); +static const ter_str_id ter_t_rdoor_boarded_damaged( "t_rdoor_boarded_damaged" ); +static const ter_str_id ter_t_wall( "t_wall" ); +static const ter_str_id ter_t_wall_glass( "t_wall_glass" ); +static const ter_str_id ter_t_wall_glass_alarm( "t_wall_glass_alarm" ); +static const ter_str_id ter_t_window( "t_window" ); +static const ter_str_id ter_t_window_alarm( "t_window_alarm" ); +static const ter_str_id ter_t_window_alarm_taped( "t_window_alarm_taped" ); +static const ter_str_id ter_t_window_boarded( "t_window_boarded" ); +static const ter_str_id ter_t_window_boarded_noglass( "t_window_boarded_noglass" ); +static const ter_str_id ter_t_window_domestic( "t_window_domestic" ); +static const ter_str_id ter_t_window_domestic_taped( "t_window_domestic_taped" ); +static const ter_str_id ter_t_window_no_curtains( "t_window_no_curtains" ); +static const ter_str_id ter_t_window_no_curtains_taped( "t_window_no_curtains_taped" ); +static const ter_str_id ter_t_window_taped( "t_window_taped" ); + static const trait_id trait_DEBUG_HS( "DEBUG_HS" ); static const trait_id trait_NPC_CONSTRUCTION_LEV_2( "NPC_CONSTRUCTION_LEV_2" ); static const trait_id trait_NPC_MISSION_LEV_1( "NPC_MISSION_LEV_1" ); @@ -1554,7 +1590,7 @@ void talk_function::field_plant( npc &p, const std::string &place ) tinymap bay; bay.load( site, false ); for( const tripoint &plot : bay.points_on_zlevel() ) { - if( bay.ter( plot ) == t_dirtmound ) { + if( bay.ter( plot ) == ter_t_dirtmound ) { empty_plots++; } } @@ -1594,7 +1630,7 @@ void talk_function::field_plant( npc &p, const std::string &place ) //Plant the actual seeds for( const tripoint &plot : bay.points_on_zlevel() ) { - if( bay.ter( plot ) == t_dirtmound && limiting_number > 0 ) { + if( bay.ter( plot ) == ter_t_dirtmound && limiting_number > 0 ) { std::list used_seed; if( item::count_by_charges( seed_id ) ) { used_seed = player_character.use_charges( seed_id, 1 ); @@ -1603,7 +1639,7 @@ void talk_function::field_plant( npc &p, const std::string &place ) } used_seed.front().set_age( 0_turns ); bay.add_item_or_charges( plot, used_seed.front() ); - bay.set( plot, t_dirt, f_plant_seed ); + bay.set( plot, ter_t_dirt, f_plant_seed ); limiting_number--; } } @@ -1697,7 +1733,7 @@ void talk_function::field_harvest( npc &p, const std::string &place ) bay.i_clear( plot ); bay.furn_set( plot, f_null ); - bay.ter_set( plot, t_dirtmound ); + bay.ter_set( plot, ter_t_dirtmound ); } } } @@ -2773,12 +2809,10 @@ std::set talk_function::loot_building( const tripoint_abs_omt &site, for( const tripoint &p : bay.points_on_zlevel() ) { const ter_id t = bay.ter( p ); //Open all the doors, doesn't need to be exhaustive - if( t == t_door_c || t == t_door_c_peep || t == t_door_b - || t == t_door_boarded || t == t_door_boarded_damaged - || t == t_rdoor_boarded || t == t_rdoor_boarded_damaged - || t == t_door_boarded_peep || t == t_door_boarded_damaged_peep ) { - bay.ter_set( p, t_door_o ); - } else if( t == t_door_locked || t == t_door_locked_peep || t == t_door_locked_alarm ) { + const std::unordered_set openable_doors = {ter_t_door_c, ter_t_door_c_peep, ter_t_door_b, ter_t_door_boarded, ter_t_door_boarded_damaged, ter_t_rdoor_boarded, ter_t_rdoor_boarded_damaged, ter_t_door_boarded_peep, ter_t_door_boarded_damaged_peep }; + if( openable_doors.find( t.id() ) != openable_doors.end() ) { + bay.ter_set( p, ter_t_door_o ); + } else if( t == ter_t_door_locked || t == ter_t_door_locked_peep || t == ter_t_door_locked_alarm ) { const map_bash_info &bash = bay.ter( p ).obj().bash; bay.ter_set( p, bash.ter_set ); // Bash doors twice @@ -2786,27 +2820,24 @@ std::set talk_function::loot_building( const tripoint_abs_omt &site, bay.ter_set( p, bash_again.ter_set ); bay.spawn_items( p, item_group::items_from( bash.drop_group, calendar::turn ) ); bay.spawn_items( p, item_group::items_from( bash_again.drop_group, calendar::turn ) ); - } else if( t == t_door_metal_c || t == t_door_metal_locked || t == t_door_metal_pickable ) { - bay.ter_set( p, t_door_metal_o ); - } else if( t == t_door_glass_c ) { - bay.ter_set( p, t_door_glass_o ); - } else if( t == t_wall && one_in( 25 ) ) { + } else if( t == ter_t_door_metal_c || t == ter_t_door_metal_locked || + t == ter_t_door_metal_pickable ) { + bay.ter_set( p, ter_t_door_metal_o ); + } else if( t == ter_t_door_glass_c ) { + bay.ter_set( p, ter_t_door_glass_o ); + } else if( t == ter_t_wall && one_in( 25 ) ) { const map_bash_info &bash = bay.ter( p ).obj().bash; bay.ter_set( p, bash.ter_set ); bay.spawn_items( p, item_group::items_from( bash.drop_group, calendar::turn ) ); bay.collapse_at( p, false ); } //Smash easily breakable stuff - else if( ( t == t_window || t == t_window_taped || t == t_window_domestic || - t == t_window_boarded_noglass || t == t_window_domestic_taped || - t == t_window_alarm_taped || t == t_window_boarded || - t == t_curtains || t == t_window_alarm || - t == t_window_no_curtains || t == t_window_no_curtains_taped ) - && one_in( 4 ) ) { + else if( const std::unordered_set weak_window_ters = {ter_t_window, ter_t_window_taped, ter_t_window_domestic, ter_t_window_boarded_noglass, ter_t_window_domestic_taped, ter_t_window_alarm_taped, ter_t_window_boarded, ter_t_curtains, ter_t_window_alarm, ter_t_window_no_curtains, ter_t_window_no_curtains_taped }; + weak_window_ters.find( t.id() ) != weak_window_ters.end() && one_in( 4 ) ) { const map_bash_info &bash = bay.ter( p ).obj().bash; bay.ter_set( p, bash.ter_set ); bay.spawn_items( p, item_group::items_from( bash.drop_group, calendar::turn ) ); - } else if( ( t == t_wall_glass || t == t_wall_glass_alarm ) && one_in( 3 ) ) { + } else if( ( t == ter_t_wall_glass || t == ter_t_wall_glass_alarm ) && one_in( 3 ) ) { const map_bash_info &bash = bay.ter( p ).obj().bash; bay.ter_set( p, bash.ter_set ); bay.spawn_items( p, item_group::items_from( bash.drop_group, calendar::turn ) ); diff --git a/src/mission_start.cpp b/src/mission_start.cpp index 8c038c598b261..82bc241f4c319 100644 --- a/src/mission_start.cpp +++ b/src/mission_start.cpp @@ -38,6 +38,9 @@ static const itype_id itype_software_useless( "software_useless" ); static const mission_type_id mission_MISSION_GET_ZOMBIE_BLOOD_ANAL( "MISSION_GET_ZOMBIE_BLOOD_ANAL" ); +static const ter_str_id ter_t_floor( "t_floor" ); +static const ter_str_id ter_t_wall_metal( "t_wall_metal" ); + /* These functions are responsible for making changes to the game at the moment * the mission is accepted by the player. They are also responsible for * updating *miss with the target and any other important information. @@ -89,7 +92,7 @@ static tripoint find_potential_computer_point( const tinymap &compmap ) for( const tripoint &p : compmap.points_on_zlevel() ) { if( compmap.furn( p ) == f_console_broken ) { broken.emplace_back( p ); - } else if( broken.empty() && compmap.ter( p ) == t_floor && compmap.furn( p ) == f_null ) { + } else if( broken.empty() && compmap.ter( p ) == ter_t_floor && compmap.furn( p ) == f_null ) { for( const tripoint &p2 : compmap.points_in_radius( p, 1 ) ) { if( compmap.furn( p2 ) == f_bed || compmap.furn( p2 ) == f_dresser ) { potential.emplace_back( p ); @@ -208,9 +211,9 @@ void mission_start::place_deposit_box( mission *miss ) compmap.load( site, false ); std::vector valid; for( const tripoint &p : compmap.points_on_zlevel() ) { - if( compmap.ter( p ) == t_floor ) { + if( compmap.ter( p ) == ter_t_floor ) { for( const tripoint &p2 : compmap.points_in_radius( p, 1 ) ) { - if( compmap.ter( p2 ) == t_wall_metal ) { + if( compmap.ter( p2 ) == ter_t_wall_metal ) { valid.push_back( p ); break; } diff --git a/src/monattack.cpp b/src/monattack.cpp index ab41b96dcf32e..b133e3e281bba 100644 --- a/src/monattack.cpp +++ b/src/monattack.cpp @@ -221,6 +221,14 @@ static const species_id species_LEECH_PLANT( "LEECH_PLANT" ); static const species_id species_SLIME( "SLIME" ); static const species_id species_ZOMBIE( "ZOMBIE" ); +static const ter_str_id ter_t_dirt( "t_dirt" ); +static const ter_str_id ter_t_dirtmound( "t_dirtmound" ); +static const ter_str_id ter_t_marloss( "t_marloss" ); +static const ter_str_id ter_t_root_wall( "t_root_wall" ); +static const ter_str_id ter_t_tree( "t_tree" ); +static const ter_str_id ter_t_tree_young( "t_tree_young" ); +static const ter_str_id ter_t_underbrush( "t_underbrush" ); + static const trait_id trait_ACIDBLOOD( "ACIDBLOOD" ); static const trait_id trait_MARLOSS( "MARLOSS" ); static const trait_id trait_MARLOSS_BLUE( "MARLOSS_BLUE" ); @@ -555,7 +563,7 @@ bool mattack::graze( monster *z ) !here.has_flag( ter_furn_flag::TFLAG_GRAZER_INEDIBLE, p ) && ( z->amount_eaten <= z->stomach_size ) ) { add_msg_if_player_sees( *z, _( "The %1s eats the %2s." ), z->name(), here.tername( p ) ); - here.ter_set( p, t_dirt ); + here.ter_set( p, ter_t_dirt ); z->amount_eaten += 174; //Calorie amount is based on the "underbrush" dummy item, as with the grazer mutation. return true; @@ -1600,7 +1608,7 @@ bool mattack::growplants( monster *z ) // Only affect natural, dirtlike terrain or trees. if( !( here.has_flag_ter( ter_furn_flag::TFLAG_DIGGABLE, p ) || here.has_flag_ter( ter_furn_flag::TFLAG_TREE, p ) || - here.ter( p ) == t_tree_young ) ) { + here.ter( p ) == ter_t_tree_young ) ) { continue; } @@ -1608,7 +1616,7 @@ bool mattack::growplants( monster *z ) // Destroy everything here.destroy( p ); // And then make the ground fertile - here.ter_set( p, t_dirtmound ); + here.ter_set( p, ter_t_dirtmound ); continue; } @@ -1616,7 +1624,7 @@ bool mattack::growplants( monster *z ) if( !one_in( 4 ) ) { if( one_in( 3 ) ) { // If no tree, perhaps underbrush - here.ter_set( p, t_underbrush ); + here.ter_set( p, ter_t_underbrush ); } continue; @@ -1630,7 +1638,7 @@ bool mattack::growplants( monster *z ) continue; } - here.ter_set( p, t_tree_young ); + here.ter_set( p, ter_t_tree_young ); if( critter == nullptr || critter->uncanny_dodge() ) { continue; } @@ -1651,7 +1659,7 @@ bool mattack::growplants( monster *z ) } for( const tripoint &p : here.points_in_radius( z->pos(), 5 ) ) { const ter_id ter = here.ter( p ); - if( ter != t_tree_young && ter != t_underbrush ) { + if( ter != ter_t_tree_young && ter != ter_t_underbrush ) { // Skip as soon as possible to avoid all the checks continue; } @@ -1662,13 +1670,13 @@ bool mattack::growplants( monster *z ) continue; } - if( ter == t_tree_young ) { + if( ter == ter_t_tree_young ) { // Young tree => tree // TODO: Make this deal damage too - young tree can be walked on, tree can't - here.ter_set( p, t_tree ); - } else if( ter == t_underbrush ) { + here.ter_set( p, ter_t_tree ); + } else if( ter == ter_t_underbrush ) { // Underbrush => young tree - here.ter_set( p, t_tree_young ); + here.ter_set( p, ter_t_tree_young ); if( critter != nullptr && !critter->uncanny_dodge() ) { const bodypart_id &hit = body_part_hit_by_plant(); critter->add_msg_player_or_npc( m_bad, @@ -1821,9 +1829,9 @@ bool mattack::triffid_heartbeat( monster *z ) add_msg( m_warning, _( "The root walls creak around you." ) ); for( const tripoint &dest : here.points_in_radius( z->pos(), 3 ) ) { if( g->is_empty( dest ) && one_in( 4 ) ) { - here.ter_set( dest, t_root_wall ); - } else if( here.ter( dest ) == t_root_wall && one_in( 10 ) ) { - here.ter_set( dest, t_dirt ); + here.ter_set( dest, ter_t_root_wall ); + } else if( here.ter( dest ) == ter_t_root_wall && one_in( 10 ) ) { + here.ter_set( dest, ter_t_dirt ); } } // Open blank tiles as long as there's no possible route @@ -1834,7 +1842,7 @@ bool mattack::triffid_heartbeat( monster *z ) rng( player_character.posy(), z->posy() - 3 ) ); tripoint dest( p, z->posz() ); tries++; - here.ter_set( dest, t_dirt ); + here.ter_set( dest, ter_t_dirt ); if( rl_dist( dest, player_character.pos() ) > 3 && g->num_creatures() < 30 && !creatures.creature_at( dest ) && one_in( 20 ) ) { // Spawn an extra monster mtype_id montype = mon_triffid; @@ -2175,7 +2183,7 @@ bool mattack::fungus_fortify( monster *z ) player_character.unset_mutation( trait_MARLOSS_BLUE ); player_character.set_mutation( trait_THRESH_MARLOSS ); here.ter_set( player_character.pos(), - t_marloss ); // We only show you the door. You walk through it on your own. + ter_t_marloss ); // We only show you the door. You walk through it on your own. get_memorial().add( pgettext( "memorial_male", "Was shown to the Marloss Gateway." ), pgettext( "memorial_female", "Was shown to the Marloss Gateway." ) ); diff --git a/src/monmove.cpp b/src/monmove.cpp index e10d084e0468c..cbda3a0a14b7f 100644 --- a/src/monmove.cpp +++ b/src/monmove.cpp @@ -85,6 +85,11 @@ static const material_id material_iflesh( "iflesh" ); static const species_id species_FUNGUS( "FUNGUS" ); static const species_id species_ZOMBIE( "ZOMBIE" ); +static const ter_str_id ter_t_lava( "t_lava" ); +static const ter_str_id ter_t_pit( "t_pit" ); +static const ter_str_id ter_t_pit_glass( "t_pit_glass" ); +static const ter_str_id ter_t_pit_spiked( "t_pit_spiked" ); + bool monster::is_immune_field( const field_type_id &fid ) const { if( fid == fd_fungal_haze ) { @@ -264,7 +269,7 @@ bool monster::know_danger_at( const tripoint &p ) const const ter_id target = here.ter( p ); if( !here.has_vehicle_floor( p ) ) { // Don't enter lava if we have any concept of heat being bad - if( avoid_fire && target == t_lava ) { + if( avoid_fire && target == ter_t_lava ) { return false; } @@ -276,7 +281,7 @@ bool monster::know_danger_at( const tripoint &p ) const // Don't enter open pits ever unless tiny, can fly or climb well if( !( type->size == creature_size::tiny || can_climb() ) && - ( target == t_pit || target == t_pit_spiked || target == t_pit_glass ) ) { + ( target == ter_t_pit || target == ter_t_pit_spiked || target == ter_t_pit_glass ) ) { return false; } } @@ -691,7 +696,10 @@ void monster::plan() } if( mon_plan.swarms ) { if( rating < 5 ) { // Too crowded here - wander_pos = get_location() + point( rng( 1, 3 ), rng( 1, 3 ) ); + wander_pos = get_location(); + while( wander_pos == get_location() ) { + wander_pos += point( rng( -3, 3 ), rng( -3, 3 ) ); + } wandf = 2; mon_plan.target = nullptr; // Swarm to the furthest ally you can see diff --git a/src/mutation.cpp b/src/mutation.cpp index 79b02a6cfac4b..62ef29e4ce1f9 100644 --- a/src/mutation.cpp +++ b/src/mutation.cpp @@ -78,14 +78,13 @@ static const trait_id trait_M_BLOOM( "M_BLOOM" ); static const trait_id trait_M_FERTILE( "M_FERTILE" ); static const trait_id trait_M_PROVENANCE( "M_PROVENANCE" ); static const trait_id trait_NAUSEA( "NAUSEA" ); +static const trait_id trait_ROBUST( "ROBUST" ); static const trait_id trait_SLIMESPAWNER( "SLIMESPAWNER" ); static const trait_id trait_SNAIL_TRAIL( "SNAIL_TRAIL" ); static const trait_id trait_TREE_COMMUNION( "TREE_COMMUNION" ); static const trait_id trait_VOMITOUS( "VOMITOUS" ); static const trait_id trait_WEB_WEAVER( "WEB_WEAVER" ); -static const vitamin_id vitamin_instability( "instability" ); - namespace io { @@ -172,6 +171,50 @@ bool Character::has_base_trait( const trait_id &b ) const return my_traits.find( b ) != my_traits.end(); } +int Character::get_instability_per_category( const mutation_category_id &categ ) const +{ + int mut_count = 0; + bool robust = has_trait( trait_ROBUST ); + // For each and every trait we have... + for( const trait_id &mut : get_mutations() ) { + // only count muts that have 0 or more points, aren't a threshold, are valid, and aren't a base trait. + if( mut.obj().points > -1 && !mut.obj().threshold && mut.obj().valid && !has_base_trait( mut ) ) { + bool in_categ = false; + // If among all allowed categories the mutation has, the input category is one of them. + for( const mutation_category_id &Ch_cat : mut.obj().category ) { + if( Ch_cat == categ ) { + in_categ = true; + } + } + + const int height = mutation_height( mut ); + + // Thus add 1 point if it's in the tree we mutate into, otherwise add 2 points + // or, if we have Robust Genetics, treat all mutations as in-tree. + if( in_categ || robust ) { + mut_count += height * 1; + } else { + mut_count += height * 2; + } + } + } + return mut_count; +} + +int get_total_nonbad_in_category( const mutation_category_id &categ ) +{ + int mut_count = 0; + + // Iterate through all available traits in this category and count every one that isn't bad or the threshold. + for( const trait_id &traits_iter : mutations_category[categ] ) { + const mutation_branch &mdata = traits_iter.obj(); + if( mdata.points > -1 && !mdata.threshold ) { + mut_count += 1; + } + } + return mut_count; +} + void Character::toggle_trait( const trait_id &trait_, const std::string &var_ ) { // Take copy of argument because it might be a reference into a container @@ -982,27 +1025,30 @@ bool Character::mutation_ok( const trait_id &mutation, bool allow_good, bool all return true; } -bool Character::roll_bad_mutation() const +bool Character::roll_bad_mutation( const mutation_category_id &categ ) const { + // We will never have worse odds than this no matter our instability + float MAX_BAD_CHANCE = 0.67; + // or, if we have Robust, cap it lower. + bool ret = false; - //Instability value at which bad mutations become possible - const float I0 = 900.0; - //Instability value at which good and bad mutations are equally likely - const float I50 = 2800.0; - //Static to avoid recalculating this every time - std::log is not constexpr - static const float exp = std::log( 2 ) / std::log( I50 / I0 ); + // The following values are, respectively, the total number of non-bad traits in a category and + int muts_max = get_total_nonbad_in_category( categ ); + // how many good mutations we have in total. Mutations which don't belong to the tree we're mutating towards count double for this value. Starting traits don't count at all. + int insta_actual = get_instability_per_category( categ ); - if( vitamin_get( vitamin_instability ) == 0 ) { - add_msg_debug( debugmode::DF_MUTATION, "No instability, no bad mutations allowed" ); + if( insta_actual == 0 ) { + add_msg_debug( debugmode::DF_MUTATION, "No mutations yet, no bad mutations allowed" ); return ret; } else { - //A curve that is 0 until I0, crosses 0.5 at I50, then slowly approaches 1 - float chance = std::max( 0.0f, 1 - std::pow( I0 / vitamin_get( vitamin_instability ), exp ) ); + // When we have a total instability score equal to the number of non-bad mutations in the tree, our odds of good/bad are 50/50. + float chance = 0.5 * static_cast( insta_actual ) / static_cast( muts_max ); + chance = std::min( chance, MAX_BAD_CHANCE ); ret = rng_float( 0, 1 ) < chance; add_msg_debug( debugmode::DF_MUTATION, - "Bad mutation chance caused by instability %.1f, roll_bad_mutation returned %s", chance, - ret ? "true" : "false" ); + "%s is the instability category chosen, which has %d total good traits. Adjusted instability score for the category is %d, giving a chance of bad mut of %.3f.", + categ.c_str(), muts_max, insta_actual, chance ); return ret; } } @@ -1025,12 +1071,6 @@ void Character::mutate( const int &true_random_chance, bool use_vitamins ) allow_good = true; allow_bad = true; try_opposite = false; - } else if( roll_bad_mutation() ) { - // If we picked bad, mutation can be bad or neutral - allow_bad = true; - } else { - // Otherwise, can be good or neutral - allow_good = true; } add_msg_debug( debugmode::DF_MUTATION, "mutate: true_random_chance %d", @@ -1048,6 +1088,14 @@ void Character::mutate( const int &true_random_chance, bool use_vitamins ) cat = *cat_list.pick(); cat_list.add_or_replace( cat, 0 ); add_msg_debug( debugmode::DF_MUTATION, "Picked category %s", cat.c_str() ); + // Only decide if it's good or bad after we pick the category. + if( roll_bad_mutation( cat ) ) { + // If we picked bad, mutation can be bad or neutral. + allow_bad = true; + } else { + // Otherwise, can be good or neutral. + allow_good = true; + } } else { // This is fairly direct in explaining why it fails - hopefully it'll help folks to learn the system without needing to read docs add_msg_if_player( m_bad, @@ -1241,7 +1289,7 @@ void Character::mutate_category( const mutation_category_id &cat, const bool use // Mutation selector and true_random overrides good / bad mutation rolls allow_good = true; allow_bad = true; - } else if( roll_bad_mutation() ) { + } else if( roll_bad_mutation( cat ) ) { // If we picked bad, mutation can be bad or neutral allow_bad = true; } else { @@ -1613,8 +1661,6 @@ bool Character::mutate_towards( const trait_id &mut, const mutation_category_id mut_vit.c_str(), vitamin_get( mut_vit ), vitamin_cost ); vitamin_mod( mut_vit, -vitamin_cost ); add_msg_debug( debugmode::DF_MUTATION, "mutate_towards: vitamin level %d", vitamin_get( mut_vit ) ); - // No instability necessary for true random mutations - they are, after all, true random - vitamin_mod( vitamin_instability, vitamin_cost ); } else { add_msg_debug( debugmode::DF_MUTATION, "mutate_towards: vitamin %s level %d below vitamin cost %d", mut_vit.c_str(), vitamin_get( mut_vit ), vitamin_cost ); diff --git a/src/mutation.h b/src/mutation.h index a0cc6d728330d..cbe8091453c6d 100644 --- a/src/mutation.h +++ b/src/mutation.h @@ -554,6 +554,7 @@ bool b_is_higher_trait_of_a( const trait_id &trait_a, const trait_id &trait_b ); bool are_opposite_traits( const trait_id &trait_a, const trait_id &trait_b ); bool are_same_type_traits( const trait_id &trait_a, const trait_id &trait_b ); bool contains_trait( std::vector> traits, const trait_id &trait ); +int get_total_nonbad_in_category( const mutation_category_id &categ ); enum class mutagen_technique : int { consumed_mutagen, diff --git a/src/npctalk.cpp b/src/npctalk.cpp index 9dc0545ff9fb0..91aa41e118184 100644 --- a/src/npctalk.cpp +++ b/src/npctalk.cpp @@ -3996,12 +3996,31 @@ talk_effect_fun_t::func f_bulk_trade_accept( const JsonObject &jo, std::string_v item tmp( d.cur_item ); int quantity = dov_quantity.evaluate( d ); int seller_has = 0; + int seller_has_loose = 0; + std::vector seller_cans; + auto is_canned_item = [&tmp]( const item & e ) { + std::vector pockets = e.get_all_contained_pockets(); + return pockets.size() == 1 && + pockets[0]->size() == 1 && + pockets[0]->sealed() && + pockets[0]->front().type == tmp.type; + }; if( tmp.count_by_charges() ) { seller_has = seller->charges_of( d.cur_item ); } else { - seller_has = seller->items_with( [&tmp]( const item & e ) { - return tmp.type == e.type; + std::vector cans_tmp = seller->items_with( is_canned_item ); + for( item *it : cans_tmp ) { + seller_cans.emplace_back( *it ); + } + seller_has_loose = seller->items_with( [&tmp, + &cans_tmp]( const item & e ) { + return tmp.type == e.type && + !std::any_of( cans_tmp.begin(), cans_tmp.end(), [&e]( const item * n ) { + return &n->get_all_contained_pockets()[0]->front() == &e; + } ); } ).size(); + seller_has = cans_tmp.size() + seller_has_loose; + } seller_has = ( quantity == -1 ) ? seller_has : std::min( seller_has, quantity ); tmp.charges = seller_has; @@ -4047,9 +4066,15 @@ talk_effect_fun_t::func f_bulk_trade_accept( const JsonObject &jo, std::string_v if( tmp.count_by_charges() ) { seller->use_charges( d.cur_item, seller_has ); } else { - seller->use_amount( d.cur_item, seller_has ); + seller->use_amount( d.cur_item, seller_has_loose ); + seller->remove_items_with( is_canned_item ); + } + if( seller_cans.size() != size_t( seller_has ) ) { + buyer->i_add( tmp ); + } + for( const item &it : seller_cans ) { + buyer->i_add( it ); } - buyer->i_add( tmp ); }; } diff --git a/src/npctrade_utils.cpp b/src/npctrade_utils.cpp index 62bfb4e520336..98eb063fea8c0 100644 --- a/src/npctrade_utils.cpp +++ b/src/npctrade_utils.cpp @@ -11,6 +11,8 @@ #include "vehicle.h" #include "vpart_position.h" +static const ter_str_id ter_t_floor( "t_floor" ); + static const zone_type_id zone_type_LOOT_UNSORTED( "LOOT_UNSORTED" ); namespace @@ -89,7 +91,7 @@ void add_fallback_zone( npc &guy ) for( tripoint_abs_ms const &t : closest_points_first( loc, PICKUP_RANGE ) ) { tripoint_bub_ms const t_here = here.bub_from_abs( t ); if( here.has_furn( t_here ) && - ( here.furn( t_here )->max_volume > t_floor->max_volume || + ( here.furn( t_here )->max_volume > ter_t_floor->max_volume || here.furn( t_here )->has_flag( ter_furn_flag::TFLAG_CONTAINER ) ) && here.can_put_items_ter_furn( t_here ) && !here.route( guy.pos_bub(), t_here, guy.get_pathfinding_settings(), diff --git a/src/overmapbuffer.h b/src/overmapbuffer.h index 140ea97bfe641..6b5ab15662ecb 100644 --- a/src/overmapbuffer.h +++ b/src/overmapbuffer.h @@ -144,6 +144,8 @@ class overmapbuffer public: overmapbuffer(); + bool externally_set_args = false; + static cata_path terrain_filename( const point_abs_om & ); static cata_path player_filename( const point_abs_om & ); diff --git a/src/popup.cpp b/src/popup.cpp index dbb5a0c6303f2..2bbd1e6d22ab2 100644 --- a/src/popup.cpp +++ b/src/popup.cpp @@ -23,7 +23,7 @@ class query_popup_impl : public cataimgui::window short keyboard_selected_option; explicit query_popup_impl( query_popup *parent ) : cataimgui::window( "QUERY_POPUP", - ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoScrollbar ) { + ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_AlwaysAutoResize ) { msg_width = 400; this->parent = parent; keyboard_selected_option = 0; @@ -38,14 +38,7 @@ class query_popup_impl : public cataimgui::window protected: void draw_controls() override; cataimgui::bounds get_bounds() override { - float height = float( str_height_to_pixels( parent->folded_msg.size() ) ) + - ( ImGui::GetStyle().ItemSpacing.y * 2 ); - if( !parent->buttons.empty() ) { - height += float( str_height_to_pixels( 1 ) ) + ( ImGui::GetStyle().ItemInnerSpacing.y * 2 ) + - ( ImGui::GetStyle().ItemSpacing.y * 2 ); - } - return { -1.f, parent->ontop ? 0 : -1.f, - float( msg_width ) + ( ImGui::GetStyle().WindowBorderSize * 2 ), height }; + return { -1.f, parent->ontop ? 0 : -1.f, -1.f, -1.f }; } }; @@ -588,10 +581,14 @@ query_popup::result query_popup::query_once_imgui() } else if( res.action == "LEFT" ) { if( impl->keyboard_selected_option > 0 ) { impl->keyboard_selected_option--; + } else { + impl->keyboard_selected_option = short( buttons.size() - 1 ); } } else if( res.action == "RIGHT" ) { if( impl->keyboard_selected_option < short( buttons.size() - 1 ) ) { impl->keyboard_selected_option++; + } else { + impl->keyboard_selected_option = 0; } } else if( res.action == "HELP_KEYBINDINGS" ) { // Keybindings may have changed, regenerate the UI diff --git a/src/proficiency.cpp b/src/proficiency.cpp index d829feac34e21..4ee1d692295f7 100644 --- a/src/proficiency.cpp +++ b/src/proficiency.cpp @@ -58,6 +58,7 @@ std::string enum_to_string( const proficiency_bonus_type case proficiency_bonus_type::dexterity: return "dexterity"; case proficiency_bonus_type::intelligence: return "intelligence"; case proficiency_bonus_type::perception: return "perception"; + case proficiency_bonus_type::stamina: return "stamina"; case proficiency_bonus_type::last: break; // *INDENT-ON* } @@ -220,6 +221,22 @@ std::vector proficiency::get_bonuses( const std::string &cate return bonus_it->second; } +std::optional proficiency::bonus_for( const std::string &category, + proficiency_bonus_type type ) const +{ + auto bonus_it = _bonuses.find( category ); + if( bonus_it == _bonuses.end() ) { + return std::nullopt; + } + for( const proficiency_bonus &b : bonus_it->second ) { + if( b.type == type ) { + return b.value; + } + } + + return std::nullopt; +} + learning_proficiency &proficiency_set::fetch_learning( const proficiency_id &target ) { for( learning_proficiency &cursor : learning ) { @@ -287,7 +304,7 @@ std::vector proficiency_set::display() const } bool proficiency_set::practice( const proficiency_id &practicing, const time_duration &amount, - const std::optional &max ) + float remainder, const std::optional &max ) { if( has_learned( practicing ) || !practicing->can_learn() || !has_prereqs( practicing ) ) { return false; @@ -303,6 +320,11 @@ bool proficiency_set::practice( const proficiency_id &practicing, const time_dur } current.practiced += amount; + current.remainder += remainder; + if( current.remainder > 1.f ) { + current.practiced += 1_seconds; + current.remainder -= 1.f; + } if( current.practiced >= practicing->time_to_learn() ) { for( std::vector::iterator it = learning.begin(); it != learning.end(); ) { @@ -546,6 +568,7 @@ void learning_proficiency::serialize( JsonOut &jsout ) const jsout.member( "id", id ); jsout.member( "practiced", practiced ); + jsout.member( "remainder", remainder ); jsout.end_object(); } @@ -554,6 +577,7 @@ void learning_proficiency::deserialize( const JsonObject &jo ) { jo.read( "id", id ); jo.read( "practiced", practiced ); + jo.read( "remainder", remainder, 0.f ); } void book_proficiency_bonus::deserialize( const JsonObject &jo ) diff --git a/src/proficiency.h b/src/proficiency.h index ff798a0bbd8c1..be16a72da1cd6 100644 --- a/src/proficiency.h +++ b/src/proficiency.h @@ -32,6 +32,7 @@ enum class proficiency_bonus_type : int { dexterity, intelligence, perception, + stamina, last }; @@ -112,6 +113,7 @@ class proficiency std::set required_proficiencies() const; std::vector get_bonuses( const std::string &category ) const; + std::optional bonus_for( const std::string &category, proficiency_bonus_type type ) const; }; // The proficiencies you know, and the ones you're learning. @@ -129,7 +131,7 @@ class proficiency_set std::vector display() const; // True if the proficiency is learned; bool practice( const proficiency_id &practicing, const time_duration &amount, - const std::optional &max ); + float remainder, const std::optional &max ); void learn( const proficiency_id &learned ); void remove( const proficiency_id &lost ); @@ -162,6 +164,8 @@ struct learning_proficiency { // How long we have practiced this proficiency time_duration practiced; + // Rounding errors of seconds, so that proficiencies practiced very briefly don't get truncated + float remainder = 0.f; learning_proficiency() = default; learning_proficiency( const proficiency_id &id, const time_duration &practiced ) : id( id ), diff --git a/src/recipe.cpp b/src/recipe.cpp index 0a3e990df91d7..811ef985458b7 100644 --- a/src/recipe.cpp +++ b/src/recipe.cpp @@ -46,6 +46,7 @@ static const itype_id itype_null( "null" ); static const std::string flag_FULL_MAGAZINE( "FULL_MAGAZINE" ); + recipe::recipe() : skill_used( skill_id::NULL_ID() ) {} int recipe::get_difficulty( const Character &crafter ) const diff --git a/src/regional_settings.cpp b/src/regional_settings.cpp index 3dbbe1dcacead..0a8caff6f46da 100644 --- a/src/regional_settings.cpp +++ b/src/regional_settings.cpp @@ -18,7 +18,7 @@ #include "string_formatter.h" #include "translations.h" -ter_furn_id::ter_furn_id() : ter( t_null ), furn( f_null ) { } +ter_furn_id::ter_furn_id() : ter( ter_str_id::NULL_ID().id() ), furn( f_null ) { } template void read_and_set_or_throw( const JsonObject &jo, const std::string &member, T &target, @@ -761,7 +761,7 @@ void groundcover_extra::finalize() // FIXME: return bool for failure for( std::map::const_iterator it = percent_str.begin(); it != percent_str.end(); ++it ) { - tf_id.ter = t_null; + tf_id.ter = ter_str_id::NULL_ID().id(); tf_id.furn = f_null; if( it->second < 0.0001 ) { continue; @@ -782,7 +782,7 @@ void groundcover_extra::finalize() // FIXME: return bool for failure for( std::map::const_iterator it = boosted_percent_str.begin(); it != boosted_percent_str.end(); ++it ) { - tf_id.ter = t_null; + tf_id.ter = ter_str_id::NULL_ID().id(); tf_id.furn = f_null; if( it->second < 0.0001 ) { continue; @@ -844,7 +844,7 @@ void forest_biome_component::finalize() { for( const std::pair &pr : unfinalized_types ) { ter_furn_id tf_id; - tf_id.ter = t_null; + tf_id.ter = ter_str_id::NULL_ID().id(); tf_id.furn = f_null; const ter_str_id tid( pr.first ); const furn_str_id fid( pr.first ); @@ -922,7 +922,7 @@ void forest_mapgen_settings::finalize() { for( auto &pr : unfinalized_biomes ) { pr.second.finalize(); - const oter_id ot( pr.first ); + const oter_type_id ot( pr.first ); biomes[ot] = pr.second; } } diff --git a/src/regional_settings.h b/src/regional_settings.h index f5afed699299e..558bad5c2bf7e 100644 --- a/src/regional_settings.h +++ b/src/regional_settings.h @@ -152,7 +152,7 @@ struct forest_biome { struct forest_mapgen_settings { std::map unfinalized_biomes; - std::map biomes; + std::map biomes; void finalize(); forest_mapgen_settings() = default; diff --git a/src/requirements.cpp b/src/requirements.cpp index 64cba3ba5cf45..39cab3312fe6b 100644 --- a/src/requirements.cpp +++ b/src/requirements.cpp @@ -1647,6 +1647,10 @@ deduped_requirement_data::deduped_requirement_data( const requirement_data &in, pending.push( { without_dupes, next.index + 1 } ); } + if( alternatives_.empty() && pending.empty() ) { + debugmsg( "Recipe definition %s somehow has no valid recipes!", context.str() ); + } + // Because this algorithm is super-exponential in the worst case, add a // sanity check to prevent things getting too far out of control. // The worst case in the core game currently is boots_fur diff --git a/src/savegame_json.cpp b/src/savegame_json.cpp index 83f281d4af21b..9111dc2caf603 100644 --- a/src/savegame_json.cpp +++ b/src/savegame_json.cpp @@ -155,10 +155,14 @@ static const mtype_id mon_breather( "mon_breather" ); static const skill_id skill_chemistry( "chemistry" ); static const ter_str_id ter_t_ash( "t_ash" ); +static const ter_str_id ter_t_dirt( "t_dirt" ); static const ter_str_id ter_t_pwr_sb_support_l( "t_pwr_sb_support_l" ); static const ter_str_id ter_t_pwr_sb_switchgear_l( "t_pwr_sb_switchgear_l" ); static const ter_str_id ter_t_pwr_sb_switchgear_s( "t_pwr_sb_switchgear_s" ); static const ter_str_id ter_t_rubble( "t_rubble" ); +static const ter_str_id ter_t_support_l( "t_support_l" ); +static const ter_str_id ter_t_switchgear_l( "t_switchgear_l" ); +static const ter_str_id ter_t_switchgear_s( "t_switchgear_s" ); static const ter_str_id ter_t_wreckage( "t_wreckage" ); static const std::array( object_type::NUM_OBJECT_TYPES )> @@ -4851,24 +4855,24 @@ void submap::load( const JsonValue &jv, const std::string &member_name, int vers const ter_str_id tid( terrain_json.next_string() ); if( tid == ter_t_rubble ) { - m->ter[i][j] = ter_id( "t_dirt" ); + m->ter[i][j] = ter_t_dirt; m->frn[i][j] = furn_id( "f_rubble" ); m->itm[i][j].insert( rock ); m->itm[i][j].insert( rock ); } else if( tid == ter_t_wreckage ) { - m->ter[i][j] = ter_id( "t_dirt" ); + m->ter[i][j] = ter_t_dirt; m->frn[i][j] = furn_id( "f_wreckage" ); m->itm[i][j].insert( chunk ); m->itm[i][j].insert( chunk ); } else if( tid == ter_t_ash ) { - m->ter[i][j] = ter_id( "t_dirt" ); + m->ter[i][j] = ter_t_dirt; m->frn[i][j] = furn_id( "f_ash" ); } else if( tid == ter_t_pwr_sb_support_l ) { - m->ter[i][j] = ter_id( "t_support_l" ); + m->ter[i][j] = ter_t_support_l; } else if( tid == ter_t_pwr_sb_switchgear_l ) { - m->ter[i][j] = ter_id( "t_switchgear_l" ); + m->ter[i][j] = ter_t_switchgear_l; } else if( tid == ter_t_pwr_sb_switchgear_s ) { - m->ter[i][j] = ter_id( "t_switchgear_s" ); + m->ter[i][j] = ter_t_switchgear_s; } else { m->ter[i][j] = tid.id(); } @@ -4889,7 +4893,7 @@ void submap::load( const JsonValue &jv, const std::string &member_name, int vers iid = terstr.id(); } else { debugmsg( "invalid ter_str_id '%s'", terstr.str() ); - iid = t_dirt; + iid = ter_t_dirt; } } else if( terrain_entry.test_array() ) { JsonArray terrain_rle = terrain_entry; @@ -4898,7 +4902,7 @@ void submap::load( const JsonValue &jv, const std::string &member_name, int vers iid = terstr.id(); } else { debugmsg( "invalid ter_str_id '%s'", terstr.str() ); - iid = t_dirt; + iid = ter_t_dirt; } remaining = terrain_rle.next_int() - 1; if( terrain_rle.size() > 2 ) { diff --git a/src/start_location.cpp b/src/start_location.cpp index b144d4143c8a3..a6b9ebbc26daf 100644 --- a/src/start_location.cpp +++ b/src/start_location.cpp @@ -33,6 +33,18 @@ class item; static const efftype_id effect_bleed( "bleed" ); +static const ter_str_id ter_t_curtains( "t_curtains" ); +static const ter_str_id ter_t_door_boarded( "t_door_boarded" ); +static const ter_str_id ter_t_door_c( "t_door_c" ); +static const ter_str_id ter_t_door_c_peep( "t_door_c_peep" ); +static const ter_str_id ter_t_door_locked( "t_door_locked" ); +static const ter_str_id ter_t_door_o( "t_door_o" ); +static const ter_str_id ter_t_floor( "t_floor" ); +static const ter_str_id ter_t_window( "t_window" ); +static const ter_str_id ter_t_window_boarded( "t_window_boarded" ); +static const ter_str_id ter_t_window_domestic( "t_window_domestic" ); +static const ter_str_id ter_t_window_no_curtains( "t_window_no_curtains" ); + static const zone_type_id zone_type_ZONE_START_POINT( "ZONE_START_POINT" ); namespace @@ -68,12 +80,12 @@ std::string start_location::name() const int start_location::targets_count() const { - return _omt_types.size(); + return _locations.size(); } -std::pair start_location::random_target() const +omt_types_parameters start_location::random_target() const { - return random_entry( _omt_types ); + return random_entry( _locations ); } bool start_location::requires_city() const @@ -106,14 +118,21 @@ void start_location::load( const JsonObject &jo, const std::string &src ) std::string ter; for( const JsonValue entry : jo.get_array( "terrain" ) ) { ot_match_type ter_match_type = ot_match_type::type; + std::unordered_map parameter_map; if( entry.test_string() ) { ter = entry.get_string(); } else { JsonObject jot = entry.get_object(); ter = jot.get_string( "om_terrain" ); - ter_match_type = jot.get_enum_value( "om_terrain_match_type", ter_match_type ); + if( jot.has_string( "om_terrain_match_type" ) ) { + ter_match_type = jot.get_enum_value( "om_terrain_match_type", ter_match_type ); + } + if( jot.has_object( "parameters" ) ) { + std::unordered_map parameter_map; + jot.read( "parameters", parameter_map ); + } } - _omt_types.emplace_back( ter, ter_match_type ); + _locations.emplace_back( omt_types_parameters{ ter, ter_match_type, parameter_map } ); } if( jo.has_array( "city_sizes" ) ) { assign( jo, "city_sizes", constraints_.city_size, strict ); @@ -142,7 +161,7 @@ static void add_boardable( const tinymap &m, const tripoint &p, std::vector &range ) for( const tripoint &p : range ) { bool must_board_around = false; const ter_id t = m.ter( p ); - if( t == t_window_domestic || t == t_window || t == t_window_no_curtains ) { + if( t == ter_t_window_domestic || t == ter_t_window || t == ter_t_window_no_curtains ) { // Windows are always to the outside and must be boarded must_board_around = true; - m.ter_set( p, t_window_boarded ); - } else if( t == t_door_c || t == t_door_locked || t == t_door_c_peep ) { + m.ter_set( p, ter_t_window_boarded ); + } else if( t == ter_t_door_c || t == ter_t_door_locked || t == ter_t_door_c_peep ) { // Only board up doors that lead to the outside if( m.is_outside( p + tripoint_north ) || m.is_outside( p + tripoint_south ) || m.is_outside( p + tripoint_east ) || m.is_outside( p + tripoint_west ) ) { - m.ter_set( p, t_door_boarded ); + m.ter_set( p, ter_t_door_boarded ); must_board_around = true; } else { // internal doors are opened instead - m.ter_set( p, t_door_o ); + m.ter_set( p, ter_t_door_o ); } } if( must_board_around ) { @@ -231,53 +250,113 @@ void start_location::prepare_map( tinymap &m ) const m.build_outside_cache( z ); board_up( m, m.points_on_zlevel( z ) ); } else { - m.translate( t_window_domestic, t_curtains ); + m.translate( ter_t_window_domestic, ter_t_curtains ); } } -tripoint_abs_omt start_location::find_player_initial_location( const point_abs_om &origin ) const +std::pair> + start_location::find_player_initial_location( const point_abs_om &origin ) const { // Spiral out from the world origin scanning for a compatible starting location, // creating overmaps as necessary. const int radius = 3; + const omt_types_parameters chosen_target = random_target(); for( const point_abs_om &omp : closest_points_first( origin, radius ) ) { overmap &omap = overmap_buffer.get( omp ); - const tripoint_om_omt omtstart = omap.find_random_omt( random_target() ); + const tripoint_om_omt omtstart = omap.find_random_omt( std::make_pair( chosen_target.omt, + chosen_target.omt_type ) ); if( omtstart.raw() != tripoint_min ) { - return project_combine( omp, omtstart ); + return std::make_pair( project_combine( omp, omtstart ), chosen_target.parameters ); } } // Should never happen, if it does we messed up. 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; + return std::make_pair( overmap::invalid_tripoint, chosen_target.parameters ); } -tripoint_abs_omt start_location::find_player_initial_location( const city &origin ) const +std::pair> + start_location::find_player_initial_location( const city &origin ) const { overmap &omap = overmap_buffer.get( origin.pos_om ); - std::vector valid; + std::vector> valid; for( const point_om_omt &omp : closest_points_first( origin.pos, origin.size ) ) { for( int k = constraints_.allowed_z_levels.min; k <= constraints_.allowed_z_levels.max; k++ ) { tripoint_om_omt p( omp, k ); if( !can_belong_to_city( p, origin ) ) { continue; } - for( const auto &target : _omt_types ) { - if( is_ot_match( target.first, omap.ter( p ), target.second ) ) { - valid.push_back( p ); - } + auto target_is_ot_match = [&]( const omt_types_parameters & target ) { + return is_ot_match( target.omt, omap.ter( p ), target.omt_type ); + }; + auto it = std::find_if( _locations.begin(), _locations.end(), + target_is_ot_match ); + if( it != _locations.end() ) { + valid.emplace_back( p, *it ); } } } - const tripoint_om_omt omtstart = random_entry( valid, tripoint_om_omt( tripoint_min ) ); + const std::pair random_valid = random_entry( valid, + std::make_pair( tripoint_om_omt( tripoint_min ), omt_types_parameters() ) ); + const tripoint_om_omt omtstart = random_valid.first; if( omtstart.raw() != tripoint_min ) { - return project_combine( origin.pos_om, omtstart ); + return std::make_pair( project_combine( origin.pos_om, omtstart ), random_valid.second.parameters ); } // Should never happen, if it does we messed up. popup( _( "Unable to generate a valid starting location %s [%s] in a city [%s], please report this failure." ), name(), id.str(), origin.name ); - return overmap::invalid_tripoint; + return std::make_pair( overmap::invalid_tripoint, random_valid.second.parameters ); +} + +void start_location::set_parameters( const tripoint_abs_omt &omtstart, + const std::unordered_map ¶meters_to_set ) const +{ + if( parameters_to_set.empty() ) { + return; + } + overmap_buffer.externally_set_args = true; + std::optional *maybe_args = overmap_buffer.mapgen_args( omtstart ); + if( !maybe_args ) { + debugmsg( "No overmap special args at start location." ); + return; + } + std::optional s = overmap_buffer.overmap_special_at( omtstart ); + if( !s ) { + debugmsg( "No overmap special at start location from which to fetch parameters." ); + return; + } + const overmap_special &special = **s; + const mapgen_parameters ¶ms = special.get_params(); + mapgen_arguments args; + for( const auto ¶m_to_set : parameters_to_set ) { + const std::string ¶m_name_to_set = param_to_set.first; + const std::string &value_to_set = param_to_set.second; + auto param_it = params.map.find( param_name_to_set ); + if( param_it == params.map.end() ) { + debugmsg( "Parameter %s not found", param_name_to_set ); + continue; + } + const mapgen_parameter ¶m = param_it->second; + if( param.scope() != mapgen_parameter_scope::overmap_special ) { + debugmsg( "Parameter %s is not of scope overmap_special", param_name_to_set ); + continue; + } + std::vector possible_values = param.all_possible_values( params ); + auto value_it = std::find( possible_values.begin(), possible_values.end(), value_to_set ); + if( value_it == possible_values.end() ) { + debugmsg( "Parameter value %s for parameter %s not found", value_to_set, param_name_to_set ); + continue; + } + if( *maybe_args ) { + maybe_args->value().map[param_name_to_set] = + cata_variant::from_string( param.type(), std::move( *value_it ) ); + } else { + mapgen_arguments args; + args.map[param_name_to_set] = + cata_variant::from_string( param.type(), std::move( *value_it ) ); + *maybe_args = args; + } + } } void start_location::prepare_map( const tripoint_abs_omt &omtstart ) const diff --git a/src/start_location.h b/src/start_location.h index de83f3ea1bf3a..400b8da49deee 100644 --- a/src/start_location.h +++ b/src/start_location.h @@ -27,6 +27,12 @@ struct start_location_placement_constraints { numeric_interval allowed_z_levels{ -OVERMAP_DEPTH, OVERMAP_HEIGHT }; }; +struct omt_types_parameters { + std::string omt; + ot_match_type omt_type; + std::unordered_map parameters; +}; + class start_location { public: @@ -39,7 +45,7 @@ class start_location std::string name() const; int targets_count() const; - std::pair random_target() const; + omt_types_parameters random_target() const; const std::set &flags() const; /** @@ -48,14 +54,21 @@ class start_location * It may return `overmap::invalid_tripoint` if no suitable starting location could be found * in the world. */ - tripoint_abs_omt find_player_initial_location( const point_abs_om &origin ) const; + std::pair> + find_player_initial_location( const point_abs_om &origin ) const; /** * Find a suitable start location on the overmap in specific city. * @return Global, absolute overmap terrain coordinates where the player should spawn. * It may return `overmap::invalid_tripoint` if no suitable starting location could be found * in the world. */ - tripoint_abs_omt find_player_initial_location( const city &origin ) const; + std::pair> + find_player_initial_location( const city &origin ) const; + /** + * Set any parameters assigned to the chosen start location + */ + void set_parameters( const tripoint_abs_omt &omtstart, + const std::unordered_map ¶meters_to_set ) const; /** * Initialize the map at players start location using @ref prepare_map. * @param omtstart Global overmap terrain coordinates where the player is to be spawned. @@ -95,7 +108,7 @@ class start_location bool can_belong_to_city( const tripoint_om_omt &p, const city &cit ) const; private: translation _name; - std::vector> _omt_types; + std::vector _locations; std::set _flags; start_location_placement_constraints constraints_; diff --git a/src/timed_event.cpp b/src/timed_event.cpp index 45a152a3c357c..1b3ae9c68a842 100644 --- a/src/timed_event.cpp +++ b/src/timed_event.cpp @@ -51,6 +51,15 @@ static const mtype_id mon_spider_widow_giant( "mon_spider_widow_giant" ); static const spell_id spell_dks_summon_alrp( "dks_summon_alrp" ); +static const ter_str_id ter_t_fault( "t_fault" ); +static const ter_str_id ter_t_grate( "t_grate" ); +static const ter_str_id ter_t_rock_floor( "t_rock_floor" ); +static const ter_str_id ter_t_root_wall( "t_root_wall" ); +static const ter_str_id ter_t_stairs_down( "t_stairs_down" ); +static const ter_str_id ter_t_underbrush( "t_underbrush" ); +static const ter_str_id ter_t_water_dp( "t_water_dp" ); +static const ter_str_id ter_t_water_sh( "t_water_sh" ); + timed_event::timed_event( timed_event_type e_t, const time_point &w, int f_id, tripoint_abs_ms p, int s, std::string key ) : type( e_t ) @@ -134,9 +143,10 @@ void timed_event::actualize() std::optional fault_point; bool horizontal = false; for( const tripoint &p : here.points_on_zlevel() ) { - if( here.ter( p ) == t_fault ) { + if( here.ter( p ) == ter_t_fault ) { fault_point = p; - horizontal = here.ter( p + tripoint_east ) == t_fault || here.ter( p + tripoint_west ) == t_fault; + horizontal = here.ter( p + tripoint_east ) == ter_t_fault || + here.ter( p + tripoint_west ) == ter_t_fault; break; } } @@ -146,7 +156,7 @@ void timed_event::actualize() if( horizontal ) { monp.x = rng( fault_point->x, fault_point->x + 2 * SEEX - 8 ); for( int n = -1; n <= 1; n++ ) { - if( here.ter( point( monp.x, fault_point->y + n ) ) == t_rock_floor ) { + if( here.ter( point( monp.x, fault_point->y + n ) ) == ter_t_rock_floor ) { monp.y = fault_point->y + n; } } @@ -154,7 +164,7 @@ void timed_event::actualize() // Vertical fault monp.y = rng( fault_point->y, fault_point->y + 2 * SEEY - 8 ); for( int n = -1; n <= 1; n++ ) { - if( here.ter( point( fault_point->x + n, monp.y ) ) == t_rock_floor ) { + if( here.ter( point( fault_point->x + n, monp.y ) ) == ter_t_rock_floor ) { monp.x = fault_point->x + n; } } @@ -170,8 +180,8 @@ void timed_event::actualize() case timed_event_type::ROOTS_DIE: get_event_bus().send(); for( const tripoint &p : here.points_on_zlevel() ) { - if( here.ter( p ) == t_root_wall && one_in( 3 ) ) { - here.ter_set( p, t_underbrush ); + if( here.ter( p ) == ter_t_root_wall && one_in( 3 ) ) { + here.ter_set( p, ter_t_underbrush ); } } break; @@ -180,8 +190,8 @@ void timed_event::actualize() get_event_bus().send(); bool saw_grate = false; for( const tripoint &p : here.points_on_zlevel() ) { - if( here.ter( p ) == t_grate ) { - here.ter_set( p, t_stairs_down ); + if( here.ter( p ) == ter_t_grate ) { + here.ter_set( p, ter_t_stairs_down ); if( !saw_grate && player_character.sees( p ) ) { saw_grate = true; } @@ -201,28 +211,28 @@ void timed_event::actualize() flood_buf[p.x][p.y] = here.ter( p ); } for( const tripoint &p : here.points_on_zlevel() ) { - if( here.ter( p ) == t_water_sh ) { + if( here.ter( p ) == ter_t_water_sh ) { bool deepen = false; for( const tripoint &w : points_in_radius( p, 1 ) ) { - if( here.ter( w ) == t_water_dp ) { + if( here.ter( w ) == ter_t_water_dp ) { deepen = true; break; } } if( deepen ) { - flood_buf[p.x][p.y] = t_water_dp; + flood_buf[p.x][p.y] = ter_t_water_dp; flooded = true; } - } else if( here.ter( p ) == t_rock_floor ) { + } else if( here.ter( p ) == ter_t_rock_floor ) { bool flood = false; for( const tripoint &w : points_in_radius( p, 1 ) ) { - if( here.ter( w ) == t_water_dp || here.ter( w ) == t_water_sh ) { + if( here.ter( w ) == ter_t_water_dp || here.ter( w ) == ter_t_water_sh ) { flood = true; break; } } if( flood ) { - flood_buf[p.x][p.y] = t_water_sh; + flood_buf[p.x][p.y] = ter_t_water_sh; flooded = true; } } @@ -234,7 +244,7 @@ void timed_event::actualize() // Check if we should print a message if( flood_buf[player_character.posx()][player_character.posy()] != here.ter( player_character.pos() ) ) { - if( flood_buf[player_character.posx()][player_character.posy()] == t_water_sh ) { + if( flood_buf[player_character.posx()][player_character.posy()] == ter_t_water_sh ) { add_msg( m_warning, _( "Water quickly floods up to your knees." ) ); get_memorial().add( pgettext( "memorial_male", "Water level reached knees." ), @@ -337,7 +347,7 @@ void timed_event::per_turn() case timed_event_type::AMIGARA_WHISPERS: { bool faults = false; for( const tripoint &p : here.points_on_zlevel() ) { - if( here.ter( p ) == t_fault ) { + if( here.ter( p ) == ter_t_fault ) { faults = true; break; } diff --git a/src/trapfunc.cpp b/src/trapfunc.cpp index f608ff65c5f2f..35dbaee5da17f 100644 --- a/src/trapfunc.cpp +++ b/src/trapfunc.cpp @@ -88,6 +88,14 @@ static const skill_id skill_throw( "throw" ); static const species_id species_ROBOT( "ROBOT" ); +static const ter_str_id ter_t_floor_blue( "t_floor_blue" ); +static const ter_str_id ter_t_floor_green( "t_floor_green" ); +static const ter_str_id ter_t_floor_red( "t_floor_red" ); +static const ter_str_id ter_t_pit( "t_pit" ); +static const ter_str_id ter_t_rock_blue( "t_rock_blue" ); +static const ter_str_id ter_t_rock_green( "t_rock_green" ); +static const ter_str_id ter_t_rock_red( "t_rock_red" ); + static const trait_id trait_INFRESIST( "INFRESIST" ); // A pit becomes less effective as it fills with corpses. @@ -946,7 +954,7 @@ bool trapfunc::pit_spikes( const tripoint &p, Creature *c, item * ) if( one_in( 4 ) ) { add_msg_if_player_sees( p, _( "The spears break!" ) ); map &here = get_map(); - here.ter_set( p, t_pit ); + here.ter_set( p, ter_t_pit ); // 4 spears to a pit for( int i = 0; i < 4; i++ ) { if( one_in( 3 ) ) { @@ -1037,7 +1045,7 @@ bool trapfunc::pit_glass( const tripoint &p, Creature *c, item * ) if( one_in( 5 ) ) { add_msg_if_player_sees( p, _( "The shards shatter!" ) ); map &here = get_map(); - here.ter_set( p, t_pit ); + here.ter_set( p, ter_t_pit ); // 20 shards in a pit. for( int i = 0; i < 20; i++ ) { if( one_in( 3 ) ) { @@ -1180,7 +1188,7 @@ bool trapfunc::sinkhole( const tripoint &p, Creature *c, item *i ) _( "A sinkhole under collapses!" ) ); if( success ) { here.remove_trap( p ); - here.ter_set( p, t_pit ); + here.ter_set( p, ter_t_pit ); return true; } you->add_msg_player_or_npc( m_bad, _( "You fall into the sinkhole!" ), @@ -1189,7 +1197,7 @@ bool trapfunc::sinkhole( const tripoint &p, Creature *c, item *i ) return false; } here.remove_trap( p ); - here.ter_set( p, t_pit ); + here.ter_set( p, ter_t_pit ); c->mod_moves( -c->get_speed() ); pit( p, c, i ); return true; @@ -1372,23 +1380,23 @@ bool trapfunc::temple_toggle( const tripoint &p, Creature *c, item * ) int &j = tmp.y; for( i = 0; i < MAPSIZE_X; i++ ) { for( j = 0; j < MAPSIZE_Y; j++ ) { - if( type == t_floor_red ) { - if( here.ter( tmp ) == t_rock_green ) { - here.ter_set( tmp, t_floor_green ); - } else if( here.ter( tmp ) == t_floor_green ) { - here.ter_set( tmp, t_rock_green ); + if( type == ter_t_floor_red ) { + if( here.ter( tmp ) == ter_t_rock_green ) { + here.ter_set( tmp, ter_t_floor_green ); + } else if( here.ter( tmp ) == ter_t_floor_green ) { + here.ter_set( tmp, ter_t_rock_green ); } - } else if( type == t_floor_green ) { - if( here.ter( tmp ) == t_rock_blue ) { - here.ter_set( tmp, t_floor_blue ); - } else if( here.ter( tmp ) == t_floor_blue ) { - here.ter_set( tmp, t_rock_blue ); + } else if( type == ter_t_floor_green ) { + if( here.ter( tmp ) == ter_t_rock_blue ) { + here.ter_set( tmp, ter_t_floor_blue ); + } else if( here.ter( tmp ) == ter_t_floor_blue ) { + here.ter_set( tmp, ter_t_rock_blue ); } - } else if( type == t_floor_blue ) { - if( here.ter( tmp ) == t_rock_red ) { - here.ter_set( tmp, t_floor_red ); - } else if( here.ter( tmp ) == t_floor_red ) { - here.ter_set( tmp, t_rock_red ); + } else if( type == ter_t_floor_blue ) { + if( here.ter( tmp ) == ter_t_rock_red ) { + here.ter_set( tmp, ter_t_floor_red ); + } else if( here.ter( tmp ) == ter_t_floor_red ) { + here.ter_set( tmp, ter_t_rock_red ); } } } @@ -1404,19 +1412,19 @@ bool trapfunc::temple_toggle( const tripoint &p, Creature *c, item * ) if( blocked_tiles.size() == 8 ) { for( int i = 7; i >= 0 ; --i ) { - if( here.ter( blocked_tiles.at( i ) ) != t_rock_red && - here.ter( blocked_tiles.at( i ) ) != t_rock_green && - here.ter( blocked_tiles.at( i ) ) != t_rock_blue ) { + if( here.ter( blocked_tiles.at( i ) ) != ter_t_rock_red && + here.ter( blocked_tiles.at( i ) ) != ter_t_rock_green && + here.ter( blocked_tiles.at( i ) ) != ter_t_rock_blue ) { blocked_tiles.erase( blocked_tiles.begin() + i ); } } const tripoint &pnt = random_entry( blocked_tiles ); - if( here.ter( pnt ) == t_rock_red ) { - here.ter_set( pnt, t_floor_red ); - } else if( here.ter( pnt ) == t_rock_green ) { - here.ter_set( pnt, t_floor_green ); - } else if( here.ter( pnt ) == t_rock_blue ) { - here.ter_set( pnt, t_floor_blue ); + if( here.ter( pnt ) == ter_t_rock_red ) { + here.ter_set( pnt, ter_t_floor_red ); + } else if( here.ter( pnt ) == ter_t_rock_green ) { + here.ter_set( pnt, ter_t_floor_green ); + } else if( here.ter( pnt ) == ter_t_rock_blue ) { + here.ter_set( pnt, ter_t_floor_blue ); } } diff --git a/src/ui_manager.cpp b/src/ui_manager.cpp index 66f9e3623f3d4..ec7cea68e0dab 100644 --- a/src/ui_manager.cpp +++ b/src/ui_manager.cpp @@ -453,6 +453,12 @@ void ui_adaptor::redraw_invalidated( ) imclient->end_frame(); imgui_frame_started = false; + + // if any ImGui window needed to calculate the size of its contents, + // it needs an extra frame to draw. We do that here. + if( imclient->auto_size_frame_active() ) { + redraw_invalidated(); + } } void ui_adaptor::screen_resized() diff --git a/src/vehicle_autodrive.cpp b/src/vehicle_autodrive.cpp index f3c3c870d0646..0698e72f21f6f 100644 --- a/src/vehicle_autodrive.cpp +++ b/src/vehicle_autodrive.cpp @@ -137,6 +137,8 @@ * coordinates. */ +static const ter_str_id ter_t_open_air( "t_open_air" ); + static constexpr int OMT_SIZE = coords::map_squares_per( coords::omt ); static constexpr int NAV_MAP_NUM_OMT = 2; static constexpr int NAV_MAP_SIZE_X = NAV_MAP_NUM_OMT * OMT_SIZE; @@ -723,7 +725,7 @@ bool vehicle::autodrive_controller::check_drivable( const tripoint_bub_ms &pt ) if( avatar.get_memorized_tile( pt_abs ) == mm_submap::default_tile ) { // apparently open air doesn't get memorized, so pretend it is or else // we can't fly helicopters due to the many unseen tiles behind the driver - if( !( data.air_ok && here.ter( pt ) == t_open_air ) ) { + if( !( data.air_ok && here.ter( pt ) == ter_t_open_air ) ) { return false; } } @@ -750,12 +752,12 @@ bool vehicle::autodrive_controller::check_drivable( const tripoint_bub_ms &pt ) } const ter_id terrain = here.ter( pt ); - if( terrain == t_null ) { + if( terrain == ter_str_id::NULL_ID() ) { return false; } // open air is an obstacle to non-flying vehicles; it is drivable // for flying vehicles - if( terrain == t_open_air ) { + if( terrain == ter_t_open_air ) { return data.air_ok; } const ter_t &terrain_type = terrain.obj(); diff --git a/src/vehicle_move.cpp b/src/vehicle_move.cpp index 6327bc1dc534d..5c3a4d9cb9096 100644 --- a/src/vehicle_move.cpp +++ b/src/vehicle_move.cpp @@ -59,6 +59,17 @@ static const proficiency_id proficiency_prof_driver( "prof_driver" ); static const skill_id skill_driving( "driving" ); +static const ter_str_id ter_t_railroad_track( "t_railroad_track" ); +static const ter_str_id ter_t_railroad_track_d( "t_railroad_track_d" ); +static const ter_str_id ter_t_railroad_track_d1( "t_railroad_track_d1" ); +static const ter_str_id ter_t_railroad_track_d2( "t_railroad_track_d2" ); +static const ter_str_id ter_t_railroad_track_d_on_tie( "t_railroad_track_d_on_tie" ); +static const ter_str_id ter_t_railroad_track_h( "t_railroad_track_h" ); +static const ter_str_id ter_t_railroad_track_h_on_tie( "t_railroad_track_h_on_tie" ); +static const ter_str_id ter_t_railroad_track_on_tie( "t_railroad_track_on_tie" ); +static const ter_str_id ter_t_railroad_track_v( "t_railroad_track_v" ); +static const ter_str_id ter_t_railroad_track_v_on_tie( "t_railroad_track_v_on_tie" ); + static const trait_id trait_DEFT( "DEFT" ); static const trait_id trait_PROF_SKATER( "PROF_SKATER" ); @@ -1676,17 +1687,16 @@ void vehicle::precalculate_vehicle_turning( units::angle new_turn_dir, bool chec // special case for rails if( check_rail_direction ) { - ter_id terrain_at_wheel = here.ter( wheel_tripoint ); + const ter_str_id &terrain_at_wheel = here.ter( wheel_tripoint ).id(); // check is it correct tile to turn into - if( !is_diagonal_movement && - ( terrain_at_wheel == t_railroad_track_d || terrain_at_wheel == t_railroad_track_d1 || - terrain_at_wheel == t_railroad_track_d2 || terrain_at_wheel == t_railroad_track_d_on_tie ) ) { + if( !is_diagonal_movement ) { + const std::unordered_set diagonal_track_ters = { ter_t_railroad_track_d, ter_t_railroad_track_d1, ter_t_railroad_track_d2, ter_t_railroad_track_d_on_tie }; + if( diagonal_track_ters.find( terrain_at_wheel ) != diagonal_track_ters.end() ) { + incorrect_tiles_not_diagonal++; + } + } else if( const std::unordered_set straight_track_ters = { ter_t_railroad_track, ter_t_railroad_track_on_tie, ter_t_railroad_track_h, ter_t_railroad_track_v, ter_t_railroad_track_h_on_tie, ter_t_railroad_track_v_on_tie }; + straight_track_ters.find( terrain_at_wheel ) != straight_track_ters.end() ) { incorrect_tiles_not_diagonal++; - } else if( is_diagonal_movement && - ( terrain_at_wheel == t_railroad_track || terrain_at_wheel == t_railroad_track_on_tie || - terrain_at_wheel == t_railroad_track_h || terrain_at_wheel == t_railroad_track_v || - terrain_at_wheel == t_railroad_track_h_on_tie || terrain_at_wheel == t_railroad_track_v_on_tie ) ) { - incorrect_tiles_diagonal++; } if( incorrect_tiles_diagonal > allowed_incorrect_tiles_diagonal || incorrect_tiles_not_diagonal > allowed_incorrect_tiles_not_diagonal ) { diff --git a/src/vehicle_use.cpp b/src/vehicle_use.cpp index a2a06b0673c9e..98cbcb58960d7 100644 --- a/src/vehicle_use.cpp +++ b/src/vehicle_use.cpp @@ -97,6 +97,9 @@ static const quality_id qual_SCREW( "SCREW" ); static const skill_id skill_mechanics( "mechanics" ); +static const ter_str_id ter_t_dirt( "t_dirt" ); +static const ter_str_id ter_t_dirtmound( "t_dirtmound" ); + static const vpart_id vpart_horn_bicycle( "horn_bicycle" ); static const zone_type_id zone_type_VEHICLE_PATROL( "VEHICLE_PATROL" ); @@ -998,7 +1001,7 @@ void vehicle::transform_terrain() } if( prereq_fulfilled ) { const ter_id new_ter = ter_id( ttd.post_terrain ); - if( new_ter != t_null ) { + if( new_ter != ter_str_id::NULL_ID() ) { here.ter_set( start_pos, new_ter ); } const furn_id new_furn = furn_id( ttd.post_furniture ); @@ -1073,11 +1076,11 @@ void vehicle::operate_planter() for( auto i = v.begin(); i != v.end(); i++ ) { if( i->is_seed() ) { // If it is an "advanced model" then it will avoid damaging itself or becoming damaged. It's a real feature. - if( here.ter( loc ) != t_dirtmound && vp.has_feature( "ADVANCED_PLANTER" ) ) { + if( here.ter( loc ) != ter_t_dirtmound && vp.has_feature( "ADVANCED_PLANTER" ) ) { //then don't put the item there. break; - } else if( here.ter( loc ) == t_dirtmound ) { - here.set( loc, t_dirt, f_plant_seed ); + } else if( here.ter( loc ) == ter_t_dirtmound ) { + here.set( loc, ter_t_dirt, f_plant_seed ); } else if( !here.has_flag( ter_furn_flag::TFLAG_PLOWABLE, loc ) ) { //If it isn't plowable terrain, then it will most likely be damaged. damage( here, planter_id, rng( 1, 10 ), damage_bash, false ); diff --git a/tests/act_build_test.cpp b/tests/act_build_test.cpp index f0ddf71de4f50..ed3780d7f87da 100644 --- a/tests/act_build_test.cpp +++ b/tests/act_build_test.cpp @@ -14,7 +14,15 @@ #include "player_helpers.h" static const activity_id ACT_MULTIPLE_CONSTRUCTION( "ACT_MULTIPLE_CONSTRUCTION" ); + static const faction_id faction_free_merchants( "free_merchants" ); + +static const ter_str_id ter_t_dirt( "t_dirt" ); +static const ter_str_id ter_t_metal_grate_window( "t_metal_grate_window" ); +static const ter_str_id ter_t_railroad_rubble( "t_railroad_rubble" ); +static const ter_str_id ter_t_window_boarded_noglass( "t_window_boarded_noglass" ); +static const ter_str_id ter_t_window_empty( "t_window_empty" ); + static const zone_type_id zone_type_CONSTRUCTION_BLUEPRINT( "CONSTRUCTION_BLUEPRINT" ); static const zone_type_id zone_type_LOOT_UNSORTED( "LOOT_UNSORTED" ); @@ -156,11 +164,11 @@ void run_test_case( Character &u ) construction const build = setup_testcase( u, "test_constr_remove_gravel", tri_gravel, tripoint_bub_ms() ); // first check that we don't get stuck in a loop - here.ter_set( tri_gravel, t_dirt ); + here.ter_set( tri_gravel, ter_t_dirt ); run_activities( u, 1 ); REQUIRE( here.partial_con_at( tri_gravel ) == nullptr ); - here.ter_set( tri_gravel, t_railroad_rubble ); + here.ter_set( tri_gravel, ter_t_railroad_rubble ); run_activities( u, build.time * 10 ); REQUIRE( here.ter( tri_gravel ) == ter_id( build.post_terrain ) ); } @@ -171,10 +179,10 @@ void run_test_case( Character &u ) tripoint_bub_ms const tri_window( tripoint_south ); construction const build = setup_testcase( u, "test_constr_window_boarded", tri_window, tripoint_bub_ms() ); - here.ter_set( tri_window, t_window_empty ); + here.ter_set( tri_window, ter_t_window_empty ); REQUIRE( build.pre_terrain != "t_window_empty" ); run_activities( u, build.time * 10 ); - REQUIRE( here.ter( tri_window ) == t_window_boarded_noglass ); + REQUIRE( here.ter( tri_window ) == ter_t_window_boarded_noglass ); } SECTION( "1-step construction activity with existing partial" ) { @@ -200,7 +208,7 @@ void run_test_case( Character &u ) pc.id = get_construction( "test_constr_window_boarded_noglass_empty" ).id; here.partial_con_set( tri_window, pc ); run_activities( u, build.time * 10 ); - REQUIRE( here.ter( tri_window ) == t_window_boarded_noglass ); + REQUIRE( here.ter( tri_window ) == ter_t_window_boarded_noglass ); } SECTION( "1-step construction activity with mismatched partial" ) { @@ -223,7 +231,7 @@ void run_test_case( Character &u ) here.build_map_cache( u.pos().z ); tripoint_bub_ms const tri_window = { 0, 5, 0 }; for( tripoint_bub_ms const &it : here.points_in_radius( tri_window, 1 ) ) { - here.ter_set( it, t_metal_grate_window ); + here.ter_set( it, ter_t_metal_grate_window ); } construction const build = setup_testcase( u, "test_constr_door", tri_window, tripoint_bub_ms() ); diff --git a/tests/cardio_test.cpp b/tests/cardio_test.cpp index f669055cd1398..d201a7820be32 100644 --- a/tests/cardio_test.cpp +++ b/tests/cardio_test.cpp @@ -37,6 +37,8 @@ static const move_mode_id move_mode_run( "run" ); static const skill_id skill_swimming( "swimming" ); +static const ter_str_id ter_t_pavement( "t_pavement" ); + // Base cardio for default character static const int base_cardio = 1000; // Base stamina @@ -53,7 +55,7 @@ static void verify_default_cardio_options() } // Count the number of steps (tiles) until character runs out of stamina or becomes winded. -static int running_steps( Character &they, const ter_id &terrain = t_pavement ) +static int running_steps( Character &they, const ter_str_id &terrain = ter_t_pavement ) { map &here = get_map(); // Please take off your shoes when entering, and no NPCs allowed diff --git a/tests/char_suffer_test.cpp b/tests/char_suffer_test.cpp index ad9a4183c9d26..ecabf79b12d8c 100644 --- a/tests/char_suffer_test.cpp +++ b/tests/char_suffer_test.cpp @@ -22,6 +22,8 @@ static const efftype_id effect_grabbed( "grabbed" ); +static const ter_str_id ter_t_rock_wall( "t_rock_wall" ); + static const trait_id trait_ALBINO( "ALBINO" ); static const trait_id trait_SUNBURN( "SUNBURN" ); @@ -507,8 +509,8 @@ TEST_CASE( "suffering_from_asphyxiation", "[char][suffer][oxygen][grab]" ) map &here = get_map(); WHEN( "crushed against two walls by two grabbers" ) { - here.ter_set( dummy.pos() + tripoint_south, t_rock_wall ); - here.ter_set( dummy.pos() + tripoint_north, t_rock_wall ); + here.ter_set( dummy.pos() + tripoint_south, ter_t_rock_wall ); + here.ter_set( dummy.pos() + tripoint_north, ter_t_rock_wall ); REQUIRE( here.impassable( dummy.pos() + tripoint_south ) ); REQUIRE( here.impassable( dummy.pos() + tripoint_north ) ); diff --git a/tests/connect_rotate_test.cpp b/tests/connect_rotate_test.cpp index fb1315ebb0920..832556b5ff3a9 100644 --- a/tests/connect_rotate_test.cpp +++ b/tests/connect_rotate_test.cpp @@ -10,6 +10,10 @@ #include "player_helpers.h" #include "sdltiles.h" +static const ter_str_id ter_t_floor( "t_floor" ); +static const ter_str_id ter_t_pavement( "t_pavement" ); +static const ter_str_id ter_t_wall( "t_wall" ); + class cata_tiles_test_helper { public: @@ -37,10 +41,10 @@ TEST_CASE( "walls_should_be_unconnected_without_nearby_walls", "[multitile][conn // Unconnected WHEN( "no connecting neighbours" ) { - REQUIRE( here.ter_set( pos + point_east, t_floor ) ); - REQUIRE( here.ter_set( pos + point_south, t_floor ) ); - REQUIRE( here.ter_set( pos + point_west, t_floor ) ); - REQUIRE( here.ter_set( pos + point_north, t_floor ) ); + REQUIRE( here.ter_set( pos + point_east, ter_t_floor ) ); + REQUIRE( here.ter_set( pos + point_south, ter_t_floor ) ); + REQUIRE( here.ter_set( pos + point_west, ter_t_floor ) ); + REQUIRE( here.ter_set( pos + point_north, ter_t_floor ) ); THEN( "the wall should be unconnected" ) { cata_tiles_test_helper::get_connect_values( pos, subtile, rotation, @@ -67,10 +71,10 @@ TEST_CASE( "walls_should_connect_to_walls_as_end_pieces", "[multitile][connects] // End pieces WHEN( "connecting neighbour south" ) { - REQUIRE( here.ter_set( pos + point_south, t_wall ) ); - REQUIRE( here.ter_set( pos + point_east, t_floor ) ); - REQUIRE( here.ter_set( pos + point_north, t_floor ) ); - REQUIRE( here.ter_set( pos + point_west, t_floor ) ); + REQUIRE( here.ter_set( pos + point_south, ter_t_wall ) ); + REQUIRE( here.ter_set( pos + point_east, ter_t_floor ) ); + REQUIRE( here.ter_set( pos + point_north, ter_t_floor ) ); + REQUIRE( here.ter_set( pos + point_west, ter_t_floor ) ); THEN( "the wall should be connected as end_piece N" ) { cata_tiles_test_helper::get_connect_values( pos, subtile, rotation, @@ -80,10 +84,10 @@ TEST_CASE( "walls_should_connect_to_walls_as_end_pieces", "[multitile][connects] } } WHEN( "connecting neighbour east" ) { - REQUIRE( here.ter_set( pos + point_south, t_floor ) ); - REQUIRE( here.ter_set( pos + point_east, t_wall ) ); - REQUIRE( here.ter_set( pos + point_north, t_floor ) ); - REQUIRE( here.ter_set( pos + point_west, t_floor ) ); + REQUIRE( here.ter_set( pos + point_south, ter_t_floor ) ); + REQUIRE( here.ter_set( pos + point_east, ter_t_wall ) ); + REQUIRE( here.ter_set( pos + point_north, ter_t_floor ) ); + REQUIRE( here.ter_set( pos + point_west, ter_t_floor ) ); THEN( "the wall should be connected as end_piece W" ) { cata_tiles_test_helper::get_connect_values( pos, subtile, rotation, @@ -93,10 +97,10 @@ TEST_CASE( "walls_should_connect_to_walls_as_end_pieces", "[multitile][connects] } } WHEN( "connecting neighbour north" ) { - REQUIRE( here.ter_set( pos + point_south, t_floor ) ); - REQUIRE( here.ter_set( pos + point_east, t_floor ) ); - REQUIRE( here.ter_set( pos + point_north, t_wall ) ); - REQUIRE( here.ter_set( pos + point_west, t_floor ) ); + REQUIRE( here.ter_set( pos + point_south, ter_t_floor ) ); + REQUIRE( here.ter_set( pos + point_east, ter_t_floor ) ); + REQUIRE( here.ter_set( pos + point_north, ter_t_wall ) ); + REQUIRE( here.ter_set( pos + point_west, ter_t_floor ) ); THEN( "the wall should be connected as end_piece S" ) { cata_tiles_test_helper::get_connect_values( pos, subtile, rotation, @@ -106,10 +110,10 @@ TEST_CASE( "walls_should_connect_to_walls_as_end_pieces", "[multitile][connects] } } WHEN( "connecting neighbour west" ) { - REQUIRE( here.ter_set( pos + point_south, t_floor ) ); - REQUIRE( here.ter_set( pos + point_east, t_floor ) ); - REQUIRE( here.ter_set( pos + point_north, t_floor ) ); - REQUIRE( here.ter_set( pos + point_west, t_wall ) ); + REQUIRE( here.ter_set( pos + point_south, ter_t_floor ) ); + REQUIRE( here.ter_set( pos + point_east, ter_t_floor ) ); + REQUIRE( here.ter_set( pos + point_north, ter_t_floor ) ); + REQUIRE( here.ter_set( pos + point_west, ter_t_wall ) ); THEN( "the wall should be connected as end_piece E" ) { cata_tiles_test_helper::get_connect_values( pos, subtile, rotation, @@ -136,10 +140,10 @@ TEST_CASE( "walls_should_connect_to_walls_as_corners", "[multitile][connects]" ) // Corners WHEN( "connecting neighbour south and east" ) { - REQUIRE( here.ter_set( pos + point_south, t_wall ) ); - REQUIRE( here.ter_set( pos + point_east, t_wall ) ); - REQUIRE( here.ter_set( pos + point_north, t_floor ) ); - REQUIRE( here.ter_set( pos + point_west, t_floor ) ); + REQUIRE( here.ter_set( pos + point_south, ter_t_wall ) ); + REQUIRE( here.ter_set( pos + point_east, ter_t_wall ) ); + REQUIRE( here.ter_set( pos + point_north, ter_t_floor ) ); + REQUIRE( here.ter_set( pos + point_west, ter_t_floor ) ); THEN( "the wall should be connected as corner NW" ) { cata_tiles_test_helper::get_connect_values( pos, subtile, rotation, @@ -149,10 +153,10 @@ TEST_CASE( "walls_should_connect_to_walls_as_corners", "[multitile][connects]" ) } } WHEN( "connecting neighbour north and east" ) { - REQUIRE( here.ter_set( pos + point_south, t_floor ) ); - REQUIRE( here.ter_set( pos + point_east, t_wall ) ); - REQUIRE( here.ter_set( pos + point_north, t_wall ) ); - REQUIRE( here.ter_set( pos + point_west, t_floor ) ); + REQUIRE( here.ter_set( pos + point_south, ter_t_floor ) ); + REQUIRE( here.ter_set( pos + point_east, ter_t_wall ) ); + REQUIRE( here.ter_set( pos + point_north, ter_t_wall ) ); + REQUIRE( here.ter_set( pos + point_west, ter_t_floor ) ); THEN( "the wall should be connected as corner SW" ) { cata_tiles_test_helper::get_connect_values( pos, subtile, rotation, @@ -162,10 +166,10 @@ TEST_CASE( "walls_should_connect_to_walls_as_corners", "[multitile][connects]" ) } } WHEN( "connecting neighbour north and west" ) { - REQUIRE( here.ter_set( pos + point_south, t_floor ) ); - REQUIRE( here.ter_set( pos + point_east, t_floor ) ); - REQUIRE( here.ter_set( pos + point_north, t_wall ) ); - REQUIRE( here.ter_set( pos + point_west, t_wall ) ); + REQUIRE( here.ter_set( pos + point_south, ter_t_floor ) ); + REQUIRE( here.ter_set( pos + point_east, ter_t_floor ) ); + REQUIRE( here.ter_set( pos + point_north, ter_t_wall ) ); + REQUIRE( here.ter_set( pos + point_west, ter_t_wall ) ); THEN( "the wall should be connected as corner SE" ) { cata_tiles_test_helper::get_connect_values( pos, subtile, rotation, @@ -175,10 +179,10 @@ TEST_CASE( "walls_should_connect_to_walls_as_corners", "[multitile][connects]" ) } } WHEN( "connecting neighbour south and west" ) { - REQUIRE( here.ter_set( pos + point_south, t_wall ) ); - REQUIRE( here.ter_set( pos + point_east, t_floor ) ); - REQUIRE( here.ter_set( pos + point_north, t_floor ) ); - REQUIRE( here.ter_set( pos + point_west, t_wall ) ); + REQUIRE( here.ter_set( pos + point_south, ter_t_wall ) ); + REQUIRE( here.ter_set( pos + point_east, ter_t_floor ) ); + REQUIRE( here.ter_set( pos + point_north, ter_t_floor ) ); + REQUIRE( here.ter_set( pos + point_west, ter_t_wall ) ); THEN( "the wall should be connected as corner NE" ) { cata_tiles_test_helper::get_connect_values( pos, subtile, rotation, @@ -205,10 +209,10 @@ TEST_CASE( "walls_should_connect_to_walls_as_edges", "[multitile][connects]" ) // Edges WHEN( "connecting neighbour north and south" ) { - REQUIRE( here.ter_set( pos + point_south, t_wall ) ); - REQUIRE( here.ter_set( pos + point_east, t_floor ) ); - REQUIRE( here.ter_set( pos + point_north, t_wall ) ); - REQUIRE( here.ter_set( pos + point_west, t_floor ) ); + REQUIRE( here.ter_set( pos + point_south, ter_t_wall ) ); + REQUIRE( here.ter_set( pos + point_east, ter_t_floor ) ); + REQUIRE( here.ter_set( pos + point_north, ter_t_wall ) ); + REQUIRE( here.ter_set( pos + point_west, ter_t_floor ) ); THEN( "the wall should be connected as edge NS" ) { cata_tiles_test_helper::get_connect_values( pos, subtile, rotation, @@ -218,10 +222,10 @@ TEST_CASE( "walls_should_connect_to_walls_as_edges", "[multitile][connects]" ) } } WHEN( "connecting neighbour east and west" ) { - REQUIRE( here.ter_set( pos + point_south, t_floor ) ); - REQUIRE( here.ter_set( pos + point_east, t_wall ) ); - REQUIRE( here.ter_set( pos + point_north, t_floor ) ); - REQUIRE( here.ter_set( pos + point_west, t_wall ) ); + REQUIRE( here.ter_set( pos + point_south, ter_t_floor ) ); + REQUIRE( here.ter_set( pos + point_east, ter_t_wall ) ); + REQUIRE( here.ter_set( pos + point_north, ter_t_floor ) ); + REQUIRE( here.ter_set( pos + point_west, ter_t_wall ) ); THEN( "the wall should be connected as edge EW" ) { cata_tiles_test_helper::get_connect_values( pos, subtile, rotation, @@ -248,10 +252,10 @@ TEST_CASE( "walls_should_connect_to_walls_as_t-connections_and_fully", "[multiti // T connections WHEN( "connecting neighbour all but north" ) { - REQUIRE( here.ter_set( pos + point_south, t_wall ) ); - REQUIRE( here.ter_set( pos + point_east, t_wall ) ); - REQUIRE( here.ter_set( pos + point_north, t_floor ) ); - REQUIRE( here.ter_set( pos + point_west, t_wall ) ); + REQUIRE( here.ter_set( pos + point_south, ter_t_wall ) ); + REQUIRE( here.ter_set( pos + point_east, ter_t_wall ) ); + REQUIRE( here.ter_set( pos + point_north, ter_t_floor ) ); + REQUIRE( here.ter_set( pos + point_west, ter_t_wall ) ); THEN( "the wall should be connected as t-connection N" ) { cata_tiles_test_helper::get_connect_values( pos, subtile, rotation, @@ -261,10 +265,10 @@ TEST_CASE( "walls_should_connect_to_walls_as_t-connections_and_fully", "[multiti } } WHEN( "connecting neighbour all but west" ) { - REQUIRE( here.ter_set( pos + point_south, t_wall ) ); - REQUIRE( here.ter_set( pos + point_east, t_wall ) ); - REQUIRE( here.ter_set( pos + point_north, t_wall ) ); - REQUIRE( here.ter_set( pos + point_west, t_floor ) ); + REQUIRE( here.ter_set( pos + point_south, ter_t_wall ) ); + REQUIRE( here.ter_set( pos + point_east, ter_t_wall ) ); + REQUIRE( here.ter_set( pos + point_north, ter_t_wall ) ); + REQUIRE( here.ter_set( pos + point_west, ter_t_floor ) ); THEN( "the wall should be connected as t-connection W" ) { cata_tiles_test_helper::get_connect_values( pos, subtile, rotation, @@ -274,10 +278,10 @@ TEST_CASE( "walls_should_connect_to_walls_as_t-connections_and_fully", "[multiti } } WHEN( "connecting neighbour all but south" ) { - REQUIRE( here.ter_set( pos + point_south, t_floor ) ); - REQUIRE( here.ter_set( pos + point_east, t_wall ) ); - REQUIRE( here.ter_set( pos + point_north, t_wall ) ); - REQUIRE( here.ter_set( pos + point_west, t_wall ) ); + REQUIRE( here.ter_set( pos + point_south, ter_t_floor ) ); + REQUIRE( here.ter_set( pos + point_east, ter_t_wall ) ); + REQUIRE( here.ter_set( pos + point_north, ter_t_wall ) ); + REQUIRE( here.ter_set( pos + point_west, ter_t_wall ) ); THEN( "the wall should be connected as t-connection S" ) { cata_tiles_test_helper::get_connect_values( pos, subtile, rotation, @@ -287,10 +291,10 @@ TEST_CASE( "walls_should_connect_to_walls_as_t-connections_and_fully", "[multiti } } WHEN( "connecting neighbour all but east" ) { - REQUIRE( here.ter_set( pos + point_south, t_wall ) ); - REQUIRE( here.ter_set( pos + point_east, t_floor ) ); - REQUIRE( here.ter_set( pos + point_north, t_wall ) ); - REQUIRE( here.ter_set( pos + point_west, t_wall ) ); + REQUIRE( here.ter_set( pos + point_south, ter_t_wall ) ); + REQUIRE( here.ter_set( pos + point_east, ter_t_floor ) ); + REQUIRE( here.ter_set( pos + point_north, ter_t_wall ) ); + REQUIRE( here.ter_set( pos + point_west, ter_t_wall ) ); THEN( "the wall should be connected as t-connection E" ) { cata_tiles_test_helper::get_connect_values( pos, subtile, rotation, @@ -301,10 +305,10 @@ TEST_CASE( "walls_should_connect_to_walls_as_t-connections_and_fully", "[multiti } // All WHEN( "connecting neighbour all" ) { - REQUIRE( here.ter_set( pos + point_south, t_wall ) ); - REQUIRE( here.ter_set( pos + point_east, t_wall ) ); - REQUIRE( here.ter_set( pos + point_north, t_wall ) ); - REQUIRE( here.ter_set( pos + point_west, t_wall ) ); + REQUIRE( here.ter_set( pos + point_south, ter_t_wall ) ); + REQUIRE( here.ter_set( pos + point_east, ter_t_wall ) ); + REQUIRE( here.ter_set( pos + point_north, ter_t_wall ) ); + REQUIRE( here.ter_set( pos + point_west, ter_t_wall ) ); THEN( "the wall should be connected as center" ) { cata_tiles_test_helper::get_connect_values( pos, subtile, rotation, @@ -333,10 +337,10 @@ TEST_CASE( "windows_should_connect_to_walls_and_rotate_to_indoor_floor", "[multi // Edges WHEN( "connecting neighbours north and south, and rotate to west" ) { - REQUIRE( here.ter_set( pos + point_east, t_pavement ) ); - REQUIRE( here.ter_set( pos + point_south, t_wall ) ); - REQUIRE( here.ter_set( pos + point_west, t_floor ) ); - REQUIRE( here.ter_set( pos + point_north, t_wall ) ); + REQUIRE( here.ter_set( pos + point_east, ter_t_pavement ) ); + REQUIRE( here.ter_set( pos + point_south, ter_t_wall ) ); + REQUIRE( here.ter_set( pos + point_west, ter_t_floor ) ); + REQUIRE( here.ter_set( pos + point_north, ter_t_wall ) ); THEN( "the window should be connected as NS, with W positive" ) { cata_tiles_test_helper::get_connect_values( pos, subtile, rotation, @@ -346,10 +350,10 @@ TEST_CASE( "windows_should_connect_to_walls_and_rotate_to_indoor_floor", "[multi } } WHEN( "connecting neighbours east and west, and rotate to north" ) { - REQUIRE( here.ter_set( pos + point_east, t_wall ) ); - REQUIRE( here.ter_set( pos + point_south, t_pavement ) ); - REQUIRE( here.ter_set( pos + point_west, t_wall ) ); - REQUIRE( here.ter_set( pos + point_north, t_floor ) ); + REQUIRE( here.ter_set( pos + point_east, ter_t_wall ) ); + REQUIRE( here.ter_set( pos + point_south, ter_t_pavement ) ); + REQUIRE( here.ter_set( pos + point_west, ter_t_wall ) ); + REQUIRE( here.ter_set( pos + point_north, ter_t_floor ) ); THEN( "the window should be connected EW, with N positive" ) { cata_tiles_test_helper::get_connect_values( pos, subtile, rotation, @@ -359,10 +363,10 @@ TEST_CASE( "windows_should_connect_to_walls_and_rotate_to_indoor_floor", "[multi } } WHEN( "connecting neighbours north and south, and rotate to east" ) { - REQUIRE( here.ter_set( pos + point_east, t_floor ) ); - REQUIRE( here.ter_set( pos + point_south, t_wall ) ); - REQUIRE( here.ter_set( pos + point_west, t_pavement ) ); - REQUIRE( here.ter_set( pos + point_north, t_wall ) ); + REQUIRE( here.ter_set( pos + point_east, ter_t_floor ) ); + REQUIRE( here.ter_set( pos + point_south, ter_t_wall ) ); + REQUIRE( here.ter_set( pos + point_west, ter_t_pavement ) ); + REQUIRE( here.ter_set( pos + point_north, ter_t_wall ) ); THEN( "the window should be connected as NS, with E positive" ) { cata_tiles_test_helper::get_connect_values( pos, subtile, rotation, @@ -372,10 +376,10 @@ TEST_CASE( "windows_should_connect_to_walls_and_rotate_to_indoor_floor", "[multi } } WHEN( "connecting neighbours east and west, and rotate to south" ) { - REQUIRE( here.ter_set( pos + point_east, t_wall ) ); - REQUIRE( here.ter_set( pos + point_south, t_floor ) ); - REQUIRE( here.ter_set( pos + point_west, t_wall ) ); - REQUIRE( here.ter_set( pos + point_north, t_pavement ) ); + REQUIRE( here.ter_set( pos + point_east, ter_t_wall ) ); + REQUIRE( here.ter_set( pos + point_south, ter_t_floor ) ); + REQUIRE( here.ter_set( pos + point_west, ter_t_wall ) ); + REQUIRE( here.ter_set( pos + point_north, ter_t_pavement ) ); THEN( "the window should be connected as EW, with S positive" ) { cata_tiles_test_helper::get_connect_values( pos, subtile, rotation, @@ -386,10 +390,10 @@ TEST_CASE( "windows_should_connect_to_walls_and_rotate_to_indoor_floor", "[multi } WHEN( "connecting neighbours north and south, and rotate to east and west" ) { - REQUIRE( here.ter_set( pos + point_east, t_floor ) ); - REQUIRE( here.ter_set( pos + point_south, t_wall ) ); - REQUIRE( here.ter_set( pos + point_west, t_floor ) ); - REQUIRE( here.ter_set( pos + point_north, t_wall ) ); + REQUIRE( here.ter_set( pos + point_east, ter_t_floor ) ); + REQUIRE( here.ter_set( pos + point_south, ter_t_wall ) ); + REQUIRE( here.ter_set( pos + point_west, ter_t_floor ) ); + REQUIRE( here.ter_set( pos + point_north, ter_t_wall ) ); THEN( "the window should be connected as NS, with E and W negative" ) { cata_tiles_test_helper::get_connect_values( pos, subtile, rotation, @@ -399,10 +403,10 @@ TEST_CASE( "windows_should_connect_to_walls_and_rotate_to_indoor_floor", "[multi } } WHEN( "connecting neighbours east and west, and nothing to rotate to" ) { - REQUIRE( here.ter_set( pos + point_east, t_wall ) ); - REQUIRE( here.ter_set( pos + point_south, t_pavement ) ); - REQUIRE( here.ter_set( pos + point_west, t_wall ) ); - REQUIRE( here.ter_set( pos + point_north, t_pavement ) ); + REQUIRE( here.ter_set( pos + point_east, ter_t_wall ) ); + REQUIRE( here.ter_set( pos + point_south, ter_t_pavement ) ); + REQUIRE( here.ter_set( pos + point_west, ter_t_wall ) ); + REQUIRE( here.ter_set( pos + point_north, ter_t_pavement ) ); THEN( "the window should be connected as EW, with N and S negative" ) { cata_tiles_test_helper::get_connect_values( pos, subtile, rotation, @@ -412,10 +416,10 @@ TEST_CASE( "windows_should_connect_to_walls_and_rotate_to_indoor_floor", "[multi } } WHEN( "connecting neighbours north and south, and nothing to rotate to" ) { - REQUIRE( here.ter_set( pos + point_east, t_pavement ) ); - REQUIRE( here.ter_set( pos + point_south, t_wall ) ); - REQUIRE( here.ter_set( pos + point_west, t_pavement ) ); - REQUIRE( here.ter_set( pos + point_north, t_wall ) ); + REQUIRE( here.ter_set( pos + point_east, ter_t_pavement ) ); + REQUIRE( here.ter_set( pos + point_south, ter_t_wall ) ); + REQUIRE( here.ter_set( pos + point_west, ter_t_pavement ) ); + REQUIRE( here.ter_set( pos + point_north, ter_t_wall ) ); THEN( "the window should be connected as NS, with E and W negative" ) { cata_tiles_test_helper::get_connect_values( pos, subtile, rotation, @@ -425,10 +429,10 @@ TEST_CASE( "windows_should_connect_to_walls_and_rotate_to_indoor_floor", "[multi } } WHEN( "connecting neighbours east and west, and rotate to north and south" ) { - REQUIRE( here.ter_set( pos + point_east, t_wall ) ); - REQUIRE( here.ter_set( pos + point_south, t_floor ) ); - REQUIRE( here.ter_set( pos + point_west, t_wall ) ); - REQUIRE( here.ter_set( pos + point_north, t_floor ) ); + REQUIRE( here.ter_set( pos + point_east, ter_t_wall ) ); + REQUIRE( here.ter_set( pos + point_south, ter_t_floor ) ); + REQUIRE( here.ter_set( pos + point_west, ter_t_wall ) ); + REQUIRE( here.ter_set( pos + point_north, ter_t_floor ) ); THEN( "the window should be connected as EW, with N and S positive" ) { cata_tiles_test_helper::get_connect_values( pos, subtile, rotation, @@ -456,10 +460,10 @@ TEST_CASE( "unconnected_windows_rotate_to_indoor_floor", "[multitile][rotates]" // Unconnected WHEN( "nothing to rotate to" ) { - REQUIRE( here.ter_set( pos + point_east, t_pavement ) ); - REQUIRE( here.ter_set( pos + point_south, t_pavement ) ); - REQUIRE( here.ter_set( pos + point_west, t_pavement ) ); - REQUIRE( here.ter_set( pos + point_north, t_pavement ) ); + REQUIRE( here.ter_set( pos + point_east, ter_t_pavement ) ); + REQUIRE( here.ter_set( pos + point_south, ter_t_pavement ) ); + REQUIRE( here.ter_set( pos + point_west, ter_t_pavement ) ); + REQUIRE( here.ter_set( pos + point_north, ter_t_pavement ) ); THEN( "the window should be unconnected" ) { cata_tiles_test_helper::get_connect_values( pos, subtile, rotation, @@ -470,10 +474,10 @@ TEST_CASE( "unconnected_windows_rotate_to_indoor_floor", "[multitile][rotates]" } WHEN( "indoor floor to the north" ) { - REQUIRE( here.ter_set( pos + point_east, t_pavement ) ); - REQUIRE( here.ter_set( pos + point_south, t_pavement ) ); - REQUIRE( here.ter_set( pos + point_west, t_pavement ) ); - REQUIRE( here.ter_set( pos + point_north, t_floor ) ); + REQUIRE( here.ter_set( pos + point_east, ter_t_pavement ) ); + REQUIRE( here.ter_set( pos + point_south, ter_t_pavement ) ); + REQUIRE( here.ter_set( pos + point_west, ter_t_pavement ) ); + REQUIRE( here.ter_set( pos + point_north, ter_t_floor ) ); THEN( "the window rotate to the north" ) { cata_tiles_test_helper::get_connect_values( pos, subtile, rotation, @@ -483,10 +487,10 @@ TEST_CASE( "unconnected_windows_rotate_to_indoor_floor", "[multitile][rotates]" } } WHEN( "indoor floor to the east" ) { - REQUIRE( here.ter_set( pos + point_east, t_floor ) ); - REQUIRE( here.ter_set( pos + point_south, t_pavement ) ); - REQUIRE( here.ter_set( pos + point_west, t_pavement ) ); - REQUIRE( here.ter_set( pos + point_north, t_pavement ) ); + REQUIRE( here.ter_set( pos + point_east, ter_t_floor ) ); + REQUIRE( here.ter_set( pos + point_south, ter_t_pavement ) ); + REQUIRE( here.ter_set( pos + point_west, ter_t_pavement ) ); + REQUIRE( here.ter_set( pos + point_north, ter_t_pavement ) ); THEN( "the window rotate to the east" ) { cata_tiles_test_helper::get_connect_values( pos, subtile, rotation, @@ -496,10 +500,10 @@ TEST_CASE( "unconnected_windows_rotate_to_indoor_floor", "[multitile][rotates]" } } WHEN( "indoor floor to the south" ) { - REQUIRE( here.ter_set( pos + point_east, t_pavement ) ); - REQUIRE( here.ter_set( pos + point_south, t_floor ) ); - REQUIRE( here.ter_set( pos + point_west, t_pavement ) ); - REQUIRE( here.ter_set( pos + point_north, t_pavement ) ); + REQUIRE( here.ter_set( pos + point_east, ter_t_pavement ) ); + REQUIRE( here.ter_set( pos + point_south, ter_t_floor ) ); + REQUIRE( here.ter_set( pos + point_west, ter_t_pavement ) ); + REQUIRE( here.ter_set( pos + point_north, ter_t_pavement ) ); THEN( "the window rotate to the south" ) { cata_tiles_test_helper::get_connect_values( pos, subtile, rotation, @@ -509,10 +513,10 @@ TEST_CASE( "unconnected_windows_rotate_to_indoor_floor", "[multitile][rotates]" } } WHEN( "indoor floor to the west" ) { - REQUIRE( here.ter_set( pos + point_east, t_pavement ) ); - REQUIRE( here.ter_set( pos + point_south, t_pavement ) ); - REQUIRE( here.ter_set( pos + point_west, t_floor ) ); - REQUIRE( here.ter_set( pos + point_north, t_pavement ) ); + REQUIRE( here.ter_set( pos + point_east, ter_t_pavement ) ); + REQUIRE( here.ter_set( pos + point_south, ter_t_pavement ) ); + REQUIRE( here.ter_set( pos + point_west, ter_t_floor ) ); + REQUIRE( here.ter_set( pos + point_north, ter_t_pavement ) ); THEN( "the window rotate to the west" ) { cata_tiles_test_helper::get_connect_values( pos, subtile, rotation, diff --git a/tests/eoc_test.cpp b/tests/eoc_test.cpp index 5c93659b10687..fce034c121eb5 100644 --- a/tests/eoc_test.cpp +++ b/tests/eoc_test.cpp @@ -137,6 +137,9 @@ static const skill_id skill_survival( "survival" ); static const spell_id spell_test_eoc_spell( "test_eoc_spell" ); +static const ter_str_id ter_t_dirt( "t_dirt" ); +static const ter_str_id ter_t_grass( "t_grass" ); + static const trait_id trait_process_mutation( "process_mutation" ); static const trait_id trait_process_mutation_two( "process_mutation_two" ); @@ -284,19 +287,19 @@ TEST_CASE( "EOC_transform_radius", "[eoc][timed_event]" ) clear_map(); tripoint_abs_ms const start = get_avatar().get_location(); dialogue newDialog( get_talker_for( get_avatar() ), nullptr ); - check_ter_in_radius( start, eoc_range, t_grass ); + check_ter_in_radius( start, eoc_range, ter_t_grass ); effect_on_condition_EOC_TEST_TRANSFORM_RADIUS->activate( newDialog ); - check_ter_in_radius( start, eoc_range, t_dirt ); + check_ter_in_radius( start, eoc_range, ter_t_dirt ); g->place_player_overmap( project_to( start ) + point{ 60, 60 } ); REQUIRE( !get_map().inbounds( start ) ); calendar::turn += delay - 1_seconds; get_timed_events().process(); - check_ter_in_radius( start, eoc_range, t_dirt ); + check_ter_in_radius( start, eoc_range, ter_t_dirt ); calendar::turn += 2_seconds; get_timed_events().process(); - check_ter_in_radius( start, eoc_range, t_grass ); + check_ter_in_radius( start, eoc_range, ter_t_grass ); } TEST_CASE( "EOC_transform_line", "[eoc][timed_event]" ) @@ -313,9 +316,9 @@ TEST_CASE( "EOC_transform_line", "[eoc][timed_event]" ) tripoint_abs_ms const start = get_avatar().get_location(); tripoint_abs_ms const end = npc.get_location(); dialogue newDialog( get_talker_for( get_avatar() ), get_talker_for( npc ) ); - check_ter_in_line( start, end, t_grass ); + check_ter_in_line( start, end, ter_t_grass ); effect_on_condition_EOC_TEST_TRANSFORM_LINE->activate( newDialog ); - check_ter_in_line( start, end, t_dirt ); + check_ter_in_line( start, end, ter_t_dirt ); } TEST_CASE( "EOC_activity_finish", "[eoc][timed_event]" ) diff --git a/tests/field_test.cpp b/tests/field_test.cpp index 93884b15243eb..07783151ef9eb 100644 --- a/tests/field_test.cpp +++ b/tests/field_test.cpp @@ -23,6 +23,7 @@ static const efftype_id effect_test_rash( "test_rash" ); static const field_type_str_id field_fd_acid( "fd_acid" ); static const field_type_str_id field_fd_test( "fd_test" ); +static const ter_str_id ter_t_open_air( "t_open_air" ); static const ter_str_id ter_t_tree_walnut( "t_tree_walnut" ); static int count_fields( const field_type_str_id &field_type ) @@ -183,7 +184,7 @@ TEST_CASE( "fd_acid_falls_down", "[field]" ) m.process_fields(); // remove floor under the acid field - m.ter_set( p, t_open_air ); + m.ter_set( p, ter_t_open_air ); m.build_floor_cache( 0 ); REQUIRE( m.valid_move( p, p + tripoint_below ) ); diff --git a/tests/food_fun_for_test.cpp b/tests/food_fun_for_test.cpp index 1b9474846fe5f..1e94b4a5ac1d6 100644 --- a/tests/food_fun_for_test.cpp +++ b/tests/food_fun_for_test.cpp @@ -367,13 +367,16 @@ TEST_CASE( "fun_for_food_eaten_too_often", "[fun_for][food][monotony]" ) std::pair actual_fun; // A big box of tasty toast-ems - item toastem( "toastem", calendar::turn, 10 ); + item toastem( "toastem_test", calendar::turn, 10 ); REQUIRE( toastem.is_comestible() ); // Base fun value and monotony penalty for toast-em int toastem_fun = toastem.get_comestible_fun(); int toastem_penalty = toastem.get_comestible()->monotony_penalty; + REQUIRE( toastem_fun > 0 ); + REQUIRE( toastem_penalty > 0 ); + // Will do 2 rounds of penalty testing, so base fun needs to be at least 2x that REQUIRE( toastem_fun > 2 * toastem_penalty ); diff --git a/tests/gates_test.cpp b/tests/gates_test.cpp index 9e11b1ddfa8a5..ad774eb5905f5 100644 --- a/tests/gates_test.cpp +++ b/tests/gates_test.cpp @@ -10,6 +10,12 @@ #include "sounds.h" #include "type_id.h" +static const ter_str_id ter_t_door_c( "t_door_c" ); +static const ter_str_id ter_t_door_locked( "t_door_locked" ); +static const ter_str_id ter_t_door_o( "t_door_o" ); +static const ter_str_id ter_t_window_no_curtains( "t_window_no_curtains" ); +static const ter_str_id ter_t_window_no_curtains_open( "t_window_no_curtains_open" ); + TEST_CASE( "doors_should_be_able_to_open_and_close", "[gates]" ) { map &here = get_map(); @@ -19,25 +25,25 @@ TEST_CASE( "doors_should_be_able_to_open_and_close", "[gates]" ) WHEN( "the door is unlocked" ) { // create closed door on tile next to player - REQUIRE( here.ter_set( pos, t_door_c ) ); - REQUIRE( here.ter( pos ).obj().id == t_door_c->id ); + REQUIRE( here.ter_set( pos, ter_t_door_c ) ); + REQUIRE( here.ter( pos ).obj().id == ter_t_door_c->id ); THEN( "the door should be able to open and close" ) { CHECK( here.open_door( get_avatar(), pos, true, false ) ); - CHECK( here.ter( pos ).obj().id == t_door_o->id ); + CHECK( here.ter( pos ).obj().id == ter_t_door_o->id ); CHECK( here.close_door( pos, true, false ) ); - CHECK( here.ter( pos ).obj().id == t_door_c->id ); + CHECK( here.ter( pos ).obj().id == ter_t_door_c->id ); } } WHEN( "the door is locked" ) { // create locked door on tile next to player - REQUIRE( here.ter_set( pos, t_door_locked ) ); - REQUIRE( here.ter( pos ).obj().id == t_door_locked->id ); + REQUIRE( here.ter_set( pos, ter_t_door_locked ) ); + REQUIRE( here.ter( pos ).obj().id == ter_t_door_locked->id ); THEN( "the door should not be able to open" ) { CHECK_FALSE( here.close_door( pos, true, false ) ); - CHECK( here.ter( pos ).obj().id == t_door_locked->id ); + CHECK( here.ter( pos ).obj().id == ter_t_door_locked->id ); } } } @@ -50,19 +56,19 @@ TEST_CASE( "windows_should_be_able_to_open_and_close", "[gates]" ) tripoint pos = get_avatar().pos() + point_east; // create closed window on tile next to player - REQUIRE( here.ter_set( pos, t_window_no_curtains ) ); - REQUIRE( here.ter( pos ).obj().id == t_window_no_curtains->id ); + REQUIRE( here.ter_set( pos, ter_t_window_no_curtains ) ); + REQUIRE( here.ter( pos ).obj().id == ter_t_window_no_curtains->id ); WHEN( "the window is opened from the inside" ) { THEN( "the window should be able to open" ) { CHECK( here.open_door( get_avatar(), pos, true, false ) ); - CHECK( here.ter( pos ).obj().id == t_window_no_curtains_open->id ); + CHECK( here.ter( pos ).obj().id == ter_t_window_no_curtains_open->id ); } } WHEN( "the window is opened from the outside" ) { THEN( "the window should not be able to open" ) { CHECK_FALSE( here.close_door( pos, false, false ) ); - CHECK( here.ter( pos ).obj().id == t_window_no_curtains->id ); + CHECK( here.ter( pos ).obj().id == ter_t_window_no_curtains->id ); } } } @@ -80,56 +86,56 @@ TEST_CASE( "doors_and_windows_should_make_whoosh_sound", "[gates]" ) tripoint pos = get_avatar().pos() + point_east; WHEN( "the door is opened" ) { - REQUIRE( here.ter_set( pos, t_door_c ) ); - REQUIRE( here.ter( pos ).obj().id == t_door_c->id ); + REQUIRE( here.ter_set( pos, ter_t_door_c ) ); + REQUIRE( here.ter( pos ).obj().id == ter_t_door_c->id ); // make sure there is no sounds before action REQUIRE( sounds::get_monster_sounds().first.empty() ); REQUIRE( here.open_door( get_avatar(), pos, true, false ) ); - REQUIRE( here.ter( pos ).obj().id == t_door_o->id ); + REQUIRE( here.ter( pos ).obj().id == ter_t_door_o->id ); THEN( "the door should make a swish sound" ) { CHECK_FALSE( sounds::get_monster_sounds().first.empty() ); } } WHEN( "the door is closed" ) { - REQUIRE( here.ter_set( pos, t_door_o ) ); - REQUIRE( here.ter( pos ).obj().id == t_door_o->id ); + REQUIRE( here.ter_set( pos, ter_t_door_o ) ); + REQUIRE( here.ter( pos ).obj().id == ter_t_door_o->id ); // make sure there is no sounds before action REQUIRE( sounds::get_monster_sounds().first.empty() ); REQUIRE( here.close_door( pos, true, false ) ); - REQUIRE( here.ter( pos ).obj().id == t_door_c->id ); + REQUIRE( here.ter( pos ).obj().id == ter_t_door_c->id ); THEN( "the door should make a swish sound" ) { CHECK_FALSE( sounds::get_monster_sounds().first.empty() ); } } WHEN( "the window is opened" ) { - REQUIRE( here.ter_set( pos, t_window_no_curtains ) ); - REQUIRE( here.ter( pos ).obj().id == t_window_no_curtains->id ); + REQUIRE( here.ter_set( pos, ter_t_window_no_curtains ) ); + REQUIRE( here.ter( pos ).obj().id == ter_t_window_no_curtains->id ); // make sure there is no sounds before action REQUIRE( sounds::get_monster_sounds().first.empty() ); REQUIRE( here.open_door( get_avatar(), pos, true, false ) ); - REQUIRE( here.ter( pos ).obj().id == t_window_no_curtains_open->id ); + REQUIRE( here.ter( pos ).obj().id == ter_t_window_no_curtains_open->id ); THEN( "the window should make a swish sound" ) { CHECK_FALSE( sounds::get_monster_sounds().first.empty() ); } } WHEN( "the window is closed" ) { - REQUIRE( here.ter_set( pos, t_window_no_curtains_open ) ); - REQUIRE( here.ter( pos ).obj().id == t_window_no_curtains_open->id ); + REQUIRE( here.ter_set( pos, ter_t_window_no_curtains_open ) ); + REQUIRE( here.ter( pos ).obj().id == ter_t_window_no_curtains_open->id ); // make sure there is no sounds before action REQUIRE( sounds::get_monster_sounds().first.empty() ); REQUIRE( here.close_door( pos, true, false ) ); - REQUIRE( here.ter( pos ).obj().id == t_window_no_curtains->id ); + REQUIRE( here.ter( pos ).obj().id == ter_t_window_no_curtains->id ); THEN( "the window should make a swish sound" ) { CHECK_FALSE( sounds::get_monster_sounds().first.empty() ); @@ -156,8 +162,8 @@ TEST_CASE( "character_should_lose_moves_when_opening_or_closing_doors_or_windows they.set_moves( 0 ); WHEN( "avatar opens door" ) { - REQUIRE( here.ter_set( pos, t_door_c ) ); - REQUIRE( here.ter( pos ).obj().id == t_door_c->id ); + REQUIRE( here.ter_set( pos, ter_t_door_c ) ); + REQUIRE( here.ter( pos ).obj().id == ter_t_door_c->id ); REQUIRE( avatar_action::move( they, here, tripoint_east ) ); @@ -166,8 +172,8 @@ TEST_CASE( "character_should_lose_moves_when_opening_or_closing_doors_or_windows } } WHEN( "avatar fails to open locked door" ) { - REQUIRE( here.ter_set( pos, t_door_locked ) ); - REQUIRE( here.ter( pos ).obj().id == t_door_locked->id ); + REQUIRE( here.ter_set( pos, ter_t_door_locked ) ); + REQUIRE( here.ter( pos ).obj().id == ter_t_door_locked->id ); REQUIRE_FALSE( avatar_action::move( they, here, tripoint_east ) ); @@ -179,8 +185,8 @@ TEST_CASE( "character_should_lose_moves_when_opening_or_closing_doors_or_windows REQUIRE( here.is_outside( pos ) ); WHEN( "avatar fails to open window" ) { - REQUIRE( here.ter_set( pos, t_window_no_curtains ) ); - REQUIRE( here.ter( pos ).obj().id == t_window_no_curtains->id ); + REQUIRE( here.ter_set( pos, ter_t_window_no_curtains ) ); + REQUIRE( here.ter( pos ).obj().id == ter_t_window_no_curtains->id ); REQUIRE_FALSE( avatar_action::move( they, here, tripoint_east ) ); @@ -218,8 +224,8 @@ TEST_CASE( "character_should_lose_moves_when_opening_or_closing_doors_or_windows REQUIRE_FALSE( here.is_outside( pos ) ); WHEN( "avatar opens window" ) { - REQUIRE( here.ter_set( pos, t_window_no_curtains ) ); - REQUIRE( here.ter( pos ).obj().id == t_window_no_curtains->id ); + REQUIRE( here.ter_set( pos, ter_t_window_no_curtains ) ); + REQUIRE( here.ter( pos ).obj().id == ter_t_window_no_curtains->id ); REQUIRE( avatar_action::move( they, here, tripoint_east ) ); diff --git a/tests/ground_destroy_test.cpp b/tests/ground_destroy_test.cpp index d272c99685973..d42134302416e 100644 --- a/tests/ground_destroy_test.cpp +++ b/tests/ground_destroy_test.cpp @@ -18,7 +18,7 @@ TEST_CASE( "pavement_destroy", "[.]" ) { const ter_id flat_roof_id = ter_id( "t_flat_roof" ); - REQUIRE( flat_roof_id != t_null ); + REQUIRE( flat_roof_id != ter_str_id::NULL_ID() ); clear_map_and_put_player_underground(); map &here = get_map(); @@ -41,7 +41,7 @@ TEST_CASE( "pavement_destroy", "[.]" ) TEST_CASE( "explosion_on_ground", "[.]" ) { ter_id flat_roof_id = ter_id( "t_flat_roof" ); - REQUIRE( flat_roof_id != t_null ); + REQUIRE( flat_roof_id != ter_str_id::NULL_ID() ); clear_map_and_put_player_underground(); std::vector test_terrain_id = { @@ -88,10 +88,10 @@ TEST_CASE( "explosion_on_floor_with_rock_floor_basement", "[.]" ) ter_id rock_floor_id = ter_id( "t_rock_floor" ); ter_id open_air_id = ter_id( "t_open_air" ); - REQUIRE( flat_roof_id != t_null ); - REQUIRE( floor_id != t_null ); - REQUIRE( rock_floor_id != t_null ); - REQUIRE( open_air_id != t_null ); + REQUIRE( flat_roof_id != ter_str_id::NULL_ID() ); + REQUIRE( floor_id != ter_str_id::NULL_ID() ); + REQUIRE( rock_floor_id != ter_str_id::NULL_ID() ); + REQUIRE( open_air_id != ter_str_id::NULL_ID() ); clear_map_and_put_player_underground(); @@ -145,10 +145,10 @@ TEST_CASE( "collapse_checks", "[.]" ) const ter_id wall_id = ter_id( "t_wall" ); const ter_id open_air_id = ter_id( "t_open_air" ); - REQUIRE( floor_id != t_null ); - REQUIRE( dirt_id != t_null ); - REQUIRE( wall_id != t_null ); - REQUIRE( open_air_id != t_null ); + REQUIRE( floor_id != ter_str_id::NULL_ID() ); + REQUIRE( dirt_id != ter_str_id::NULL_ID() ); + REQUIRE( wall_id != ter_str_id::NULL_ID() ); + REQUIRE( open_air_id != ter_str_id::NULL_ID() ); clear_map_and_put_player_underground(); @@ -208,7 +208,7 @@ TEST_CASE( "collapse_checks", "[.]" ) } const ter_id t_id = here.ter( pt ); tile_count += 1; - if( t_id == t_open_air ) { + if( t_id == open_air_id ) { open_air_count += 1; if( corners.find( pt ) != corners.end() ) { no_wall_count += 1; diff --git a/tests/map_bash_test.cpp b/tests/map_bash_test.cpp index 74c5e2b19442a..da013eb8dcf48 100644 --- a/tests/map_bash_test.cpp +++ b/tests/map_bash_test.cpp @@ -9,6 +9,7 @@ static const furn_str_id furn_test_f_bash_persist( "test_f_bash_persist" ); static const furn_str_id furn_test_f_eoc( "test_f_eoc" ); +static const ter_str_id ter_t_floor( "t_floor" ); static const ter_str_id ter_test_t_bash_persist( "test_t_bash_persist" ); static const ter_str_id ter_test_t_pit_shallow( "test_t_pit_shallow" ); @@ -46,7 +47,7 @@ static void test_bash_set( const bash_test_set &set ) constexpr int max_tries = 999; for( const furn_id &furn : set.tested_furn ) { INFO( string_format( "%s bashing %s", test.id, furn.id().str() ) ); - here.ter_set( test_pt, t_floor ); + here.ter_set( test_pt, ter_t_floor ); here.furn_set( test_pt, furn ); int tries = 0; while( here.furn( test_pt ) == furn && tries < max_tries ) { diff --git a/tests/map_helpers.cpp b/tests/map_helpers.cpp index 88cb0ff27160c..770409134cd43 100644 --- a/tests/map_helpers.cpp +++ b/tests/map_helpers.cpp @@ -28,6 +28,10 @@ #include "submap.h" #include "type_id.h" +static const ter_str_id ter_t_grass( "t_grass" ); +static const ter_str_id ter_t_open_air( "t_open_air" ); +static const ter_str_id ter_t_rock( "t_rock" ); + // Remove all vehicles from the map void clear_vehicles( map *target ) { @@ -55,7 +59,7 @@ void wipe_map_terrain( map *target ) map &here = target ? *target : get_map(); const int mapsize = here.getmapsize() * SEEX; for( int z = -1; z <= OVERMAP_HEIGHT; ++z ) { - ter_id terrain = z == 0 ? t_grass : z < 0 ? t_rock : t_open_air; + ter_id terrain = z == 0 ? ter_t_grass : z < 0 ? ter_t_rock : ter_t_open_air; for( int x = 0; x < mapsize; ++x ) { for( int y = 0; y < mapsize; ++y ) { here.set( { x, y, z}, terrain, f_null ); @@ -190,9 +194,9 @@ void build_water_test_map( const ter_id &surface, const ter_id &mid, const ter_i } else if( p.z == z_bottom ) { here.ter_set( p, bottom ); } else if( p.z < z_bottom ) { - here.ter_set( p, t_rock ); + here.ter_set( p, ter_t_rock ); } else if( p.z > z_surface ) { - here.ter_set( p, t_open_air ); + here.ter_set( p, ter_t_open_air ); } } diff --git a/tests/monster_vision_test.cpp b/tests/monster_vision_test.cpp index ed073d02bf8d5..297c4fd9cb98f 100644 --- a/tests/monster_vision_test.cpp +++ b/tests/monster_vision_test.cpp @@ -8,12 +8,14 @@ #include "monster.h" #include "options_helpers.h" +static const ter_str_id ter_t_floor( "t_floor" ); + struct tripoint; static monster &spawn_and_clear( const tripoint &pos, bool set_floor ) { if( set_floor ) { - get_map().set( pos, t_floor, f_null ); + get_map().set( pos, ter_t_floor, f_null ); } return spawn_test_monster( "mon_zombie", pos ); } diff --git a/tests/move_cost_test.cpp b/tests/move_cost_test.cpp index 52d9a5d661a6e..194442974ef08 100644 --- a/tests/move_cost_test.cpp +++ b/tests/move_cost_test.cpp @@ -34,6 +34,9 @@ static const move_mode_id move_mode_prone( "prone" ); static const move_mode_id move_mode_run( "run" ); static const move_mode_id move_mode_walk( "walk" ); +static const ter_str_id ter_t_grass( "t_grass" ); +static const ter_str_id ter_t_pavement( "t_pavement" ); + static const trait_id trait_HOOVES( "HOOVES" ); static const trait_id trait_LEG_TENTACLES( "LEG_TENTACLES" ); static const trait_id trait_PADDED_FEET( "PADDED_FEET" ); @@ -99,13 +102,13 @@ TEST_CASE( "footwear_may_affect_movement_cost", "[move_cost][shoes]" ) REQUIRE( ava.get_modifier( character_modifier_limb_run_cost_mod ) == Approx( 1.11696 ) ); WHEN( "on pavement and running" ) { ava.set_movement_mode( move_mode_run ); - here.ter_set( ava.pos(), t_pavement ); + here.ter_set( ava.pos(), ter_t_pavement ); THEN( "much faster than sneakers" ) { CHECK( ava.run_cost( 100 ) == 27 ); } } WHEN( "on grass" ) { - here.ter_set( ava.pos(), t_grass ); + here.ter_set( ava.pos(), ter_t_grass ); THEN( "much slower than sneakers" ) { CHECK( ava.run_cost( 100 ) == 167 ); } @@ -119,13 +122,13 @@ TEST_CASE( "footwear_may_affect_movement_cost", "[move_cost][shoes]" ) REQUIRE( ava.get_modifier( character_modifier_limb_run_cost_mod ) == Approx( 1.11696 ) ); WHEN( "on pavement and running" ) { ava.set_movement_mode( move_mode_run ); - here.ter_set( ava.pos(), t_pavement ); + here.ter_set( ava.pos(), ter_t_pavement ); THEN( "faster than sneakers" ) { CHECK( ava.run_cost( 100 ) == 39 ); } } WHEN( "on grass" ) { - here.ter_set( ava.pos(), t_grass ); + here.ter_set( ava.pos(), ter_t_grass ); THEN( "slower than sneakers" ) { CHECK( ava.run_cost( 100 ) == 145 ); } @@ -139,13 +142,13 @@ TEST_CASE( "footwear_may_affect_movement_cost", "[move_cost][shoes]" ) REQUIRE( ava.get_modifier( character_modifier_limb_run_cost_mod ) == Approx( 1.0 ) ); WHEN( "on pavement and running" ) { ava.set_movement_mode( move_mode_run ); - here.ter_set( ava.pos(), t_pavement ); + here.ter_set( ava.pos(), ter_t_pavement ); THEN( "slightly faster than sneakers" ) { CHECK( ava.run_cost( 100 ) == 42 ); } } WHEN( "on grass" ) { - here.ter_set( ava.pos(), t_grass ); + here.ter_set( ava.pos(), ter_t_grass ); THEN( "slightly slower than sneakers" ) { CHECK( ava.run_cost( 100 ) == 110 ); } diff --git a/tests/mutation_test.cpp b/tests/mutation_test.cpp index ce43b64edad12..ebfabb5105fd3 100644 --- a/tests/mutation_test.cpp +++ b/tests/mutation_test.cpp @@ -24,9 +24,16 @@ static const mutation_category_id mutation_category_LUPINE( "LUPINE" ); static const mutation_category_id mutation_category_MOUSE( "MOUSE" ); static const mutation_category_id mutation_category_RAPTOR( "RAPTOR" ); static const mutation_category_id mutation_category_REMOVAL_TEST( "REMOVAL_TEST" ); +static const mutation_category_id mutation_category_TROGLOBITE( "TROGLOBITE" ); +static const trait_id trait_EAGLEEYED( "EAGLEEYED" ); +static const trait_id trait_FELINE_EARS( "FELINE_EARS" ); static const trait_id trait_GOURMAND( "GOURMAND" ); +static const trait_id trait_MYOPIC( "MYOPIC" ); +static const trait_id trait_QUICK( "QUICK" ); static const trait_id trait_SMELLY( "SMELLY" ); +static const trait_id trait_STR_UP( "STR_UP" ); +static const trait_id trait_STR_UP_2( "STR_UP_2" ); static const trait_id trait_TEST_OVERMAP_SIGHT_5( "TEST_OVERMAP_SIGHT_5" ); static const trait_id trait_TEST_OVERMAP_SIGHT_MINUS_10( "TEST_OVERMAP_SIGHT_MINUS_10" ); static const trait_id trait_TEST_REMOVAL_0( "TEST_REMOVAL_0" ); @@ -37,10 +44,8 @@ static const trait_id trait_TEST_TRIGGER_2_active( "TEST_TRIGGER_2_active" ); static const trait_id trait_TEST_TRIGGER_active( "TEST_TRIGGER_active" ); static const trait_id trait_UGLY( "UGLY" ); -static const vitamin_id vitamin_instability( "instability" ); static const vitamin_id vitamin_mutagen( "mutagen" ); static const vitamin_id vitamin_mutagen_human( "mutagen_human" ); -static const vitamin_id vitamin_mutagen_test( "mutagen_test" ); static const vitamin_id vitamin_mutagen_test_removal( "mutagen_test_removal" ); static std::string get_mutations_as_string( const Character &you ); @@ -563,70 +568,129 @@ TEST_CASE( "All_valid_mutations_can_be_purified", "[mutations][purifier]" ) } } -//The chance of a mutation being bad is a function of instability, see -//Character::roll_bad_mutation. This can't be easily tested on in-game -//mutations, because exceptions exist - e.g., you can roll a good mutation, but -//end up mutating a bad one, because the bad mutation is a prerequisite for the one -//you actually rolled. -//For this reason, this tests on an artificial category that doesn't -//mix good and bad mutations within trees. Additionally, it doesn't contain -//neutral mutations, because those are always allowed. -//This also incidentally tests that, given available mutations and enough mutagen, -//Character::mutate always succeeds to give exactly one mutation. +// Your odds of getting a good or bad mutation depend on what mutations you have and what tree you're in. +// You are given an integer that is first multiplied by 0.5 and then divided by the total non-bad mutations in the tree. +// For example if you mutate into Alpha, that tree has 21 mutations (as of 3/14/2024) that aren't bad. +// Troglobite has 28 mutations that aren't bad. (as of 3/4/2024). +// Thus, for all things equal, Alpha gets more bad mutations per good mutation than Trog, +// but since Trog gets more good muts total it has more chances to get bad mutations. +// The aforementioned "integer" is increased from 0 by 1 for each non-bad mutation you have. +// Mutations you have are counted as two if they don't belong to the tree you're mutating into. +// Starting traits are never counted, and bad mutations are never counted. Only "valid" (mutable) mutations count. +// This test case compares increasing instability in both Alpha and Trog as more mutations are added. +// Given that Alpha and Trog share some mutations but not all, they should either increase instability at the same or different rates. +// This test then also checks and makes sure that Alpha gets more bad mutations than Trog given the same total instability in each. +// After that it checks to make sure each tree gets more bad mutations than before after increasing effective instability by 4x. + TEST_CASE( "Chance_of_bad_mutations_vs_instability", "[mutations][instability]" ) { Character &dummy = get_player_character(); + clear_avatar(); - static const std::vector> bad_chance_by_inst = { - {0, 0.0f}, - {500, 0.0f}, - {1000, 0.062f}, - {1500, 0.268f}, - {2000, 0.386f}, - {2500, 0.464f}, - {3000, 0.521f}, - {4000, 0.598f}, - {5000, 0.649f}, - {6000, 0.686f}, - {8000, 0.737f} - }; - - const int tries = 1000; - const int muts_per_try = 5; - const float margin = 0.05f; - - for( const std::pair &ilevel : bad_chance_by_inst ) { - int bad = 0; - for( int i = 0; i < tries; i++ ) { - clear_avatar(); - dummy.vitamin_set( vitamin_mutagen_test, 10000 ); - for( int ii = 0; ii < muts_per_try; ii++ ) { - dummy.vitamin_set( vitamin_instability, ilevel.first ); - dummy.mutate( 0, true ); - } + REQUIRE( dummy.get_instability_per_category( mutation_category_ALPHA ) == 0 ); + REQUIRE( dummy.get_instability_per_category( mutation_category_TROGLOBITE ) == 0 ); - std::vector muts = dummy.get_mutations(); - REQUIRE( muts.size() == static_cast( muts_per_try ) ); - for( const trait_id &m : muts ) { - REQUIRE( m.obj().points != 0 ); - if( m.obj().points < 0 ) { - bad += 1; - } - } + + WHEN( "character mutates Strong, a mutation belonging to both Alpha and Troglobite" ) { + dummy.set_mutation( trait_STR_UP ); + THEN( "Both Alpha and Troglobite see their instability increase by 1" ) { + CHECK( dummy.get_instability_per_category( mutation_category_ALPHA ) == 1 ); + CHECK( dummy.get_instability_per_category( mutation_category_TROGLOBITE ) == 1 ); + } + } + + WHEN( "they then mutate Very Strong, which requires Strong and also belongs to both trees" ) { + dummy.set_mutation( trait_STR_UP_2 ); + THEN( "Both Alpha and Troglobite see their instability increase by 1 more (2 total)" ) { + CHECK( dummy.get_instability_per_category( mutation_category_ALPHA ) == 2 ); + CHECK( dummy.get_instability_per_category( mutation_category_TROGLOBITE ) == 2 ); + } + } + + WHEN( "they then mutate Quick, which belongs to Troglobite but not Alpha" ) { + dummy.set_mutation( trait_STR_UP_2 ); + dummy.set_mutation( trait_QUICK ); + THEN( "Alpha increases instability by 2 and Troglobite increases by 1" ) { + CHECK( dummy.get_instability_per_category( mutation_category_ALPHA ) == 4 ); + CHECK( dummy.get_instability_per_category( mutation_category_TROGLOBITE ) == 3 ); + } + } + + WHEN( "The character has Quick as a starting trait instead of a mutation" ) { + dummy.set_mutation( trait_STR_UP_2 ); + dummy.toggle_trait( trait_QUICK ); + REQUIRE( dummy.has_trait( trait_QUICK ) ); + THEN( "Neither Alpha or Troglobite have their instability increased" ) { + CHECK( dummy.get_instability_per_category( mutation_category_ALPHA ) == 2 ); + CHECK( dummy.get_instability_per_category( mutation_category_TROGLOBITE ) == 2 ); + } + } + + WHEN( "The character mutates Near Sighted, which is a \"bad\" mutation" ) { + dummy.set_mutation( trait_STR_UP_2 ); + dummy.set_mutation( trait_MYOPIC ); + THEN( "They do not gain instability since only 0+ point mutations increase that" ) { + CHECK( dummy.get_instability_per_category( mutation_category_ALPHA ) == 2 ); + CHECK( dummy.get_instability_per_category( mutation_category_TROGLOBITE ) == 2 ); } + } - INFO( "Current instability: " << ilevel.first ); - if( ilevel.second == 0.0f ) { - CHECK( bad == 0 ); - } else { - float lower = ilevel.second - margin; - float upper = ilevel.second + margin; - float frac_bad = static_cast( bad ) / ( tries * muts_per_try ); + const int tries = 10000; + int trogBads = 0; + int alphaBads = 0; - CHECK( frac_bad > lower ); - CHECK( frac_bad < upper ); + clear_avatar(); + dummy.set_mutation( trait_STR_UP_2 ); + REQUIRE( dummy.get_instability_per_category( mutation_category_ALPHA ) == 2 ); + REQUIRE( dummy.get_instability_per_category( mutation_category_TROGLOBITE ) == 2 ); + + // 10k trials, compare the number of successes of bad mutations. + // As of 3/4/2024, Alpha has 21 non-bad mutations and Trog has 28. + // Given that effective instability is currently 2, Alpha should see avg. 475 badmuts and trog 357 avg. + // The odds of Trog rolling well enough to "win" are effectively zero if roll_bad_mutation() works correctly. + // roll_bad_mutation does not actually give a bad mutation; it is called by the primary mutate function. + for( int i = 0; i < tries; i++ ) { + if( dummy.roll_bad_mutation( mutation_category_ALPHA ) ) { + alphaBads++; + } + if( dummy.roll_bad_mutation( mutation_category_TROGLOBITE ) ) { + trogBads++; } } + + WHEN( "Alpha and Troglobite both have the same level of instability" ) { + THEN( "Alpha has fewer total mutations, so its odds of a bad mutation are higher than Trog's" ) { + CHECK( alphaBads > trogBads ); + } + } + + // Then, increase our instability and try again. + dummy.set_mutation( trait_FELINE_EARS ); + dummy.set_mutation( trait_EAGLEEYED ); + dummy.set_mutation( trait_GOURMAND ); + REQUIRE( dummy.get_instability_per_category( mutation_category_ALPHA ) == 8 ); + REQUIRE( dummy.get_instability_per_category( mutation_category_TROGLOBITE ) == 8 ); + + int trogBads2 = 0; + int alphaBads2 = 0; + + for( int i = 0; i < tries; i++ ) { + if( dummy.roll_bad_mutation( mutation_category_ALPHA ) ) { + alphaBads2++; + } + if( dummy.roll_bad_mutation( mutation_category_TROGLOBITE ) ) { + trogBads2++; + } + } + + WHEN( "The player has more mutation instability than before" ) { + THEN( "They have a higher chance of getting bad mutations than before" ) { + CHECK( alphaBads2 > alphaBads ); + CHECK( trogBads2 > trogBads ); + } + } + clear_avatar(); + } // Verify that flags linked to core mutations are still there. diff --git a/tests/player_activities_test.cpp b/tests/player_activities_test.cpp index 70216112806e1..d9ae968028e57 100644 --- a/tests/player_activities_test.cpp +++ b/tests/player_activities_test.cpp @@ -84,6 +84,7 @@ static const recipe_id recipe_water_clean( "water_clean" ); static const skill_id skill_traps( "traps" ); +static const ter_str_id ter_t_dirt( "t_dirt" ); static const ter_str_id ter_t_wall( "t_wall" ); static const ter_str_id ter_test_t_boltcut1( "test_t_boltcut1" ); static const ter_str_id ter_test_t_boltcut2( "test_t_boltcut2" ); @@ -585,8 +586,8 @@ TEST_CASE( "boltcut", "[activity][boltcut]" ) clear_map(); clear_avatar(); - mp.ter_set( tripoint_zero, t_null ); - REQUIRE( mp.ter( tripoint_zero ) == t_null ); + mp.ter_set( tripoint_zero, ter_str_id::NULL_ID() ); + REQUIRE( mp.ter( tripoint_zero ) == ter_str_id::NULL_ID() ); item_location boltcutter = setup_dummy(); setup_activity( boltcutter ); @@ -600,8 +601,8 @@ TEST_CASE( "boltcut", "[activity][boltcut]" ) clear_map(); clear_avatar(); - mp.ter_set( tripoint_zero, t_dirt ); - REQUIRE( mp.ter( tripoint_zero ) == t_dirt ); + mp.ter_set( tripoint_zero, ter_t_dirt ); + REQUIRE( mp.ter( tripoint_zero ) == ter_t_dirt ); item_location boltcutter = setup_dummy(); setup_activity( boltcutter ); @@ -737,7 +738,7 @@ TEST_CASE( "boltcut", "[activity][boltcut]" ) REQUIRE( dummy.activity.id() == ACT_NULL ); THEN( "terrain gets converted to new terrain type" ) { - CHECK( mp.ter( tripoint_zero ) == t_dirt ); + CHECK( mp.ter( tripoint_zero ) == ter_t_dirt ); } } @@ -849,8 +850,8 @@ TEST_CASE( "hacksaw", "[activity][hacksaw]" ) clear_map(); clear_avatar(); - mp.ter_set( tripoint_zero, t_null ); - REQUIRE( mp.ter( tripoint_zero ) == t_null ); + mp.ter_set( tripoint_zero, ter_str_id::NULL_ID() ); + REQUIRE( mp.ter( tripoint_zero ) == ter_str_id::NULL_ID() ); item_location hacksaw = setup_dummy(); setup_activity( hacksaw ); @@ -864,8 +865,8 @@ TEST_CASE( "hacksaw", "[activity][hacksaw]" ) clear_map(); clear_avatar(); - mp.ter_set( tripoint_zero, t_dirt ); - REQUIRE( mp.ter( tripoint_zero ) == t_dirt ); + mp.ter_set( tripoint_zero, ter_t_dirt ); + REQUIRE( mp.ter( tripoint_zero ) == ter_t_dirt ); item_location hacksaw = setup_dummy(); setup_activity( hacksaw ); @@ -1002,7 +1003,7 @@ TEST_CASE( "hacksaw", "[activity][hacksaw]" ) REQUIRE( dummy.activity.id() == ACT_NULL ); THEN( "terrain gets converted to new terrain type" ) { - CHECK( mp.ter( tripoint_zero ) == t_dirt ); + CHECK( mp.ter( tripoint_zero ) == ter_t_dirt ); } } @@ -1115,8 +1116,8 @@ TEST_CASE( "oxytorch", "[activity][oxytorch]" ) clear_map(); clear_avatar(); - mp.ter_set( tripoint_zero, t_null ); - REQUIRE( mp.ter( tripoint_zero ) == t_null ); + mp.ter_set( tripoint_zero, ter_str_id::NULL_ID() ); + REQUIRE( mp.ter( tripoint_zero ) == ter_str_id::NULL_ID() ); item_location welding_torch = setup_dummy(); setup_activity( welding_torch ); @@ -1130,8 +1131,8 @@ TEST_CASE( "oxytorch", "[activity][oxytorch]" ) clear_map(); clear_avatar(); - mp.ter_set( tripoint_zero, t_dirt ); - REQUIRE( mp.ter( tripoint_zero ) == t_dirt ); + mp.ter_set( tripoint_zero, ter_t_dirt ); + REQUIRE( mp.ter( tripoint_zero ) == ter_t_dirt ); item_location welding_torch = setup_dummy(); setup_activity( welding_torch ); @@ -1257,7 +1258,7 @@ TEST_CASE( "oxytorch", "[activity][oxytorch]" ) REQUIRE( dummy.activity.id() == ACT_NULL ); THEN( "terrain gets converted to new terrain type" ) { - CHECK( mp.ter( tripoint_zero ) == t_dirt ); + CHECK( mp.ter( tripoint_zero ) == ter_t_dirt ); } } @@ -1412,8 +1413,8 @@ TEST_CASE( "prying", "[activity][prying]" ) clear_map(); clear_avatar(); - mp.ter_set( tripoint_zero, t_null ); - REQUIRE( mp.ter( tripoint_zero ) == t_null ); + mp.ter_set( tripoint_zero, ter_str_id::NULL_ID() ); + REQUIRE( mp.ter( tripoint_zero ) == ter_str_id::NULL_ID() ); item_location prying_tool = setup_dummy( true ); setup_activity( prying_tool ); @@ -1427,8 +1428,8 @@ TEST_CASE( "prying", "[activity][prying]" ) clear_map(); clear_avatar(); - mp.ter_set( tripoint_zero, t_dirt ); - REQUIRE( mp.ter( tripoint_zero ) == t_dirt ); + mp.ter_set( tripoint_zero, ter_t_dirt ); + REQUIRE( mp.ter( tripoint_zero ) == ter_t_dirt ); item_location prying_tool = setup_dummy( true ); setup_activity( prying_tool ); @@ -1523,7 +1524,7 @@ TEST_CASE( "prying", "[activity][prying]" ) REQUIRE( dummy.activity.id() == ACT_NULL ); THEN( "terrain gets converted to new terrain type" ) { - CHECK( mp.ter( tripoint_zero ) == t_dirt ); + CHECK( mp.ter( tripoint_zero ) == ter_t_dirt ); } } @@ -1582,7 +1583,7 @@ TEST_CASE( "prying", "[activity][prying]" ) REQUIRE( dummy.activity.id() == ACT_NULL ); THEN( "terrain gets converted to new type" ) { - CHECK( mp.ter( tripoint_zero ) == t_dirt ); + CHECK( mp.ter( tripoint_zero ) == ter_t_dirt ); } } @@ -1606,7 +1607,7 @@ TEST_CASE( "prying", "[activity][prying]" ) WHEN( "activity fails" ) { CHECK( dummy.activity.id() == ACT_NULL ); - CHECK( mp.ter( terrain_pos ) == t_dirt ); + CHECK( mp.ter( terrain_pos ) == ter_t_dirt ); const map_stack items = get_map().i_at( terrain_pos ); int count_shards = 0; for( const item &it : items ) { diff --git a/tests/stats_tracker_test.cpp b/tests/stats_tracker_test.cpp index f8f020d981159..e0882aa4fb98b 100644 --- a/tests/stats_tracker_test.cpp +++ b/tests/stats_tracker_test.cpp @@ -135,23 +135,22 @@ TEST_CASE( "stats_tracker_minimum_events", "[stats]" ) b.subscribe( &s ); const mtype_id no_monster; - const ter_id t_null( "t_null" ); constexpr event_type am = event_type::avatar_moves; CHECK( s.get_events( am ).minimum( "z" ) == 0 ); - b.send( no_monster, t_null, move_mode_walk, false, 0 ); + b.send( no_monster, ter_str_id::NULL_ID(), move_mode_walk, false, 0 ); CHECK( s.get_events( am ).minimum( "z" ) == 0 ); - b.send( no_monster, t_null, move_mode_walk, false, -1 ); + b.send( no_monster, ter_str_id::NULL_ID(), move_mode_walk, false, -1 ); CHECK( s.get_events( am ).minimum( "z" ) == -1 ); - b.send( no_monster, t_null, move_mode_walk, false, 1 ); + b.send( no_monster, ter_str_id::NULL_ID(), move_mode_walk, false, 1 ); CHECK( s.get_events( am ).minimum( "z" ) == -1 ); - b.send( no_monster, t_null, move_mode_walk, false, -3 ); + b.send( no_monster, ter_str_id::NULL_ID(), move_mode_walk, false, -3 ); CHECK( s.get_events( am ).minimum( "z" ) == -3 ); - b.send( no_monster, t_null, move_mode_walk, true, -1 ); + b.send( no_monster, ter_str_id::NULL_ID(), move_mode_walk, true, -1 ); CHECK( s.get_events( am ).minimum( "z" ) == -3 ); - b.send( no_monster, t_null, move_mode_walk, true, 1 ); + b.send( no_monster, ter_str_id::NULL_ID(), move_mode_walk, true, 1 ); CHECK( s.get_events( am ).minimum( "z" ) == -3 ); - b.send( no_monster, t_null, move_mode_walk, true, -5 ); + b.send( no_monster, ter_str_id::NULL_ID(), move_mode_walk, true, -5 ); CHECK( s.get_events( am ).minimum( "z" ) == -5 ); } @@ -162,23 +161,22 @@ TEST_CASE( "stats_tracker_maximum_events", "[stats]" ) b.subscribe( &s ); const mtype_id no_monster; - const ter_id t_null( "t_null" ); constexpr event_type am = event_type::avatar_moves; CHECK( s.get_events( am ).maximum( "z" ) == 0 ); - b.send( no_monster, t_null, move_mode_walk, false, 0 ); + b.send( no_monster, ter_str_id::NULL_ID(), move_mode_walk, false, 0 ); CHECK( s.get_events( am ).maximum( "z" ) == 0 ); - b.send( no_monster, t_null, move_mode_walk, false, 1 ); + b.send( no_monster, ter_str_id::NULL_ID(), move_mode_walk, false, 1 ); CHECK( s.get_events( am ).maximum( "z" ) == 1 ); - b.send( no_monster, t_null, move_mode_walk, false, 1 ); + b.send( no_monster, ter_str_id::NULL_ID(), move_mode_walk, false, 1 ); CHECK( s.get_events( am ).maximum( "z" ) == 1 ); - b.send( no_monster, t_null, move_mode_walk, false, 3 ); + b.send( no_monster, ter_str_id::NULL_ID(), move_mode_walk, false, 3 ); CHECK( s.get_events( am ).maximum( "z" ) == 3 ); - b.send( no_monster, t_null, move_mode_walk, true, 1 ); + b.send( no_monster, ter_str_id::NULL_ID(), move_mode_walk, true, 1 ); CHECK( s.get_events( am ).maximum( "z" ) == 3 ); - b.send( no_monster, t_null, move_mode_walk, true, 1 ); + b.send( no_monster, ter_str_id::NULL_ID(), move_mode_walk, true, 1 ); CHECK( s.get_events( am ).maximum( "z" ) == 3 ); - b.send( no_monster, t_null, move_mode_walk, true, 5 ); + b.send( no_monster, ter_str_id::NULL_ID(), move_mode_walk, true, 5 ); CHECK( s.get_events( am ).maximum( "z" ) == 5 ); } @@ -219,17 +217,20 @@ TEST_CASE( "stats_tracker_with_event_statistics", "[stats]" ) SECTION( "movement" ) { const mtype_id no_monster; - const ter_id t_null( "t_null" ); const ter_id t_water_dp( "t_water_dp" ); - const cata::event walk = cata::event::make( no_monster, t_null, + const cata::event walk = cata::event::make( no_monster, + ter_str_id::NULL_ID(), move_mode_walk, false, 0 ); - const cata::event ride = cata::event::make( mon_horse, t_null, + const cata::event ride = cata::event::make( mon_horse, + ter_str_id::NULL_ID(), move_mode_walk, false, 0 ); - const cata::event run = cata::event::make( no_monster, t_null, + const cata::event run = cata::event::make( no_monster, + ter_str_id::NULL_ID(), move_mode_run, false, 0 ); - const cata::event crouch = cata::event::make( no_monster, t_null, + const cata::event crouch = cata::event::make( no_monster, + ter_str_id::NULL_ID(), move_mode_crouch, false, 0 ); const cata::event swim = cata::event::make( no_monster, t_water_dp, move_mode_walk, false, 0 ); @@ -419,17 +420,20 @@ TEST_CASE( "stats_tracker_watchers", "[stats]" ) SECTION( "movement" ) { const mtype_id no_monster; - const ter_id t_null( "t_null" ); const ter_id t_water_dp( "t_water_dp" ); - const cata::event walk = cata::event::make( no_monster, t_null, + const cata::event walk = cata::event::make( no_monster, + ter_str_id::NULL_ID(), move_mode_walk, false, 0 ); - const cata::event ride = cata::event::make( mon_horse, t_null, + const cata::event ride = cata::event::make( mon_horse, + ter_str_id::NULL_ID(), move_mode_walk, false, 0 ); - const cata::event run = cata::event::make( no_monster, t_null, + const cata::event run = cata::event::make( no_monster, + ter_str_id::NULL_ID(), move_mode_run, false, 0 ); - const cata::event crouch = cata::event::make( no_monster, t_null, + const cata::event crouch = cata::event::make( no_monster, + ter_str_id::NULL_ID(), move_mode_crouch, false, 0 ); const cata::event swim = cata::event::make( no_monster, t_water_dp, move_mode_walk, false, 0 ); @@ -790,12 +794,13 @@ TEST_CASE( "achievements_tracker", "[stats]" ) SECTION( "movement" ) { const mtype_id no_monster; - const ter_id t_null( "t_null" ); const ter_id t_water_dp( "t_water_dp" ); const ter_id t_shrub_raspberry( "t_shrub_raspberry" ); - const cata::event walk = cata::event::make( no_monster, t_null, + const cata::event walk = cata::event::make( no_monster, + ter_str_id::NULL_ID(), move_mode_walk, false, 0 ); - const cata::event run = cata::event::make( no_monster, t_null, + const cata::event run = cata::event::make( no_monster, + ter_str_id::NULL_ID(), move_mode_run, false, 0 ); const cata::event sharp_move = cata::event::make( no_monster, t_shrub_raspberry, move_mode_walk, false, 0 ); @@ -805,9 +810,11 @@ TEST_CASE( "achievements_tracker", "[stats]" ) t_water_dp, move_mode_walk, true, 0 ); const cata::event swim_underwater_deep = cata::event::make( no_monster, t_water_dp, move_mode_walk, true, -5 ); - const cata::event walk_max_z = cata::event::make( no_monster, t_null, + const cata::event walk_max_z = cata::event::make( no_monster, + ter_str_id::NULL_ID(), move_mode_walk, false, OVERMAP_HEIGHT ); - const cata::event walk_min_z = cata::event::make( no_monster, t_null, + const cata::event walk_min_z = cata::event::make( no_monster, + ter_str_id::NULL_ID(), move_mode_walk, false, -OVERMAP_DEPTH ); SECTION( "achievement_marathon" ) { diff --git a/tests/submap_load_test.cpp b/tests/submap_load_test.cpp index 0ecb1d6eeda39..6d8dd6b9c0b3e 100644 --- a/tests/submap_load_test.cpp +++ b/tests/submap_load_test.cpp @@ -27,6 +27,13 @@ static const construction_str_id construction_constr_ground_cable( "constr_ground_cable" ); static const construction_str_id construction_constr_rack_coat( "constr_rack_coat" ); +static const ter_str_id ter_t_dirt( "t_dirt" ); +static const ter_str_id ter_t_floor( "t_floor" ); +static const ter_str_id ter_t_floor_blue( "t_floor_blue" ); +static const ter_str_id ter_t_floor_green( "t_floor_green" ); +static const ter_str_id ter_t_floor_red( "t_floor_red" ); +static const ter_str_id ter_t_rock_floor( "t_rock_floor" ); + // NOLINTNEXTLINE(cata-static-declarations) extern const int savegame_version; @@ -837,7 +844,7 @@ static bool is_normal_submap( const submap &sm, submap_checks checks = {} ) // For every point on the submap for( int y = 0; y < SEEY; ++y ) { for( int x = 0; x < SEEX; ++x ) { - if( terrain && sm.get_ter( { x, y } ) != t_dirt ) { + if( terrain && sm.get_ter( { x, y } ) != ter_t_dirt ) { return false; } if( furniture && sm.get_furn( { x, y } ) != f_null ) { @@ -905,28 +912,28 @@ TEST_CASE( "submap_terrain_rle_load", "[submap][load]" ) INFO( string_format( "sw: %s", ter_sw.id().str() ) ); INFO( string_format( "se: %s", ter_se.id().str() ) ); // Require to prevent the lower CHECK from being spammy - REQUIRE( ter_nw == t_floor_green ); - REQUIRE( ter_ne == t_floor_red ); - REQUIRE( ter_sw == t_floor ); - REQUIRE( ter_se == t_floor_blue ); + REQUIRE( ter_nw == ter_t_floor_green ); + REQUIRE( ter_ne == ter_t_floor_red ); + REQUIRE( ter_sw == ter_t_floor ); + REQUIRE( ter_se == ter_t_floor_blue ); // And for the rest of the map, half of it is t_dirt, the other half t_rock_floor for( int x = 1; x < SEEX - 2; ++x ) { - CHECK( sm.get_ter( { x, 0 } ) == t_dirt ); + CHECK( sm.get_ter( { x, 0 } ) == ter_t_dirt ); } for( int y = 1; y < SEEY / 2; ++y ) { for( int x = 0; x < SEEX; ++x ) { - CHECK( sm.get_ter( { x, y } ) == t_dirt ); + CHECK( sm.get_ter( { x, y } ) == ter_t_dirt ); } } for( int y = SEEY / 2; y < SEEY - 1; ++y ) { for( int x = 0; x < SEEX; ++x ) { - CHECK( sm.get_ter( { x, y } ) == t_rock_floor ); + CHECK( sm.get_ter( { x, y } ) == ter_t_rock_floor ); } } for( int x = 1; x < SEEX - 2; ++x ) { - CHECK( sm.get_ter( { x, SEEY - 1 } ) == t_rock_floor ); + CHECK( sm.get_ter( { x, SEEY - 1 } ) == ter_t_rock_floor ); } } @@ -942,12 +949,11 @@ TEST_CASE( "submap_terrain_load_invalid_ter_ids_as_t_dirt", "[submap][load]" ) REQUIRE( error == "invalid ter_str_id 't_this_ter_id_does_not_exist'" ); //capture_debugmsg_during - const ter_id t_dirt( "t_dirt" ); for( int x = 0; x < SEEX; x++ ) { for( int y = 0; y < SEEY; y++ ) { CAPTURE( x, y ); // expect t_rock_floor patch in a corner - const ter_id expected = ( ( x == 11 ) && ( y == 11 ) ) ? t_rock_floor : t_dirt; + const ter_id expected = ( ( x == 11 ) && ( y == 11 ) ) ? ter_t_rock_floor : ter_t_dirt; CHECK( sm.get_ter( {x, y} ) == expected ); } }