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