ScummVM API documentation
task.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_TASK_H
27 #define SAGA2_TASK_H
28 
29 #include "saga2/target.h"
30 #include "saga2/patrol.h"
31 
32 namespace Saga2 {
33 
34 const int kDefaultEvalRate = 10;
35 
36 const size_t kMaxTaskSize = 48;
37 
38 // Integers representing task types
39 enum TaskType {
40  kWanderTask,
41  kTetheredWanderTask,
42  kGotoLocationTask,
43  kGotoRegionTask,
44  kGotoObjectTask,
45  kGotoActorTask,
46  kGoAwayFromObjectTask,
47  kGoAwayFromActorTask,
48  kHuntToBeNearLocationTask,
49  kHuntToBeNearObjectTask,
50  kHuntToPossessTask,
51  kHuntToBeNearActorTask,
52  kHuntToKillTask,
53  kHuntToGiveTask,
54  kBandTask,
55  kBandAndAvoidEnemiesTask,
56  kFollowPatrolRouteTask,
57  kAttendTask
58 };
59 
60 /* ===================================================================== *
61  Function prototypes
62  * ===================================================================== */
63 
64 class Task;
65 class TaskStack;
66 
67 // Run through the active task stacks, updating each
68 void updateActorTasks();
69 
70 void pauseActorTasks();
71 void resumeActorTasks();
72 
73 // Allocate a new task stack
74 TaskStack *newTaskStack(Actor *a);
75 void newTaskStack(TaskStack *p);
76 
77 // Dispose of a previously allocated task stack
78 void deleteTaskStack(TaskStack *p);
79 
80 // Return the ID number of a specified task stack
81 TaskStackID getTaskStackID(TaskStack *ts);
82 
83 // Return a pointer to a TaskStack given a TaskStackID
84 TaskStack *getTaskStackAddress(TaskStackID id);
85 
86 // Initialize the task stack list
87 void initTaskStacks();
88 
89 void saveTaskStacks(Common::OutSaveFile *outS);
90 void loadTaskStacks(Common::InSaveFile *in, int32 chunkSize);
91 
92 // Cleanup the task stacks
93 void cleanupTaskStacks();
94 
95 
96 void newTask(Task *t);
97 void newTask(Task *t, TaskID id);
98 
99 // Dispose of a previously allocated task
100 void deleteTask(Task *p);
101 
102 // Return a task's ID number
103 TaskID getTaskID(Task *t);
104 
105 // Return a pointer to a Task given a TaskID
106 Task *getTaskAddress(TaskID id);
107 
108 // Initialize the task list
109 void initTasks();
110 
111 void saveTasks(Common::OutSaveFile *outS);
112 void loadTasks(Common::InSaveFile *in, int32 chunkSize);
113 
114 // Cleanup the task list
115 void cleanupTasks();
116 
117 /* ===================================================================== *
118  Task Class
119  * ===================================================================== */
120 
121 // This is the base class for all Task classes
122 class Task {
123  friend class TaskStack;
124 
125 protected:
126  // A pointer to this task's stack
127  TaskStack *_stack;
128  TaskStackID _stackID;
129 
130 public:
131  Common::String _type;
132 
133  // Constructor -- initial construction
134  Task(TaskStack *ts) : _stack(ts), _stackID(NoTaskStack) {
135  newTask(this);
136  }
137 
138  Task(TaskStack *ts, TaskID id) : _stack(ts) {
139  newTask(this, id);
140  }
141 
142  Task(Common::InSaveFile *in, TaskID id);
143 
144  // Virtual destructor -- do nothing
145  virtual ~Task() {
146  deleteTask(this);
147  }
148 
149  // Fixup any subtask pointers
150  virtual void fixup();
151 
152  // Return the number of bytes necessary to archive this Task
153  // in a buffer
154  virtual int32 archiveSize() const;
155 
156  virtual void write(Common::MemoryWriteStreamDynamic *out) const;
157 
158  // Return an integer representing the type of this task
159  virtual int16 getType() const = 0;
160 
161  virtual void abortTask() = 0;
162  virtual TaskResult evaluate() = 0;
163  virtual TaskResult update() = 0;
164 
165  // Determine if the specified task is equivalent to this task
166  virtual bool operator == (const Task &t) const = 0;
167  bool operator != (const Task &t) const {
168  return !operator == (t);
169  }
170 };
171 
172 /* ===================================================================== *
173  WanderTask Class
174  * ===================================================================== */
175 
176 // This class is basically a shell around the wander motion task
177 class WanderTask : public Task {
178 protected:
179  bool _paused; // Flag indicating "paused"ness of this task
180  int16 _counter; // Counter for tracking pause length
181 
182 public:
183  // Constructor
184  WanderTask(TaskStack *ts) : Task(ts) {
185  debugC(2, kDebugTasks, " - WanderTask");
186  _type = "WanderTask";
187  wander();
188  }
189 
190  WanderTask(Common::InSaveFile *in, TaskID id);
191 
192  // Return the number of bytes needed to archive this object in
193  // a buffer
194  int32 archiveSize() const;
195 
196  void write(Common::MemoryWriteStreamDynamic *out) const;
197 
198  // Return an integer representing the type of this task
199  int16 getType() const;
200 
201  void abortTask();
202  TaskResult evaluate();
203  TaskResult update();
204 
205  // Determine if the specified task is equivalent to this task
206  bool operator == (const Task &t) const;
207 
208 protected:
209  // Update function used while task is not paused
210  virtual TaskResult handleWander();
211 
212  // Update function used while task is paused
213  TaskResult handlePaused() {
214  return kTaskNotDone;
215  }
216 
217  // Set this task into the paused state
218  void pause();
219 
220  // Set this task into the wander state
221  void wander();
222 };
223 
224 /* ===================================================================== *
225  TetheredWanderTask Class
226  * ===================================================================== */
227 
228 class GotoRegionTask;
229 
230 // This class is basically a shell around the tethered wander
231 // motion task
233  // Tether coordinates
234  int16 _minU,
235  _minV,
236  _maxU,
237  _maxV;
238 
239  // Pointer to subtask for going to the tether region
240  GotoRegionTask *_gotoTether;
241  TaskID _gotoTetherID;
242 
243 public:
244  // Constructor
246  TaskStack *ts,
247  int16 uMin,
248  int16 vMin,
249  int16 uMax,
250  int16 vMax) :
251  WanderTask(ts),
252  _minU(uMin),
253  _minV(vMin),
254  _maxU(uMax),
255  _maxV(vMax),
256  _gotoTether(NULL),
257  _gotoTetherID(NoTask) {
258  debugC(2, kDebugTasks, " - TetheredWanderTask");
259  _type = "TetheredWanderTask";
260  }
261 
262  TetheredWanderTask(Common::InSaveFile *in, TaskID id);
263 
264  // Fixup the subtask pointers
265  void fixup();
266 
267  // Return the number of bytes needed to archive this object in
268  // a buffer
269  int32 archiveSize() const;
270 
271  void write(Common::MemoryWriteStreamDynamic *out) const;
272 
273  // Return an integer representing the type of this task
274  int16 getType() const;
275 
276  void abortTask();
277 
278  // Determine if the specified task is equivalent to this task
279  bool operator == (const Task &t) const;
280 
281  // Update function used while task is not paused
282  TaskResult handleWander();
283 };
284 
285 /* ===================================================================== *
286  GotoTask Class
287  * ===================================================================== */
288 
289 class GotoTask : public Task {
290  WanderTask *_wander;
291  TaskID _wanderID;
292  bool _prevRunState;
293 
294 public:
295  // Constructor -- initial construction
296  GotoTask(TaskStack *ts) :
297  Task(ts),
298  _wander(NULL),
299  _wanderID(NoTask),
300  _prevRunState(false) {
301  debugC(2, kDebugTasks, " - GotoTask");
302  _type = "GotoTask";
303  }
304 
305  GotoTask(Common::InSaveFile *in, TaskID id);
306 
307  // Fixup the subtask pointer
308  void fixup();
309 
310  // Return the number of bytes needed to archive this object in
311  // a buffer
312  int32 archiveSize() const;
313 
314  void write(Common::MemoryWriteStreamDynamic *out) const;
315 
316  void abortTask();
317  TaskResult evaluate();
318  TaskResult update();
319 
320 private:
321  virtual TilePoint destination() = 0;
322  virtual TilePoint intermediateDest() = 0;
323  virtual bool lineOfSight() = 0;
324  virtual bool run() = 0;
325 };
326 
327 /* ===================================================================== *
328  GotoLocationTask Class
329  * ===================================================================== */
330 
331 class GotoLocationTask : public GotoTask {
332  TilePoint _targetLoc;
333  uint8 _runThreshold;
334 
335 public:
336  // Constructor -- initial construction
338  TaskStack *ts,
339  const TilePoint &tp,
340  uint8 runDist = maxuint8) :
341  GotoTask(ts),
342  _targetLoc(tp),
343  _runThreshold(runDist) {
344  debugC(2, kDebugTasks, " - GotoLocationTask");
345  _type = "GotoLocationTask";
346  }
347 
348  GotoLocationTask(Common::InSaveFile *in, TaskID id);
349 
350  // Return the number of bytes needed to archive this object in
351  // a buffer
352  int32 archiveSize() const;
353 
354  void write(Common::MemoryWriteStreamDynamic *out) const;
355 
356  // Return an integer representing the type of this task
357  int16 getType() const;
358 
359  // Determine if the specified task is equivalent to this task
360  bool operator == (const Task &t) const;
361 
362  const TilePoint getTarget() const {
363  return _targetLoc;
364  }
365 
366  void changeTarget(const TilePoint &newTarget) {
367  _targetLoc = newTarget;
368  }
369 
370 private:
371  TilePoint destination();
372  TilePoint intermediateDest();
373  bool lineOfSight();
374  bool run();
375 };
376 
377 /* ===================================================================== *
378  GotoRegionTask Class
379  * ===================================================================== */
380 
381 class GotoRegionTask : public GotoTask {
382  int16 _regionMinU,
383  _regionMinV,
384  _regionMaxU,
385  _regionMaxV;
386 
387 public:
388  // Constructor -- initial construction
390  TaskStack *ts,
391  int16 minU,
392  int16 minV,
393  int16 maxU,
394  int16 maxV) :
395  GotoTask(ts),
396  _regionMinU(minU),
397  _regionMinV(minV),
398  _regionMaxU(maxU),
399  _regionMaxV(maxV) {
400  debugC(2, kDebugTasks, " - GotoRegionTask");
401  _type = "GotoRegionTask";
402  }
403 
404  GotoRegionTask(Common::InSaveFile *in, TaskID id);
405 
406  // Return the number of bytes needed to archive this object in
407  // a buffer
408  int32 archiveSize() const;
409 
410  void write(Common::MemoryWriteStreamDynamic *out) const;
411 
412  // Return an integer representing the type of this task
413  int16 getType() const;
414 
415  // Determine if the specified task is equivalent to this task
416  bool operator == (const Task &t) const;
417 
418 private:
419  TilePoint destination();
420  TilePoint intermediateDest();
421  bool lineOfSight();
422  bool run();
423 };
424 
425 /* ===================================================================== *
426  GotoObjectTargetTask Class
427  * ===================================================================== */
428 
430  TilePoint _lastTestedLoc;
431  int16 _sightCtr;
432 
433  uint8 _flags;
434 
435  enum {
436  kTrack = (1 << 0),
437  kInSight = (1 << 1)
438  };
439 
440  // static const doesn't work in Visual C++
441  enum {
442  kSightRate = 16
443  };
444 // static const int16 sightRate = 16;
445 
446 protected:
447  TilePoint _lastKnownLoc;
448 
449 public:
450  // Constructor -- initial construction
451  GotoObjectTargetTask(TaskStack *ts, bool trackFlag) :
452  GotoTask(ts),
453  _lastTestedLoc(Nowhere),
454  _sightCtr(0),
455  _flags(trackFlag ? kTrack : 0),
456  _lastKnownLoc(Nowhere) {
457  debugC(2, kDebugTasks, " - GotoObjectTargetTask");
458  _type = "GotoObjectTargetTask";
459  }
460 
462 
463  // Return the number of bytes needed to archive this object in
464  // a buffer
465  int32 archiveSize() const;
466 
467  void write(Common::MemoryWriteStreamDynamic *out) const;
468 
469 private:
470  TilePoint destination();
471  TilePoint intermediateDest();
472  bool lineOfSight();
473 
474  virtual GameObject *getObject() = 0;
475 
476 protected:
477  bool tracking() const {
478  return (_flags & kTrack) != 0;
479  }
480  bool isInSight() const {
481  return (_flags & kInSight) != 0;
482  }
483 };
484 
485 //const int16 GotoObjectTargetTask::sightRate = 16;
486 
487 /* ===================================================================== *
488  GotoObjectTask Class
489  * ===================================================================== */
490 
492  GameObject *_targetObj;
493 
494 public:
495  // Constructor -- initial construction
497  TaskStack *ts,
498  GameObject *obj,
499  bool trackFlag = false) :
500  GotoObjectTargetTask(ts, trackFlag),
501  _targetObj(obj) {
502  debugC(2, kDebugTasks, " - GotoObjectTask");
503  _type = "GotoObjectTask";
504  }
505 
506  GotoObjectTask(Common::InSaveFile *in, TaskID id);
507 
508  // Return the number of bytes needed to archive this object in
509  // a buffer
510  int32 archiveSize() const;
511 
512  void write(Common::MemoryWriteStreamDynamic *out) const;
513 
514  // Return an integer representing the type of this task
515  int16 getType() const;
516 
517  // Determine if the specified task is equivalent to this task
518  bool operator == (const Task &t) const;
519 
520  const GameObject *getTarget() const {
521  return _targetObj;
522  }
523 
524 private:
525  bool run();
526  GameObject *getObject();
527 };
528 
529 /* ===================================================================== *
530  GotoActorTask Class
531  * ===================================================================== */
532 
534  Actor *_targetActor;
535 
536 public:
537  // Constructor -- initial construction
538  GotoActorTask(TaskStack *ts, Actor *a, bool trackFlag = false) :
539  GotoObjectTargetTask(ts, trackFlag),
540  _targetActor(a) {
541  debugC(2, kDebugTasks, " - GotoActorTask");
542  _type = "GotoActorTask";
543  }
544  GotoActorTask(Common::InSaveFile *in, TaskID id);
545 
546  // Return the number of bytes needed to archive this object in
547  // a buffer
548  int32 archiveSize() const;
549 
550  void write(Common::MemoryWriteStreamDynamic *out) const;
551 
552  // Return an integer representing the type of this task
553  int16 getType() const;
554 
555  // Determine if the specified task is equivalent to this task
556  bool operator == (const Task &t) const;
557 
558  const Actor *getTarget() const {
559  return _targetActor;
560  }
561 
562 private:
563  bool run();
564  GameObject *getObject();
565 };
566 
567 /* ===================================================================== *
568  GoAwayFromTask Class
569  * ===================================================================== */
570 
571 class GoAwayFromTask : public Task {
572  GotoLocationTask *_goTask;
573  TaskID _goTaskID;
574 
575  uint8 _flags;
576 
577  enum {
578  kRun = (1 << 0)
579  };
580 
581 public:
582  // Constructor -- initial construction
584  Task(ts),
585  _goTask(NULL),
586  _goTaskID(NoTask),
587  _flags(0) {
588  debugC(2, kDebugTasks, " - GoAwayFromTask1");
589  _type = "GoAwayFromTask";
590  }
591 
592  GoAwayFromTask(TaskStack *ts, bool runFlag) :
593  Task(ts),
594  _goTask(NULL),
595  _goTaskID(NoTask),
596  _flags(runFlag ? kRun : 0) {
597  debugC(2, kDebugTasks, " - GoAwayFromTask2");
598  _type = "GoAwayFromTask";
599  }
600 
601  GoAwayFromTask(Common::InSaveFile *in, TaskID id);
602 
603  // Fixup the subtask pointer
604  void fixup();
605 
606  // Return the number of bytes needed to archive this object in
607  // a buffer
608  int32 archiveSize() const;
609 
610  void write(Common::MemoryWriteStreamDynamic *out) const;
611 
612  void abortTask();
613  TaskResult evaluate();
614  TaskResult update();
615 
616 private:
617  virtual TilePoint getRepulsionVector() = 0;
618 };
619 
620 /* ===================================================================== *
621  GoAwayFromObjectTask Class
622  * ===================================================================== */
623 
625  GameObject *_obj;
626 
627 public:
628  // Constructor -- initial construction
630  GoAwayFromTask(ts),
631  _obj(object) {
632  debugC(2, kDebugTasks, " - GoAwayFromObjectTask");
633  _type = "GoAwayFromObjectTask";
634  }
635 
637 
638  // Return the number of bytes needed to archive this object in
639  // a buffer
640  int32 archiveSize() const;
641 
642  void write(Common::MemoryWriteStreamDynamic *out) const;
643 
644  // Return an integer representing the type of this task
645  int16 getType() const;
646 
647  // Determine if the specified task is equivalent to this task
648  bool operator == (const Task &t) const;
649 
650 private:
651  TilePoint getRepulsionVector();
652 };
653 
654 /* ===================================================================== *
655  GoAwayFromActorTask Class
656  * ===================================================================== */
657 
659  TargetPlaceHolder _targetMem;
660 
661 public:
662  // Constructor -- initial construction
663  GoAwayFromActorTask(TaskStack *ts, Actor *a, bool runFlag = false);
664  GoAwayFromActorTask(TaskStack *ts, const ActorTarget &at, bool runFlag = false);
665 
666  GoAwayFromActorTask(Common::InSaveFile *in, TaskID id);
667 
668  // Return the number of bytes needed to archive this object in
669  // a buffer
670  int32 archiveSize() const;
671 
672  void write(Common::MemoryWriteStreamDynamic *out) const;
673 
674  // Return an integer representing the type of this task
675  int16 getType() const;
676 
677  // Determine if the specified task is equivalent to this task
678  bool operator == (const Task &t) const;
679 
680 private:
681  TilePoint getRepulsionVector();
682 
683  const ActorTarget *getTarget() const {
684  return (const ActorTarget *)_targetMem;
685  }
686 };
687 
688 /* ===================================================================== *
689  HuntTask Class
690  * ===================================================================== */
691 
692 class HuntTask : public Task {
693  Task *_subTask; // This will either be a wander task of a
694  TaskID _subTaskID;
695  // goto task
696  uint8 _huntFlags;
697 
698  enum HuntFlags {
699  kHuntWander = (1 << 0), // Indicates that subtask is a wander task
700  kHuntGoto = (1 << 1) // Indicates that subtask is a goto task
701  };
702 
703 public:
704  // Constructor -- initial construction
705  HuntTask(TaskStack *ts) : Task(ts), _huntFlags(0), _subTask(nullptr), _subTaskID(NoTask) {
706  debugC(2, kDebugTasks, " - HuntTask");
707  _type = "HuntTask";
708  }
709 
710  HuntTask(Common::InSaveFile *in, TaskID id);
711 
712  // Fixup the subtask pointer
713  void fixup();
714 
715  // Return the number of bytes needed to archive this object in
716  // a buffer
717  int32 archiveSize() const;
718 
719  void write(Common::MemoryWriteStreamDynamic *out) const;
720 
721  void abortTask();
722  TaskResult evaluate();
723  TaskResult update();
724 
725 private:
726  void removeWanderTask();
727  void removeGotoTask();
728 
729 protected:
730  virtual void evaluateTarget() = 0;
731 
732  virtual bool targetHasChanged(GotoTask *gotoTarget) = 0;
733  virtual GotoTask *setupGoto() = 0;
734  virtual TilePoint currentTargetLoc() = 0;
735 
736  virtual bool atTarget() = 0;
737  virtual void atTargetabortTask() = 0;
738  virtual TaskResult atTargetEvaluate() = 0;
739  virtual TaskResult atTargetUpdate() = 0;
740 };
741 
742 /* ===================================================================== *
743  HuntLocationTask Class
744  * ===================================================================== */
745 
746 class HuntLocationTask : public HuntTask {
747  TargetPlaceHolder _targetMem;
748 
749 protected:
750  TilePoint _currentTarget;
751 
752 public:
753  // Constructor -- initial construction
754  HuntLocationTask(TaskStack *ts, const Target &t);
755 
756  HuntLocationTask(Common::InSaveFile *in, TaskID id);
757 
758  // Return the number of bytes needed to archive this object in
759  // a buffer
760  int32 archiveSize() const;
761 
762  void write(Common::MemoryWriteStreamDynamic *out) const;
763 
764 protected:
765  bool targetHasChanged(GotoTask *gotoTarget);
766  GotoTask *setupGoto();
767  TilePoint currentTargetLoc();
768 
769  const Target *getTarget() const {
770  return (const Target *)_targetMem;
771  }
772 };
773 
774 /* ===================================================================== *
775  HuntToBeNearLocationTask Class
776  * ===================================================================== */
777 
779  uint16 _range;
780 
781  uint8 _targetEvaluateCtr;
782 
783  // static const doesn't work in Visual C++
784  enum {
785  kTargetEvaluateRate = 64
786  };
787 // static const uint8 kTargetEvaluateRate;
788 
789 public:
790  // Constructor -- initial construction
791  HuntToBeNearLocationTask(TaskStack *ts, const Target &t, uint16 r) :
792  HuntLocationTask(ts, t),
793  _range(r),
794  _targetEvaluateCtr(0) {
795  debugC(2, kDebugTasks, " - HuntToBeNearLocationTask");
796  _type = "HuntToBeNearLocationTask";
797  }
798 
800 
801  // Return the number of bytes needed to archive this object in
802  // a buffer
803  int32 archiveSize() const;
804 
805  void write(Common::MemoryWriteStreamDynamic *out) const;
806 
807  // Return an integer representing the type of this task
808  int16 getType() const;
809 
810  // Determine if the specified task is equivalent to this task
811  bool operator == (const Task &t) const;
812 
813 protected:
814  void evaluateTarget();
815 
816  bool atTarget();
817 
818  void atTargetabortTask();
819  TaskResult atTargetEvaluate();
820  TaskResult atTargetUpdate();
821 
822  uint16 getRange() const {
823  return _range;
824  }
825 };
826 
827 //const uint8 HuntToBeNearLocationTask::kTargetEvaluateRate = 64;
828 
829 /* ===================================================================== *
830  HuntObjectTask Class
831  * ===================================================================== */
832 
833 class HuntObjectTask : public HuntTask {
834  TargetPlaceHolder _targetMem;
835 
836 protected:
837  GameObject *_currentTarget;
838 
839 public:
840  // Constructor -- initial construction
841  HuntObjectTask(TaskStack *ts, const ObjectTarget &ot);
842 
843  HuntObjectTask(Common::InSaveFile *in, TaskID id);
844 
845  // Return the number of bytes needed to archive this object in
846  // a buffer
847  int32 archiveSize() const;
848 
849  void write(Common::MemoryWriteStreamDynamic *out) const;
850 
851 protected:
852  bool targetHasChanged(GotoTask *gotoTarget);
853  GotoTask *setupGoto();
854  TilePoint currentTargetLoc();
855 
856  const ObjectTarget *getTarget() const {
857  return (const ObjectTarget *)_targetMem;
858  }
859 };
860 
861 /* ===================================================================== *
862  HuntToBeNearObjectTask Class
863  * ===================================================================== */
864 
866  uint16 _range;
867 
868  uint8 _targetEvaluateCtr;
869 
870  enum {
871  kTargetEvaluateRate = 64
872  };
873 // static const uint8 kTargetEvaluateRate;
874 
875 public:
876  // Constructor -- initial construction
878  TaskStack *ts,
879  const ObjectTarget &ot,
880  uint16 r) :
881  HuntObjectTask(ts, ot),
882  _range(r),
883  _targetEvaluateCtr(0) {
884  debugC(2, kDebugTasks, " - HuntToBeNearObjectTask");
885  _type = "HuntToBeNearObjectTask";
886  }
887 
889 
890  // Return the number of bytes needed to archive this object in
891  // a buffer
892  int32 archiveSize() const;
893 
894  void write(Common::MemoryWriteStreamDynamic *out) const;
895 
896  // Return an integer representing the type of this task
897  int16 getType() const;
898 
899  // Determine if the specified task is equivalent to this task
900  bool operator == (const Task &t) const;
901 
902 protected:
903  void evaluateTarget();
904 
905  bool atTarget();
906 
907  void atTargetabortTask();
908  TaskResult atTargetEvaluate();
909  TaskResult atTargetUpdate();
910 
911  uint16 getRange() const {
912  return _range;
913  }
914 };
915 
916 //const uint8 HuntToBeNearObjectTask::kTargetEvaluateRate = 64;
917 
918 /* ===================================================================== *
919  HuntToPossessTask Class
920  * ===================================================================== */
921 
923  uint8 _targetEvaluateCtr;
924 
925  enum {
926  kTargetEvaluateRate = 64
927  };
928 // static const uint8 kTargetEvaluateRate;
929 
930  bool _grabFlag;
931 
932 public:
933  // Constructor -- initial construction
934  HuntToPossessTask(TaskStack *ts, const ObjectTarget &ot) :
935  HuntObjectTask(ts, ot),
936  _targetEvaluateCtr(0),
937  _grabFlag(false) {
938  debugC(2, kDebugTasks, " - HuntToPossessTask");
939  _type = "HuntToPossessTask";
940  }
941 
942  HuntToPossessTask(Common::InSaveFile *in, TaskID id);
943 
944  // Return the number of bytes needed to archive this object in
945  // a buffer
946  int32 archiveSize() const;
947 
948  void write(Common::MemoryWriteStreamDynamic *out) const;
949 
950  // Return an integer representing the type of this task
951  int16 getType() const;
952 
953  // Determine if the specified task is equivalent to this task
954  bool operator == (const Task &t) const;
955 
956 protected:
957  void evaluateTarget();
958  bool atTarget();
959 
960  void atTargetabortTask();
961  TaskResult atTargetEvaluate();
962  TaskResult atTargetUpdate();
963 };
964 
965 //const uint8 HuntToPossessTask::kTargetEvaluateRate = 16;
966 
967 /* ===================================================================== *
968  HuntActorTask Class
969  * ===================================================================== */
970 
971 class HuntActorTask : public HuntTask {
972  TargetPlaceHolder _targetMem;
973  uint8 _flags;
974 
975  enum {
976  kTrack = (1 << 0)
977  };
978 
979 protected:
980  Actor *_currentTarget;
981 
982 public:
983  // Constructor -- initial construction
985  TaskStack *ts,
986  const ActorTarget &at,
987  bool trackFlag);
988 
989  HuntActorTask(Common::InSaveFile *in, TaskID id);
990 
991  // Return the number of bytes needed to archive this object in
992  // a buffer
993  int32 archiveSize() const;
994 
995  void write(Common::MemoryWriteStreamDynamic *out) const;
996 
997 protected:
998  bool targetHasChanged(GotoTask *gotoTarget);
999  GotoTask *setupGoto();
1000  TilePoint currentTargetLoc();
1001 
1002  const ActorTarget *getTarget() const {
1003  return (const ActorTarget *)_targetMem;
1004  }
1005 
1006  bool tracking() const {
1007  return (_flags & kTrack) != 0;
1008  }
1009 };
1010 
1011 /* ===================================================================== *
1012  HuntToBeNearActorTask Class
1013  * ===================================================================== */
1014 
1016  GoAwayFromObjectTask *_goAway; // The 'go away' sub task pointer
1017  TaskID _goAwayID;
1018  uint16 _range; // Maximum range
1019 
1020  uint8 _targetEvaluateCtr;
1021 
1022  enum {
1023  kTargetEvaluateRate = 16
1024  };
1025 // static const uint8 kTargetEvaluateRate;
1026 
1027 public:
1028 
1029  enum {
1030  kTooClose = 12
1031  };
1032 
1033  // Constructor -- initial construction
1035  TaskStack *ts,
1036  const ActorTarget &at,
1037  uint16 r,
1038  bool trackFlag = false) :
1039  HuntActorTask(ts, at, trackFlag),
1040  _goAway(NULL),
1041  _goAwayID(NoTask),
1042  _range(MAX<uint16>(r, 16)),
1043  _targetEvaluateCtr(0) {
1044  debugC(2, kDebugTasks, " - HuntToBeNearActorTask");
1045  _type = "HuntToBeNearActorTask";
1046  }
1047 
1048  HuntToBeNearActorTask(Common::InSaveFile *in, TaskID id);
1049 
1050  // Fixup the subtask pointer
1051  void fixup();
1052 
1053  // Return the number of bytes needed to archive this object in
1054  // a buffer
1055  int32 archiveSize() const;
1056 
1057  void write(Common::MemoryWriteStreamDynamic *out) const;
1058 
1059  // Return an integer representing the type of this task
1060  int16 getType() const;
1061 
1062  // Determine if the specified task is equivalent to this task
1063  bool operator == (const Task &t) const;
1064 
1065 protected:
1066  void evaluateTarget();
1067 
1068  bool atTarget();
1069 
1070  void atTargetabortTask();
1071  TaskResult atTargetEvaluate();
1072  TaskResult atTargetUpdate();
1073 
1074  uint16 getRange() const {
1075  return _range;
1076  }
1077 };
1078 
1079 //const uint8 HuntToBeNearActorTask::kTargetEvaluateRate = 64;
1080 
1081 /* ===================================================================== *
1082  HuntToKillTask Class
1083  * ===================================================================== */
1084 
1086  uint8 _targetEvaluateCtr;
1087  uint8 _specialAttackCtr;
1088 
1089  enum {
1090  kTargetEvaluateRate = 16
1091  };
1092 
1093  enum {
1094  kCurrentWeaponBonus = 1
1095  };
1096 
1097  uint8 _flags;
1098 
1099  enum {
1100  kEvalWeapon = (1 << 0)
1101  };
1102 // static const uint8 kTargetEvaluateRate;
1103 
1104 public:
1105  // Constructor -- initial construction
1107  TaskStack *ts,
1108  const ActorTarget &at,
1109  bool trackFlag = false);
1110 
1111  HuntToKillTask(Common::InSaveFile *in, TaskID id);
1112 
1113  // Return the number of bytes needed to archive this object in
1114  // a buffer
1115  int32 archiveSize() const;
1116 
1117  void write(Common::MemoryWriteStreamDynamic *out) const;
1118 
1119  // Return an integer representing the type of this task
1120  int16 getType() const;
1121 
1122  // Determine if the specified task is equivalent to this task
1123  bool operator == (const Task &t) const;
1124 
1125  void abortTask();
1126  TaskResult update();
1127 
1128 protected:
1129  void evaluateTarget();
1130  bool atTarget();
1131 
1132  void atTargetabortTask();
1133  TaskResult atTargetEvaluate();
1134  TaskResult atTargetUpdate();
1135 
1136 private:
1137  void evaluateWeapon();
1138 };
1139 
1140 //const uint8 HuntToKillTask::kTargetEvaluateRate = 16;
1141 
1142 // Utility function used for combat target selection
1143 inline int16 closenessScore(int16 dist) {
1144  return 128 / dist;
1145 }
1146 
1147 /* ===================================================================== *
1148  HuntToGiveTask Class
1149  * ===================================================================== */
1150 
1152  GameObject *_objToGive;
1153 
1154 public:
1155  // Constructor -- initial construction
1157  TaskStack *ts,
1158  const ActorTarget &at,
1159  GameObject *obj,
1160  bool trackFlag = false) :
1161  HuntActorTask(ts, at, trackFlag),
1162  _objToGive(obj) {
1163  debugC(2, kDebugTasks, " - HuntToGiveTask");
1164  _type = "HuntToGiveTask";
1165  }
1166 
1167  HuntToGiveTask(Common::InSaveFile *in, TaskID id);
1168 
1169  // Return the number of bytes needed to archive this object in
1170  // a buffer
1171  int32 archiveSize() const;
1172 
1173  void write(Common::MemoryWriteStreamDynamic *out) const;
1174 
1175  // Return an integer representing the type of this task
1176  int16 getType() const;
1177 
1178  // Determine if the specified task is equivalent to this task
1179  bool operator == (const Task &t) const;
1180 
1181 protected:
1182  void evaluateTarget();
1183  bool atTarget();
1184 
1185  void atTargetabortTask();
1186  TaskResult atTargetEvaluate();
1187  TaskResult atTargetUpdate();
1188 };
1189 
1190 /* ===================================================================== *
1191  BandTask Class
1192  * ===================================================================== */
1193 
1194 class AttendTask;
1195 
1196 class BandTask : public HuntTask {
1197  AttendTask *_attend;
1198  TaskID _attendID;
1199 
1200  TilePoint _currentTarget;
1201  uint8 _targetEvaluateCtr;
1202 
1203  enum {
1204  kTargetEvaluateRate = 2
1205  };
1206 
1207 public:
1208 
1210  public:
1211  virtual ~RepulsorIterator() {}
1212 
1213  virtual bool first(
1214  TilePoint &repulsorVector,
1215  int16 &repulsorStrength) = 0;
1216 
1217  virtual bool next(
1218  TilePoint &repulsorVector,
1219  int16 &repulsorStrength) = 0;
1220  };
1221 
1223  protected:
1224  Actor *_a;
1225 
1226  private:
1227  Band *_band;
1228  int _bandIndex;
1229 
1230  public:
1231  BandingRepulsorIterator(Actor *actor) : _a(actor), _band(nullptr), _bandIndex(0) {}
1232 
1233  bool first(
1234  TilePoint &repulsorVector,
1235  int16 &repulsorStrength);
1236 
1237  bool next(
1238  TilePoint &repulsorVector,
1239  int16 &repulsorStrength);
1240  };
1241 
1242 
1243  // This class should be nested in the BandAndAvoidEnemiesTask class
1244  // but Visual C++ 4.0 is lame and won't let the
1245  // BandAndAvoidEnemiesTask inherit the BandingRepulsorIterator class
1246  // even though it is explicitly declared protected and not private.
1247  // Watcom C++, however, works correctly.
1249  Actor *_actorArray[6];
1250  int _numActors,
1251  _actorIndex;
1252  bool _iteratingThruEnemies;
1253 
1254  public:
1256  BandingRepulsorIterator(actor), _numActors(0), _actorIndex(0), _iteratingThruEnemies(false) {
1257  for (int i = 0; i < 6; i++)
1258  _actorArray[i] = 0;
1259  }
1260 
1261  private:
1262  bool firstEnemyRepulsor(
1263  TilePoint &repulsorVector,
1264  int16 &repulsorStrength);
1265 
1266  bool nextEnemyRepulsor(
1267  TilePoint &repulsorVector,
1268  int16 &repulsorStrength);
1269 
1270  public:
1271  bool first(
1272  TilePoint &repulsorVector,
1273  int16 &repulsorStrength);
1274 
1275  bool next(
1276  TilePoint &repulsorVector,
1277  int16 &repulsorStrength);
1278  };
1279 
1280 public:
1281  // Constructor -- initial construction
1282  BandTask(TaskStack *ts) :
1283  HuntTask(ts),
1284  _attend(NULL),
1285  _attendID(NoTask),
1286  _currentTarget(Nowhere),
1287  _targetEvaluateCtr(0) {
1288  debugC(2, kDebugTasks, " - BandTask");
1289  _type = "BandTask";
1290  }
1291 
1292  BandTask(Common::InSaveFile *in, TaskID id);
1293 
1294  // Fixup the subtask pointer
1295  void fixup();
1296 
1297  // Return the number of bytes needed to archive this object in
1298  // a buffer
1299  int32 archiveSize() const;
1300 
1301  void write(Common::MemoryWriteStreamDynamic *out) const;
1302 
1303  // Return an integer representing the type of this task
1304  int16 getType() const;
1305 
1306  // Determine if the specified task is equivalent to this task
1307  bool operator == (const Task &t) const;
1308 
1309 protected:
1310  void evaluateTarget();
1311 
1312  bool targetHasChanged(GotoTask *gotoTarget);
1313  GotoTask *setupGoto();
1314  TilePoint currentTargetLoc();
1315 
1316  bool atTarget();
1317 
1318  void atTargetabortTask();
1319  TaskResult atTargetEvaluate();
1320  TaskResult atTargetUpdate();
1321 
1322  virtual int16 getRunThreshold();
1323  virtual RepulsorIterator *getNewRepulsorIterator();
1324 };
1325 
1326 /* ===================================================================== *
1327  BandAndAvoidEnemiesTask Class
1328  * ===================================================================== */
1329 
1331 protected:
1332  // I had to move this nested class up to the BandTask class because
1333  // Visual C++ is lame.
1334  /* class BandAndAvoidEnemiesRepulsorIterator : public BandingRepulsorIterator {
1335  Actor *_actorArray[6];
1336  int _numActors,
1337  _actorIndex;
1338  bool _iteratingThruEnemies;
1339 
1340  public:
1341  BandAndAvoidEnemiesRepulsorIterator(Actor *actor) :
1342  BandingRepulsorIterator(actor) {}
1343 
1344  private:
1345  bool firstEnemyRepulsor(
1346  TilePoint &repulsorVector,
1347  int16 &repulsorStrength);
1348 
1349  bool nextEnemyRepulsor(
1350  TilePoint &repulsorVector,
1351  int16 &repulsorStrength);
1352 
1353  public:
1354  bool first(
1355  TilePoint &repulsorVector,
1356  int16 &repulsorStrength);
1357 
1358  bool next(
1359  TilePoint &repulsorVector,
1360  int16 &repulsorStrength);
1361  };
1362  */
1363 public:
1364  // Constructor -- initial constructor
1366 
1367  BandAndAvoidEnemiesTask(Common::InSaveFile *in, TaskID id) : BandTask(in, id) {}
1368 
1369  // Return an integer representing the type of this task
1370  int16 getType() const;
1371 
1372  // Determine if the specified task is equivalent to this task
1373  bool operator == (const Task &t) const;
1374 
1375 protected:
1376  int16 getRunThreshold();
1377  RepulsorIterator *getNewRepulsorIterator();
1378 };
1379 
1380 /* ===================================================================== *
1381  FollowPatrolRouteTask Class
1382  * ===================================================================== */
1383 
1384 class FollowPatrolRouteTask : public Task {
1385  GotoLocationTask *_gotoWayPoint; // A goto waypoint sub task
1386  TaskID _gotoWayPointID;
1387  // pointer.
1388  PatrolRouteIterator _patrolIter; // The patrol route iterator.
1389  int16 _lastWayPointNum; // Waypoint at which to end
1390  // this task.
1391  bool _paused; // Flag indicating "paused"ness
1392  // of this task
1393  int16 _counter; // Counter for tracking pause
1394  // length
1395 
1396 public:
1397  // Constructor -- initial construction
1399  TaskStack *ts,
1400  PatrolRouteIterator iter,
1401  int16 stopAt = -1) :
1402  Task(ts),
1403  _gotoWayPoint(NULL),
1404  _gotoWayPointID(NoTask),
1405  _patrolIter(iter),
1406  _lastWayPointNum(stopAt), _counter(0) {
1407  debugC(2, kDebugTasks, " - FollowPatrolRouteTask");
1408  _type = "FollowPatrolRouteTask";
1409  followPatrolRoute();
1410  }
1411 
1412  FollowPatrolRouteTask(Common::InSaveFile *in, TaskID id);
1413 
1414  // Fixup the subtask pointer
1415  void fixup();
1416 
1417  // Return the number of bytes needed to archive this object in
1418  // a buffer
1419  int32 archiveSize() const;
1420 
1421  void write(Common::MemoryWriteStreamDynamic *out) const;
1422 
1423  // Return an integer representing the type of this task
1424  int16 getType() const;
1425 
1426  void abortTask();
1427  TaskResult evaluate();
1428  TaskResult update();
1429 
1430  // Determine if the specified task is equivalent to this task
1431  bool operator == (const Task &t) const;
1432 
1433  // Update function used if this task is not paused
1434  TaskResult handleFollowPatrolRoute();
1435 
1436  // Update function used if this task is paused
1437  TaskResult handlePaused();
1438 
1439  // Set this task into the paused state
1440  void pause();
1441 
1442  // Set this task into the unpaused state
1443  void followPatrolRoute() {
1444  _paused = false;
1445  }
1446 };
1447 
1448 /* ===================================================================== *
1449  AttendTask Class
1450  * ===================================================================== */
1451 
1452 class AttendTask : public Task {
1453  GameObject *_obj;
1454 
1455 public:
1456  // Constructor -- initial construction
1457  AttendTask(TaskStack *ts, GameObject *o) : Task(ts), _obj(o) {
1458  debugC(2, kDebugTasks, " - AttendTask");
1459  _type = "AttendTask";
1460  }
1461 
1462  AttendTask(Common::InSaveFile *in, TaskID id);
1463 
1464  // Return the number of bytes needed to archive this object in
1465  // a buffer
1466  int32 archiveSize() const;
1467 
1468  void write(Common::MemoryWriteStreamDynamic *out) const;
1469 
1470  // Return an integer representing the type of this task
1471  int16 getType() const;
1472 
1473  void abortTask();
1474  TaskResult evaluate();
1475  TaskResult update();
1476 
1477  // Determine if the specified task is equivalent to this task
1478  bool operator == (const Task &t) const;
1479 };
1480 
1481 #if 0
1482 
1483 // The defend task is no longer necessary
1484 
1485 /* ===================================================================== *
1486  DefendTask Class
1487  * ===================================================================== */
1488 
1489 class DefendTask : public Task {
1490  Actor *_attacker;
1491 
1492  Task *_subTask;
1493 
1494 public:
1495  // Constructor -- initial construction
1496  DefendTask(TaskStack *ts, Actor *a) : Task(ts), _attacker(a), _subTask(NULL) {}
1497 
1498  // Fixup the subtask pointer
1499  void fixup();
1500 
1501  // Return the number of bytes needed to archive this object in
1502  // a buffer
1503  int32 archiveSize() const;
1504 
1505  // Return an integer representing the type of this task
1506  int16 getType() const;
1507 
1508  void abortTask();
1509  TaskResult evaluate();
1510  TaskResult update();
1511 
1512  // Determine if the specified task is equivalent to this task
1513  bool operator == (const Task &t) const;
1514 };
1515 
1516 /* ===================================================================== *
1517  ParryTask Class
1518  * ===================================================================== */
1519 
1520 class ParryTask : public Task {
1521  Actor *_attacker;
1522  GameObject *_defenseObj;
1523 
1524  uint8 _flags;
1525 
1526  enum {
1527  kMotionStarted = (1 << 0),
1528  kBlockStarted = (1 << 1)
1529  };
1530 
1531 public:
1532  // Constructor -- initial construction
1533  ParryTask(TaskStack *ts, Actor *a, GameObject *obj) :
1534  Task(ts),
1535  _attacker(a),
1536  _defenseObj(obj),
1537  _flags(0) {
1538  }
1539 
1540  // Return the number of bytes needed to archive this object in
1541  // a buffer
1542  int32 archiveSize() const;
1543 
1544  // Return an integer representing the type of this task
1545  int16 getType() const;
1546 
1547  void abortTask();
1548  TaskResult evaluate();
1549  TaskResult update();
1550 
1551  // Determine if the specified task is equivalent to this task
1552  bool operator == (const Task &t) const;
1553 };
1554 
1555 #endif
1556 
1557 /* ===================================================================== *
1558  TaskStack Class
1559  * ===================================================================== */
1560 
1561 // This class contains data common to all task's in an actor task
1562 // stack. Also, this class manages the automatic task reevaluation.
1563 class TaskStack {
1564 
1565  TaskID _stackBottomID; // Bottom task in stack
1566 
1567  int16 _evalCount, // Counter for automatic task re-evaluation
1568  _evalRate; // Rate of automatic task re-evalutation
1569 public:
1570  Actor *_actor; // Pointer to actor performing tasks
1571 
1572  // Constructor
1573  TaskStack() :
1574  _stackBottomID(0),
1575  _evalCount(0),
1576  _evalRate(0),
1577  _actor(nullptr) {}
1578 
1579  TaskStack(Actor *a) :
1580  _stackBottomID(NoTask),
1581  _actor(a),
1582  _evalCount(kDefaultEvalRate),
1583  _evalRate(kDefaultEvalRate) {
1584 
1585  newTaskStack(this);
1586  }
1587 
1588  // Destructor
1589  ~TaskStack() {
1590  if (_actor)
1591  _actor->_curTask = nullptr;
1592  deleteTaskStack(this);
1593  }
1594 
1595  // Return the number of bytes necessary to archive this TaskStack
1596  // in a buffer
1597  int32 archiveSize() {
1598  return sizeof(ObjectID) // actor's id
1599  + sizeof(_stackBottomID)
1600  + sizeof(_evalCount)
1601  + sizeof(_evalRate);
1602  }
1603 
1604  void write(Common::MemoryWriteStreamDynamic *out);
1605 
1606  void read(Common::InSaveFile *in);
1607 
1608  // Set the bottom task of this task stack
1609  void setTask(Task *t);
1610 
1611  // Return a pointer to the bottom task in this task stack
1612  const Task *getTask() {
1613  return _stackBottomID != NoTask
1614  ? getTaskAddress(_stackBottomID)
1615  : NULL;
1616  }
1617 
1618  Actor *getActor() {
1619  return _actor;
1620  }
1621 
1622  // Abort all tasks in stack
1623  void abortTask();
1624  // Re-evaluate tasks in stack
1625  TaskResult evaluate();
1626  // Update the state of the tasks in stack
1627  TaskResult update();
1628 };
1629 
1630 } // end of namespace Saga2
1631 
1632 #endif
Definition: task.h:177
Definition: task.h:331
Definition: str.h:59
Definition: task.h:658
Definition: task.h:122
Definition: task.h:429
Definition: savefile.h:54
Definition: task.h:746
Definition: target.h:135
Definition: target.h:401
Definition: task.h:778
Definition: actor.h:32
Definition: task.h:1384
Definition: task.h:1085
Definition: memstream.h:194
Definition: tcoords.h:127
Definition: stream.h:745
Definition: actor.h:589
Definition: task.h:1196
Definition: task.h:533
Definition: band.h:115
Definition: patrol.h:115
Definition: task.h:692
Definition: task.h:1151
Definition: task.h:381
Definition: task.h:232
Definition: objects.h:118
Definition: task.h:624
Definition: task.h:865
Definition: target.h:530
Definition: task.h:1209
Definition: task.h:922
Definition: task.h:1452
Definition: task.h:971
Definition: task.h:289
void void void void void debugC(int level, uint32 debugChannels, MSVC_PRINTF const char *s,...) GCC_PRINTF(3
Definition: task.h:833
Definition: task.h:571
Definition: task.h:1563
Definition: task.h:1015
Definition: task.h:1330
Definition: task.h:491