Skip to content

Commit

Permalink
Merge pull request CleverRaven#49857 from Ramza13/morale_json
Browse files Browse the repository at this point in the history
Add morale and focus functions
  • Loading branch information
kevingranade authored Jul 23, 2021
2 parents d70fed3 + 87a6eb4 commit bb34304
Show file tree
Hide file tree
Showing 8 changed files with 125 additions and 3 deletions.
5 changes: 5 additions & 0 deletions doc/NPCs.md
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,9 @@ Effect | Description
`u_mod_fatigue: fatigue_int`<br/>`npc_mod_fatigue: fatigue_int` | Your character or the NPC will have `fatigue_int` added or subtracted from its fatigue.
`u_make_sound, npc_make_sound: message_string`, `volume: volume_int`, `type: type_string`, | A sound of description `message_string` will be made at your character or the NPC's location of volume `volume_int` and type `type_string`. Possible types are: background, weather, music, movement, speech, electronic_speech, activity, destructive_activity, alarm, combat, alert, or order
`u_mod_healthy, npc_mod_healthy : amount_int, cap: cap_int` | Your character or the NPC will have `amount_int` added or subtracted from its health value, but not beyond `cap_int`.
`u_add_morale: morale_string`, (*optional* `bonus: bonus_int` ), (*optional* `max_bonus: max_bonus_int` ), (*optional* `duration: duration_int`), (*optional* `decay_start` : `decay_int`), (*optional* `capped`: `capped_bool`)<br/> `npc_add_morale: morale_string`, (*optional* `bonus: bonus_int` ), (*optional* `max_bonus: max_bonus_int` ), (*optional* `duration: duration_int`), (*optional*`decay_start` : `decay_int`), (*optional* `capped`: `capped_bool`)| Your character or the NPC will gain a morale bonus of type `morale_string`. Morale is changed by `bonus_int` (default 1), with a maximum of up to `max_bonus_int` (default 1). It will last for `duration: duration_int` seconds (default 1 hour). It will begin to decay after `decay_int` seconds (default 0.5 hours). `capped_bool` Whether this morale is capped or not, defaults to false.
`u_lose_morale: morale_string`<br/>`npc_lose_morale: morale_string` | Your character or the NPC will lose any morale of type `morale_string`.
`u_mod_focus: focus_int`<br/>`npc_mod_focus: focus_int` | Your character or the NPC will have `focus_int` added or subtracted from its focus.

#### Trade / Items

Expand Down Expand Up @@ -644,6 +647,8 @@ Condition | Type | Description
`"u_has_power"`<br/>`"npc_has_power"` | int | `true` if the player character's or NPC's bionic power is at least the value of `u_has_power` or `npc_has_power`.
`"u_can_see"`<br/>`"npc_can_see"` | simple string | `true` if the player character or NPC is not blind and is either not sleeping or has the see_sleep trait.
`"u_is_deaf"`<br/>`"npc_is_deaf"` | int | `true` if the player character or NPC can't hear.
`"u_has_focus"`<br/>`"npc_has_focus"` | int | `true` if the player character's or NPC's focus is at least the value of `u_has_focus` or `npc_has_focus`.
`"u_has_morale"`<br/>`"npc_has_morale"` | int | `true` if the player character's or NPC's morale is at least the value of `u_has_morale` or `npc_has_morale`.

#### Player Only conditions

Expand Down
28 changes: 28 additions & 0 deletions src/condition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,26 @@ void conditional_t<T>::set_has_effect( const JsonObject &jo, const std::string &
};
}

template<class T>
void conditional_t<T>::set_has_morale( const JsonObject &jo, const std::string &member,
bool is_npc )
{
const int min_morale = jo.get_int( member );
condition = [min_morale, is_npc]( const T & d ) {
return d.actor( is_npc )->morale_cur() >= min_morale;
};
}

template<class T>
void conditional_t<T>::set_has_focus( const JsonObject &jo, const std::string &member,
bool is_npc )
{
const int min_focus = jo.get_int( member );
condition = [min_focus, is_npc]( const T & d ) {
return d.actor( is_npc )->focus_cur() >= min_focus;
};
}

template<class T>
void conditional_t<T>::set_need( const JsonObject &jo, const std::string &member, bool is_npc )
{
Expand Down Expand Up @@ -1149,10 +1169,18 @@ conditional_t<T>::conditional_t( const JsonObject &jo )
set_has_pain( jo, "u_has_pain" );
} else if( jo.has_member( "npc_has_pain" ) ) {
set_has_pain( jo, "npc_has_pain", is_npc );
} else if( jo.has_int( "u_has_morale" ) ) {
set_has_morale( jo, "u_has_morale" );
} else if( jo.has_int( "npc_has_morale" ) ) {
set_has_morale( jo, "npc_has_morale", is_npc );
} else if( jo.has_member( "u_has_power" ) ) {
set_has_power( jo, "u_has_power" );
} else if( jo.has_member( "npc_has_power" ) ) {
set_has_power( jo, "npc_has_power", is_npc );
} else if( jo.has_int( "u_has_focus" ) ) {
set_has_focus( jo, "u_has_focus" );
} else if( jo.has_int( "npc_has_focus" ) ) {
set_has_focus( jo, "npc_has_focus", is_npc );
} else if( jo.has_string( "is_weather" ) ) {
set_is_weather( jo );
} else {
Expand Down
5 changes: 3 additions & 2 deletions src/condition.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ const std::unordered_set<std::string> complex_conds = { {
"u_compare_time_since_var", "npc_compare_time_since_var", "is_weather", "one_in_chance",
"is_temperature", "is_windpower", "is_humidity", "is_pressure", "u_is_height", "npc_is_height",
"u_has_worn_with_flag", "npc_has_worn_with_flag", "u_has_wielded_with_flag", "npc_has_wielded_with_flag",
"u_has_pain", "npc_has_pain", "u_has_power", "npc_has_power"
"u_has_pain", "npc_has_pain", "u_has_power", "npc_has_power", "u_has_focus", "npc_has_focus", "u_has_morale", "npc_has_morale"
}
};
} // namespace dialogue_data
Expand Down Expand Up @@ -156,7 +156,8 @@ struct conditional_t {
void set_u_know_recipe( const JsonObject &jo, const std::string &member );
void set_mission_has_generic_rewards();
void set_can_see( bool is_npc = false );

void set_has_morale( const JsonObject &jo, const std::string &member, bool is_npc = false );
void set_has_focus( const JsonObject &jo, const std::string &member, bool is_npc = false );
bool operator()( const T &d ) const {
if( !condition ) {
return false;
Expand Down
4 changes: 3 additions & 1 deletion src/dialogue.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,9 @@ struct talk_effect_fun_t {
const translation &name );
void set_u_learn_recipe( const std::string &learned_recipe_id );
void set_npc_first_topic( const std::string &chat_topic );

void set_mod_focus( const JsonObject &jo, const std::string &member, bool is_npc );
void set_add_morale( const JsonObject &jo, const std::string &member, bool is_npc );
void set_lose_morale( const JsonObject &jo, const std::string &member, bool is_npc );
void operator()( const dialogue &d ) const {
if( !function ) {
return;
Expand Down
45 changes: 45 additions & 0 deletions src/npctalk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2316,6 +2316,39 @@ void talk_effect_fun_t::set_queue_effect_on_condition( const JsonObject &jo,
}
};
}
void talk_effect_fun_t::set_add_morale( const JsonObject &jo, const std::string &member,
bool is_npc )
{
std::string new_type = jo.get_string( member );
int bonus = jo.get_int( "bonus" );
int max_bonus = jo.get_int( "max_bonus", 0 );
time_duration duration = time_duration::from_seconds( jo.get_int( "duration", 3600 ) );
time_duration decay_start = time_duration::from_seconds( jo.get_int( "decay_start", 1800 ) );
const bool capped = jo.get_bool( "capped", false );
function = [is_npc, new_type, bonus, max_bonus, duration, decay_start,
capped]( const dialogue & d ) {
d.actor( is_npc )->add_morale( morale_type( new_type ), bonus, max_bonus, duration, decay_start,
capped );
};
}

void talk_effect_fun_t::set_lose_morale( const JsonObject &jo, const std::string &member,
bool is_npc )
{
std::string old_morale = jo.get_string( member );
function = [is_npc, old_morale]( const dialogue & d ) {
d.actor( is_npc )->remove_morale( morale_type( old_morale ) );
};
}

void talk_effect_fun_t::set_mod_focus( const JsonObject &jo, const std::string &member,
bool is_npc )
{
int amount = jo.get_int( member );
function = [is_npc, amount]( const dialogue & d ) {
d.actor( is_npc )->mod_focus( amount );
};
}

void talk_effect_t::set_effect_consequence( const talk_effect_fun_t &fun,
dialogue_consequence con )
Expand Down Expand Up @@ -2586,6 +2619,18 @@ void talk_effect_t::parse_sub_effect( const JsonObject &jo )
subeffect_fun.set_mod_healthy( jo, "u_mod_healthy", false );
} else if( jo.has_member( "npc_mod_healthy" ) ) {
subeffect_fun.set_mod_healthy( jo, "npc_mod_healthy", true );
} else if( jo.has_int( "u_mod_focus" ) ) {
subeffect_fun.set_mod_focus( jo, "u_mod_focus", false );
} else if( jo.has_int( "npc_mod_focus" ) ) {
subeffect_fun.set_mod_focus( jo, "npc_mod_focus", true );
} else if( jo.has_string( "u_add_morale" ) ) {
subeffect_fun.set_add_morale( jo, "u_add_morale", false );
} else if( jo.has_string( "npc_add_morale" ) ) {
subeffect_fun.set_add_morale( jo, "npc_add_morale", true );
} else if( jo.has_string( "u_lose_morale" ) ) {
subeffect_fun.set_lose_morale( jo, "u_lose_morale", false );
} else if( jo.has_string( "npc_lose_morale" ) ) {
subeffect_fun.set_lose_morale( jo, "npc_lose_morale", true );
} else {
jo.throw_error( "invalid sub effect syntax: " + jo.str() );
}
Expand Down
9 changes: 9 additions & 0 deletions src/talker.h
Original file line number Diff line number Diff line change
Expand Up @@ -333,5 +333,14 @@ class talker
return 0_kJ;
}
virtual void mod_healthy_mod( int, int ) {};
virtual int morale_cur() const {
return 0;
}
virtual int focus_cur() const {
return 0;
}
virtual void mod_focus( int ) {}
virtual void add_morale( const morale_type &, int, int, time_duration, time_duration, bool ) {}
virtual void remove_morale( const morale_type & ) {}
};
#endif // CATA_SRC_TALKER_H
26 changes: 26 additions & 0 deletions src/talker_character.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -340,3 +340,29 @@ void talker_character::mod_healthy_mod( int amount, int cap )
{
me_chr->mod_healthy_mod( amount, cap );
}

int talker_character::morale_cur() const
{
return me_chr->get_morale_level();
}

void talker_character::add_morale( const morale_type &new_morale, int bonus, int max_bonus,
time_duration duration, time_duration decay_start, bool capped )
{
me_chr->add_morale( new_morale, bonus, max_bonus, duration, decay_start, capped );
}

void talker_character::remove_morale( const morale_type &old_morale )
{
me_chr->rem_morale( old_morale );
}

int talker_character::focus_cur() const
{
return me_chr->get_focus();
}

void talker_character::mod_focus( int amount )
{
me_chr->mod_focus( amount );
}
6 changes: 6 additions & 0 deletions src/talker_character.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,12 @@ class talker_character: public talker
void mod_pain( int amount ) override;
bool can_see() const override;
void mod_healthy_mod( int, int ) override;
int morale_cur() const override;
void add_morale( const morale_type &new_morale, int bonus, int max_bonus, time_duration duration,
time_duration decay_started, bool capped ) override;
void remove_morale( const morale_type &old_morale ) override;
int focus_cur() const override;
void mod_focus( int ) override;
protected:
talker_character() = default;
player *me_chr;
Expand Down

0 comments on commit bb34304

Please sign in to comment.