Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields

creature.h

00001 /***************************************************************************
00002                           creature.h  -  description
00003                              -------------------
00004     begin                : Sat May 3 2003
00005     copyright            : (C) 2003 by Gabor Torok
00006     email                : cctorok@yahoo.com
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  *                                                                         *
00011  *   This program is free software; you can redistribute it and/or modify  *
00012  *   it under the terms of the GNU General Public License as published by  *
00013  *   the Free Software Foundation; either version 2 of the License, or     *
00014  *   (at your option) any later version.                                   *
00015  *                                                                         *
00016  ***************************************************************************/
00017 
00018 #ifndef CREATURE_H
00019 #define CREATURE_H
00020 
00021 #include <stdio.h>
00022 #include <string.h>
00023 #include <stdlib.h>
00024 #include <iostream>
00025 //#include <conio.h>   // for getch
00026 #include <vector>    // STL for Vector
00027 #include <map>
00028 #include <algorithm> // STL for Heap
00029 #include "glshape.h"
00030 #include "md2shape.h"
00031 #include "map.h"
00032 #include "session.h"
00033 #include "util.h"
00034 #include "rpg/character.h"
00035 #include "rpg/monster.h"
00036 #include "constants.h"
00037 #include "effect.h"
00038 #include "events/potionexpirationevent.h"
00039 #include "rpg/spell.h"
00040 #include "persist.h"
00041 #include "battle.h"
00042 
00043 using namespace std;
00044 
00045 #define MAX_CLOSED_NODES 50
00046 
00047 class Map;
00048 class Session;
00049 class Effect;
00050 class Item;
00051 class Location;
00052 class Battle;
00053 
00062 // how many times to attempt to move to range
00063 #define MAX_FAILED_MOVE_ATTEMPTS 10
00064 
00065 class Creature {
00066   
00067  private:
00068   // gui information
00069   GLfloat x, y, z;
00070   Creature *next;
00071   GLShape *shape;
00072   char *model_name, *skin_name;
00073   Uint16 dir;
00074   Session *session;
00075   int motion;
00076   int failedToMoveWithinRangeAttemptCount;
00077   int facingDirection;
00078   int formation;
00079   int index;
00080   int tx, ty;
00081   int selX, selY;
00082   int proposedX, proposedY, proposedPathIndex;
00083   int bestPathPos;
00084   vector<Location> bestPath;
00085   vector<Location> proposedPath;
00086   Creature *targetCreature;
00087   int targetX, targetY, targetZ;
00088   Item *targetItem;
00089   Sint16 cornerX, cornerY;
00090   bool arrived; // true if no particular destination set for this creature
00091   map<int, Event*> stateModEventMap;
00092   GLfloat angle, wantedAngle, angleStep;
00093   int portraitTextureIndex;
00094   
00095   // inventory
00096   Item *inventory[MAX_INVENTORY_SIZE];
00097   int inventory_count;
00098   int equipped[Constants::INVENTORY_COUNT];
00099 
00100   // character information
00101   char *name;
00102   int level, exp, hp, mp, startingHp, startingMp, ac, thirst, hunger, money, expOfNextLevel;
00103   Character *character;
00104   int skills[Constants::SKILL_COUNT], skillMod[Constants::SKILL_COUNT], skillBonus[Constants::SKILL_COUNT];
00105   GLuint stateMod, protStateMod;
00106   Monster *monster;
00107 
00108   char description[300];
00109   GLint lastTick;
00110   int speed;
00111   int armor, bonusArmor;
00112   int moveRetrycount;
00113   int availableSkillPoints;
00114   
00115   static const int MAX_MOVE_RETRY = 15;
00116   int lastTurn;
00117 
00118   GLuint effectDuration;
00119   GLuint damageEffectCounter;
00120   Effect *effect;
00121   int effectType;
00122 
00123   vector<Spell*> spells;
00124   int action;
00125   Item *actionItem;
00126   Spell *actionSpell;
00127   Creature *preActionTargetCreature;
00128 
00129   int moveCount;
00130   Uint32 lastMove;
00131   Battle *battle;
00132 
00133   Date lastEnchantDate;
00134   int character_model_info_index;
00135   int deityIndex;
00136 
00137   Spell *quickSpell[12];
00138   
00139  public:
00140   static const int DIAMOND_FORMATION = 0;
00141   static const int STAGGERED_FORMATION = 1;
00142   static const int SQUARE_FORMATION = 2;
00143   static const int ROW_FORMATION = 3;
00144   static const int SCOUT_FORMATION = 4;
00145   static const int CROSS_FORMATION = 5;
00146   static const int FORMATION_COUNT = 6;
00147   
00148   Creature(Session *session, Character *character, char *name, int character_model_info_index);
00149   Creature(Session *session, Monster *monster, GLShape *shape);
00150   ~Creature();
00151 
00152   inline void setQuickSpell( int index, Spell *spell ) { 
00153     for( int i = 0; i < 12; i++ ) {
00154       if( quickSpell[ i ] == spell ) {
00155         // already stored
00156         return;
00157       }
00158     }
00159     quickSpell[ index ] = spell; 
00160   }
00161   inline Spell *getQuickSpell( int index ) { return quickSpell[ index ]; }
00162 
00163   inline void setDeityIndex( int n ) { deityIndex = n; }
00164   inline int getDeityIndex() { return deityIndex; }
00165 
00166   inline void setPortraitTextureIndex( int n ) { this->portraitTextureIndex = n; }
00167   inline int getPortraitTextureIndex() { return portraitTextureIndex; }
00168 
00169   inline vector<Location> *getPath() { return &bestPath; }
00170   inline int getPathIndex() { return bestPathPos; }
00171 
00172   inline vector<Location> *getProposedPath() { return &proposedPath; }
00173   inline int getProposedPathIndex() { return proposedPathIndex; }
00174   inline int getProposedX() { return proposedX; }
00175   inline int getProposedY() { return proposedY; }
00176 
00177   inline int getCharacterModelInfoIndex() { return character_model_info_index; }
00178 
00179   inline void setLastEnchantDate(Date date) { lastEnchantDate = date; }
00180   inline Date getLastEnchantDate() { return lastEnchantDate; }
00181 
00182   inline Battle *getBattle() { return battle; }
00183 
00184   CreatureInfo *save();
00185   static Creature *load(Session *session, CreatureInfo *info);
00186 
00187   inline void setLastTurn(int n) { lastTurn = n; }
00188   inline int getLastTurn() { return lastTurn; }
00189 
00190   inline bool isMonster() { return (monster ? TRUE : FALSE); }
00191   
00192   inline int getTargetX() { if(targetCreature) return toint(targetCreature->getX()); else return targetX; }
00193   inline int getTargetY() { if(targetCreature) return toint(targetCreature->getY()); else return targetY; }
00194   inline int getTargetZ() { if(targetCreature) return toint(targetCreature->getZ()); else return targetZ; }
00195   void setTargetCreature(Creature *c);
00196   inline Creature *getTargetCreature() { return targetCreature; }
00197   inline void setTargetLocation(int x, int y, int z) { targetItem = NULL; targetCreature = NULL; targetX = x; targetY = y; targetZ = z; }
00198   inline void getTargetLocation(int *x, int *y, int *z) { *x = targetX; *y = targetY; *z = targetZ; }
00199   inline void setTargetItem(int x, int y, int z, Item *item) { setTargetLocation(x, y, z); targetItem = item; }
00200   inline Item *getTargetItem() { return targetItem; }
00201   
00202   inline void setMotion(int motion) { this->motion = motion; }  
00203   inline int getMotion() { return this->motion; }
00204 
00208 //  bool Creature::isInRange();
00209     
00210   inline void setFacingDirection(int direction) { this->facingDirection = direction;}
00211   inline int getFacingDirection() { return this->facingDirection; }
00212   
00213   
00214   inline char *getDescription() { return description; }
00215 
00216   inline void setLastTick(GLint n) { this->lastTick = n; }
00217   inline GLint getLastTick() { return lastTick; }
00218 
00219   // FIXME: should be modified by inventory (boots of speed, etc.)
00220   inline int getSpeed() { return speed; }
00221   
00225   bool move(Uint16 dir, Map *map);
00226   void switchDirection(bool force);
00227   bool follow(Map *map);
00228   bool moveToLocator(Map *map);
00229   void stopMoving();
00230   
00231   inline void moveTo(GLfloat x, GLfloat y, GLfloat z) { this->x = x; this->y = y; this->z = z; }
00232   inline GLfloat getX() { return x; }
00233   inline GLfloat getY() { return y; }
00234   inline GLfloat getZ() { return z; }
00235   inline char *getModelName() { return model_name; }
00236   inline char *getSkinName() { return skin_name; }
00237   inline GLShape *getShape() { return shape; }
00238   inline void setFormation(int formation) { this->formation = formation; }
00239   inline int getFormation() { return formation; }
00240   void setNext(Creature *next, int index);
00241   void setNextDontMove(Creature *next, int index);
00242   inline Uint16 getDir() { return dir; }
00243   inline void setDir(Uint16 dir) { this->dir = dir; }
00244   
00245   inline void draw() { getShape()->draw(); }  
00246     
00250   void findCorner(Sint16 *px, Sint16 *py, Sint16 *pz);
00251   
00252   void setSelXY(int x, int y, bool force=false);
00253   inline int getSelX() { return selX; }
00254   inline int getSelY() { return selY; }
00255   void findPath( int x, int y );
00256   
00257   bool anyMovesLeft();
00258   
00259   // inventory
00260   // get the item at the given equip-index (inventory location)
00261   float inventoryWeight;
00262   inline float getInventoryWeight() { return inventoryWeight;  }
00263   float getMaxInventoryWeight();
00264   Item *getEquippedInventory(int index);
00265   
00266   inline Item *getInventory(int index) { return inventory[index]; }
00267   inline int getInventoryCount() { return inventory_count; }
00268   inline void setInventory(int index, Item *item) { 
00269         if(index < inventory_count) inventory[index] = item; 
00270   }
00271   // returns the index of the last item added
00272   bool addInventory(Item *item, bool force=false);
00273   Item *removeInventory(int index);  
00274   int findInInventory(Item *item);
00275   // returns true if ate/drank item completely and false else
00276   bool eatDrink(int index);  
00277   bool eatDrink(Item *item);
00278   bool computeNewItemWeight(RpgItem * rpgItem);
00279   // equip or doff if already equipped
00280   void equipInventory(int index);
00281   int doff(int index);
00282   // return the equip index (inventory location) for an inventory index
00283   int getEquippedIndex(int index);
00284   bool isItemInInventory(Item *item);
00285   // return the item at location Character::INVENTORY_LEFT_HAND, etc.
00286   Item *getItemAtLocation(int location);
00287   bool isEquipped( Item *item );
00288   bool isEquipped( int inventoryIndex );
00289   bool removeCursedItems();
00290 
00291   // return the best equipped weapon that works on this distance, 
00292   // or NULL if none are available
00293   Item *getBestWeapon(float dist);  
00294 
00295   inline char *getName() { return name; }
00296   inline Character *getCharacter() { return character; }  
00297   inline Monster *getMonster() { return monster; }  
00298   inline int getLevel() { return level; }
00299   inline int getExpOfNextLevel() { return expOfNextLevel; }
00300   inline int getExp() { return exp; }
00301   inline int getMoney() { return money; }
00302   inline int getHp() { return hp; }
00303   inline int getStartingHp() { return hp; }
00304   int getMaxHp();
00305   inline int getMp() { return mp; }
00306   inline int getStartingMp() { return mp; }
00307   int getMaxMp();
00308   inline int getThirst() { return thirst; }
00309   inline int getHunger() { return hunger; }
00310   inline int getSkill(int index) { return skills[index] + skillBonus[index]; }
00311   inline bool getStateMod(int mod) { return (stateMod & (1 << mod) ? true : false); }  
00312   inline bool getProtectedStateMod(int mod) { return (protStateMod & (1 << mod) ? true : false); }  
00313 
00314   inline void setName(char *s) { name = s; }
00315   inline void setCharacter(Character *c) { character = c; }  
00316   inline void setLevel(int n) { level = n; }
00317   void setExp();
00318   inline void setExp(int n) { exp = n; }
00319   inline void setMoney(int n) { money = n; }
00320   inline void setHp(int n) { hp = n; }
00321   inline void setMp(int n) { mp = n; }
00322   inline void setThirst(int n)  { if(n<0)n=0; if(n>10)n=10; thirst = n; }
00323   inline void setHunger(int n)  { if(n<0)n=0; if(n>10)n=10; hunger = n; } 
00324   inline void setHp() { hp = ( getLevel() + 1 ) * getCharacter()->getStartingHp(); }
00325   inline void setMp() { mp = ( getLevel() + 1 ) * getCharacter()->getStartingMp(); }
00326 
00327   bool incSkillMod(int index);
00328   bool decSkillMod(int index);
00329   void applySkillMod();
00330   inline int getSkillMod(int index) { return skillMod[index]; }
00331   inline void setSkill(int index, int value) { skills[index] = value; }
00332   inline void setSkillBonus(int index, int value) { skillBonus[index] = value; }
00333   inline int getSkillBonus(int index) { return skillBonus[index]; }
00334   inline void setStateMod(int mod, bool setting) { 
00335     if(setting) stateMod |= (1 << mod);  
00336     else stateMod &= ((GLuint)0xffff - (GLuint)(1 << mod)); 
00337   }
00338   inline void setProtectedStateMod(int mod, bool setting) { 
00339     if(setting) protStateMod |= (1 << mod);  
00340     else protStateMod &= ((GLuint)0xffff - (GLuint)(1 << mod)); 
00341   }
00342 
00343   // return the initiative for a battle round (0-10), the lower the faster the attack
00344   // the method can return negative numbers if the weapon skill is very high (-10 to 10)
00345   int getInitiative(Item *weapon, Spell *spell=NULL);
00346 
00347   // roll the die for the toHit number. returns a value between 0(total miss) - 100(best hit)
00348   int getToHit(Item *weapon, int *maxToHit=NULL, int *rolledToHit=NULL);
00349 
00350   // get the armor value of the creature (0-100) (this is the max armor)
00351   inline int getArmor() { return armor; }
00352 
00353   // get the armor as modified by each item's assc. skill
00354   int getSkillModifiedArmor();
00355   
00356   // return the damage as:
00357   // rand(weapon + power + (skill - 50 % weapon))
00358   int getDamage(Item *weapon, int *maxDamage=NULL, int *rolledDamage=NULL);
00359 
00360   // take damage
00361   // return true if the creature dies
00362   bool takeDamage( int damage, int effect_type = Constants::EFFECT_GLOW, GLuint delay=0 );
00363 
00364   // returns exp gained
00365   int addExperience(Creature *creature_killed);
00366 
00367   int addExperience(int exp);
00368 
00369   // get angle to target creature
00370   float getTargetAngle();
00371 
00372   // returns coins gained
00373   int addMoney(Creature *creature_killed);
00374 
00375   void getDetailedDescription(char *s);
00376 
00377   // effects
00378   void startEffect( int effect_type, int duration = Constants::DAMAGE_DURATION, GLuint delay=0 );
00379   inline void setEffectType(int n) { this->effectType = n; }
00380   inline int getEffectType() { return effectType; }  
00381   inline Effect *getEffect() { return effect; }
00382   inline int getDamageEffect() { return damageEffectCounter; }
00383   inline void resetDamageEffect() { damageEffectCounter = SDL_GetTicks(); }
00384   inline bool isEffectOn() { return (SDL_GetTicks() - damageEffectCounter < effectDuration ? true : false); }
00385 
00386   inline int getAvailableSkillPoints() { return availableSkillPoints; }
00387   inline void setAvailableSkillPoints(int n) { availableSkillPoints = n; }
00388   
00389   int getMaxProjectileCount(Item *item);
00390 
00391   void usePotion(Item *item);
00392 
00393   inline void setBonusArmor(int n) { bonusArmor = n; if(bonusArmor < 0) bonusArmor = 0; recalcAggregateValues(); }
00394   inline int getBonusArmor() { return bonusArmor; }
00395 
00396   // FIXME: O(n) but there aren't that many spells...
00397   // return true if spell was added, false if creature already had this spell
00398   bool addSpell(Spell *spell);
00399   // FIXME: O(n) but there aren't that many spells...
00400   bool isSpellMemorized(Spell *spell);
00401   inline int getSpellCount() { return (int)spells.size(); }
00402   inline Spell *getSpell(int index) { return spells[index]; }
00403 
00404   void setAction(int action, Item *item=NULL, Spell *spell=NULL);
00405   inline int getAction() { return action; }
00406   inline Item *getActionItem() { return actionItem; }
00407   inline Spell *getActionSpell() { return actionSpell; }
00408 
00409 
00410 
00411   // handling battle targets (which in the future may be more than targetCreature)
00412   inline bool hasTarget() { return targetCreature || targetItem || targetX || targetY || targetZ; }
00413   bool isTargetValid();
00414   bool canAttack(Creature *creature);
00415   void cancelTarget();
00416   void followTarget();
00417   //void makeTargetRetaliate();
00418   void decideMonsterAction();
00419   float getDistanceToTarget();
00420 
00421 
00422   inline void setStateModEvent(int mod, Event *event) { stateModEventMap[mod] = event; }
00423   inline Event *getStateModEvent(int mod) { return(stateModEventMap.find(mod) == stateModEventMap.end() ? NULL : stateModEventMap[mod]); }
00424 
00425  protected:
00426 
00431   void getFormationPosition(Sint16 *px, Sint16 *py, Sint16 *pz);
00432 
00433   void commonInit();
00434   void calculateExpOfNextLevel();
00435   void monsterInit();
00436   void recalcAggregateValues();
00437 
00438   bool gotoPosition(Map *map, Sint16 px, Sint16 py, Sint16 pz, char *debug);
00439 
00444   GLfloat getStep();
00445 };
00446 
00447 
00448 #endif
00449 

Generated on Thu Jun 16 21:50:42 2005 for scourge by  doxygen 1.4.0