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
29namespace Ultima {
30namespace Ultima8 {
31
32class ActorAnimProcess;
33struct PathfindingState;
34class CombatProcess;
35class AttackProcess;
36
37class Actor : public Container {
38 friend class ActorAnimProcess;
39 friend class AnimationTracker;
40public:
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
157
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
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
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 {
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
417protected:
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
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: stream.h:385
Definition: str.h:59
Definition: stream.h:77
Definition: actor_anim_process.h:38
Definition: actor.h:37
Common::String dumpInfo() const override
dump some info about this object to a string
uint16 getDamageType() const override
get the damage type this object does when hitting something
uint8 _unkByte
Definition: actor.h:434
uint16 _attackMoveDodgeFactor
Definition: actor.h:466
uint32 _attackMoveStartFrame
Definition: actor.h:461
bool _attackAimFlag
A flag used in Crusader attack process which adjusts the aim accuracy.
Definition: actor.h:469
uint16 assignObjId() override
static Actor * createActor(uint32 shape, uint32 frame)
create an actor, assign objid, make it ethereal and load monster stats.
uint16 doAnim(Animation::Sequence anim, Direction dir, unsigned int steps=0)
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.
uint16 doAnimAfter(Animation::Sequence anim, Direction dir, ProcId waitfor)
virtual ProcId die(uint16 damageType, uint16 damagePts, Direction srcDir)
int32 _lastTickWasHit
Kernel timer last time NPC was hit (only used in Crusader)
Definition: actor.h:457
bool removeItem(Item *item) override
uint16 setActivityCru(int activity)
void addFireAnimOffsets(int32 &x, int32 &y, int32 &z)
Add the x/y/z fire offsets given the current state of the actor.
uint16 turnTowardDir(Direction dir, ProcId prevpid=0)
bool hasAnim(Animation::Sequence anim)
check if this actor has a specific animation
void tookHitCru()
A cru-specific behavior - mostly make "ugh" noises, or explode for some robots.
void setToStartOfAnim(Animation::Sequence anim)
uint16 setActivityU8(int activity)
bool isBusy() const
True if the actor is currently doing an animation.
void killAllButCombatProcesses()
kill all processes except those related to combat
Animation::Result tryAnim(Animation::Sequence anim, Direction dir, unsigned int steps=0, PathfindingState *state=0)
bool areEnemiesNear()
check if NPCs are near which are in combat mode and hostile
uint16 _defaultActivity[3]
the 3 default NPC activities from Crusader
Definition: actor.h:442
uint16 _currentActivityNo
Current and last activity (only used in Crusader)
Definition: actor.h:450
ProcId killAllButFallAnims(bool death)
int calculateAttackDamage(uint16 other, int damage, uint16 type)
uint16 _activeWeapon
Active weapon item (only used in Crusader)
Definition: actor.h:454
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
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
void receiveHit(uint16 other, Direction dir, int damage, uint16 type) override
uint16 setActivity(int activity)
int32 _homeX
The "home" position used in some Crusader attack tactics.
Definition: actor.h:445
bool canSeeControlledActor(bool forcombat)
Whether this NPC has the controlled actor in their sights (Crusader only)
uint16 schedule(uint32 time)
uint16 _combatTactic
tactic being used in combat (for Crusader), the entry in the combat.dat flex.
Definition: actor.h:437
Definition: animation_tracker.h:37
Definition: attack_process.h:41
Definition: combat_process.h:33
Definition: container.h:35
Definition: item.h:42
Definition: pathfinder.h:39