Skip to content

Commit

Permalink
Recursive proficiency learning for NPC class definitions
Browse files Browse the repository at this point in the history
  • Loading branch information
RenechCDDA committed May 22, 2024
1 parent 7b15057 commit ce06b54
Show file tree
Hide file tree
Showing 6 changed files with 13 additions and 8 deletions.
3 changes: 2 additions & 1 deletion doc/NPCs.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ Format:
"id": "NC_EXAMPLE", // Mandatory, unique id that refers to this class.
"name": { "str": "Example NPC" }, // Mandatory, display name for this class.
"job_description": "I'm helping you learn the game.", // Mandatory
"common": false, // Optional. Whether or not this class can appear via random generation.
"common": false, // Optional, defaults true. Whether or not this class can appear via random generation. Randomly generated NPCs will have skills, proficiencies, and bionics applied to them as a default new player character would.
"sells_belongings": false, // Optional. See [Shopkeeper NPC configuration](#shopkeeper-npc-configuration)
"bonus_str": { "rng": [ -4, 0 ] }, // Optional. Modifies stat by the given value. This example shows a random distribution between -4 and 0.
"bonus_dex": 100, // Optional. This example always adds exactly 100 to the stat.
Expand Down Expand Up @@ -72,6 +72,7 @@ Format:
],
"shopkeeper_blacklist": "test_blacklist",
"restock_interval": "6 days",
"proficiencies": [ "prof_gunsmithing_basic", "prof_spotting" ], // Optional. Note that prereqs do not need to be defined. NPCs of this class will learn this proficiency *and all pre-requesite proficiencies*.
"traits": [ { "group": "BG_survival_story_EVACUEE" }, { "group": "NPC_starting_traits" }, { "group": "Appearance_demographics" } ] // Optional
}
```
Expand Down
3 changes: 2 additions & 1 deletion src/character.h
Original file line number Diff line number Diff line change
Expand Up @@ -2458,7 +2458,8 @@ class Character : public Creature, public visitable
float get_proficiency_practice( const proficiency_id &prof ) const;
time_duration get_proficiency_practiced_time( const proficiency_id &prof ) const;
bool has_prof_prereqs( const proficiency_id &prof ) const;
void add_proficiency( const proficiency_id &prof, bool ignore_requirements = false );
void add_proficiency( const proficiency_id &prof, bool ignore_requirements = false,
bool recursive = false );
void lose_proficiency( const proficiency_id &prof, bool ignore_requirements = false );
bool practice_proficiency( const proficiency_id &prof, const time_duration &amount,
const std::optional<time_duration> &max = std::nullopt );
Expand Down
5 changes: 3 additions & 2 deletions src/character_proficiency.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,14 @@ bool Character::has_prof_prereqs( const proficiency_id &prof ) const
return _proficiencies->has_prereqs( prof );
}

void Character::add_proficiency( const proficiency_id &prof, bool ignore_requirements )
void Character::add_proficiency( const proficiency_id &prof, bool ignore_requirements,
bool recursive )
{
if( ignore_requirements ) {
_proficiencies->direct_learn( prof );
return;
}
_proficiencies->learn( prof );
_proficiencies->learn( prof, recursive );
}

void Character::lose_proficiency( const proficiency_id &prof, bool ignore_requirements )
Expand Down
2 changes: 1 addition & 1 deletion src/npc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -688,7 +688,7 @@ void npc::randomize( const npc_class_id &type, const npc_template_id &tem_id )
}
// Add proficiencies
for( const proficiency_id &prof : myclass->_starting_proficiencies ) {
add_proficiency( prof );
add_proficiency( prof, false, true );
}
if( myclass->is_common() ) {
add_default_background();
Expand Down
6 changes: 4 additions & 2 deletions src/proficiency.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -365,11 +365,13 @@ void proficiency_set::set_time_practiced( const proficiency_id &practicing,
current.practiced = amount;
}

void proficiency_set::learn( const proficiency_id &learned )
void proficiency_set::learn( const proficiency_id &learned, bool recursive )
{
for( const proficiency_id &req : learned->required_proficiencies() ) {
if( !has_learned( req ) ) {
if( !has_learned( req ) && !recursive ) {
return;
} else if( recursive ) {
learn( req, recursive );
}
}
known.insert( learned );
Expand Down
2 changes: 1 addition & 1 deletion src/proficiency.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ class proficiency_set
// True if the proficiency is learned;
bool practice( const proficiency_id &practicing, const time_duration &amount,
float remainder, const std::optional<time_duration> &max );
void learn( const proficiency_id &learned );
void learn( const proficiency_id &learned, bool recursive = false );
void remove( const proficiency_id &lost );

// Ignore requirements, made for debugging
Expand Down

0 comments on commit ce06b54

Please sign in to comment.