Skip to content

Commit

Permalink
Apply different messages per intensity level (CleverRaven#65549)
Browse files Browse the repository at this point in the history
* Apply messages

* Update creature.cpp

* Update creature.cpp

* Revert "Update creature.cpp"

This reverts commit 9733773.

* Update effects.json

* Attempting to copy decay msgs to apply

* Update src/effect.cpp

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* Apply suggestions from code review

* Attempted Fixes

* Robusting makes me feel good

* cast to appease

* Update data/mods/Xedra_Evolved/effects/effects.json

* Update effects.json

* Update effects.json

* Update effects.json

* Update data/mods/Xedra_Evolved/effects/effects.json

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* Update data/mods/Xedra_Evolved/effects/effects.json

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: bombasticSlacks <dillon.matchett@gmail.com>
  • Loading branch information
3 people authored Jul 16, 2023
1 parent 6e02791 commit c5487bd
Show file tree
Hide file tree
Showing 8 changed files with 142 additions and 97 deletions.
39 changes: 31 additions & 8 deletions data/mods/Xedra_Evolved/effects/effects.json
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,18 @@
"id": "cheval_overdose",
"//": "Intensity 1 is a standard dosage of the drug. Further intensities reflect taking pills while the first dose hasn't worn off. It is not wise to do so.",
"name": [ "Energized", "Enflamed", "Arythmic", "Tachycardiac" ],
"apply_message": "These magickal trucker pills have kicked in and you feel great!",
"apply_message": [
[ "These magickal trucker pills have kicked in and you feel great!", "good" ],
[
"You shouldn't have taken this many pills. Your skin flushes and your nerves feel like they are on fire.",
"bad"
],
[ "Your heartbeat doesn't feel normal. Why on earth did you take more of these pills?", "bad" ],
[
"This might just be it, the big one. With no hospital available you're just going to have to ride it straight through Hell.",
"bad"
]
],
"decay_messages": [
[
"These magickal trucker pills have worn off and you feel rough. It might be best to go ahead and sleep through the hangover as best you can.",
Expand All @@ -233,27 +244,39 @@
[ "Your heartbeat slows into a somewhat normal rhythm but your skin is still on fire.", "good" ],
[ "The pain in your chest subsides but your heart is still beating in a concerning fashion.", "good" ]
],
"rating": "mixed",
"max_intensity": 4,
"blood_analysis_description": "Patient has dangerous levels of multiple chemicals in their blood. Sedation and restraint suggested.",
"base_mods": { "speed_mod": [ 10 ], "str_mod": [ 1 ], "stim_amount": [ 1 ], "stim_tick": [ 500 ], "stim_max_val": [ 50 ] },
"base_mods": {
"speed_mod": [ 10 ],
"str_mod": [ 1 ],
"stim_amount": [ 1 ],
"stim_tick": [ 500 ],
"stim_max_val": [ 50 ],
"hurt_chance": [ 1 ],
"hurt_tick": [ 15000 ],
"pain_amount": [ 0 ],
"pain_chance": [ 2 ],
"pain_tick": [ 400 ],
"hurt_amount": [ 1 ]
},
"scaling_mods": {
"perspiration_amount": [ 6 ],
"perspiration_min": [ 1 ],
"perspiration_chance": [ 2 ],
"perspiration_tick": [ 1500 ],
"perspiration_tick": [ 150 ],
"pain_amount": [ 10 ],
"pain_min": [ 1 ],
"pain_chance": [ 2 ],
"pain_tick": [ 6000 ],
"stim_max_val": [ 100 ]
"hurt_amount": [ 1 ],
"pain_tick": [ -100 ],
"hurt_tick": [ -4925 ],
"stim_max_val": [ 400 ]
}
},
{
"type": "effect_type",
"id": "cheval_withdrawal",
"rating": "bad",
"blood_analysis_description": "Heightened levels of organosulfur compounds, mercury, and silver.",
"blood_analysis_description": "Patient has multiple byproducts in blood stream suggesting extended drug binge.",
"base_mods": { "speed_mod": [ -15 ], "str_mod": [ -1 ], "stim_amount": [ -1 ], "stim_tick": [ 500 ], "stim_max_val": [ -50 ] }
},
{
Expand Down
14 changes: 14 additions & 0 deletions doc/EFFECTS_JSON.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,9 @@ if it doesn't exist.
"rating": "good" - Defaults to "neutral" if missing
```
This is used for how the messages when the effect is applied and removed are displayed. Also this affects "blood_analysis_description" (see below) field: effects with "good" rating will be colored green, effects with any other rating will be colored red when character conducts a blood analysis through some means.

If [apply_message](#advanced-apply_message) is an array you can't include this entry (it is handled with apply message).

Valid entries are:
```C++
"good"
Expand All @@ -181,6 +184,17 @@ If the "apply_message" or "remove_message" fields exist, the respective message
displayed upon the addition or removal of the effect. Note: "apply_message" will only display
if the effect is being added, not if it is simply incrementing a current effect (so only new bites, etc.).

### advanced apply_message
```C++
"apply_message": [
["Your effect is applied", "good"],
["You took way too much effect", "bad"],
]
```
You can instead of having a string for apply_message and including a [rating](#rating) can do advanced apply_message. This is an array of arrays with each inner array matching up with an intensity level and including the message and rating. This is useful for effects that too much of is a bad thing.

When using an advanced apply_message you can not include a [rating: ""](#rating) entry.

### Memorial Log
```C++
"apply_memorial_log": "log",
Expand Down
4 changes: 2 additions & 2 deletions src/bodygraph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -502,9 +502,9 @@ void bodygraph_display::prepare_infotext( bool reset_pos )
info_txt.emplace_back( string_format( "%s:", colorize( _( "Effects" ), c_magenta ) ) );
for( const effect &eff : info.effects ) {
if( eff.get_id()->is_show_in_info() ) {
effect_rating rt = eff.get_id()->get_rating();
game_message_type rt = eff.get_id()->get_rating( eff.get_intensity() );
info_txt.emplace_back( string_format( " %s", colorize( eff.disp_name(),
rt == e_good ? c_green : rt == e_bad ? c_red : c_yellow ) ) );
rt == m_good ? c_green : rt == m_bad ? c_red : c_yellow ) ) );
}
}
info_txt.emplace_back( "--" );
Expand Down
2 changes: 1 addition & 1 deletion src/character.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2736,7 +2736,7 @@ void Character::conduct_blood_analysis()
continue;
}
effect_descriptions.emplace_back( elem.first->get_blood_analysis_description() );
colors.emplace_back( elem.first->get_rating() == e_good ? c_green : c_red );
colors.emplace_back( elem.first->get_rating() == m_good ? c_green : c_red );
}

const int win_w = 46;
Expand Down
11 changes: 6 additions & 5 deletions src/creature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1542,10 +1542,10 @@ void Creature::add_effect( const effect_source &source, const efftype_id &eff_id
if( e.get_int_dur_factor() > 0_turns ) {
// Set intensity if value is given
} else if( intensity > 0 ) {
e.set_intensity( intensity );
e.set_intensity( intensity, true );
// Else intensity uses the type'd step size if it already exists
} else if( e.get_int_add_val() != 0 ) {
e.mod_intensity( e.get_int_add_val() );
e.mod_intensity( e.get_int_add_val(), true );
}

// Bound intensity by [1, max intensity]
Expand Down Expand Up @@ -1598,8 +1598,8 @@ void Creature::add_effect( const effect_source &source, const efftype_id &eff_id
( *effects )[eff_id][bp] = e;
if( Character *ch = as_character() ) {
get_event_bus().send<event_type::character_gains_effect>( ch->getID(), eff_id );
if( is_avatar() && !type.get_apply_message().empty() ) {
add_msg( type.gain_game_message_type(), type.get_apply_message() );
if( is_avatar() ) {
eff_id->add_apply_msg( e.get_intensity() );
}
}
on_effect_int_change( eff_id, e.get_intensity(), bp );
Expand Down Expand Up @@ -1681,7 +1681,8 @@ bool Creature::remove_effect( const efftype_id &eff_id, const bodypart_id &bp )
if( Character *ch = as_character() ) {
if( is_avatar() ) {
if( !type.get_remove_message().empty() ) {
add_msg( type.lose_game_message_type(), type.get_remove_message() );
add_msg( type.lose_game_message_type( get_effect( eff_id, bp.id() ).get_intensity() ),
type.get_remove_message() );
}
}
get_event_bus().send<event_type::character_loses_effect>( ch->getID(), eff_id );
Expand Down
144 changes: 80 additions & 64 deletions src/effect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -549,9 +549,13 @@ bool effect_type::has_flag( const flag_id &flag ) const
return flags.count( flag );
}

effect_rating effect_type::get_rating() const
game_message_type effect_type::get_rating( int intensity ) const
{
return rating;
if( apply_msgs.size() < static_cast<size_t>( intensity ) ) {
return apply_msgs[intensity - 1].second;
} else {
return apply_msgs[0].second;
}
}

bool effect_type::use_name_ints() const
Expand All @@ -568,41 +572,32 @@ bool effect_type::use_desc_ints( bool reduced ) const
}
}

game_message_type effect_type::gain_game_message_type() const
game_message_type effect_type::lose_game_message_type( int intensity ) const
{
switch( rating ) {
case e_good:
return m_good;
case e_bad:
switch( get_rating( intensity ) ) {
case m_good:
return m_bad;
case e_neutral:
return m_neutral;
case e_mixed:
return m_mixed;
default:
// Should never happen
return m_neutral;
}
}
game_message_type effect_type::lose_game_message_type() const
{
switch( rating ) {
case e_good:
return m_bad;
case e_bad:
case m_bad:
return m_good;
case e_neutral:
case m_neutral:
return m_neutral;
case e_mixed:
case m_mixed:
return m_mixed;
default:
// Should never happen
return m_neutral;
}
}
std::string effect_type::get_apply_message() const
void effect_type::add_apply_msg( int intensity ) const
{
return apply_message.translated();
if( intensity - 1 < static_cast<int>( apply_msgs.size() ) ) {
add_msg( apply_msgs[intensity - 1].second,
apply_msgs[intensity - 1].first.translated() );
} else if( !apply_msgs[0].first.empty() ) {
// if the apply message is empty we shouldn't show the message
add_msg( apply_msgs[0].second,
apply_msgs[0].first.translated() );
}
}
std::string effect_type::get_apply_memorial_log( const memorial_gender gender ) const
{
Expand Down Expand Up @@ -644,30 +639,68 @@ bool effect_type::load_miss_msgs( const JsonObject &jo, const std::string_view m
{
return jo.read( member, miss_msgs );
}

static std::optional<game_message_type> process_rating( std::string r )
{
if( r == "good" ) {
return m_good;
} else if( r == "neutral" ) {
return m_neutral;
} else if( r == "bad" ) {
return m_bad;
} else if( r == "mixed" ) {
return m_mixed;
} else {
// handle errors for returning nothing above
return {};
}
}

// helps load the internal message arrays for decay and apply into the msgs vector
static void load_msg_help( const JsonArray &ja,
std::vector<std::pair<translation, game_message_type>> &apply_msgs )
{
translation msg;
ja.read( 0, msg );
std::string r = ja.get_string( 1 );
std::optional<game_message_type> rate = process_rating( r );
if( !rate.has_value() ) {
ja.throw_error(
1, string_format( "Unexpected message type \"%s\"; expected \"good\", "
"\"neutral\", " "\"bad\", or \"mixed\"", r ) );
rate = m_neutral;
}
apply_msgs.emplace_back( msg, rate.value() );
}

bool effect_type::load_decay_msgs( const JsonObject &jo, const std::string_view member )
{
if( jo.has_array( member ) ) {
for( JsonArray inner : jo.get_array( member ) ) {
translation msg;
inner.read( 0, msg );
std::string r = inner.get_string( 1 );
game_message_type rate = m_neutral;
if( r == "good" ) {
rate = m_good;
} else if( r == "neutral" ) {
rate = m_neutral;
} else if( r == "bad" ) {
rate = m_bad;
} else if( r == "mixed" ) {
rate = m_mixed;
} else {
inner.throw_error(
1, string_format( "Unexpected message type \"%s\"; expected \"good\", "
"\"neutral\", " "\"bad\", or \"mixed\"", r ) );
}
decay_msgs.emplace_back( msg, rate );
load_msg_help( inner, decay_msgs );
}
return true;
}
return false;
}

bool effect_type::load_apply_msgs( const JsonObject &jo, const std::string_view member )
{
if( jo.has_array( member ) ) {
JsonArray ja = jo.get_array( member );
for( JsonArray inner : jo.get_array( member ) ) {
load_msg_help( inner, apply_msgs );
}
return true;
} else {
translation msg;
optional( jo, false, member, msg );
if( jo.has_string( "rating" ) ) {
std::optional<game_message_type> rate = process_rating( jo.get_string( "rating" ) );
apply_msgs.emplace_back( msg, rate.value() );
} else {
apply_msgs.emplace_back( msg, game_message_type::m_neutral );
}
}
return false;
}
Expand Down Expand Up @@ -1135,6 +1168,8 @@ int effect::set_intensity( int val, bool alert )
val - 1 < static_cast<int>( eff_type->decay_msgs.size() ) ) {
add_msg( eff_type->decay_msgs[ val - 1 ].second,
eff_type->decay_msgs[ val - 1 ].first.translated() );
} else if( alert ) {
eff_type->add_apply_msg( val );
}

if( val == 0 && !eff_type->int_decay_remove ) {
Expand Down Expand Up @@ -1443,26 +1478,6 @@ void load_effect_type( const JsonObject &jo )

new_etype.part_descs = jo.get_bool( "part_descs", false );

if( jo.has_member( "rating" ) ) {
std::string r = jo.get_string( "rating" );
if( r == "good" ) {
new_etype.rating = e_good;
} else if( r == "neutral" ) {
new_etype.rating = e_neutral;
} else if( r == "bad" ) {
new_etype.rating = e_bad;
} else if( r == "mixed" ) {
new_etype.rating = e_mixed;
} else {
jo.throw_error_at(
"rating",
string_format( "Unexpected rating \"%s\"; expected \"good\", \"neutral\", "
"\"bad\", or \"mixed\"", r ) );
}
} else {
new_etype.rating = e_neutral;
}
jo.read( "apply_message", new_etype.apply_message );
jo.read( "remove_message", new_etype.remove_message );
optional( jo, false, "apply_memorial_log", new_etype.apply_memorial_log,
text_style_check_reader() );
Expand Down Expand Up @@ -1511,6 +1526,7 @@ void load_effect_type( const JsonObject &jo )

new_etype.load_miss_msgs( jo, "miss_messages" );
new_etype.load_decay_msgs( jo, "decay_messages" );
new_etype.load_apply_msgs( jo, "apply_message" );

new_etype.main_parts_only = jo.get_bool( "main_parts_only", false );
new_etype.show_in_info = jo.get_bool( "show_in_info", false );
Expand Down
Loading

0 comments on commit c5487bd

Please sign in to comment.