Skip to content

Commit

Permalink
Add some dialog function (CleverRaven#67120)
Browse files Browse the repository at this point in the history
* add topic_item mutator, get hp_max

* format json

* doc update

* topic_item is string

* port hp_max to math
  • Loading branch information
lispcoc authored Jul 26, 2023
1 parent 76d122a commit 6ddada9
Show file tree
Hide file tree
Showing 11 changed files with 79 additions and 0 deletions.
24 changes: 24 additions & 0 deletions data/json/npcs/TALK_TEST.json
Original file line number Diff line number Diff line change
Expand Up @@ -1624,6 +1624,30 @@
{ "text": "Mod Innawood is loaded.", "topic": "TALK_DONE", "condition": { "mod_is_loaded": "innawood" } }
]
},
{
"type": "talk_topic",
"id": "TALK_TEST_TOPIC_ITEM_MUTATOR",
"dynamic_line": "This is a test conversation that shouldn't appear in the game.",
"responses": [ { "text": "This is a basic test response.", "topic": "TALK_DONE" } ],
"repeat_responses": [
{
"for_item": "bottle_glass",
"response": { "text": "This is a repeated item bottle_glass test response", "topic": "TALK_TEST_TOPIC_ITEM_MUTATOR_2" }
}
]
},
{
"type": "talk_topic",
"id": "TALK_TEST_TOPIC_ITEM_MUTATOR_2",
"dynamic_line": "This is a test conversation that shouldn't appear in the game.",
"responses": [
{
"text": "This is a basic test response.",
"topic": "TALK_DONE",
"effect": { "set_string_var": { "mutator": "topic_item" }, "target_var": { "global_val": "key1" } }
}
]
},
{
"type": "npc_class",
"id": "test_shop_class",
Expand Down
2 changes: 2 additions & 0 deletions doc/NPCs.md
Original file line number Diff line number Diff line change
Expand Up @@ -1261,6 +1261,7 @@ Mutator Name | Required Keys | Description
`"ma_technique_description"` | `matec_id`: String or [variable object](#variable-object). | Returns the description of the martial arts tech with ID `matec_id`
`"valid_technique`" | `blacklist`: array of String or [variable object](#variable-object). <br/> `crit`: bool <br/> `dodge_counter`: bool <br/> `block_counter`: bool | Returns a random valid technique for the alpha talker to use against the beta talker with the provided specifications.
`"loc_relative_u"` | `target`: String or [variable object](#variable-object). | target should be a string like "(x,y,z)" where x,y,z are coordinates relative to the player. Returns the abs_ms coordinates as a string (ready to store as a location variable), in the form "(x,y,z)" of the provided point relative to the player. So `"target":"(0,1,0)"` would return the point south of the player.
`"topic_item"` | | Returns current topic_item as a string. See [Repeat Responses](#repeat-responses)


### Compare Numbers and Arithmetics
Expand Down Expand Up @@ -1462,6 +1463,7 @@ _function arguments are `d`oubles (or sub-expressions), `s`trings, or `v`[ariabl
|----------|------|--------|-------|-------------|
| armor(`s`/`v`,`s`/`v`) ||| u, n | Return the numerical value for a characters armor on a body part, for a damage type.<br/> Variables are damagetype ID, bodypart ID.<br/> Example:<br/>`"condition": { "math": [ "u_armor('bash', 'torso')", ">=", "5"] }`|
| attack_speed() ||| u, n | Return the characters current adjusted attack speed with their current weapon.<br/> Example:<br/>`"condition": { "math": [ "u_attack_speed()", ">=", "10"] }`|
| hp_max(`s`/`v`) ||| u, n | Return the characters max amount of hp on a body part.<br/> Variable is bodypart ID.<br/> Example:<br/>`"condition": { "math": [ "u_hp_max('torso')", ">=", "100"] }`|
| game_option(`s`/`v`) ||| N/A<br/>(global) | Return the numerical value of a game option<br/> Example:<br/>`"condition": { "math": [ "game_option('NPC_SPAWNTIME')", ">=", "5"] }`|
| monsters_nearby(`s`/`v`...) ||| u, n, global | Return the number of nearby monsters. Takes any number of `s`tring or `v`ariable positional parameters as monster IDs. <br/><br/>Optional kwargs:<br/>`radius`: `d`/`v` - limit to radius (rl_dist)<br/>`location`: `v` - center search on this location<br/><br/>The `location` kwarg is mandatory in the global scope.<br/><br/>Examples:<br/>`"condition": { "math": [ "u_monsters_nearby('radius': u_search_radius * 3)", ">", "5" ] }`<br/><br/>`"condition": { "math": [ "monsters_nearby('mon_void_maw', 'mon_void_limb', mon_fotm_var, 'radius': u_search_radius * 3, 'location': u_search_loc)", ">", "5" ] }`|
| num_input(`s`/`v`,`d`/`v`) ||| N/A<br/>(global) | Prompt the player for a number.<br/> Variables are Prompt text, Default Value:<br/>`"math": [ "u_value_to_set", "=", "num_input('Playstyle Perks Cost?', 4)" ]`|
Expand Down
4 changes: 4 additions & 0 deletions src/condition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1546,6 +1546,10 @@ static std::function<T( const dialogue & )> get_get_str_( const JsonObject &jo,
tripoint_abs_ms target_pos = char_pos + tripoint::from_string( target.evaluate( d ) );
return ret_func( target_pos.to_string() );
};
} else if( jo.get_string( "mutator" ) == "topic_item" ) {
return [ret_func]( const dialogue & d ) {
return ret_func( d.cur_item.str() );
};
}

return nullptr;
Expand Down
9 changes: 9 additions & 0 deletions src/math_parser_diag.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,15 @@ std::function<double( dialogue & )> armor_eval( char scope,
};
}

std::function<double( dialogue & )> hp_max_eval( char scope,
std::vector<diag_value> const &params, diag_kwargs const &/* kwargs */ )
{
return[bpid = params[0], beta = is_beta( scope )]( dialogue const & d ) {
bodypart_id bp( bpid.str( d ) );
return d.actor( beta )->get_hp_max( bp );
};
}

std::function<double( dialogue & )> num_input_eval( char /*scope*/,
std::vector<diag_value> const &params, diag_kwargs const &/* kwargs */ )
{
Expand Down
2 changes: 2 additions & 0 deletions src/math_parser_diag.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ using decl_diag_ass = std::function<void( dialogue &, double )> ( char scope,

decl_diag_eval armor_eval;
decl_diag_eval attack_speed_eval;
decl_diag_eval hp_max_eval;
decl_diag_eval monsters_nearby_eval;
decl_diag_eval num_input_eval;
decl_diag_eval option_eval;
Expand All @@ -119,6 +120,7 @@ inline std::map<std::string_view, dialogue_func_eval> const dialogue_eval_f{
{ "armor", { "un", 2, armor_eval } },
{ "attack_speed", { "un", 0, attack_speed_eval } },
{ "game_option", { "g", 1, option_eval } },
{ "hp_max", { "un", 1, hp_max_eval } },
{ "monsters_nearby", { "ung", -1, monsters_nearby_eval } },
{ "num_input", { "g", 2, num_input_eval } },
{ "pain", { "un", 0, pain_eval } },
Expand Down
3 changes: 3 additions & 0 deletions src/talker.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,9 @@ class talker
virtual int get_cur_hp( const bodypart_id & ) const {
return 0;
}
virtual int get_hp_max( const bodypart_id & ) const {
return 0;
}
virtual int get_cur_part_temp( const bodypart_id & ) const {
return 0;
}
Expand Down
5 changes: 5 additions & 0 deletions src/talker_character.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,11 @@ int talker_character_const::get_cur_hp( const bodypart_id &bp ) const
return me_chr_const->get_hp( bp );
}

int talker_character_const::get_hp_max( const bodypart_id &bp ) const
{
return me_chr_const->get_hp_max( bp );
}

int talker_character_const::get_cur_part_temp( const bodypart_id &bp ) const
{
return me_chr_const->get_part_temp_conv( bp );
Expand Down
1 change: 1 addition & 0 deletions src/talker_character.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class talker_character_const: public talker_cloner<talker_character_const>
tripoint_abs_ms global_pos() const override;
tripoint_abs_omt global_omt_location() const override;
int get_cur_hp( const bodypart_id &bp ) const override;
int get_hp_max( const bodypart_id &bp ) const override;
int get_cur_part_temp( const bodypart_id &bp ) const override;

// stats, skills, traits, bionics, and magic
Expand Down
5 changes: 5 additions & 0 deletions src/talker_monster.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,11 @@ int talker_monster_const::get_cur_hp( const bodypart_id & ) const
return me_mon_const->get_hp();
}

int talker_monster_const::get_hp_max( const bodypart_id & ) const
{
return me_mon_const->get_hp_max();
}

bool talker_monster_const::will_talk_to_u( const Character &you, bool )
{
return !you.is_dead_state();
Expand Down
1 change: 1 addition & 0 deletions src/talker_monster.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ class talker_monster_const: public talker_cloner<talker_monster_const>
bool will_talk_to_u( const Character &u, bool force ) override;
std::vector<std::string> get_topics( bool radio_contact ) override;
int get_cur_hp( const bodypart_id & ) const override;
int get_hp_max( const bodypart_id & ) const override;
protected:
talker_monster_const() = default;
const monster *me_mon_const;
Expand Down
23 changes: 23 additions & 0 deletions tests/npc_talk_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1651,3 +1651,26 @@ TEST_CASE( "npc_arithmetic", "[npc_talk]" )
// Teardown
player_character.remove_value( var_name );
}

TEST_CASE( "test_topic_item_mutator", "[npc_talk]" )
{
dialogue d;
prep_test( d );
Character &player_character = get_avatar();
clear_avatar();
global_variables &globvars = get_globals();
globvars.clear_global_values();

player_character.inv->add_item( item( itype_bottle_glass ) );
CHECK( player_character.has_amount( itype_bottle_glass, 1 ) );
d.add_topic( "TALK_TEST_TOPIC_ITEM_MUTATOR" );
gen_response_lines( d, 2 );
talk_response &chosen = d.responses[0];
CHECK( chosen.text == "This is a repeated item bottle_glass test response" );
d.add_topic( chosen.success.next_topic );
gen_dynamic_line( d );
gen_response_lines( d, 1 );
chosen = d.responses[0];
chosen.success.apply( d );
CHECK( globvars.get_global_value( "npctalk_var_key1" ) == "bottle_glass" );
}

0 comments on commit 6ddada9

Please sign in to comment.