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

Allow spawning items with flags #70168

Merged
merged 4 commits into from
Dec 14, 2023
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
4 changes: 2 additions & 2 deletions doc/NPCs.md
Original file line number Diff line number Diff line change
Expand Up @@ -852,8 +852,8 @@ Effect | Description
`give_equipment` | Allows your character to select items from the NPC's inventory and transfer them to your inventory.
`npc_gets_item` | Allows your character to select an item from your character's inventory and transfer it to the NPC's inventory. The NPC will not accept it if they do not have space or weight to carry it, and will set a reason that can be referenced in a future dynamic line with `"use_reason"`.
`npc_gets_item_to_use` | Allow your character to select an item from your character's inventory and transfer it to the NPC's inventory. The NPC will attempt to wield it and will not accept it if it is too heavy or is an inferior weapon to what they are currently using, and will set a reason that can be referenced in a future dynamic line with `"use_reason"`.
`u_spawn_item: `string or [variable object](#variable-object), (*optional* `count: `int or [variable object](#variable-object)), (*optional* `container: `string or [variable object](#variable-object)), (*optional* `use_item_group: `bool), (*optional* `suppress_message: `bool) | Your character gains the item or `count` copies of the item, contained in container if specified. If used in an NPC conversation the items are said to be given by the NPC. If a variable item is passed for the name an item of the type contained in it will be used. If `use_item_group` is true (defaults to false) it will instead pull an item from the item group given. If `suppress_message` is true (defaults to false) no message will be shown. If `force_equip` is true (defaults to false) characters will equip the items if they can.
`u_buy_item: `string or [variable object](#variable-object), `cost: `int or [variable object](#variable-object), (*optional* `count: `int or [variable object](#variable-object)), (*optional* `container: `string or [variable object](#variable-object)), (*optional* `true_eocs: eocs_array`), (*optional* `false_eocs: eocs_array`), (*optional* `use_item_group: `bool), (*optional* `suppress_message: `bool) | The NPC will sell your character the item or `count` copies of the item, contained in `container`, and will subtract `cost` from `op_of_u.owed`. If the `op_o_u.owed` is less than `cost`, the trade window will open and the player will have to trade to make up the difference; the NPC will not give the player the item unless `cost` is satisfied. If `use_item_group` is true (defaults to false) it will instead pull an item from the item group given. If `suppress_message` is true (defaults to false) no message will be shown
`u_spawn_item: `string or [variable object](#variable-object), (*optional* `count: `int or [variable object](#variable-object)), (*optional* `container: `string or [variable object](#variable-object)), (*optional* `use_item_group: `bool), (*optional* `suppress_message: `bool), (*optional* `flags: `array of string or [variable object](#variable-object)) | Your character gains the item or `count` copies of the item, contained in container if specified. If used in an NPC conversation the items are said to be given by the NPC. If a variable item is passed for the name an item of the type contained in it will be used. If `use_item_group` is true (defaults to false) it will instead pull an item from the item group given. If `suppress_message` is true (defaults to false) no message will be shown. If `force_equip` is true (defaults to false) characters will equip the items if they can. The item will have all the flags from the array `flags`.
`u_buy_item: `string or [variable object](#variable-object), `cost: `int or [variable object](#variable-object), (*optional* `count: `int or [variable object](#variable-object)), (*optional* `container: `string or [variable object](#variable-object)), (*optional* `true_eocs: eocs_array`), (*optional* `false_eocs: eocs_array`), (*optional* `use_item_group: `bool), (*optional* `suppress_message: `bool), (*optional* `flags: `array of string or [variable object](#variable-object)) | The NPC will sell your character the item or `count` copies of the item, contained in `container`, and will subtract `cost` from `op_of_u.owed`. If the `op_o_u.owed` is less than `cost`, the trade window will open and the player will have to trade to make up the difference; the NPC will not give the player the item unless `cost` is satisfied. If `use_item_group` is true (defaults to false) it will instead pull an item from the item group given. If `suppress_message` is true (defaults to false) no message will be shown. The item will have all the flags from the array `flags`.
`u_sell_item: `string or [variable object](#variable-object), (*optional* `cost: `int or [variable object](#variable-object)), (*optional* `count: `string or [variable object](#variable-object)), (*optional* `true_eocs: eocs_array`), (*optional* `false_eocs: eocs_array`) | Your character will give the NPC the item or `count` copies of the item, and will add `cost` to the NPC's `op_of_u.owed` if specified.<br/>If cost isn't present, the your character gives the NPC the item at no charge.<br/>This effect will fail if you do not have at least `count` copies of the item, so it should be checked with. If the item is sold, then all of the effect_on_conditions in `true_eocs` are run, otherwise all the effect_on_conditions in `false_eocs` are run.
`u_bulk_trade_accept, npc_bulk_trade_accept, u_bulk_trade_accept, npc_bulk_trade_accept: `int or [variable object](#variable-object) | Only valid after a `repeat_response`. The player trades all instances of the item from the `repeat_response` with the NPC. For `u_bulk_trade_accept`, the player loses the items from their inventory and gains the same value of the NPC's faction currency; for `npc_bulk_trade_accept`, the player gains the items from the NPC's inventory and loses the same value of the NPC's faction currency. If there is remaining value, or the NPC doesn't have a faction currency, the remainder goes into the NPC's `op_of_u.owed`. If `quantity` is specified only that many items/charges will be moved.
`u_bulk_donate, npc_bulk_donate` or `u_bulk_donate, npc_bulk_donate: `int or [variable object](#variable-object) | Only valid after a `repeat_response`. The player or NPC transfers all instances of the item from the `repeat_response`. For `u_bulk_donate`, the player loses the items from their inventory and the NPC gains them; for `npc_bulk_donate`, the player gains the items from the NPC's inventory and the NPC loses them. If a value is specified only that many items/charges will be moved.
Expand Down
33 changes: 28 additions & 5 deletions src/npctalk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2948,7 +2948,9 @@ static void map_add_item( item &it, tripoint_abs_ms target_pos )
}

static void receive_item( itype_id &item_name, int count, std::string_view container_name,
const dialogue &d, bool use_item_group, bool suppress_message, bool add_talker = true,
const dialogue &d, bool use_item_group, bool suppress_message,
const std::vector<std::string> &flags,
bool add_talker = true,
const tripoint_abs_ms &p = tripoint_abs_ms(), bool force_equip = false )
{
item new_item;
Expand All @@ -2957,6 +2959,10 @@ static void receive_item( itype_id &item_name, int count, std::string_view conta
} else {
new_item = item( item_name, calendar::turn );
}
for( const std::string &flag : flags ) {
new_item.set_flag( flag_id( flag ) );
}

if( container_name.empty() ) {
if( new_item.count_by_charges() ) {
new_item.charges = count;
Expand Down Expand Up @@ -3032,12 +3038,21 @@ void talk_effect_fun_t::set_spawn_item( const JsonObject &jo, std::string_view m
loc_var = read_var_info( jo.get_object( "loc" ) );
}
bool force_equip = jo.get_bool( "force_equip", false );

std::vector<str_or_var> flags;
for( JsonValue jv : jo.get_array( "flags" ) ) {
flags.emplace_back( get_str_or_var( jv, "flags" ) );
}
function = [item_name, count, container_name, use_item_group, suppress_message,
add_talker, loc_var, force_equip]( dialogue & d ) {
add_talker, loc_var, force_equip, flags]( dialogue & d ) {
itype_id iname = itype_id( item_name.evaluate( d ) );
const tripoint_abs_ms target_location = get_tripoint_from_var( loc_var, d );
std::vector<std::string> flags_str( flags.size() );
for( const str_or_var &flat_sov : flags ) {
flags_str.emplace_back( flat_sov.evaluate( d ) );
}
receive_item( iname, count.evaluate( d ), container_name.evaluate( d ), d, use_item_group,
suppress_message, add_talker, target_location, force_equip );
suppress_message, flags_str, add_talker, target_location, force_equip );
};
dialogue d( get_talker_for( get_avatar() ), nullptr, {} );
likely_rewards.emplace_back( static_cast<int>( count.evaluate( d ) ),
Expand All @@ -3064,17 +3079,25 @@ void talk_effect_fun_t::set_u_buy_item( const JsonObject &jo, std::string_view m
container_name.str_val = "";
}

std::vector<str_or_var> flags;
for( JsonValue jv : jo.get_array( "flags" ) ) {
flags.emplace_back( get_str_or_var( jv, "flags" ) );
}
str_or_var item_name = get_str_or_var( jo.get_member( member ), member, true );
function = [item_name, cost, count, container_name, true_eocs, false_eocs,
use_item_group, suppress_message]( dialogue & d ) {
use_item_group, suppress_message, flags]( dialogue & d ) {
if( !d.actor( true )->buy_from( cost.evaluate( d ) ) ) {
popup( _( "You can't afford it!" ) );
run_eoc_vector( false_eocs, d );
return;
}
itype_id iname = itype_id( item_name.evaluate( d ) );
std::vector<std::string> flags_str( flags.size() );
for( const str_or_var &flat_sov : flags ) {
flags_str.emplace_back( flat_sov.evaluate( d ) );
}
receive_item( iname, count.evaluate( d ),
container_name.evaluate( d ), d, use_item_group, suppress_message );
container_name.evaluate( d ), d, use_item_group, suppress_message, flags_str );
run_eoc_vector( true_eocs, d );
};
}
Expand Down
Loading