ScummVM API documentation
actor.h
1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program. If not, see <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 #ifndef WORLD_ACTORS_ACTOR_H
23 #define WORLD_ACTORS_ACTOR_H
24 
25 #include "ultima/ultima8/world/container.h"
26 #include "ultima/ultima8/usecode/intrinsics.h"
27 #include "ultima/ultima8/world/actors/animation.h"
28 
29 namespace Ultima {
30 namespace Ultima8 {
31 
32 class ActorAnimProcess;
33 struct PathfindingState;
34 class CombatProcess;
35 class AttackProcess;
36 
37 class Actor : public Container {
38  friend class ActorAnimProcess;
39  friend class AnimationTracker;
40 public:
41  Actor();
42  ~Actor() override;
43 
44  int16 getStr() const {
45  return _strength;
46  }
47  void setStr(int16 str) {
48  _strength = str;
49  }
50  int16 getDex() const {
51  return _dexterity;
52  }
53  void setDex(int16 dex) {
54  _dexterity = dex;
55  }
56  int16 getInt() const {
57  return _intelligence;
58  }
59  void setInt(int16 intl) {
60  _intelligence = intl;
61  }
62  uint16 getHP() const {
63  return _hitPoints;
64  }
65  void setHP(uint16 hp) {
66  _hitPoints = hp;
67  }
68  int16 getMana() const {
69  return _mana;
70  }
71  void setMana(int16 mp) {
72  _mana = mp;
73  }
74 
75  int16 getMaxMana() const;
76  uint16 getMaxHP() const;
77 
78  bool isDead() const {
79  return (_actorFlags & ACT_DEAD) != 0;
80  }
81 
82  bool isInCombat() const {
83  return (_actorFlags & ACT_INCOMBAT) != 0;
84  }
85 
86  bool isKneeling() const {
87  return (_actorFlags & ACT_KNEELING) != 0;
88  }
89 
90  bool isFalling() const;
91 
92  CombatProcess *getCombatProcess() const; // in U8
93  AttackProcess *getAttackProcess() const; // in Crusader
94  virtual void setInCombat(int activity);
95  virtual void clearInCombat();
96 
97  uint16 getAlignment() const {
98  return _alignment;
99  }
100  void setAlignment(uint16 a) {
101  _alignment = a;
102  }
103  uint16 getEnemyAlignment() const {
104  return _enemyAlignment;
105  }
106  void setEnemyAlignment(uint16 a) {
107  _enemyAlignment = a;
108  }
109 
110  Animation::Sequence getLastAnim() const {
111  return _lastAnim;
112  }
113  void setLastAnim(Animation::Sequence anim) {
114  _lastAnim = anim;
115  }
116  Direction getDir() const {
117  return _direction;
118  }
119  void setDir(Direction dir) {
120  _direction = dir;
121  }
122  int32 getFallStart() const {
123  return _fallStart;
124  }
125  void setFallStart(int32 zp) {
126  _fallStart = zp;
127  }
128  void setUnkByte(uint8 b) {
129  _unkByte = b;
130  }
131  uint8 getUnkByte() const {
132  return _unkByte;
133  }
134 
135  bool hasActorFlags(uint32 flags) const {
136  return (_actorFlags & flags) != 0;
137  }
138  void setActorFlag(uint32 mask) {
139  _actorFlags |= mask;
140  if (mask & ACT_KNEELING)
141  _cachedShapeInfo = nullptr;
142  }
143  void clearActorFlag(uint32 mask) {
144  _actorFlags &= ~mask;
145  if (mask & ACT_KNEELING)
146  _cachedShapeInfo = nullptr;
147  }
148 
149  void setCombatTactic(int no) {
150  _combatTactic = no;
151  }
152 
156  bool loadMonsterStats();
157 
160  bool giveTreasure();
161 
162  virtual void teleport(int mapnum, int32 x, int32 y, int32 z);
163 
164  bool removeItem(Item *item) override;
165 
167  uint16 schedule(uint32 time);
168 
169  bool setEquip(Item *item, bool checkwghtvol = false);
170  uint16 getEquip(uint32 type) const;
171 
172  virtual uint32 getArmourClass() const;
173  virtual uint16 getDefenseType() const;
174  virtual int16 getAttackingDex() const;
175  virtual int16 getDefendingDex() const;
176 
177  uint16 getDamageType() const override;
178  virtual int getDamageAmount() const;
179 
180  void setDefaultActivity(int no, uint16 activity);
181  uint16 getDefaultActivity(int no) const;
182 
183  void setHomePosition(int32 x, int32 y, int32 z);
184  void getHomePosition(int32 &x, int32 &y, int32 &z) const;
185 
191  int calculateAttackDamage(uint16 other, int damage, uint16 type);
192 
196  void receiveHit(uint16 other, Direction dir, int damage, uint16 type) override;
197 
203  virtual ProcId die(uint16 damageType, uint16 damagePts, Direction srcDir);
204 
207 
210  ProcId killAllButFallAnims(bool death);
211 
213  bool areEnemiesNear();
214 
217  uint16 setActivity(int activity);
218 
219  uint16 getCurrentActivityNo() const {
220  return _currentActivityNo;
221  }
222 
223  uint16 getLastActivityNo() const {
224  return _lastActivityNo;
225  }
226 
227  void clearLastActivityNo() {
228  _lastActivityNo = 0;
229  }
230 
231  int32 getLastTickWasHit() const {
232  return _lastTickWasHit;
233  }
234 
237  uint16 doAnim(Animation::Sequence anim, Direction dir, unsigned int steps = 0);
238 
242  uint16 doAnimAfter(Animation::Sequence anim, Direction dir, ProcId waitfor);
243 
245  bool hasAnim(Animation::Sequence anim);
246 
249  void setToStartOfAnim(Animation::Sequence anim);
250 
258  Animation::Result tryAnim(Animation::Sequence anim, Direction dir, unsigned int steps = 0, PathfindingState *state = 0);
259 
261  DirectionMode animDirMode(Animation::Sequence anim) const;
262 
264  bool isBusy() const;
265 
267  int32 collideMove(int32 x, int32 y, int32 z, bool teleport, bool force,
268  ObjId *hititem = 0, uint8 *dirs = 0) override;
269 
273  uint16 turnTowardDir(Direction dir, ProcId prevpid = 0);
274 
276  static Actor *createActor(uint32 shape, uint32 frame);
277 
278  uint16 assignObjId() override; // assign an NPC objid
279 
280  Common::String dumpInfo() const override;
281 
282  bool loadData(Common::ReadStream *rs, uint32 version);
283  void saveData(Common::WriteStream *ws) override;
284 
286  virtual int receiveShieldHit(int damage, uint16 damage_type) {
287  return damage;
288  }
289 
290  uint16 getActiveWeapon() const {
291  return _activeWeapon;
292  }
293 
294  uint16 getCombatTactic() const {
295  return _combatTactic;
296  }
297 
298  bool activeWeaponIsSmall() const;
299 
301  void tookHitCru();
302 
304  bool canSeeControlledActor(bool forcombat);
305 
307  void addFireAnimOffsets(int32 &x, int32 &y, int32 &z);
308 
309  uint32 getAttackMoveTimeoutFinishFrame() const {
311  }
312 
313  uint16 getAttackMoveDodgeFactor() const {
314  return _attackMoveDodgeFactor;
315  }
316 
317  bool getAttackAimFlag() const {
318  return _attackAimFlag;
319  }
320 
321  void setAttackAimFlag(bool val) {
322  _attackAimFlag = val;
323  }
324 
325  ENABLE_RUNTIME_CLASSTYPE()
326 
327  INTRINSIC(I_isNPC);
328  INTRINSIC(I_getDir);
329  INTRINSIC(I_getLastAnimSet);
330  INTRINSIC(I_pathfindToItem);
331  INTRINSIC(I_pathfindToPoint);
332  INTRINSIC(I_getStr);
333  INTRINSIC(I_getDex);
334  INTRINSIC(I_getInt);
335  INTRINSIC(I_getHp);
336  INTRINSIC(I_getMaxHp);
337  INTRINSIC(I_getMana);
338  INTRINSIC(I_getAlignment);
339  INTRINSIC(I_getEnemyAlignment);
340  INTRINSIC(I_setStr);
341  INTRINSIC(I_setDex);
342  INTRINSIC(I_setInt);
343  INTRINSIC(I_setHp);
344  INTRINSIC(I_setMana);
345  INTRINSIC(I_setAlignment);
346  INTRINSIC(I_setEnemyAlignment);
347  INTRINSIC(I_getMap);
348  INTRINSIC(I_addHp);
349  INTRINSIC(I_teleport);
350  INTRINSIC(I_doAnim);
351  INTRINSIC(I_isInCombat);
352  INTRINSIC(I_setInCombat);
353  INTRINSIC(I_clrInCombat);
354  INTRINSIC(I_setTarget);
355  INTRINSIC(I_getTarget);
356  INTRINSIC(I_isEnemy);
357  INTRINSIC(I_isDead);
358  INTRINSIC(I_setDead);
359  INTRINSIC(I_clrDead);
360  INTRINSIC(I_isImmortal);
361  INTRINSIC(I_setImmortal);
362  INTRINSIC(I_clrImmortal);
363  INTRINSIC(I_isWithstandDeath);
364  INTRINSIC(I_setWithstandDeath);
365  INTRINSIC(I_clrWithstandDeath);
366  INTRINSIC(I_isFeignDeath);
367  INTRINSIC(I_setFeignDeath);
368  INTRINSIC(I_clrFeignDeath);
369  INTRINSIC(I_areEnemiesNear);
370  INTRINSIC(I_isBusy);
371  INTRINSIC(I_createActor);
372  INTRINSIC(I_createActorCru);
373  INTRINSIC(I_setActivity);
374  INTRINSIC(I_setAirWalkEnabled);
375  INTRINSIC(I_getAirWalkEnabled);
376  INTRINSIC(I_schedule);
377  INTRINSIC(I_getEquip);
378  INTRINSIC(I_setEquip);
379  INTRINSIC(I_setDefaultActivity0);
380  INTRINSIC(I_setDefaultActivity1);
381  INTRINSIC(I_setDefaultActivity2);
382  INTRINSIC(I_getDefaultActivity0);
383  INTRINSIC(I_getDefaultActivity1);
384  INTRINSIC(I_getDefaultActivity2);
385  INTRINSIC(I_setCombatTactic);
386  INTRINSIC(I_setUnkByte);
387  INTRINSIC(I_getUnkByte);
388  INTRINSIC(I_getLastActivityNo);
389  INTRINSIC(I_getCurrentActivityNo);
390  INTRINSIC(I_turnToward);
391  INTRINSIC(I_isKneeling);
392  INTRINSIC(I_isFalling);
393 
394  enum ActorFlags {
395  ACT_INVINCIBLE = 0x000001, // flags from npcdata byte 0x1B
396  ACT_ASCENDING = 0x000002,
397  ACT_DESCENDING = 0x000004,
398  ACT_ANIMLOCK = 0x000008,
399 
400  ACT_KNEELING = 0x000100, // not the same bit used in Crusader, but use this because it's empty.
401  ACT_FIRSTSTEP = 0x000400, // flags from npcdata byte 0x2F
402  ACT_INCOMBAT = 0x000800,
403  ACT_DEAD = 0x001000,
404  ACT_SURRENDERED = 0x002000, // not the same bit used in Crusader, but use this because it's empty.
405  ACT_WEAPONREADY = 0x004000, // not the same bit used in Crusader, but use this because it's empty.
406  ACT_COMBATRUN = 0x008000,
407 
408  ACT_AIRWALK = 0x010000, // flags from npcdata byte 0x30
409  ACT_IMMORTAL = 0x040000,
410  ACT_WITHSTANDDEATH = 0x080000,
411  ACT_FEIGNDEATH = 0x100000,
412  ACT_STUNNED = 0x200000,
413  ACT_POISONED = 0x400000,
414  ACT_PATHFINDING = 0x800000
415  };
416 
417 protected:
418  int16 _strength;
419  int16 _dexterity;
420  int16 _intelligence;
421  uint16 _hitPoints;
422  int16 _mana;
423 
424  uint16 _alignment, _enemyAlignment;
425 
426  Animation::Sequence _lastAnim;
427  uint16 _animFrame;
428  Direction _direction;
429 
430  int32 _fallStart;
431 
434  uint8 _unkByte;
435 
438 
439  uint32 _actorFlags;
440 
442  uint16 _defaultActivity[3];
443 
445  int32 _homeX;
446  int32 _homeY;
447  int32 _homeZ;
448 
451  uint16 _lastActivityNo;
452 
455 
458 
467 
470 
473  uint16 setActivityU8(int activity);
474 
477  uint16 setActivityCru(int activity);
478 
479  bool loadMonsterStatsU8();
480  bool loadMonsterStatsCru();
481 
482  void receiveHitU8(uint16 other, Direction dir, int damage, uint16 type);
483  void receiveHitCru(uint16 other, Direction dir, int damage, uint16 type);
484 
485  void setInCombatU8();
486  void setInCombatCru(int activity);
487 
488  ProcId dieU8(uint16 damageType);
489  ProcId dieCru(uint16 damageType, uint16 damagePts, Direction srcDir);
490 };
491 
492 } // End of namespace Ultima8
493 } // End of namespace Ultima
494 
495 #endif
Definition: str.h:59
virtual int receiveShieldHit(int damage, uint16 damage_type)
take a hit and optionally adjust it with the shields for this NPC.
Definition: actor.h:286
int32 _lastTickWasHit
Kernel timer last time NPC was hit (only used in Crusader)
Definition: actor.h:457
uint16 assignObjId() override
Definition: stream.h:77
int32 _homeX
The "home" position used in some Crusader attack tactics.
Definition: actor.h:445
ProcId killAllButFallAnims(bool death)
Definition: item.h:42
uint16 turnTowardDir(Direction dir, ProcId prevpid=0)
static Actor * createActor(uint32 shape, uint32 frame)
create an actor, assign objid, make it ethereal and load monster stats.
Definition: actor_anim_process.h:38
uint16 setActivityU8(int activity)
virtual ProcId die(uint16 damageType, uint16 damagePts, Direction srcDir)
Common::String dumpInfo() const override
dump some info about this object to a string
uint16 setActivityCru(int activity)
int calculateAttackDamage(uint16 other, int damage, uint16 type)
uint16 getDamageType() const override
get the damage type this object does when hitting something
Definition: detection.h:27
DirectionMode animDirMode(Animation::Sequence anim) const
Get the number of directions supported by a given animation.
uint32 _attackMoveTimeout
The number of frames the above effect lasts for.
Definition: actor.h:463
void addFireAnimOffsets(int32 &x, int32 &y, int32 &z)
Add the x/y/z fire offsets given the current state of the actor.
uint16 doAnimAfter(Animation::Sequence anim, Direction dir, ProcId waitfor)
void receiveHit(uint16 other, Direction dir, int damage, uint16 type) override
bool removeItem(Item *item) override
int32 collideMove(int32 x, int32 y, int32 z, bool teleport, bool force, ObjId *hititem=0, uint8 *dirs=0) override
overrides the standard item collideMove so we can notify nearby objects.
bool isBusy() const
True if the actor is currently doing an animation.
void setToStartOfAnim(Animation::Sequence anim)
Definition: pathfinder.h:38
uint16 setActivity(int activity)
Definition: container.h:36
Definition: animation_tracker.h:36
uint16 _activeWeapon
Active weapon item (only used in Crusader)
Definition: actor.h:454
void tookHitCru()
A cru-specific behavior - mostly make "ugh" noises, or explode for some robots.
Definition: actor.h:37
uint16 _defaultActivity[3]
the 3 default NPC activities from Crusader
Definition: actor.h:442
uint16 doAnim(Animation::Sequence anim, Direction dir, unsigned int steps=0)
uint16 _currentActivityNo
Current and last activity (only used in Crusader)
Definition: actor.h:450
bool _attackAimFlag
A flag used in Crusader attack process which adjusts the aim accuracy.
Definition: actor.h:469
Definition: stream.h:385
uint8 _unkByte
Definition: actor.h:434
void killAllButCombatProcesses()
kill all processes except those related to combat
Definition: combat_process.h:33
bool hasAnim(Animation::Sequence anim)
check if this actor has a specific animation
bool canSeeControlledActor(bool forcombat)
Whether this NPC has the controlled actor in their sights (Crusader only)
bool areEnemiesNear()
check if NPCs are near which are in combat mode and hostile
uint16 _attackMoveDodgeFactor
Definition: actor.h:466
uint16 _combatTactic
tactic being used in combat (for Crusader), the entry in the combat.dat flex.
Definition: actor.h:437
Definition: attack_process.h:41
uint32 _attackMoveStartFrame
Definition: actor.h:461
Animation::Result tryAnim(Animation::Sequence anim, Direction dir, unsigned int steps=0, PathfindingState *state=0)
uint16 schedule(uint32 time)