File: npc_shopkeeper_item_groups_test.cpp

package info (click to toggle)
cataclysm-dda 0.H-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 710,808 kB
  • sloc: cpp: 524,019; python: 11,580; sh: 1,228; makefile: 1,169; xml: 507; javascript: 150; sql: 56; exp: 41; perl: 37
file content (142 lines) | stat: -rw-r--r-- 5,998 bytes parent folder | download
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 ) );
            }
        }
    }
}