Skip to content

Commit

Permalink
Allow spawning items with flags (CleverRaven#70168)
Browse files Browse the repository at this point in the history
* First

* Update npctalk.cpp

* Update npctalk.cpp

* Update src/npctalk.cpp

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

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
  • Loading branch information
Ramza13 and github-actions[bot] authored Dec 14, 2023
1 parent a63d167 commit 8554ba5
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 7 deletions.
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 @@ -2956,7 +2956,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 @@ -2965,6 +2967,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 @@ -3040,12 +3046,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 @@ -3072,17 +3087,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

0 comments on commit 8554ba5

Please sign in to comment.