1 #include "itype.h"
2
3 #include <cstdlib>
4 #include <utility>
5
6 #include "debug.h"
7 #include "item.h"
8 #include "make_static.h"
9 #include "player.h"
10 #include "recipe.h"
11 #include "ret_val.h"
12 #include "translations.h"
13
14 struct tripoint;
15
name() const16 std::string gunmod_location::name() const
17 {
18 // Yes, currently the name is just the translated id.
19 return _( _id );
20 }
21
name() const22 std::string islot_book::recipe_with_description_t::name() const
23 {
24 if( optional_name ) {
25 return optional_name->translated();
26 } else {
27 return recipe->result_name();
28 }
29 }
30
31 namespace io
32 {
33 template<>
enum_to_string(condition_type data)34 std::string enum_to_string<condition_type>( condition_type data )
35 {
36 switch( data ) {
37 case condition_type::FLAG:
38 return "FLAG";
39 case condition_type::COMPONENT_ID:
40 return "COMPONENT_ID";
41 case condition_type::num_condition_types:
42 break;
43 }
44 debugmsg( "Invalid condition_type" );
45 abort();
46 }
47 } // namespace io
48
nname(unsigned int quantity) const49 std::string itype::nname( unsigned int quantity ) const
50 {
51 // Always use singular form for liquids.
52 // (Maybe gases too? There are no gases at the moment)
53 if( phase == phase_id::LIQUID ) {
54 quantity = 1;
55 }
56 return name.translated( quantity );
57 }
58
charges_per_volume(const units::volume & vol) const59 int itype::charges_per_volume( const units::volume &vol ) const
60 {
61 if( volume == 0_ml ) {
62 // TODO: items should not have 0 volume at all!
63 return item::INFINITE_CHARGES;
64 }
65 return ( count_by_charges() ? stack_size : 1 ) * vol / volume;
66 }
67
68 // Members of iuse struct, which is slowly morphing into a class.
has_use() const69 bool itype::has_use() const
70 {
71 return !use_methods.empty();
72 }
73
has_flag(const flag_id & flag) const74 bool itype::has_flag( const flag_id &flag ) const
75 {
76 return item_tags.count( flag );
77 }
78
get_flags() const79 const itype::FlagsSetType &itype::get_flags() const
80 {
81 return item_tags;
82 }
83
can_use(const std::string & iuse_name) const84 bool itype::can_use( const std::string &iuse_name ) const
85 {
86 return get_use( iuse_name ) != nullptr;
87 }
88
get_use(const std::string & iuse_name) const89 const use_function *itype::get_use( const std::string &iuse_name ) const
90 {
91 const auto iter = use_methods.find( iuse_name );
92 return iter != use_methods.end() ? &iter->second : nullptr;
93 }
94
tick(player & p,item & it,const tripoint & pos) const95 int itype::tick( player &p, item &it, const tripoint &pos ) const
96 {
97 // Note: can go higher than current charge count
98 // Maybe should move charge decrementing here?
99 int charges_to_use = 0;
100 for( const auto &method : use_methods ) {
101 const int val = method.second.call( p, it, true, pos ).value_or( 0 );
102 if( charges_to_use < 0 || val < 0 ) {
103 charges_to_use = -1;
104 } else {
105 charges_to_use += val;
106 }
107 }
108
109 return charges_to_use;
110 }
111
invoke(player & p,item & it,const tripoint & pos) const112 cata::optional<int> itype::invoke( player &p, item &it, const tripoint &pos ) const
113 {
114 if( !has_use() ) {
115 return 0;
116 }
117 return invoke( p, it, pos, use_methods.begin()->first );
118 }
119
invoke(player & p,item & it,const tripoint & pos,const std::string & iuse_name) const120 cata::optional<int> itype::invoke( player &p, item &it, const tripoint &pos,
121 const std::string &iuse_name ) const
122 {
123 const use_function *use = get_use( iuse_name );
124 if( use == nullptr ) {
125 debugmsg( "Tried to invoke %s on a %s, which doesn't have this use_function",
126 iuse_name, nname( 1 ) );
127 return 0;
128 }
129
130 p.invalidate_weight_carried_cache();
131 const auto ret = use->can_call( p, it, false, pos );
132
133 if( !ret.success() ) {
134 p.add_msg_if_player( m_info, ret.str() );
135 return 0;
136 }
137
138 return use->call( p, it, false, pos );
139 }
140
name() const141 std::string gun_type_type::name() const
142 {
143 return pgettext( "gun_type_type", name_.c_str() );
144 }
145
can_have_charges() const146 bool itype::can_have_charges() const
147 {
148 if( count_by_charges() ) {
149 return true;
150 }
151 if( tool && tool->max_charges > 0 ) {
152 return true;
153 }
154 if( gun && gun->clip > 0 ) {
155 return true;
156 }
157 if( has_flag( STATIC( flag_id( "CAN_HAVE_CHARGES" ) ) ) ) {
158 return true;
159 }
160 return false;
161 }
162