1 /*
2  * PROPRIETARY INFORMATION.  This software is proprietary to POWDER
3  * Development, and is not to be reproduced, transmitted, or disclosed
4  * in any way without written permission.
5  *
6  * Produced by:	Jeff Lait
7  *
8  *      	POWDER Development
9  *
10  * NAME:        item.h ( POWDER Library, C++ )
11  *
12  * COMMENTS:
13  *	This provides the definition for all itmes.
14  */
15 
16 #ifndef __item_h__
17 #define __item_h__
18 
19 #include "glbdef.h"
20 #include "grammar.h"
21 #include "mobref.h"
22 #include "name.h"
23 
24 class SRAMSTREAM;
25 
26 class MOB;
27 class INTRINSIC;
28 class INTRINSIC_COUNTER;
29 class MAP;
30 class ARTIFACT;
31 
32 // One time initialization.
33 void item_init();
34 
35 class ITEM
36 {
37 private:
38     ITEM(); // Create items with ::create please.
39 public:
40     ~ITEM();
41 
42     static ITEM	*create(ITEM_NAMES definition, bool allowartifact = true,
43 			bool nocurse = false);
44 
45     // This returns the mundane item enum that goes with the exceptional
46     // magic type.  ITEM_NONE is returned if it couldn't be found.
47     static ITEM_NAMES lookupMagicItem(MAGICTYPE_NAMES magictype,
48 				int magicclass);
49 
50     static ITEM *createMagicItem(MAGICTYPE_NAMES magictype,
51 				 int magicclass,
52 				 bool allowartifact = true,
53 				 bool nocurse = false);
54 
55     // Creates a clone of this item.  All the local data will
56     // match.  Note that the corpse mob will be cleared!  This is because
57     // we have ownership of it, so bad stuff would happen if we cloned it.
58     ITEM	*createClone() const;
59 
60     // Create any random item.
61     static ITEM *createRandom(bool allowartifact = true);
62     // Create a random of a given type.
63     static ITEM *createRandomType(ITEMTYPE_NAMES type,
64 				  bool allowartifact = true);
65     static ITEM *createRandomFromTable(int *table, int max_prob,
66 				  bool allowartifact = true);
67 
68     // Creates a corpse from the given mob...
69     static ITEM *createCorpse(MOB *mob);
70 
71     // Creates a statue from the given mob...
72     static ITEM *createStatue(MOB *mob);
73 
74     static ITEM *load(SRAMSTREAM &is);
75 
76     static BUF	 buildAttackName(const ATTACK_DEF *attack);
77 
78     static void  loadGlobal(SRAMSTREAM &is);
79     static void  saveGlobal(SRAMSTREAM &is);
80 
81     // This builds, or rebuilds all the itemtype tables....
82     static void  	 init();
83 
84     void		 save(SRAMSTREAM &os);
85 
86     // Verifies any mob's that we may have attached.
87     bool		 verifyMob() const;
88 
89     // Verifies the counter isn't present
90     bool		 verifyCounterGone(INTRINSIC_COUNTER *counter) const;
91 
92     // This runs the heartbeat on the item.
93     // Returns false if the item should be destroyed.
94     bool		 doHeartbeat(MAP *map, MOB *owner);
95 
96     void		 setPos(int x, int y);
getX()97     int			 getX() const { return myX; }
getY()98     int			 getY() const { return myY; }
getEnchantment()99     int			 getEnchantment() const { return myEnchantment; }
100     void		 enchant(int delta);
101 
102     // Turns this item into an artifact.
103     void		 makeArtifact(const char *name = 0);
104 
105     // Cancels in the nethack sense into a plain-jane version
106     // Vanilla, it should be noted, is hardly "ordinary", so this
107     // is at best abuse of notation.
108     void		 makeVanilla();
109 
110     // Raise, resurrect, etc:
111     // Returns true if success
112     // this is *not* deleted on success, so the caller should
113     // get rid of it or there will be a soulless corpse
114     // left behind.
115     bool		 resurrect(MAP *map, MOB *resser, int x, int y);
116     bool		 raiseZombie(MAP *map, MOB *raiser);
117     bool		 raiseSkeleton(MAP *map, MOB *raiser);
118 
119     bool		 petrify(MAP *map, MOB *petrifier);
120     bool		 unpetrify(MAP *map, MOB *unpetrifier);
121 
122     // Polymorphs this item.  Returns the newly created item on
123     // success, 0 if failed.  Does not delete this on success!
124     ITEM		*polymorph(MOB *polyer);
125 
126     // Tries to break this item.  The DC is a rough guess of
127     // how strongly it should break.  The X/Y is the map location
128     // where the break occurs.  The owner is null if no mob
129     // currently owns the item.  If no owner, the item is assumed
130     // to be in limbo.
131     // The breaker is the mob responsible for breaking the item.
132     // Returns true if the item is destroyed (It will be deleted then!)
133     // If item is stacked, breaking it will only destroy one element
134     // of the stack!  (And also not return true!)
135     bool		 doBreak(int dc, MOB *breaker, MOB *owner,
136 				MAP *map, int x, int y);
137 
138     // Rename my base type.
139     void		 renameType(const char *newname);
140 
141     // Rename myself.
142     void		 rename(const char *newname);
143     void		 rename(BUF buf);
144 
145     // Returns our own name, 0 if not assigned.
146     const char		*getPersonalName() const;
147 
getNext()148     ITEM		*getNext() const { return myNext; }
setNext(ITEM * item)149     void		 setNext(ITEM *item) { myNext = item; }
150 
151     // Query methods to determine the nature of the item..
152     MATERIAL_NAMES	 getMaterial() const;
153     ATTACK_NAMES	 getAttackName() const;
154     ATTACK_NAMES	 getThrownAttackName() const;
155     const ATTACK_DEF	*getAttack() const;
156     const ATTACK_DEF	*getThrownAttack() const;
157 
158     bool		 requiresLauncher() const;
159     bool		 canLaunchThis(ITEM *launcher) const;
160 
161     SKILL_NAMES	 	 getAttackSkill() const;
162     SKILL_NAMES		 getSpecialSkill() const;
163 
164     MOB			*getCorpseMob() const;
165     MOB			*getStatueMob() const;
166 
167     SIZE_NAMES		 getSize() const;
168 
169     int			 getNoiseLevel() const;
170 
171     // This calculates average damage.
172     int			 calcAverageDamage() const;
173 
getDefinition()174     ITEM_NAMES		 getDefinition() const
175 			 { return (ITEM_NAMES) myDefinition; }
setDefinition(ITEM_NAMES def)176     void		 setDefinition(ITEM_NAMES def)
177 			 { myDefinition = def; }
178     ITEMTYPE_NAMES	 getItemType() const;
179 
defn()180     const ITEM_DEF	&defn() const { return defn(getDefinition()); }
defn(ITEM_NAMES item)181     static const ITEM_DEF &defn(ITEM_NAMES item) { return glb_itemdefs[item]; }
182 
183     // This returns whether the intrinsics of this item should
184     // be granted even if it is just carried and not equipped.
185     bool		 isCarryIntrinsic() const;
186 
187     // This returns true if the item is fully identified in every way.
188     bool		 isFullyIdentified() const;
189     // This returns whether the class is identified
190     bool		 isIdentified() const;
191     // This returns if the bless/cursed status is known.
192     bool		 isKnownCursed() const;
193     // Do we know if the item is not cursed?
194     // Ie, have we tried it on and not gotten a stuck to our hands?
195     bool		 isKnownNotCursed() const;
196     // This returns if the enchantment is known.
197     bool		 isKnownEnchant() const;
198     // Return sif the charges is known.
199     bool		 isKnownCharges() const;
200     // Returns if poison status is known
201     bool		 isKnownPoison() const;
202     // Returns if class is known
203     bool		 isKnownClass() const;
204     // This marks both the specific item, and its class, as ided.
205     // It identifies all aspects of this item.
206     void		 markIdentified(bool silent = false);
207     // This identifies only the class of the item (Ie; Wand of fireball)
208     // rather than the entire thing (Ie: Wand of fireball (5))
209     void		 markClassKnown(bool silent = false);
210     // This marks that we now know the enchant status of this item.
211     void		 markEnchantKnown();
212     // This marks that we now know the cursed status of this item.
213     void		 markCursedKnown();
214     // Likewise, but we know it is merely not cursed.
215     void		 markNotCursedKnown(bool isknown=true);
216     // This marks we know the charge status.
217     void		 markChargesKnown();
218     void		 clearChargesKnown();
219     // This means we know the poison status.
220     void		 markPoisonKnown();
221 
222     // Determines if this is currently in some creatures pocket, or
223     // on the world map.
224     bool		 isInventory() const;
225     void		 setInventory(bool isinventory);
226 
227     void		 makeCursed();
228     void		 makeBlessed();
229     bool		 isCursed() const;
230     bool		 isBlessed() const;
231     // Armor is all slots, so includes rings and amulets
232     bool		 isArmor() const;
233     bool		 isWeapon() const;
234     bool		 isBoots() const;
235     bool		 isHelmet() const;
236     bool		 isShield() const;
237     bool		 isJacket() const;
238     bool		 isRing() const;
239     bool		 isAmulet() const;
240     bool		 isPassable() const;
241     bool		 isQuivered() const;
242     bool		 isFavorite() const;
243     bool		 isMapped() const;
244     bool		 isArtifact() const;
245     // Returns the artifact data structure which describes this item.
246     // Used internally to determine behaviour.
247     const ARTIFACT	*getArtifact() const;
248 
249     // Dissolves this item, return true if it should be destroyed
250     bool		 dissolve(MOB *dissolver = 0, bool *interesting = 0);
251 
252     // Determines if we can be dissolved by normal acid.
253     bool		 canDissolve() const;
254 
255     // Ignites this item return true if it should be destroyed
256     bool		 ignite(MOB *igniter = 0, bool *interesting = 0);
257 
258     // Electrifies this item
259     bool		 electrify(int points, MOB *shocker, bool *interesting);
260 
261     // Determines if we will burn up by normal lava
262     bool		 canBurn() const;
263 
264     // Douses this with water.
265     // Returns true if should destroy item
266     bool		 douse(MOB *douser = 0, bool *interesting = 0);
267 
268     // Returns the precedence the item should have for stacking on the
269     // floor.  Low numbers go under high numbers.  Thus, impassables
270     // such as Boulders should have a high stack, junk like corpses
271     // low stack.
272     int			 getStackOrder() const;
273     void		 markMapped(bool mapstatus=true);
274     void		 markQuivered(bool isquivered=true);
275     void		 markFavorite(bool isfavorite=true);
276     bool		 isBelowGrade() const;
277     void		 markBelowGrade(bool belowgrade=true);
278 
279     void		 makePoisoned(POISON_NAMES poison, int charges);
280     bool		 isPoisoned() const;
281     void		 applyPoison(MOB *src, MOB *target, bool force=false);
282 
283     // This finds out if the item emits light, and if so, how far.
284     bool	 	 isLight() const;
285     int		 	 getLightRadius() const;
286     TILE_NAMES		 getTile() const;
287     MINI_NAMES		 getMiniTile() const;
288 
289     // Stack functions:  These manipulate stacks of items, which are
290     // collections of identical items.
getStackCount()291     int			 getStackCount() const { return myStackCount; }
292     // Returns if we can merge with the given item.
293     bool		 canMerge(ITEM *item) const;
294     // Increments stack count.  Caller should likely delete item.  We
295     // take the item as it's count size may be greater.  We may also
296     // want to amortize some feature, such as a count down timer.
297     void		 mergeStack(ITEM *item);
298     // Pulls a substack off this stack.  The new ITEM * doesn't
299     // belong anywhere, so should be acquired somewhere.  You can't
300     // specify 0 or all items here - just move the pointer in that case!
301     ITEM		*splitStack(int count=1);
302     // Removes an item from this stack and immediately deletes the item
303     // Does not handle the case of removing the last item!
304     void		 splitAndDeleteStack(int count=1);
305 
306     // For those times when you want a specific number...
307     // Do not use lightly.  Should only be done on item generation.
setStackCount(int newcount)308     void		setStackCount(int newcount) { myStackCount = newcount; }
309 
310     int			 getAC() const;
311     int			 getCoolness() const;
312     int			 getWeight() const;
313 
314     int			 getCharges() const;
315     // This will automatically split the charges up among
316     // the stack if this is a stacked item.
317     void		 addCharges(int morecharges);
318     void		 useCharge();
319     void		 setAsPreserved();
320 
321     MAGICTYPE_NAMES	 getMagicType() const;
322     int			 getMagicClass() const;
323 
324     // This merges into the given table all the intrinsics this item has.
325     // It creates the table if it is 0 and there are intrinsics.
326     void		 buildIntrinsicTable(INTRINSIC *&intrinsic) const;
327 
328     bool		 hasIntrinsic(INTRINSIC_NAMES intrinsic) const;
329 
330     // Equivalent to glb_itemdefs[item].name, except handles the
331     // case of the item being identified by returning the identified name
332     static const char	*getItemName(ITEM_NAMES item, bool forceid=false);
333 
334     // Returns the base name devoid of identifiers
335     const char		*getRawName(bool idclass=false) const;
336     BUF			 getName(bool article=true, bool shortname=false,
337 				 bool neverpronoun=false,
338 				 bool idclass=false,
339 				 bool forcesingle=false) const;
340 
341     // Much like monster formatting.
342     // %U refers to the item.  owner isn't part of format string but
343     // is used to determine who spams the message.
344     void		 formatAndReport(MOB *owner, const char *str);
345     void		 formatAndReport(const char *str);
346 
347     // Pages a list of all identified item types.
348     static void		 viewDiscoveries();
349 
350     void		 viewDescription() const;
351     // Send the description to the paging system.
352     void		 pageDescription(bool brief) const;
353 
354     // Returns it, they, etc.
355     const char		*getPronoun() const;
356 
357     // your, its, his, her, their, etc.
358     const char  	*getPossessive() const;
359 
360     // Returns itself, themself, etc.
361     const char 		*getReflexive() const;
362 
363     // Returns it, them, etc.
364     const char		*getAccusative() const;
365 
366     BUF			 conjugate(const char *infinitive, bool past=false) const;
367 
368     // This gets the tense of this item, which includes the plurality of it.
369     VERB_PERSON		 getPerson() const;
370 
371     // Actions.
372     // Yep, items can do actions too.
373 
374     // This dips the dippee into this, with dipper being the entity
375     // responsible.  Neither this nor dipper should be owned by anyone.
376     // The result of the dip is two items which should be added back in,
377     // NULL if they were destroyed.
378     bool		 actionDip(MOB *dipper, ITEM *dippee,
379 				ITEM *&newpotion, ITEM *&newitem);
380 
381     // This zaps this, with zapper being the entity responsible.
382     // this is assumed to be owned by the zapper.
383     // true is returned if an action is consumed.
384     // dx == dy == dz == 0 means zap self.
385     // dz == +/-1 means ceiling/floor.
386     // this MAY be destroyed by this function!
387     bool		 actionZap(MOB *zapper,
388 			    int dx, int dy, int dz);
389 
390     // Zap callback methods
391     bool		 zapCallback(int x, int y);
392     static bool		 zapCallbackStatic(int x, int y, bool final,
393 					    void *data);
394 
395     // Grenade callback methods
396     bool		 grenadeCallback(int x, int y);
397     static bool		 grenadeCallbackStatic(int x, int y, bool final,
398 						void *data);
399 
400     // Ensure external invokers of grenadeCallback can get the proper
401     // credit.
setZapper(MOB * mob)402     static void		 setZapper(MOB *mob) { ourZapper.setMob(mob); }
403 
404     // Teleport the item to a randomly selected square.
405     // Map is level to teleport on.
406     bool 		 randomTeleport(MAP *map, bool mapownsitem,
407 					MOB *teleporter);
408 
409     // Make the item fall into a hole and drop into the level below.
410     // Pass the map in as the fall may be recursive, if you are unlucky.
411     bool 		 fallInHole(MAP * curLevel, bool mapownsitem,
412 				    MOB *dropper);
413 
414 protected:
415     // This data must be kept as limitted as possible, as there
416     // are a lot of items.
417     // Make sure this is all initialized in ::create and copied in
418     // ::createClone.
419     u8			 myDefinition;
420     u8			 myStackCount;
421     u8			 myX, myY;
422     s8			 myEnchantment;
423     u8			 myCharges;
424     u8			 myPoison;
425     u8			 myPoisonCharges;
426     ITEMFLAG1_NAMES	 myFlag1;
427 
428     MOBREF		 myCorpseMob;
429 
430     NAME		 myName;
431 
432     ITEM		*myNext;
433 
434     static MOBREF	 ourZapper;
435 };
436 
437 #endif
438