and a powerful force hurls them through the air!",
"miss_msg_u": "%s stares at you, and you feel a crushing pressure for a moment before the feeling vanishes!",
diff --git a/data/mods/MindOverMatter/monsters/species_new.json b/data/mods/MindOverMatter/monsters/species_new.json
index c4242fe355b53..753e7c2786934 100644
--- a/data/mods/MindOverMatter/monsters/species_new.json
+++ b/data/mods/MindOverMatter/monsters/species_new.json
@@ -5,6 +5,12 @@
"description": "a being immune to psionics",
"//": "This is an extra species to attach to any monster that is supposed to be immune to psionics--it will prevent them from being targeted by psionic powers. If the monster is supposed to be fully immune, they will still need appropriate monster flags or armor against psionic damage types to prevent them from being caught in the AoE of powers targeted elsewhere."
},
+ {
+ "type": "SPECIES",
+ "id": "TELEKIN_PUSHPULL_NULL",
+ "description": "a being immune to being thrown telekinetically",
+ "//": "This is an extra species to attach to any monster that is supposed to be immune to telekinetic push or pull. Immunity to telekinetic damage is handled by flags."
+ },
{
"type": "SPECIES",
"id": "YRAX_CONSTRUCT",
diff --git a/data/mods/MindOverMatter/powers/telekinesis.json b/data/mods/MindOverMatter/powers/telekinesis.json
index 83b9f4a086ece..68170fb5f3fe6 100644
--- a/data/mods/MindOverMatter/powers/telekinesis.json
+++ b/data/mods/MindOverMatter/powers/telekinesis.json
@@ -38,7 +38,7 @@
"base_casting_time": 50,
"final_casting_time": 10,
"casting_time_increment": -4,
- "ignored_monster_species": [ "PSI_NULL" ]
+ "ignored_monster_species": [ "PSI_NULL", "TELEKIN_PUSHPULL_NULL" ]
},
{
"id": "telekinetic_push",
@@ -79,7 +79,7 @@
"base_casting_time": 50,
"final_casting_time": 10,
"casting_time_increment": -4,
- "ignored_monster_species": [ "PSI_NULL" ]
+ "ignored_monster_species": [ "PSI_NULL", "TELEKIN_PUSHPULL_NULL" ]
},
{
"id": "telekinetic_noise",
@@ -91,7 +91,7 @@
"valid_targets": [ "ground" ],
"spell_class": "TELEKINETIC",
"skill": "metaphysics",
- "flags": [ "PSIONIC", "CONCENTRATE", "RANDOM_DAMAGE", "NO_HANDS", "NO_LEGS", "NO_EXPLOSION_SFX" ],
+ "flags": [ "PSIONIC", "CONCENTRATE", "RANDOM_DAMAGE", "NO_PROJECTILE", "NO_HANDS", "NO_LEGS", "NO_EXPLOSION_SFX" ],
"difficulty": 2,
"max_level": { "math": [ "int_to_level(1)" ] },
"effect": "noise",
@@ -172,7 +172,7 @@
"base_casting_time": 75,
"final_casting_time": 30,
"casting_time_increment": -3,
- "ignored_monster_species": [ "PSI_NULL" ]
+ "ignored_monster_species": [ "PSI_NULL", "TELEKIN_PUSHPULL_NULL" ]
},
{
"id": "telekinetic_momentum",
@@ -313,7 +313,7 @@
},
"min_range": 1,
"max_range": 1,
- "ignored_monster_species": [ "PSI_NULL" ]
+ "ignored_monster_species": [ "PSI_NULL", "TELEKIN_PUSHPULL_NULL" ]
},
{
"id": "telekinetic_strength",
diff --git a/data/mods/MindOverMatter/powers/teleportation.json b/data/mods/MindOverMatter/powers/teleportation.json
index 4d9c20c927d9a..92e43f10f5acb 100644
--- a/data/mods/MindOverMatter/powers/teleportation.json
+++ b/data/mods/MindOverMatter/powers/teleportation.json
@@ -535,7 +535,7 @@
"type": "SPELL",
"name": "[Ψ]Oubliette",
"description": "Teleport the target through the nether to some other dimension. They are technically not dead, but they are no longer your concern. Oubliette will occasionally fail when used against very powerful enemies, or succeed but cause damage to the teleporter.",
- "message": "With a tremendous mental exertion, you hurl your target to another dimension!",
+ "message": "",
"teachable": false,
"valid_targets": [ "hostile" ],
"spell_class": "TELEPORTER",
@@ -543,7 +543,8 @@
"flags": [ "PSIONIC", "CONCENTRATE", "SILENT", "RANDOM_DAMAGE", "NO_HANDS", "NO_LEGS", "NO_EXPLOSION_SFX" ],
"difficulty": 7,
"max_level": { "math": [ "int_to_level(1)" ] },
- "effect": "banishment",
+ "effect": "effect_on_condition",
+ "effect_str": "EOC_TELEPORTER_OUBLIETTE_HANDLING",
"shape": "blast",
"min_damage": {
"math": [
@@ -570,6 +571,24 @@
"casting_time_increment": -5.5,
"ignored_monster_species": [ "PSI_NULL" ]
},
+ {
+ "id": "teleport_banish_self_target",
+ "type": "SPELL",
+ "name": "Oubliette Self",
+ "description": "This is the banishment that the target casts on themselves.",
+ "valid_targets": [ "self" ],
+ "skill": "metaphysics",
+ "flags": [ "PSIONC", "SILENT", "RANDOM_DAMAGE" ],
+ "effect": "banishment",
+ "shape": "blast",
+ "spell_class": "TELEPORTER",
+ "teachable": false,
+ "min_damage": { "math": [ "u_psi_teleporter_damage" ] },
+ "max_damage": { "math": [ "u_psi_teleporter_damage" ] },
+ "min_range": 0,
+ "max_range": 0,
+ "ignored_monster_species": [ "PSI_NULL" ]
+ },
{
"id": "teleport_gateway",
"type": "SPELL",
diff --git a/data/mods/MindOverMatter/powers/teleportation_eoc.json b/data/mods/MindOverMatter/powers/teleportation_eoc.json
index 86576288e7f42..847ecb97d6879 100644
--- a/data/mods/MindOverMatter/powers/teleportation_eoc.json
+++ b/data/mods/MindOverMatter/powers/teleportation_eoc.json
@@ -36,6 +36,70 @@
}
]
},
+ {
+ "type": "effect_on_condition",
+ "id": "EOC_TELEPORTER_OUBLIETTE_HANDLING",
+ "condition": {
+ "and": [
+ { "not": { "u_has_flag": "TELESTOP" } },
+ { "not": { "u_has_flag": "TELEPORT_IMMUNE" } },
+ { "not": { "u_has_worn_with_flag": "DIMENSIONAL_ANCHOR" } }
+ ]
+ },
+ "effect": [ { "run_eocs": "EOC_TELEPORTER_OUBLIETTE_HANDLING_2" } ],
+ "false_effect": [ { "npc_message": "Your target wavers for a moment, but nothing happens." } ]
+ },
+ {
+ "type": "effect_on_condition",
+ "id": "EOC_TELEPORTER_OUBLIETTE_HANDLING_2",
+ "condition": { "not": "u_is_npc" },
+ "effect": [
+ {
+ "math": [
+ "u_psi_teleporter_damage",
+ "=",
+ "rng(((15 + (n_spell_level('teleport_banish') * 15)) * ( ( n_val('intelligence') + 10) / 20 ) * n_nether_attunement_power_scaling),((350 + (n_spell_level('teleport_banish') * 35)) * ( ( n_val('intelligence') + 10) / 20 ) * n_nether_attunement_power_scaling))"
+ ]
+ },
+ { "math": [ "u_health_comparison", "=", "u_hp('ALL')" ] },
+ {
+ "if": { "math": [ "u_psi_teleporter_damage", ">", "u_health_comparison" ] },
+ "then": [
+ { "u_cast_spell": { "id": "teleport_banish_self_target", "message": "" } },
+ { "npc_message": "With a tremendous mental exertion, you hurl your target to another dimension!" }
+ ]
+ }
+ ],
+ "false_effect": [
+ {
+ "math": [
+ "u_psi_teleporter_damage",
+ "=",
+ "rng(((15 + (n_spell_level('teleport_banish') * 15)) * ( ( n_val('intelligence') + 10) / 20 ) * n_nether_attunement_power_scaling),((350 + (n_spell_level('teleport_banish') * 35)) * ( ( n_val('intelligence') + 10) / 20 ) * n_nether_attunement_power_scaling))"
+ ]
+ },
+ {
+ "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"
+ ]
+ },
+ {
+ "if": { "math": [ "u_psi_teleporter_damage", ">", "u_health_comparison" ] },
+ "then": [
+ "u_die",
+ { "npc_message": "With a tremendous mental exertion, you hurl your target to another dimension!" },
+ {
+ "u_map_run_item_eocs": "all",
+ "min_radius": 0,
+ "max_radius": 0,
+ "true_eocs": [ { "id": "EOC_TELEPORTER_OUBLIETTE_HANDLING_DELETE_NPC_ITEMS", "effect": [ "npc_die" ] } ]
+ }
+ ]
+ }
+ ]
+ },
{
"type": "effect_on_condition",
"id": "EOC_TELEPORT_SUMMON",
diff --git a/data/mods/MindOverMatter/recipes/psionics_practice.json b/data/mods/MindOverMatter/recipes/psionics_practice.json
index 26074e923b64d..8b31f8aac4698 100644
--- a/data/mods/MindOverMatter/recipes/psionics_practice.json
+++ b/data/mods/MindOverMatter/recipes/psionics_practice.json
@@ -90,6 +90,20 @@
"byproducts": [ [ "matrix_crystal_drained_dust", 10 ] ],
"book_learn": [ [ "manual_psionics_advan", 3 ], [ "schematics_matrix_channeling", 3 ], [ "schematics_matrix_aligning", 3 ] ]
},
+ {
+ "id": "prac_psionics_prof_ritual",
+ "type": "practice",
+ "activity_level": "LIGHT_EXERCISE",
+ "category": "CC_PRACTICE",
+ "subcategory": "CSC_PRACTICE_METAPHYSICS",
+ "name": "thought-form exercises",
+ "description": "Practice holding mental images and scenes in your mind for an extended period without your mind wandering.",
+ "skill_used": "metaphysics",
+ "practice_data": { "min_difficulty": 4, "max_difficulty": 4, "skill_limit": 4 },
+ "proficiencies": [ { "proficiency": "prof_psionic_ritual", "time_multiplier": 1, "skill_penalty": 0 } ],
+ "time": "1 h",
+ "book_learn": [ [ "manual_psionic_ritual", 4 ] ]
+ },
{
"id": "prac_concentration_basic",
"type": "practice",
diff --git a/data/mods/MindOverMatter/recipes/research.json b/data/mods/MindOverMatter/recipes/research.json
index c05857f1aff32..c54fcd3c6bf4a 100644
--- a/data/mods/MindOverMatter/recipes/research.json
+++ b/data/mods/MindOverMatter/recipes/research.json
@@ -201,6 +201,7 @@
"type": "good"
},
{ "u_add_trait": "PSI_EXTENDED_CHANNELING" },
+ { "u_forget_recipe": "psi_research_extended_channeling" },
{ "run_eocs": "EOC_PSI_PRACTICE_FOCUS_MOD" }
],
"false_effect": [
diff --git a/data/mods/TEST_DATA/EOC.json b/data/mods/TEST_DATA/EOC.json
index 024d6fb9c319f..fdb4692462f8f 100644
--- a/data/mods/TEST_DATA/EOC.json
+++ b/data/mods/TEST_DATA/EOC.json
@@ -338,15 +338,15 @@
"effect": [
{ "set_string_var": "prof_test", "target_var": { "global_val": "prof_id" } },
{ "math": [ "key_total_time_required", "=", "u_proficiency(prof_id, 'format': 'total_time_required')" ] },
- { "math": [ "u_proficiency(prof_id)", "=", "50" ] },
+ { "math": [ "u_proficiency(prof_id, 'direct': true)", "=", "50" ] },
{ "math": [ "key_time_spent_50", "=", "u_proficiency(prof_id)" ] },
- { "math": [ "u_proficiency(prof_id, 'format': 'percent')", "=", "50" ] },
+ { "math": [ "u_proficiency(prof_id, 'format': 'percent', 'direct': true)", "=", "50" ] },
{ "math": [ "key_percent_50", "=", "u_proficiency(prof_id, 'format': 'percent')" ] },
{ "math": [ "key_percent_50_turn", "=", "u_proficiency(prof_id)" ] },
- { "math": [ "u_proficiency(prof_id, 'format': 'permille')", "=", "50" ] },
+ { "math": [ "u_proficiency(prof_id, 'format': 'permille', 'direct': true)", "=", "50" ] },
{ "math": [ "key_permille_50", "=", "u_proficiency(prof_id, 'format': 'permille')" ] },
{ "math": [ "key_permille_50_turn", "=", "u_proficiency(prof_id)" ] },
- { "math": [ "u_proficiency(prof_id, 'format': 'time_left')", "=", "50" ] },
+ { "math": [ "u_proficiency(prof_id, 'format': 'time_left', 'direct': true)", "=", "50" ] },
{ "math": [ "key_time_left_50", "=", "u_proficiency(prof_id, 'format': 'time_left')" ] },
{ "math": [ "key_time_left_50_turn", "=", "u_proficiency(prof_id)" ] }
]
diff --git a/data/mods/TEST_DATA/mutations.json b/data/mods/TEST_DATA/mutations.json
index 8e69486e732e9..9f567335e8871 100644
--- a/data/mods/TEST_DATA/mutations.json
+++ b/data/mods/TEST_DATA/mutations.json
@@ -8,6 +8,7 @@
"dummy": true,
"category": [ "HUMAN" ],
"cancels": [
+ "TEST_CONSISTENCY_CHECK",
"TEST_ENCH_MUTATION",
"TEST_GOOD1",
"TEST_GOOD2",
@@ -37,6 +38,15 @@
"enchantments": [ "TEST_ENCH" ],
"category": [ "CEPHALOPOD" ]
},
+ {
+ "type": "mutation",
+ "id": "TEST_CONSISTENCY_CHECK",
+ "name": "Dummy Test Trait",
+ "points": 0,
+ "description": "Test trait to trip the consistency check: it shouldn't cause a load error since it overwrites a basegame trait.",
+ "prereqs": [ "WINGS_STUB" ],
+ "category": [ "INST_TEST" ]
+ },
{
"type": "mutation",
"id": "TEST_TRIGGER",
diff --git a/doc/EFFECT_ON_CONDITION.md b/doc/EFFECT_ON_CONDITION.md
index 5a1634d242b6b..7b3d446299004 100644
--- a/doc/EFFECT_ON_CONDITION.md
+++ b/doc/EFFECT_ON_CONDITION.md
@@ -2044,7 +2044,7 @@ Run EOCs on items in your or NPC's inventory
| Syntax | Optionality | Value | Info |
| --- | --- | --- | --- |
| "u_run_inv_eocs" / "npc_run_inv_eocs" | **mandatory** | string or [variable object](#variable-object) | way the item would be picked;
values can be:
`all` - all items that match the conditions are picked;
`random` - from all items that match the conditions, one picked;
`manual` - menu is open with all items that can be picked, and you can choose one;
`manual_mult` - same as `manual`, but multiple items can be picked |
-| "search_data" | optional | `search_data` | sets the condition for the target item; lack of search_data means any item can be picked; conditions can be:
`id` - id of a specific item;
`category` - category of an item (case sensitive, should always be in lower case);
`flags`- flag or flags the item has
`excluded_flags`- flag or flags the item doesn't have
`material` - material of an item;
`worn_only` - if true, return only items, that are worn;
`wielded_only` - if true, return only wielded items |
+| "search_data" | optional | `search_data` | sets the condition for the target item; lack of search_data means any item can be picked; conditions can be:
`id` - id of a specific item;
`category` - category of an item (case sensitive, should always be in lower case);
`flags`- flag or flags the item has
`excluded_flags`- flag or flags the item doesn't have
`material` - material of an item;
`worn_only` - if true, return only items, that are worn;
`wielded_only` - if true, return only wielded items;
`calories` - minimum amount of kcal of an item |
| "title" | optional | string or [variable object](#variable-object) | name of the menu, that would be shown, if `manual` or `manual_mult` is used |
| "true_eocs" / "false_eocs" | optional | string, [variable object](##variable-object), inline EoC, or range of all of them | if item was picked successfully, all EoCs from `true_eocs` are run, otherwise all EoCs from `false_eocs` are run; picked item is returned as npc; for example, `n_hp()` return hp of an item |
diff --git a/doc/JSON_INFO.md b/doc/JSON_INFO.md
index b6d6e89c8d2df..e0801c2d682c6 100644
--- a/doc/JSON_INFO.md
+++ b/doc/JSON_INFO.md
@@ -2972,7 +2972,7 @@ See [MUTATIONS.md](MUTATIONS.md)
"always_invisible": true, // Super well hidden traps the player can never detect
"funnel_radius": 200, // millimeters. The higher the more rain it will capture.
"comfort": 0, // Same property affecting furniture and terrain
- "floor_bedding_warmth": -500, // Same property affecting furniture and terrain
+ "floor_bedding_warmth": -500, // Same property affecting furniture and terrain. Also affects how comfortable a resting place this is(affects healing). Vanilla values should not exceed 1000.
"spell_data": { "id": "bear_trap" }, // data required for trapfunc::spell()
"trigger_weight": "200 g", // If an item with this weight or more is thrown onto the trap, it triggers. Defaults to 500 grams.
"drops": [ "beartrap" ], // ID of item spawned when disassembled
@@ -3201,7 +3201,7 @@ These values apply to crafting tasks performed at the WORKBENCH.
#### The following optional fields are specific to SEATs.
```c++
"comfort": 3, // (Optional, default=0). Sleeping comfort as for terrain/furniture.
-"floor_bedding_warmth": 300, // (Optional, default=0). Bonus warmth as for terrain/furniture.
+"floor_bedding_warmth": 300, // (Optional, default=0). Bonus warmth as for terrain/furniture. Also affects how comfortable a resting place this is(affects healing). Vanilla values should not exceed 1000.
"bonus_fire_warmth_feet": 200,// (Optional, default=0). Bonus fire warmth as for terrain/furniture.
```
@@ -5438,7 +5438,7 @@ How comfortable this terrain/furniture is. Impact ability to fall asleep on it.
#### `floor_bedding_warmth`
-Bonus warmth offered by this terrain/furniture when used to sleep.
+Bonus warmth offered by this terrain/furniture when used to sleep. Also affects how comfortable a resting place this is(affects healing). Vanilla values should not exceed 1000.
#### `bonus_fire_warmth_feet`
diff --git a/doc/MAGIC.md b/doc/MAGIC.md
index 138388d7f25d7..fb994f6d2b7e1 100644
--- a/doc/MAGIC.md
+++ b/doc/MAGIC.md
@@ -807,7 +807,7 @@ Character status value | Description
`BLEED_STOP_BONUS` | Affects the `bleed` level when applying medicine.
`BODYTEMP_SLEEP` | Amount of warmth (in celcius) added to you when you sleep. Default is 0, so better to use `add`
`BONUS_BLOCK` | Affects the number of blocks you can perform.
-`BONUS_DODGE` | Affects the number of dodges you can perform.
+`BONUS_DODGE` | Affects the number of dodges you can perform. Do not confuse with `DODGE_CHANCE`
`CARDIO_MULTIPLIER` | Affects total cardio fitness by this amount. Since it's a percent, using `multiply` is recommended.
`CARRY_WEIGHT` | Affect the summary weight player can carry. `"add": 1000` adds 1 kg of weight to carry.
`CASTING_TIME_MULTIPLIER` | Same as mutation `casting_time_multiplier` field, changes your casting speed. Since it's a percent, using `multiply` is recommended. `"multiply": 2"` triples the casting speed
@@ -818,6 +818,7 @@ Character status value | Description
`CRAFTING_SPEED_MULTIPLIER` | Changes your crafting speed. Since it's a percent, using `multiply` is recommended. Positive values decrease crafting time, negative values increase it.
`DEXTERITY` | Affects the dexterity stat.
`DISINFECTANT_BONUS` | Affects the `disinfectant_power` you have when applying medicine.
+`DODGE_CHANCE` | Modifies the probability to dodge an attack. Default is 0, so better to use `add`
`EFFECTIVE_HEALTH_MOD` | If this is anything other than zero (which it defaults to) you will use it instead of your actual health mod.
`EXTRA_ACID` | EXTRA_TYPE increases received damage of the selected type.
`EXTRA_BASH` |
diff --git a/doc/NPCs.md b/doc/NPCs.md
index 78648d101b69f..b163f4f59dde5 100644
--- a/doc/NPCs.md
+++ b/doc/NPCs.md
@@ -1352,7 +1352,7 @@ _some functions support array arguments or kwargs, denoted with square brackets
| moon_phase() | ✅ | ❌ | N/A
(global) | Returns current phase of the Moon. MOON_NEW = 0,
WAXING_CRESCENT = 1,
HALF_MOON_WAXING = 2,
WAXING_GIBBOUS = 3,
FULL = 4,
WANING_GIBBOUS = 5,
HALF_MOON_WANING = 6,
WANING_CRESCENT = 7 |
| num_input(`s`/`v`,`d`/`v`) | ✅ | ❌ | N/A
(global) | Prompt the player for a number.
Arguments are Prompt text, Default Value:
`"math": [ "u_value_to_set", "=", "num_input('Playstyle Perks Cost?', 4)" ]`|
| pain() | ✅ | ✅ | u, n | Return or set pain
Example:
`{ "math": [ "n_pain()", "=", "u_pain() + 9000" ] }`|
-| proficiency(`s`/`v`) | ✅ | ✅ | u, n | Return or set proficiency
Argument is proficiency ID.
Optional kwargs:
`format`: `s` - `percent` return or set how many percent done the learning is. `permille` does likewise for permille. `time_spent` return or set total time spent. `time_left` return or set the remaining time. `total_time_required` return total time required to train a given proficiency (read only).
Example:
`{ "math": [ "u_proficiency('prof_intro_chemistry', 'format': 'percent')", "=", "50" ] }`|
+| proficiency(`s`/`v`) | ✅ | ✅ | u, n | Return or set proficiency
Argument is proficiency ID.
Optional kwargs:
`format`: `s` - `percent` return or set how many percent done the learning is. `permille` does likewise for permille. `time_spent` return or set total time spent. `time_left` return or set the remaining time. `total_time_required` return total time required to train a given proficiency (read only).
`direct`: `true`/`false`/`d` - false (default) perform the adjustment by practicing the proficiency for the given amount of time. This will likely result in different values than specified. `true` perform the adjustment directly, bypassing other factors that may affect it.
Example:
`{ "math": [ "u_proficiency('prof_intro_chemistry', 'format': 'percent')", "=", "50" ] }`|
| school_level(`s`/`v`) | ✅ | ❌ | u, n | Return the highest level of spells known of that school.
Argument is school ID.
Example:
`"condition": { "math": [ "u_school_level('MAGUS')", ">=", "3"] }`|
| school_level_adjustment(`s`/`v`) | ✅ | ✅ | u, n | Return or set temporary caster level adjustment. Only useable by EoCs that trigger on the event `opens_spellbook`. Old values will be reset to 0 before the event triggers. To avoid overwriting values from other EoCs, it is recommended to adjust the values here with `+=` or `-=` instead of setting it to an absolute value.
Argument is school ID.
Example:
`{ "math": [ "u_school_level_adjustment('MAGUS')", "+=", "3"] }`|
| skill(`s`/`v`) | ✅ | ✅ | u, n | Return or set skill level
Example:
`"condition": { "math": [ "u_skill('driving')", ">=", "5"] }`
`"condition": { "math": [ "u_skill(someskill)", ">=", "5"] }`|
diff --git a/src/action.cpp b/src/action.cpp
index a1516d987dddf..55193407acfb4 100644
--- a/src/action.cpp
+++ b/src/action.cpp
@@ -10,7 +10,7 @@
#include
#include "avatar.h"
-#include "cached_options.h"
+#include "cached_options.h" // IWYU pragma: keep
#include "cata_utility.h"
#include "character.h"
#include "creature.h"
@@ -18,9 +18,12 @@
#include "debug.h"
#include "flag.h"
#include "game.h"
+#include "game_constants.h"
#include "input_context.h"
+#include "input_enums.h"
#include "inventory.h"
#include "item.h"
+#include "item_location.h"
#include "map.h"
#include "map_iterator.h"
#include "mapdata.h"
diff --git a/src/action.h b/src/action.h
index e81798c888c5c..19d62f8e19000 100644
--- a/src/action.h
+++ b/src/action.h
@@ -13,6 +13,7 @@
struct input_event;
struct point;
+struct tripoint;
/**
* Enumerates all discrete actions that can be performed by player
diff --git a/src/activity_handlers.cpp b/src/activity_handlers.cpp
index 0612addfdf72b..caa71439eb60a 100644
--- a/src/activity_handlers.cpp
+++ b/src/activity_handlers.cpp
@@ -1167,14 +1167,16 @@ static bool butchery_drops_harvest( item *corpse_item, const mtype &mt, Characte
const int item_charges = monster_weight_remaining / to_gram( item::find_type(
leftover_id )->weight );
if( item_charges > 0 ) {
- item ruined_parts( leftover_id, calendar::turn, item_charges );
+ item ruined_parts( leftover_id, calendar::turn );
ruined_parts.set_mtype( &mt );
ruined_parts.set_item_temperature( corpse_item->temperature );
ruined_parts.set_rot( corpse_item->get_rot() );
if( !you.backlog.empty() && you.backlog.front().id() == ACT_MULTIPLE_BUTCHER ) {
ruined_parts.set_var( "activity_var", you.name );
}
- here.add_item_or_charges( you.pos(), ruined_parts );
+ for( int i = 0; i < item_charges; ++i ) {
+ here.add_item_or_charges( you.pos(), ruined_parts );
+ }
}
}
diff --git a/src/avatar.cpp b/src/avatar.cpp
index 393449ea5396c..337f136d50060 100644
--- a/src/avatar.cpp
+++ b/src/avatar.cpp
@@ -2,9 +2,9 @@
#include
#include
-#include
#include
-#include
+#include
+#include
#include
#include
#include