1 /*-------------------------------------------------------------------------------
2 
3 	BARONY
4 	File: items.hpp
5 	Desc: contains names and definitions for items
6 
7 	Copyright 2013-2016 (c) Turning Wheel LLC, all rights reserved.
8 	See LICENSE for details.
9 
10 -------------------------------------------------------------------------------*/
11 
12 #pragma once
13 
14 #include "main.hpp"
15 #include "entity.hpp"
16 
17 // variables
18 extern bool weaponSwitch;
19 extern bool shieldSwitch;
20 extern Sint32 pickaxeGimpTimer;
21 extern Sint32 swapWeaponGimpTimer;
22 
23 // items
24 typedef enum ItemType
25 {
26 	WOODEN_SHIELD,
27 	QUARTERSTAFF,
28 	BRONZE_SWORD,
29 	BRONZE_MACE,
30 	BRONZE_AXE,
31 	BRONZE_SHIELD,
32 	SLING,
33 	IRON_SPEAR,
34 	IRON_SWORD,
35 	IRON_MACE,
36 	IRON_AXE,
37 	IRON_SHIELD,
38 	SHORTBOW,
39 	STEEL_HALBERD,
40 	STEEL_SWORD,
41 	STEEL_MACE,
42 	STEEL_AXE,
43 	STEEL_SHIELD,
44 	STEEL_SHIELD_RESISTANCE,
45 	CROSSBOW,
46 	GLOVES,
47 	GLOVES_DEXTERITY,
48 	BRACERS,
49 	BRACERS_CONSTITUTION,
50 	GAUNTLETS,
51 	GAUNTLETS_STRENGTH,
52 	CLOAK,
53 	CLOAK_MAGICREFLECTION,
54 	CLOAK_INVISIBILITY,
55 	CLOAK_PROTECTION,
56 	LEATHER_BOOTS,
57 	LEATHER_BOOTS_SPEED,
58 	IRON_BOOTS,
59 	IRON_BOOTS_WATERWALKING,
60 	STEEL_BOOTS,
61 	STEEL_BOOTS_LEVITATION,
62 	STEEL_BOOTS_FEATHER,
63 	LEATHER_BREASTPIECE,
64 	IRON_BREASTPIECE,
65 	STEEL_BREASTPIECE,
66 	HAT_PHRYGIAN,
67 	HAT_HOOD,
68 	HAT_WIZARD,
69 	HAT_JESTER,
70 	LEATHER_HELM,
71 	IRON_HELM,
72 	STEEL_HELM,
73 	AMULET_SEXCHANGE,
74 	AMULET_LIFESAVING,
75 	AMULET_WATERBREATHING,
76 	AMULET_MAGICREFLECTION,
77 	AMULET_STRANGULATION,
78 	AMULET_POISONRESISTANCE,
79 	POTION_WATER,
80 	POTION_BOOZE,
81 	POTION_JUICE,
82 	POTION_SICKNESS,
83 	POTION_CONFUSION,
84 	POTION_EXTRAHEALING,
85 	POTION_HEALING,
86 	POTION_CUREAILMENT,
87 	POTION_BLINDNESS,
88 	POTION_RESTOREMAGIC,
89 	POTION_INVISIBILITY,
90 	POTION_LEVITATION,
91 	POTION_SPEED,
92 	POTION_ACID,
93 	POTION_PARALYSIS,
94 	SCROLL_MAIL,
95 	SCROLL_IDENTIFY,
96 	SCROLL_LIGHT,
97 	SCROLL_BLANK,
98 	SCROLL_ENCHANTWEAPON,
99 	SCROLL_ENCHANTARMOR,
100 	SCROLL_REMOVECURSE,
101 	SCROLL_FIRE,
102 	SCROLL_FOOD,
103 	SCROLL_MAGICMAPPING,
104 	SCROLL_REPAIR,
105 	SCROLL_DESTROYARMOR,
106 	SCROLL_TELEPORTATION,
107 	SCROLL_SUMMON,
108 	MAGICSTAFF_LIGHT,
109 	MAGICSTAFF_DIGGING,
110 	MAGICSTAFF_LOCKING,
111 	MAGICSTAFF_MAGICMISSILE,
112 	MAGICSTAFF_OPENING,
113 	MAGICSTAFF_SLOW,
114 	MAGICSTAFF_COLD,
115 	MAGICSTAFF_FIRE,
116 	MAGICSTAFF_LIGHTNING,
117 	MAGICSTAFF_SLEEP,
118 	RING_ADORNMENT,
119 	RING_SLOWDIGESTION,
120 	RING_PROTECTION,
121 	RING_WARNING,
122 	RING_STRENGTH,
123 	RING_CONSTITUTION,
124 	RING_INVISIBILITY,
125 	RING_MAGICRESISTANCE,
126 	RING_CONFLICT,
127 	RING_LEVITATION,
128 	RING_REGENERATION,
129 	RING_TELEPORTATION,
130 	SPELLBOOK_FORCEBOLT,
131 	SPELLBOOK_MAGICMISSILE,
132 	SPELLBOOK_COLD,
133 	SPELLBOOK_FIREBALL,
134 	SPELLBOOK_LIGHT,
135 	SPELLBOOK_REMOVECURSE,
136 	SPELLBOOK_LIGHTNING,
137 	SPELLBOOK_IDENTIFY,
138 	SPELLBOOK_MAGICMAPPING,
139 	SPELLBOOK_SLEEP,
140 	SPELLBOOK_CONFUSE,
141 	SPELLBOOK_SLOW,
142 	SPELLBOOK_OPENING,
143 	SPELLBOOK_LOCKING,
144 	SPELLBOOK_LEVITATION,
145 	SPELLBOOK_INVISIBILITY,
146 	SPELLBOOK_TELEPORTATION,
147 	SPELLBOOK_HEALING,
148 	SPELLBOOK_EXTRAHEALING,
149 	SPELLBOOK_CUREAILMENT,
150 	SPELLBOOK_DIG,
151 	GEM_ROCK,
152 	GEM_LUCK,
153 	GEM_GARNET,
154 	GEM_RUBY,
155 	GEM_JACINTH,
156 	GEM_AMBER,
157 	GEM_CITRINE,
158 	GEM_JADE,
159 	GEM_EMERALD,
160 	GEM_SAPPHIRE,
161 	GEM_AQUAMARINE,
162 	GEM_AMETHYST,
163 	GEM_FLUORITE,
164 	GEM_OPAL,
165 	GEM_DIAMOND,
166 	GEM_JETSTONE,
167 	GEM_OBSIDIAN,
168 	GEM_GLASS,
169 	TOOL_PICKAXE,
170 	TOOL_TINOPENER,
171 	TOOL_MIRROR,
172 	TOOL_LOCKPICK,
173 	TOOL_SKELETONKEY,
174 	TOOL_TORCH,
175 	TOOL_LANTERN,
176 	TOOL_BLINDFOLD,
177 	TOOL_TOWEL,
178 	TOOL_GLASSES,
179 	TOOL_BEARTRAP,
180 	FOOD_BREAD,
181 	FOOD_CREAMPIE,
182 	FOOD_CHEESE,
183 	FOOD_APPLE,
184 	FOOD_MEAT,
185 	FOOD_FISH,
186 	FOOD_TIN,
187 	READABLE_BOOK,
188 	SPELL_ITEM,
189 	ARTIFACT_SWORD,
190 	ARTIFACT_MACE,
191 	ARTIFACT_SPEAR,
192 	ARTIFACT_AXE,
193 	ARTIFACT_BOW,
194 	ARTIFACT_BREASTPIECE,
195 	ARTIFACT_HELM,
196 	ARTIFACT_BOOTS,
197 	ARTIFACT_CLOAK,
198 	ARTIFACT_GLOVES,
199 	CRYSTAL_BREASTPIECE,
200 	CRYSTAL_HELM,
201 	CRYSTAL_BOOTS,
202 	CRYSTAL_SHIELD,
203 	CRYSTAL_GLOVES,
204 	VAMPIRE_DOUBLET,
205 	WIZARD_DOUBLET,
206 	HEALER_DOUBLET,
207 	MIRROR_SHIELD,
208 	BRASS_KNUCKLES,
209 	IRON_KNUCKLES,
210 	SPIKED_GAUNTLETS,
211 	FOOD_TOMALLEY,
212 	TOOL_CRYSTALSHARD,
213 	CRYSTAL_SWORD,
214 	CRYSTAL_SPEAR,
215 	CRYSTAL_BATTLEAXE,
216 	CRYSTAL_MACE,
217 	BRONZE_TOMAHAWK,
218 	IRON_DAGGER,
219 	STEEL_CHAKRAM,
220 	CRYSTAL_SHURIKEN,
221 	CLOAK_BLACK,
222 	MAGICSTAFF_STONEBLOOD,
223 	MAGICSTAFF_BLEED,
224 	MAGICSTAFF_SUMMON,
225 	TOOL_BLINDFOLD_FOCUS,
226 	TOOL_BLINDFOLD_TELEPATHY,
227 	SPELLBOOK_SUMMON,
228 	SPELLBOOK_STONEBLOOD,
229 	SPELLBOOK_BLEED,
230 	SPELLBOOK_REFLECT_MAGIC,
231 	SPELLBOOK_ACID_SPRAY,
232 	SPELLBOOK_STEAL_WEAPON,
233 	SPELLBOOK_DRAIN_SOUL,
234 	SPELLBOOK_VAMPIRIC_AURA,
235 	SPELLBOOK_CHARM_MONSTER,
236 	POTION_EMPTY,
237 	ARTIFACT_ORB_BLUE,
238 	ARTIFACT_ORB_RED,
239 	ARTIFACT_ORB_PURPLE,
240 	ARTIFACT_ORB_GREEN,
241 	TUNIC,
242 	HAT_FEZ,
243 	MAGICSTAFF_CHARM,
244 	POTION_POLYMORPH,
245 	FOOD_BLOOD,
246 	CLOAK_BACKPACK,
247 	TOOL_ALEMBIC,
248 	POTION_FIRESTORM,
249 	POTION_ICESTORM,
250 	POTION_THUNDERSTORM,
251 	POTION_STRENGTH,
252 	SUEDE_BOOTS,
253 	SUEDE_GLOVES,
254 	CLOAK_SILVER,
255 	HAT_HOOD_SILVER,
256 	HAT_HOOD_RED,
257 	SILVER_DOUBLET,
258 	SPELLBOOK_REVERT_FORM,
259 	SPELLBOOK_RAT_FORM,
260 	SPELLBOOK_SPIDER_FORM,
261 	SPELLBOOK_TROLL_FORM,
262 	SPELLBOOK_IMP_FORM,
263 	SPELLBOOK_SPRAY_WEB,
264 	SPELLBOOK_POISON,
265 	SPELLBOOK_SPEED,
266 	SPELLBOOK_FEAR,
267 	SPELLBOOK_STRIKE,
268 	SPELLBOOK_DETECT_FOOD,
269 	SPELLBOOK_WEAKNESS,
270 	MASK_SHAMAN,
271 	SPELLBOOK_AMPLIFY_MAGIC,
272 	SPELLBOOK_SHADOW_TAG,
273 	SPELLBOOK_TELEPULL,
274 	SPELLBOOK_DEMON_ILLU,
275 	SPELLBOOK_TROLLS_BLOOD,
276 	SPELLBOOK_SALVAGE,
277 	TOOL_WHIP,
278 	SPELLBOOK_FLUTTER,
279 	SPELLBOOK_DASH,
280 	SPELLBOOK_SELF_POLYMORPH,
281 	SPELLBOOK_9,
282 	SPELLBOOK_10,
283 	MAGICSTAFF_POISON,
284 	TOOL_METAL_SCRAP,
285 	TOOL_MAGIC_SCRAP,
286 	TOOL_TINKERING_KIT,
287 	TOOL_SENTRYBOT,
288 	TOOL_DETONATOR_CHARGE,
289 	TOOL_BOMB,
290 	TOOL_SLEEP_BOMB,
291 	TOOL_FREEZE_BOMB,
292 	TOOL_TELEPORT_BOMB,
293 	TOOL_GYROBOT,
294 	TOOL_SPELLBOT,
295 	TOOL_DECOY,
296 	TOOL_DUMMYBOT,
297 	MACHINIST_APRON,
298 	ENCHANTED_FEATHER,
299 	PUNISHER_HOOD,
300 	SCROLL_CHARGING,
301 	QUIVER_SILVER,
302 	QUIVER_PIERCE,
303 	QUIVER_LIGHTWEIGHT,
304 	QUIVER_FIRE,
305 	QUIVER_KNOCKBACK,
306 	QUIVER_CRYSTAL,
307 	QUIVER_HUNTING,
308 	LONGBOW,
309 	COMPOUND_BOW,
310 	HEAVY_CROSSBOW,
311 	BOOMERANG,
312 	SCROLL_CONJUREARROW
313 } ItemType;
314 const int NUMITEMS = 287;
315 
316 //NOTE: If you change this, make sure to update NUMCATEGORIES in game.h to reflect the total number of categories. Not doing that will make bad things happen.
317 typedef enum Category
318 {
319 	WEAPON,
320 	ARMOR,
321 	AMULET,
322 	POTION,
323 	SCROLL,
324 	MAGICSTAFF,
325 	RING,
326 	SPELLBOOK,
327 	GEM,
328 	THROWN,
329 	TOOL,
330 	FOOD,
331 	BOOK,
332 	SPELL_CAT
333 } Category;
334 
335 typedef enum Status
336 {
337 	BROKEN,
338 	DECREPIT,
339 	WORN,
340 	SERVICABLE,
341 	EXCELLENT
342 } Status;
343 
344 typedef enum EquipmentType
345 {
346 	TYPE_NONE,
347 	TYPE_HELM,
348 	TYPE_HAT,
349 	TYPE_BREASTPIECE,
350 	TYPE_BOOTS,
351 	TYPE_SHIELD,
352 	TYPE_GLOVES,
353 	TYPE_CLOAK,
354 	TYPE_RING,
355 	TYPE_AMULET,
356 	TYPE_MASK,
357 	TYPE_SWORD,
358 	TYPE_AXE,
359 	TYPE_SPEAR,
360 	TYPE_MACE,
361 	TYPE_BOW,
362 	TYPE_PROJECTILE,
363 	TYPE_OFFHAND
364 } EquipmentType;
365 
366 class SummonProperties
367 {
368 	//TODO: Store monster stats.
369 public:
370 	SummonProperties();
371 	~SummonProperties() noexcept;
372 
373 	SummonProperties(const SummonProperties& other) = default;
374 	SummonProperties(SummonProperties&& other) noexcept = default;
375 	SummonProperties& operator=(const SummonProperties& other) = default;
376 	SummonProperties& operator=(SummonProperties&& other) noexcept = default;
377 
378 protected:
379 
380 private:
381 
382 };
383 
384 // inventory item structure
385 class Item
386 {
387 public:
388 	ItemType type;
389 	Status status;
390 
391 	Sint16 beatitude;  // blessedness
392 	Sint16 count;      // how many of item
393 	Uint32 appearance; // large random static number
394 	bool identified;   // if the item is identified or not
395 	Uint32 uid;        // item uid
396 	Sint32 x, y;       // slot coordinates in item grid
397 	Uint32 ownerUid;   // original owner
398 	Uint32 interactNPCUid; // if NPC is interacting with item
399 	bool forcedPickupByPlayer; // player used interact on NPC with item on floor
400 	bool isDroppable; // if item should drop on death
401 
402 	// weight, category and other generic info reported by function calls
403 
404 	node_t* node;
405 
406 	/*
407 	 * Gems use this to store information about what sort of creature they contain.
408 	 */
409 	//SummonProperties *captured_monster;
410 	//I wish there was an easy way to do this.
411 	//As it stands, no item destructor is called , so this would lead to a memory leak.
412 	//And tracking down every time an item gets deleted and calling an item destructor would be quite a doozey.
413 
414 	char* description() const;
415 	char* getName() const;
416 
417 	//General Functions.
418 	Sint32 weaponGetAttack(const Stat* wielder = nullptr) const; //Returns the tohit of the weapon.
419 	Sint32 armorGetAC(const Stat* wielder = nullptr) const;
420 	bool canUnequip(const Stat* wielder = nullptr); //Returns true if the item can be unequipped (not cursed), false if it can't (cursed).
421 	int buyValue(int player) const;
422 	int sellValue(int player) const;
423 	bool usableWhileShapeshifted(const Stat* wielder = nullptr) const;
424 	char* getScrollLabel() const;
425 
426 	void apply(int player, Entity* entity);
427 	void applyLockpickToWall(int player, int x, int y) const;
428 
429 	//Item usage functions.
430 	void applySkeletonKey(int player, Entity& entity);
431 	void applyLockpick(int player, Entity& entity);
432 	void applyOrb(int player, ItemType type, Entity& entity);
433 	void applyEmptyPotion(int player, Entity& entity);
434 	//-----ITEM COMPARISON FUNCTIONS-----
435 	/*
436 	 * Returns which weapon hits harder.
437 	 */
438 	static bool isThisABetterWeapon(const Item& newWeapon, const Item* weaponAlreadyHave);
439 	static bool isThisABetterArmor(const Item& newArmor, const Item* armorAlreadyHave); //Also checks shields.
440 	bool shouldItemStack(int player) const;
441 
442 	bool isShield() const;
443 
444 	enum ItemBombPlacement : int
445 	{
446 		BOMB_FLOOR,
447 		BOMB_WALL,
448 		BOMB_CHEST,
449 		BOMB_DOOR
450 	};
451 	enum ItemBombFacingDirection : int
452 	{
453 		BOMB_UP,
454 		BOMB_NORTH,
455 		BOMB_EAST,
456 		BOMB_SOUTH,
457 		BOMB_WEST
458 	};
459 	enum ItemBombTriggerType : int
460 	{
461 		BOMB_TRIGGER_ENEMIES,
462 		BOMB_TELEPORT_RECEIVER,
463 		BOMB_TRIGGER_ALL
464 	};
465 	void applyBomb(Entity* parent, ItemType type, ItemBombPlacement placement, ItemBombFacingDirection dir, Entity* thrown, Entity* onEntity);
466 	void applyTinkeringCreation(Entity* parent, Entity* thrown);
467 	bool unableToEquipDueToSwapWeaponTimer() const;
468 	bool tinkeringBotIsMaxHealth() const;
469 	bool isTinkeringItemWithThrownLimit() const;
470 };
471 extern Uint32 itemuids;
472 
473 static const int INVENTORY_SIZEX = 12;
474 extern int INVENTORY_SIZEY;
475 #define INVENTORY_SIZE ((INVENTORY_SIZEX)*(INVENTORY_SIZEY))
476 #define INVENTORY_STARTX ((xres)/2-(INVENTORY_SIZEX)*(INVENTORY_SLOTSIZE)/2-inventory_mode_item_img->w/2)
477 static const int INVENTORY_STARTY = 10;
478 
479 extern Item* selectedItem;
480 
481 // item generic
482 class ItemGeneric
483 {
484 public:
485 	char* name_identified;      // identified item name
486 	char* name_unidentified;    // unidentified item name
487 	int index;                  // world model
488 	int fpindex;                // first person model
489 	int variations;             // number of model variations
490 	int weight;                 // weight per item
491 	int value;                  // value per item
492 	list_t images;              // item image filenames (inventory)
493 	list_t surfaces;            // item image surfaces (inventory)
494 	Category category;          // item category
495 	int level;					// item level for random generation
496 };
497 extern ItemGeneric items[NUMITEMS];
498 
499 //----------Item usage functions----------
500 bool item_PotionWater(Item*& item, Entity* entity, Entity* usedBy);
501 bool item_PotionBooze(Item*& item, Entity* entity, Entity* usedBy, bool shouldConsumeItem = true);
502 bool item_PotionJuice(Item*& item, Entity* entity, Entity* usedBy);
503 bool item_PotionSickness(Item*& item, Entity* entity, Entity* usedBy);
504 bool item_PotionConfusion(Item*& item, Entity* entity, Entity* usedBy);
505 bool item_PotionCureAilment(Item*& item, Entity* entity, Entity* usedBy);
506 bool item_PotionBlindness(Item*& item, Entity* entity, Entity* usedBy);
507 bool item_PotionHealing(Item*& item, Entity* entity, Entity* usedBy, bool shouldConsumeItem = true);
508 bool item_PotionExtraHealing(Item*& item, Entity* entity, Entity* usedBy, bool shouldConsumeItem = true);
509 bool item_PotionRestoreMagic(Item*& item, Entity* entity, Entity* usedBy);
510 bool item_PotionInvisibility(Item*& item, Entity* entity, Entity* usedBy);
511 bool item_PotionLevitation(Item*& item, Entity* entity, Entity* usedBy);
512 bool item_PotionSpeed(Item*& item, Entity* entity, Entity* usedBy);
513 bool item_PotionStrength(Item*& item, Entity* entity, Entity* usedBy);
514 bool item_PotionAcid(Item*& item, Entity* entity, Entity* usedBy);
515 bool item_PotionUnstableStorm(Item*& item, Entity* entity, Entity* usedBy, Entity* thrownPotion);
516 bool item_PotionParalysis(Item*& item, Entity* entity, Entity* usedBy);
517 Entity* item_PotionPolymorph(Item*& item, Entity* entity, Entity* usedBy);
518 void item_ScrollMail(Item* item, int player);
519 void item_ScrollIdentify(Item* item, int player);
520 void item_ScrollLight(Item* item, int player);
521 void item_ScrollBlank(Item* item, int player);
522 void item_ScrollEnchantWeapon(Item* item, int player);
523 void item_ScrollEnchantArmor(Item* item, int player);
524 void item_ScrollRemoveCurse(Item* item, int player);
525 bool item_ScrollFire(Item* item, int player); // return true if exploded into fire.
526 void item_ScrollFood(Item* item, int player);
527 void item_ScrollConjureArrow(Item* item, int player);
528 void item_ScrollMagicMapping(Item* item, int player);
529 void item_ScrollRepair(Item* item, int player);
530 void item_ScrollDestroyArmor(Item* item, int player);
531 void item_ScrollTeleportation(Item* item, int player);
532 void item_ScrollSummon(Item* item, int player);
533 void item_AmuletSexChange(Item* item, int player);
534 void item_ToolTowel(Item*& item, int player);
535 void item_ToolTinOpener(Item* item, int player);
536 void item_ToolMirror(Item*& item, int player);
537 void item_ToolBeartrap(Item*& item, int player);
538 void item_Food(Item*& item, int player);
539 void item_FoodTin(Item*& item, int player);
540 void item_FoodAutomaton(Item*& item, int player);
541 void item_Gem(Item* item, int player);
542 void item_Spellbook(Item*& item, int player);
543 
544 //General functions.
545 Item* newItem(ItemType type, Status status, Sint16 beatitude, Sint16 count, Uint32 appearance, bool identified, list_t* inventory);
546 void addItemToMonsterInventory(Item &item, list_t& inventory);
547 Item* uidToItem(Uint32 uid);
548 ItemType itemCurve(Category cat);
549 ItemType itemLevelCurve(Category cat, int minLevel, int maxLevel);
550 Item* newItemFromEntity(const Entity* entity); //Make sure to call free(item).
551 Entity* dropItemMonster(Item* item, Entity* monster, Stat* monsterStats, Sint16 count = 1);
552 Item** itemSlot(Stat* myStats, Item* item);
553 
554 enum Category itemCategory(const Item* item);
555 Sint32 itemModel(const Item* item);
556 Sint32 itemModelFirstperson(const Item* item);
557 SDL_Surface* itemSprite(Item* item);
558 void consumeItem(Item*& item, int player); //NOTE: Items have to be unequipped before calling this function on them. NOTE: THIS CAN FREE THE ITEM POINTER. Sets item to nullptr if it does.
559 bool dropItem(Item* item, int player, bool notifyMessage = true); // return true on free'd item
560 void useItem(Item* item, int player, Entity* usedBy = nullptr);
561 enum EquipItemResult : int
562 {
563 	EQUIP_ITEM_FAIL_CANT_UNEQUIP,
564 	EQUIP_ITEM_SUCCESS_NEWITEM,
565 	EQUIP_ITEM_SUCCESS_UPDATE_QTY,
566 	EQUIP_ITEM_SUCCESS_UNEQUIP
567 };
568 enum EquipItemSendToServerSlot : int
569 {
570 	EQUIP_ITEM_SLOT_WEAPON,
571 	EQUIP_ITEM_SLOT_SHIELD,
572 	EQUIP_ITEM_SLOT_MASK,
573 	EQUIP_ITEM_SLOT_HELM,
574 	EQUIP_ITEM_SLOT_GLOVES,
575 	EQUIP_ITEM_SLOT_BOOTS,
576 	EQUIP_ITEM_SLOT_BREASTPLATE,
577 	EQUIP_ITEM_SLOT_CLOAK,
578 	EQUIP_ITEM_SLOT_AMULET,
579 	EQUIP_ITEM_SLOT_RING
580 };
581 void playerTryEquipItemAndUpdateServer(Item* item);
582 void clientSendEquipUpdateToServer(EquipItemSendToServerSlot slot, EquipItemResult equipType, int player,
583 	ItemType type, Status status, Sint16 beatitude, int count, Uint32 appearance, bool identified);
584 void clientUnequipSlotAndUpdateServer(EquipItemSendToServerSlot slot, Item* item);
585 EquipItemResult equipItem(Item* item, Item** slot, int player);
586 Item* itemPickup(int player, Item* item);
587 bool itemIsEquipped(const Item* item, int player);
588 bool shouldInvertEquipmentBeatitude(const Stat* wielder);
589 bool isItemEquippableInShieldSlot(const Item* item);
590 bool itemIsConsumableByAutomaton(const Item& item);
591 
592 extern const real_t potionDamageSkillMultipliers[6];
593 extern const real_t thrownDamageSkillMultipliers[6];
594 extern std::mt19937 enchantedFeatherScrollSeed;
595 extern std::vector<int> enchantedFeatherScrollsShuffled;
596 static const std::vector<int> enchantedFeatherScrollsFixedList =
597 {
598 	SCROLL_BLANK,
599 	SCROLL_MAIL,
600 	SCROLL_DESTROYARMOR,
601 	SCROLL_DESTROYARMOR,
602 	SCROLL_DESTROYARMOR,
603 	SCROLL_FIRE,
604 	SCROLL_FIRE,
605 	SCROLL_FIRE,
606 	SCROLL_LIGHT,
607 	SCROLL_LIGHT,
608 	SCROLL_SUMMON,
609 	SCROLL_SUMMON,
610 	SCROLL_IDENTIFY,
611 	SCROLL_IDENTIFY,
612 	SCROLL_REMOVECURSE,
613 	SCROLL_CONJUREARROW,
614 	SCROLL_FOOD,
615 	SCROLL_FOOD,
616 	SCROLL_TELEPORTATION,
617 	SCROLL_TELEPORTATION,
618 	SCROLL_CHARGING,
619 	SCROLL_REPAIR,
620 	SCROLL_MAGICMAPPING,
621 	SCROLL_ENCHANTWEAPON,
622 	SCROLL_ENCHANTARMOR
623 };
624 static const int ENCHANTED_FEATHER_MAX_DURABILITY = 101;
625 static const int QUIVER_MAX_AMMO_QTY = 51;
626 static const int SCRAP_MAX_STACK_QTY = 101;
627 
628 //-----ITEM COMPARISON FUNCS-----
629 /*
630  * Only compares items of the same type.
631  */
632 int itemCompare(const Item* item1, const Item* item2, bool checkAppearance);
633 
634 /*
635  * Returns true if potion is harmful to the player.
636  */
637 bool isPotionBad(const Item& potion);
638 bool isRangedWeapon(const Item& item);
639 bool isMeleeWeapon(const Item& item);
640 bool itemIsThrowableTinkerTool(const Item* item);
641 
642 void createCustomInventory(Stat* stats, int itemLimit);
643 void copyItem(Item* itemToSet, const Item* itemToCopy);
644 bool swapMonsterWeaponWithInventoryItem(Entity* my, Stat* myStats, node_t* inventoryNode, bool moveStack, bool overrideCursed);
645 bool monsterUnequipSlot(Stat* myStats, Item** slot, Item* itemToUnequip);
646 bool monsterUnequipSlotFromCategory(Stat* myStats, Item** slot, Category cat);
647 node_t* itemNodeInInventory(const Stat* myStats, Sint32 itemToFind, Category cat);
648 node_t* spellbookNodeInInventory(const Stat* myStats, int spellIDToFind);
649 node_t* getRangedWeaponItemNodeInInventory(const Stat* myStats, bool includeMagicstaff);
650 node_t* getMeleeWeaponItemNodeInInventory(const Stat* myStats);
651 ItemType itemTypeWithinGoldValue(int cat, int minValue, int maxValue);
652 bool itemSpriteIsQuiverThirdPersonModel(int sprite);
653 bool itemSpriteIsQuiverBaseThirdPersonModel(int sprite);
654 bool itemTypeIsQuiver(ItemType type);
655 bool itemSpriteIsBreastpiece(int sprite);
656 real_t rangedAttackGetSpeedModifier(const Stat* myStats);
657 bool rangedWeaponUseQuiverOnAttack(const Stat* myStats);
658 real_t getArtifactWeaponEffectChance(ItemType type, Stat& wielder, real_t* effectAmount);
659 void updateHungerMessages(Entity* my, Stat* myStats, Item* eaten);
660 bool playerCanSpawnMoreTinkeringBots(const Stat* myStats);
661 int maximumTinkeringBotsCanBeDeployed(const Stat* myStats);
662 extern bool overrideTinkeringLimit;
663 extern int decoyBoxRange;
664 
665 // unique monster item appearance to avoid being dropped on death.
666 static const int MONSTER_ITEM_UNDROPPABLE_APPEARANCE = 1234567890;
667 static const int ITEM_TINKERING_APPEARANCE = 987654320;
668 static const int ITEM_GENERATED_QUIVER_APPEARANCE = 1122334455;
669 
670 bool loadItemLists();