1 /**
2  * @file items.h
3  *
4  * Interface of item functionality.
5  */
6 #ifndef __ITEMS_H__
7 #define __ITEMS_H__
8 
9 #include "itemdat.h"
10 
11 DEVILUTION_BEGIN_NAMESPACE
12 
13 #ifdef __cplusplus
14 extern "C" {
15 #endif
16 
17 typedef enum item_quality {
18 	ITEM_QUALITY_NORMAL,
19 	ITEM_QUALITY_MAGIC,
20 	ITEM_QUALITY_UNIQUE,
21 } item_quality;
22 
23 /*
24  First 5 bits store level
25  6th bit stores onlygood flag
26  7th bit stores uper15 flag - uper means unique percent, this flag is true for unique monsters and loot from them has 15% to become unique
27  8th bit stores uper1 flag - this is loot from normal monsters, which has 1% to become unique
28  9th bit stores info if item is unique
29  10th bit stores info if item is a basic one from griswold
30  11th bit stores info if item is a premium one from griswold
31  12th bit stores info if item is from wirt
32  13th bit stores info if item is from adria
33  14th bit stores info if item is from pepin
34  15th bit stores pregen flag
35 
36  combining CF_UPER15 and CF_UPER1 flags (CF_USEFUL) is used to mark potions and town portal scrolls created on the ground
37  CF_TOWN is combining all store flags and indicates if item has been bought from a NPC
38  */
39 typedef enum icreateinfo_flag {
40 	// clang-format off
41 	CF_LEVEL        = (1 << 6) - 1,
42 	CF_ONLYGOOD     = 1 << 6,
43 	CF_UPER15       = 1 << 7,
44 	CF_UPER1        = 1 << 8,
45 	CF_UNIQUE       = 1 << 9,
46 	CF_SMITH        = 1 << 10,
47 	CF_SMITHPREMIUM = 1 << 11,
48 	CF_BOY          = 1 << 12,
49 	CF_WITCH        = 1 << 13,
50 	CF_HEALER       = 1 << 14,
51 	CF_PREGEN       = 1 << 15,
52 
53 	CF_USEFUL = CF_UPER15 | CF_UPER1,
54 	CF_TOWN   = CF_SMITH | CF_SMITHPREMIUM | CF_BOY | CF_WITCH | CF_HEALER,
55 	// clang-format on
56 } icreateinfo_flag;
57 
58 typedef enum icreateinfo_flag2 {
59 	// clang-format off
60 	CF_HELLFIRE = 1,
61 	// clang-format on
62 } icreateinfo_flag2;
63 
64 typedef struct ItemStruct {
65 	Sint32 _iSeed;
66 	Uint16 _iCreateInfo;
67 	enum item_type _itype;
68 	Sint32 _ix;
69 	Sint32 _iy;
70 	bool _iAnimFlag;
71 	Uint8 *_iAnimData;  // PSX name -> ItemFrame
72 	Sint32 _iAnimLen;   // Number of frames in current animation
73 	Sint32 _iAnimFrame; // Current frame of animation.
74 	Sint32 _iAnimWidth;
75 	Sint32 _iAnimWidth2; // width 2?
76 	bool _iDelFlag;      // set when item is flagged for deletion, deprecated in 1.02
77 	Uint8 _iSelFlag;
78 	bool _iPostDraw;
79 	bool _iIdentified;
80 	Sint8 _iMagical;
81 	char _iName[64];
82 	char _iIName[64];
83 	enum item_equip_type _iLoc;
84 	enum item_class _iClass;
85 	Sint32 _iCurs;
86 	Sint32 _ivalue;
87 	Sint32 _iIvalue;
88 	Sint32 _iMinDam;
89 	Sint32 _iMaxDam;
90 	Sint32 _iAC;
91 	Sint32 _iFlags; // item_special_effect
92 	enum item_misc_id _iMiscId;
93 	enum spell_id _iSpell;
94 	Sint32 _iCharges;
95 	Sint32 _iMaxCharges;
96 	Sint32 _iDurability;
97 	Sint32 _iMaxDur;
98 	Sint32 _iPLDam;
99 	Sint32 _iPLToHit;
100 	Sint32 _iPLAC;
101 	Sint32 _iPLStr;
102 	Sint32 _iPLMag;
103 	Sint32 _iPLDex;
104 	Sint32 _iPLVit;
105 	Sint32 _iPLFR;
106 	Sint32 _iPLLR;
107 	Sint32 _iPLMR;
108 	Sint32 _iPLMana;
109 	Sint32 _iPLHP;
110 	Sint32 _iPLDamMod;
111 	Sint32 _iPLGetHit;
112 	Sint32 _iPLLight;
113 	Sint8 _iSplLvlAdd;
114 	Sint8 _iRequest;
115 	Sint32 _iUid;
116 	Sint32 _iFMinDam;
117 	Sint32 _iFMaxDam;
118 	Sint32 _iLMinDam;
119 	Sint32 _iLMaxDam;
120 	Sint32 _iPLEnAc;
121 	enum item_effect_type _iPrePower;
122 	enum item_effect_type _iSufPower;
123 	Sint32 _iVAdd1;
124 	Sint32 _iVMult1;
125 	Sint32 _iVAdd2;
126 	Sint32 _iVMult2;
127 	Sint8 _iMinStr;
128 	Uint8 _iMinMag;
129 	Sint8 _iMinDex;
130 	bool _iStatFlag;
131 	Sint32 IDidx;
132 	Uint32 dwBuff;
133 	Sint32 _iDamAcFlags;
134 
135 	/**
136 	 * @brief Checks whether this item is empty or not.
137 	 * @return 'True' in case the item is empty and 'False' otherwise.
138 	 */
isEmptyItemStruct139 	bool isEmpty() const
140 	{
141 		return this->_itype == ITYPE_NONE;
142 	}
143 
144 	/**
145 	 * @brief Checks whether this item is an equipment.
146 	 * @return 'True' in case the item is an equipment and 'False' otherwise.
147 	 */
isEquipmentItemStruct148 	bool isEquipment() const
149 	{
150 		if (this->isEmpty()) {
151 			return false;
152 		}
153 
154 		switch (this->_iLoc) {
155 		case ILOC_AMULET:
156 		case ILOC_ARMOR:
157 		case ILOC_HELM:
158 		case ILOC_ONEHAND:
159 		case ILOC_RING:
160 		case ILOC_TWOHAND:
161 			return true;
162 
163 		default:
164 			return false;
165 		}
166 	}
167 
168 	/**
169 	 * @brief Checks whether this item is a weapon.
170 	 * @return 'True' in case the item is a weapon and 'False' otherwise.
171 	 */
isWeaponItemStruct172 	bool isWeapon() const
173 	{
174 		if (this->isEmpty()) {
175 			return false;
176 		}
177 
178 		switch (this->_itype) {
179 		case ITYPE_AXE:
180 		case ITYPE_BOW:
181 		case ITYPE_MACE:
182 		case ITYPE_STAFF:
183 		case ITYPE_SWORD:
184 			return true;
185 
186 		default:
187 			return false;
188 		}
189 	}
190 
191 	/**
192 	 * @brief Checks whether this item is an armor.
193 	 * @return 'True' in case the item is an armor and 'False' otherwise.
194 	 */
isArmorItemStruct195 	bool isArmor() const
196 	{
197 		if (this->isEmpty()) {
198 			return false;
199 		}
200 
201 		switch (this->_itype) {
202 		case ITYPE_HARMOR:
203 		case ITYPE_LARMOR:
204 		case ITYPE_MARMOR:
205 			return true;
206 
207 		default:
208 			return false;
209 		}
210 	}
211 
212 	/**
213 	 * @brief Checks whether this item is a helm.
214 	 * @return 'True' in case the item is a helm and 'False' otherwise.
215 	 */
isHelmItemStruct216 	bool isHelm() const
217 	{
218 		return !this->isEmpty() && this->_itype == ITYPE_HELM;
219 	}
220 
221 	/**
222 	 * @brief Checks whether this item is a shield.
223 	 * @return 'True' in case the item is a shield and 'False' otherwise.
224 	 */
isShieldItemStruct225 	bool isShield() const
226 	{
227 		return !this->isEmpty() && this->_itype == ITYPE_SHIELD;
228 	}
229 
230 	/**
231 	 * @brief Checks whether this item is a jewelry.
232 	 * @return 'True' in case the item is a jewelry and 'False' otherwise.
233 	 */
isJewelryItemStruct234 	bool isJewelry() const
235 	{
236 		if (this->isEmpty()) {
237 			return false;
238 		}
239 
240 		switch (this->_itype) {
241 		case ITYPE_AMULET:
242 		case ITYPE_RING:
243 			return true;
244 
245 		default:
246 			return false;
247 		}
248 	}
249 
250 } ItemStruct;
251 
252 typedef struct ItemGetRecordStruct {
253 	Sint32 nSeed;
254 	Uint16 wCI;
255 	Sint32 nIndex;
256 	Uint32 dwTimestamp;
257 } ItemGetRecordStruct;
258 
259 typedef struct CornerStoneStruct {
260 	Sint32 x;
261 	Sint32 y;
262 	bool activated;
263 	ItemStruct item;
264 } CornerStoneStruct;
265 
266 extern int itemactive[MAXITEMS];
267 extern BOOL uitemflag;
268 extern int itemavail[MAXITEMS];
269 extern ItemStruct item[MAXITEMS + 1];
270 extern CornerStoneStruct CornerStone;
271 extern BOOL UniqueItemFlag[128];
272 extern int numitems;
273 
274 bool IsItemAvailable(int i);
275 bool IsUniqueAvailable(int i);
276 void InitItemGFX();
277 void InitItems();
278 void CalcPlrItemVals(int p, BOOL Loadgfx);
279 void CalcPlrScrolls(int p);
280 void CalcPlrStaff(int p);
281 void CalcPlrInv(int p, BOOL Loadgfx);
282 void SetPlrHandItem(ItemStruct *h, int idata);
283 void GetPlrHandSeed(ItemStruct *h);
284 void GetGoldSeed(int pnum, ItemStruct *h);
285 int GetGoldCursor(int value);
286 void SetPlrHandGoldCurs(ItemStruct *h);
287 void CreatePlrItems(int p);
288 BOOL ItemSpaceOk(int i, int j);
289 int AllocateItem();
290 void GetSuperItemLoc(int x, int y, int *xx, int *yy);
291 void GetItemAttrs(int i, int idata, int lvl);
292 void SaveItemPower(int i, item_effect_type power, int param1, int param2, int minval, int maxval, int multval);
293 void GetItemPower(int i, int minlvl, int maxlvl, int flgs, BOOL onlygood);
294 void SetupItem(int i);
295 int RndItem(int m);
296 void SpawnUnique(int uid, int x, int y);
297 void SpawnItem(int m, int x, int y, BOOL sendmsg);
298 void CreateRndItem(int x, int y, BOOL onlygood, BOOL sendmsg, BOOL delta);
299 void CreateRndUseful(int pnum, int x, int y, BOOL sendmsg);
300 void CreateTypeItem(int x, int y, BOOL onlygood, int itype, int imisc, BOOL sendmsg, BOOL delta);
301 void RecreateItem(int ii, int idx, WORD icreateinfo, int iseed, int ivalue, bool isHellfire);
302 void RecreateEar(int ii, WORD ic, int iseed, int Id, int dur, int mdur, int ch, int mch, int ivalue, int ibuff);
303 void items_427A72();
304 void items_427ABA(int x, int y);
305 void SpawnQuestItem(int itemid, int x, int y, int randarea, int selflag);
306 void SpawnRock();
307 void SpawnRewardItem(int itemid, int xx, int yy);
308 void SpawnMapOfDoom(int xx, int yy);
309 void SpawnRuneBomb(int xx, int yy);
310 void SpawnTheodore(int xx, int yy);
311 void RespawnItem(int i, BOOL FlipFlag);
312 void DeleteItem(int ii, int i);
313 void ProcessItems();
314 void FreeItemGFX();
315 void GetItemFrm(int i);
316 void GetItemStr(int i);
317 void CheckIdentify(int pnum, int cii);
318 void DoRepair(int pnum, int cii);
319 void DoRecharge(int pnum, int cii);
320 void DoOil(int pnum, int cii);
321 void PrintItemPower(char plidx, ItemStruct *x);
322 void DrawUniqueInfo(CelOutputBuffer out);
323 void PrintItemDetails(ItemStruct *x);
324 void PrintItemDur(ItemStruct *x);
325 void UseItem(int p, item_misc_id Mid, spell_id spl);
326 BOOL StoreStatOk(ItemStruct *h);
327 void SpawnSmith(int lvl);
328 void SpawnPremium(int pnum);
329 void WitchBookLevel(int ii);
330 void SpawnWitch(int lvl);
331 void SpawnBoy(int lvl);
332 void SpawnHealer(int lvl);
333 void SpawnStoreGold();
334 void RecreateTownItem(int ii, int idx, WORD icreateinfo, int iseed, int ivalue);
335 void RecalcStoreStats();
336 int ItemNoFlippy();
337 void CreateSpellBook(int x, int y, spell_id ispell, BOOL sendmsg, BOOL delta);
338 void CreateMagicArmor(int x, int y, int imisc, int icurs, BOOL sendmsg, BOOL delta);
339 void CreateAmulet(int x, int y, int curlv, BOOL sendmsg, BOOL delta);
340 void CreateMagicWeapon(int x, int y, int imisc, int icurs, BOOL sendmsg, BOOL delta);
341 BOOL GetItemRecord(int nSeed, WORD wCI, int nIndex);
342 void SetItemRecord(int nSeed, WORD wCI, int nIndex);
343 void PutItemRecord(int nSeed, WORD wCI, int nIndex);
344 
345 /* data */
346 
347 extern int MaxGold;
348 
349 extern BYTE ItemCAnimTbl[];
350 extern int ItemInvSnds[];
351 
352 #ifdef __cplusplus
353 }
354 #endif
355 
356 DEVILUTION_END_NAMESPACE
357 
358 #endif /* __ITEMS_H__ */
359