Skip to content

Commit

Permalink
add dynamic lone wolf faction to dynamic npcs
Browse files Browse the repository at this point in the history
remove debug messages

add get_bool() default choice
  • Loading branch information
David Brown committed Sep 14, 2019
1 parent faa20d1 commit 9155080
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 8 deletions.
9 changes: 5 additions & 4 deletions data/json/npcs/factions.json
Original file line number Diff line number Diff line change
Expand Up @@ -297,10 +297,11 @@
"likes_u": 0,
"respects_u": 0,
"known_by_u": false,
"size": 100,
"power": 100,
"food_supply": 172800,
"wealth": 2500000,
"size": 1,
"power": 1,
"food_supply": 1,
"lone_wolf_faction": true,
"wealth": 1,
"relations": {
"lobby_beggars": { "knows your voice": true },
"free_merchants": { "knows your voice": true },
Expand Down
6 changes: 4 additions & 2 deletions doc/FACTIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,17 @@ An NPC faction looks like this:
"size": 100,
"power": 100,
"food_supply": 115200,
"lone_wolf_faction": true,
"wealth": 75000000,
"currency": "FMCNote",
"relations": {
"relations": {
"free_merchants": {
"kill on sight": false,
"watch your back": true,
"share my stuff": true,
"guard your stuff": true,
"lets you in": true,
"defends your space": true,
"defends your space": true,
"knows your voice": true
},
"old_guard": {
Expand Down Expand Up @@ -57,6 +58,7 @@ Field | Meaning
`"currency"` | string, the item `"id"` of the faction's preferred currency. Faction shopkeeps will trade faction current at 100% value, for both selling and buying.
`"relations"` | dictionary, a description of how the faction sees other factions. See below
`"mon_faction"` | string, optional. The monster faction `"name"` of the monster faction that this faction counts as. Defaults to "human" if unspecified.
`"lone_wolf_faction"` | bool, optional. This is a proto/micro faction template that is used to generate 1-person factions for dynamically spawned NPCs, defaults to "false" if unspecified.

## Faction relations
Factions can have relations with each other that apply to each member of the faction. Faction relationships are not reciprocal: members of the Free Merchants will defend members of the Lobby Beggars, but members of the Lobby Beggars will not defend members of the Free Merchants.
Expand Down
7 changes: 6 additions & 1 deletion src/debug_menu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1062,7 +1062,12 @@ void debug()
temp->mission = NPC_MISSION_NULL;
temp->add_new_mission( mission::reserve_random( ORIGIN_ANY_NPC, temp->global_omt_location(),
temp->getID() ) );
temp->set_fac( faction_id( "no_faction" ) );
std::string new_fac_id = "solo_";
new_fac_id += temp->name;
// create a new "lone wolf" faction for this one NPC
faction *new_solo_fac = g->faction_manager_ptr->add_new_faction( temp->name,
faction_id( new_fac_id ), faction_id( "no_faction" ) );
temp->set_fac( new_solo_fac ? new_solo_fac->id : faction_id( "no_faction" ) );
g->load_npcs();
}
break;
Expand Down
33 changes: 33 additions & 0 deletions src/faction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ faction_template::faction_template()
wealth = 0;
size = 0;
power = 0;
lone_wolf_faction = false;
currency = "null";
}

Expand Down Expand Up @@ -96,6 +97,7 @@ faction_template::faction_template( JsonObject &jsobj )
} else {
currency = "null";
}
lone_wolf_faction = jsobj.get_bool( "lone_wolf_faction", false );
load_relations( jsobj );
mon_faction = jsobj.get_string( "mon_faction", "human" );
}
Expand Down Expand Up @@ -316,6 +318,21 @@ void faction_manager::clear()
factions.clear();
}

void faction_manager::remove_faction( const faction_id &id )
{
if( id.str().empty() || id == faction_id( "no_faction" ) ) {
return;
}
int index = 0;
for( faction &elem : factions ) {
if( id == elem.id ) {
factions.erase( factions.begin() + index );
return;
}
index++;
}
}

void faction_manager::create_if_needed()
{
if( !factions.empty() ) {
Expand All @@ -326,6 +343,21 @@ void faction_manager::create_if_needed()
}
}

faction *faction_manager::add_new_faction( const std::string &name_new, const faction_id &id_new,
const faction_id &template_id )
{
for( const faction_template &fac_temp : npc_factions::all_templates ) {
if( template_id == fac_temp.id ) {
faction fac( fac_temp );
fac.name = name_new;
fac.id = id_new;
factions.emplace_back( fac );
}
}
faction *ret = get( id_new );
return ret ? ret : nullptr;
}

faction *faction_manager::get( const faction_id &id )
{
for( faction &elem : factions ) {
Expand All @@ -334,6 +366,7 @@ faction *faction_manager::get( const faction_id &id )
for( const faction_template &fac_temp : npc_factions::all_templates ) {
if( fac_temp.id == id ) {
elem.currency = fac_temp.currency;
elem.lone_wolf_faction = fac_temp.lone_wolf_faction;
elem.name = fac_temp.name;
elem.desc = fac_temp.desc;
elem.mon_faction = fac_temp.mon_faction;
Expand Down
5 changes: 4 additions & 1 deletion src/faction.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ class faction_template
int power; // General measure of our power
int food_supply; //Total nutritional value held
int wealth; //Total trade currency
bool lone_wolf_faction; // is this a faction for just one person?
std::string currency; // itype_id of the faction currency
std::map<std::string, std::bitset<npc_factions::rel_types>> relations;
std::string mon_faction; // mon_faction_id of the monster faction; defaults to human
Expand Down Expand Up @@ -114,7 +115,9 @@ class faction_manager

void clear();
void create_if_needed();

faction *add_new_faction( const std::string &name_new, const faction_id &id_new,
const faction_id &template_id );
void remove_faction( const faction_id &id );
const std::vector<faction> &all() const {
return factions;
}
Expand Down
6 changes: 6 additions & 0 deletions src/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11007,6 +11007,12 @@ void game::perhaps_add_random_npc()
std::shared_ptr<npc> tmp = std::make_shared<npc>();
tmp->normalize();
tmp->randomize();
std::string new_fac_id = "solo_";
new_fac_id += tmp->name;
// create a new "lone wolf" faction for this one NPC
faction *new_solo_fac = faction_manager_ptr->add_new_faction( tmp->name, faction_id( new_fac_id ),
faction_id( "no_faction" ) );
tmp->set_fac( new_solo_fac ? new_solo_fac->id : faction_id( "no_faction" ) );
// adds the npc to the correct overmap.
tmp->spawn_at_sm( msx, msy, 0 );
overmap_buffer.insert_npc( tmp );
Expand Down
4 changes: 4 additions & 0 deletions src/npc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2088,6 +2088,10 @@ void npc::die( Creature *nkiller )
critter->mounted_player = nullptr;
critter->mounted_player_id = character_id();
}
// if this NPC was the only member of a micro-faction, clean it up.
if( my_fac && my_fac->lone_wolf_faction ) {
g->faction_manager_ptr->remove_faction( fac_id );
}
dead = true;
Character::die( nkiller );

Expand Down

0 comments on commit 9155080

Please sign in to comment.