Skip to content

Commit

Permalink
Camp takeovers
Browse files Browse the repository at this point in the history
  • Loading branch information
RenechCDDA committed Jun 16, 2024
1 parent 9426fb3 commit 482fdba
Show file tree
Hide file tree
Showing 4 changed files with 128 additions and 0 deletions.
30 changes: 30 additions & 0 deletions data/json/effects_on_condition/misc_effect_on_condition.json
Original file line number Diff line number Diff line change
Expand Up @@ -162,5 +162,35 @@
"id": "morale_dislikes_sewer",
"type": "morale_type",
"text": "Dislikes being in sewer"
},
{
"type": "effect_on_condition",
"id": "EOC_TOOK_OVER_CAMP_NOTICE",
"eoc_type": "EVENT",
"required_event": "camp_taken_over",
"condition": { "expects_vars": [ "old_owner", "new_owner", "camp_name", "was_violent" ] },
"effect": [
{
"if": { "compare_string": [ "your_followers", { "context_val": "new_owner" } ] },
"then": {
"queue_eocs": {
"id": "EOC_camp_rumor_spread",
"effect": { "u_message": "Rumors of your takeover of <context_val:camp_name> have begun to spread…", "type": "mixed" }
},
"time_in_future": [ "7 days", "14 days" ]
},
"else": [
{
"//": "Don't bother player unless they even have a camp.",
"if": "u_has_camp",
"then": {
"u_message": "While you've been out of contact with the powers of <context_val:camp_name> it's been taken over by its enemies.",
"popup": true,
"type": "bad"
}
}
]
}
]
}
]
72 changes: 72 additions & 0 deletions src/basecamp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "clzones.h"
#include "color.h"
#include "debug.h"
#include "event_bus.h"
#include "faction.h"
#include "faction_camp.h"
#include "game.h"
Expand All @@ -28,6 +29,7 @@
#include "map.h"
#include "map_iterator.h"
#include "mapdata.h"
#include "messages.h"
#include "npc.h"
#include "output.h"
#include "overmap.h"
Expand Down Expand Up @@ -841,6 +843,76 @@ faction_id basecamp::get_owner()
return owner;
}

void basecamp::handle_takeover_by( faction_id new_owner, bool violent_takeover )
{
get_event_bus().send<event_type::camp_taken_over>( get_owner(), new_owner, name, violent_takeover );

// If anyone was somehow assigned here, they aren't any longer.
assigned_npcs.clear();
camp_workers.clear();

add_msg_debug( debugmode::DF_CAMPS, "Camp %s owned by %s is being taken over by %s!",
name, fac()->name, new_owner->name );

if( !violent_takeover ) {
set_owner( new_owner );
return;
}

// Since it was violent, the old owner is going to be upset.
// Currently only handles player faction, and very bluntly.
if( new_owner == get_player_character().get_faction()->id ) {
fac()->likes_u -= 100;
fac()->trusts_u -= 100;
}

int num_of_owned_camps = 0;
// Go over all camps in existence and count the ones belonging to current owner
// TODO: Remove this when camps stop being stored on the player
for( tripoint_abs_omt camp_loc : get_player_character().camps ) {
std::optional<basecamp *> bcp = overmap_buffer.find_camp( camp_loc.xy() );
if( !bcp ) {
continue;
}
basecamp *checked_camp = *bcp;
// Note: Will count current basecamp object as well
if( checked_camp->get_owner() == get_owner() ) {
add_msg_debug( debugmode::DF_CAMPS,
"Camp %s at %s is owned by %s, adding it to plunder calculations.",
checked_camp->name, checked_camp->camp_omt_pos().to_string(), get_owner()->name );
num_of_owned_camps++;
}
}

if( num_of_owned_camps < 1 ) {
debugmsg( "Tried to take over a camp owned by %s, but they somehow own no camps! Is the owner's faction id no longer valid?",
get_owner().c_str() );
// Also abort the rest
set_owner( new_owner );
return;
}

// The faction taking over also seizes resources proportional to the number of camps the previous owner had
// e.g. a single-camp faction has its entire stockpile plundered, a 10-camp faction has 10% transferred
nutrients captured_with_camp = fac()->food_supply / num_of_owned_camps;
nutrients taken_from_camp = -captured_with_camp;
camp_food_supply( taken_from_camp );
add_msg_debug( debugmode::DF_CAMPS,
"Food supplies of %s plundered by %d kilocalories! Total food supply reduced to %d kilocalories after losing %.1f%% of their camps.",
fac()->name, captured_with_camp.kcal(), fac()->food_supply.kcal(),
1.0 / static_cast<double>( num_of_owned_camps ) * 100.0 );
set_owner( new_owner );
int previous_days_of_food = camp_food_supply_days( MODERATE_EXERCISE );
camp_food_supply( captured_with_camp );
add_msg_debug( debugmode::DF_CAMPS,
"Food supply of new owner %s has increased to %d kilocalories due to takeover of camp %s!",
fac()->name, new_owner->food_supply.kcal(), name );
if( new_owner == get_player_character().get_faction()->id ) {
popup( _( "Through your looting of %s you found %d days worth of food and other resources." ),
name, camp_food_supply_days( MODERATE_EXERCISE ) - previous_days_of_food );
}
}

void basecamp::form_crafting_inventory()
{
map &here = get_camp_map();
Expand Down
4 changes: 4 additions & 0 deletions src/basecamp.h
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,10 @@ class basecamp
int camp_morale( int change = 0 ) const;

bool allowed_access_by( Character &guy, bool water_request = false ) const;
/* Transfers ownership of a camp and send an event signalling it. If violent_takeover, also applies relation
* maluses and transfers a proportional amount of the previous owner's food/resources to the new owner.
*/
void handle_takeover_by( faction_id new_owner, bool violent_takeover );
// recipes, gathering, and craft support functions
// from a direction
std::map<recipe_id, translation> recipe_deck( const point &dir ) const;
Expand Down
22 changes: 22 additions & 0 deletions src/iexamine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1984,6 +1984,28 @@ void iexamine::bulletin_board( Character &you, const tripoint &examp )
if( bcp ) {
basecamp *temp_camp = *bcp;
if( !temp_camp->allowed_access_by( you ) ) {
if( !you.is_avatar() ) {
return; // One day, NPCs may be able to use bulletin boards
}
// Checks the reality bubble for NPCs
std::vector<shared_ptr_fast<npc>> nearby_npcs = overmap_buffer.get_npcs_near_player( HALF_MAPSIZE );
bool unoccupied_camp = true;
for( npc_ptr &some_guy : nearby_npcs ) {
if( !some_guy ) {
continue;
} else if( some_guy->get_faction()->id == temp_camp->get_owner() ) {
unoccupied_camp = false;
}
}
if( unoccupied_camp &&
query_yn( _( "There's nobody here to protect %s. Do you want to claim ownership?" ),
temp_camp->camp_name() ) ) {
bool plunder = query_yn(
_( "Take whatever you can find from the stores? This may anger %s and their allies." ),
temp_camp->get_owner()->name );
temp_camp->handle_takeover_by( you.get_faction()->id, plunder );
return;
}
you.add_msg_if_player( _( "You don't run this camp, the board is useless to you." ) );
return;
}
Expand Down

0 comments on commit 482fdba

Please sign in to comment.