1 /* GemRB - Infinity Engine Emulator
2  * Copyright (C) 2003 The GemRB Project
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  *
19  */
20 
21 /**
22  * @file Item.h
23  * Declares Item, class for all things your PCs can pick, carry and wear
24  * and many they can't.
25  * @author The GemRB Project
26  */
27 
28 #ifndef ITEM_H
29 #define ITEM_H
30 
31 #include "exports.h"
32 #include "ie_types.h"
33 #include "Resource.h"
34 
35 #include "EffectQueue.h"
36 
37 #include <vector>
38 
39 namespace GemRB {
40 
41 class Projectile;
42 
43 // Item Flags bits
44 // !!! Keep these synchronized with GUIDefines.h !!!
45 #define IE_ITEM_CRITICAL     0x00000001
46 #define IE_ITEM_TWO_HANDED   0x00000002
47 #define IE_ITEM_MOVABLE      0x00000004
48 #define IE_ITEM_DISPLAYABLE  0x00000008
49 #define IE_ITEM_CURSED       0x00000010
50 #define IE_ITEM_NOT_COPYABLE 0x00000020
51 #define IE_ITEM_MAGICAL      0x00000040
52 #define IE_ITEM_BOW          0x00000080 // TODO: ee lefthanded
53 #define IE_ITEM_SILVER       0x00000100
54 #define IE_ITEM_COLD_IRON    0x00000200
55 #define IE_ITEM_STOLEN       0x00000400 // TODO: ee offhanded
56 #define IE_ITEM_CONVERSABLE  0x00000800
57 #define IE_ITEM_PULSATING    0x00001000 // TODO: ee fake offhand
58 #define IE_ITEM_UNSELLABLE   ( IE_ITEM_CRITICAL | IE_ITEM_STOLEN ) // beware: IE_STORE_BUYCRITS may override the first half
59 // see IESDP for details
60 #define IE_ITEM_FORCE_2H     0x00002000 // TODO: ee, Force two-handed animation DISABLE_OFFHAND
61 #define IE_ITEM_NOT_OFFHAND  0x00004000 // TODO: ee, Not usable in off-hand
62 #define IE_ITEM_INV_USABLE   0x00008000 // TODO: ee ADAMANTINE (itemflag.ids); pstee, usable in inventory
63 #define IE_ITEM_ADAMANTINE   0x00010000 // RECHECK vs IE_ITEM_INV_USABLE (missing from ids)
64 //tobex modder extensions, please note, these are not copied into the local slot bits
65 #define IE_ITEM_NO_DISPEL    0x01000000 // TODO: disables destruction by dispelling; named BODYPART in ee - different?
66 #define IE_ITEM_TOGGLE_CRITS 0x02000000 //toggles critical hit avertion
67 #define IE_ITEM_NO_INVIS     0x04000000 // TODO: don't target invisible
68 
69 
70 //Extended header recharge flags
71 #define IE_ITEM_USESTRENGTH  1          //weapon, EE splits it in two
72 #define IE_ITEM_BREAKABLE    2          //weapon
73 #define IE_ITEM_USESTRENGTH_DMG  4      // EE
74 #define IE_ITEM_USESTRENGTH_HIT  8      // EE
75 #define IE_ITEM_USEDEXTERITY 16         //gemrb weapon finesse (move this if tobex implements it elsewhere)
76 #define IE_ITEM_HOSTILE      0x400      //equipment
77 #define IE_ITEM_RECHARGE     0x800      //equipment
78 #define IE_ITEM_BYPASS       0x10000    //weapon (bypass shield and armor bonus)
79 #define IE_ITEM_KEEN         0x20000    //weapon
80 
81 //modder extensions
82 #define IE_ITEM_BACKSTAB     0x01000000 //can used for backstab (ranged weapon)
83 
84 //item use locations (weapons are not listed in equipment list)
85 #define ITEM_LOC_WEAPON    1   //this is a weapon slot (uses thac0 etc)
86 #define ITEM_LOC_EQUIPMENT 3   //this slot appears on equipment list
87 //other item locations appear useless
88 
89 //attack types
90 #define ITEM_AT_MELEE      1
91 #define ITEM_AT_PROJECTILE 2
92 #define ITEM_AT_MAGIC      3
93 #define ITEM_AT_BOW	4
94 
95 //target types
96 #define TARGET_INVALID  0          //all the rest (default)
97 #define TARGET_CREA  1             //single living creature
98 #define TARGET_INV   2             //inventory item (not used?)
99 #define TARGET_DEAD  3             //creature, item or point
100 #define TARGET_AREA  4             //point target
101 #define TARGET_SELF  5             //self
102 #define TARGET_UNKNOWN 6           //unknown (use default)
103 #define TARGET_NONE  7             //self
104 
105 //projectile qualifiers
106 #define PROJ_ARROW  1
107 #define PROJ_BOLT   2
108 #define PROJ_BULLET 4
109 
110 //charge depletion flags
111 #define CHG_NONE    0
112 #define CHG_BREAK   1
113 #define CHG_NOSOUND 2
114 #define CHG_DAY     3
115 
116 //items caster level is hardcoded to 10
117 #define ITEM_CASTERLEVEL   10
118 
119 struct DMGOpcodeInfo {
120 	const char *TypeName;
121 	int DiceThrown;
122 	int DiceSides;
123 	int DiceBonus;
124 	int Chance;
125 };
126 
127 /**
128  * @class ITMExtHeader
129  * Header for special effects and uses of an Item.
130  */
131 
132 class GEM_EXPORT ITMExtHeader {
133 public:
134 	ITMExtHeader();
135 	~ITMExtHeader();
136 	ieByte AttackType;
137 	ieByte IDReq;
138 	ieByte Location;
139 	ieByte AltDiceSides = 0;
140 	ieResRef UseIcon;
141 	ieStrRef Tooltip;
142 	ieByte Target;
143 	ieByte TargetNumber;
144 	ieWord Range;
145 	//this is partially redundant, but the original engine uses this value to
146 	//determine projectile type (ProjectileQualifier is almost always set too)
147 	//We use this field only when really needed, and resolve the redundancy
148 	//in the exporter. The reason: using bitfields is more flexible.
149 	//ieByte ProjectileType;
150 	ieByte AltDiceThrown = 0;
151 	ieByte Speed = 0;
152 	ieByte AltDamageBonus = 0;
153 	ieWord THAC0Bonus;
154 	ieWord DiceSides;
155 	ieWord DiceThrown;
156 	ieWordSigned DamageBonus; //this must be signed!!!
157 	ieWord DamageType;
158 	ieWord FeatureCount;
159 	ieWord FeatureOffset;
160 	ieWord Charges;
161 	ieWord ChargeDepletion;
162 	ieDword RechargeFlags; //this is a bitfield with many bits
163 	ieWord ProjectileAnimation;
164 	ieWord MeleeAnimation[3];
165 	//this value is set in projectiles and launchers too
166 	int ProjectileQualifier; //this is a derived value determined on load time
167 	Effect *features;
168 };
169 
170 /**
171  * @class Item
172  * Class for all things your PCs can pick, carry and wear and many they can't.
173  */
174 
175 class GEM_EXPORT Item {
176 public:
177 	Item();
178 	~Item();
179 
180 	ITMExtHeader *ext_headers;
181 	Effect *equipping_features;
182 	ieResRef Name; //the resref of the item itself!
183 
184 	ieStrRef ItemName;
185 	ieStrRef ItemNameIdentified;
186 	ieResRef ReplacementItem;
187 	ieDword Flags;
188 	ieWord ItemType;
189 	ieDword UsabilityBitmask;
190 	char AnimationType[2];
191 	ieByte MinLevel;
192 	ieByte unknown1;
193 	ieByte MinStrength;
194 	ieByte unknown2;
195 	ieByte MinStrengthBonus;
196 	//kit1
197 	ieByte MinIntelligence;
198 	//kit2
199 	ieByte MinDexterity;
200 	//kit3
201 	ieByte MinWisdom;
202 	//kit4
203 	ieByte MinConstitution;
204 	ieByte WeaProf;
205 	ieByte MinCharisma;
206 	ieByte unknown3;
207 	ieDword KitUsability;
208 	ieDword Price;
209 	ieWord MaxStackAmount;
210 	ieResRef ItemIcon;
211 	ieWord LoreToID;
212 	ieResRef GroundIcon;
213 	ieDword Weight;
214 	ieStrRef ItemDesc;
215 	ieStrRef ItemDescIdentified;
216 	ieResRef DescriptionIcon;
217 	ieDword Enchantment;
218 	ieDword ExtHeaderOffset;
219 	ieWord ExtHeaderCount;
220 	ieDword FeatureBlockOffset;
221 	ieWord EquippingFeatureOffset;
222 	ieWord EquippingFeatureCount;
223 
224 	// PST and BG2 only
225 	ieResRef Dialog;
226 	ieStrRef DialogName;
227 
228 	// PST only
229 	ieWord WieldColor;
230 
231 	// PST and IWD2 only
232 	char unknown[26];
233 	// flag items to mutually exclusive to equip
234 	ieDword ItemExcl;
235 public:
GetItemName(bool identified)236 	ieStrRef GetItemName(bool identified) const
237 	{
238 		if(identified) {
239 			if((int) ItemNameIdentified>=0) return ItemNameIdentified;
240 			return ItemName;
241 		}
242 		if((int) ItemName>=0) {
243 			return ItemName;
244 		}
245 		return ItemNameIdentified;
246 	}
GetItemDesc(bool identified)247 	ieStrRef GetItemDesc(bool identified) const
248 	{
249 		if(identified) {
250 			if((int) ItemDescIdentified>=0) return ItemDescIdentified;
251 			return ItemDesc;
252 		}
253 		if((int) ItemDesc>=0) {
254 			return ItemDesc;
255 		}
256 		return ItemDescIdentified;
257 	}
258 
259 	//returns if the item is usable, expend will also expend a charge
260 	int UseCharge(ieWord *Charges, int header, bool expend) const;
261 
262 	//returns the requested extended header
263 	//-1 will return melee weapon header, -2 the ranged one
GetExtHeader(int which)264 	ITMExtHeader *GetExtHeader(int which) const
265 	{
266 		if(which < 0)
267 			return GetWeaponHeader(which == -2) ;
268 		if(ExtHeaderCount<=which) {
269 			return NULL;
270 		}
271 		return ext_headers+which;
272 	}
GetWieldedGradient()273 	ieDword GetWieldedGradient() const
274 	{
275 		return WieldColor;
276 	}
277 
278 	//-1 will return the equipping feature block
279 	EffectQueue *GetEffectBlock(Scriptable *self, const Point &pos, int header, ieDwordSigned invslot, ieDword pro) const;
280 	//returns a projectile created from an extended header
281 	//if miss is non-zero, then no effects will be loaded
282 	Projectile *GetProjectile(Scriptable *self, int header, const Point &target, ieDwordSigned invslot, int miss) const;
283 	//Builds an equipping glow effect from gradient colour
284 	//this stuff is not item specific, could be moved elsewhere
285 	Effect *BuildGlowEffect(int gradient) const;
286 	//returns the average damage of the weapon (doesn't check for special effects)
287 	int GetDamagePotential(bool ranged, ITMExtHeader *&header) const;
288 	//returns the weapon header
289 	ITMExtHeader *GetWeaponHeader(bool ranged) const;
290 	int GetWeaponHeaderNumber(bool ranged) const;
291 	int GetEquipmentHeaderNumber(int cnt) const;
292 	unsigned int GetCastingDistance(int header) const;
293 	// returns  a vector with details about any extended headers containing fx_damage with a 100% probability
294 	std::vector<DMGOpcodeInfo> GetDamageOpcodesDetails(const ITMExtHeader *header) const;
295 private:
296 };
297 
298 }
299 
300 #endif // ! ITEM_H
301