forked from cataclysmbnteam/Cataclysm-BN
-
Notifications
You must be signed in to change notification settings - Fork 0
/
itype.h
1082 lines (897 loc) · 31.5 KB
/
itype.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_ITYPE_H
#define CATA_SRC_ITYPE_H
#include <array>
#include <iosfwd>
#include <map>
#include <memory>
#include <optional>
#include <set>
#include <string>
#include <unordered_set>
#include <vector>
#include "bodypart.h" // body_part::num_bp
#include "calendar.h"
#include "color.h" // nc_color
#include "damage.h"
#include "enums.h" // point
#include "explosion.h"
#include "game_constants.h"
#include "iuse.h" // use_function
#include "pldata.h" // add_type
#include "shape.h"
#include "stomach.h"
#include "translations.h"
#include "type_id.h"
#include "units.h"
#include "value_ptr.h"
class Item_factory;
class item;
class JsonObject;
class JsonIn;
class player;
class relic;
struct tripoint;
template <typename E> struct enum_traits;
enum art_effect_active : int;
enum art_charge : int;
enum art_charge_req : int;
enum art_effect_passive : int;
class gun_modifier_data
{
private:
std::string name_;
int qty_;
std::set<std::string> flags_;
public:
/**
* @param n A string that can be translated via @ref _ (must have been extracted for translation).
*/
gun_modifier_data( const std::string &n, const int q, const std::set<std::string> &f ) : name_( n ),
qty_( q ), flags_( f ) { }
std::string name() const {
return name_;
}
/// @returns The translated name of the gun mode.
std::string tname() const {
return _( name_ );
}
int qty() const {
return qty_;
}
const std::set<std::string> &flags() const {
return flags_;
}
};
class gunmod_location
{
private:
std::string _id;
public:
gunmod_location() = default;
gunmod_location( const std::string &id ) : _id( id ) { }
/// Returns the translated name.
std::string name() const;
/// Returns the location id.
std::string str() const {
return _id;
}
bool operator==( const gunmod_location &rhs ) const {
return _id == rhs._id;
}
bool operator<( const gunmod_location &rhs ) const {
return _id < rhs._id;
}
};
struct islot_tool {
std::set<ammotype> ammo_id;
std::optional<itype_id> revert_to;
std::string revert_msg;
itype_id subtype;
int max_charges = 0;
int def_charges = 0;
int charge_factor = 1;
int charges_per_use = 0;
int turns_per_charge = 0;
int power_draw = 0;
std::vector<int> rand_charges;
};
struct islot_comestible {
public:
friend Item_factory;
friend item;
/** subtype, e.g. FOOD, DRINK, MED */
std::string comesttype;
/** tool needed to consume (e.g. lighter for cigarettes) */
itype_id tool = itype_id::NULL_ID();
/** Defaults # of charges (drugs, loaf of bread? etc) */
int def_charges = 1;
/** effect on character thirst (may be negative) */
int quench = 0;
/** Nutrition values to use for this type when they aren't calculated from
* components */
nutrients default_nutrition;
/** Time until becomes rotten at standard temperature, or zero if never spoils */
time_duration spoils = 0_turns;
/** addiction potential */
int addict = 0;
/** effects of addiction */
add_type add = add_type::NONE;
/** stimulant effect */
int stim = 0;
/**fatigue altering effect*/
int fatigue_mod = 0;
/** Reference to other item that replaces this one as a component in recipe results */
itype_id cooks_like;
/** Reference to item that will be received after smoking current item */
itype_id smoking_result;
/** TODO: add documentation */
int healthy = 0;
/** chance (odds) of becoming parasitised when eating (zero if never occurs) */
int parasites = 0;
/**Amount of radiation you get from this comestible*/
int radiation = 0;
/** freezing point in degrees Fahrenheit, below this temperature item can freeze */
int freeze_point = units::to_fahrenheit( temperatures::freezing );
/**List of diseases carried by this comestible and their associated probability*/
std::map<diseasetype_id, int> contamination;
//** specific heats in J/(g K) and latent heat in J/g */
float specific_heat_liquid = 4.186;
float specific_heat_solid = 2.108;
float latent_heat = 333;
/** A penalty applied to fun for every time this food has been eaten in the last 48 hours */
int monotony_penalty = 2;
/** 1 nutr ~= 8.7kcal (1 nutr/5min = 288 nutr/day at 2500kcal/day) */
static constexpr float kcal_per_nutr = 2500.0f / ( 12 * 24 );
bool has_calories() const {
return default_nutrition.kcal > 0;
}
int get_default_nutr() const {
return default_nutrition.kcal / kcal_per_nutr;
}
/** The monster group that is drawn from when the item rots away */
mongroup_id rot_spawn = mongroup_id::NULL_ID();
/** Chance the above monster group spawns*/
int rot_spawn_chance = 10;
private:
/** effect on morale when consuming */
int fun = 0;
};
struct islot_brewable {
/** What are the results of fermenting this item? */
std::vector<itype_id> results;
/** How long for this brew to ferment. */
time_duration time = 0_turns;
};
struct islot_container {
/**
* Inner volume of the container.
*/
units::volume contains = 0_ml;
/**
* Can be resealed.
*/
bool seals = false;
/**
* Can hold liquids.
*/
bool watertight = false;
/**
* Contents do not spoil.
*/
bool preserves = false;
/**
* If this is set to anything but "null", changing this container's contents in any way
* will turn this item into that type.
*/
itype_id unseals_into = itype_id::NULL_ID();
};
struct islot_armor {
/**
* Bitfield of enum body_part
* TODO: document me.
*/
body_part_set covers;
/**
* Whether this item can be worn on either side of the body
*/
bool sided = false;
/**
* How much this item encumbers the player.
*/
int encumber = 0;
/**
* When storage is full, how much it encumbers the player.
*/
int max_encumber = 0;
/**
* Percentage of the body part area that this item covers.
* This determines how likely it is to hit the item instead of the player.
*/
int coverage = 0;
/**
* TODO: document me.
*/
int thickness = 0;
/**
* Resistance to environmental effects.
*/
int env_resist = 0;
/**
* Environmental protection of a gas mask with installed filter.
*/
int env_resist_w_filter = 0;
/**
* How much warmth this item provides.
*/
int warmth = 0;
/**
* How much storage this items provides when worn.
*/
units::volume storage = 0_ml;
/**
* Factor modifiying weight capacity
*/
float weight_capacity_modifier = 1.0;
/**
* Bonus to weight capacity
*/
units::mass weight_capacity_bonus = 0_gram;
/**
* Whitelisted clothing mods.
* Restricted clothing mods must be listed here by id to be compatible.
*/
std::vector<std::string> valid_mods;
};
struct islot_pet_armor {
/**
* TODO: document me.
*/
int thickness = 0;
/**
* Resistance to environmental effects.
*/
int env_resist = 0;
/**
* Environmental protection of a gas mask with installed filter.
*/
int env_resist_w_filter = 0;
/**
* How much storage this items provides when worn.
*/
units::volume storage = 0_ml;
/**
* The maximum volume a pet can be and wear this armor
*/
units::volume max_vol = 0_ml;
/**
* The minimum volume a pet can be and wear this armor
*/
units::volume min_vol = 0_ml;
/**
* What animal bodytype can wear this armor
*/
std::string bodytype = "none";
};
struct islot_book {
/**
* Which skill it upgrades, if any. Can be @ref skill_id::NULL_ID.
*/
skill_id skill = skill_id::NULL_ID();
/**
* Which martial art it teaches. Can be @ref matype_id::NULL_ID.
*/
matype_id martial_art = matype_id::NULL_ID();
/**
* The skill level the book provides.
*/
int level = 0;
/**
* The skill level required to understand it.
*/
int req = 0;
/**
* How fun reading this is, can be negative.
*/
int fun = 0;
/**
* Intelligence required to read it.
*/
int intel = 0;
/**
* How long in minutes it takes to read.
* "To read" means getting 1 skill point, not all of them.
*/
int time = 0;
/**
* Fun books have chapters; after all are read, the book is less fun.
*/
int chapters = 0;
/**
* What recipes can be learned from this book.
*/
struct recipe_with_description_t {
/**
* The recipe that can be learned (never null).
*/
const class recipe *recipe;
/**
* The skill level required to learn the recipe.
*/
int skill_level;
/**
* The name for the recipe as it appears in the book.
*/
std::string name;
/**
* Hidden means it does not show up in the description of the book.
*/
bool hidden;
bool operator<( const recipe_with_description_t &rhs ) const {
return recipe < rhs.recipe;
}
bool is_hidden() const {
return hidden;
}
};
using recipe_list_t = std::set<recipe_with_description_t>;
recipe_list_t recipes;
};
struct islot_mod {
/** If non-empty restrict mod to items with those base (before modifiers) ammo types */
std::set<ammotype> acceptable_ammo;
/** If set modifies parent ammo to this type */
std::set<ammotype> ammo_modifier;
/** If non-empty replaces the compatible magazines for the parent item */
std::map< ammotype, std::set<itype_id> > magazine_adaptor;
/** Proportional adjustment of parent item ammo capacity */
float capacity_multiplier = 1.0;
};
/**
* Common data for ranged things: guns, gunmods and ammo.
* The values of the gun itself, its mods and its current ammo (optional) are usually summed
* up in the item class and the sum is used.
*/
struct common_ranged_data {
/**
* Damage, armor piercing and multipliers for each.
* If multipliers are set on both gun and ammo, values will be normalized
* as in @ref damage_instance::add_damage
*/
damage_instance damage;
/**
* Range bonus from gun.
*/
int range = 0;
/**
* Dispersion "bonus" from gun.
*/
int dispersion = 0;
};
struct islot_engine {
friend Item_factory;
friend item;
public:
/** for combustion engines the displacement (cc) */
int displacement = 0;
};
struct islot_wheel {
public:
/** diameter of wheel (inches) */
int diameter = 0;
/** width of wheel (inches) */
int width = 0;
};
struct fuel_explosion {
int explosion_chance_hot = 0;
int explosion_chance_cold = 0;
float explosion_factor = 0.0f;
bool fiery_explosion = false;
float fuel_size_factor = 0.0f;
};
struct islot_fuel {
public:
/** Energy of the fuel (kilojoules per charge) */
float energy = 0.0f;
struct fuel_explosion explosion_data;
bool has_explode_data = false;
std::string pump_terrain = "t_null";
};
// TODO: this shares a lot with the ammo item type, merge into a separate slot type?
struct islot_gun : common_ranged_data {
/**
* What skill this gun uses.
*/
skill_id skill_used = skill_id::NULL_ID();
/**
* What type of ammo this gun uses.
*/
std::set<ammotype> ammo;
/**
* Gun durability, affects gun being damaged during shooting.
*/
int durability = 0;
/**
* For guns with an integral magazine what is the capacity?
*/
int clip = 0;
/**
* Reload time, in moves.
*/
int reload_time = 100;
/**
* Noise displayed when reloading the weapon.
*/
std::string reload_noise = translate_marker( "click." );
/**
* Volume of the noise made when reloading this weapon.
*/
int reload_noise_volume = 0;
/** Maximum aim achievable using base weapon sights */
int sight_dispersion = 30;
/** Modifies base loudness as provided by the currently loaded ammo */
int loudness = 0;
/**
* If this uses UPS charges, how many (per shoot), 0 for no UPS charges at all.
*/
int ups_charges = 0;
/**
* One in X chance for gun to require major cleanup after firing blackpowder shot.
*/
int blackpowder_tolerance = 8;
/**
* Minimum ammo recoil for gun to be able to fire more than once per attack.
*/
int min_cycle_recoil = 0;
/**
* Length of gun barrel, if positive allows sawing down of the barrel
*/
units::volume barrel_length = 0_ml;
/**
* Effects that are applied to the ammo when fired.
*/
std::set<ammo_effect_str_id> ammo_effects;
/**
* Location for gun mods.
* Key is the location (untranslated!), value is the number of mods
* that the location can have. The value should be > 0.
*/
std::map<gunmod_location, int> valid_mod_locations;
/**
*Built in mods. string is id of mod. These mods will get the IRREMOVABLE flag set.
*/
std::set<itype_id> built_in_mods;
/**
*Default mods, string is id of mod. These mods are removable but are default on the weapon.
*/
std::set<itype_id> default_mods;
/** Firing modes are supported by the gun. Always contains at least DEFAULT mode */
std::map<gun_mode_id, gun_modifier_data> modes;
/** Burst size for AUTO mode (legacy field for items not migrated to specify modes ) */
int burst = 0;
/** How easy is control of recoil? If unset value automatically derived from weapon type */
int handling = -1;
/**
* Additional recoil applied per shot before effects of handling are considered
* @note useful for adding recoil effect to guns which otherwise consume no ammo
*/
int recoil = 0;
};
/// The type of gun. The second "_type" suffix is only to distinguish it from `item::gun_type`.
class gun_type_type
{
private:
std::string name_;
public:
/// @param name The untranslated name of the gun type. Must have been extracted
/// for translation with the context "gun_type_type".
gun_type_type( const std::string &name ) : name_( name ) {}
/// Translated name.
std::string name() const;
friend bool operator==( const gun_type_type &l, const gun_type_type &r ) {
return l.name_ == r.name_;
}
friend struct std::hash<gun_type_type>;
friend class Item_factory;
};
namespace std
{
template<>
struct hash<gun_type_type> {
size_t operator()( const gun_type_type &t ) const {
return hash<std::string>()( t.name_ );
}
};
} // namespace std
struct islot_gunmod : common_ranged_data {
/** Where is this gunmod installed (e.g. "stock", "rail")? */
gunmod_location location;
/** What kind of weapons can this gunmod be used with (e.g. "rifle", "crossbow")? */
std::unordered_set<gun_type_type> usable;
/** If this value is set (non-negative), this gunmod functions as a sight. A sight is only usable to aim by a character whose current @ref Character::recoil is at or below this value. */
int sight_dispersion = -1;
/**
* For sights (see @ref sight_dispersion), this value affects time cost of aiming.
* Higher is better. In case of multiple usable sights,
* the one with highest aim speed is used.
*/
int aim_speed = -1;
/** Modifies base loudness as provided by the currently loaded ammo */
int loudness = 0;
/** How many moves does this gunmod take to install? */
int install_time = 0;
/** Increases base gun UPS consumption by this many times per shot */
float ups_charges_multiplier = 1.0f;
/** Increases base gun UPS consumption by this value per shot */
int ups_charges_modifier = 0;
/** Increases gun weight by this many times */
float weight_multiplier = 1.0f;
/** Firing modes added to or replacing those of the base gun */
std::map<gun_mode_id, gun_modifier_data> mode_modifier;
std::set<ammo_effect_str_id> ammo_effects;
/** Relative adjustment to base gun handling */
int handling = 0;
/** Percentage value change to the gun's loading time. Higher is slower */
int reload_modifier = 0;
/** Percentage value change to the gun's loading time. Higher is less likely */
int consume_chance = 10000;
/** Divsor to scale back gunmod consumption damage. lower is more damaging. Affected by ammo loudness and recoil, see ranged.cpp for how much. */
int consume_divisor = 1;
/** Modifies base strength required */
int min_str_required_mod = 0;
/** Additional gunmod slots to add to the gun */
std::map<gunmod_location, int> add_mod;
/** Not compatable on weapons that have this mod slot */
std::set<gunmod_location> blacklist_mod;
};
struct islot_magazine {
/** What type of ammo this magazine can be loaded with */
std::set<ammotype> type;
/** Capacity of magazine (in equivalent units to ammo charges) */
int capacity = 0;
/** Default amount of ammo contained by a magazine (often set for ammo belts) */
int count = 0;
/** Default type of ammo contained by a magazine (often set for ammo belts) */
itype_id default_ammo = itype_id::NULL_ID();
/**
* How reliable this magazine on a range of 0 to 10?
* @see doc/GAME_BALANCE.md
*/
int reliability = 0;
/** How long it takes to load each unit of ammo into the magazine */
int reload_time = 100;
/** For ammo belts one linkage (of given type) is dropped for each unit of ammo consumed */
std::optional<itype_id> linkage;
/** If false, ammo will cook off if this mag is affected by fire */
bool protects_contents = false;
};
struct islot_battery {
/** Maximum energy the battery can store */
units::energy max_capacity;
};
struct islot_ammo : common_ranged_data {
/**
* Ammo type, basically the "form" of the ammo that fits into the gun/tool.
*/
ammotype type;
/**
* Type id of casings, if any.
*/
std::optional<itype_id> casing;
/**
* Control chance for and state of any items dropped at ranged target
*@{*/
itype_id drop = itype_id::NULL_ID();
bool drop_active = true;
/*@}*/
/**
* Chance to fail to recover the ammo used.
* As in, one_in(this_var) chance of destroying it.
* For 100% chances, see @ref drop.
*/
int dont_recover_one_in = 1;
/**
* Default charges.
*/
int def_charges = 1;
/**
* See @ref ammo_effect struct.
*/
std::set<ammo_effect_str_id> ammo_effects;
/**
* Base loudness of ammo (possibly modified by gun/gunmods). If unspecified an
* appropriate value is calculated based upon the other properties of the ammo
*/
int loudness = -1;
/** Recoil (per shot), roughly equivalent to kinetic energy (in Joules) */
int recoil = 0;
/**
* Should this ammo explode in fire?
* This value is cached by item_factory based on ammo_effects and item material.
* @warning It is not read from the json directly.
*/
bool cookoff = false;
/**
* Should this ammo apply a special explosion effect when in fire?
* This value is cached by item_factory based on ammo_effects and item material.
* @warning It is not read from the json directly.
* */
bool special_cookoff = false;
/**
* Some combat ammo might not have a damage value
* Set this to make it show as combat ammo anyway
*/
std::optional<bool> force_stat_display;
/**
* AoE shape or null if it's a projectile.
*/
std::optional<shape_factory> shape;
bool was_loaded;
void load( const JsonObject &jo );
void deserialize( JsonIn &jsin );
};
struct islot_bionic {
/**
* Arbitrary difficulty scale, see bionics.cpp for its usage.
*/
int difficulty = 0;
/**
* Id of the bionic, see bionics.cpp for its usage.
*/
bionic_id id;
/**
* Whether this CBM is an upgrade of another.
*/
bool is_upgrade = false;
/**
* Item with installation data that can be used to provide almost guaranteed successful install of corresponding bionic.
*/
itype_id installation_data;
};
struct islot_seed {
/**
* Time it takes for a seed to grow (based of off a season length of 91 days).
*/
time_duration grow = 0_turns;
/**
* Amount of harvested charges of fruits is divided by this number.
*/
int fruit_div = 1;
/**
* Name of the plant.
*/
translation plant_name;
/**
* Type id of the fruit item.
*/
itype_id fruit_id;
/**
* Whether to spawn seed items additionally to the fruit items.
*/
bool spawn_seeds = true;
/**
* Additionally items (a list of their item ids) that will spawn when harvesting the plant.
*/
std::vector<itype_id> byproducts;
islot_seed() = default;
};
struct islot_artifact {
art_charge charge_type;
art_charge_req charge_req;
std::vector<art_effect_passive> effects_wielded;
std::vector<art_effect_active> effects_activated;
std::vector<art_effect_passive> effects_carried;
std::vector<art_effect_passive> effects_worn;
std::vector<std::string> dream_msg_unmet;
std::vector<std::string> dream_msg_met;
int dream_freq_unmet;
int dream_freq_met;
};
enum condition_type {
FLAG,
COMPONENT_ID,
num_condition_types
};
template<>
struct enum_traits<condition_type> {
static constexpr auto last = condition_type::num_condition_types;
};
// A name that is applied under certain conditions.
struct conditional_name {
// Context type (i.e. "FLAG" or "COMPONENT_ID")
condition_type type;
// Context name (i.e. "CANNIBALISM" or "mutant")
std::string condition;
// Name to apply (i.e. "Luigi lasagne" or "smoked mutant"). Can use %s which will
// be replaced by the item's normal name and/or preceding conditional names.
translation name;
};
class islot_milling
{
public:
itype_id into_;
int conversion_rate_;
};
struct itype {
friend class Item_factory;
using FlagsSetType = std::set<std::string>;
std::vector<std::pair<itype_id, mod_id>> src;
/**
* Slots for various item type properties. Each slot may contain a valid pointer or null, check
* this before using it.
*/
/*@{*/
cata::value_ptr<islot_container> container;
cata::value_ptr<islot_tool> tool;
cata::value_ptr<islot_comestible> comestible;
cata::value_ptr<islot_brewable> brewable;
cata::value_ptr<islot_armor> armor;
cata::value_ptr<islot_pet_armor> pet_armor;
cata::value_ptr<islot_book> book;
cata::value_ptr<islot_mod> mod;
cata::value_ptr<islot_engine> engine;
cata::value_ptr<islot_wheel> wheel;
cata::value_ptr<islot_fuel> fuel;
cata::value_ptr<islot_gun> gun;
cata::value_ptr<islot_gunmod> gunmod;
cata::value_ptr<islot_magazine> magazine;
cata::value_ptr<islot_battery> battery;
cata::value_ptr<islot_bionic> bionic;
cata::value_ptr<islot_ammo> ammo;
cata::value_ptr<islot_seed> seed;
cata::value_ptr<islot_artifact> artifact;
cata::value_ptr<relic> relic_data;
cata::value_ptr<islot_milling> milling_data;
/*@}*/
private:
/** Can item be combined with other identical items? */
bool stackable_ = false;
/** Minimum and maximum amount of damage to an item (state of maximum repair). */
// TODO: create and use a MinMax class or similar to put both values into one object.
/// @{
int damage_min_ = -1000;
int damage_max_ = +4000;
/// @}
protected:
itype_id id = itype_id::NULL_ID(); /** unique string identifier for this type */
// private because is should only be accessed through itype::nname!
// nname() is used for display purposes
translation name = no_translation( "none" );
public:
itype();
virtual ~itype();
int damage_min() const;
int damage_max() const;
// used for generic_factory for copy-from
bool was_loaded = false;
// a hint for tilesets: if it doesn't have a tile, what does it look like?
itype_id looks_like;
// What item this item repairs like if it doesn't have a recipe
itype_id repairs_like;
std::set<weapon_category_id> weapon_category;
std::string snippet_category;
translation description; // Flavor text
ascii_art_id picture_id;
// The container it comes in
std::optional<itype_id> default_container;
std::map<quality_id, int> qualities; //Tool quality indicators
std::map<std::string, std::string> properties;
// A list of conditional names, in order of ascending priority.
std::vector<conditional_name> conditional_names;
// What we're made of (material names). .size() == made of nothing.
// MATERIALS WORK IN PROGRESS.
std::vector<material_id> materials;
/** Actions an instance can perform (if any) indexed by action type */
std::map<std::string, use_function> use_methods;
/** Action to take BEFORE the item is placed on map. If it returns non-zero, item won't be placed. */
use_function drop_action;
/** Fields to emit when item is in active state */
std::set<emit_id> emits;
std::set<matec_id> techniques;
// Minimum stat(s) or skill(s) to use the item
std::map<skill_id, int> min_skills;
int min_str = 0;
int min_dex = 0;
int min_int = 0;
int min_per = 0;
phase_id phase = SOLID; // e.g. solid, liquid, gas
// How should the item explode
explosion_data explosion;
// Should the item explode when lit on fire
bool explode_in_fire = false;
/** Is item destroyed after the countdown action is run? */
bool countdown_destroy = false;
/** Default countdown interval (if any) for item */
int countdown_interval = 0;
/** Action to take when countdown expires */
use_function countdown_action;
/**
* @name Non-negative properties
* After loading from JSON these properties guaranteed to be zero or positive
*/
/**@{*/
/** Weight of item ( or each stack member ) */
units::mass weight = 0_gram;
/** Weight difference with the part it replaces for mods */
units::mass integral_weight = -1_gram;
/**
* Space occupied by items of this type
* CAUTION: value given is for a default-sized stack. Avoid using where @ref count_by_charges items may be encountered; see @ref item::volume instead.
* To determine how many of an item can fit in a given space, use @ref charges_per_volume.
*/
units::volume volume = 0_ml;
/**
* Space consumed when integrated as part of another item (defaults to volume)
* CAUTION: value given is for a default-sized stack. Avoid using this. In general, see @ref item::volume instead.
*/
units::volume integral_volume = -1_ml;
/** Number of items per above volume for @ref count_by_charges items */
int stack_size = 0;
/** Value before cataclysm. Price given is for a default-sized stack. */
units::money price = 0_cent;
/** Value after cataclysm, dependent upon practical usages. Price given is for a default-sized stack. */
units::money price_post = -1_cent;
/**@}*/
// If non-rigid volume (and if worn encumbrance) increases proportional to contents
bool rigid = true;
/** Damage output in melee for zero or more damage types */
std::array<int, NUM_DT> melee;
/** Base damage output when thrown */
damage_instance thrown_damage;
int m_to_hit = 0; // To-hit bonus for melee combat; -5 to 5 is reasonable
unsigned light_emission = 0; // Exactly the same as item_tags LIGHT_*, this is for lightmap.