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  * Based on the original sources
22  * Faery Tale II -- The Halls of the Dead
23  * (c) 1993-1996 The Wyrmkeep Entertainment Co.
24  */
25 
26 #ifndef SAGA2_ACTOR_H
27 #define SAGA2_ACTOR_H
28 
29 #include "saga2/objects.h"
30 #include "saga2/saveload.h"
31 
32 namespace Saga2 {
33 
34 class ActorAssignment;
35 class Band;
36 class MotionTask;
37 class TaskStack;
38 
39 const int kBandingDist = kSectorSize * 2;
40 const int kActorScriptVars = 4;
41 
42 /* ===================================================================== *
43  Actor character attributes
44  * ===================================================================== */
45 
46 // Defines the colors of MANA
47 
48 enum ActorSkillID {
49  kSkillIDArchery = 0,
50  kSkillIDSwordcraft,
51  kSkillIDShieldcraft,
52  kSkillIDBludgeon,
53  kSkillIDThrowing, // gone
54  kSkillIDSpellcraft,
55  kSkillIDStealth, // gone
56  kSkillIDAgility,
57  kSkillIDBrawn,
58  kSkillIDLockpick, // gone
59  kSkillIDPilfer, // gone
60  kSkillIDFirstAid, // gone
61  kSkillIDSpotHidden, // gone
62  kNumSkills
63 };
64 
65 enum ArmorObjectTypes {
66  SHIRT_ARMOR = 0,
67  BOOT_ARMOR,
68  BRACER_ARMOR,
69  HELM_ARMOR,
70  NECKLACE_ARMOR,
71  CLOAK_ARMOR,
72  RING_ARMOR,
73 
74  ARMOR_COUNT
75 };
76 
77 /* ===================================================================== *
78  ArmorAttributes struct
79  * ===================================================================== */
80 
82  uint8 damageAbsorbtion,
83  damageDivider,
84  defenseBonus;
85 };
86 
87 /* ===================================================================== *
88  ActorAttributes structure
89  * ===================================================================== */
90 
91 // this enum acts as a layer of indirection for the unioned allSkills
92 // array.
93 
94 
95 // This defines the basic skills possessed by an actor
97  enum skillInfo {
98  kSkillBasePercent = 100,
99  kSkillFracPointsPerLevel = 5, // this being twenty and levels at 5
100  kSkillLevels = 20, // will make the advancement calc quick & easy
101  kSkillMaxLevel = kSkillFracPointsPerLevel * kSkillLevels
102  };
103 
104  enum vitalityInfo {
105  kVitalityLimit = 256
106  };
107 
108  // Automatic skills
109  uint8 archery, // Accuracy of missile weapons
110  swordcraft, // Accuracy of bladed melee weapons
111  shieldcraft, // Actor's ability to use a shield
112  bludgeon, // Accuracy of non-bladed melee weapons
113  throwing, // Ability to throw objects accurately
114  spellcraft, // Accuracy of spell combat
115  stealth, // Ability to remain unnoticed
116  agility, // Ability to dodge
117  brawn, // Ability to lift, and damage of weapons
118  lockpick; // Ability to pick locks
119 
120  // Manual skills
121  uint8 pilfer, // Ability to "lift" an item
122  firstAid, // Ability to heal recent injuries
123  spotHidden; // Ability to spot hidden objects
124 
125  // Pad byte for alignment
126  int8 pad;
127 
128  // Hit-points
129  int16 vitality;
130 
131  // Magic energy
132  int16 redMana,
133  orangeMana,
134  yellowMana,
135  greenMana,
136  blueMana,
137  violetMana;
138 
139  uint8 &skill(int16 id) {
140  switch (id) {
141  case kSkillIDArchery: return archery;
142  case kSkillIDSwordcraft: return swordcraft;
143  case kSkillIDShieldcraft: return shieldcraft;
144  case kSkillIDBludgeon: return bludgeon;
145  case kSkillIDThrowing: return throwing;
146  case kSkillIDSpellcraft: return spellcraft;
147  case kSkillIDStealth: return stealth;
148  case kSkillIDAgility: return agility;
149  case kSkillIDBrawn: return brawn;
150  case kSkillIDLockpick: return lockpick;
151  case kSkillIDPilfer: return pilfer;
152  case kSkillIDFirstAid: return firstAid;
153  case kSkillIDSpotHidden: return spotHidden;
154  }
155  error("Incorrect skill id: %d", id);
156  }
157  int16 &mana(int16 id) {
158  switch (id) {
159  case kManaIDRed: return redMana;
160  case kManaIDOrange: return orangeMana;
161  case kManaIDYellow: return yellowMana;
162  case kManaIDGreen: return greenMana;
163  case kManaIDBlue: return blueMana;
164  case kManaIDViolet: return violetMana;
165  }
166  error("Incorrect mana id: %d", id);
167  }
168 
169  uint8 getSkillLevel(int16 id) {
170  return skill(id) / kSkillFracPointsPerLevel + 1;
171  }
172 
173  void read(Common::InSaveFile *in) {
174  archery = in->readByte();
175  swordcraft = in->readByte();
176  shieldcraft = in->readByte();
177  bludgeon = in->readByte();
178  throwing = in->readByte();
179  spellcraft = in->readByte();
180  stealth = in->readByte();
181  agility = in->readByte();
182  brawn = in->readByte();
183  lockpick = in->readByte();
184  pilfer = in->readByte();
185  firstAid = in->readByte();
186  spotHidden = in->readByte();
187  pad = in->readSByte();
188  vitality = in->readSint16LE();
189  redMana = in->readSint16LE();
190  orangeMana = in->readSint16LE();
191  yellowMana = in->readSint16LE();
192  greenMana = in->readSint16LE();
193  blueMana = in->readSint16LE();
194  violetMana = in->readSint16LE();
195  }
196 
197  void write(Common::MemoryWriteStreamDynamic *out) {
198  out->writeByte(archery);
199  out->writeByte(swordcraft);
200  out->writeByte(shieldcraft);
201  out->writeByte(bludgeon);
202  out->writeByte(throwing);
203  out->writeByte(spellcraft);
204  out->writeByte(stealth);
205  out->writeByte(agility);
206  out->writeByte(brawn);
207  out->writeByte(lockpick);
208  out->writeByte(pilfer);
209  out->writeByte(firstAid);
210  out->writeByte(spotHidden);
211  out->writeSByte(pad);
212  out->writeSint16LE(vitality);
213  out->writeSint16LE(redMana);
214  out->writeSint16LE(orangeMana);
215  out->writeSint16LE(yellowMana);
216  out->writeSint16LE(greenMana);
217  out->writeSint16LE(blueMana);
218  out->writeSint16LE(violetMana);
219  }
220 }; // 28 bytes
221 
222 
223 const int kBaseCarryingCapacity = 100;
224 const int kCarryingCapacityBonusPerBrawn = 200 / ActorAttributes::kSkillLevels;
225 
226 /* ===================================================================== *
227  ResourceActorProtoExtension structure
228  * ===================================================================== */
229 
230 enum combatBehaviorTypes {
231  kBehaviorHungry,
232  kBehaviorCowardly,
233  kBehaviorBerserk,
234  kBehaviorSmart
235 };
236 
237 // This defines the additional data fields needed for actor prototypes
239 
240  ActorAttributes baseStats; // Base stats for non-player actors
241 
242  // Defines behavior for combat tactics.
243  uint8 combatBehavior;
244  uint8 gruntStyle;
245 
246  uint32 baseEffectFlags; // special effects, see EFFECTS.H
247 
248  // Default constructor -- do nothing
250  memset(&baseStats, 0, sizeof(baseStats));
251 
252  combatBehavior = 0;
253  gruntStyle = 0;
254  baseEffectFlags = 0;
255  }
256 
257  void load(Common::SeekableReadStream *stream) {
258  baseStats.read(stream);
259  combatBehavior = stream->readByte();
260  gruntStyle = stream->readByte();
261  baseEffectFlags = stream->readUint32LE();
262  }
263 }; // 28 bytes
264 
265 /* ===================================================================== *
266  ResourceActorPrototype structure
267  * ===================================================================== */
268 
269 // Defines the actor prototype data as read from the resource file
271  ResourceObjectPrototype proto; // Standard prototype data
272  ResourceActorProtoExtension ext; // Extended actor data
273 
274  void load(Common::SeekableReadStream *stream) {
275  proto.load(stream);
276  ext.load(stream);
277  }
278 };
279 
280 /* ===================================================================== *
281  ActorProto prototype behavior for Actors
282  * ===================================================================== */
283 
285 
286 private:
287  enum {
288  kViewableRows = 3,
289  kViewableCols = 3,
290  kMaxRows = 3,
291  kMaxCols = 3
292  };
293 
294 public:
296  ProtoObj(a.proto),
298  }
299 
300  // returns the containment type flags for this object
301  virtual uint16 containmentSet();
302 
303  // returns true if this object can contain another object
304  virtual bool canContain(ObjectID dObj, ObjectID item);
305 
306  // Determine if this object can contain another object at a
307  // specified slot
308  virtual bool canContainAt(
309  ObjectID dObj,
310  ObjectID item,
311  const TilePoint &where);
312 
313  weaponID getWeaponID();
314 
315  // use this actor
316  bool useAction(ObjectID dObj, ObjectID enactor);
317 
318  // open this actor
319  bool canOpen(ObjectID dObj, ObjectID enactor);
320  bool openAction(ObjectID dObj, ObjectID enactor);
321 
322  // close this actor
323  bool closeAction(ObjectID dObj, ObjectID enactor);
324 
325  bool strikeAction(
326  ObjectID dObj,
327  ObjectID enactor,
328  ObjectID item);
329 
330  bool damageAction(
331  ObjectID dObj,
332  ObjectID enactor,
333  ObjectID target);
334 
335  // drop another object onto this actor.
336  bool acceptDropAction(
337  ObjectID dObj,
338  ObjectID enactor,
339  ObjectID droppedObj,
340  int count);
341 
342  // cause damage directly
343  bool acceptDamageAction(
344  ObjectID dObj,
345  ObjectID enactor,
346  int8 absDamage,
347  effectDamageTypes dType,
348  int8 dice,
349  uint8 sides,
350  int8 perDieMod);
351 
352  // cause healing directly
353  bool acceptHealingAction(ObjectID dObj, ObjectID enactor, int8 healing);
354 
355  // Accept strike from an object (allows this actor to cause
356  // damage to the striking object).
357  bool acceptStrikeAction(
358  ObjectID dObj,
359  ObjectID enactor,
360  ObjectID strikingObj,
361  uint8 skillIndex);
362 
363  // Handle the results of an object being inserted into this object
364  // at the specified slot
365  bool acceptInsertionAtAction(
366  ObjectID dObj,
367  ObjectID enactor,
368  ObjectID item,
369  const TilePoint &where,
370  int16 num = 1);
371 
372  // Initiate an attack using this type of object
373  virtual void initiateAttack(ObjectID attacker, ObjectID target);
374 
375  // Given an object sound effect record, which sound should be made
376  // when this object is damaged
377  virtual uint8 getDamageSound(const ObjectSoundFXs &soundFXs);
378 
379  // Do the background processing, if needed, for this object.
380  void doBackgroundUpdate(GameObject *obj);
381 
382  // Cause the user's associated skill to grow
383  void applySkillGrowth(ObjectID enactor, uint8 points = 1);
384 
385  bool greetActor(
386  ObjectID dObj, // object dropped on
387  ObjectID enactor); // person doing dropping
388 
389 public:
390  virtual uint16 getViewableRows() {
391  return kViewableRows;
392  }
393  virtual uint16 getViewableCols() {
394  return kViewableCols;
395  }
396  virtual uint16 getMaxRows() {
397  return kMaxRows;
398  }
399  virtual uint16 getMaxCols() {
400  return kMaxCols;
401  }
402 
403  virtual bool canFitBulkwise(GameObject *container, GameObject *obj);
404  virtual bool canFitMasswise(GameObject *container, GameObject *obj);
405 
406  virtual uint16 massCapacity(GameObject *container);
407  virtual uint16 bulkCapacity(GameObject *container);
408 };
409 
410 /* ============================================================================ *
411  Actor: Describes an instance of a character
412  * ============================================================================ */
413 
414 enum actorCreationFlags {
415  kActorPermanent = (1 << 0)
416 };
417 
418 enum DispositionType {
419  kDispositionFriendly,
420  kDispositionEnemy,
421 
422  kDispositionPlayer
423 };
424 
425 enum actionSequenceOptions {
426 
427  // Flags set by call to setAction
428  kAnimateRepeat = (1 << 0), // repeat animation when done
429  kAnimateReverse = (1 << 1), // animate in reverse direction
430  kAnimateAlternate = (1 << 2), // both directions, back & forth
431  kAnimateRandom = (1 << 3), // pick a random frame
432  kAnimateNoRestart = (1 << 4), // don't reset from start
433 
434  // This flag is set if the animation has been put on hold until
435  // the actor's appearance is reloaded.
436  kAnimateOnHold = (1 << 5),
437 
438  // This flag is set if the final frame of the animation has
439  // been reached.
440  kAnimateFinished = (1 << 6),
441 
442  // This flag gets set if the sprite could not be displayed
443  // because it's bank hasn't been loaded yet.
444  kAnimateNotLoaded = (1 << 7)
445 };
446 
447 // Various types of action sequences
448 
449 
450 enum ActorAnimationTypes {
451 
452  // Various types of stands
453  kActionStand = 0, // standing still
454  kActionWaitAgressive, // an agigressive wait cycle
455  kActionWaitImpatient, // an impatient wait cycle
456  kActionWaitFriendly, // a a friendly wait cycle
457 
458  // Walking and running
459  kActionWalk, // walking motion
460  kActionRun, // running motion
461 
462  // Squatting
463  kActionDuck, // stoop to dodge sword
464  kActionStoop, // stoop to pick up object
465 
466  // Jumping
467  kActionFreeFall, // how he looks in ballistic
468  kActionFreeFallRunning, // a running leap (free fall)
469  kActionJumpUp, // begin jump straight up
470  kActionJumpFwd, // begin jump forward
471  kActionJumpBack, // begin jump back in surprise
472  kActionLand, // land after jump
473  kActionFallBadly, // after a very long fall
474 
475  // Climbing
476  kActionClimbLadder, // climb a ladder (2 directions)
477 
478  // Talking & interacting
479  kActionTalk, // talking
480  kActionGesture, // gesture with hands or body
481  kActionGiveItem, // give or take item
482 
483  // Two-handed weapon use
484  kActionTwoHandSwingHigh, // full overhead swing aim high
485  kActionTwoHandSwingLow, // full overhead swing aim low
486  kActionTwoHandSwingLeftHigh, // partial swing on left (high)
487  kActionTwoHandSwingLeftLow, // partial swing on left (low)
488  kActionTwoHandSwingRightHigh, // partial swing on rgt (high)
489  kActionTwoHandSwingRightLow, // partial swing on rgt (low)
490  kActionTwoHandParry, // hold sword up to parry
491 
492  // One-handed weapon use
493  kActionSwingHigh, // one-handed swing (high)
494  kActionSwingLow, // one-handed swing (low)
495  kActionParryHigh, // one-handed parry (high)
496  kActionParryLow, // one-handed parry (low)
497  kActionShieldParry, // parry with shield
498 
499  kActionThrowObject, // throw
500 
501  // Other combat actions
502  kActionFireBow, // fire an arrow
503  kActionCastSpell, // cast a magic spell
504  kActionUseWand, // cast a magic spell w/wand
505  kActionUseStaff, // cast a magic spell w/staff
506  kActionHit, // show impact of blow
507  kActionKnockedDown, // knocked down by opponent
508  kActionDie, // death agony
509 
510  // Passive actions
511  kActionSleep, // sleeping
512  kActionDead, // dead body on ground
513  kActionSit, // sitting at table
514 
515  // Misc actions built from other frames
516  kActionListenAtDoor, // listening at doors
517  kActionShoveDoor, // try to force a door open
518  kActionSpecial1, // special Action
519  kActionSpecial2, // special Action
520  kActionSpecial3, // special Action
521  kActionSpecial4, // special Action
522  kActionSpecial5, // special Action
523  kActionSpecial6, // special Action
524  kActionSpecial7, // special Action
525  kActionSpecial8 // special Action
526 };
527 
528 enum ActorGoalTypes {
529  kActorGoalFollowAssignment,
530  kActorGoalPreserveSelf,
531  kActorGoalAttackEnemy,
532  kActorGoalFollowLeader,
533  kActorGoalAvoidEnemies
534 };
535 
536 // The actor structure will be divided into two parts. The
537 // ResourceActor structure defines the data as it is stored in the
538 // resource file. The Actor structure has a copy of all of the
539 // ResourceActor data members, plus data members which will be
540 // initialized and used during run time.
541 
543 
544  // Social loyalty
545  uint8 faction; // actor's faction
546 
547  // Appearance attribute
548  uint8 colorScheme; // indirect color map
549 
550  int32 appearanceID; // appearnce of this actor
551 
552  // Personality attributes
553  int8 attitude, // cooperativeness
554  mood; // happiness
555  uint8 disposition; // actor disposition
556  // 0 = friendly, 1 = enemy,
557  // 2 = Julian, 3 = Philip,
558  // 4 = Kevin
559 
560  // Character orientation
561  Direction currentFacing; // current facing direction
562 
563  // Tether info
564  int16 tetherLocU; // tether U coordinate
565  int16 tetherLocV; // tether V coordinate
566  int16 tetherDist; // length of tether
567 
568  // Held objects
569  ObjectID leftHandObject, // object held in left hand.
570  rightHandObject; // object held in right hand.
571 
572  // Knowledge packets
573  uint16 knowledge[16];
574 
575  // Schedule script ID
576  uint16 schedule;
577 
578  // Pad bytes
579  uint8 reserved[18];
580 
582 };
583 
584 class Actor : public GameObject {
585  friend class ActorProto;
586  friend class MotionTask;
587  friend class Task;
588  friend class TaskStack;
589 
590 public:
591 
592  // Resource fields
593 
594  // Social loyalty
595  uint8 _faction; // actor's faction
596 
597  // Appearance attribute
598  uint8 _colorScheme; // indirect color map
599 
600  int32 _appearanceID; // appearnce of this actor
601 
602  // Personality attributes
603  int8 _attitude, // cooperativeness
604  _mood; // happiness
605  uint8 _disposition; // actor disposition
606  // 0 = friendly, 1 = enemy,
607  // 2 = Julian, 3 = Philip,
608  // 4 = Kevin
609 
610  // Character orientation
611  Direction _currentFacing; // current facing direction
612 
613  // Tether info
614  int16 _tetherLocU; // tether U coordinate
615  int16 _tetherLocV; // tether V coordinate
616  int16 _tetherDist; // length of tether
617 
618  // Held objects
619  ObjectID _leftHandObject, // object held in left hand.
620  _rightHandObject; // object held in right hand.
621 
622  // Knowledge packets
623  uint16 _knowledge[16];
624 
625  // Schedule script ID
626  uint16 _schedule;
627 
628  // Run-time fields
629 
630  uint8 _conversationMemory[4];// last things talked about
631 
632  // Sprite animation variables
633  uint8 _currentAnimation, // current action sequence
634  _currentPose, // current pose in sequence
635  _animationFlags; // current posing flags
636 
637  // Various actor flags
638  enum {
639  kAFLobotomized = (1 << 0),
640  kAFTemporary = (1 << 1),
641  kAFAfraid = (1 << 2),
642  kAFHasAssignment = (1 << 3),
643  kAFSpecialAttack = (1 << 4),
644  kAFFightStance = (1 << 5)
645  };
646 
647  uint8 _flags;
648 
649  // Contains sprite index and positioning info for the current
650  // actor state.
651  ActorPose _poseInfo; // current animation state
652 
653  // Pointer to the appearance record (sprite array) for this actor.
654  ActorAppearance *_appearance; // appearance structs
655 
656  int16 _cycleCount; // misc counter for actions
657  int16 _kludgeCount; // another misc counter
658 
659  uint32 _enchantmentFlags; // flags indicating racial
660  // abilities and enchantments
661 
662  // Movement attributes
663  MotionTask *_moveTask;
664 
665  // Current task
666  TaskStack *_curTask;
667 
668  // Current goal type
669  uint8 _currentGoal;
670 
671  // Used for deltayed deactivation (and also to word-align struct)
672  uint8 _deactivationCounter;
673 
674  // Assignment
675  ActorAssignment *_assignment;
676  // assignments
677 
678  // Current effective stats
679  ActorAttributes _effectiveStats;
680 
681  uint8 _actionCounter; // coordinate moves in combat
682 
683  uint16 _effectiveResistance; // resistances (see EFFECTS.H)
684  uint16 _effectiveImmunity; // immunities (see EFFECTS.H)
685 
686  int16 _recPointsPerUpdate; // fractional vitality recovery
687 
688  int16 _currentRecoveryPoints; // fraction left from last recovery
689 
690  enum vitalityRecovery {
691  kRecPointsPerVitality = 10
692  };
693 
694 
695  Actor *_leader; // This actor's leader
696  ObjectID _leaderID;
697  Band *_followers; // This actor's band of followers
698  BandID _followersID;
699 
700  ObjectID _armorObjects[ARMOR_COUNT]; // armor objects being worn
701 
702  GameObject *_currentTarget;
703  ObjectID _currentTargetID;
704 
705  int16 _scriptVar[kActorScriptVars]; // scratch variables for scripter use
706 
707  // Member functions
708 
709 private:
710  // Initialize actor record
711  void init(
712  int16 protoIndex,
713  uint16 nameIndex,
714  uint16 scriptIndex,
715  int32 appearanceNum,
716  uint8 colorSchemeIndex,
717  uint8 factionNum,
718  uint8 initFlags);
719 
720 public:
721  // Default constructor
722  Actor();
723 
724  // Constructor - initial actor construction
725  Actor(const ResourceActor &res);
726 
728 
729  // Destructor
730  ~Actor();
731 
732  // Return the number of bytes needed to archive this actor
733  int32 archiveSize();
734 
735  void write(Common::MemoryWriteStreamDynamic *out);
736 
737  static Actor *newActor(
738  int16 protoNum,
739  uint16 nameIndex,
740  uint16 scriptIndex,
741  int32 appearanceNum,
742  uint8 colorSchemeIndex,
743  uint8 factionNum,
744  uint8 initFlags);
745 
746  // Delete this actor
747  void deleteActor();
748 
749 private:
750  // Turn incrementally
751  void turn(Direction targetDir) {
752  Direction relativeDir = (targetDir - _currentFacing) & 0x7;
753 
754  _currentFacing =
755  (relativeDir < 4
756  ? _currentFacing + 1
757  : _currentFacing - 1)
758  & 0x7;
759  }
760 public:
761 
762  // Cause the actor to stop his current motion task is he is
763  // interruptable
764  void stopMoving();
765 
766  // Cause this actor to die
767  void die();
768 
769  // Cause this actor to return from the dead
770  void imNotQuiteDead();
771 
772  // makes the actor do a vitality change test
773  void vitalityUpdate();
774 
775  // Perform actor specific activation tasks
776  void activateActor();
777 
778  // Perform actor specific deactivation tasks
779  void deactivateActor();
780 
781  // De-lobotomize this actor
782  void delobotomize();
783 
784  // Lobotomize this actor
785  void lobotomize();
786 
787  // Return a pointer to the actor's current assignment
788  ActorAssignment *getAssignment() {
789  return _flags & kAFHasAssignment
790  ? _assignment
791  : nullptr;
792  }
793 
794  // determine whether this actor has a specified property
795  bool hasProperty(const ActorProperty &actorProp) {
796  // The function call operator is used explicitly because
797  // Visual C++ 4.0 doesn't like it otherwise.
798  return actorProp.operator()(this);
799  }
800 
801  // Determine if specified point is within actor's arms' reach
802  bool inReach(const TilePoint &tp);
803 
804  // Determine if specified point is within an objects use range
805  bool inUseRange(const TilePoint &tp, GameObject *obj);
806 
807  // Determine if actor is dead
808  bool isDead() {
809  return _effectiveStats.vitality <= 0;
810  }
811 
812  // Determine if actor is immobile (i.e. can't walk)
813  bool isImmobile();
814 
815  // Return a pointer to this actor's currently readied offensive
816  // object
817  GameObject *offensiveObject();
818 
819  // Returns pointers to this actor's readied primary defensive object
820  // and optionally their scondary defensive object
821  void defensiveObject(GameObject **priPtr, GameObject **secPtr = NULL);
822 
823  // Returns a pointer to the object with which this actor is
824  // currently blocking, if any
825  GameObject *blockingObject(Actor *attacker);
826 
827  // Return the total used armor attributes
828  void totalArmorAttributes(ArmorAttributes &armorAttribs);
829 
830  // Determine if specified point is within actor's attack range
831  bool inAttackRange(const TilePoint &tp);
832 
833  // Attack the specified object with the currently selected weapon
834  void attack(GameObject *obj);
835 
836  // Stop any attack on the specified object
837  void stopAttack(GameObject *obj);
838 
839  // Determine if this actor can block an attack with objects
840  // currently being held
841  bool canDefend();
842 
843  // Return a numeric value which roughly estimates this actor's
844  // offensive strength
845  int16 offenseScore();
846 
847  // Return a numeric value which roughly estimates this actor's
848  // defensive strength
849  int16 defenseScore();
850 
851  // Handle the effect of a successful hit on an opponent in combat
852  void handleSuccessfulStrike(GameObject *weapon) {
853  weapon->proto()->applySkillGrowth(thisID());
854  }
855 
856  // Return the value of this actor's disposition
857  int16 getDisposition() {
858  return _disposition;
859  }
860 
861  // Give the actor a new disposition
862  int16 setDisposition(int16 newDisp) {
863  int16 oldDisp = _disposition;
864  if (newDisp < kDispositionPlayer)
865  _disposition = newDisp;
866  return oldDisp;
867  }
868 
869  // Return a pointer to the effective stats
870  ActorAttributes *getStats() {
871  return &_effectiveStats;
872  }
873 
874  // Return a pointer to this actor's base stats
875  ActorAttributes *getBaseStats();
876 
877  // Return the color remapping table
878  void getColorTranslation(ColorTable map);
879 
880  // Determine if this actor is interruptable
881  bool isInterruptable() {
882  return _actionCounter == 0;
883  }
884 
885  // Determine if this actor is permanently uninterruptable
886  bool isPermanentlyUninterruptable() {
887  return _actionCounter == maxuint8;
888  }
889 
890  // Set the inturruptability for this actor
891  void setInterruptablity(bool val) {
892  _actionCounter = val ? 0 : maxuint8;
893  }
894 
895  // Set action time counter for this actor
896  // REM: the action points will eventually need to be scaled based
897  // upon enchantments and abilities
898  void setActionPoints(uint8 points) {
899  _actionCounter = points;
900  }
901 
902  // Drop the all of the actor's inventory
903  void dropInventory();
904 
905  // Place an object into this actor's right or left hand
906  void holdInRightHand(ObjectID objID);
907  void holdInLeftHand(ObjectID objID);
908 
909  // Wear a piece of armor
910  void wear(ObjectID objID, uint8 where);
911 
912  // Update the appearance of an actor with no motion task.
913  void updateAppearance(int32 deltaTime);
914 
915  // Used To Find Wait State When Preffered Not Available
916  bool setAvailableAction(int16 action1, int16 action2, int16 action3, int16 actiondefault);
917 
918  // Set the current animation sequence that the actor is doing.
919  // Returns the number of poses in the sequence, or 0 if there
920  // are no poses in the sequence.
921  int16 setAction(int16 newState, int16 flags);
922 
923  // returns true if the action is available in the current
924  // direction.
925  bool isActionAvailable(int16 newState, bool anyDir = false);
926 
927  // Return the number of animation frames in the specified action
928  // for the specified direction
929  int16 animationFrames(int16 actionType, Direction dir);
930 
931  // Update the current animation sequence to the next frame
932  bool nextAnimationFrame();
933 
934  // calculate which sprite frames to show. Return false if
935  // sprite frames are not loaded.
936  bool calcSpriteFrames();
937 
938  // Calculate the frame list entry, given the current actor's
939  // body state, and facing direction.
940 // FrameListEntry *calcFrameState( int16 bodyState );
941 
942  // Returns 0 if not moving, 1 if path being calculated,
943  // 2 if path being followed.
944  int pathFindState();
945 
946  // High level actor behavior functions
947 private:
948  void setGoal(uint8 newGoal);
949 
950 public:
951  void evaluateNeeds();
952 
953  // Called every frame to update the state of this actor
954  void updateState();
955 
956  void handleTaskCompletion(TaskResult result);
957  void handleOffensiveAct(Actor *attacker);
958  void handleDamageTaken(uint8 damage);
959  void handleSuccessfulStrike(Actor *target, int8 damage);
960  void handleSuccessfulKill(Actor *target);
961 
962 private:
963  static bool canBlockWith(GameObject *defenseObj, Direction relativeDir);
964 public:
965  void evaluateMeleeAttack(Actor *attacker);
966 
967  // Banding related functions
968  void bandWith(Actor *newLeader);
969  void disband();
970 
971  bool inBandingRange() {
972  assert(_leader != NULL);
973 
974  return _leader->IDParent() == IDParent()
975  && (_leader->getLocation() - getLocation()).quickHDistance()
976  <= kBandingDist;
977  }
978 
979 private:
980  bool addFollower(Actor *newBandMember);
981  void removeFollower(Actor *bandMember);
982 
983  TaskStack *createFollowerTask(Actor *bandMember);
984  uint8 evaluateFollowerNeeds(Actor *follower);
985 
986 public:
987  // Knowledge-related member functions
988  bool addKnowledge(uint16 kID);
989  bool removeKnowledge(uint16 kID);
990  void clearKnowledge();
991  void useKnowledge(scriptCallFrame &scf);
992 
993  bool canSenseProtaganistIndirectly(SenseInfo &info, int16 range);
994  bool canSenseSpecificActorIndirectly(
995  SenseInfo &info,
996  int16 range,
997  Actor *a);
998  bool canSenseSpecificObjectIndirectly(
999  SenseInfo &info,
1000  int16 range,
1001  ObjectID obj);
1002  bool canSenseActorPropertyIndirectly(
1003  SenseInfo &info,
1004  int16 range,
1005  ActorPropertyID prop);
1006  bool canSenseObjectPropertyIndirectly(
1007  SenseInfo &info,
1008  int16 range,
1009  ObjectPropertyID prop);
1010 
1011  // Take mana from actor's mana pool (if possible)
1012  bool takeMana(ActorManaID i, int8 dMana);
1013 
1014  bool hasMana(ActorManaID i, int8 dMana);
1015 
1016  uint32 getBaseEnchantmentEffects();
1017  uint16 getBaseResistance();
1018  uint16 getBaseImmunity();
1019  uint16 getBaseRecovery();
1020 
1021  bool resists(effectResistTypes r) {
1022  return _effectiveResistance & (1 << r);
1023  }
1024  bool isImmuneTo(effectImmuneTypes r) {
1025  return _effectiveImmunity & (1 << r);
1026  }
1027  bool hasEffect(effectOthersTypes e) {
1028  return (_enchantmentFlags & (1 << e)) != 0;
1029  }
1030 
1031  void setResist(effectResistTypes r, bool on) {
1032  _effectiveResistance = on ?
1033  _effectiveResistance | (1 << r) :
1034  _effectiveResistance & ~(1 << r);
1035  }
1036 
1037  void setImmune(effectImmuneTypes r, bool on) {
1038  _effectiveImmunity = on ?
1039  _effectiveImmunity | (1 << r) :
1040  _effectiveImmunity & ~(1 << r);
1041  }
1042 
1043  void setEffect(effectOthersTypes e, bool on) {
1044  _enchantmentFlags = on ?
1045  _enchantmentFlags | (1 << e) :
1046  _enchantmentFlags & ~(1 << e);
1047  }
1048 
1049  bool makeSavingThrow();
1050 
1051  void setFightStance(bool val) {
1052  if (val)
1053  _flags |= kAFFightStance;
1054  else
1055  _flags &= ~kAFFightStance;
1056  }
1057 };
1058 
1059 inline bool isPlayerActor(Actor *a) {
1060  return a->_disposition >= kDispositionPlayer;
1061 }
1062 
1063 inline bool isPlayerActor(ObjectID obj) {
1064  return isActor(obj)
1065  && isPlayerActor((Actor *)GameObject::objectAddress(obj));
1066 }
1067 
1068 inline bool isEnemy(Actor *a) {
1069  return !a->isDead() && a->_disposition == kDispositionEnemy;
1070 }
1071 
1072 inline bool isEnemy(ObjectID obj) {
1073  return isActor(obj)
1074  && isEnemy((Actor *)GameObject::objectAddress(obj));
1075 }
1076 
1077 void updateActorStates();
1078 
1079 void pauseActorStates();
1080 void resumeActorStates();
1081 
1082 void setCombatBehavior(bool enabled);
1083 
1084 // Determine if the actors are currently initialized
1085 bool areActorsInitialized();
1086 
1087 void clearEnchantments(Actor *a);
1088 void addEnchantment(Actor *a, uint16 enchantmentID);
1089 
1090 /* ============================================================================ *
1091  Actor factions table
1092  * ============================================================================ */
1093 
1094 enum factionTallyTypes {
1095  kFactionNumKills = 0, // # of times faction member killed by PC
1096  kFactionNumThefts, // # of times PC steals from faction member
1097  kFactionNumFavors, // accumulated by SAGA script.
1098 
1099  kFactionNumColumns
1100 };
1101 
1102 // Get the attitude a particular faction has for a char.
1103 int16 GetFactionTally(int faction, enum factionTallyTypes act);
1104 
1105 // Increment / Decrement faction attitude
1106 // Whenever an actor is killed, call:
1107 // AddFactionAttitude( actor.faction, kFactionNumKills, 1 );
1108 // Whenever an actor is robbed, call:
1109 // AddFactionAttitude( actor.faction, kFactionNumThefts, 1 );
1110 int16 AddFactionTally(int faction, enum factionTallyTypes act, int amt);
1111 
1112 // Initialize the faction tally table
1113 void initFactionTallies();
1114 
1115 // Save the faction tallies to a save file
1116 void saveFactionTallies(Common::OutSaveFile *outS);
1117 
1118 // Load the faction tallies from a save file
1119 void loadFactionTallies(Common::InSaveFile *in);
1120 
1121 // Cleanup the faction tally table
1122 inline void cleanupFactionTallies() { /* Nothing to do */ }
1123 
1125 public:
1126 
1127  enum {
1128  kEvalRate = 8,
1129  kEvalRateMask = kEvalRate - 1
1130  };
1131 
1132  Common::Array<Actor *> _actorList;
1133 
1134  int32 _updatesViaScript;
1135  int32 _baseActorIndex;
1136  int16 _factionTable[kMaxFactions][kFactionNumColumns];
1137  bool _actorStatesPaused;
1138  bool _combatBehaviorEnabled;
1139 
1140  ActorManager() {
1141  _updatesViaScript = 0;
1142  _baseActorIndex = kEvalRateMask;
1143 
1144  memset(_factionTable, 0, sizeof(_factionTable));
1145 
1146  _actorStatesPaused = false;
1147  _combatBehaviorEnabled = false;
1148  }
1149 };
1150 
1151 } // end of namespace Saga2
1152 
1153 #endif
Definition: actor.h:284
Definition: objects.h:63
Definition: task.h:122
Definition: objproto.h:371
Definition: savefile.h:54
Definition: actor.h:238
Definition: array.h:52
uint32 readUint32LE()
Definition: stream.h:473
Definition: motion.h:92
Definition: actor.h:32
Definition: script.h:55
Definition: memstream.h:194
Definition: tcoords.h:127
Definition: stream.h:745
Definition: sensor.h:100
Definition: actor.h:584
Definition: actor.h:270
Definition: band.h:115
byte readByte()
Definition: stream.h:434
Definition: actor.h:81
Definition: sprite.h:271
Definition: actor.h:1124
Definition: objects.h:118
void NORETURN_PRE error(MSVC_PRINTF const char *s,...) GCC_PRINTF(1
FORCEINLINE int16 readSint16LE()
Definition: stream.h:543
Definition: sprite.h:102
FORCEINLINE void writeSint16LE(int16 value)
Definition: stream.h:194
FORCEINLINE int8 readSByte()
Definition: stream.h:447
Definition: actor.h:542
Definition: objproto.h:173
Definition: objects.h:1291
void writeSByte(int8 value)
Definition: stream.h:146
Definition: task.h:1563
Definition: property.h:45
Definition: actor.h:96
Definition: assign.h:51
void writeByte(byte value)
Definition: stream.h:140