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