00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
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
00026 #include <vector>
00027 #include <map>
00028 #include <algorithm>
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
00063 #define MAX_FAILED_MOVE_ATTEMPTS 10
00064
00065 class Creature {
00066
00067 private:
00068
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;
00091 map<int, Event*> stateModEventMap;
00092 GLfloat angle, wantedAngle, angleStep;
00093 int portraitTextureIndex;
00094
00095
00096 Item *inventory[MAX_INVENTORY_SIZE];
00097 int inventory_count;
00098 int equipped[Constants::INVENTORY_COUNT];
00099
00100
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
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
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
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
00260
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
00272 bool addInventory(Item *item, bool force=false);
00273 Item *removeInventory(int index);
00274 int findInInventory(Item *item);
00275
00276 bool eatDrink(int index);
00277 bool eatDrink(Item *item);
00278 bool computeNewItemWeight(RpgItem * rpgItem);
00279
00280 void equipInventory(int index);
00281 int doff(int index);
00282
00283 int getEquippedIndex(int index);
00284 bool isItemInInventory(Item *item);
00285
00286 Item *getItemAtLocation(int location);
00287 bool isEquipped( Item *item );
00288 bool isEquipped( int inventoryIndex );
00289 bool removeCursedItems();
00290
00291
00292
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
00344
00345 int getInitiative(Item *weapon, Spell *spell=NULL);
00346
00347
00348 int getToHit(Item *weapon, int *maxToHit=NULL, int *rolledToHit=NULL);
00349
00350
00351 inline int getArmor() { return armor; }
00352
00353
00354 int getSkillModifiedArmor();
00355
00356
00357
00358 int getDamage(Item *weapon, int *maxDamage=NULL, int *rolledDamage=NULL);
00359
00360
00361
00362 bool takeDamage( int damage, int effect_type = Constants::EFFECT_GLOW, GLuint delay=0 );
00363
00364
00365 int addExperience(Creature *creature_killed);
00366
00367 int addExperience(int exp);
00368
00369
00370 float getTargetAngle();
00371
00372
00373 int addMoney(Creature *creature_killed);
00374
00375 void getDetailedDescription(char *s);
00376
00377
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
00397
00398 bool addSpell(Spell *spell);
00399
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
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
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