1 /*************************************************************************** 2 creature.h - A class describing any creature 3 ------------------- 4 begin : Sat May 3 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 CREATURE_H 19 #define CREATURE_H 20 #pragma once 21 22 #include <stdio.h> 23 #include <string.h> 24 #include <stdlib.h> 25 #include <iostream> 26 //#include <conio.h> // for getch 27 #include <vector> // STL for Vector 28 #include <map> 29 #include <set> 30 #include <algorithm> // STL for Heap 31 32 #include "persist.h" 33 #include "date.h" 34 #include "render/renderedcreature.h" 35 #include "storable.h" 36 #include "rpg/rpglib.h" 37 #include "session.h" 38 #include "render/texture.h" 39 40 class Map; 41 class Effect; 42 class Location; 43 class Battle; 44 class PathManager; 45 class GLShape; 46 class Item; 47 class Event; 48 class RenderedItem; 49 class NpcInfo; 50 class RenderedProjectile; 51 class Trap; 52 53 54 /** 55 *@author Gabor Torok 56 57 This class is both the UI representation (shape) and state (backpack, etc.) of a character or monster. 58 All creatures of the same type (character or monster) share the same instance of the prototype class (Character of Monster) 59 60 */ 61 62 // how many times to attempt to move to range 63 #define MAX_FAILED_MOVE_ATTEMPTS 10 64 65 /// Contains the location of an item in the backpack or where it is equipped. 66 67 class BackpackInfo { 68 public: 69 int backpackIndex; 70 int equipIndex; 71 }; 72 73 /// An individual char/NPC/monster (look and state). 74 75 class Creature : public RenderedCreature { 76 77 private: 78 // gui information 79 GLShape *shape; 80 std::string model_name; 81 std::string skin_name; 82 Uint16 dir; 83 Session *session; 84 int motion; 85 int failedToMoveWithinRangeAttemptCount; 86 int facingDirection; 87 int formation; 88 int tx, ty; 89 int selX, selY; 90 int cantMoveCounter; 91 PathManager* pathManager; 92 Creature *targetCreature; 93 int targetX, targetY, targetZ; 94 Item *targetItem; 95 bool arrived; // true if no particular destination set for this creature 96 std::map<int, Event*> stateModEventMap; 97 int portraitTextureIndex; 98 GLfloat angle, wantedAngle, angleStep; 99 100 // backpack 101 Item *backpack; 102 int equipped[Constants::EQUIP_LOCATION_COUNT]; 103 int preferredWeapon; 104 105 // character information 106 char name[255]; 107 int level, experience, hp, mp, startingHp, startingMp, ac, thirst, hunger, money, expOfNextLevel; 108 int sex; 109 Character *character; 110 int skills[Skill::SKILL_COUNT], skillBonus[Skill::SKILL_COUNT], skillMod[Skill::SKILL_COUNT]; 111 int availableSkillMod; 112 bool hasAvailableSkillPoints; 113 int skillsUsed[Skill::SKILL_COUNT]; 114 GLuint stateMod, protStateMod; 115 Monster *monster; 116 117 GLint lastTick; 118 int speed, originalSpeed; 119 float armor; 120 int bonusArmor; 121 bool armorChanged; 122 float lastArmor[ RpgItem::DAMAGE_TYPE_COUNT ]; 123 float lastArmorSkill[ RpgItem::DAMAGE_TYPE_COUNT ]; 124 float lastDodgePenalty[ RpgItem::DAMAGE_TYPE_COUNT ]; 125 126 int lastTurn; 127 128 std::vector<Spell*> spells; 129 int action; 130 Item *actionItem; 131 Spell *actionSpell; 132 SpecialSkill *actionSkill; 133 Creature *preActionTargetCreature; 134 135 int moveCount; 136 Uint32 lastMove; 137 Battle *battle; 138 139 Date lastEnchantDate; 140 int character_model_info_index; 141 int deityIndex; 142 143 Storable *quickSpell[12]; 144 145 NpcInfo *npcInfo; 146 147 std::set<SpecialSkill*> specialSkills; 148 std::set<std::string> specialSkillNames; 149 150 bool mapChanged; 151 152 std::map<Location*, Uint32> secretDoorAttempts; 153 std::map<Trap*, Uint32> trapFindAttempts; 154 bool moving; 155 156 char causeOfDeath[255], pendingCauseOfDeath[255]; 157 bool backpackSorted; 158 std::map<Item*, BackpackInfo*> invInfos; 159 Uint32 lastPerceptionCheck; 160 bool boss, savedMissionObjective, scripted; 161 int scriptedAnim; 162 163 Texture portrait; 164 Uint32 lastDecision; 165 Creature *summoner; 166 std::vector<Creature *> summoned; 167 168 public: 169 static const int DIAMOND_FORMATION = 0; 170 static const int STAGGERED_FORMATION = 1; 171 static const int SQUARE_FORMATION = 2; 172 static const int ROW_FORMATION = 3; 173 static const int SCOUT_FORMATION = 4; 174 static const int CROSS_FORMATION = 5; 175 static const int FORMATION_COUNT = 6; 176 177 // The creature AI 178 #define AI_DECISION_INTERVAL 1000 179 180 enum { 181 AI_STATE_STANDING_NO_ENEMY = 0, 182 AI_STATE_STANDING_ENEMY_AROUND, 183 AI_STATE_LOITERING_NO_ENEMY, 184 AI_STATE_LOITERING_ENEMY_AROUND, 185 AI_STATE_LOITERING_END_OF_PATH, 186 AI_STATE_MOVING_TOWARDS_ENEMY, 187 AI_STATE_ENGAGING_ENEMY, 188 AI_STATE_LOW_HP, 189 AI_STATE_ENEMY_LOW_HP, 190 AI_STATE_LOW_MP, 191 AI_STATE_ENEMY_LOW_MP, 192 AI_STATE_AC_NEEDS_PIMPING, 193 AI_STATE_SURROUNDED, 194 AI_STATE_OUTNUMBERED, 195 AI_STATE_FEW_ENEMIES, 196 197 AI_STATE_COUNT 198 }; 199 200 enum { 201 AI_ACTION_ATTACK_CLOSEST_ENEMY = 0, 202 AI_ACTION_CAST_ATTACK_SPELL, 203 AI_ACTION_CAST_AREA_SPELL, 204 AI_ACTION_HEAL, 205 AI_ACTION_CAST_AC_SPELL, 206 AI_ACTION_ATTACK_RANDOM_ENEMY, 207 AI_ACTION_START_LOITERING, 208 AI_ACTION_STOP_MOVING, 209 AI_ACTION_GO_ON, 210 211 AI_ACTION_COUNT 212 }; 213 214 Creature( Session *session, Character *character, char const* name, int sex, int character_model_info_index ); 215 Creature( Session *session, Monster *monster, GLShape *shape, bool initMonster = true ); 216 ~Creature(); 217 218 /// The session object used to create this class instance. getSession()219 inline Session* getSession() { 220 return session; 221 } 222 223 /// The current battle turn. getBattle()224 inline Battle *getBattle() { 225 return battle; 226 } 227 getPathManager()228 inline PathManager* getPathManager() { 229 return pathManager; 230 } 231 232 // ####################### 233 // #### CREATURE TYPE #### 234 // ####################### 235 getBackpack()236 inline Item *getBackpack() { return backpack; } 237 238 /// Is it an NPC? (this excludes wandering heroes, which are in fact auto controlled characters) isNpc()239 inline bool isNpc() { 240 return( monster ? monster->isNpc() : false ); 241 } 242 243 /// Sets whether the creature is an NPC. setNpc(bool b)244 inline void setNpc( bool b ) { 245 if ( monster ) monster->setNpc( b ); 246 if ( !b ) npcInfo = NULL; 247 } 248 249 /// Is it a wandering hero (recruitable character)? isWanderingHero()250 inline bool isWanderingHero() { 251 return( !session->getParty()->isPartyMember( this ) && ( character != NULL ) ); 252 } 253 254 /// Is it a monster? isMonster()255 inline bool isMonster() { 256 return( ( monster != NULL ) && !monster->isNpc() ); 257 } 258 259 /// Is it harmless critter? isHarmlessAnimal()260 inline bool isHarmlessAnimal() { 261 return( ( monster != NULL ) && monster->isHarmless() ); 262 } 263 264 /// Is it a party member? isPartyMember()265 inline bool isPartyMember() { 266 return( session->getParty()->isPartyMember( this ) ); 267 } 268 269 /// Is it the currently active party member? isPlayer()270 inline bool isPlayer() { 271 return( this == session->getParty()->getPlayer() ); 272 } 273 274 /// Is it controlled by the computer? isAutoControlled()275 inline bool isAutoControlled() { 276 return( !isPartyMember() || getStateMod( StateMod::possessed ) ); 277 } 278 279 /// Is creature c of friendly alignment? isFriendly(Creature * c)280 inline bool isFriendly( Creature *c ) { 281 bool f = ( ( isMonster() && c->isMonster() ) || ( !isMonster() && !c->isMonster() ) ); 282 return ( getStateMod( StateMod::possessed ) ? !f : f ); 283 } 284 setBoss(bool b)285 inline void setBoss( bool b ) { 286 this->boss = b; 287 } 288 289 /// Is it a level boss? isBoss()290 virtual inline bool isBoss() { 291 return this->boss; 292 } 293 isSavedMissionObjective()294 inline bool isSavedMissionObjective() { 295 return savedMissionObjective; 296 } 297 setSavedMissionObjective(bool b)298 inline void setSavedMissionObjective( bool b ) { 299 savedMissionObjective = b; 300 } 301 302 // #################### 303 // #### APPEARANCE #### 304 // #################### 305 306 /// The name of the 3D model used for the creature. getModelName()307 inline char const* getModelName() { 308 return model_name.c_str(); 309 } 310 311 /// The 3D shape of the creature. getShape()312 inline GLShape *getShape() { 313 return shape; 314 } 315 getSkinName()316 inline char const* getSkinName() { 317 return skin_name.c_str(); 318 } 319 getCharacterModelInfoIndex()320 inline int getCharacterModelInfoIndex() { 321 return character_model_info_index; 322 } 323 324 void draw(); 325 326 void drawMoviePortrait( int width, int height ); 327 void drawPortrait( int width, int height, bool inFrame = false ); 328 setPortraitTextureIndex(int n)329 inline void setPortraitTextureIndex( int n ) { 330 this->portraitTextureIndex = n; 331 } 332 getPortraitTextureIndex()333 inline int getPortraitTextureIndex() { 334 return portraitTextureIndex; 335 } 336 setSex(int n)337 inline void setSex( int n ) { 338 this->sex = n; 339 } 340 341 /// Male/female? getSex()342 inline int getSex() { 343 return this->sex; 344 } 345 346 // ################### 347 // #### ANIMATION #### 348 // ################### 349 setScriptedAnimation(int n)350 inline void setScriptedAnimation( int n ) { 351 this->scriptedAnim = n; 352 } 353 354 void setScripted( bool b ); 355 getScriptedAnimation()356 inline int getScriptedAnimation() { 357 return this->scriptedAnim; 358 } 359 360 /// Will the creature stay visible in movie mode? isScripted()361 inline bool isScripted() { 362 return this->scripted; 363 } 364 365 /// Currently moving? isMoving()366 inline bool isMoving() { 367 return moving; 368 } 369 setMoving(bool b)370 inline void setMoving( bool b ) { 371 moving = b; 372 } 373 getAngle()374 inline GLfloat getAngle() { 375 return angle; 376 } 377 setFacingDirection(int direction)378 inline void setFacingDirection( int direction ) { 379 this->facingDirection = direction; 380 } 381 382 /// The direction the creature faces (U, D, L, R). getFacingDirection()383 inline int getFacingDirection() { 384 return this->facingDirection; 385 } 386 getDir()387 inline Uint16 getDir() { 388 return dir; 389 } 390 391 /// Direction of movement (U, D, L, R). setDir(Uint16 dir)392 inline void setDir( Uint16 dir ) { 393 this->dir = dir; 394 } 395 396 // ######################## 397 // #### MAP NAVIGATION #### 398 // ######################## 399 400 /** 401 The movement functions return true if movement has occured, false if it has not. 402 */ 403 404 bool move( Uint16 dir ); 405 void switchDirection( bool force ); 406 bool follow( Creature *leader ); 407 408 /// Makes the creature move out of another creature's path. 409 void moveAway( Creature *other ); 410 Location *moveToLocator(); 411 412 void stopMoving(); 413 bool anyMovesLeft(); 414 415 void setMotion( int motion ); 416 417 /// The current mode of motion (stand, run, loiter around...) getMotion()418 inline int getMotion() { 419 return this->motion; 420 } 421 setFormation(int formation)422 inline void setFormation( int formation ) { 423 this->formation = formation; 424 } 425 426 /// Formations are currently unused. getFormation()427 inline int getFormation() { 428 return formation; 429 } 430 431 /// Map X coordinate of currently selected target. getTargetX()432 inline int getTargetX() { 433 if ( targetCreature ) return toint( targetCreature->getX() ); else return targetX; 434 } 435 436 /// Map Y coordinate of currently selected target. getTargetY()437 inline int getTargetY() { 438 if ( targetCreature ) return toint( targetCreature->getY() ); else return targetY; 439 } 440 441 /// Map Z coordinate of currently selected target. getTargetZ()442 inline int getTargetZ() { 443 if ( targetCreature ) return toint( targetCreature->getZ() ); else return targetZ; 444 } 445 446 void setTargetCreature( Creature *c, bool findPath = false , float range = static_cast<float>( MIN_DISTANCE ) ); 447 448 /// The creature that is currently set as a target. getTargetCreature()449 inline Creature *getTargetCreature() { 450 return targetCreature; 451 } 452 453 bool setSelCreature( Creature* creature, float range, bool cancelIfNotPossible = false ); 454 setTargetLocation(int x,int y,int z)455 inline void setTargetLocation( int x, int y, int z ) { 456 targetItem = NULL; targetCreature = NULL; targetX = x; targetY = y; targetZ = z; 457 } 458 459 /// The map location that is currently set as a target. getTargetLocation(int * x,int * y,int * z)460 inline void getTargetLocation( int *x, int *y, int *z ) { 461 *x = targetX; *y = targetY; *z = targetZ; 462 } 463 setTargetItem(int x,int y,int z,Item * item)464 inline void setTargetItem( int x, int y, int z, Item *item ) { 465 setTargetLocation( x, y, z ); targetItem = item; 466 } 467 468 /// The item that is currently set as a target. getTargetItem()469 inline Item *getTargetItem() { 470 return targetItem; 471 } 472 473 bool setSelXY( int x, int y, bool cancelIfNotPossible = false ); 474 475 /// Set target without performing pathfinding. setSelXYNoPath(int x,int y)476 inline void setSelXYNoPath( int x, int y ) { 477 selX = x; selY = y; 478 } 479 480 /// Map X coordinate of selection target. getSelX()481 inline int getSelX() { 482 return selX; 483 } 484 485 /// Map Y coordinate of selection target. getSelY()486 inline int getSelY() { 487 return selY; 488 } 489 490 float getDistanceToTarget( RenderedCreature *creature = NULL ); 491 float getDistanceToSel(); 492 float getDistance( RenderedCreature *other ); 493 494 // get angle to target creature 495 float getTargetAngle(); 496 497 /// Unused. setMapChanged()498 inline void setMapChanged() { 499 mapChanged = true; 500 } 501 502 // ############### 503 // #### AUDIO #### 504 // ############### 505 506 void playCharacterSound( int soundType, int panning ); 507 void playFootstep(); 508 509 // ########################## 510 // #### BASIC ATTRIBUTES #### 511 // ########################## 512 513 /// The creature's UNLOCALIZED name. getName()514 inline char *getName() { 515 return name; 516 } 517 setName(char const * s)518 inline void setName( char const* s ) { 519 strncpy( name, s, 254 ); name[254] = '\0'; 520 } 521 522 virtual char const* getType(); 523 void getDetailedDescription( std::string& s ); 524 525 float getAlignment(); 526 527 /// The creature's level. getLevel()528 inline int getLevel() { 529 return level; 530 } 531 setLevel(int n)532 inline void setLevel( int n ) { 533 level = ( n < 1 ? 1 : n ); evalSpecialSkills(); 534 } 535 536 /// Experience points needed for next level. getExpOfNextLevel()537 inline int getExpOfNextLevel() { 538 return expOfNextLevel; 539 } 540 541 /// Experience points. getExp()542 inline int getExp() { 543 return experience; 544 } 545 546 void setExp(); 547 548 /// Amount of experience points. setExp(int n)549 inline void setExp( int n ) { 550 experience = ( n < 0 ? 0 : n ); evalSpecialSkills(); 551 } 552 553 int addExperience( int exp ); 554 int addExperienceWithMessage( int exp ); 555 556 void changeProfession( Character *character ); 557 558 /// Amount of money the creature holds. getMoney()559 inline int getMoney() { 560 return money; 561 } 562 setMoney(int n)563 inline void setMoney( int n ) { 564 money = n; evalSpecialSkills(); 565 } 566 567 /// Current hit points. getHp()568 inline int getHp() { 569 return hp; 570 } 571 572 void setHp(); 573 setHp(int n)574 inline void setHp( int n ) { 575 hp = ( n < 0 ? 0 : n ); evalSpecialSkills(); 576 } 577 578 int getMaxHp(); 579 580 /// Current magic points. getMp()581 inline int getMp() { 582 return mp; 583 } 584 585 void setMp(); 586 setMp(int n)587 inline void setMp( int n ) { 588 mp = ( n < 0 ? 0 : n ); evalSpecialSkills(); 589 } 590 591 /// Starting HP for level 1. 592 int getStartingHp(); 593 594 /// Starting MP for level 1. 595 int getStartingMp(); 596 597 int getMaxMp(); 598 599 /// Current thirst level. getThirst()600 inline int getThirst() { 601 return thirst; 602 } 603 setThirst(int n)604 inline void setThirst( int n ) { 605 if ( n < 0 )n = 0; if ( n > 10 )n = 10; thirst = n; evalSpecialSkills(); 606 } 607 608 /// Current hunger level. getHunger()609 inline int getHunger() { 610 return hunger; 611 } 612 setHunger(int n)613 inline void setHunger( int n ) { 614 if ( n < 0 )n = 0; if ( n > 10 )n = 10; hunger = n; evalSpecialSkills(); 615 } 616 617 //#### INTERNAL creature types #### 618 619 void setNpcInfo( NpcInfo *npcInfo ); 620 621 /// Extra info for edited NPCs. getNpcInfo()622 inline NpcInfo *getNpcInfo() { 623 return npcInfo; 624 } 625 626 /// Gets character info. getCharacter()627 inline Character *getCharacter() { 628 return character; 629 } 630 631 void setCharacter( Character *c ); 632 633 /// Gets monster/NPC info. getMonster()634 inline Monster *getMonster() { 635 return monster; 636 } 637 638 // ################ 639 // #### SKILLS #### 640 // ################ 641 642 /// Returns the value of the specified skill. 643 inline int getSkill( int index, bool includeMod = true ) { 644 return skills[index] + skillBonus[index] + ( includeMod ? skillMod[index] : 0 ); 645 } 646 647 void setSkill( int index, int value ); 648 649 /// Additional skill bonus. getSkillBonus(int index)650 inline int getSkillBonus( int index ) { 651 return skillBonus[index]; 652 } 653 654 void setSkillBonus( int index, int value ); 655 656 /// Skill modification (after levelup) that has not yet been applied. getSkillMod(int index)657 inline int getSkillMod( int index ) { 658 return skillMod[index]; 659 } 660 661 void setSkillMod( int index, int value ); 662 getAvailableSkillMod()663 inline int getAvailableSkillMod() { 664 return availableSkillMod; 665 } 666 setAvailableSkillMod(int n)667 inline void setAvailableSkillMod( int n ) { 668 availableSkillMod = n; 669 if ( !hasAvailableSkillPoints && n > 0 ) hasAvailableSkillPoints = true; 670 } 671 672 void applySkillMods(); 673 674 /// Still skill points left? getHasAvailableSkillPoints()675 bool getHasAvailableSkillPoints() { 676 return hasAvailableSkillPoints; 677 } 678 679 bool rollSkill( int skill, float luckDiv = 0.0f ); 680 void rollPerception(); 681 682 bool rollSecretDoor( Location *pos ); 683 void resetSecretDoorAttempts(); 684 685 bool rollTrapFind( Trap *trap ); 686 void resetTrapFindAttempts(); 687 void disableTrap( Trap *trap ); 688 689 // ############################## 690 // #### SPECIAL CAPABILITIES #### 691 // ############################## 692 693 /// Does it have this special capability? hasCapability(char * name)694 inline bool hasCapability( char *name ) { 695 std::string skillName = name; 696 return specialSkillNames.find( skillName ) != specialSkillNames.end(); 697 } 698 699 /// Does it have this special capability? hasSpecialSkill(SpecialSkill * ss)700 inline bool hasSpecialSkill( SpecialSkill *ss ) { 701 return specialSkills.find( ss ) != specialSkills.end(); 702 } 703 704 char *useSpecialSkill( SpecialSkill *specialSkill, bool manualOnly ); 705 void evalSpecialSkills(); 706 707 void applyRecurringSpecialSkills(); 708 float applyAutomaticSpecialSkills( int event, char *varName, float value ); 709 710 // #################### 711 // #### STATE MODS #### 712 // #################### 713 714 /// Returns the active state of a state mod. getStateMod(int mod)715 inline bool getStateMod( int mod ) { 716 return ( stateMod & ( 1 << mod ) ? true : false ); 717 } 718 719 void setStateMod( int mod, bool setting ); 720 721 /// Returns whether the specified state mod is protected (by an item etc.) getProtectedStateMod(int mod)722 inline bool getProtectedStateMod( int mod ) { 723 return ( protStateMod & ( 1 << mod ) ? true : false ); 724 } 725 726 void setProtectedStateMod( int mod, bool setting ); 727 728 /// Schedules state mod effects. setStateModEvent(int mod,Event * event)729 inline void setStateModEvent( int mod, Event *event ) { 730 stateModEventMap[mod] = event; 731 } 732 getStateModEvent(int mod)733 inline Event *getStateModEvent( int mod ) { 734 return( stateModEventMap.find( mod ) == stateModEventMap.end() ? NULL : stateModEventMap[mod] ); 735 } 736 737 // ############### 738 // #### MAGIC #### 739 // ############### 740 741 bool addSpell( Spell *spell ); 742 bool isSpellMemorized( Spell *spell ); 743 744 /// Number of spells the creature knows. getSpellCount()745 inline int getSpellCount() { 746 return static_cast<int>( spells.size() ); 747 } 748 getSpell(int index)749 inline Spell *getSpell( int index ) { 750 return spells[index]; 751 } 752 setDeityIndex(int n)753 inline void setDeityIndex( int n ) { 754 deityIndex = n; 755 } 756 /// Deity of the creature. getDeityIndex()757 inline int getDeityIndex() { 758 return deityIndex; 759 } 760 setLastEnchantDate(Date date)761 inline void setLastEnchantDate( Date date ) { 762 lastEnchantDate = date; 763 } 764 765 /// Last point in time when the creature tried to enchant something. getLastEnchantDate()766 inline Date getLastEnchantDate() { 767 return lastEnchantDate; 768 } 769 770 // ################## 771 // #### BACKPACK #### 772 // ################## 773 774 float backpackWeight; 775 776 /// Total weight of the backpack. getBackpackWeight()777 inline float getBackpackWeight() { 778 return backpackWeight; 779 } 780 781 float getMaxBackpackWeight(); 782 /// Number of items carried in backpack. 783 int getBackpackContentsCount(); 784 785 /// The item at a specified backpack index. 786 Item *getBackpackItem( int backpackIndex ); 787 788 bool addToBackpack( Item *item, int itemX=0, int itemY=0 ); 789 Item *removeFromBackpack( int backpackIndex ); 790 void debugBackpack(); 791 int findInBackpack( Item *item ); 792 bool isItemInBackpack( Item *item ); 793 794 Item *getEquippedItem( int equipLocation ); 795 Item *getEquippedItemByIndex( int equipIndex ); 796 void equipFromBackpack( int backpackIndex, int equipIndexHint = -1 ); 797 int doff( int backpackIndex ); 798 bool isEquippedWeapon( int equipLocation ); 799 800 bool isEquipped( Item *item ); 801 bool isEquipped( int backpackIndex ); 802 int getEquippedIndex( int backpackIndex ); 803 804 char *canEquipItem( Item *item, bool interactive = true ); 805 isBackpackSorted()806 inline bool isBackpackSorted() { 807 return backpackSorted; 808 } 809 setBackpackSorted(bool b)810 inline void setBackpackSorted( bool b ) { 811 backpackSorted = b; 812 } 813 814 void pickUpOnMap( RenderedItem *item ); 815 816 bool eatDrink( int backpackIndex ); 817 bool eatDrink( Item *item ); 818 void usePotion( Item *item ); 819 820 bool removeCursedItems(); 821 822 BackpackInfo *getBackpackInfo( Item *item, bool createIfMissing = false ); 823 824 /// Stores an item/spell etc. in a specified quickspell slot. setQuickSpell(int index,Storable * storable)825 inline void setQuickSpell( int index, Storable *storable ) { 826 for ( int i = 0; storable && i < 12; i++ ) { 827 if ( quickSpell[ i ] == storable ) { 828 // already stored 829 return; 830 } 831 } 832 quickSpell[ index ] = storable; 833 } 834 835 /// Returns the storable in a given quickspell slot. getQuickSpell(int index)836 inline Storable *getQuickSpell( int index ) { 837 return quickSpell[ index ]; 838 } 839 840 // ################ 841 // #### BATTLE #### 842 // ################ 843 setLastTurn(int n)844 inline void setLastTurn( int n ) { 845 lastTurn = n; 846 } 847 getLastTurn()848 inline int getLastTurn() { 849 return lastTurn; 850 } 851 852 // speed/initiative related stuff. 853 854 float getAttacksPerRound( Item *item = NULL ); 855 float getMaxAP(); 856 // return the initiative for a battle round, the lower the faster the attack 857 int getInitiative( int *max = NULL ); 858 // FIXME: should be modified by equipped items (boots of speed, etc.) 859 getSpeed()860 inline int getSpeed() { 861 return speed; 862 } 863 864 float getWeaponAPCost( Item *item, bool showDebug = true ); 865 866 // return the best equipped weapon that works on this distance, 867 // or NULL if none are available 868 Item *getBestWeapon( float dist, bool callScript = false ); 869 870 // Attack related. 871 872 /// The active weapon. getPreferredWeapon()873 inline int getPreferredWeapon() { 874 return preferredWeapon; 875 } 876 setPreferredWeapon(int n)877 inline void setPreferredWeapon( int n ) { 878 preferredWeapon = n; 879 } 880 881 bool nextPreferredWeapon(); 882 883 bool canAttack( RenderedCreature *creature, int *cursor = NULL ); 884 float getAttack( Item *weapon, float *maxP = NULL, float *minP = NULL, bool callScript = false ); 885 void getCth( Item *weapon, float *cth, float *skill, bool showDebug = true ); 886 float getAttackerStateModPercent(); 887 float rollMagicDamagePercent( Item *item ); 888 889 std::vector<RenderedProjectile*> *getProjectiles(); 890 int getMaxProjectileCount( Item *item ); 891 892 // Defense related. 893 894 float getParry( Item **parryItem ); 895 float getDodge( Creature *attacker, Item *weapon = NULL ); 896 897 float getArmor( float *armor, float *dodgePenalty, int damageType, Item *vsWeapon = NULL ); getBonusArmor()898 inline int getBonusArmor() { 899 return bonusArmor; 900 } setBonusArmor(int n)901 inline void setBonusArmor( int n ) { 902 bonusArmor = n; if ( bonusArmor < 0 ) bonusArmor = 0; recalcAggregateValues(); 903 } 904 905 float getDefenderStateModPercent( bool magical ); 906 907 // take damage 908 // return true if the creature dies 909 bool takeDamage( float damage, int effect_type = Constants::EFFECT_GLOW, GLuint delay = 0 ); 910 911 // Action scheduler. 912 913 void setAction( int action, Item *item = NULL, Spell *spell = NULL, SpecialSkill *skill = NULL ); 914 /// Current creature action (item, spell, capability). getAction()915 inline int getAction() { 916 return action; 917 } 918 /// The item used for the current action. getActionItem()919 inline Item *getActionItem() { 920 return actionItem; 921 } 922 /// The spell used for the current action. getActionSpell()923 inline Spell *getActionSpell() { 924 return actionSpell; 925 } 926 /// The capability used for the current action. getActionSkill()927 inline SpecialSkill *getActionSkill() { 928 return actionSkill; 929 } 930 931 // Target handling. 932 933 bool isTargetValid(); 934 hasTarget()935 inline bool hasTarget() { 936 return targetCreature || targetItem || targetX || targetY || targetZ; 937 } 938 939 void cancelTarget(); 940 941 /// Are we doing something (not being idle?) isBusy()942 inline bool isBusy() { 943 return hasTarget() || getAction() > Constants::ACTION_NO_ACTION || getActionItem() || getActionSkill() || getActionSpell(); 944 } 945 946 // The descriptions of why you died. 947 setCauseOfDeath(char * s)948 inline void setCauseOfDeath( char *s ) { 949 strncpy( this->causeOfDeath, s, 254 ); this->causeOfDeath[254] = 0; 950 } 951 getCauseOfDeath()952 inline char *getCauseOfDeath() { 953 return this->causeOfDeath; 954 } 955 setPendingCauseOfDeath(char * s)956 inline void setPendingCauseOfDeath( char *s ) { 957 strncpy( this->pendingCauseOfDeath, s, 254 ); this->pendingCauseOfDeath[254] = 0; 958 } 959 getPendingCauseOfDeath()960 inline char *getPendingCauseOfDeath() { 961 return this->pendingCauseOfDeath; 962 } 963 964 // Misc. methods. 965 966 // returns exp gained 967 int addExperience( Creature *creature_killed ); 968 969 // returns coins gained 970 int addMoney( Creature *creature_killed ); 971 972 // ################### 973 // #### AI BATTLE #### 974 // ################### 975 976 void decideAction(); 977 978 Creature *getClosestTarget(); 979 bool attackClosestTarget(); 980 981 Creature *getRandomTarget(); 982 bool attackRandomTarget(); 983 984 bool isWithPrereq( Item *item ); 985 bool isWithPrereq( Spell *spell ); 986 Creature *findClosestTargetWithPrereq( Spell *spell ); 987 988 bool castHealingSpell( bool checkOnly = false ); 989 bool castOffensiveSpell( bool checkOnly = false ); 990 bool castAreaSpell( bool checkOnly = false ); 991 bool castACSpell( bool checkOnly = false ); 992 993 bool useMagicItem( bool checkOnly = false ); 994 995 // ############## 996 // #### MISC #### 997 // ############## 998 999 CreatureInfo *save(); 1000 static Creature *load( Session *session, CreatureInfo *info ); 1001 1002 void resurrect( int rx, int ry ); 1003 1004 /// Unused. setLastTick(GLint n)1005 inline void setLastTick( GLint n ) { 1006 this->lastTick = n; 1007 } 1008 /// Unused. getLastTick()1009 inline GLint getLastTick() { 1010 return lastTick; 1011 } 1012 getMaxSummonedCreatures()1013 inline int getMaxSummonedCreatures() { 1014 return getLevel() / ( isSummoned() ? 6 : 3 ); 1015 } 1016 Creature *summonCreature( bool friendly=true ); 1017 Creature *doSummon( Monster *monster, int sx, int sy, int ex=0, int ey=0, bool friendly=true ); 1018 void dismissSummonedCreature(); setSummoner(Creature * summoner)1019 inline void setSummoner( Creature *summoner ) { this->summoner = summoner; } addSummoned(Creature * summonee)1020 inline void addSummoned( Creature *summonee ) { this->summoned.push_back( summonee ); } isSummoned()1021 inline bool isSummoned() { return summoner != NULL; } getSummoned()1022 inline std::vector<Creature*> *getSummoned() { return &summoned; } getSummoner()1023 inline Creature *getSummoner() { return summoner; } 1024 void dismissSummonedCreatures(); 1025 1026 1027 protected: 1028 1029 void evalTrap(); 1030 1031 /** 1032 * Recalculate skills when stats change. 1033 */ 1034 void skillChanged( int index, int oldValue, int newValue ); 1035 1036 1037 void calcArmor( int damageType, 1038 float *armorP, 1039 float *dodgePenalty, 1040 bool callScript = false ); 1041 1042 1043 void commonInit(); 1044 void calculateExpOfNextLevel(); 1045 void monsterInit(); 1046 void recalcAggregateValues(); 1047 1048 Location *takeAStepOnPath(); 1049 void computeAngle( GLfloat newX, GLfloat newY ); 1050 void showWaterEffect( GLfloat newX, GLfloat newY ); 1051 1052 /** 1053 * How big of a step to take. 1054 * Use fps, speed and gamespeed to figure this out. 1055 */ 1056 GLfloat getStep(); 1057 1058 /** 1059 * Apply a weapon influence modifier. 1060 * 1061 * @param weapon the item used or null for unarmed attack 1062 * @param influenceType an influence type from RpgItem 1063 * @param debugMessage a message to print 1064 * @return the bonus (malus if negative) 1065 */ 1066 float getInfluenceBonus( Item *weapon, 1067 int influenceType, 1068 char const* debugMessage ); 1069 }; 1070 1071 1072 #endif 1073 1074