From 5138fe780b69e0b8ea952e347d73487658103940 Mon Sep 17 00:00:00 2001 From: RenechCDDA <84619419+RenechCDDA@users.noreply.github.com> Date: Wed, 13 Nov 2024 19:58:58 -0500 Subject: [PATCH 1/7] Butchering humans causes opinion loss with non-cannibals that see Non-cannibal NPCs refuse to butcher humans --- src/activity_handlers.cpp | 32 +++++++++++++++++++++++++------- src/activity_handlers.h | 6 ++++-- src/activity_item_handling.cpp | 22 ++++++++++++++++++++++ src/character.h | 2 ++ src/consumption.cpp | 9 +++++++-- 5 files changed, 60 insertions(+), 11 deletions(-) diff --git a/src/activity_handlers.cpp b/src/activity_handlers.cpp index 5ab4240c1ea5d..03f7b2b9ca793 100644 --- a/src/activity_handlers.cpp +++ b/src/activity_handlers.cpp @@ -479,6 +479,27 @@ void activity_handlers::butcher_do_turn( player_activity *act, Character * ) corpse_item.set_var( butcher_progress_var( action ), progress ); } +static bool do_cannibalism_piss_people_off( Character &you ) +{ + if( !you.is_avatar() ) { + return true; // NPCs dont accidentally cause player hate + } + + if( !query_yn( + _( "Really desecrate the mortal remains of a fellow human being by butchering them for meat?" ) ) ) { + return false; // player cancels + } + + for( npc &guy : g->all_npcs() ) { + if( guy.is_active() && guy.sees( you ) && !guy.okay_with_eating_humans() ) { + // massive opinion penalty + guy.op_of_u.trust -= 5; + guy.op_of_u.value -= 5; + } + } + return true; +} + static void set_up_butchery( player_activity &act, Character &you, butcher_type action ) { const int factor = you.max_quality( action == butcher_type::DISSECT ? qual_CUT_FINE : qual_BUTCHER, @@ -597,20 +618,18 @@ static void set_up_butchery( player_activity &act, Character &you, butcher_type } } - + // TODO: Extract this bool into a function const bool is_human = corpse.id == mtype_id::NULL_ID() || ( ( corpse.in_species( species_HUMAN ) || corpse.in_species( species_FERAL ) ) && !corpse.in_species( species_ZOMBIE ) ); // applies to all butchery actions except for dissections - if( is_human && action != butcher_type::DISSECT && !( you.has_flag( json_flag_CANNIBAL ) || - you.has_flag( json_flag_PSYCHOPATH ) || you.has_flag( json_flag_SAPIOVORE ) ) ) { + if( is_human && action != butcher_type::DISSECT && !you.okay_with_eating_humans() ) { //first determine if the butcherer has the dissect_humans proficiency. if( you.has_proficiency( proficiency_prof_dissect_humans ) ) { //if it's player doing the butchery, ask them first. if( you.is_avatar() ) { - if( query_yn( - _( "Really desecrate the mortal remains of a fellow human being by butchering them for meat?" ) ) ) { + if( do_cannibalism_piss_people_off( you ) ) { //give the player a random message showing their disgust and cause morale penalty. switch( rng( 1, 3 ) ) { case 1: @@ -667,8 +686,7 @@ static void set_up_butchery( player_activity &act, Character &you, butcher_type } // applies to only dissections, so that dissect_humans training makes a difference. - if( is_human && action == butcher_type::DISSECT && !( you.has_flag( json_flag_CANNIBAL ) || - you.has_flag( json_flag_PSYCHOPATH ) || you.has_flag( json_flag_SAPIOVORE ) ) ) { + if( is_human && action == butcher_type::DISSECT && !you.okay_with_eating_humans() ) { if( you.has_proficiency( proficiency_prof_dissect_humans ) ) { //you're either trained for this, densensitized, or both. doesn't bother you. if( you.is_avatar() ) { diff --git a/src/activity_handlers.h b/src/activity_handlers.h index 54c4a8ae9f4a3..82a9e377d11cd 100644 --- a/src/activity_handlers.h +++ b/src/activity_handlers.h @@ -90,7 +90,8 @@ enum class do_activity_reason : int { NEEDS_MOP, // This spot can be mopped, if a mop is present. NEEDS_FISHING, // This spot can be fished, if the right tool is present. NEEDS_CRAFT, // There is at least one item to craft. - NEEDS_DISASSEMBLE // There is at least one item to disassemble. + NEEDS_DISASSEMBLE, // There is at least one item to disassemble. + REFUSES_THIS_WORK // Character refuses to do this for some reason, maybe against their beliefs or needs danger prompt. }; @@ -122,7 +123,8 @@ const std::vector do_activity_reason_string = { "NEEDS_MOP", "NEEDS_FISHING", "NEEDS_CRAFT", - "NEEDS_DISASSEMBLE" + "NEEDS_DISASSEMBLE", + "REFUSES_THIS_WORK" }; struct activity_reason_info { diff --git a/src/activity_item_handling.cpp b/src/activity_item_handling.cpp index b5303a2e82fbc..b9e6638a343ef 100644 --- a/src/activity_item_handling.cpp +++ b/src/activity_item_handling.cpp @@ -124,6 +124,10 @@ static const quality_id qual_WELD( "WELD" ); static const requirement_id requirement_data_mining_standard( "mining_standard" ); +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_stump( "t_stump" ); static const ter_str_id ter_t_trunk( "t_trunk" ); @@ -1213,6 +1217,16 @@ static activity_reason_info can_do_activity_there( const activity_id &act, Chara } } if( !corpses.empty() ) { + for( item &body : corpses ) { + const mtype &corpse = *body.get_mtype(); + // TODO: Extract this bool into a function + const bool is_human = corpse.id == mtype_id::NULL_ID() || ( ( corpse.in_species( species_HUMAN ) || + corpse.in_species( species_FERAL ) ) && + !corpse.in_species( species_ZOMBIE ) ); + if( is_human && !you.okay_with_eating_humans() ) { + return activity_reason_info::fail( do_activity_reason::REFUSES_THIS_WORK ); + } + } if( big_count > 0 && small_count == 0 ) { if( !b_rack_present ) { return activity_reason_info::fail( do_activity_reason::NO_ZONE ); @@ -2742,6 +2756,14 @@ static requirement_check_result generic_multi_activity_check_requirement( if( can_do_it ) { return requirement_check_result::CAN_DO_LOCATION; } + if( reason == do_activity_reason::REFUSES_THIS_WORK ) { + you.add_msg_if_player( m_info, + _( "There's a human corpse there. You wouldn't want to butcher it by accident." ) ); + if( you.is_npc() ) { + add_msg_if_player_sees( you, m_info, _( "%s refuses to butcher a human corpse." ), + you.disp_name() ); + } + } if( reason == do_activity_reason::DONT_HAVE_SKILL || reason == do_activity_reason::NO_ZONE || reason == do_activity_reason::ALREADY_DONE || diff --git a/src/character.h b/src/character.h index 83169225be830..be8591951460f 100644 --- a/src/character.h +++ b/src/character.h @@ -3386,6 +3386,8 @@ class Character : public Creature, public visitable int nutrition_for( const item &comest ) const; /** Can the food be [theoretically] eaten no matter the consequences? */ ret_val can_eat( const item &food ) const; + /** Would this character be normally willing to consume human flesh? */ + bool okay_with_eating_humans() const; /** * Same as @ref can_eat, but takes consequences into account. * Asks about them if @param interactive is true, refuses otherwise. diff --git a/src/consumption.cpp b/src/consumption.cpp index 73a76e90fa68d..e779033e3180a 100644 --- a/src/consumption.cpp +++ b/src/consumption.cpp @@ -955,6 +955,12 @@ ret_val Character::can_eat( const item &food ) const return ret_val::make_success(); } +bool Character::okay_with_eating_humans() const +{ + return has_flag( STATIC( json_character_flag( "CANNIBAL" ) ) ) || + has_flag( json_flag_PSYCHOPATH ) || has_flag( json_flag_SAPIOVORE ); +} + ret_val Character::will_eat( const item &food, bool interactive ) const { ret_val ret = can_eat( food ); @@ -989,8 +995,7 @@ ret_val Character::will_eat( const item &food, bool interactive ) const bool food_is_human_flesh = food.has_vitamin( vitamin_human_flesh_vitamin ) || ( food.has_flag( flag_STRICT_HUMANITARIANISM ) && !has_flag( json_flag_STRICT_HUMANITARIAN ) ); - if( ( food_is_human_flesh && !has_flag( STATIC( json_character_flag( "CANNIBAL" ) ) ) && - !has_flag( json_flag_PSYCHOPATH ) && !has_flag( json_flag_SAPIOVORE ) ) && + if( ( food_is_human_flesh && !okay_with_eating_humans() ) && ( !food.has_flag( flag_HEMOVORE_FUN ) || ( !has_flag( json_flag_BLOODFEEDER ) ) ) ) { add_consequence( _( "The thought of eating human flesh makes you feel sick." ), CANNIBALISM ); } From ff57283ab33331ad86e1402790c0319b7e429a3e Mon Sep 17 00:00:00 2001 From: RenechCDDA <84619419+RenechCDDA@users.noreply.github.com> Date: Sun, 17 Nov 2024 14:15:01 -0500 Subject: [PATCH 2/7] Cannibal food is worthless --- data/json/vitamin.json | 1 + src/item.cpp | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/data/json/vitamin.json b/data/json/vitamin.json index d724eb2457ab3..f3dd1c7d6300a 100644 --- a/data/json/vitamin.json +++ b/data/json/vitamin.json @@ -517,6 +517,7 @@ "type": "vitamin", "vit_type": "counter", "name": { "str": "Consumed human flesh" }, + "flags": [ "NO_SELL" ], "min": 0, "max": 10000, "rate": "1 h" diff --git a/src/item.cpp b/src/item.cpp index f3c921fa82bfc..7632fae5649dc 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -225,6 +225,7 @@ static const vitamin_id vitamin_human_flesh_vitamin( "human_flesh_vitamin" ); // vitamin flags static const std::string flag_NO_DISPLAY( "NO_DISPLAY" ); +static const std::string flag_NO_SELL( "NO_SELL" ); // fault flags static const std::string flag_BLACKPOWDER_FOULING_DAMAGE( "BLACKPOWDER_FOULING_DAMAGE" ); @@ -7115,6 +7116,15 @@ int item::price_no_contents( bool practical, std::optional price_override ) price *= fault->price_mod(); } + if( is_food() && get_comestible() ) { + const nutrients &nutrients_value = default_character_compute_effective_nutrients( *this ); + for( const std::pair &vit_pair : nutrients_value.vitamins() ) { + if( vit_pair.second > 0 && vit_pair.first->has_flag( flag_NO_SELL ) ) { + price = 0.0; + } + } + } + return price; } From 3f676200d4ba41020d8ce1e554afd559cb40b021 Mon Sep 17 00:00:00 2001 From: RenechCDDA <84619419+RenechCDDA@users.noreply.github.com> Date: Sun, 17 Nov 2024 14:45:17 -0500 Subject: [PATCH 3/7] Get/set faction food supply's vitamins through json --- doc/NPCs.md | 2 +- src/math_parser_diag.cpp | 17 +++++++++++++---- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/doc/NPCs.md b/doc/NPCs.md index 3e03c090324b6..bbd3c0d21d2ec 100644 --- a/doc/NPCs.md +++ b/doc/NPCs.md @@ -1350,7 +1350,7 @@ _some functions support array arguments or kwargs, denoted with square brackets | effect_duration(`s`/`v`) | ✅ | ✅ | u, n | Return the characters duration of effect.
Argument is effect ID.

Optional kwargs:
`bodypart`: `s`/`v` - Specify the bodypart to get/set duration of effect.
`unit`: `s`/`v` - Specify the unit of the duration. Omitting will use seconds.

Example:
`"condition": { "math": [ "u_effect_duration('bite', 'bodypart': 'torso')", ">", "1"] }`
`{ "math": [ "_thing", "=", "u_effect_duration('yrax_overcharged', 'bodypart': 'torso', 'unit': 'hours')" ] }`| | encumbrance(`s`/`v`) | ✅ | ❌ | u, n | Return the characters total encumbrance of a body part.
Argument is bodypart ID.
For items, returns typical encumbrance of the item.

Example:
`"condition": { "math": [ "u_encumbrance('torso')", ">", "0"] }`| | energy(`s`/`v`) | ✅ | ❌ | u, n | Return a numeric value (in millijoules) for an energy string (see [Units](JSON_INFO.md#units)).

Example:
`{ "math": [ "u_val('power')", "-=", "energy('25 kJ')" ] }`| -| faction_like(`s`/`v`)
faction_respect(`s`/`v`)
faction_trust(`s`/`v`)
faction_food_supply(`s`/`v`)
faction_wealth(`s`/`v`)
faction_power(`s`/`v`)
faction_size(`s`/`v`) | ✅ | ✅ | N/A
(global) | Return the like/respect/trust/fac_food_supply/wealth/power/size value a faction has for the avatar.
Argument is faction ID.

Example:
`"condition": { "math": [ "faction_like('hells_raiders') < -60" ] }`| +| faction_like(`s`/`v`)
faction_respect(`s`/`v`)
faction_trust(`s`/`v`)
faction_food_supply(`s`/`v`)
faction_wealth(`s`/`v`)
faction_power(`s`/`v`)
faction_size(`s`/`v`) | ✅ | ✅ | N/A
(global) | Return the like/respect/trust/fac_food_supply/wealth/power/size value a faction has for the avatar.
Argument is faction ID.
`faction_food_supply` has an optional second argument(kwarg) for getting/setting vitamins.

Example:
`"condition": { "math": [ "faction_like('hells_raiders') < -60" ] }`

`{ "math": [ "calcium_amount", "=", "faction_food_supply('your_followers', 'vitamin':'calcium')" ] },`
`{ "u_message": "Calcium stored is ", "type": "good" },`| | field_strength(`s`/`v`) | ✅ | ❌ | u, n, global | Return the strength of a field on the tile.
Argument is field ID.

Optional kwargs:
`location`: `v` - center search on this location

The `location` kwarg is mandatory in the global scope.

Examples:
`"condition": { "math": [ "u_field_strength('fd_blood')", ">", "5" ] }`

`"condition": { "math": [ "field_strength('fd_blood_insect', 'location': u_search_loc)", ">", "5" ] }`| | has_flag(`s`/`v`) | ✅ | ❌ | u, n | Check whether the actor has a flag. Meant to be used as condition for ternaries. Argument is trait ID.

Example:
`"condition": { "math": [ "u_blorg", "=", "u_has_flag('MUTATION_TRESHOLD') ? 100 : 15" ] }`| | has_trait(`s`/`v`) | ✅ | ❌ | u, n | Check whether the actor has a trait. Meant to be used as condition for ternaries. Argument is trait ID.

Example:
`"condition": { "math": [ "u_blorg", "=", "u_has_trait('FEEBLE') ? 100 : 15" ] }`| diff --git a/src/math_parser_diag.cpp b/src/math_parser_diag.cpp index 3dca58c37131d..9c72fe8d677d7 100644 --- a/src/math_parser_diag.cpp +++ b/src/math_parser_diag.cpp @@ -268,19 +268,28 @@ diag_assign_dbl_f faction_trust_ass( char /* scope */, std::vector c } diag_eval_dbl_f faction_food_supply_eval( char /* scope */, - std::vector const ¶ms, diag_kwargs const &/* kwargs */ ) + std::vector const ¶ms, diag_kwargs const &kwargs ) { - return [fac_val = params[0]]( const_dialogue const & d ) { + diag_value vit_val = kwargs.kwarg_or( "vitamin" ); + return [fac_val = params[0], vit_val]( const_dialogue const & d ) { faction *fac = g->faction_manager_ptr->get( faction_id( fac_val.str( d ) ) ); + if( !vit_val.is_empty() ) { + return static_cast( fac->food_supply.get_vitamin( vitamin_id( vit_val.str() ) ) ); + } return static_cast( fac->food_supply.calories ); }; } diag_assign_dbl_f faction_food_supply_ass( char /* scope */, - std::vector const ¶ms, diag_kwargs const &/* kwargs */ ) + std::vector const ¶ms, diag_kwargs const &kwargs ) { - return [fac_val = params[0]]( dialogue const & d, double val ) { + diag_value vit_val = kwargs.kwarg_or( "vitamin" ); + return [fac_val = params[0], vit_val]( dialogue const & d, double val ) { faction *fac = g->faction_manager_ptr->get( faction_id( fac_val.str( d ) ) ); + if( !vit_val.is_empty() ) { + fac->food_supply.add_vitamin( vitamin_id( vit_val.str() ), val ); + return; + } fac->food_supply.calories = val; }; } From 015eadd60d81286618c9adebb02f7ef199944491 Mon Sep 17 00:00:00 2001 From: RenechCDDA <84619419+RenechCDDA@users.noreply.github.com> Date: Sun, 17 Nov 2024 16:23:11 -0500 Subject: [PATCH 4/7] Refugee center exiles anyone that practices cannibalism --- .../Smokes/free_merchant_shopkeep_talk.json | 57 ++++++++++++++++--- 1 file changed, 50 insertions(+), 7 deletions(-) diff --git a/data/json/npcs/refugee_center/surface_staff/Smokes/free_merchant_shopkeep_talk.json b/data/json/npcs/refugee_center/surface_staff/Smokes/free_merchant_shopkeep_talk.json index db37cd6005a39..dbefe293fdf12 100644 --- a/data/json/npcs/refugee_center/surface_staff/Smokes/free_merchant_shopkeep_talk.json +++ b/data/json/npcs/refugee_center/surface_staff/Smokes/free_merchant_shopkeep_talk.json @@ -37,9 +37,13 @@ }, { "text": "Let's trade.", - "topic": "TALK_FREE_MERCHANTS_MERCHANT_DoneTrading", "condition": { "compare_string": [ "yes", { "u_val": "general_meeting_u_met_Gavin" } ] }, - "effect": "start_trade" + "trial": { + "type": "CONDITION", + "condition": { "math": [ "faction_food_supply('free_merchants', 'vitamin':'human_flesh_vitamin')", "<", "1" ] } + }, + "success": { "effect": "start_trade", "topic": "TALK_FREE_MERCHANTS_MERCHANT_DoneTrading" }, + "failure": { "topic": "TALK_FREE_MERCHANTS_MERCHANT_CANNIBAL_GTFO" } }, { "text": "Just saying hello. Keep safe.", @@ -55,7 +59,15 @@ "speaker_effect": [ { "effect": "distribute_food_auto" } ], "responses": [ { "text": "About other things…", "topic": "TALK_FREE_MERCHANTS_MERCHANT_Talk" }, - { "text": "Let's trade.", "topic": "TALK_FREE_MERCHANTS_MERCHANT_DoneTrading", "effect": "start_trade" }, + { + "text": "Let's trade.", + "trial": { + "type": "CONDITION", + "condition": { "math": [ "faction_food_supply('free_merchants', 'vitamin':'human_flesh_vitamin')", "<", "1" ] } + }, + "success": { "effect": "start_trade", "topic": "TALK_FREE_MERCHANTS_MERCHANT_DoneTrading" }, + "failure": { "topic": "TALK_FREE_MERCHANTS_MERCHANT_CANNIBAL_GTFO" } + }, { "text": "When will you have new stuff in stock?", "topic": "TALK_FREE_MERCHANTS_MERCHANT_AskedRestock" }, { "text": "That's all for now. ", "topic": "TALK_DONE" } ] @@ -94,7 +106,15 @@ ], "responses": [ { "text": "Got some time to talk?", "topic": "TALK_FREE_MERCHANTS_MERCHANT_Talk" }, - { "text": "Let's trade.", "topic": "TALK_FREE_MERCHANTS_MERCHANT_DoneTrading", "effect": "start_trade" }, + { + "text": "Let's trade.", + "trial": { + "type": "CONDITION", + "condition": { "math": [ "faction_food_supply('free_merchants', 'vitamin':'human_flesh_vitamin')", "<", "1" ] } + }, + "success": { "effect": "start_trade", "topic": "TALK_FREE_MERCHANTS_MERCHANT_DoneTrading" }, + "failure": { "topic": "TALK_FREE_MERCHANTS_MERCHANT_CANNIBAL_GTFO" } + }, { "text": "I just wanted to look around. ", "topic": "TALK_DONE" } ] }, @@ -162,7 +182,15 @@ "topic": "TALK_FREE_MERCHANTS_MERCHANT_OutsideWorld" }, { "text": "I'm looking for work. Can I do anything for the center?", "topic": "TALK_MISSION_LIST" }, - { "text": "Let's trade.", "topic": "TALK_FREE_MERCHANTS_MERCHANT_DoneTrading", "effect": "start_trade" }, + { + "text": "Let's trade.", + "trial": { + "type": "CONDITION", + "condition": { "math": [ "faction_food_supply('free_merchants', 'vitamin':'human_flesh_vitamin')", "<", "1" ] } + }, + "success": { "effect": "start_trade", "topic": "TALK_FREE_MERCHANTS_MERCHANT_DoneTrading" }, + "failure": { "topic": "TALK_FREE_MERCHANTS_MERCHANT_CANNIBAL_GTFO" } + }, { "text": "Are you interested in buying any processed lumber?", "topic": "TALK_EVAC_MERCHANT_DEAL_NEGOTIATE", @@ -303,8 +331,12 @@ }, { "text": "Mind if I take a look at your stock?", - "topic": "TALK_FREE_MERCHANTS_MERCHANT_DoneTrading", - "effect": "start_trade" + "trial": { + "type": "CONDITION", + "condition": { "math": [ "faction_food_supply('free_merchants', 'vitamin':'human_flesh_vitamin')", "<", "1" ] } + }, + "success": { "effect": "start_trade", "topic": "TALK_FREE_MERCHANTS_MERCHANT_DoneTrading" }, + "failure": { "topic": "TALK_FREE_MERCHANTS_MERCHANT_CANNIBAL_GTFO" } }, { "text": "Radios? That seems awfully specific.", "topic": "TALK_FREE_MERCHANTS_MERCHANT_SellingHardware1" }, { "text": "Good to know.", "topic": "TALK_FREE_MERCHANTS_MERCHANT_Talk" } @@ -329,6 +361,17 @@ { "text": "I'll keep that in mind.", "topic": "TALK_FREE_MERCHANTS_MERCHANT_Talk" } ] }, + { + "id": "TALK_FREE_MERCHANTS_MERCHANT_CANNIBAL_GTFO", + "type": "talk_topic", + "dynamic_line": "Listen, buddy. We were putting away some of the last food you gave us and noticed it was… off. Okay I'll cut the shit- It was people. I don't know how you got it, or what you did, but we aren't taking any chances. You are not welcome here anymore. I'll give you one minute to fuck off and never come back.", + "speaker_effect": [ + { + "effect": [ "end_conversation", { "run_eocs": [ "EOC_GAVE_BEGGAR_CANNIBAL_PROOF" ], "time_in_future": "1 minutes" } ] + } + ], + "responses": [ { "text": "But I-", "topic": "TALK_DONE" } ] + }, { "id": "TALK_EVAC_MERCHANT_DEAL_NEGOTIATE", "type": "talk_topic", From 86325b6f41c439ceb6b1343cb150de6babde36e6 Mon Sep 17 00:00:00 2001 From: RenechCDDA <84619419+RenechCDDA@users.noreply.github.com> Date: Sun, 17 Nov 2024 17:23:53 -0500 Subject: [PATCH 5/7] Correctly check for cannibalism in all butchery paths (with or without human dissection proficiency) Actually check affected NPC opinions and make_angry if need be Witnessing NPCs that are upset will comment on it (to make it apparent the source of their anger) --- src/activity_handlers.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/activity_handlers.cpp b/src/activity_handlers.cpp index 03f7b2b9ca793..f39ef0d820cdc 100644 --- a/src/activity_handlers.cpp +++ b/src/activity_handlers.cpp @@ -492,9 +492,14 @@ static bool do_cannibalism_piss_people_off( Character &you ) for( npc &guy : g->all_npcs() ) { if( guy.is_active() && guy.sees( you ) && !guy.okay_with_eating_humans() ) { + guy.say( _( "? Are you butchering them? That's not okay, ." ) ); // massive opinion penalty guy.op_of_u.trust -= 5; guy.op_of_u.value -= 5; + guy.op_of_u.anger += 5; + if( guy.turned_hostile() ) { + guy.make_angry(); + } } } return true; @@ -657,7 +662,7 @@ static void set_up_butchery( player_activity &act, Character &you, butcher_type } else { //this runs if the butcherer does NOT have prof_dissect_humans if( you.is_avatar() ) { - if( query_yn( _( "Would you dare desecrate the mortal remains of a fellow human being?" ) ) ) { + if( do_cannibalism_piss_people_off( you ) ) { //random message and morale penalty switch( rng( 1, 3 ) ) { case 1: From 774ce3848a69f5c312fed00c6489d044d6e8e8d6 Mon Sep 17 00:00:00 2001 From: RenechCDDA <84619419+RenechCDDA@users.noreply.github.com> Date: Mon, 18 Nov 2024 23:44:12 -0500 Subject: [PATCH 6/7] Use dialogue scoping for variable resolution Co-authored-by: andrei <68240139+andrei8l@users.noreply.github.com> --- src/math_parser_diag.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/math_parser_diag.cpp b/src/math_parser_diag.cpp index 9c72fe8d677d7..142a659be845b 100644 --- a/src/math_parser_diag.cpp +++ b/src/math_parser_diag.cpp @@ -274,7 +274,7 @@ diag_eval_dbl_f faction_food_supply_eval( char /* scope */, return [fac_val = params[0], vit_val]( const_dialogue const & d ) { faction *fac = g->faction_manager_ptr->get( faction_id( fac_val.str( d ) ) ); if( !vit_val.is_empty() ) { - return static_cast( fac->food_supply.get_vitamin( vitamin_id( vit_val.str() ) ) ); + return static_cast( fac->food_supply.get_vitamin( vitamin_id( vit_val.str( d ) ) ) ); } return static_cast( fac->food_supply.calories ); }; @@ -287,7 +287,7 @@ diag_assign_dbl_f faction_food_supply_ass( char /* scope */, return [fac_val = params[0], vit_val]( dialogue const & d, double val ) { faction *fac = g->faction_manager_ptr->get( faction_id( fac_val.str( d ) ) ); if( !vit_val.is_empty() ) { - fac->food_supply.add_vitamin( vitamin_id( vit_val.str() ), val ); + fac->food_supply.add_vitamin( vitamin_id( vit_val.str( d ) ), val ); return; } fac->food_supply.calories = val; From e970f2b0862c7e4a25c46b9b000949d6c227423c Mon Sep 17 00:00:00 2001 From: RenechCDDA <84619419+RenechCDDA@users.noreply.github.com> Date: Fri, 27 Dec 2024 07:14:47 -0500 Subject: [PATCH 7/7] Clang fix --- src/activity_handlers.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/activity_handlers.cpp b/src/activity_handlers.cpp index 2ef61d6c4b8a3..0ac4de7cbdc8f 100644 --- a/src/activity_handlers.cpp +++ b/src/activity_handlers.cpp @@ -207,10 +207,7 @@ static const itype_id itype_pseudo_magazine( "pseudo_magazine" ); static const json_character_flag json_flag_ASOCIAL1( "ASOCIAL1" ); static const json_character_flag json_flag_ASOCIAL2( "ASOCIAL2" ); -static const json_character_flag json_flag_CANNIBAL( "CANNIBAL" ); static const json_character_flag json_flag_PAIN_IMMUNE( "PAIN_IMMUNE" ); -static const json_character_flag json_flag_PSYCHOPATH( "PSYCHOPATH" ); -static const json_character_flag json_flag_SAPIOVORE( "SAPIOVORE" ); static const json_character_flag json_flag_SILENT_SPELL( "SILENT_SPELL" ); static const json_character_flag json_flag_SOCIAL1( "SOCIAL1" ); static const json_character_flag json_flag_SOCIAL2( "SOCIAL2" );