diff --git a/doc/EFFECT_ON_CONDITION.md b/doc/EFFECT_ON_CONDITION.md index 5affff8c927b5..b3da0aa11d282 100644 --- a/doc/EFFECT_ON_CONDITION.md +++ b/doc/EFFECT_ON_CONDITION.md @@ -530,6 +530,27 @@ checks is `victim_type` has `zombie` faction { "compare_string": [ "zombie", { "mutator": "mon_faction", "mtype_id": { "context_val": "victim_type" } } ] } ``` +### `u_profession` +- type: string or [variable object](##variable-object) +- Return true if player character has the given profession id or its "hobby" subtype + +#### Valid talkers: + +| Avatar | Character | NPC | Monster | Furniture | Item | +| ------ | --------- | --------- | ---- | ------- | --- | +| ✔️ | ✔️ | ❌ | ❌ | ❌ | ❌ | + +#### Examples +True if the character has selected Heist Driver profession at the character creation +```json +{ "u_profession": "heist_driver" } +``` + +True if the character has selected Fishing background at the character creation +```json +{ "u_profession": "fishing" } +``` + ### `u_has_strength`, `npc_has_strength`, `u_has_dexterity`, `npc_has_dexterity`, `u_has_intelligence`, `npc_has_intelligence`, `u_has_perception`, `npc_has_perception` - type: int or [variable object](##variable-object) - Return true if alpha or beta talker stat is at least the value or higher diff --git a/src/character.cpp b/src/character.cpp index 3c3633dbc52c7..badfb037ee30b 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -5248,6 +5248,16 @@ item Character::reduce_charges( item *it, int quantity ) return result; } +const profession *Character::get_profession() const +{ + return prof; +} + +std::set Character::get_hobbies() const +{ + return hobbies; +} + bool Character::has_mission_item( int mission_id ) const { return mission_id != -1 && has_item_with( has_mission_item_filter{ mission_id } ); diff --git a/src/character.h b/src/character.h index f0eee80ee42bc..30718348eb716 100644 --- a/src/character.h +++ b/src/character.h @@ -753,6 +753,11 @@ class Character : public Creature, public visitable virtual bool is_ally( const Character &p ) const = 0; virtual bool is_obeying( const Character &p ) const = 0; + //returns character's profession + const profession *get_profession() const; + //returns the hobbies + std::set get_hobbies() const; + // Has item with mission_id bool has_mission_item( int mission_id ) const; @@ -4057,4 +4062,4 @@ std::string get_stat_name( character_stat Stat ); extern template bool Character::can_lift( const item &obj ) const; extern template bool Character::can_lift( const vehicle &obj ) const; -#endif // CATA_SRC_CHARACTER_H \ No newline at end of file +#endif // CATA_SRC_CHARACTER_H diff --git a/src/condition.cpp b/src/condition.cpp index a735b5bd9af6e..da410e33a21a9 100644 --- a/src/condition.cpp +++ b/src/condition.cpp @@ -46,6 +46,7 @@ #include "overmapbuffer.h" #include "point.h" #include "popup.h" +#include "profession.h" #include "ranged.h" #include "recipe_groups.h" #include "talker.h" @@ -630,6 +631,28 @@ void conditional_t::set_u_safe_mode_trigger( const JsonObject &jo, std::string_v }; } +void conditional_t::set_u_profession( const JsonObject &jo, std::string_view member ) +{ + str_or_var u_profession = get_str_or_var( jo.get_member( member ), member, true ); + condition = [u_profession]( dialogue const & d ) { + const profession *prof = get_player_character().get_profession(); + std::set hobbies = get_player_character().get_hobbies(); + if( prof->get_profession_id() == profession_id( u_profession.evaluate( d ) ) ) { + return true; + } else if( profession_id( u_profession.evaluate( d ) )->is_hobby() ) { + for( const profession *hob : hobbies ) { + if( hob->get_profession_id() == profession_id( u_profession.evaluate( d ) ) ) { + return true; + } + break; + } + return false; + } else { + return false; + } + }; +} + void conditional_t::set_has_strength( const JsonObject &jo, std::string_view member, bool is_npc ) { @@ -3453,6 +3476,7 @@ parsers = { {"u_has_mission", jarg::string, &conditional_t::set_u_has_mission }, {"u_monsters_in_direction", jarg::string, &conditional_t::set_u_monsters_in_direction }, {"u_safe_mode_trigger", jarg::member, &conditional_t::set_u_safe_mode_trigger }, + {"u_profession", jarg::string, &conditional_t::set_u_profession }, {"u_has_strength", "npc_has_strength", jarg::member | jarg::array, &conditional_t::set_has_strength }, {"u_has_dexterity", "npc_has_dexterity", jarg::member | jarg::array, &conditional_t::set_has_dexterity }, {"u_has_intelligence", "npc_has_intelligence", jarg::member | jarg::array, &conditional_t::set_has_intelligence }, diff --git a/src/condition.h b/src/condition.h index 6b330243cbbd5..aea1323d7e422 100644 --- a/src/condition.h +++ b/src/condition.h @@ -103,6 +103,7 @@ struct conditional_t { void set_u_has_mission( const JsonObject &jo, std::string_view member ); void set_u_monsters_in_direction( const JsonObject &jo, std::string_view member ); void set_u_safe_mode_trigger( const JsonObject &jo, std::string_view member ); + void set_u_profession( const JsonObject &jo, std::string_view member ); void set_has_strength( const JsonObject &jo, std::string_view member, bool is_npc = false ); void set_has_dexterity( const JsonObject &jo, std::string_view member, bool is_npc = false ); void set_has_intelligence( const JsonObject &jo, std::string_view member, bool is_npc = false ); diff --git a/src/profession.cpp b/src/profession.cpp index 513d6f5650d2e..0625f8f19d25e 100644 --- a/src/profession.cpp +++ b/src/profession.cpp @@ -841,6 +841,11 @@ const return ret; } +profession_id profession::get_profession_id() const +{ + return id; +} + bool profession::is_hobby() const { return _subtype == "hobby"; diff --git a/src/profession.h b/src/profession.h index 3309041ad7d06..eddfb2792d4ab 100644 --- a/src/profession.h +++ b/src/profession.h @@ -135,6 +135,9 @@ class profession std::map spells() const; void learn_spells( avatar &you ) const; + //returns the profession id + profession_id get_profession_id() const; + /** * Check if this type of profession has a certain flag set. *