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