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: creature.h ( POWDER Library, C++ ) 11 * 12 * COMMENTS: 13 * This provides the definition of all mob types. Individual 14 * instances are copied out of the main ROM table so they can store 15 * their non-static data. 16 */ 17 18 #ifndef __creature_h__ 19 #define __creature_h__ 20 21 #include "grammar.h" 22 23 #include "glbdef.h" 24 #include "intrinsic.h" 25 #include "mobref.h" 26 #include "name.h" 27 #include "speed.h" 28 #include "map.h" 29 30 class ITEM; 31 class SRAMSTREAM; 32 class MOB; 33 34 // One time mob initialization. 35 void mob_init(); 36 37 // AI initialization, resetting, saving, loading 38 void ai_init(); 39 void ai_reset(); 40 41 // invoked by save/loadGlobal 42 void ai_save(SRAMSTREAM &os); 43 void ai_load(SRAMSTREAM &is); 44 45 // 46 // Used for the drag and drop menu system to go to and from u8 and 47 // our action/spell values. 48 // These are usually tied to actions, hence their presence here. 49 // 50 u8 action_packStripButton(ACTION_NAMES action); 51 u8 action_packStripButton(SPELL_NAMES spell); 52 void action_unpackStripButton(u8 value, ACTION_NAMES &action, SPELL_NAMES &spell); 53 54 // The grey value will be 0 if this sprite isn't useable, so should be grey 55 // to 256 for a fully charged sprite. 56 SPRITE_NAMES action_spriteFromStripButton(u8 value, int *grey = 0); 57 void action_indexToOverlayPos(int index, int &x, int &y); 58 59 60 61 // Kill counters. 62 extern u16 glbKillCount[NUM_MOBS]; 63 64 // Inventory size... 65 #define MOBINV_WIDTH 12 66 #define MOBINV_HEIGHT 8 67 68 // AI State variables. These are volatile 69 #define AI_DIRTY_INVENTORY 0x8000 70 #define AI_HAS_THROWABLE 0x4000 71 #define AI_HAS_ATTACKWAND 0x2000 72 #define AI_HAS_EDIBLE 0x1000 73 #define AI_LAST_HIT_LOC 0x03ff 74 75 // AI FSM Modes. This is non-volatile. 76 #define AI_FSM_NORMAL 0 77 #define AI_FSM_ATTACK 1 78 #define AI_FSM_GUARD 2 79 #define AI_FSM_STAY 3 80 #define AI_FSM_JUSTBORN 4 81 82 // Intrinsic source flags 83 #define INTRINSIC_FROM_ITEM 1 84 #define INTRINSIC_FROM_PERMAMENT 2 85 #define INTRINSIC_FROM_TEMPORARY 4 86 87 class INTRINSIC_COUNTER 88 { 89 public: 90 #ifdef STRESS_TEST ~INTRINSIC_COUNTER()91 ~INTRINSIC_COUNTER() 92 { 93 // Verify that we are no longer referenced by anyone. 94 if (glbCurLevel) 95 glbCurLevel->verifyCounterGone(this); 96 } 97 #endif 98 INTRINSIC_NAMES myIntrinsic; 99 int myTurns; 100 INTRINSIC_COUNTER *myNext; 101 // Tracks who put this counter on! 102 MOBREF myInflictor; 103 }; 104 105 // Instance of a mob. 106 // Do not make this virtual or you will have misunderstood the 107 // point of the exercise! 108 class MOB 109 { 110 private: 111 MOB(); // Create mobs with ::create please. 112 public: 113 ~MOB(); 114 115 // Resets all the mob counts, such as the number of creatures slain, 116 // etc. 117 static void init(); 118 119 // Loads & saves the global state. 120 static void saveGlobal(SRAMSTREAM &os); 121 static void loadGlobal(SRAMSTREAM &is); 122 123 // The avatar is the special mob through which everything is viewed. 124 // It also gets the pronoun "you". 125 static MOB *getAvatar(); 126 static void setAvatar(MOB *mob); 127 128 static void saveAvatar(SRAMSTREAM &os); 129 static void loadAvatar(SRAMSTREAM &is); 130 131 // Mobs can belong to lists... getNext()132 MOB *getNext() { return myNext; } setNext(MOB * mob)133 void setNext(MOB *mob) { myNext = mob; } 134 isAvatar()135 bool isAvatar() const { return getAvatar() == this; } 136 isAvatarOnFreshSquare()137 static bool isAvatarOnFreshSquare() { return ourAvatarOnFreshSquare; } setAvatarOnFreshSquare(bool fresh)138 static void setAvatarOnFreshSquare(bool fresh) 139 { ourAvatarOnFreshSquare = fresh; } 140 141 // Are we currently polymorphed? isPolymorphed()142 bool isPolymorphed() const { return !myBaseType.isNull(); } 143 // Returns the base creature type. This is what you are 144 // before polymorphing. getBaseType()145 MOB *getBaseType() const { return myBaseType.getMob(); } 146 147 // Get our MOBREF. Pass by reference to minimize reconstruction. 148 // DO NOT USE THIS. Instead, use MOBREF.setMob(this), which has 149 // the advantage of dealing with the MOB * being null. getMobRef()150 const MOBREF &getMobRef() const { return myOwnRef; } 151 152 // This alert tells us to invalidate any references to the given mob. 153 void alertMobGone(MOB *mob); 154 // This clears all the references on this mob as a result of it 155 // being unregistered from a map. 156 void clearReferences(); 157 158 static MOB *create(MOB_NAMES definition); 159 160 // Equips self with an ascension worthy set of equipment/abilities. 161 void buildAscensionKit(); 162 163 // Creates a new mob, possibly updating the avatar. 164 static MOB *load(SRAMSTREAM &is); 165 166 // Writes out mob data... 167 void save(SRAMSTREAM &os); 168 169 // Verifies our MOBREFs are valid. 170 // Reports 0 if nulls, ! if bad link. 171 bool verifyMob() const; 172 173 // Verifies that we don't see the given INTRINISC_COUNTER anywhere. 174 bool verifyCounterGone(INTRINSIC_COUNTER *counter) const; 175 176 // Chooses an NPC def given a threat level 177 static MOB_NAMES chooseNPC(int threatlevel); 178 179 // Creates an NPC given a threat level. 180 static MOB *createNPC(int threatlevel); 181 182 // Turn this mob into a unique. 183 // This should be done just after create! 184 void makeUnique(); 185 186 // Is the mob physically capable of being on the given square. 187 // checksafety will prohibit squares that will damage the 188 // critter. 189 bool canMove(int nx, int ny, bool checkitem, 190 bool allowdoor = false, 191 bool checksafety = false) const; 192 193 // Checks if the mob can move through a diagonal passage. We 194 // prohibit kiddie-corner style moves. If dx and dy are not both 195 // non-zero, turns into a normal canMove. 196 // In case of diagonal, the orthogonal passages are only tested 197 // for MOVE flags, not for bolders, mobs, safety, etc. 198 bool canMoveDelta(int dx, int dy, bool checkitem, 199 bool allowdoor = false, 200 bool checksafety = false) const; 201 202 // This returns true if this is aware of mob. This means that: 203 // A) this cannot see, has telepathy, and mob has a mind. 204 // B) this can see, mob is visible, has los, and mob is lit 205 // C) this can see, can see invisible, mob is invisible, has los, and lit. 206 // D) if either party is in a pit, the distance is 1. 207 // E) both parties are same submerge state. 208 // F) not deaf, noiselevel of other critter is high enough 209 // G) has warning, other creature in range. 210 // The LOS check is skipped if checklos = false. 211 // If only sight is true, only sight checks are made. 212 bool canSense(const MOB *mob, bool checklos = true, bool onlysight = false) const; 213 214 // Returns *how* you can sense the given mob. 215 SENSE_NAMES getSenseType(const MOB *mob) const; 216 217 // This is the movement mask we currently can do, modified by items, 218 // etc. 219 MOVE_NAMES getMoveType() const; 220 getX()221 int getX() const { return myX; } getY()222 int getY() const { return myY; } getDLevel()223 int getDLevel() const { return myDLevel; } setDLevel(int d)224 void setDLevel(int d) { myDLevel = d; } 225 int getTile() const; // This is Upper left. 226 int getTileLL() const; 227 int getTileLR() const; 228 int getTileUR() const; 229 getDefinition()230 MOB_NAMES getDefinition() const { return (MOB_NAMES) myDefinition; } setOrigDefinition(MOB_NAMES origdefn)231 void setOrigDefinition(MOB_NAMES origdefn) { myOrigDefinition = origdefn; } 232 233 // Changes our internal & original type. If reset, we wipe 234 // out our mp/hp type stats. 235 void changeDefinition(MOB_NAMES newdefn, bool reset); 236 getMobType()237 MOBTYPE_NAMES getMobType() const { return (MOBTYPE_NAMES) glb_mobdefs[myDefinition].mobtype; } 238 defn()239 const MOB_DEF &defn() const { return defn(getDefinition()); } defn(MOB_NAMES mob)240 static const MOB_DEF &defn(MOB_NAMES mob) { return glb_mobdefs[mob]; } 241 getHP()242 int getHP() const { return myHP; } getMaxHP()243 int getMaxHP() const { return myMaxHP; } 244 void incrementMaxHP(int amount); setMinimalHP()245 void setMinimalHP() { myHP = 1; } setMaximalHP()246 void setMaximalHP() { myHP = myMaxHP; } forceHP(int hp)247 void forceHP(int hp) { myMaxHP = myHP = hp; } getHitDie()248 int getHitDie() const { return myHitDie / 2; } incrementHitDie(int amount)249 void incrementHitDie(int amount) { myHitDie += amount*2; } getExpLevel()250 int getExpLevel() const { return myExpLevel; } getMP()251 int getMP() const { return myMP; } getMaxMP()252 int getMaxMP() const { return myMaxMP; } 253 void incrementMaxMP(int amount); getMagicDie()254 int getMagicDie() const { return myMagicDie / 2; } incrementMagicDie(int amount)255 void incrementMagicDie(int amount) { myMagicDie += amount*2; } getExp()256 int getExp() const { return myExp; } 257 getStrength()258 int getStrength() const 259 { return glb_mobdefs[myDefinition].strength; } getSmarts()260 int getSmarts() const 261 { return glb_mobdefs[myDefinition].smarts; } getSize()262 SIZE_NAMES getSize() const { return (SIZE_NAMES) 263 glb_mobdefs[myDefinition].size; } 264 265 // This gets the maximum AC of the creature. 266 int getAC() const; 267 268 // Computes the score, only really sensible for the avatar 269 int calcScore(bool haswon) const; 270 271 // This properly rolls the AC to find out what it is for this 272 // particular hit. 273 int rollAC(MOB *attacker) const; 274 getMaterial()275 MATERIAL_NAMES getMaterial() const 276 { return (MATERIAL_NAMES) glb_mobdefs[myDefinition].material; } 277 278 bool hasBreathAttack() const; 279 ATTACK_NAMES getBreathAttack() const; 280 bool isBreathAttackCharged() const; 281 int getBreathRange() const; 282 const char *getBreathSubstance() const; 283 284 bool isTalkative() const; 285 286 void submergeItemEffects(SQUARE_NAMES tile); 287 288 bool hasItem(ITEM_NAMES def) const; 289 290 // This finds out if the mob emits light, and if so, how far. 291 bool isLight() const; 292 int getLightRadius() const; 293 294 // Determines if we are allowed to move on diagonals 295 // (obscure reference to diabolizing matrices) 296 bool canMoveDiabolically() const; 297 298 bool canResurrectFromCorpse() const; 299 bool isBoneless() const; 300 bool isBloodless() const; 301 setAIFSM(int fsm)302 void setAIFSM(int fsm) { myAIFSM = fsm; } setAITarget(MOB * mob)303 void setAITarget(MOB *mob) { myAITarget.setMob(mob); } clearAITarget()304 void clearAITarget() { myAITarget.setMob(0); } getAITarget()305 MOB *getAITarget() const { return myAITarget.getMob(); } 306 307 // Returns the master of this mob. This is who the mob 308 // immediately reports to 309 MOB *getMaster() const; 310 311 // Returns true if this mob is at some level a slave of the given 312 // critter. 313 // You are not a slave to yourself. 314 bool isSlave(const MOB *owner) const; 315 316 // Makes this a slave of the given master. 317 void makeSlaveOf(const MOB *owner); 318 319 // Returns true if we have a common master. 320 bool hasCommonMaster(const MOB *other) const; 321 322 bool hasIntrinsic(INTRINSIC_NAMES intrinsic, bool allowitem=true) const; 323 324 // Return bit field showing all sources of the intrinsic 325 int intrinsicFromWhat(INTRINSIC_NAMES intrinsic) const; 326 327 // Return a string giving the identifier for the intrinsic source 328 const char *intrinsicFromWhatLetter(INTRINSIC_NAMES intrinsic) const; 329 330 // These just chain to the relevant intrinsic, but allow for 331 // more legible code. 332 bool hasSkill(SKILL_NAMES skill, bool allowitem=true, bool ignoreamnesia=false) const; 333 bool hasSpell(SPELL_NAMES spell, bool allowitem=true, bool ignoreamnesia=false) const; 334 335 // Rolls to see if the given skill meets its proc chance 336 bool skillProc(SKILL_NAMES skill) const; 337 338 // These determine if you have the necessary prereqs. 339 // If explain is true, the list of failed prereqs is given. 340 bool canLearnSkill(SKILL_NAMES skill, bool explain=false) const; 341 int getUsedSkillSlots() const; 342 int getFreeSkillSlots() const; 343 bool canLearnSpell(SPELL_NAMES spell, bool explain=false) const; 344 int getUsedSpellSlots() const; 345 int getFreeSpellSlots() const; 346 347 void clearDeathIntrinsics(bool silent); 348 349 bool canDigest(ITEM *item) const; 350 bool safeToDigest(ITEM *item) const; 351 352 bool canFly() const; 353 354 // Return true if anything we are wearing is made of that material. 355 bool isWearing(MATERIAL_NAMES material) const; 356 357 // Sorts our linked list invenroy to match the expected slot 358 // order 359 void sortInventoryBySlot(); 360 361 // This sets the intrinsic permamently & instantly. 362 void setIntrinsic(INTRINSIC_NAMES intrinsic); 363 // Merges into our intrinsic all those in the given string 364 void mergeIntrinsicsFromString(const char *rawstr); 365 // This removes the intrinsic. It does so instantly & permamently. 366 void clearIntrinsic(INTRINSIC_NAMES intrinsic, bool silent=false); 367 // This sets the given intrinsic for the given number of turns. 368 // Turns are eaten every heartbeat. 369 // If the intrinsic is already on permamently, it doesn't affect 370 // anything. 371 // We are not guaranteed to return a counter. 372 // If quiet is set, we never announce the gain/loss 373 void setTimedIntrinsic(MOB *inflictor, 374 INTRINSIC_NAMES intrinsic, int turns, 375 bool quiet = false); 376 377 int getAttackBonus(const ATTACK_DEF *attack, ATTACKSTYLE_NAMES style); 378 379 // Returns the probability, 0..100 inclusive, that the second 380 // weapon should be allowed to proc. 381 // This is zero if there is no second weapon, etc. 382 int getSecondWeaponChance() const; 383 384 // This gets THIS mobs attitude towards APPRAISEE. 385 ATTITUDE_NAMES getAttitude(const MOB *appraisee) const; 386 getAI()387 AI_NAMES getAI() const 388 { return (AI_NAMES) glb_mobdefs[myDefinition].ai; } 389 390 // Move the mob into the given tile, updating the gfx map & 391 // applying any relevant callbacks. 392 // Note the new mob x/y is not necessarily nx ny! 393 // Returns false if the creature is now dead. 394 bool move(int nx, int ny, bool interlevel = false); 395 396 // This runs all the every-turn things this mob should do. This will 397 // cause the mob to age, consume food, regain magic & hits, etc. This 398 // is often in the MOBs time frame, not the world time frame, so usually 399 // occurs before the mob's AI frame (so faster mobs consume faster) 400 // This returns true if the mob can still perform an action. It 401 // returns false if the mob's ai should be skipped (eg: the mob died) 402 bool doHeartbeat(); 403 404 // This finds a random dx,dy pair for which canMove returns true. 405 // The move will not move into the owner. 406 void findRandomValidMove(int &dx, int &dy, MOB *owner); 407 408 // Determines if the creature is confused. It then will adjust 409 // the dx, dy, and dz values appropriately. It does the random 410 // chance to keep the original decision. 411 // Care must be taken to not end up with double jeopardy. 412 void applyConfusion(int &dx, int &dy); 413 void applyConfusionNoSelf(int &dx, int &dy); 414 void applyConfusion(int &dx, int &dy, int &dz); 415 416 // Returns number of foes that are melee adjacent, 417 // does not count friends, sleeping, or paralysed. 418 int calculateFoesSurrounding() const; 419 420 // Returns true if this mob should doAI on the given phase. 421 bool validMovePhase(PHASE_NAMES phase); 422 423 // This does the prequel actions prior to the creature getting its 424 // move. It's move would either be the user action or the doAI 425 // action. 426 // true is returned if the user should act, false if the prequel 427 // ate their action. 428 bool doMovePrequel(); 429 430 // AI: All ai prefixed functions, along with doAI, are found in 431 // ai.cpp. 432 // 433 // This runs the AI script on this MOB, which will cause it to run 434 // some action or another. 435 void doAI(); 436 437 // Returns true if we successfully move in the given direction. 438 // We will try and jump if possible. 439 // actionBump will be used, but blockers will be avoided. 440 // if target mob blocks, an attack will still be made. 441 // This can handle dx & dy both being non zero, in which case it 442 // picks one of them. 443 bool aiMoveInDirection(int dx, int dy, int distx, int disty, 444 MOB *target); 445 446 // Decays knowledge of us. 447 void aiDecayKnowledgeBase(); 448 449 // Returns true if we know that the given target has a resistance 450 // to the element. This means we should likely not bother with 451 // an attack based on that element. 452 bool aiCanTargetResist(MOB *target, ELEMENT_NAMES element) const; 453 454 // Tries to note that the given target has the given intrinsic, 455 // internally tranforms into a call to CanResist. 456 void aiNoteThatTargetHasIntrinsic(MOB *target, INTRINSIC_NAMES intrinsic); 457 // Tries to note that the given target can resist the given element 458 void aiNoteThatTargetCanResist(MOB *target, ELEMENT_NAMES element); 459 // Internal function when we've passed the tests. 460 void aiTrulyNoteThatTargetCanResist(MOB *target, ELEMENT_NAMES element); 461 462 // Returns true if acted. 463 // Searches inventory for useful items and uses them. 464 bool aiUseInventory(); 465 466 // Picks up whatever is on the ground. 467 bool aiBePackrat(); 468 469 // Searches through one's invenotry for yummy stuff and eats it. 470 bool aiEatStuff(); 471 472 // Tries to leave melee combat through teleportation, etc. 473 // Only does so if it decides it's unsafe (low hp, etc) 474 bool aiDoFleeMelee(MOB *target); 475 476 // Looks for any battle preperations it can do. Ie, casting 477 // buffs, etc. 478 // The dx, dy is the offset to our target. 479 bool aiDoBattlePrep(int diffx, int diffy); 480 481 // Heal, cure, etc. 482 bool aiDoUrgentMoves(); 483 484 // Specific action ai: 485 486 // Attacks: These will attack in the given direction at the 487 // given range. 488 bool aiDoRangedAttack(int dx, int dy, int range); 489 bool aiDoThrownAttack(int dx, int dy, int range); 490 bool aiDoWandAttack(int dx, int dy, int range); 491 bool aiDoSpellAttack(int dx, int dy, int range); 492 493 // Heals: These attempt to restore health/cure poison. 494 bool aiDoHealSelf(); 495 bool aiDoCurePoisonSelf(); 496 497 // This attempts to immerse onself in water. 498 bool aiDoDouseSelf(); 499 500 // Attempts to freeze the square I stand on 501 bool aiDoFreezeMySquare(); 502 503 // Try to get off my current square onto a safe square 504 bool aiDoEscapeMySquare(); 505 506 // This will attempt to stop stoning, provided we care about it. 507 bool aiDoStopStoningSelf(); 508 509 // Specific AI behaviours: 510 511 // Mice run around with the right hand rule getting into mischief. 512 bool aiDoMouse(); 513 514 // Testing functions. 515 bool aiIsItemCooler(ITEM *item, ITEMSLOT_NAMES slot); 516 bool aiIsItemThrowable(ITEM *item, MOB *target = 0) const; 517 bool aiIsItemZapAttack(ITEM *item) const; 518 519 bool aiIsPoisoned() const; 520 521 bool aiWillOpenDoors() const; 522 523 // Actions... This is where all the creature smarts go. At the 524 // root is the actionBump - this is a request by a creature to go 525 // in a certain direction. What it means is creature dependent... 526 // Actions return true if they consumed a timeslot, and false if 527 // they failed. 528 529 // All of the "action" prefixed functions can be found in action.cpp. 530 bool actionBump(int dx, int dy); 531 532 // The creature uses its breath attack in the given direction. 533 bool actionBreathe(int dx, int dy); 534 535 // Note all these callbacks take a MOBREF * inside data! 536 static bool meltRocksCBStatic(int x, int y, bool final, void *data); 537 538 // The attack is in ourEffectAttack. 539 static bool areaAttackCBStatic(int x, int y, bool final, void *data); 540 541 // Spell is in ourZapSpell. 542 static bool zapCallbackStatic(int x, int y, bool final, void *data); 543 544 // This tries to swap with a creature in the given direction. 545 bool actionSwap(int dx, int dy); 546 547 // Talk to someone or something 548 bool actionTalk(int dx, int dy); 549 550 // Puts the mob to sleep for 50 turns. 551 bool actionSleep(); 552 553 // This tries to push on the given direction. 554 bool actionPush(int dx, int dy); 555 556 // This will move in the given direction. It does no intelligence 557 // checks! 558 bool actionWalk(int dx, int dy, bool spacewalk = false); 559 560 // This will jump in the given direction. This will move you 561 // two squares. It can jump over things, but not through walls. 562 // Destination must be visible and lit. 563 bool actionJump(int dx, int dy); 564 565 // Applies the magic door effect, only valid for avatars. 566 // Coords are absolute location of magical door. 567 bool actionMagicDoorEffect(int x, int y); 568 569 // This will try to open the object in the given direction. 570 bool actionOpen(int dx, int dy); 571 572 // THis will try to close the object. 573 bool actionClose(int dx, int dy); 574 575 // This causes this MOB to search the given square, spamming 576 // the appropriate discovery and revealling it to the world. 577 // It returns true if anything was found. 578 // The isaction controls if it was purposeful or not. This affects 579 // the probability in dark areas. Darkness penalty only applies 580 // to purposeful search attempts. (Finding stuff accidentally is 581 // bad, so should be encouraged :>) 582 bool searchSquare(int x, int y, bool isaction); 583 584 // This searches at the square we are now on. 585 bool actionSearch(); 586 587 // This will attack what is in the given direction. 588 bool actionAttack(int dx, int dy, int multiplierbonus = 0); 589 590 // This handles attempts to climb things. 591 bool actionClimb(); 592 bool actionClimbUp(); 593 bool actionClimbDown(); 594 595 bool actionDig(int dx, int dy, int dz, int range, bool magical); 596 597 // Picks up whats on the floor. 598 // The specified item is which item to pickup. 599 // Note that picking up an item may destroy it when it merges 600 // with a stack, newitem will be set to the resulting item. 601 bool actionPickUp(ITEM *item, ITEM **newitem = 0); 602 // Tries to drop the given item. 603 bool actionDrop(int ix, int iy); 604 605 // Sorts the inventory items. 606 bool actionSort(); 607 608 // Tries to eat. 609 // This doubles as drinking. 610 bool actionEat(int ix, int iy); 611 612 // Tries to throw. 613 bool actionThrow(int ix, int iy, int dx, int dy, int dz); 614 615 // Throws a quivered item. 616 bool actionFire(int dx, int dy, int dz); 617 618 // Puts the specified object into the quiver. 619 bool actionQuiver(int ix, int iy); 620 621 // Verifies you can zap 622 bool ableToZap(int ix, int iy, int dx, int dy, int dz, bool quiet); 623 624 // Tries to zap. 625 bool actionZap(int ix, int iy, int dx, int dy, int dz); 626 627 // Tries to cast. 628 bool actionCast(SPELL_NAMES spell, int dx, int dy, int dz); 629 630 // Verifies if you can read. 631 bool ableToRead(int ix, int iy, bool quiet); 632 633 // Tries to read. 634 bool actionRead(int ix, int iy); 635 636 // The potion is what to dip into, the i() is what to dip. 637 bool actionDip(int potionx, int potiony, int ix, int iy); 638 639 // This will cause you to query the gods as to your current 640 // status. 641 bool actionPray(); 642 643 // Take control of given mob, only really works for avatar. 644 bool actionPossess(MOB *mob, int duration); 645 646 // Removes our possession and returns ourself to our original 647 // body, provided it exists. 648 bool actionReleasePossession(bool systemshock = false); 649 650 // This will perform a random teleport, unless the creature has 651 // teleport control, in which case it will use its own AI (or 652 // user input) for the destination. 653 // allowcontrol will enable teleport control to be tested. 654 // givecontrol will grant the creature telecontrol for this action. 655 // Xloc and yloc give the teleport destination, if present. 656 bool actionTeleport(bool allowcontrol=true, bool givecontrol=false, 657 int xloc=-1, int yloc=-1); 658 659 bool actionForget(SPELL_NAMES spell, SKILL_NAMES skill); 660 661 // UPdates our tile according to what we are wearing. 662 void rebuildAppearance(); 663 664 // Update our worn intrinsic according to what we have equipped. 665 void rebuildWornIntrinsic(); 666 667 // Determines how well dressed the creature is. 668 // per god amounts optionally stored in dressiness. 0 is nothing 669 // nice, no consistent maximum. 670 void determineClassiness(int *dressiness = 0); 671 672 // Verifies you can equip the item. 673 bool ableToEquip(int ix, int iy, ITEMSLOT_NAMES slot, bool quiet); 674 675 // Tries to equip the item in the given inventory slot. 676 bool actionEquip(int ix, int iy, ITEMSLOT_NAMES slot, bool quiet=false); 677 678 // Verifies you can remove the item. 679 bool ableToDequip(ITEMSLOT_NAMES slot, bool quiet); 680 681 // Tries to take off the item in the given slot. 682 bool actionDequip(ITEMSLOT_NAMES slot, bool quiet = false); 683 684 // Returns the total skill the creature has with the given 685 // armour or weapon. 686 int getWeaponSkillLevel(const ITEM *weapon, 687 ATTACKSTYLE_NAMES attackstyle) const; 688 int getArmourSkillLevel(const ITEM *armour) const; 689 690 // This records that src tried to attack us. 691 // We may choose to disregard this if we feel it is friendly fire, 692 // or currently have someone we hate more. 693 void noteAttacker(MOB *src); 694 695 // Receptor functions... 696 // The attacking item may be null, in which case the mob attacks 697 // alone. 698 // These return false if the creature dies. 699 // The actuallyhit is set to true if any attack landed. 700 // It is NOT set to false otherwise! 701 bool receiveAttack(ATTACK_NAMES attack, MOB *src, ITEM *weapon, 702 ITEM *launcher, 703 ATTACKSTYLE_NAMES style, 704 bool *actuallyhit = 0, int multiplier = 0); 705 bool receiveAttack(const ATTACK_DEF *attack, MOB *src, ITEM *weapon, 706 ITEM *launcher, 707 ATTACKSTYLE_NAMES style, 708 bool *actuallyhit = 0, int multiplier = 0); 709 bool receiveDamage(ATTACK_NAMES attack, MOB *src, 710 ITEM *weapon, 711 ITEM *launcher, 712 ATTACKSTYLE_NAMES style, 713 int multiplier = 1, 714 int damage_reduction = 0); 715 bool receiveDamage(const ATTACK_DEF *attack, MOB *src, 716 ITEM *weapon, 717 ITEM *launcher, 718 ATTACKSTYLE_NAMES style, 719 int multiplier = 1, 720 int damage_reduction = 0); 721 void receiveDeathExp(int explevel); 722 void receiveExp(int exp); 723 // Clears all experience: Ouch! 724 void wipeExp(); 725 726 // Enchant a random piece of armour by the given amounts. 727 // ITEMSLOT_NAMES -1 means a random armour piece. 728 void receiveArmourEnchant(ITEMSLOT_NAMES slot, int bonus, bool shudder); 729 730 // Enchant your weapon. 731 void receiveWeaponEnchant(int bonus, bool shudder); 732 733 // Curses random item that isn't already cursed, starting with 734 // your equipped items. 735 // onlyequip true will ensure only equipped items will be cursed. 736 // forceany prevents the code from preferring equipped items. 737 void receiveCurse(bool onlyequip, bool forceany); 738 739 // Uncurses random cursed item, starting with equipped items. 740 // Doall true means it will uncurse everything. 741 void receiveUncurse(bool doall); 742 743 // Only update HP through these methods to ensure consistent treatment 744 // vampiric heals prevent Tlosh from growing angry. 745 bool receiveHeal(int hp, MOB *src, bool vampiric = false); 746 bool receiveMana(int mp, MOB *src); 747 bool receiveCure(); 748 bool receiveSlowPoison(); 749 750 SPELL_NAMES findSpell(GOD_NAMES god, int *numspell = 0) const; 751 SKILL_NAMES findSkill(GOD_NAMES god, int *numskill = 0) const; 752 753 void learnSpell(SPELL_NAMES spell, int duration = -1); 754 void learnSkill(SKILL_NAMES skill, int duration = -1); 755 // Returns if we are able to cast the spell, ie have enough mana, 756 // have the right intrinsic, etc. 757 bool canCastSpell(SPELL_NAMES spell); 758 // Returns how close we are to casting the spell. 0 means 759 // not possible, 256 we can cast it this instant. 760 int spellCastability(SPELL_NAMES spell); 761 void gainLevel(); 762 763 // Undo casting cost of the spell. 764 void cancelSpell(SPELL_NAMES spell); 765 766 // 767 // piety functions. These are implemented in piety.cpp. 768 // They control the implicity worship given to one or more gods 769 // by just about any action. 770 // 771 // Currently only the avatar triggers these, but theoritically 772 // that could be expanded. 773 // 774 void pietyGainLevel(); 775 776 void pietyKill(MOB *mob, ATTACKSTYLE_NAMES style); 777 void pietyEat(ITEM *item, int foodval); 778 void pietyDress(INTRINSIC_NAMES intrinsic); 779 void pietyZapWand(ITEM *wand); 780 void pietySurrounded(int numenemy); 781 void pietyHeal(int amount, bool self, bool enemy, bool vampiric); 782 void pietyCastSpell(SPELL_NAMES spell); 783 void pietyCreateTrap(); 784 void pietyFindSecret(); 785 void pietyAttack(MOB *mob, const ATTACK_DEF *attack, 786 ATTACKSTYLE_NAMES style); 787 // You made the given amount of noise. 788 void pietyMakeNoise(int noise); 789 // You identified something. 790 void pietyIdentify(ITEM_NAMES itemdef); 791 792 // Broke an item 793 void pietyBreak(ITEM *item); 794 795 // Prints out a report of the current piety levels of all gods. 796 void pietyReport(); 797 798 // Announces the whim of xom if you are following ><0|V| 799 void pietyAnnounceWhimOfXom(); 800 801 // Runs the god AI to determine what to do with the poor player. 802 void pietyRungods(); 803 804 // Used to actually apply piety points to a given god. 805 void pietyGrant(GOD_NAMES god, int amount, bool forbidden = false); 806 807 // Applied when one performs a forbidden action. 808 void pietyTransgress(GOD_NAMES god); 809 810 // Applied to use up some god points in doling out punishment. 811 void pietyPunish(GOD_NAMES god); 812 813 // Applied to use up some god points in doling out rewards. 814 void pietyBoon(GOD_NAMES god); 815 816 // Returns true if the player can benefit from the given boon. 817 bool pietyBoonValid(BOON_NAMES boon); 818 819 // What sort of crappy comment is this? 820 // "The string can take certain parameters..." 821 void reportMessage(const char *str) const; reportMessage(BUF buf)822 inline void reportMessage(BUF buf) const 823 { reportMessage(buf.buffer()); } 824 825 // This reports a message with mob specific connotations: 826 // %U means the mob itself. 827 // %u means the mob itself without any article. 828 // %i means the item identified at class level 829 // %R means the possessive of the mob. (full name!) 830 // %r means the possessive, pronoun. 831 // %A means the accusative of the mob. 832 // %p means the pronoun. 833 // %M? means the mob, using the same code as above. 834 // %I? means the item, using the same code as above. 835 // %I1? means the singular item, using the same code as above. 836 // <foo> means to conjugate foo with this mob. 837 // <I:..> and <M:..> conjugate respectively. 838 // %B1, %B2, refer to an ancillary buffer with a specific 839 // numbering order. 840 void formatAndReport(const char *str); 841 void formatAndReport(const char *str, const char *b1, const char *b2 = 0, const char *b3 = 0); formatAndReport(const char * str,BUF b1)842 inline void formatAndReport(const char *str, BUF b1) 843 { formatAndReport(str, b1.buffer()); } 844 void formatAndReport(const char *str, const MOB *mob, const char *b1 = 0, const char *b2 = 0, const char *b3 = 0); formatAndReport(const char * str,const MOB * mob,BUF b1)845 inline void formatAndReport(const char *str, const MOB *mob, BUF b1) 846 { formatAndReport(str, mob, b1.buffer()); } 847 void formatAndReport(const char *str, const ITEM *item, const char *b1 = 0, const char *b2 = 0, const char *b3 = 0); formatAndReport(const char * str,const ITEM * item,BUF b1)848 inline void formatAndReport(const char *str, const ITEM *item, BUF b1) 849 { formatAndReport(str, item, b1.buffer()); } 850 void formatAndReportExplicit(const char *str, const MOB *mob, const ITEM *item, const char *b1 = 0, const char *b2 = 0, const char *b3 = 0); formatAndReportExplicit(const char * str,const MOB * mob,const ITEM * item,BUF b1)851 inline void formatAndReportExplicit(const char *str, const MOB *mob, const ITEM *item, BUF b1) 852 { formatAndReportExplicit(str, mob, item, b1.buffer()); } 853 854 static BUF formatToString(const char *str, const MOB *self, const ITEM *selfitem, const MOB *mob, const ITEM *item, const char *b1 = 0, const char *b2 = 0, const char *b3 = 0); 855 static BUF formatToString(const char *str, const MOB *self, const ITEM *selfitem, const MOB *mob, const ITEM *item, BUF b1, BUF b2, BUF b3); 856 857 // Conjugates a verb with our own tense. If this is an avatar, 858 // that means "You", otherwise "It". 859 BUF conjugate(const char *infinitive, bool past=false) const; 860 861 // This gets the tense which this mob should be addressed with, ie, 862 // me, you, he, she, it, they? 863 VERB_PERSON getPerson() const; 864 VERB_PERSON getGender() const; 865 866 // you, it, he, she, they, etc. 867 const char *getPronoun() const; 868 869 // your, its, his, her, their, etc. 870 const char *getPossessive() const; 871 872 // yours, its, his, hers, theirs, etc. 873 const char *getOwnership() const; 874 875 // yourself, itself, himself, herself, etc 876 const char *getReflexive() const; 877 878 // you, it, him, her, etc. 879 const char *getAccusative() const; 880 881 // dragon, the dragon, a dragon, etc. 882 BUF getName(bool usearticle = true, bool usedefinite = true, 883 bool forcevisible = false, bool neverpronoun = false) const; 884 885 // The headless is in perfect health. It would be a hard fight. 886 BUF getDescription() const; 887 888 // This displays the long description of this particular mob. 889 // It will also provide all the other cool facts, like what they 890 // are wearing, etc. 891 void viewDescription() const; 892 893 // Displays a character dump of the characters abilities. 894 // Also saves to a file on the PC version. 895 void characterDump(bool ondeath, bool didwin, bool savefile, int truetime = -1); 896 897 void pageCharacterDump(bool ondeath, bool didwin, int truetime = -1); 898 899 // Determines if this mob moved last turn. Only works 900 // for the avatar. 901 bool hasMovedLastTurn() const; 902 void getLastMoveDirection(int &dx, int &dy) const; 903 void resetLastMoveDirection() const; 904 void flagLastMoveAsOld() const; 905 906 // Rename the MOB this name. 907 void christen(const char *name); christen(BUF buf)908 void christen(BUF buf) 909 { christen(buf.buffer()); } 910 911 // Perform a smarts/str check against the given difficulty. 912 // Result is: 913 // -1 - Guaranteed fail 914 // 0 - Failed a check. 915 // 1 - Succeeded check. 916 // 2 - Guaranteed success. 917 // One should have different text for each so people know if they 918 // should test again. 919 int smartsCheck(int smarts); 920 int strengthCheck(int str); 921 922 // Picks up an item, assigns it into a slot. 923 // Returns false if failed (item is there, or no room) 924 // Note that this *CAN* delete item! This occurs if it gets 925 // merged into a stack in the inventory. 926 bool acquireItem(ITEM *item, int sx, int sy, ITEM **newitem = 0); 927 bool acquireItem(ITEM *item, ITEM **newitem = 0); 928 // Finds first free item slot, returns false if none. 929 bool findItemSlot(int &sx, int &sy) const; 930 // Gets the item given a slot. Possible null. 931 ITEM *getItem(int sx, int sy) const; 932 // Returns a random item from our inventory, null if there are no 933 // items. 934 ITEM *randomItem() const; 935 // Unlinks & returns the item from the given slot. 936 ITEM *dropItem(int sx, int sy); 937 938 // Destroys all items in this inventory. 939 void destroyInventory(); 940 941 // Reverses the order of our inventory. Theoritically this 942 // should be a no-op, but our quiver uses this order. 943 void reverseInventory(); 944 945 // Drops one of the rings the creature is wearing, provide 946 // at least two rings are worn. 947 void dropOneRing(); 948 949 // Gets the item from the specified equipped slot (same as 950 // getItem(0, (int)name) 951 ITEM *getEquippedItem(ITEMSLOT_NAMES slot) const; 952 953 // Determine if any item is equipped (faster than testing 954 // each slot in turn...) 955 bool hasAnyEquippedItems() const; 956 957 bool hasSlot(ITEMSLOT_NAMES slot) const; 958 // Note: May return 0 if there is no such slot! 959 const char *getSlotName(ITEMSLOT_NAMES slot) const; 960 961 // Returns the first equipped item, if any, that grants the 962 // given intrinsic. 963 ITEM *getSourceOfIntrinsic(INTRINSIC_NAMES intrinsic) const; 964 965 // Returns the mob that inflicted the timed intrinsic, if any. 966 MOB *getInflictorOfIntrinsic(INTRINSIC_NAMES intrinsic) const; 967 968 // This will create a new MOB for ourself. 969 // All stashed mob references will be transfered to the new mob. 970 // Polymorphing a morphed mob returns it to its original state. 971 bool actionPolymorph(bool allowcontrol = true, 972 bool forcecontrol = false, 973 MOB_NAMES newdef = MOB_NONE); 974 975 // This undoes the effect of polymorph. 976 bool actionUnPolymorph(bool silent = false, 977 bool systemshock = false); 978 979 // This turns the creature into stone. 980 bool actionPetrify(); 981 982 // This usually does nothing :> 983 bool actionUnPetrify(); 984 985 HUNGER_NAMES getHungerLevel() const; 986 987 void starve(int foodval); 988 void feed(int foodval); 989 990 // Applies system shock to this, 10% of maxhp lost 991 void systemshock(); 992 993 // Attempts to save this creatures life. Does not attempt 994 // reverting to original form style saving, only INTRINSIC_LIFESAVED 995 // type saving. 996 // Returns true if critter saved, false if not saved. Will destroy 997 // source of saving. 998 bool attemptLifeSaving(const char *deathmsg); 999 1000 // This marks this mob as having just died. This will increment 1001 // the kill counts & also do proper victory stuff when the 1002 // user gets axed. 1003 // This does not mean any one gets the exp, or the mob won't be 1004 // back. For example, kill/res loops will count, as will 1005 // petrifies. 1006 // becameitem flags if the monster died in a way in which it 1007 // can come back 1008 void triggerAsDeath(ATTACK_NAMES attack, MOB *src, ITEM *weapon, bool becameitem); 1009 void triggerAsDeath(const ATTACK_DEF *attack, MOB *src, ITEM *weapon, bool becameitem); 1010 1011 // This adds the given noise to this mob. 1012 void makeNoise(int noiselevel); 1013 // This adds any noise from the given slot. 1014 void makeEquipNoise(ITEMSLOT_NAMES slot); 1015 // This reveals the amount of noise this mob is making. 1016 // If the observer is null, it is the total noise. If it is 1017 // a creature, it is a random number from 0 to max noise. The trick 1018 // is that this will be the same for every call on this time slice 1019 // and with this pair of critters. 1020 int getNoiseLevel(const MOB *observer) const; 1021 1022 protected: 1023 // Internal methods to handle intrinsic counters: 1024 INTRINSIC_COUNTER *getCounter(INTRINSIC_NAMES intrinsic) const; 1025 void removeCounter(INTRINSIC_NAMES intrinsic); 1026 INTRINSIC_COUNTER *addCounter(MOB *inflictor, 1027 INTRINSIC_NAMES intrinsic, int turns); 1028 1029 // myDefinition is what we are now. myOrigDefinition is 1030 // what we were when we were created. Polymorph doesn't 1031 // create this difference, stuff like ghastify does. 1032 u8 myDefinition, myOrigDefinition; 1033 u8 myX, myY, myExpLevel; 1034 1035 // These actually store twice our hit die to allow us to 1036 // gain fractional levels. 1037 u8 myHitDie, myMagicDie; 1038 1039 // This is the amount of noise the mob has made so far. Not saved. 1040 u8 myNoiseLevel; 1041 1042 u8 myDLevel; 1043 1044 u8 myGender; 1045 1046 // Current state in AI FSM. Stored to disk. 1047 u8 myAIFSM; 1048 1049 MOBREF myOwnRef; 1050 1051 // When we are polymorphed, this is non-null and holds the base critter 1052 // type. 1053 MOBREF myBaseType; 1054 1055 // Stores relevant AI state stuff. Not saved. 1056 u16 myAIState; 1057 1058 // Food levels. 1059 u16 myFoodLevel; 1060 1061 // Note, HP had better be able to go negative. 1062 short myHP, myMaxHP; 1063 short myMP, myMaxMP; 1064 short myExp; 1065 MOB *myNext; 1066 1067 // AI related state information: 1068 MOBREF myAITarget; 1069 1070 NAME myName; 1071 1072 ITEM *myInventory; 1073 1074 INTRINSIC myIntrinsic; 1075 INTRINSIC *myWornIntrinsic; 1076 1077 INTRINSIC_COUNTER *myCounters; 1078 1079 static s8 ourAvatarDx, ourAvatarDy; 1080 1081 static SPELL_NAMES ourZapSpell; 1082 static ATTACK_NAMES ourEffectAttack; 1083 static int ourFireBallCount; 1084 static bool ourAvatarOnFreshSquare; 1085 static bool ourAvatarMoveOld; 1086 }; 1087 1088 #endif 1089