1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
|
#include "avatar.h"
#include "cata_catch.h"
#include "creature_tracker.h"
#include "game.h"
#include "item_group.h"
#include "map.h"
#include "map_helpers.h"
#include "npc.h"
#include "npc_class.h"
#include "player_helpers.h"
static npc_template_id const npc_template_test_npc_trader( "test_npc_trader" );
static std::pair<bool, bool> has_and_can_restock( npc const &guy, item const &it )
{
bool can_restock_item = false;
bool item_in_groups = false;
for( shopkeeper_item_group const &ig : guy.myclass->get_shopkeeper_items() ) {
if( item_group::group_contains_item( ig.id, it.typeId() ) ) {
item_in_groups = true;
can_restock_item |= ig.can_restock( guy );
}
}
return { item_in_groups, can_restock_item };
}
TEST_CASE( "npc_shopkeeper_item_groups", "[npc][trade]" )
{
clear_avatar();
clear_npcs();
tripoint const npc_pos = get_avatar().pos() + tripoint_east;
const character_id id = get_map().place_npc( npc_pos.xy(), npc_template_test_npc_trader );
npc &guy = *g->find_npc( id );
GIVEN( "item in basic group with no conditions" ) {
item pants( "test_pants_fur" );
pants.set_owner( guy );
THEN( "item is available for selling and restocking" ) {
std::pair<bool, bool> har_pants = has_and_can_restock( guy, pants );
REQUIRE( har_pants.first == true );
REQUIRE( har_pants.second == true );
REQUIRE( guy.wants_to_sell( { map_cursor{ tripoint_zero }, &pants } ) );
}
}
GIVEN( "item in inventory" ) {
g->load_npcs();
creature_tracker &creatures = get_creature_tracker();
REQUIRE( creatures.creature_at<npc>( npc_pos ) != nullptr );
item backpack( "test_backpack" );
backpack.set_owner( guy );
REQUIRE( guy.wants_to_sell( { map_cursor{ tripoint_zero }, &backpack } ) );
WHEN( "backpack is worn - not available for sale" ) {
auto backpack_iter = *guy.wear_item( backpack );
item &it = *backpack_iter;
REQUIRE( !guy.wants_to_sell( { map_cursor{ tripoint_zero }, &it } ) );
item scrap( "scrap" );
scrap.set_owner( guy );
REQUIRE( guy.wants_to_sell( { map_cursor{ tripoint_zero }, &scrap } ) );
item_location const scrap_inv = guy.i_add( scrap );
REQUIRE( scrap_inv );
THEN( "sell_belongings is true - item in inventory available for sale" ) {
guy.myclass = NC_NONE;
REQUIRE( guy.myclass->sells_belongings == true );
REQUIRE( guy.wants_to_sell( scrap_inv ) );
}
THEN( "sell_belongings is false - item in inventory is not available for sale" ) {
REQUIRE( guy.myclass->sells_belongings == false );
REQUIRE( !guy.wants_to_sell( scrap_inv ) );
}
}
}
GIVEN( "item in group gated by non-strict condition" ) {
item hammer( "hammer" );
hammer.set_owner( guy );
WHEN( "condition not met" ) {
std::pair<bool, bool> har_hammer = has_and_can_restock( guy, hammer );
THEN( "item is available for restocking but not selling" ) {
REQUIRE( har_hammer.first == true );
REQUIRE( har_hammer.second == true );
REQUIRE( !guy.wants_to_sell( { map_cursor{ tripoint_zero }, &hammer } ) );
}
}
WHEN( "condition met" ) {
get_avatar().set_value( "npctalk_var_bool_test_tools_access", "yes" );
std::pair<bool, bool> har_hammer = has_and_can_restock( guy, hammer );
THEN( "item is available for selling and restocking" ) {
REQUIRE( har_hammer.first == true );
REQUIRE( har_hammer.second == true );
REQUIRE( guy.wants_to_sell( { map_cursor{ tripoint_zero }, &hammer } ) );
}
}
}
GIVEN( "item in group gated by strict condition" ) {
item multitool( "test_multitool" );
multitool.set_owner( guy );
WHEN( "condition not met" ) {
std::pair<bool, bool> har_multitool = has_and_can_restock( guy, multitool );
THEN( "item is not available for selling or restocking" ) {
REQUIRE( har_multitool.first == true );
REQUIRE( har_multitool.second == false );
REQUIRE( !guy.wants_to_sell( { map_cursor{ tripoint_zero }, &multitool } ) );
}
}
WHEN( "condition met" ) {
get_avatar().set_value( "npctalk_var_bool_test_multitool_access", "yes" );
std::pair<bool, bool> har_multitool = has_and_can_restock( guy, multitool );
THEN( "item is available for selling and restocking" ) {
REQUIRE( har_multitool.first == true );
REQUIRE( har_multitool.second == true );
REQUIRE( guy.wants_to_sell( { map_cursor{ tripoint_zero }, &multitool } ) );
}
}
}
GIVEN( "containter with single item type and conditions only for contents" ) {
item multitool( "test_multitool" );
item bag( "bag_plastic" );
int const num = GENERATE( 1, 2 );
bool ret = true;
for( int i = 0; i < num; i++ ) {
ret &= bag.put_in( multitool, pocket_type::CONTAINER ).success();
}
CAPTURE( num, bag.display_name() );
REQUIRE( ret );
bag.set_owner( guy );
item_location const loc( map_cursor{ tripoint_zero}, &bag );
WHEN( "condition for contents not met" ) {
THEN( "container can't be sold" ) {
REQUIRE( !guy.wants_to_sell( loc ) );
}
}
WHEN( "condition for contents met" ) {
get_avatar().set_value( "npctalk_var_bool_test_multitool_access", "yes" );
THEN( "container can be sold" ) {
REQUIRE( guy.wants_to_sell( loc ) );
}
}
}
}
|