-
Notifications
You must be signed in to change notification settings - Fork 276
/
item.h
2440 lines (2159 loc) · 104 KB
/
item.h
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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#pragma once
#ifndef CATA_SRC_ITEM_H
#define CATA_SRC_ITEM_H
#include <climits>
#include <cstdint>
#include <functional>
#include <list>
#include <map>
#include <optional>
#include <set>
#include <string>
#include <type_traits>
#include <utility>
#include <vector>
#include "calendar.h"
#include "cata_arena.h"
#include "detached_ptr.h"
#include "enums.h"
#include "flat_set.h"
#include "game_object.h"
#include "gun_mode.h"
#include "io_tags.h"
#include "item_contents.h"
#include "location_vector.h"
#include "pimpl.h"
#include "safe_reference.h"
#include "string_id.h"
#include "type_id.h"
#include "units.h"
#include "value_ptr.h"
#include "visitable.h"
class Character;
class JsonIn;
class JsonObject;
class JsonOut;
class Creature;
class faction;
class gunmod_location;
class item;
class iteminfo_query;
class material_type;
class monster;
class nc_color;
class player;
class recipe;
class relic;
class relic_recharge;
struct armor_portion_data;
struct islot_comestible;
struct itype;
struct item_comp;
class item_drop_token;
template<typename CompType>
struct comp_selection;
struct tool_comp;
struct mtype;
struct tripoint;
template<typename T>
class ret_val;
class item_location;
namespace enchant_vals
{
enum class mod : int;
} // namespace enchant_vals
using bodytype_id = std::string;
using faction_id = string_id<faction>;
class item_category;
struct islot_armor;
struct use_function;
enum art_effect_passive : int;
enum phase_id : int;
enum body_part : int;
enum m_size : int;
enum class side : int;
class body_part_set;
class map;
struct damage_instance;
struct damage_unit;
struct fire_data;
class weather_manager;
enum damage_type : int;
enum clothing_mod_type : int;
std::string rad_badge_color( int rad );
struct light_emission {
unsigned short luminance;
short width;
short direction;
};
extern light_emission nolight;
/**
* Value and metadata for one property of an item
*
* Contains the value of one property of an item, as well as various metadata items required to
* output that value. This is used primarily for user output of information about an item, for
* example in the various inventory menus. See @ref item::info() for the main example of how a
* class desiring to provide user output might obtain a class of this type.
*
* As an example, if the item being queried was a piece of clothing, then several properties might
* be returned. All would have sType "ARMOR". There would be one for the coverage stat with
* sName "Coverage: ", another for the warmth stat with sName "Warmth: ", etc.
*/
struct iteminfo {
public:
/** Category of item that owns this iteminfo. See @ref item_category. */
std::string sType;
/** Main text of this property's name */
std::string sName;
/** Formatting text to be placed between the name and value of this item. */
std::string sFmt;
/** Numerical value of this property. Set to -999 if no compare value is present */
std::string sValue;
/** Internal double floating point version of value, for numerical comparisons */
double dValue;
/** Flag indicating type of sValue. True if integer, false if single decimal */
bool is_int;
/** Flag indicating whether a newline should be printed after printing this item */
bool bNewLine;
/** Reverses behavior of red/green text coloring; smaller values are green if true */
bool bLowerIsBetter;
/** Whether to print sName. If false, use for comparisons but don't print for user. */
bool bDrawName;
/** Whether to print a sign on positive values */
bool bShowPlus;
/** Flag indicating decimal with three points of precision. */
bool three_decimal;
enum flags {
no_flags = 0,
is_decimal = 1 << 0, ///< Print as decimal rather than integer
is_three_decimal = 1 << 1, ///< Print as decimal with three points of precision
no_newline = 1 << 2, ///< Do not follow with a newline
lower_is_better = 1 << 3, ///< Lower values are better for this stat
no_name = 1 << 4, ///< Do not print the name
show_plus = 1 << 5, ///< Use a + sign for positive values
};
/**
* @param Type The item type of the item this iteminfo belongs to.
* @param Name The name of the property this iteminfo describes.
* @param Fmt Formatting text desired between item name and value
* @param Flags Additional flags to customize this entry
* @param Value Numerical value of this property, -999 for none.
*/
iteminfo( const std::string &Type, const std::string &Name, const std::string &Fmt = "",
flags Flags = no_flags, double Value = -999 );
iteminfo( const std::string &Type, const std::string &Name, double Value );
};
inline iteminfo::flags operator|( iteminfo::flags l, iteminfo::flags r )
{
using I = std::underlying_type<iteminfo::flags>::type;
return static_cast<iteminfo::flags>( static_cast<I>( l ) | r );
}
inline iteminfo::flags &operator|=( iteminfo::flags &l, iteminfo::flags r )
{
return l = l | r;
}
class item_reload_option
{
public:
item_reload_option() = default;
item_reload_option( const item_reload_option & );
item_reload_option &operator=( const item_reload_option & );
item_reload_option( const player *who, item *target, const item *parent,
item &ammo );
const player *who = nullptr;
item *target = nullptr;
item *ammo;
int qty() const {
return qty_;
}
void qty( int val );
int moves() const;
explicit operator bool() const {
return who && target && ammo && qty_ > 0;
}
private:
int qty_ = 0;
int max_qty = INT_MAX;
const item *parent = nullptr;
};
inline bool is_crafting_component( const item &component );
/**
* Returns a reference to a null item (see @ref item::is_null). The reference is always valid
* and stays valid until the program ends.
*/
item &null_item_reference();
enum class item_location_type : int {
invalid = 0,
character = 1,
map = 2,
vehicle = 3,
container = 4,
monster = 5,
};
class item : public location_visitable<item>, public game_object<item>
{
public:
using FlagsSetType = cata::flat_set<flag_id>;
item();
item( item && ) = delete;
item( const item & );
item &operator=( const item & );
explicit item( const itype_id &id, time_point turn = calendar::turn, int qty = -1 );
explicit item( const itype *type, time_point turn = calendar::turn, int qty = -1 );
/** Suppress randomization and always start with default quantity of charges */
struct default_charges_tag {};
item( const itype_id &id, time_point turn, default_charges_tag );
item( const itype *type, time_point turn, default_charges_tag );
/** Default (or randomized) charges except if counted by charges then only one charge */
struct solitary_tag {};
item( const itype_id &id, time_point turn, solitary_tag );
item( const itype *type, time_point turn, solitary_tag );
/** For constructing in-progress crafts */
item( const recipe *rec, int qty, std::vector<detached_ptr<item>> &&items,
std::vector<item_comp> &&selections );
// Legacy constructor for constructing from string rather than itype_id
// TODO: remove this and migrate code using it.
template<typename... Args>
item( const std::string &itype, Args &&... args ) :
item( itype_id( itype ), std::forward<Args>( args )... )
{}
public:
friend cata_arena<item>;
friend item &null_item_reference();
~item();
void on_destroy();
inline static detached_ptr<item> spawn( JsonIn &jsin ) {
detached_ptr<item> p = spawn();
p->deserialize( jsin );
if( p->is_null() ) {
return detached_ptr<item>();
}
return p;
}
inline static detached_ptr<item> spawn( const item &source ) {
if( source.is_null() ) {
return detached_ptr<item>();
}
return detached_ptr<item>( new item( source ) );
}
template<typename... T>
inline static detached_ptr<item> spawn( T... args ) {
return detached_ptr<item>( new item( std::forward<T>( args )... ) ) ;
}
inline static item *spawn_temporary( const item &source ) {
if( source.is_null() ) {
return &null_item_reference();
}
detached_ptr<item> p = item::spawn( source );
return &*p;
}
template<typename... T>
inline static item *spawn_temporary( T... args ) {
detached_ptr<item> p = item::spawn( std::forward<T>( args )... );
return &*p;
}
/**
* Converts this instance to another type preserving all other aspects
* @param new_type the type id to convert to
* @return same instance to allow method chaining
*/
void convert( const itype_id &new_type );
/**
* Converts this instance to the inactive type
* If the item is either inactive or cannot be deactivated is a no-op
* @param ch character currently possessing or acting upon the item (if any)
* @param alert whether to display any messages
* @return same instance to allow method chaining
*/
void deactivate( const Character *ch = nullptr, bool alert = true );
/** Converts instance to active state */
void activate();
/**
* Add or remove energy from a battery.
* If adding the specified energy quantity would go over the battery's capacity fill
* the battery and ignore the remainder.
* If adding the specified energy quantity would reduce the battery's charge level
* below 0 do nothing and return how far below 0 it would have gone.
* @param qty energy quantity to add (can be negative)
* @return 0 valued energy quantity on success
*/
units::energy mod_energy( const units::energy &qty );
/**
* Sets the ammo for this instance
* Any existing ammo is removed. If necessary a magazine is also added.
* @param ammo specific type of ammo (must be compatible with item ammo type)
* @param qty maximum ammo (capped by item capacity) or negative to fill to capacity
* @return same instance to allow method chaining
*/
void ammo_set( const itype_id &ammo, int qty = -1 );
/**
* Removes all ammo from this instance
* If the item is neither a tool, gun nor magazine is a no-op
* For items reloading using magazines any empty magazine remains present.
*/
void ammo_unset();
/**
* Sets damage constrained by @ref min_damage and @ref max_damage
* @note this method does not invoke the @ref on_damage callback
* @return same instance to allow method chaining
*/
void set_damage( int qty );
/**
* Splits a count-by-charges item, taking qty charges away from it and creating a new (detached) item from them.
* If the entire stack is taken, or the item doesn't count by charges then it returns itself detached.
* @param qty number of required charges to split from source. 0 means all.
* @return new instance containing exactly qty charges or *this after detaching
*/
detached_ptr<item> split( int qty );
virtual bool attempt_detach( std::function < detached_ptr<item>( detached_ptr<item> && ) > )
override;
/**
* Similar to attempt_detach except this splits a count-by-charges item, taking qty charges away from it and creating a new (detached) item from them.
* This detached item is then passed to the lambda. Whatever is returned by the lambda is then merged back into the original item, even if all charges were taken originally.
* Trying to call this on a non-count-by-charges item or returning an item dissimilar to the argument will result in a debugmsg.
*/
bool attempt_split( int qty, const std::function < detached_ptr<item>( detached_ptr<item> && ) > &
cb );
/**
* Make a corpse of the given monster type.
* The monster type id must be valid (see @ref MonsterGenerator::get_all_mtypes).
*
* The turn parameter sets the birthday of the corpse, in other words: the turn when the
* monster died. Because corpses are removed from the map when they reach a certain age,
* one has to be careful when placing corpses with a birthday of 0. They might be
* removed immediately when the map is loaded without been seen by the player.
*
* The name parameter can be used to give the corpse item a name. This is
* used instead of the monster type name ("corpse of X" instead of "corpse of bear").
*
* With the default parameters it makes a human corpse, created at the current turn.
*/
/*@{*/
static detached_ptr<item> make_corpse( const mtype_id &mt = string_id<mtype>::NULL_ID(),
time_point turn = calendar::turn, const std::string &name = "", int upgrade_time = -1 );
/*@}*/
/**
* @return The monster type associated with this item (@ref corpse). It is usually the
* type that this item is made of (e.g. corpse, meat or blood of the monster).
* May return a null-pointer.
*/
const mtype *get_mtype() const;
/**
* Sets the monster type associated with this item (@ref corpse). You must not pass a
* null pointer.
* TODO: change this to take a reference instead.
*/
void set_mtype( const mtype *m );
/**
* Whether this is a corpse item. Corpses always have valid monster type (@ref corpse)
* associated (@ref get_mtype return a non-null pointer) and have been created
* with @ref make_corpse.
*/
bool is_corpse() const;
/**
* Whether this is a corpse that can be revived.
*/
bool can_revive() const;
/**
* Whether this corpse should revive now. Note that this function includes some randomness,
* the return value can differ on successive calls.
* @param pos The location of the item (see REVIVE_SPECIAL flag).
*/
bool ready_to_revive( const tripoint &pos ) const;
bool is_money() const;
/**
* Returns the default color of the item (e.g. @ref itype::color).
*/
nc_color color() const;
/**
* Returns the color of the item depending on usefulness for the player character,
* e.g. differently if it its an unread book or a spoiling food item etc.
* This should only be used for displaying data, it should not affect game play.
*/
nc_color color_in_inventory() const;
/**
* Returns the color of the item depending on usefulness for the passed player,
* e.g. differently if it its an unread book or a spoiling food item etc.
* This should only be used for displaying data, it should not affect game play.
*
* @param for_player NPC or avatar which would read book.
*/
// TODO: Start using this version in more places for interation with NPCs
// e.g. giving them unmatching food or allergic thing.
nc_color color_in_inventory( const player &p ) const;
/**
* Return the (translated) item name.
* @param quantity used for translation to the proper plural form of the name, e.g.
* returns "rock" for quantity 1 and "rocks" for quantity > 0.
* @param with_prefix determines whether to include more item properties, such as
* the extent of damage and burning (was created to sort by name without prefix
* in additional inventory)
*/
std::string tname( unsigned int quantity = 1, bool with_prefix = true,
unsigned int truncate = 0 ) const;
std::string display_money( unsigned int quantity, unsigned int total,
const std::optional<unsigned int> &selected = std::nullopt ) const;
/**
* Returns the item name and the charges or contained charges (if the item can have
* charges at all). Calls @ref tname with given quantity and with_prefix being true.
*/
std::string display_name( unsigned int quantity = 1 ) const;
/** Returns the name that will be used when referring to the object in error messages */
std::string debug_name() const override;
/**
* Return all the information about the item and its type as a vector.
*
* This includes the different
* properties of the @ref itype (if they are visible to the player).
* @param parts controls which parts of the iteminfo to return.
* @param batch The batch crafting number to multiply data by
* @returns The properties (encapsulated into @ref iteminfo) are added to this vector,
* the vector can be used to compare them to properties of another item.
*/
/*@{*/
std::vector<iteminfo> info() const;
std::vector<iteminfo> info( int batch ) const;
std::vector<iteminfo> info( const iteminfo_query &parts, int batch,
temperature_flag temperature ) const;
std::vector<iteminfo> info( temperature_flag temperature ) const;
/*@}*/
/**
* As @ref info, but as a string rather than a vector of properties.
*/
/*@{*/
std::string info_string() const;
std::string info_string( const iteminfo_query &parts, int batch = 1,
temperature_flag temperature = temperature_flag::TEMP_NORMAL ) const;
/*@}*/
/* type specific helper functions for info() that should probably be in itype() */
void basic_info( std::vector<iteminfo> &info, const iteminfo_query *parts, int batch,
bool debug ) const;
void med_info( const item *med_item, std::vector<iteminfo> &info, const iteminfo_query *parts,
int batch, bool debug ) const;
void food_info( const item *food_item, std::vector<iteminfo> &info, const iteminfo_query *parts,
int batch, bool debug, temperature_flag temperature ) const;
void magazine_info( std::vector<iteminfo> &info, const iteminfo_query *parts, int batch,
bool debug ) const;
void ammo_info( std::vector<iteminfo> &info, const iteminfo_query *parts, int batch,
bool debug ) const;
void gun_info( const item *mod, std::vector<iteminfo> &info, const iteminfo_query *parts, int batch,
bool debug ) const;
void gunmod_info( std::vector<iteminfo> &info, const iteminfo_query *parts, int batch,
bool debug ) const;
void armor_protection_info( std::vector<iteminfo> &info, const iteminfo_query *parts, int batch,
bool debug ) const;
void armor_info( std::vector<iteminfo> &info, const iteminfo_query *parts, int batch,
bool debug ) const;
void animal_armor_info( std::vector<iteminfo> &info, const iteminfo_query *parts, int batch,
bool debug ) const;
void armor_fit_info( std::vector<iteminfo> &info, const iteminfo_query *parts, int batch,
bool debug ) const;
void book_info( std::vector<iteminfo> &info, const iteminfo_query *parts, int batch,
bool debug ) const;
void battery_info( std::vector<iteminfo> &info, const iteminfo_query *parts, int batch,
bool debug ) const;
void container_info( std::vector<iteminfo> &info, const iteminfo_query *parts, int batch,
bool debug ) const;
void tool_info( std::vector<iteminfo> &info, const iteminfo_query *parts, int batch,
bool debug ) const;
void component_info( std::vector<iteminfo> &info, const iteminfo_query *parts, int batch,
bool debug ) const;
void repair_info( std::vector<iteminfo> &info, const iteminfo_query *parts, int batch,
bool debug ) const;
void disassembly_info( std::vector<iteminfo> &info, const iteminfo_query *parts, int batch,
bool debug ) const;
void qualities_info( std::vector<iteminfo> &info, const iteminfo_query *parts, int batch,
bool debug ) const;
void bionic_info( std::vector<iteminfo> &info, const iteminfo_query *parts, int batch,
bool debug ) const;
void combat_info( std::vector<iteminfo> &info, const iteminfo_query *parts, int batch,
bool debug ) const;
void contents_info( std::vector<iteminfo> &info, const iteminfo_query *parts, int batch,
bool debug ) const;
void final_info( std::vector<iteminfo> &info, const iteminfo_query &parts, int batch,
bool debug ) const;
/**
* Calculate all burning calculations, but don't actually apply them to item.
* DO apply them to @ref fire_data argument, though.
* @return Amount of "burn" that would be applied to the item.
*/
float simulate_burn( fire_data &frd ) const;
/** Burns the item. Returns true if the item was destroyed. */
bool burn( fire_data &frd );
// Returns the category of this item.
const item_category &get_category() const;
/**
* Reload item using ammo from location returning true if successful
* @param u Player doing the reloading
* @param loc Location of ammo to be reloaded
* @param qty caps reloading to this (or fewer) units
*/
bool reload( player &u, item &loc, int qty );
template<typename Archive>
void io( Archive & );
using archive_type_tag = io::object_archive_tag;
void serialize( JsonOut &json ) const;
void deserialize( JsonIn &jsin );
const std::string &symbol() const;
/**
* Returns the monetary value of an item.
* If `practical` is false, returns pre-cataclysm market value,
* otherwise returns approximate post-cataclysm value.
*/
int price( bool practical ) const;
/**
* Whether two items should stack when displayed in a inventory menu.
* This is different from stacks_with, when two previously non-stackable
* items are now stackable and mergeable because, for example, they
* reaches the same temperature. This is necessary to avoid misleading
* stacks like "3 items-count-by-charge (5)".
*/
bool display_stacked_with( const item &rhs, bool check_components = false ) const;
bool stacks_with( const item &rhs, bool check_components = false,
bool skip_type_check = false ) const;
/**
* Merge charges of the other item into this item. Destroying rhs in the process.
* @return true if the items have been merged, otherwise false.
* Merging is only done for items counted by charges (@ref count_by_charges) and
* items that stack together (@ref stacks_with).
*/
bool merge_charges( detached_ptr<item> &&rhs, bool force = false );
units::mass weight( bool include_contents = true, bool integral = false ) const;
/**
* Total volume of an item accounting for all contained/integrated items
* NOTE: Result is rounded up to next nearest milliliter when working with stackable (@ref count_by_charges) items that have fractional volume per charge.
* If trying to determine how many of an item can fit in a given space, @ref charges_per_volume should be used instead.
* @param integral if true return effective volume if this item was integrated into another
*/
units::volume volume( bool integral = false ) const;
/**
* Simplified, faster volume check for when processing time is important and exact volume is not.
* NOTE: Result is rounded up to next nearest milliliter when working with stackable (@ref count_by_charges) items that have fractional volume per charge.
* If trying to determine how many of an item can fit in a given space, @ref charges_per_volume should be used instead.
*/
units::volume base_volume() const;
/** Volume check for corpses, helper for base_volume(). */
units::volume corpse_volume( const mtype *corpse ) const;
/** Required strength to be able to successfully lift the item unaided by equipment */
int lift_strength() const;
/**
* @name Melee
*
* The functions here assume the item is used in melee, even if's a gun or not a weapon at
* all. Because the functions apply to all types of items, several of the is_* functions here
* may return true for the same item. This only indicates that it can be used in various ways.
*/
/*@{*/
/**
* Base number of moves (@ref Creature::moves) that a single melee attack with this items
* takes. The actual time depends heavily on the attacker, see melee.cpp.
*/
int attack_cost() const;
/** Damage of given type caused when this item is used as melee weapon */
int damage_melee( damage_type dt ) const;
/** All damage types this item deals when used in melee (no skill modifiers etc. applied). */
damage_instance base_damage_melee() const;
/** All damage types this item deals when thrown (no skill modifiers etc. applied). */
damage_instance base_damage_thrown() const;
/**
* Calculate the item's effective damage per second past armor when wielded by a
* character against a monster.
*/
double effective_dps( const player &guy, const monster &mon ) const;
/**
* calculate effective dps against a stock set of monsters. by default, assume g->u
* is wielding
* for_display - include monsters intended for display purposes
* for_calc - include monsters intended for evaluation purposes
* for_display and for_calc are inclusive
*/
std::map<std::string, double> dps( bool for_display, bool for_calc, const player &guy ) const;
std::map<std::string, double> dps( bool for_display, bool for_calc ) const;
/** return the average dps of the weapon against evaluation monsters */
double average_dps( const player &guy ) const;
double ideal_ranged_dps( const Character &who, std::optional<gun_mode> &mode ) const;
/**
* Whether the character needs both hands to wield this item.
*/
bool is_two_handed( const Character &guy ) const;
/** Is this item an effective melee weapon for the given damage type? */
bool is_melee( damage_type dt ) const;
/**
* Is this item an effective melee weapon for any damage type?
* @see item::is_gun()
* @note an item can be both a gun and melee weapon concurrently
*/
bool is_melee() const;
/**
* The most relevant skill used with this melee weapon. Can be "null" if this is not a weapon.
* Note this function returns null if the item is a gun for which you can use gun_skill() instead.
*/
skill_id melee_skill() const;
/*@}*/
/**
* Max range of melee attack this weapon can be used for.
* Accounts for character's abilities and installed gun mods.
* Guaranteed to be at least 1
*/
int reach_range( const Character &guy ) const;
/**
* Sets time until activation for an item that will self-activate in the future.
**/
void set_countdown( int num_turns );
/**
* Consumes specified charges (or fewer) from this and any contained items
* @param what specific type of charge required, e.g. 'battery'
* @param qty maximum charges to consume. On return set to number of charges not found (or zero)
* @param used filled with duplicates of each item that provided consumed charges
* @param pos position at which the charges are being consumed
* @param filter Must return true for use to occur.
* @return true if this item should be deleted (count-by-charges items with no remaining charges)
*/
static detached_ptr<item> use_charges( detached_ptr<item> &&self, const itype_id &what, int &qty,
std::vector<detached_ptr<item>> &used,
const tripoint &pos,
const std::function<bool( const item & )> &filter = return_true<item> );
/**
* Invokes item type's @ref itype::drop_action.
* This function can change the item.
* @param pos Where is the item being placed. Note: the item isn't there yet.
* @return true if the item was destroyed during placement.
*/
bool on_drop( const tripoint &pos );
/**
* Invokes item type's @ref itype::drop_action.
* This function can change the item.
* @param pos Where is the item being placed. Note: the item isn't there yet.
* @param map A map object associated with that position.
* @return true if the item was destroyed during placement.
*/
bool on_drop( const tripoint &pos, map &map );
/**
* Consume a specific amount of items of a specific type.
* This includes this item, and any of its contents (recursively).
* @see item::use_charges - this is similar for items, not charges.
* @param it Type of consumable item.
* @param quantity How much to consume.
* @param used On success all consumed items will be stored here.
* @param filter Must return true for use to occur.
*/
static detached_ptr<item> use_amount( detached_ptr<item> &&self, const itype_id &it, int &quantity,
std::vector<detached_ptr<item>> &used,
const std::function<bool( const item & )> &filter = return_true<item> );
/** Permits filthy components, should only be used as a helper in creating filters */
bool allow_crafting_component() const;
/**
* @name Containers
*
* Containers come in two flavors:
* - suitable for liquids (@ref is_watertight_container),
* - and the remaining one (they are for currently only for flavor).
*/
/*@{*/
/** Whether this is container. Note that container does not necessarily means it's
* suitable for liquids. */
bool is_container() const;
/** Whether this is a container which can be used to store liquids. */
bool is_watertight_container() const;
/** Whether this item has no contents at all. */
bool is_container_empty() const;
/** Whether removing this item's contents will permanently alter it. */
bool is_non_resealable_container() const;
/**
* Whether this item has no more free capacity for its current content.
* @param allow_bucket Allow filling non-sealable containers
*/
bool is_container_full( bool allow_bucket = false ) const;
/**
* Fill item with liquid up to its capacity. This works for guns and tools that accept
* liquid ammo.
* @param liquid Liquid to fill the container with.
* @param amount Amount to fill item with, capped by remaining capacity
* @return the remaining liquid
*/
detached_ptr<item> fill_with( detached_ptr<item> &&liquid, int amount = INFINITE_CHARGES );
/**
* How much more of this liquid (in charges) can be put in this container.
* If this is not a container (or not suitable for the liquid), it returns 0.
* Note that mixing different types of liquid is not possible.
* Also note that this works for guns and tools that accept liquid ammo.
* @param liquid Liquid to check capacity for
* @param allow_bucket Allow filling non-sealable containers
* @param err Message to print if no more material will fit
*/
int get_remaining_capacity_for_liquid( const item &liquid, bool allow_bucket = false,
std::string *err = nullptr ) const;
int get_remaining_capacity_for_liquid( const item &liquid, const Character &p,
std::string *err = nullptr ) const;
/**
* It returns the total capacity (volume) of the container for liquids.
*/
units::volume get_container_capacity() const;
/**
* It returns the maximum volume of any contents, including liquids,
* ammo, magazines, weapons, etc.
*/
units::volume get_total_capacity() const;
/**
* Puts the given item into this one, no checks are performed.
*/
void put_in( detached_ptr<item> &&payload );
/**
* Returns this item into its default container. If it does not have a default container,
* returns this. It's intended to be used like \code newitem = newitem.in_its_container();\endcode
* You must pass the detached_ptr representing the current object, so that it can be placed inside its container.
*/
static detached_ptr<item> in_its_container( detached_ptr<item> &&self );
static detached_ptr<item> in_container( const itype_id &container_type, detached_ptr<item> &&self );
/*@}*/
bool item_has_uses_recursive() const;
/*@{*/
/**
* Funnel related functions. See weather.cpp for their usage.
*/
bool is_funnel_container( units::volume &bigger_than ) const;
void add_rain_to_container( bool acid, int charges = 1 );
/*@}*/
int get_quality( const quality_id &id ) const;
std::map<quality_id, int> get_qualities() const;
bool count_by_charges() const;
/**
* If count_by_charges(), returns charges, otherwise 1
*/
int count() const;
bool craft_has_charges();
/**
* Modify the charges of this item, only use for items counted by charges!
* The item must have enough charges for this (>= quantity) and be counted
* by charges.
* @param mod How many charges should be removed.
*/
void mod_charges( int mod );
/**
* Whether the item has to be removed as it has rotten away completely. May change the item as it calls process_rot()
* @param pnt The position of the item on the current map.
* @param temperature Flag for special locations that affect temperature.
* @param weather Weather manager to supply temperature.
* @return true if the item has rotten away and should be removed, false otherwise.
*/
static detached_ptr<item> actualize_rot( detached_ptr<item> &&self, const tripoint &pnt,
temperature_flag temperature,
const weather_manager &weather );
/**
* Returns rot of the item since last rot calculation.
* This function should not be called directly. since it does not have all the needed checks or temperature calculations.
* If you need to calc rot of item call process_rot instead.
* @param time Time point to which rot is calculated
* @param temp Temperature at which the rot is calculated
*/
auto calc_rot( time_point time, const units::temperature temp ) const -> time_duration;
/**
* Time that this item is guaranteed to stay fresh.
* @param temperature Temperature flag used to cap the duration.
* @returns Remaining guaranteed freshness duration, assuming current storage conditions.
*/
time_duration minimum_freshness_duration( temperature_flag temperature ) const;
/**
* This is part of a workaround so that items don't rot away to nothing if the smoking rack
* is outside the reality bubble.
* @param processing_duration
*/
void mod_last_rot_check( time_duration processing_duration );
/**
* Update temperature for things like food
* Update rot for things that perish
* All items that rot also have temperature
* @param seals Wether the item is in sealed container
* @param pos The current position
* @param carrier The current carrier
* @param flag to specify special temperature situations
* @param weather_generator weather manager, mostly for testing
* @return true if the item is fully rotten and is ready to be removed
*/
/*@{*/
static detached_ptr<item> process_rot( detached_ptr<item> &&self, const tripoint &pos );
static detached_ptr<item> process_rot( detached_ptr<item> &&self, bool seals, const tripoint &pos,
player *carrier, temperature_flag flag,
const weather_manager &weather_generator );
/*@}*/
int get_comestible_fun() const;
/** whether an item is perishable (can rot) */
bool goes_bad() const;
/** whether an item is perishable (can rot), even if it is currently in a preserving container */
bool goes_bad_after_opening() const;
/** Get the shelf life of the item*/
time_duration get_shelf_life() const;
/** Get @ref rot value relative to shelf life (or 0 if item does not spoil) */
double get_relative_rot() const;
/** Set current item @ref rot relative to shelf life (no-op if item does not spoil) */
void set_relative_rot( double val );
void set_rot( time_duration val );
/**
* Get time left to rot, ignoring fridge.
* Returns time to rot if item is able to, max int - N otherwise,
* where N is
* 3 for food,
* 2 for medication,
* 1 for other comestibles,
* 0 otherwise.
*/
int spoilage_sort_order() const;
/** an item is fresh if it is capable of rotting but still has a long shelf life remaining */
bool is_fresh() const {
return goes_bad() && get_relative_rot() < 0.1;
}
/** an item is about to become rotten when shelf life has nearly elapsed */
bool is_going_bad() const {
return get_relative_rot() > 0.9;
}
/** returns true if item is now rotten after all shelf life has elapsed */
bool rotten() const {
return get_relative_rot() > 1.0;
}
/**
* Whether the item has enough rot that it should get removed.
* Regular shelf life perishable foods rot away completely at 2x shelf life. Corpses last 10 days
* @return true if the item has enough rot to be removed, false otherwise.
*/
bool has_rotten_away() const;
time_duration get_rot() const {
return rot;
}
void mod_rot( const time_duration &val ) {
rot += val;
}
/** Time for this item to be fully fermented. */
time_duration brewing_time() const;
/** The results of fermenting this item. */
const std::vector<itype_id> &brewing_results() const;
/**
* Detonates the item and adds remains (if any) to drops.
* Returns true if the item actually detonated,
* potentially destroying other items and invalidating iterators.
* Should NOT be called on an item on the map, but on a local copy.
*/
static detached_ptr<item> detonate( detached_ptr<item> &&self, const tripoint &p,
std::vector<detached_ptr<item>> &drops );
bool will_explode_in_fire() const;
/**
* @name Material(s) of the item
*
* Each item is made of one or more materials (@ref material_type). Materials have
* properties that affect properties of the item (e.g. resistance against certain
* damage types).
*
* Corpses inherit the material of the monster type.
*/
/*@{*/
/**
* Get a material reference to a random material that this item is made of.
* This might return the null-material, you may check this with @ref material_type::ident.
* Note that this may also return a different material each time it's invoked (if the
* item is made from several materials).
*/
const material_type &get_random_material() const;
/**
* Get the basic (main) material of this item. May return the null-material.
*/
const material_type &get_base_material() const;
/**
* The ids of all the materials this is made of.
* This may return an empty vector.
* The returned vector does not contain the null id.
*/
const std::vector<material_id> &made_of() const;
/**
* The ids of all the qualities this contains.
*/
const std::map<quality_id, int> &quality_of() const;
/**
* Same as @ref made_of(), but returns the @ref material_type directly.
*/
std::vector<const material_type *> made_of_types() const;
/**
* Check we are made of at least one of a set (e.g. true if at least
* one item of the passed in set matches any material).