Skip to content

Commit

Permalink
Talk function for NPCs buying food at camp
Browse files Browse the repository at this point in the history
  • Loading branch information
RenechCDDA committed Sep 1, 2024
1 parent 0527e71 commit d75b37c
Show file tree
Hide file tree
Showing 8 changed files with 69 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
"id": "TALK_FREE_MERCHANTS_MERCHANT_DoneTrading",
"type": "talk_topic",
"dynamic_line": [ "Hope it helps.", "Give me second to write that down… okay, done.", "You know where to find me." ],
"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" },
Expand Down
1 change: 1 addition & 0 deletions doc/NPCs.md
Original file line number Diff line number Diff line change
Expand Up @@ -881,6 +881,7 @@ Effect | Description
`assign_guard` | Makes the NPC into a guard. If allied and at a camp, they will be assigned to that camp.
`stop_guard` | Releases the NPC from their guard duty (also see `assign_guard`). Friendly NPCs will return to following.
`start_camp` | The NPC will start a faction camp with the player.
`distribute_food_auto` | The NPC will immediately distribute all food on their tile and adjacent tiles into the local camp's larder. Requires that such a camp exists and that the NPC has access to that camp.
`wake_up` | Wakes up sleeping, but not sedated, NPCs.
`reveal_stats` | Reveals the NPC's stats, based on the player's skill at assessing them.
`end_conversation` | Ends the conversation and makes the NPC ignore you from now on.
Expand Down
4 changes: 3 additions & 1 deletion src/basecamp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -695,11 +695,13 @@ void basecamp::form_storage_zones( map &here, const tripoint_abs_ms &abspos )
if( here.check_vehicle_zones( here.get_abs_sub().z() ) ) {
mgr.cache_vzones();
}
// NPC camps may never have had bb_pos registered
validate_bb_pos( project_to<coords::ms>( omt_pos ) );
tripoint src_loc = here.getlocal( bb_pos ) + point_north;
std::vector<tripoint_abs_ms> possible_liquid_dumps;
if( mgr.has_near( zone_type_CAMP_STORAGE, abspos, 60 ) ) {
const std::vector<const zone_data *> zones = mgr.get_near_zones( zone_type_CAMP_STORAGE, abspos,
60 );
60, get_owner() );
// Find the nearest unsorted zone to dump objects at
if( !zones.empty() ) {
if( zones != storage_zones ) {
Expand Down
2 changes: 1 addition & 1 deletion src/basecamp.h
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ class basecamp
item make_fake_food( const nutrients &to_use ) const;
/// Takes all the food from the camp_food zone and increases the faction
/// food_supply
bool distribute_food();
bool distribute_food( bool player_command = true );
std::string name_display_of( const mission_id &miss_id );
void handle_hide_mission( const point &dir );
void handle_reveal_mission( const point &dir );
Expand Down
29 changes: 20 additions & 9 deletions src/faction_camp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5342,8 +5342,8 @@ bool basecamp::validate_sort_points()
zone_manager &mgr = zone_manager::get_manager();
map *here = &get_map();
const tripoint_abs_ms abspos = get_player_character().get_location();
if( !mgr.has_near( zone_type_CAMP_STORAGE, abspos, 60 ) ||
!mgr.has_near( zone_type_CAMP_FOOD, abspos, 60 ) ) {
if( !mgr.has_near( zone_type_CAMP_STORAGE, abspos, 60, get_owner() ) ||
!mgr.has_near( zone_type_CAMP_FOOD, abspos, 60, get_owner() ) ) {
if( query_yn( _( "You do not have sufficient sort zones. Do you want to add them?" ) ) ) {
return set_sort_points();
} else {
Expand Down Expand Up @@ -5732,15 +5732,22 @@ static const npc &getAverageJoe()
}

// mission support
bool basecamp::distribute_food()
bool basecamp::distribute_food( bool player_command )
{
if( !validate_sort_points() ) {
popup( _( "You do not have a camp food zone. Aborting…" ) );
if( player_command ) {
popup( _( "You do not have a camp food zone. Aborting…" ) );
} else {
debugmsg( "NPC-initiated food distribution at %s failed due to lacking zones", name );
}
return false;
}

bool distribute_vitamins = query_yn(
_( "Do you also wish to distribute comestibles without any calorie value (i.e. multivitamins, mutagens)?" ) );
bool distribute_vitamins = false; // NPCs only ever distribute food
if( player_command ) {
distribute_vitamins = query_yn(
_( "Do you also wish to distribute comestibles without any calorie value (i.e. multivitamins, mutagens)?" ) );
}

map &here = get_map();
zone_manager &mgr = zone_manager::get_manager();
Expand All @@ -5749,7 +5756,7 @@ bool basecamp::distribute_food()
}
const tripoint_abs_ms &abspos = get_dumping_spot();
const std::unordered_set<tripoint_abs_ms> &z_food =
mgr.get_near( zone_type_CAMP_FOOD, abspos, 60 );
mgr.get_near( zone_type_CAMP_FOOD, abspos, 60, nullptr, get_owner() );

double quick_rot = 0.6 + ( has_provides( "pantry" ) ? 0.1 : 0 );
double slow_rot = 0.8 + ( has_provides( "pantry" ) ? 0.05 : 0 );
Expand Down Expand Up @@ -5845,7 +5852,9 @@ bool basecamp::distribute_food()
}

if( nutrients_to_add.kcal() <= 0 && nutrients_to_add.vitamins().empty() ) {
popup( _( "No suitable items are located at the drop points…" ) );
if( player_command ) {
popup( _( "No suitable items are located at the drop points…" ) );
}
return false;
}

Expand All @@ -5857,7 +5866,9 @@ bool basecamp::distribute_food()
popup_msg = _( "You distribute vitamins and medicine to your companions." );
}

popup( popup_msg );
if( player_command ) {
popup( popup_msg );
}
camp_food_supply( nutrients_to_add );
return true;
}
Expand Down
1 change: 1 addition & 0 deletions src/npctalk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6913,6 +6913,7 @@ void talk_effect_t::parse_string_effect( const std::string &effect_id, const Jso
WRAP( clear_overrides ),
WRAP( pick_style ),
WRAP( do_disassembly ),
WRAP( distribute_food_auto ),
WRAP( nothing )
#undef WRAP
}
Expand Down
3 changes: 3 additions & 0 deletions src/npctalk.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,9 @@ void start_training_npc( npc & );
void start_training_seminar( npc &p );
void start_training_gen( Character &teacher, std::vector<Character *> &students, teach_domain &d );

// used for NPC camps
void distribute_food_auto( npc &p );

void wake_up( npc & );
void copy_npc_rules( npc &p );
void set_npc_pickup( npc &p );
Expand Down
39 changes: 39 additions & 0 deletions src/npctalk_funcs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,9 @@ static const mtype_id mon_chicken( "mon_chicken" );
static const mtype_id mon_cow( "mon_cow" );
static const mtype_id mon_horse( "mon_horse" );

static const zone_type_id zone_type_CAMP_FOOD( "CAMP_FOOD" );
static const zone_type_id zone_type_CAMP_STORAGE( "CAMP_STORAGE" );

struct itype;

static void spawn_animal( npc &p, const mtype_id &mon );
Expand Down Expand Up @@ -1266,6 +1269,42 @@ npc *pick_follower()
return followers[ menu.ret ];
}

void talk_function::distribute_food_auto( npc &p )
{
std::optional<basecamp *> bcp = overmap_buffer.find_camp( p.global_omt_location().xy() );
if( !bcp ) {
debugmsg( "distribute_food_auto called without a basecamp, aborting." );
return;
}
basecamp *npc_camp = *bcp;
if( !npc_camp->allowed_access_by( p ) ) {
debugmsg( "distribute_food_auto called on npc that isn't allowed to access local basecamp storage, aborting." );
return;
}

zone_manager &mgr = zone_manager::get_manager();
const tripoint_abs_ms &npc_abs_loc = p.get_location();
// 3x3 square with NPC in the center, includes NPC's tile and all adjacent ones, for overflow
const tripoint top_left = npc_abs_loc.raw() + point{-1, -1}; // Awful hack, zones want the raw value

Check failure on line 1288 in src/npctalk_funcs.cpp

View workflow job for this annotation

GitHub Actions / build (src)

Prefer constructing 'point' from named constant 'point_north_west' rather than explicit integer arguments. [cata-use-named-point-constants,-warnings-as-errors]
const tripoint bottom_right = npc_abs_loc.raw() + point{1, 1}; // Awful hack, zones want the raw value

Check failure on line 1289 in src/npctalk_funcs.cpp

View workflow job for this annotation

GitHub Actions / build (src)

Prefer constructing 'point' from named constant 'point_south_east' rather than explicit integer arguments. [cata-use-named-point-constants,-warnings-as-errors]
std::string zone_name = "ERROR IF YOU SEE THIS (dummy zone talk_function::distribute_food_auto)";
const faction_id &fac_id = p.get_fac_id();
mgr.add( zone_name, zone_type_CAMP_FOOD, fac_id, false, true, top_left, bottom_right );
mgr.add( zone_name, zone_type_CAMP_STORAGE, fac_id, false, true, top_left, bottom_right );
npc_camp->distribute_food( false );
// Now we clean up all camp zones, though there SHOULD only be the two we just made
auto lambda_remove_zones = [&mgr, &fac_id]( zone_type_id type_to_remove ) {
std::vector<zone_manager::ref_zone_data> p_zones = mgr.get_zones( fac_id );
for( zone_data &a_zone : p_zones ) {
if( a_zone.get_type() == type_to_remove ) {
mgr.remove( a_zone );
}
}
};
lambda_remove_zones( zone_type_CAMP_FOOD );
lambda_remove_zones( zone_type_CAMP_STORAGE );
}

void talk_function::copy_npc_rules( npc &p )
{
const npc *other = pick_follower();
Expand Down

0 comments on commit d75b37c

Please sign in to comment.