Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add supporting infrastructure for first version of migo bio-tech #50178

Merged
merged 7 commits into from
Aug 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions data/json/effect_on_condition.json
Original file line number Diff line number Diff line change
Expand Up @@ -294,5 +294,13 @@
"condition": { "u_has_bionics": "bio_leaky" },
"deactivate_condition": { "not": { "u_has_bionics": "bio_leaky" } },
"effect": [ { "u_mod_healthy": -1, "cap": -200 } ]
},
{
"id": "EOC_MIGO_INTEREST_INCREASE",
"type": "effect_on_condition",
"recurrence_min": "7 days",
"recurrence_max": "14 days",
"condition": { "not": { "one_in_chance": 4 } },
"effect": [ { "u_adjust_var": "migo_interest", "type": "migo_interest", "context": "interest", "adjustment": 1 } ]
}
]
95 changes: 95 additions & 0 deletions data/json/items/tool/science.json
Original file line number Diff line number Diff line change
Expand Up @@ -1356,5 +1356,100 @@
"symbol": ";",
"color": "light_gray",
"use_action": [ "LUX_METER" ]
},
{
"id": "migo_bio_tech",
"type": "TOOL",
"name": { "str_sp": "Mi-go Biotech" },
"conditional_names": [
{ "type": "VAR", "condition": "npctalk_var_DISPLAY_NAME_MORALE", "name": { "str_sp": "%s (happy)" } },
{ "type": "VAR", "condition": "npctalk_var_DISPLAY_NAME_FOCUS", "name": { "str_sp": "%s (focus)" } },
{ "type": "VAR", "condition": "npctalk_var_DISPLAY_NAME_PAIN", "name": { "str_sp": "%s (pain relief)" } },
{ "type": "VAR", "condition": "npctalk_var_DISPLAY_NAME_FATIGUE", "name": { "str_sp": "%s (wake up)" } }
],
"description": "A piece of mi-go biotechnology.",
"weight": "1 g",
"volume": "250 ml",
"price": 3000,
"price_postapoc": 10000,
"symbol": "!",
"color": "light_red",
"use_action": {
"type": "effect_on_conditions",
"description": "Touch the opening.",
"effect_on_conditions": [
{
"id": "EOC_MIGO_BIO_TECH_INTEREST",
"condition": { "not": { "one_in_chance": 3 } },
"effect": [
{ "message": "You have a slight feeling of being watched." },
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am pretty sure it should be u_message, not message.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is exactly what's causing #50590.

{ "u_adjust_var": "migo_interest", "type": "migo_interest", "context": "interest", "adjustment": 1 }
]
},
{
"id": "EOC_MIGO_BIO_TECH_INTEREST",
"condition": { "not": { "one_in_chance": 100 } },
"effect": [
{ "message": "You have an intense feeling of being watched." },
{ "u_adjust_var": "migo_interest", "type": "migo_interest", "context": "interest", "adjustment": 10 }
]
},
{
"id": "EOC_MIGO_BIO_TECH_SETUP",
"condition": { "not": { "npc_has_var": "function_set", "type": "migo_bio_tech", "context": "bio_tech", "value": "yes" } },
"effect": [
{ "npc_add_var": "function_set", "type": "migo_bio_tech", "context": "bio_tech", "value": "yes" },
{
"npc_add_var": "function",
"type": "migo_bio_tech",
"context": "bio_tech",
"possible_values": [ "morale", "focus", "pain", "fatigue" ]
}
]
},
{
"id": "EOC_MIGO_BIO_TECH_MORALE",
"condition": { "npc_has_var": "function", "type": "migo_bio_tech", "context": "bio_tech", "value": "morale" },
"effect": [
{ "message": "You feel amazing!" },
{
"u_add_morale": "morale_migo_bio_tech",
"bonus": 30,
"max_bonus": 50,
"duration": "12 hours",
"decay_start": "10 hours"
},
{ "npc_add_var": "MORALE", "type": "DISPLAY", "context": "NAME", "value": "" }
]
},
{
"id": "EOC_MIGO_BIO_TECH_FOCUS",
"condition": { "npc_has_var": "function", "type": "migo_bio_tech", "context": "bio_tech", "value": "focus" },
"effect": [
{ "message": "You feel incredibly focused!" },
{ "u_mod_focus": 30 },
{ "npc_add_var": "FOCUS", "type": "DISPLAY", "context": "NAME", "value": "" }
]
},
{
"id": "EOC_MIGO_BIO_TECH_PAIN",
"condition": { "npc_has_var": "function", "type": "migo_bio_tech", "context": "bio_tech", "value": "pain" },
"effect": [
{ "message": "You feel your aches and pains fade away!" },
{ "u_mod_pain": -30 },
{ "npc_add_var": "PAIN", "type": "DISPLAY", "context": "NAME", "value": "" }
]
},
{
"id": "EOC_MIGO_BIO_TECH_FATIGUE",
"condition": { "npc_has_var": "function", "type": "migo_bio_tech", "context": "bio_tech", "value": "fatigue" },
"effect": [
{ "message": "You instantly feel more awake!" },
{ "u_mod_fatigue": -30 },
{ "npc_add_var": "FATIGUE", "type": "DISPLAY", "context": "NAME", "value": "" }
]
}
]
}
}
]
5 changes: 5 additions & 0 deletions data/json/morale_types.json
Original file line number Diff line number Diff line change
Expand Up @@ -388,5 +388,10 @@
"id": "morale_nightmare",
"type": "morale_type",
"text": "Had a vivid nightmare"
},
{
"id": "morale_migo_bio_tech",
"type": "morale_type",
"text": "Used mi-go biotech"
}
]
6 changes: 6 additions & 0 deletions doc/JSON_INFO.md
Original file line number Diff line number Diff line change
Expand Up @@ -2579,6 +2579,11 @@ The `conditional_names` field allows defining alternate names for items that wil
"type": "COMPONENT_ID",
"condition": "mutant",
"name": { "str_sp": "sinister %s" }
},
{
"type": "VAR",
"condition": "npctalk_var_DISPLAY_NAME_MORALE",
"name": { "str_sp": "%s (morale)" }
}
]
}
Expand All @@ -2588,6 +2593,7 @@ You can list as many conditional names for a given item as you want. Each condit
1. The condition type:
- `COMPONENT_ID` searches all the components of the item (and all of *their* components, and so on) for an item with the condition string in their ID. The ID only needs to *contain* the condition, not match it perfectly (though it is case sensitive). For example, supplying a condition `mutant` would match `mutant_meat`.
- `FLAG` which checks if an item has the specified flag (exact match).
- `VAR` which checks if an item has a variable with the given name (exact match). Variables set with effect_on_conditions will have `npctalk_var_` in front of their name. So a variable created with: `"npc_add_var": "MORALE", "type": "DISPLAY","context":"NAME", "value": "Felt Great" }` would be named: `npctalk_var_DISPLAY_NAME_MORALE`.
2. The condition you want to look for.
3. The name to use if a match is found. Follows all the rules of a standard `name` field, with valid keys being `str`, `str_pl`, and `ctxt`. You may use %s here, which will be replaced by the name of the item. Conditional names defined prior to this one are taken into account.

Expand Down
4 changes: 2 additions & 2 deletions doc/NPCs.md
Original file line number Diff line number Diff line change
Expand Up @@ -479,7 +479,7 @@ Effect | Description
`u_add_trait: trait_string`<br/>`npc_add_trait: trait_string` | Your character or the NPC will gain the trait.
`u_lose_effect: effect_string`<br/>`npc_lose_effect: effect_string` | Your character or the NPC will lose the effect if they have it.
`u_lose_trait: trait_string`<br/>`npc_lose_trait: trait_string` | Your character or the NPC will lose the trait.
`u_add_var, npc_add_var`: `var_name, type: type_str`, `context: context_str`, either `value: value_str` or `time: true` | Your character or the NPC will store `value_str` as a variable that can be later retrieved by `u_has_var` or `npc_has_var`. `npc_add_var` can be used to store arbitrary local variables, and `u_add_var` can be used to store arbitrary "global" variables, and should be used in preference to setting effects. If `time` is used instead of `value_str`, then the current turn of the game is stored.
`u_add_var, npc_add_var`: `var_name, type: type_str`, `context: context_str`, either `value: value_str` or `time: true` or `possible_values: string_array` | Your character or the NPC will store `value_str` as a variable that can be later retrieved by `u_has_var` or `npc_has_var`. `npc_add_var` can be used to store arbitrary local variables, and `u_add_var` can be used to store arbitrary "global" variables, and should be used in preference to setting effects. If `time` is used instead of `value_str`, then the current turn of the game is stored. If `possible_values` is used one of the values given at random will be used.
`u_lose_var`, `npc_lose_var`: `var_name`, `type: type_str`, `context: context_str` | Your character or the NPC will clear any stored variable that has the same `var_name`, `type_str`, and `context_str`.
`u_adjust_var, npc_adjust_var`: `var_name, type: type_str`, `context: context_str`, `adjustment: adjustment_num` | Your character or the NPC will adjust the stored variable by `adjustment_num`.
`barber_hair` | Opens a menu allowing the player to choose a new hair style.
Expand All @@ -492,7 +492,7 @@ 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_add_morale: morale_string`, (*optional* `bonus: bonus_int` ), (*optional* `max_bonus: max_bonus_int` ), (*optional* `duration: duration_string`), (*optional* `decay_start` : `decay_string`), (*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_string` time (default 1 hour). It will begin to decay after `decay_string` time (default 30 minutes). `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.

Expand Down
3 changes: 2 additions & 1 deletion src/condition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ static const efftype_id effect_currently_busy( "currently_busy" );
std::string get_talk_varname( const JsonObject &jo, const std::string &member, bool check_value )
{
if( !jo.has_string( "type" ) || !jo.has_string( "context" ) ||
( check_value && !( jo.has_string( "value" ) || jo.has_member( "time" ) ) ) ) {
( check_value && !( jo.has_string( "value" ) || jo.has_member( "time" ) ||
jo.has_array( "possible_values" ) ) ) ) {
jo.throw_error( "invalid " + member + " condition in " + jo.str() );
}
const std::string &var_basename = jo.get_string( member );
Expand Down
4 changes: 4 additions & 0 deletions src/item.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10840,6 +10840,10 @@ std::string item::type_name( unsigned int quantity ) const
ret_name = string_format( cname.name.translated( quantity ), ret_name );
}
break;
case condition_type::VAR:
if( has_var( cname.condition ) ) {
ret_name = string_format( cname.name.translated( quantity ), ret_name );
}
case condition_type::num_condition_types:
break;
}
Expand Down
2 changes: 2 additions & 0 deletions src/itype.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ std::string enum_to_string<condition_type>( condition_type data )
return "FLAG";
case condition_type::COMPONENT_ID:
return "COMPONENT_ID";
case condition_type::VAR:
return "VAR";
case condition_type::num_condition_types:
break;
}
Expand Down
1 change: 1 addition & 0 deletions src/itype.h
Original file line number Diff line number Diff line change
Expand Up @@ -822,6 +822,7 @@ struct islot_seed {
enum condition_type {
FLAG,
COMPONENT_ID,
VAR,
num_condition_types
};

Expand Down
4 changes: 2 additions & 2 deletions src/iuse_actor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4538,8 +4538,8 @@ std::unique_ptr<iuse_actor> effect_on_conditons_actor::clone() const
void effect_on_conditons_actor::load( const JsonObject &obj )
{
description = obj.get_string( "description" );
for( const std::string &eoc : obj.get_string_array( "effect_on_conditions" ) ) {
eocs.emplace_back( effect_on_condition_id( eoc ) );
for( JsonValue jv : obj.get_array( "effect_on_conditions" ) ) {
eocs.emplace_back( effect_on_conditions::load_inline_eoc( jv, "" ) );
}
}

Expand Down
17 changes: 12 additions & 5 deletions src/npctalk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1704,13 +1704,18 @@ void talk_effect_fun_t::set_add_var( const JsonObject &jo, const std::string &me
{
const std::string var_name = get_talk_varname( jo, member );
const bool time_check = jo.has_member( "time" ) && jo.get_bool( "time" );
const std::string &value = time_check ? "" : jo.get_string( "value" );
function = [is_npc, var_name, value, time_check]( const dialogue & d ) {
std::vector<std::string> possible_values = jo.get_string_array( "possible_values" );
if( possible_values.empty() ) {
const std::string value = time_check ? "" : jo.get_string( "value" );
possible_values.push_back( value );
}
function = [is_npc, var_name, possible_values, time_check ]( const dialogue & d ) {
talker *actor = d.actor( is_npc );
if( time_check ) {
actor->set_value( var_name, string_format( "%d", to_turn<int>( calendar::turn ) ) );
} else {
actor->set_value( var_name, value );
int index = rng( 0, possible_values.size() - 1 );
actor->set_value( var_name, possible_values[index] );
}
};
}
Expand Down Expand Up @@ -2322,8 +2327,10 @@ void talk_effect_fun_t::set_add_morale( const JsonObject &jo, const std::string
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 ) );
time_duration duration;
time_duration decay_start;
optional( jo, "false", "duration", duration, 1_hours );
optional( jo, "false", "decay_start", decay_start, 30_minutes );
const bool capped = jo.get_bool( "capped", false );
function = [is_npc, new_type, bonus, max_bonus, duration, decay_start,
capped]( const dialogue & d ) {
Expand Down