1 /* GemRB - Infinity Engine Emulator 2 * Copyright (C) 2003 The GemRB Project 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License 6 * as published by the Free Software Foundation; either version 2 7 * of the License, or (at your option) any later version. 8 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 * 18 * 19 */ 20 21 #ifndef ACTOR_H 22 #define ACTOR_H 23 24 #include "Scriptable/Scriptable.h" 25 26 #include "Scriptable/PCStatStruct.h" 27 28 #include "exports.h" 29 #include "ie_types.h" 30 31 #include "Audio.h" 32 #include "CombatInfo.h" 33 #include "EffectQueue.h" 34 #include "Palette.h" 35 #include "Polygon.h" 36 #include "Video.h" 37 38 #include <map> 39 #include <set> 40 #include <vector> 41 42 namespace GemRB { 43 44 class Animation; 45 class ArmorClass; 46 class CharAnimations; 47 class DataFileMgr; 48 class Map; 49 class ScriptedAnimation; 50 class StringBuffer; 51 class ToHitStats; 52 struct PolymorphCache; 53 54 } 55 56 /** USING DEFINITIONS AS DESCRIBED IN STATS.IDS */ 57 #include "ie_stats.h" 58 59 #include "Inventory.h" 60 #include "Spellbook.h" 61 62 namespace GemRB { 63 64 #define MAX_STATS 256 65 #define MAX_LEVEL 128 66 #define MAX_FEATS 96 //3*sizeof(ieDword) 67 68 //lucky roll 69 #define LR_CRITICAL 1 70 #define LR_DAMAGELUCK 2 71 #define LR_NEGATIVE 4 72 73 //modal states 74 #define MS_NONE 0 75 #define MS_BATTLESONG 1 76 #define MS_DETECTTRAPS 2 77 #define MS_STEALTH 3 78 #define MS_TURNUNDEAD 4 79 80 //stat modifier type 81 #define MOD_ADDITIVE 0 82 #define MOD_ABSOLUTE 1 83 #define MOD_PERCENT 2 84 #define MOD_MULTIPLICATIVE 3 85 #define MOD_DIVISIVE 4 86 #define MOD_MODULUS 5 87 #define MOD_LOGAND 6 88 #define MOD_LOGOR 7 89 #define MOD_BITAND 8 90 #define MOD_BITOR 9 91 #define MOD_INVERSE 10 92 93 //'do not jump' flags 94 #define DNJ_FIT 1 95 #define DNJ_UNHINDERED 2 96 #define DNJ_JUMP 4 97 #define DNJ_BIRD (DNJ_FIT|DNJ_UNHINDERED) 98 99 //add_animation flags (override vvc) 100 #define AA_PLAYONCE 1 101 #define AA_BLEND 2 102 103 //GetDialog flags 104 #define GD_NORMAL 0 105 #define GD_CHECK 1 106 #define GD_FEEDBACK 2 //(also check) 107 108 //Panic modes 109 #define PANIC_NONE 0 110 #define PANIC_BERSERK 1 111 #define PANIC_RUNAWAY 2 112 #define PANIC_RANDOMWALK 3 113 114 //Game Difficulty 115 #define DIFF_DEFAULT 0 116 #define DIFF_EASY 1 117 #define DIFF_NORMAL 2 118 #define DIFF_CORE 3 119 #define DIFF_HARD 4 120 #define DIFF_INSANE 5 121 #define DIFF_NIGHTMARE 6 // rather check against the ini var where needed 122 123 /** flags for GetActor */ 124 //default action 125 #define GA_DEFAULT 0 126 //actor selected for talk 127 #define GA_TALK 1 128 //actor selected for attack 129 #define GA_ATTACK 2 130 //actor selected for spell target 131 #define GA_SPELL 3 132 //actor selected for defend 133 #define GA_DEFEND 4 134 //actor selected for pick pockets 135 #define GA_PICK 5 136 //action mask 137 #define GA_ACTION 15 138 //unselectable actor may not be selected (can still block) 139 #define GA_SELECT 16 140 //dead actor may not be selected 141 #define GA_NO_DEAD 32 142 //any point could be selected (area effect) 143 #define GA_POINT 64 144 //hidden actor may not be selected 145 #define GA_NO_HIDDEN 128 146 //party members cannot be selected 147 #define GA_NO_ALLY 256 148 //only party members could be selected 149 #define GA_NO_ENEMY 512 150 // 151 #define GA_NO_NEUTRAL 1024 152 //cannot target self 153 #define GA_NO_SELF 2048 154 //try other areas too 155 //(unused and removed, see git history of the commit which 156 //added this comment for some clues if you really need it) 157 //#define GA_GLOBAL 4096 158 159 //line of sight is ignored (for GetAllActorsInRadius) 160 #define GA_NO_LOS 4096 161 162 // Detect() mode: IDS matching ignores invisibility 163 #define GA_DETECT 8192 164 //cannot target unscheduled actors 165 #define GA_NO_UNSCHEDULED 16384 166 167 #define GA_ONLY_BUMPABLE 32768 168 #define GA_CAN_BUMP 65536 169 170 #define VCONST_COUNT 100 171 172 //interact types 173 #define I_NONE 0 174 #define I_INSULT 1 175 #define I_COMPLIMENT 2 176 #define I_SPECIAL 3 177 #define I_INSULT_RESP 4 178 #define I_COMPL_RESP 5 179 #define I_DIALOG 6 180 181 //flags for UseItem 182 #define UI_SILENT 1 //no sound when used up 183 #define UI_MISS 2 //ranged miss (projectile has no effects) 184 #define UI_CRITICAL 4 //a critical hit happened 185 #define UI_FAKE 8 //deplete the item but don't actually apply its effects 186 #define UI_NOAURA 16 //ignore spellcasting aura checks 187 #define UI_NOCHARGE 32 //don't deplete the item 188 189 //used to mask off current profs 190 #define PROFS_MASK 0x07 191 192 //locations of classes in the isclass/levelslots arrays 193 #define ISFIGHTER 0 194 #define ISMAGE 1 195 #define ISTHIEF 2 196 #define ISBARBARIAN 3 197 #define ISBARD 4 198 #define ISCLERIC 5 199 #define ISDRUID 6 200 #define ISMONK 7 201 #define ISPALADIN 8 202 #define ISRANGER 9 203 #define ISSORCERER 10 204 #define ISCLASS12 11 205 #define ISCLASS13 12 206 207 #define ISCLASSES 13 208 209 //appearance flags 210 211 #define APP_HALFTRANS 2 //half transparent 212 #define APP_DEATHVAR 16 //set death variable 213 #define APP_DEATHTYPE 32 //count creature type deaths 214 #define APP_ADDKILL 64 //prepend KILL_ to the creature type 215 #define APP_FACTION 128 //count killed faction 216 #define APP_TEAM 0x100 //count killed team 217 #define APP_INVULNERABLE 0x200 //invulnerable 218 #define APP_GOOD 0x400 //good count 219 #define APP_LAW 0x800 //law count 220 #define APP_LADY 0x1000 //lady count 221 #define APP_MURDER 0x2000 //murder count 222 #define APP_NOTURN 0x4000 //doesn't face gabber in dialogue 223 #define APP_BUDDY 0x8000 // unused; supposedly: npcs will turn hostile if this one dies 224 #define APP_DEAD 0x40000000 //used by the engine to prevent dying twice 225 226 #define DC_GOOD 0 227 #define DC_LAW 1 228 #define DC_LADY 2 229 #define DC_MURDER 3 230 231 // used for distinguishing damage immunity from high damage resistance 232 #define DR_IMMUNE 999999 233 234 // wild surge target change type 235 #define WSTC_SETTYPE 1 // change to this target type 236 #define WSTC_ADDTYPE 2 // affect also this target type 237 #define WSTC_RANDOMIZE 3 // choose a random target 238 struct WildSurgeSpellMods { 239 unsigned int num_castings; // number of times to cast 240 unsigned int num_wildrolls; // number of times to roll 241 unsigned int projectile_id; // new projectile id 242 unsigned int target_change_type; // settype, addtype, randomize 243 unsigned int target_type; // type to use when target_change_type is not WSTC_RANDOMIZE 244 unsigned int projectile_speed_mod; // factor in percents 245 int saving_throw_mod; 246 }; 247 248 typedef ieByte ActionButtonRow[GUIBT_COUNT]; 249 struct ActionButtonRow2 { 250 ActionButtonRow buttons; 251 ieByte clss; 252 }; 253 254 struct WeaponInfo { 255 int slot; 256 ieDword enchantment; 257 unsigned int range; 258 ieDword itemtype; 259 ieDword itemflags; 260 ieDword prof; 261 bool backstabbing; 262 ieDword wflags; 263 int critmulti; //critical hit multiplier (usually 2) 264 int critrange; // the lower value of the critical range (eg. 19 in 19-20/x3) 265 int profdmgbon; 266 int launcherdmgbon; WeaponInfoWeaponInfo267 WeaponInfo(): slot(0), enchantment(0), range(0), itemtype(0), itemflags(0), prof(0), backstabbing(false), wflags(0), critmulti(0), critrange(0), profdmgbon(0), launcherdmgbon(0) {}; 268 }; 269 270 struct BABTable { 271 ieDword level; 272 int bab; // basic attack bonus 273 int apr; // attacks per round 274 }; 275 276 struct ModalStatesStruct { 277 ieResRef spell; 278 char action[16]; 279 unsigned int entering_str; 280 unsigned int leaving_str; 281 unsigned int failed_str; 282 unsigned int aoe_spell; 283 unsigned int repeat_msg; 284 }; 285 286 struct ModalState { 287 ieDword State; 288 ieResRef Spell; //apply this spell once per round 289 ieResRef LingeringSpell; //apply this spell once per round if the effects are lingering 290 char LingeringCount; //the count of rounds for which the modal spell will be reapplied after the state ends 291 ieDword LastApplyTime; //last time the modal effect used 292 bool FirstApply; //running for the first time? 293 }; 294 295 extern void ReleaseMemoryActor(); 296 GEM_EXPORT void UpdateActorConfig(); //call this from guiscripts when some variable has changed 297 298 bool VVCSort(const ScriptedAnimation* lhs, const ScriptedAnimation* rhs); 299 using vvcSet = std::multiset<ScriptedAnimation*, decltype(VVCSort)*>; 300 using vvcDict = std::multimap<ResRef, ScriptedAnimation*>; 301 302 class GEM_EXPORT Actor : public Movable { 303 public: 304 //CRE DATA FIELDS 305 ieDword BaseStats[MAX_STATS]; 306 ieDword Modified[MAX_STATS]; 307 ieDword *PrevStats; 308 ieByteSigned DeathCounters[4]; //PST specific (good, law, lady, murder) 309 310 ieResRef BardSong; //custom bard song (updated by fx) 311 ieResRef BackstabResRef; //apply on successful backstab 312 313 PCStatsStruct* PCStats; 314 ieResRef SmallPortrait; 315 ieResRef LargePortrait; 316 /** 0: NPC, 1-8 party slot */ 317 ieByte InParty; 318 //32 is the maximum possible length of the actor name in the original games 319 char LongName[33], ShortName[33]; 320 ieStrRef ShortStrRef, LongStrRef; 321 ieStrRef StrRefs[VCONST_COUNT]; 322 323 ieDword AppearanceFlags; 324 325 ieVariable KillVar; //this second field is present in pst, iwd1 and iwd2 326 ieVariable IncKillVar; // iwd1, iwd2 327 328 ieByte SetDeathVar, IncKillCount, UnknownField; // boolean fields from iwd1 and iwd2 329 330 Inventory inventory; 331 Spellbook spellbook; 332 //savefile version (creatures embedded in area) 333 int version; 334 //in game or area actor header 335 ieDword TalkCount; 336 ieDword RemovalTime; 337 //FIXME: this is definitely not the same in bg2, in bg2 there are joinable npcs 338 //which keep a matrix of counters 339 ieDword InteractCount; //this is accessible in iwd2, probably exists in other games too 340 ieDword appearance; 341 ArmorClass AC; 342 ToHitStats ToHit; 343 ModalState Modal; 344 345 ieDword LastExit; //the global ID of the exit to be used 346 ieVariable UsedExit; // name of the exit, since global id is not stable after loading a new area 347 ieResRef LastArea; 348 char ShieldRef[2]; 349 char HelmetRef[2]; 350 char WeaponRef[2]; 351 int WeaponType; 352 ieDword multiclass; 353 bool GotLUFeedback; 354 int WMLevelMod; 355 356 int LastDamageType; 357 int LastDamage; 358 Point FollowOffset;//follow lastfollowed at this offset 359 bool Spawned; //has been created by a spawn point 360 361 ieDword TargetDoor; 362 363 EffectQueue fxqueue; 364 365 vvcDict vfxDict; 366 vvcSet vfxQueue = vvcSet(VVCSort); // sorted so we can distinguish effects infront and behind 367 ieDword *projectileImmunity; //classic bitfield 368 Holder<SoundHandle> casting_sound; 369 ieDword roundTime; //these are timers for attack rounds 370 ieDword panicMode; //runaway, berserk or randomwalk 371 ieDword nextComment; //do something random (area comment, interaction) 372 ieDword nextBored; //do something when bored 373 int FatigueComplaintDelay; // stagger tired messages 374 ieDword lastInit; 375 //how many attacks left in this round, must be public for cleave opcode 376 int attackcount; 377 378 PolymorphCache *polymorphCache; // fx_polymorph etc 379 WildSurgeSpellMods wildSurgeMods; 380 ieByte DifficultyMargin; 381 ieDword *spellStates; 382 // set after modifying maxhp, adjusts hp next tick 383 int checkHP; 384 // to determine that a tick has passed 385 ieDword checkHPTime; 386 /** 387 * We don't know how to profit of them, but PST needs them saved. 388 * Otherwise, some actors are badly drawn, like TNO but not Morte. 389 * bit 0 for a "plasma" effect: palette color entries shift by one index position per cycle update 390 * bit 1 is for enabling pulsating for the particular color range (we store them in IE_COLOR*) 391 * it periodically reduces brightness to ~50% and back to full 392 */ 393 ieByte pstColorBytes[10]; 394 395 Region drawingRegion; 396 private: 397 //this stuff doesn't get saved 398 CharAnimations* anims; 399 400 using AnimationPart = std::pair<Animation*, PaletteHolder>; 401 struct { 402 std::vector<AnimationPart> anim; 403 std::vector<AnimationPart> shadow; 404 } currentStance; 405 406 ieByte SavingThrow[5]; 407 ieByte weapSlotCount; 408 int walkScale = 0; 409 // true when command has been played after select 410 bool playedCommandSound; 411 //true every second round of attack 412 bool secondround; 413 int attacksperround; 414 //time of our next attack 415 ieDword nextattack; 416 ieDword nextWalk; 417 ieDword lastattack; 418 //trap we're trying to disarm 419 ieDword disarmTrap; 420 ieDword InTrap; 421 char AttackStance; 422 /*The projectile bringing the current attack*/ 423 Projectile* attackProjectile ; 424 ieDword TicksLastRested; 425 ieDword LastFatigueCheck; 426 unsigned int remainingTalkSoundTime; 427 unsigned int lastTalkTimeCheckAt; 428 /** paint the actor itself. Called internally by Draw() */ 429 void DrawActorSprite(const Point& p, BlitFlags flags, 430 const std::vector<AnimationPart>& anims, const Color& tint) const; 431 432 /** fixes the palette */ 433 void SetupColors(); 434 /** debugging function, gets the scripting name of an actor referenced by a global ID */ 435 const char* GetActorNameByID(ieDword ID) const; 436 /* checks a weapon quick slot and resets it to fist if it is empty */ 437 void CheckWeaponQuickSlot(unsigned int which); 438 /* helper for usability checks */ 439 int CheckUsability(const Item *item) const; 440 /* Set up all the missing stats on load time, or after level up */ 441 void CreateDerivedStatsBG(); 442 /* Set up all the missing stats on load time, or after level up */ 443 void CreateDerivedStatsIWD2(); 444 /* Gets the given ISCLASS level */ 445 ieDword GetClassLevel (const ieDword isclass) const; 446 /* Returns true if the dual class is backwards */ 447 bool IsDualSwap() const; 448 /* returns the weapon proficiency stat of the actor */ 449 int GetProficiency(int proftype) const; 450 /** Re/Inits the Modified vector for PCs/NPCs */ 451 void RefreshPCStats(); 452 void RefreshHP(); 453 bool ShouldDrawCircle() const; 454 bool HasBodyHeat() const; 455 void SetupFistData() const; 456 void UpdateFatigue(); 457 int GetSneakAttackDamage(Actor *target, WeaponInfo &wi, int &multiplier, bool weaponImmunity); 458 int GetBackstabDamage(Actor *target, WeaponInfo &wi, int multiplier, int damage) const; 459 /** for IE_EXISTANCEDELAY */ 460 void PlayExistenceSounds(); 461 ieDword GetKitIndex (ieDword kit, ieDword baseclass=0) const; 462 char GetArmorCode() const; 463 const char* GetArmorSound() const; 464 465 bool AdvanceAnimations(); 466 void UpdateDrawingRegion(); 467 /* applies modal spell etc, if needed */ 468 void UpdateModalState(ieDword gameTime); 469 470 int CalculateSpeedFromRate(bool feedback) const; 471 int CalculateSpeedFromINI(bool feedback) const; 472 ieDword IncrementDeathVariable(Variables *vars, const char *format, const char *name, ieDword start = 0) const; 473 474 public: 475 Actor(void); 476 ~Actor(void) override; 477 /** releases memory */ 478 static void ReleaseMemory(); 479 /** sets game specific parameter (which stat should determine the fist weapon type */ 480 static void SetFistStat(ieDword stat); 481 /** sets game specific default data about action buttons */ 482 static void SetDefaultActions(int qslot, ieByte slot1, ieByte slot2, ieByte slot3); 483 /** prints useful information on console */ 484 void dump() const; 485 /** prints useful information to given buffer */ 486 void dump(StringBuffer&) const; 487 /** fixes the feet circle */ 488 void SetCircleSize(); 489 /** places the actor on the map */ 490 void SetMap(Map *map); 491 /** sets the actor's position, calculating with the nojump flag*/ 492 void SetPosition(const Point &nmptTarget, int jump, int radiusx = 0, int radiusy = 0, int size = -1); 493 /** you better use SetStat, this stuff is only for special cases*/ 494 void SetAnimationID(unsigned int AnimID); 495 /** returns the animations */ 496 CharAnimations* GetAnims() const; 497 /** returns the gender of actor for cg sound - illusions are tricky */ 498 ieDword GetCGGender() const; 499 /** some hardcoded effects in puppetmaster based on puppet type */ 500 void CheckPuppet(Actor *puppet, ieDword type); 501 /** Re/Inits the Modified vector */ 502 void RefreshEffects(EffectQueue *eqfx); 503 /** gets saving throws */ 504 void RollSaves(); 505 /** returns a saving throw */ 506 bool GetSavingThrow(ieDword type, int modifier, const Effect *fx = nullptr); 507 /** Returns true if the actor is targetable */ 508 bool ValidTarget(int ga_flags, const Scriptable *checker = NULL) const; 509 /** Clamps a stat value to the valid range for the respective stat */ 510 ieDword ClampStat(unsigned int StatIndex, ieDword Value) const; 511 /** Returns a Stat value */ 512 ieDword GetStat(unsigned int StatIndex) const; 513 /** Returns a safe Stat value, one, that is not partially computed */ 514 ieDword GetSafeStat(unsigned int StatIndex) const; 515 /** Sets a Stat Value (unsaved) */ 516 bool SetStat(unsigned int StatIndex, ieDword Value, int pcf); 517 /** Returns the difference */ 518 int GetMod(unsigned int StatIndex) const; 519 /** Returns a Stat Base Value */ 520 ieDword GetBase(unsigned int StatIndex) const; 521 /** Sets a Base Stat Value */ 522 bool SetBase(unsigned int StatIndex, ieDword Value); 523 bool SetBaseNoPCF(unsigned int StatIndex, ieDword Value); 524 /** set/resets a Base Stat bit */ 525 bool SetBaseBit(unsigned int StatIndex, ieDword Value, bool setreset); 526 /** Sets the modified value in different ways, returns difference */ 527 int NewStat(unsigned int StatIndex, ieDword ModifierValue, ieDword ModifierType); 528 /** Modifies the base stat value in different ways, returns difference */ 529 int NewBase(unsigned int StatIndex, ieDword ModifierValue, ieDword ModifierType); 530 void SetLeader(Actor *actor, int xoffset=0, int yoffset=0); 531 /** Sets the Icon ResRef */ 532 //Which - 0 both, 1 Large, 2 Small 533 void SetPortrait(const char* ResRef, int Which=0); 534 void SetSoundFolder(const char *soundset); 535 /* Use overrideSet to replace PCStats->SoundSet */ 536 void GetSoundFolder(char *soundset, int flag, ieResRef overrideSet = 0) const; 537 /** Gets the Character Long Name/Short Name */ GetName(int which)538 const char* GetName(int which) const override 539 { 540 if(which==-1) which=TalkCount; 541 if (which) { 542 return LongName; 543 } 544 return ShortName; 545 } 546 /** Gets the DeathVariable */ GetScriptName(void)547 const char* GetScriptName(void) const 548 { 549 return scriptName; 550 } 551 /** Gets a Script ResRef */ 552 const char* GetScript(int ScriptIndex) const; 553 /** Gets the Character's level for XP calculations */ 554 ieDword GetXPLevel(int modified) const; 555 /** Guesses the (base) casting level */ 556 ieDword GetCasterLevel(int spelltype); 557 ieDword GetBaseCasterLevel(int spelltype, int flags=0) const; 558 ieDword GetAnyActiveCasterLevel() const; 559 /** Returns the wild mage casting level modifier */ 560 int GetWildMod(int level); 561 /** Returns any casting level modifier */ 562 int CastingLevelBonus(int level, int type); 563 564 /** Gets the Dialog ResRef */ 565 const char* GetDialog(int flags=GD_NORMAL) const; 566 void SetDialog(const ieResRef resref); 567 /** Gets the Portrait */ 568 Holder<Sprite2D> CopyPortrait(int which) const; 569 570 /** Gets the attack projectile */ GetAttackProjectile()571 Projectile* GetAttackProjectile() 572 { 573 return attackProjectile; 574 } 575 void SetName(const char* ptr, unsigned char type); 576 void SetName(int strref, unsigned char type); 577 /* Returns by how much movement speed should be divided to account for loot weight */ 578 int GetEncumbranceFactor(bool feedback) const; 579 /* calculates speed, encumbrance etc */ 580 int CalculateSpeed(bool feedback) const; GetSpeed()581 int GetSpeed() const { return walkScale; } SetSpeed(bool feedback)582 void SetSpeed(bool feedback) { walkScale = CalculateSpeed(feedback); } 583 /* checks on death of actor, returns true if it should be removed*/ 584 bool CheckOnDeath(); 585 /* receives undead turning message */ 586 void Turn(Scriptable *cleric, ieDword turnlevel); 587 /* call this on gui selects */ 588 void PlaySelectionSound(); 589 /* play a roar if the setting isn't disabled */ 590 bool PlayWarCry(int range) const; 591 /* call this when adding actions via gui */ 592 void CommandActor(Action* action, bool clearPath=true); 593 /** handle panic and other involuntary actions that mess with scripting */ 594 bool OverrideActions(); 595 /** handle idle actions, that shouldn't mess with scripting */ 596 void IdleActions(bool nonidle); 597 /* sets the actor in panic (turn/morale break) */ 598 void Panic(const Scriptable *attacker, int panicmode); 599 /* sets a multi class flag (actually this is a lot of else too) */ 600 void SetMCFlag(ieDword bitmask, int op); 601 /* inlined dialogue start */ 602 void Interact(int type) const; 603 /* returns a remapped verbal constant strref */ 604 ieStrRef GetVerbalConstant(int index) const; 605 /* returns a random remapped verbal constant strref */ 606 ieStrRef GetVerbalConstant(int start, int count) const; 607 /* displaying a random verbal constant */ 608 bool VerbalConstant(int start, int count=1, int flags=0) const; 609 /* display string or verbal constant depending on what is available */ 610 void DisplayStringOrVerbalConstant(int str, int vcstat, int vccount=1) const; 611 /* inlined dialogue response */ 612 void Response(int type) const; 613 /* called when someone died in the party */ 614 bool HasSpecialDeathReaction(const char *deadname) const; 615 void ReactToDeath(const char *deadname); 616 /* sends trigger_died to everyone in visual range */ 617 void SendDiedTrigger() const; 618 /* called when someone talks to Actor */ 619 void DialogInterrupt() const; 620 /* called when actor was hit */ 621 void GetHit(int damage=0, int spellLevel=0); 622 /* checks whether taking damage should disrupt spellcasting */ 623 bool CheckSpellDisruption(int damage, int spellLevel) const; 624 /* called when actor starts to cast a spell*/ 625 bool HandleCastingStance(const ieResRef SpellResRef, bool deplete, bool instant); 626 /* check if the actor should be just knocked out by a lethal hit */ 627 bool AttackIsStunning(int damagetype) const; 628 /* check if the actor is silenced - for casting purposes */ 629 bool CheckSilenced() const; 630 /* check and perform a cleave movement */ 631 void CheckCleave(); 632 /* deals damage to this actor */ 633 int Damage(int damage, int damagetype, Scriptable *hitter, int modtype=MOD_ADDITIVE, int critical=0, int saveflags=0); 634 /* displays the damage taken and other details (depends on the game type) */ 635 void DisplayCombatFeedback (unsigned int damage, int resisted, int damagetype, Scriptable *hitter); 636 /* play a random footstep sound */ 637 void PlayWalkSound(); 638 /* play the proper hit sound (in pst) */ 639 void PlayHitSound(DataFileMgr *resdata, int damagetype, bool suffix) const; 640 void PlaySwingSound(WeaponInfo &wi) const; 641 /* drops items from inventory to current spot */ 642 void DropItem(const ieResRef resref, unsigned int flags); 643 void DropItem(int slot, unsigned int flags); 644 /* returns item information in quickitem slot */ 645 void GetItemSlotInfo(ItemExtHeader *item, int which, int header); 646 /* returns spell information in quickspell slot */ 647 void GetSpellSlotInfo(SpellExtHeader *spell, int which); 648 /* updates quickslots */ 649 void ReinitQuickSlots(); 650 /* actor is in trap */ 651 void SetInTrap(ieDword tmp); 652 /* sets some of the internal flags */ 653 void SetRunFlags(ieDword flags); IsRunning()654 bool IsRunning() const { return InternalFlags & IF_RUNFLAGS; } 655 /* applies the kit abilities, returns false if kit is not applicable */ 656 bool ApplyKit(bool remove, ieDword baseclass=0, int diff=0); 657 /* applies the class abilities*/ 658 void ApplyClab(const char *clab, ieDword max, int remove, int diff); 659 /* calls InitQuickSlot in PCStatStruct */ 660 void SetupQuickSlot(unsigned int which, int slot, int headerindex); 661 /* returns true if the actor is PC/joinable*/ 662 bool Persistent() const; 663 /* assigns actor to party slot, 0 = NPC, areas won't remove it */ 664 void SetPersistent(int partyslot); 665 /* resurrects actor */ 666 void Resurrect(const Point &destPoint); 667 /* removes actor in the next update cycle */ 668 void DestroySelf(); 669 /* schedules actor to die */ 670 void Die(Scriptable *killer, bool grantXP = true); 671 /* debug function */ 672 void GetNextAnimation(); 673 /* debug function */ 674 void GetPrevAnimation(); 675 /* debug function */ 676 void GetNextStance(); 677 void ClearCurrentStanceAnims(); 678 /* learns the given spell, possibly receive XP */ 679 int LearnSpell(const ieResRef resref, ieDword flags, int bookmask=-1, int level=-1); 680 /* returns the ranged weapon header associated with the currently equipped projectile */ 681 ITMExtHeader *GetRangedWeapon(WeaponInfo &wi) const; 682 /* Returns current weapon range and extended header 683 if range is nonzero, then which is valid */ 684 ITMExtHeader* GetWeapon(WeaponInfo &wi, bool leftorright=false) const; 685 /* Creates player statistics */ 686 void CreateStats(); 687 /* Heals actor */ 688 void Heal(int hp); 689 /* Receive experience (handle dual/multi class) */ 690 void AddExperience(int exp, int combat); 691 /* Calculate experience bonus */ 692 int CalculateExperience(int type, int level) const; 693 /* Sets the modal state after checks */ 694 void SetModal(ieDword newstate, bool force=1); 695 /* Sets the modal spell after checks */ 696 void SetModalSpell(ieDword state, const char *spell); 697 /* casts the modal spell if any */ 698 void ApplyModal(ieResRef modalSpell); 699 /* returns current attack style */ 700 int GetAttackStyle() const; 701 /* adds the combatants to the attackers list */ 702 void AttackedBy(const Actor *actor); 703 /* reorients to face target (for immediate attack) */ 704 void FaceTarget(Scriptable *actor); 705 /* returns the number of attacks (handles monk barehanded bonus) */ 706 ieDword GetNumberOfAttacks(); 707 /* starts combat round*/ 708 void InitRound(ieDword gameTime); 709 /* returns melee penalty */ 710 int MeleePenalty() const; 711 /* gets the to hit value */ 712 int GetToHit(ieDword Flags, const Actor *target); 713 void GetTHAbilityBonus(ieDword Flags); 714 /* gets the defense against an attack */ 715 int GetDefense(int DamageType, ieDword wflags, const Actor *attacker) const; 716 /* checks if something is wrong with the weapon we are using for the attack */ 717 bool WeaponIsUsable(bool leftorright, ITMExtHeader *header=NULL) const; 718 /* get the current hit bonus */ 719 bool GetCombatDetails(int &tohit, bool leftorright, WeaponInfo &wi, ITMExtHeader *&header, ITMExtHeader *&hittingheader,\ 720 int &DamageBonus, int &speed, int &CriticalBonus, int &style, const Actor *target); 721 /* performs attack against target */ 722 void PerformAttack(ieDword gameTime); 723 /* returns the adjusted weapon range, since items have odd values stored */ 724 int GetWeaponRange(const WeaponInfo &wi) const; 725 /* filter out any damage reduction that is cancelled by high weapon enchantment and return the resulting resistance */ 726 int GetDamageReduction(int resist_stat, ieDword weaponEnchantment) const; 727 /* calculates strength (dexterity) based damage adjustment */ 728 int WeaponDamageBonus(const WeaponInfo &wi) const; 729 /* handles critical, backstab, etc. damage modifications */ 730 void ModifyWeaponDamage(WeaponInfo &wi, Actor *target, int &damage, bool &critical); 731 /* adjusts damage dealt to this actor, handles mirror images */ 732 void ModifyDamage(Scriptable *hitter, int &damage, int &resisted, int damagetype); 733 /* returns the hp adjustment based on constitution */ 734 int GetHpAdjustment(int multiplier, bool modified=true) const; 735 /* does all the housekeeping after loading the actor from file */ 736 void InitStatsOnLoad(); 737 /* sets a colour gradient stat, handles location */ 738 void SetColor( ieDword idx, ieDword grd); 739 /* sets an RGB colour modification effect; location 0xff for global */ 740 void SetColorMod( ieDword location, RGBModifier::Type type, int speed, 741 const Color&, int phase = -1) const; 742 bool Schedule(ieDword gametime, bool checkhide) const; 743 void NewPath(); 744 /* overridden method, won't walk if dead */ 745 void WalkTo(const Point &Des, ieDword flags, int MinDistance = 0); 746 /* resolve string constant (sound will be altered) */ 747 void ResolveStringConstant(ieResRef& sound, unsigned int index) const; 748 bool GetSoundFromFile(ieResRef &Sound, unsigned int index) const; 749 bool GetSoundFromINI(ieResRef &Sound, unsigned int index) const; 750 bool GetSoundFrom2DA(ieResRef &Sound, unsigned int index) const; 751 /* generate area specific oneliner */ 752 void GetAreaComment(int areaflag) const; 753 /* handle oneliner interaction, -1: unsuccessful (may comment area), 0: dialog banter, 1: oneliner */ 754 int HandleInteract(const Actor *target) const; 755 /* start bg1-style banter dialog */ 756 void HandleInteractV1(const Actor *target); 757 /* generate party banter, return true if successful */ 758 bool GetPartyComment(); 759 /* sets the quick slots */ 760 void SetActionButtonRow(ActionButtonRow &ar); 761 /* updates the quick slots */ 762 void GetActionButtonRow(ActionButtonRow &qs); 763 /* converts the iwd2 qslot index to our internal representation */ 764 int IWD2GemrbQslot (int slotindex) const; 765 int Gemrb2IWD2Qslot(ieByte actslot, int slotindex) const; 766 void dumpQSlots() const; 767 768 /* Handling automatic stance changes */ 769 bool HandleActorStance(); 770 void UpdateActorState(); 771 /* update internal per frame state and return true if state is suitable for drawing the actor */ 772 bool UpdateDrawingState(); 773 Region DrawingRegion() const override; 774 uint8_t GetElevation() const; 775 bool ShouldDrawReticle() const; 776 void DoStep(unsigned int walkScale, ieDword time = 0) override; 777 void Draw(const Region &screen, Color baseTint, Color tint, BlitFlags flags) const; 778 779 /* add mobile vvc (spell effects) to actor's list */ 780 void AddVVCell(ScriptedAnimation* vvc); 781 /* remove a vvc from the list, graceful means animated removal */ 782 void RemoveVVCells(const ResRef& vvcname); 783 /* returns true if actor already has the overlay (slow) */ 784 bool HasVVCCell(const ResRef& resource) const; 785 /* returns overlay if actor already has it (slow) */ 786 std::pair<vvcDict::const_iterator, vvcDict::const_iterator> 787 GetVVCCells(const ResRef& resource) const; 788 /* returns the vvc pointer to a hardcoded overlay */ 789 /* if it exists (faster than hasvvccell) */ 790 ScriptedAnimation *FindOverlay(int index) const; 791 792 void SetLockedPalette(const ieDword *gradients); 793 void UnlockPalette(); 794 void AddAnimation(const ieResRef resource, int gradient, int height, int flags); 795 /* plays damage animation, if hit is not set, then plays only the splash part */ 796 void PlayDamageAnimation(int x, bool hit=true); 797 void PlayCritDamageAnimation(int x); 798 /* returns mage or cleric spell casting failure, iwd2 compatible */ 799 ieDword GetSpellFailure(bool arcana) const; 800 /* returns the dexterity AC adjusted by armor, iwd2 compatible */ 801 int GetDexterityAC() const; 802 /* returns the monk wisdom AC adjusted by armor (iwd2) */ 803 int GetWisdomAC() const; 804 /* PST specific criticals */ 805 int GetCriticalType() const; 806 /* restores a spell of maximum maxlevel level, type is a mask of disabled spells */ 807 int RestoreSpellLevel(ieDword maxlevel, ieDword typemask); 808 /* rememorizes spells, cures fatigue, etc */ 809 void Rest(int hours); 810 int GetConHealAmount() const; 811 /* returns the portrait icons list */ 812 const unsigned char *GetStateString() const; 813 /* adds a state icon to the list */ 814 void AddPortraitIcon(ieByte icon); 815 /* disables a state icon in the list, doesn't remove it! */ 816 void DisablePortraitIcon(ieByte icon); 817 /* returns which slot belongs to the quickweapon slot */ 818 int GetQuickSlot(int slot) const; 819 /* Sets equipped Quick slot, if header is -1, then use the current one */ 820 int SetEquippedQuickSlot(int slot, int header); 821 /* Uses an item on the target or point */ 822 bool UseItemPoint(ieDword slot, ieDword header, const Point &point, ieDword flags); 823 bool UseItem(ieDword slot, ieDword header, Scriptable *target, ieDword flags, int damage = 0); 824 /* Deducts a charge from an item */ 825 void ChargeItem(ieDword slot, ieDword header, CREItem *item, Item *itm, bool silent, bool expend = true); 826 /* If it returns true, then default AC=10 and the lesser the better */ 827 static int IsReverseToHit(); 828 /* initialize the action buttons based on class. If forced, it will override 829 previously customized or set buttons. */ 830 void InitButtons(ieDword cls, bool forced); 831 int GetMaxEncumbrance() const; 832 int GetAbilityBonus(unsigned int ability, int value = -1) const; 833 int GetSkillStat(unsigned int skill) const; 834 int GetSkill(unsigned int skill, bool ids=false) const; 835 int GetFeat(unsigned int feat) const; 836 void SetFeat(unsigned int feat, int mode); 837 void SetFeatValue(unsigned int feat, int value, bool init = true); 838 void SetUsedWeapon(const char (&AnimationType)[2], ieWord *MeleeAnimation, 839 int WeaponType=-1); 840 void SetUsedShield(const char (&AnimationType)[2], int WeaponType=-1); 841 void SetUsedHelmet(const char (&AnimationType)[2]); 842 void SetupFist(); 843 /* Returns nonzero if the caster is held */ 844 int Immobile() const; 845 /* Returns strref if the item is unusable due to name/type restrictions */ 846 ieStrRef Disabled(const ieResRef name, ieDword type) const; 847 /* Returns constant string if the item is unusable */ 848 int Unusable(const Item *item) const; 849 /* Sets all clown colour to the given gradient */ 850 void SetGradient(ieDword gradient); 851 /* Enables an overlay */ 852 void SetOverlay(unsigned int overlay); 853 /* Checks and sets a spellstate if it wasn't set yet */ 854 bool SetSpellState(unsigned int spellstate); 855 /* Checks a spellstate */ 856 bool HasSpellState(unsigned int spellstate) const; 857 /* Checks a feat */ 858 bool HasFeat(unsigned int featindex) const; 859 /* Reports projectile immunity, nonzero if immune */ 860 ieDword ImmuneToProjectile(ieDword projectile) const; 861 /* Sets projectile immunity */ 862 void AddProjectileImmunity(ieDword projectile); 863 /* Apply feats */ 864 void ApplyFeats(); 865 /* reapply modal feat spells */ 866 void ApplyExtraSettings(); 867 /* Set up all the missing stats on load time, chargen, or after level up */ 868 void CreateDerivedStats(); 869 /* Resets the internal multiclass bitfield */ 870 void ResetMC(); 871 /* Checks if the actor is multiclassed (excluding dualclassed actors)) */ 872 bool IsMultiClassed() const; 873 /* Checks if the actor is dualclassed */ 874 bool IsDualClassed() const; 875 /* Returns an exact copy of this actor */ 876 Actor *CopySelf(bool mislead) const; 877 static ieDword GetClassID (const ieDword isclass); 878 const char *GetClassName(ieDword classID) const; 879 const char *GetKitName(ieDword kitID) const; 880 /* Returns the actor's level of the given class */ GetFighterLevel()881 ieDword GetFighterLevel() const { return GetClassLevel(ISFIGHTER); } GetMageLevel()882 ieDword GetMageLevel() const { return GetClassLevel(ISMAGE); } GetThiefLevel()883 ieDword GetThiefLevel() const { return GetClassLevel(ISTHIEF); } GetBarbarianLevel()884 ieDword GetBarbarianLevel() const { return GetClassLevel(ISBARBARIAN); } GetBardLevel()885 ieDword GetBardLevel() const { return GetClassLevel(ISBARD); } GetClericLevel()886 ieDword GetClericLevel() const { return GetClassLevel(ISCLERIC); } GetDruidLevel()887 ieDword GetDruidLevel() const { return GetClassLevel(ISDRUID); } GetMonkLevel()888 ieDword GetMonkLevel() const { return GetClassLevel(ISMONK); } GetPaladinLevel()889 ieDword GetPaladinLevel() const { return GetClassLevel(ISPALADIN); } GetRangerLevel()890 ieDword GetRangerLevel() const { return GetClassLevel(ISRANGER); } GetSorcererLevel()891 ieDword GetSorcererLevel() const { return GetClassLevel(ISSORCERER); } 892 /* Returns true if the character is a warrior */ 893 ieDword GetWarriorLevel() const; IsWarrior()894 bool IsWarrior() const { return (GetFighterLevel()||GetBarbarianLevel()||GetRangerLevel()||GetPaladinLevel()); } 895 /* Returns true if the old class is inactive */ 896 bool IsDualInactive() const; 897 /* true if we are dual-wielding */ 898 int IsDualWielding() const; 899 int GetFavoredPenalties() const; 900 bool BlocksSearchMap() const override; 901 bool CannotPassEntrance(ieDword exitID) const; 902 void UseExit(ieDword exitID); 903 //int GetReaction() const; 904 /* Similar to Roll, but takes luck into account */ 905 int LuckyRoll(int dice, int size, int add, ieDword flags=LR_CRITICAL, Actor* opponent=NULL) const; 906 /* removes normal invisibility (type 0) */ 907 void CureInvisibility(); 908 /* removes sanctuary */ 909 void CureSanctuary(); 910 /* resets the invisibility, sanctuary and modal states */ 911 void ResetState(); 912 /* checks whether the actor is behind the target */ 913 bool IsBehind(Actor* target) const; 914 /* checks whether the target is the actor's racial enemy */ 915 int GetRacialEnemyBonus(const Actor *target) const; 916 /* checks whether the actor can stay in the current modal state */ 917 bool ModalSpellSkillCheck(); 918 /* check if this actor is seen by or seeing anyone */ 919 bool SeeAnyOne(bool enemy, bool seen) const; 920 /* does all the game logic checks to see if the actor can hide */ 921 bool TryToHide(); 922 bool TryToHideIWD2(); 923 /* checks if the alignment matches one of the masking constants */ 924 //bool MatchesAlignmentMask(ieDword mask); 925 /** untargetable by spells/attack due to invisibility or sanctuary */ 926 bool Untargetable(ieResRef spellRef) const; 927 /* returns true if this it is futile to try to harm actor (dead/sanctuaried) */ 928 bool InvalidSpellTarget() const; 929 /* returns true if the spell is useless to cast on target 930 or the spell's range is smaller than range */ 931 bool InvalidSpellTarget(int spellnum, Actor *caster, int range) const; 932 /* function to get a class level used by scripting */ 933 ieDword GetLevelInClass (const ieDword classid) const; 934 /* computes the actor's classmask (iwd2) */ 935 int GetClassMask() const; 936 /* computes the actor's usable books (iwd2) */ 937 int GetBookMask() const; 938 /* computes the thieving skill bonus from race and dexterity */ 939 int GetSkillBonus(unsigned int col) const; 940 /* returns true for party members (and familiars) */ 941 bool IsPartyMember() const; 942 /* resets the bored and area comment timers */ 943 void ResetCommentTime(); 944 /* returns the armor check penalty */ 945 int GetArmorSkillPenalty(int profcheck=1) const; 946 int GetArmorSkillPenalty(int profcheck, int &armor, int &shield) const; 947 int GetArmorWeightClass(ieWord armorType) const; 948 int GetTotalArmorFailure() const; 949 int GetArmorFailure(int &armor, int &shield) const; 950 bool IsDead() const; 951 bool IsInvisibleTo(const Scriptable *checker) const; 952 int UpdateAnimationID(bool derived); 953 void MovementCommand(char *command); 954 /* shows hp/maxhp as overhead text */ 955 bool HasVisibleHP() const; 956 void DisplayHeadHPRatio(); 957 /* if Lasttarget is gone, call this */ 958 void StopAttack(); 959 int SetBaseAPRandAB(bool CheckRapidShot); 960 int BAB2APR(int pBAB, int pBABDecrement, int CheckRapidShot) const; 961 /* set to trap id if current action is disarm; unset after */ SetDisarmingTrap(ieDword trapId)962 void SetDisarmingTrap(ieDword trapId) { disarmTrap = trapId; } GetDisarmingTrap()963 ieDword GetDisarmingTrap() const { return disarmTrap; } 964 void ReleaseCurrentAction() override; 965 bool ConcentrationCheck() const; 966 void ApplyEffectCopy(Effect *oldfx, EffectRef &newref, Scriptable *Owner, ieDword param1, ieDword param2); GetLastRested()967 ieDword GetLastRested() { return TicksLastRested; } IncreaseLastRested(int inc)968 void IncreaseLastRested(int inc) { TicksLastRested += inc; LastFatigueCheck += inc; } 969 bool WasClass(ieDword oldClassID) const; 970 ieDword GetActiveClass() const; 971 bool IsKitInactive() const; 972 const char* GetRaceName() const; 973 unsigned int GetSubRace() const; 974 std::list<int> ListLevels() const; 975 void ChangeSorcererType (ieDword classIdx); 976 unsigned int GetAdjustedTime(unsigned int time) const; 977 void SetAnimatedTalking(unsigned int); 978 bool HasPlayerClass() const; 979 void PlayArmorSound() const; 980 bool ShouldModifyMorale() const; 981 bool HibernateIfAble(); 982 }; 983 } 984 985 #endif 986