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