1 /***************************************************************************
2                 item.h  -  Class representing a specific item
3                              -------------------
4     begin                : Sun Sep 28 2003
5     copyright            : (C) 2003 by Gabor Torok
6     email                : cctorok@yahoo.com
7  ***************************************************************************/
8 
9 /***************************************************************************
10  *                                                                         *
11  *   This program is free software; you can redistribute it and/or modify  *
12  *   it under the terms of the GNU General Public License as published by  *
13  *   the Free Software Foundation; either version 2 of the License, or     *
14  *   (at your option) any later version.                                   *
15  *                                                                         *
16  ***************************************************************************/
17 
18 #ifndef ITEM_H
19 #define ITEM_H
20 #pragma once
21 
22 #include "persist.h"
23 #include "render/rendereditem.h"
24 #include "storable.h"
25 #include "rpg/rpg.h"
26 #include <vector>
27 #include <map>
28 #include "rpg/rpgitem.h"
29 
30 
31 class RpgItem;
32 class Color;
33 class GLShape;
34 class Spell;
35 class MagicSchool;
36 class Dice;
37 class Session;
38 class ShapePalette;
39 class ConfigLang;
40 class ConfigNode;
41 class Scourge;
42 class Texture;
43 class Creature;
44 
45 /**
46   *@author Gabor Torok
47   */
48 
49 /// This class defines attributes and appearance of an item.
50 
51 /// This class is both the UI representation (shape) of the rpgItem and it's state (for example, wear).
52 /// All instances of the RpgItem point to the same RpgItem, but a new Item is created for each.
53 
54 class Item : public RenderedItem, Storable {
55 public:
56 
57 	#define GRID_SIZE 32
58 
59 	enum {
60 		ID_BONUS = 0,
61 		ID_DAMAGE_MUL,
62 		ID_MAGIC_DAMAGE,
63 		ID_STATE_MOD,
64 		ID_PROT_STATE_MOD,
65 		ID_SKILL_BONUS,
66 		ID_CURSED,
67 		//number of bits that represents item identification
68 		ID_COUNT,
69 		ITEM_NAME_SIZE = 255
70 	};
71 
72 	Item( Session *session, RpgItem *rpgItem, int level = 1, bool loading = false );
73 	~Item();
74 
setInventoryOf(Creature * creature)75 	inline void setInventoryOf( Creature *creature ) { inventoryOf = creature; }
getInventoryOf()76 	inline Creature *getInventoryOf() { return inventoryOf; }
77 
setMissionObjectInfo(int missionId,int objectiveIndex)78 	inline void setMissionObjectInfo( int missionId, int objectiveIndex ) {
79 		this->missionId = missionId;
80 		this->missionObjectiveIndex = objectiveIndex;
81 	}
getMissionId()82 	inline int getMissionId() {
83 		return missionId;
84 	}
getMissionObjectiveIndex()85 	inline int getMissionObjectiveIndex() {
86 		return missionObjectiveIndex;
87 	}
88 
89 	void renderIcon( Scourge *scourge, SDL_Rect *rect, int gridSize = GRID_SIZE, bool smallIcon = false );
90 	void renderIcon( Scourge *scourge, int x, int y, int w, int h, bool smallIcon = false );
91 	Texture getItemIconTexture( bool smallIcon = false );
92 	void getTooltip( char *tooltip );
93 
setBackpackLocation(int x,int y)94 	inline void setBackpackLocation( int x, int y ) {
95 		backpackX = x;
96 		backpackY = y;
97 	}
98 	/// x position in the backpack.
getBackpackX()99 	inline int getBackpackX() {
100 		return backpackX;
101 	}
102 	/// y position in the backpack.
getBackpackY()103 	inline int getBackpackY() {
104 		return backpackY;
105 	}
106 	int getBackpackWidth();
107 	int getBackpackHeight();
108 
setIdentifiedBit(int bit,bool value)109 	inline void setIdentifiedBit( int bit, bool value ) {
110 		if ( value ) identifiedBits |= ( 1 << bit );
111 		else identifiedBits &= ( ( Uint32 )0xffff - ( Uint32 )( 1 << bit ) );
112 	}
113 	/// Checks whether a special item property has been identified.
getIdentifiedBit(int bit)114 	inline bool getIdentifiedBit( int bit ) {
115 		return( identifiedBits & ( 1 << bit ) ? true : false );
116 	}
117 	void identify( int infoDetailLevel );
118 	/// Returns true if all bits in identifiedBits are set to true, i.e. fully identified.
isIdentified()119 	inline bool isIdentified() {
120 		return( isMagicItem() && identifiedBits >= ( 1 << ID_COUNT ) - 1 );
121 	}
122 	bool isFullyIdentified();
123 
124 
125 	ItemInfo *save();
126 	//ContainedItemInfo saveContainedItems();
127 	static Item *load( Session *session, ItemInfo *info );
128 
129 	/// Unused.
getColor()130 	inline Color *getColor() {
131 		return color;
132 	}
133 	/// Unused.
setColor(Color * c)134 	inline void setColor( Color *c ) {
135 		color = c;
136 	}
setShape(GLShape * s)137 	inline void setShape( GLShape *s ) {
138 		shape = s;
139 	}
140 	/// The item's 3D model.
getShape()141 	inline GLShape *getShape() {
142 		return shape;
143 	}
144 	/// This specific item's base item.
getRpgItem()145 	inline RpgItem *getRpgItem() {
146 		return rpgItem;
147 	}
isBlocking()148 	inline bool isBlocking() {
149 		return blocking;
150 	}
setBlocking(bool b)151 	inline void setBlocking( bool b ) {
152 		blocking = b;
153 	}
154 	/// Number of remaining charges/uses.
getCurrentCharges()155 	inline int getCurrentCharges() {
156 		return currentCharges;
157 	}
158 	void setCurrentCharges( int n );
setWeight(float f)159 	inline void setWeight( float f ) {
160 		if ( f < 0.0f )f = 0.1f; weight = f;
161 	}
162 	void setSpell( Spell *spell );
getSpell()163 	inline Spell *getSpell() {
164 		return spell;
165 	}
166 
167 	/// Sets whether the item's cursed status should be hidden or not.
setShowCursed(bool b)168 	inline void setShowCursed( bool b ) {
169 		showCursed = b;
170 	}
getShowCursed()171 	inline bool getShowCursed() {
172 		return showCursed;
173 	}
174 
175 	void getDetailedDescription( std::string& s, bool precise = true );
176 	/// The item's localized name.
getItemName()177 	inline char const* getItemName() {
178 		return itemName;
179 	}
180 
181 	/// Number of other items this item contains.
getContainedItemCount()182 	inline int getContainedItemCount() {
183 		return containedItemCount;
184 	}
185 	bool addContainedItem( Item *item, int itemX=0, int itemY=0 );
186 	void removeContainedItem( Item *item );
187 	Item *getContainedItem( int index );
188 	void setContainedItem( int index, Item *item );
189 	bool isContainedItem( Item *item );
190 	/// Returns true if the item contains magical items.
getContainsMagicItem()191 	inline bool getContainsMagicItem() {
192 		return containsMagicItem;
193 	}
194 
195 	bool decrementCharges();
196 
getRandomSound()197 	const std::string getRandomSound() {
198 		return rpgItem->getRandomSound();
199 	}
200 
201 	void enchant( int level );
202 
203 	char const* getType();
204 
205 
206 	// level-based attributes
207 	/// The item's level.
getLevel()208 	inline int getLevel() {
209 		return level;
210 	}
211 	/// The item's weight.
getWeight()212 	inline float getWeight() {
213 		return weight;
214 	}
215 	/// Price of the item without trade boni/mali.
getPrice()216 	inline int getPrice() {
217 		return price;
218 	}
219 	/// Unused.
getQuality()220 	inline int getQuality() {
221 		return quality;
222 	}
223 
isMagicItem()224 	inline bool isMagicItem() {
225 		return ( magicLevel > -1 );
226 	}
227 	bool isSpecial();
getSkillBonusMap()228 	inline std::map<int, int> *getSkillBonusMap() {
229 		return &skillBonus;
230 	}
231 	/// The bonus the item gives for the specified skill.
getSkillBonus(int skill)232 	inline int getSkillBonus( int skill ) {
233 		return ( skillBonus.find( skill ) == skillBonus.end() ? 0 : skillBonus[skill] );
234 	}
235 	/// The magic level (none, lesser, greater, champion, divine)
getMagicLevel()236 	inline int getMagicLevel() {
237 		return magicLevel;
238 	}
getBonus()239 	inline int getBonus() {
240 		return bonus;
241 	}
242 	/// Returns the "x times damage against ..." bonus.
getDamageMultiplier()243 	inline int getDamageMultiplier() {
244 		return damageMultiplier;
245 	}
246 	/// The monster type the damage multiplier applies to.
getMonsterType()247 	inline char const* getMonsterType() {
248 		return monsterType;
249 	}
250 	/// Magic school of the attached spell.
getSchool()251 	inline MagicSchool *getSchool() {
252 		return school;
253 	}
254 	int rollMagicDamage();
255 	int getMagicResistance();
256 	char *describeMagicDamage();
257 	/// "Cursed" state of the item.
isCursed()258 	inline bool isCursed() {
259 		return cursed;
260 	}
setCursed(bool b)261 	inline void setCursed( bool b ) {
262 		this->cursed = b;
263 	}
264 	/// Does it set the specified state mod?
isStateModSet(int mod)265 	inline bool isStateModSet( int mod ) {
266 		return( stateMod[mod] == 1 );
267 	}
268 	/// Does it protect against the specified state mod?
isStateModProtected(int mod)269 	inline bool isStateModProtected( int mod ) {
270 		return( stateMod[mod] == 2 );
271 	}
272 	int getRange();
273 
274 	void debugMagic( char *s );
275 
276 	// storable interface
277 	const char *getName();
278 	int getIconTileX();
279 	int getIconTileY();
280 	int getStorableType();
281 	const char *isStorable();
282 
283 	Texture getContainerTexture();
284 
285 private:
286 	Creature *inventoryOf;
287 	RpgItem *rpgItem;
288 	int shapeIndex;
289 	Color *color;
290 	GLShape *shape;
291 	bool blocking;
292 	Item *containedItems[MAX_CONTAINED_ITEMS];
293 	int containedItemCount;
294 	int currentCharges;
295 	Spell *spell;
296 	char itemName[ ITEM_NAME_SIZE ];
297 	bool containsMagicItem;
298 	bool showCursed;
299 	// unused: GLuint tex3d[1];
300 	// unused: unsigned char * textureInMemory;
301 	void trySetIDBit( int bit, float modifier, int infoDetailLevel );
302 
303 	static const int PARTICLE_COUNT = 30;
304 	Uint32 iconEffectTimer;
305 	ParticleStruct *iconEffectParticle[PARTICLE_COUNT];
306 	Uint32 iconUnderEffectTimer;
307 	ParticleStruct *iconUnderEffectParticle[PARTICLE_COUNT];
308 
309 	// Things that change with item level (override rpgitem values)
310 	int level;
311 	float weight;
312 	int price;
313 	int quality;
314 
315 	// former magic attrib stuff
316 	int magicLevel;
317 	int bonus; // e.g.: sword +2
318 	int damageMultiplier; // 2=double damage, 3=triple, etc.
319 	char const* monsterType; // if not NULL, damageMultiplier only for this type of monster.
320 	MagicSchool *school; // magic damage by a school (or NULL if N/A)
321 	Dice *magicDamage;
322 	bool cursed;
323 	int stateMod[StateMod::STATE_MOD_COUNT]; // 0=nothing, 1=sets, 2=clears/protects against state mod when worn
324 	bool stateModSet;
325 	std::map<int, int> skillBonus;
326 	Session *session;
327 	Uint32 identifiedBits;
328 	int backpackX, backpackY;
329 	int missionId;
330 	int missionObjectiveIndex;
331 	// unused: std::map<RpgItem*, Texture> containerTextures;
332 	Texture containerTexture;
333 
334 protected:
335 	bool findInventoryPosition( Item *item, int posX, int posY, bool useExistingLocationForSameItem );
336 	bool checkInventoryLocation( Item *item, bool useExistingLocationForSameItem, int posX, int posY );
337 
338 	void commonInit( bool loading );
339 	void describeMagic( char const* displayName );
340 
341 	DiceInfo *saveDice( Dice *dice );
342 	static DiceInfo *saveEmptyDice();
343 	static Dice *loadDice( Session *session, DiceInfo *info );
344 
345 	void renderItemIcon( Scourge *scourge, int x, int y, int w, int h, bool smallIcon = false );
346 	void renderItemIconEffect( Scourge *scourge, int x, int y, int w, int h, int iw, int ih );
347 	void renderItemIconIdentificationEffect( Scourge *scourge, int x, int y, int w, int h );
348 	void renderUnderItemIconEffect( Scourge *scourge, int x, int y, int w, int h, int iw, int ih );
349 	// unused: void create3dTex( Scourge *scourge, float w, float h );
350 	void getItemIconInfo( Texture* texp, int *rwp, int *rhp, int *oxp, int *oyp, int *iw, int *ih, int w, int h, bool smallIcon = false );
351 };
352 
353 #endif
354