Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refugee center adds food you sell/give them to their camp storage #76105

Merged
merged 1 commit into from
Sep 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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_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 @@
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
Loading