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