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 #include "saga2/saga2.h"
28 #include "saga2/actor.h"
29 #include "saga2/assign.h"
30 #include "saga2/calender.h"
31 #include "saga2/task.h"
32 #include "saga2/tile.h"
33
34 namespace Saga2 {
35
36 const uint16 kIndefiniteTime = CalenderTime::kFramesPerDay;
37
38 /* ===================================================================== *
39 ActorAssignment member functions
40 * ===================================================================== */
41
42 // Constructor
ActorAssignment(Actor * a,uint16 until)43 ActorAssignment::ActorAssignment(Actor *a, uint16 until) :
44 _startFrame(g_vm->_calender->frameInDay()),
45 _endFrame(until) {
46 _actor = a;
47 debugC(2, kDebugActors, "New assignment for %p (%s) from %d until %d: %p",
48 (void *)a, a->objName(), _startFrame, _endFrame, (void *)this);
49 a->_assignment = this;
50 a->_flags |= hasAssignment;
51 }
52
ActorAssignment(Actor * ac,Common::SeekableReadStream * stream)53 ActorAssignment::ActorAssignment(Actor *ac, Common::SeekableReadStream *stream) {
54 _startFrame = stream->readUint16LE();
55 _endFrame = stream->readUint16LE();
56
57 _actor = ac;
58 ac->_assignment = this;
59 ac->_flags |= hasAssignment;
60 }
61
62 //----------------------------------------------------------------------
63 // ActorAssignment destructor
64
~ActorAssignment(void)65 ActorAssignment::~ActorAssignment(void) {
66 Actor *a = getActor();
67 debugC(2, kDebugActors, "Ending assignment for %p (%s): %p",
68 (void *)a, a->objName(), (void *)this);
69
70 // Determine if the actor has a task initiated by this assignment
71 if (a->_currentGoal == actorGoalFollowAssignment
72 && a->_curTask != NULL) {
73 // If so, abort it
74 a->_curTask->abortTask();
75 delete a->_curTask;
76 a->_curTask = NULL;
77 }
78
79 a->_flags &= ~hasAssignment;
80 }
81
82 //----------------------------------------------------------------------
83 // Return the number of bytes need to archive the data in this
84 // assignment
85
archiveSize(void) const86 inline int32 ActorAssignment::archiveSize(void) const {
87 return sizeof(_startFrame) + sizeof(_endFrame);
88 }
89
write(Common::MemoryWriteStreamDynamic * out) const90 void ActorAssignment::write(Common::MemoryWriteStreamDynamic *out) const {
91 out->writeUint16LE(_startFrame);
92 out->writeUint16LE(_endFrame);
93 }
94
95 //----------------------------------------------------------------------
96 // Determine if the time limit for this assignment has been exceeded
97
isValid(void)98 bool ActorAssignment::isValid(void) {
99 uint16 frame = g_vm->_calender->frameInDay();
100
101 return frame < _endFrame
102 || (_startFrame >= _endFrame && frame >= _startFrame);
103 }
104
105 //----------------------------------------------------------------------
106 // Create a TaskStack for this actor and plug in the assignment's Task.
107
createTask(void)108 TaskStack *ActorAssignment::createTask(void) {
109 if (!taskNeeded()) return NULL;
110
111 Actor *a = getActor();
112 TaskStack *ts = NULL;
113
114 if ((ts = newTaskStack(a)) != NULL) {
115 Task *task = getTask(ts);
116
117 if (task != NULL)
118 ts->setTask(task);
119 else {
120 delete ts;
121 ts = NULL;
122 }
123 }
124
125 return ts;
126 }
127
getActor(void) const128 Actor *ActorAssignment::getActor(void) const {
129 return _actor;
130 }
131
132
133 //----------------------------------------------------------------------
134 // This function is called to notify the assignment of the completion
135 // of a task which the assignment had created.
136
handleTaskCompletion(TaskResult)137 void ActorAssignment::handleTaskCompletion(TaskResult) {
138 // Do nothing
139 }
140
141 //----------------------------------------------------------------------
142 // Plug a new task into the actor, if the actor is currently following
143 // his assignment
144
startTask(void)145 void ActorAssignment::startTask(void) {
146 Actor *a = getActor();
147
148 if (a->_currentGoal == actorGoalFollowAssignment)
149 a->_curTask = createTask();
150 }
151
152 //----------------------------------------------------------------------
153 // Determine if this assignment needs to create a task at this time
154
taskNeeded(void)155 bool ActorAssignment::taskNeeded(void) {
156 return true;
157 }
158
159 /* ===================================================================== *
160 PatrolRouteAssignment member functions
161 * ===================================================================== */
162
163 //----------------------------------------------------------------------
164 // Constructor -- initial object construction
165
PatrolRouteAssignment(Actor * a,uint16 until,int16 rteNo,uint8 patrolFlags,int16 start,int16 end)166 PatrolRouteAssignment::PatrolRouteAssignment(
167 Actor *a,
168 uint16 until,
169 int16 rteNo,
170 uint8 patrolFlags,
171 int16 start,
172 int16 end) :
173 ActorAssignment(a, until),
174 _routeNo(rteNo),
175 _startingWayPoint(start),
176 _endingWayPoint(end),
177 _routeFlags(patrolFlags),
178 _flags(0) {
179 }
180
PatrolRouteAssignment(Actor * a,Common::SeekableReadStream * stream)181 PatrolRouteAssignment::PatrolRouteAssignment(Actor *a, Common::SeekableReadStream *stream) :
182 ActorAssignment(a, stream) {
183 debugC(4, kDebugSaveload, "... Loading PatrolRouteAssignment");
184
185 // Restore route number
186 _routeNo = stream->readSint16LE();
187 // Restore the starting way point
188 _startingWayPoint = stream->readSint16LE();
189 // Restore the ending way point
190 _endingWayPoint = stream->readSint16LE();
191
192 // Restore the route flags
193 _routeFlags = stream->readByte();
194 // Restore the assignment flags
195 _flags = stream->readByte();
196 }
197
198 //----------------------------------------------------------------------
199 // Return the number of bytes need to archive the data in this
200 // assignment
201
archiveSize(void) const202 inline int32 PatrolRouteAssignment::archiveSize(void) const {
203 return ActorAssignment::archiveSize()
204 + sizeof(_routeNo)
205 + sizeof(_startingWayPoint)
206 + sizeof(_endingWayPoint)
207 + sizeof(_routeFlags)
208 + sizeof(_flags);
209 }
210
write(Common::MemoryWriteStreamDynamic * out) const211 void PatrolRouteAssignment::write(Common::MemoryWriteStreamDynamic *out) const {
212 debugC(3, kDebugSaveload, "... Saving PatrolRouteAssignment");
213
214 // Let the base class write its data to the buffer
215 ActorAssignment::write(out);
216
217 // Store the route number
218 out->writeSint16LE(_routeNo);
219 out->writeSint16LE(_startingWayPoint);
220 out->writeSint16LE(_endingWayPoint);
221
222 // Store the route flags
223 out->writeByte(_routeFlags);
224 // Store the assignment flags
225 out->writeByte(_flags);
226 }
227
228 //----------------------------------------------------------------------
229 // Return an integer representing the class of this object for archival
230 // reasons.
231
type(void) const232 int16 PatrolRouteAssignment::type(void) const {
233 return patrolRouteAssignment;
234 }
235
236 //----------------------------------------------------------------------
237 // This function is called to notify the assignment of the completion
238 // of a task which the assignment had created.
239
handleTaskCompletion(TaskResult result)240 void PatrolRouteAssignment::handleTaskCompletion(TaskResult result) {
241 if (result == taskSucceeded) _flags |= routeCompleted;
242 }
243
244 //----------------------------------------------------------------------
245 // Determine if assignment is still valid
246
isValid(void)247 bool PatrolRouteAssignment::isValid(void) {
248 // If the route has already been completed, then the assignment is
249 // no longer valid
250 if (_flags & routeCompleted) return false;
251
252 return ActorAssignment::isValid();
253 }
254
255 //----------------------------------------------------------------------
256 // Determine if this assignment needs to create a task at this time
257
taskNeeded(void)258 bool PatrolRouteAssignment::taskNeeded(void) {
259 // If the route has already been completed, then no task is needed
260 return !(_flags & routeCompleted);
261 }
262
263 //----------------------------------------------------------------------
264 // Construct a Task for this assignment
265
getTask(TaskStack * ts)266 Task *PatrolRouteAssignment::getTask(TaskStack *ts) {
267 int16 startPoint = _startingWayPoint;
268 uint8 mapNum = getActor()->getMapNum();
269
270 _startingWayPoint = -1;
271
272 if (startPoint == -1) {
273 int16 i;
274 uint16 bestDist = maxuint16;
275 const PatrolRoute &route = patrolRouteList[mapNum]->getRoute(_routeNo);
276 TilePoint actorLoc = getActor()->getLocation();
277
278 for (i = 0; i < route.vertices(); i++) {
279 uint16 dist = lineDist(route[i], route[(i + 1) % route.vertices()], actorLoc);
280
281 if (dist < bestDist) {
282 bestDist = dist;
283 startPoint = (_routeFlags & patrolRouteReverse) ? i : (i + 1) % route.vertices();
284 }
285 }
286 }
287
288 // Construct a patrol route iterator.
289 PatrolRouteIterator
290 iter = PatrolRouteIterator(
291 mapNum,
292 _routeNo,
293 _routeFlags,
294 startPoint);
295
296 // Construct a FollowPatrolRouteTask
297 return _endingWayPoint != -1
298 ? new FollowPatrolRouteTask(ts, iter, _endingWayPoint)
299 : new FollowPatrolRouteTask(ts, iter);
300 }
301
302 /* ===================================================================== *
303 HuntToBeNearLocationAssignment member functions
304 * ===================================================================== */
305
HuntToBeNearLocationAssignment(Actor * a,const TilePoint & tp,uint16 r)306 HuntToBeNearLocationAssignment::HuntToBeNearLocationAssignment(Actor *a, const TilePoint &tp, uint16 r) :
307 ActorAssignment(a, kIndefiniteTime) {
308 initialize(LocationTarget(tp), r);
309 }
310
311 // Construct with no time limit and an abstract target
HuntToBeNearLocationAssignment(Actor * a,const Target & targ,uint16 r)312 HuntToBeNearLocationAssignment::HuntToBeNearLocationAssignment(Actor *a, const Target &targ, uint16 r) :
313 ActorAssignment(a, kIndefiniteTime) {
314 initialize(targ, r);
315 }
316
317 //----------------------------------------------------------------------
318 // An initialization function which provides a common ground for
319 // the initial constructors.
320
initialize(const Target & targ,uint16 r)321 void HuntToBeNearLocationAssignment::initialize(
322 const Target &targ,
323 uint16 r) {
324 assert(targ.size() <= sizeof(_targetMem));
325 // Make a copy of the target
326 targ.clone(_targetMem);
327
328 _range = r;
329 }
330
HuntToBeNearLocationAssignment(Actor * a,Common::SeekableReadStream * stream)331 HuntToBeNearLocationAssignment::HuntToBeNearLocationAssignment(Actor *a, Common::SeekableReadStream *stream) :
332 ActorAssignment(a, stream) {
333 debugC(4, kDebugSaveload, "... Loading HuntToBeNearLocationAssignment");
334
335 // Restore the target
336 readTarget(_targetMem, stream);
337
338 // Restore the range
339 _range = stream->readUint16LE();
340 }
341
342 //----------------------------------------------------------------------
343 // Return the number of bytes need to archive the data in this
344 // assignment
345
archiveSize(void) const346 inline int32 HuntToBeNearLocationAssignment::archiveSize(void) const {
347 return ActorAssignment::archiveSize()
348 + targetArchiveSize(getTarget())
349 + sizeof(_range);
350 }
351
write(Common::MemoryWriteStreamDynamic * out) const352 void HuntToBeNearLocationAssignment::write(Common::MemoryWriteStreamDynamic *out) const {
353 debugC(3, kDebugSaveload, "... Saving HuntToBeNearLocationAssignment");
354
355 // Let the base class archive its data
356 ActorAssignment::write(out);
357
358 // Store the target
359 writeTarget(getTarget(), out);
360
361 // Store the range
362 out->writeUint16LE(_range);
363 }
364
365 //----------------------------------------------------------------------
366 // Return an integer representing the class of this object for archival
367 // reasons.
368
type(void) const369 int16 HuntToBeNearLocationAssignment::type(void) const {
370 return huntToBeNearLocationAssignment;
371 }
372
373 //----------------------------------------------------------------------
374 // Determine if this assignment needs to create a task at this time
375
taskNeeded(void)376 bool HuntToBeNearLocationAssignment::taskNeeded(void) {
377 Actor *a = getActor();
378 TilePoint actorLoc = a->getLocation();
379
380 return !a->inRange(getTarget()->where(a->world(), actorLoc), _range);
381 }
382
383 //----------------------------------------------------------------------
384 // Construct a Task for this assignment
385
getTask(TaskStack * ts)386 Task *HuntToBeNearLocationAssignment::getTask(TaskStack *ts) {
387 return new HuntToBeNearLocationTask(ts, *getTarget(), _range);
388 }
389
390 /* ===================================================================== *
391 HuntToBeNearActorAssignment member functions
392 * ===================================================================== */
393
394 // Construct with no time limit and specific actor
HuntToBeNearActorAssignment(Actor * a,uint16 r,bool trackFlag)395 HuntToBeNearActorAssignment::HuntToBeNearActorAssignment(
396 Actor *a,
397 uint16 r,
398 bool trackFlag) :
399 ActorAssignment(a, kIndefiniteTime) {
400 assert(isActor(a) && a != getActor());
401 initialize(SpecificActorTarget(a), r, trackFlag);
402 }
403
404 // Construct with no time limit and abstract actor target
HuntToBeNearActorAssignment(Actor * a,const ActorTarget & at,uint16 r,bool trackFlag)405 HuntToBeNearActorAssignment::HuntToBeNearActorAssignment(
406 Actor *a,
407 const ActorTarget &at,
408 uint16 r,
409 bool trackFlag) :
410 ActorAssignment(a, kIndefiniteTime) {
411 initialize(at, r, trackFlag);
412 }
413
414 //----------------------------------------------------------------------
415 // An initialization function which provides a common ground for the
416 // initial constructors.
417
initialize(const ActorTarget & at,uint16 r,bool trackFlag)418 void HuntToBeNearActorAssignment::initialize(
419 const ActorTarget &at,
420 uint16 r,
421 bool trackFlag) {
422 assert(at.size() <= sizeof(_targetMem));
423
424 // Copy the target
425 at.clone(_targetMem);
426
427 _range = r;
428 _flags = trackFlag ? track : 0;
429 }
430
HuntToBeNearActorAssignment(Actor * a,Common::SeekableReadStream * stream)431 HuntToBeNearActorAssignment::HuntToBeNearActorAssignment(Actor *a, Common::SeekableReadStream *stream) :
432 ActorAssignment(a, stream) {
433 debugC(4, kDebugSaveload, "... Loading HuntToBeNearActorAssignment");
434
435 readTarget(_targetMem, stream);
436
437 // Restore the range
438 _range = stream->readUint16LE();
439
440 // Restore the flags
441 _flags = stream->readByte();
442 }
443
444 //----------------------------------------------------------------------
445 // Return the number of bytes need to archive the data in this
446 // assignment
447
archiveSize(void) const448 inline int32 HuntToBeNearActorAssignment::archiveSize(void) const {
449 return ActorAssignment::archiveSize()
450 + targetArchiveSize(getTarget())
451 + sizeof(_range)
452 + sizeof(_flags);
453 }
454
write(Common::MemoryWriteStreamDynamic * out) const455 void HuntToBeNearActorAssignment::write(Common::MemoryWriteStreamDynamic *out) const {
456 debugC(3, kDebugSaveload, "... Saving HuntToBeNearActorAssignment");
457
458 // Let the base class archive its data
459 ActorAssignment::write(out);
460
461 // Store the target
462 writeTarget(getTarget(), out);
463
464 // Store the range
465 out->writeUint16LE(_range);
466
467 // Store the flags
468 out->writeByte(_flags);
469 }
470
471 //----------------------------------------------------------------------
472 // Return an integer representing the class of this object for archival
473 // reasons.
474
type(void) const475 int16 HuntToBeNearActorAssignment::type(void) const {
476 return huntToBeNearActorAssignment;
477 }
478
479 //----------------------------------------------------------------------
480 // Determine if this assignment needs to create a task at this time
481
taskNeeded(void)482 bool HuntToBeNearActorAssignment::taskNeeded(void) {
483 Actor *a = getActor();
484 TilePoint actorLoc = a->getLocation(),
485 targetLoc = getTarget()->where(a->world(), actorLoc);
486
487 return !a->inRange(targetLoc, _range)
488 || a->inRange(targetLoc, HuntToBeNearActorTask::tooClose);
489 }
490
491 //----------------------------------------------------------------------
492 // Construct a Task for this assignment
493
getTask(TaskStack * ts)494 Task *HuntToBeNearActorAssignment::getTask(TaskStack *ts) {
495 return new HuntToBeNearActorTask(
496 ts,
497 *getTarget(),
498 _range,
499 (_flags & track) != false);
500 }
501
502 /* ===================================================================== *
503 HuntToKillAssignment member functions
504 * ===================================================================== */
505
506 // Construct with no time limit and specific actor
HuntToKillAssignment(Actor * a,bool trackFlag)507 HuntToKillAssignment::HuntToKillAssignment(Actor *a, bool trackFlag) :
508 ActorAssignment(a, kIndefiniteTime) {
509 assert(isActor(a) && a != getActor());
510 initialize(SpecificActorTarget(a), trackFlag, true);
511 }
512
513 // Construct with no time limit and abstract actor target
HuntToKillAssignment(Actor * a,const ActorTarget & at,bool trackFlag)514 HuntToKillAssignment::HuntToKillAssignment(
515 Actor *a,
516 const ActorTarget &at,
517 bool trackFlag) :
518 ActorAssignment(a, kIndefiniteTime) {
519 initialize(at, trackFlag, false);
520 }
521
522
523 //----------------------------------------------------------------------
524 // An initialization function which provides a common ground for the
525 // initial constructors.
526
initialize(const ActorTarget & at,bool trackFlag,bool specificActorFlag)527 void HuntToKillAssignment::initialize(
528 const ActorTarget &at,
529 bool trackFlag,
530 bool specificActorFlag) {
531 assert(at.size() <= sizeof(_targetMem));
532
533 // Copy the target
534 at.clone(_targetMem);
535
536 _flags = (trackFlag ? track : 0)
537 | (specificActorFlag ? specificActor : 0);
538 }
539
540 //----------------------------------------------------------------------
541 // Return the number of bytes need to archive the data in this
542 // assignment
543
archiveSize(void) const544 inline int32 HuntToKillAssignment::archiveSize(void) const {
545 return ActorAssignment::archiveSize()
546 + targetArchiveSize(getTarget())
547 + sizeof(_flags);
548 }
549
write(Common::MemoryWriteStreamDynamic * out) const550 void HuntToKillAssignment::write(Common::MemoryWriteStreamDynamic *out) const {
551 debugC(3, kDebugSaveload, "... Saving HuntToKillAssignment");
552
553 // Let the base class archive its data
554 ActorAssignment::write(out);
555
556 // Store the target
557 writeTarget(getTarget(), out);
558
559 // Store the flags
560 out->writeByte(_flags);
561 }
562
563 //----------------------------------------------------------------------
564 // Determine if this assignment is still valid
565
isValid(void)566 bool HuntToKillAssignment::isValid(void) {
567 // If the target actor is already dead, then this is not a valid
568 // assignment
569 if (_flags & specificActor) {
570 const SpecificActorTarget *sat = (const SpecificActorTarget *)getTarget();
571
572 if (sat->getTargetActor()->isDead()) return false;
573 }
574
575 // Otherwise, determine if the base class thinks this is a valid
576 // assignment
577 return ActorAssignment::isValid();
578 }
579
580 //----------------------------------------------------------------------
581 // Return an integer representing the class of this object for archival
582 // reasons.
583
type(void) const584 int16 HuntToKillAssignment::type(void) const {
585 return huntToKillAssignment;
586 }
587
588 //----------------------------------------------------------------------
589 // Determine if this assignment needs to create a task at this time
590
taskNeeded(void)591 bool HuntToKillAssignment::taskNeeded(void) {
592 // If we're hunting a specific actor, we only need a task if that
593 // actor is still alive.
594 if (_flags & specificActor) {
595 const SpecificActorTarget *sat = (const SpecificActorTarget *)getTarget();
596
597 return !sat->getTargetActor()->isDead();
598 }
599
600 // Otherwise, we'll always want to create a task
601 return true;
602 }
603
604 //----------------------------------------------------------------------
605 // Construct a Task for this assignment
606
getTask(TaskStack * ts)607 Task *HuntToKillAssignment::getTask(TaskStack *ts) {
608 return new HuntToKillTask(
609 ts,
610 *getTarget(),
611 (_flags & track) != false);
612 }
613
614 /* ===================================================================== *
615 TetheredAssignment member functions
616 * ===================================================================== */
617
TetheredAssignment(Actor * ac,Common::SeekableReadStream * stream)618 TetheredAssignment::TetheredAssignment(Actor *ac, Common::SeekableReadStream *stream) : ActorAssignment(ac, stream) {
619 debugC(4, kDebugSaveload, "... Loading TetheredAssignment");
620
621 // Read data from buffer
622 _minU = stream->readSint16LE();
623 _minV = stream->readSint16LE();
624 _maxU = stream->readSint16LE();
625 _maxV = stream->readSint16LE();
626 }
627
628 //----------------------------------------------------------------------
629 // Return the number of bytes need to archive the data in this
630 // assignment
631
archiveSize(void) const632 inline int32 TetheredAssignment::archiveSize(void) const {
633 return ActorAssignment::archiveSize()
634 + sizeof(_minU)
635 + sizeof(_minV)
636 + sizeof(_maxU)
637 + sizeof(_maxV);
638 }
639
write(Common::MemoryWriteStreamDynamic * out) const640 void TetheredAssignment::write(Common::MemoryWriteStreamDynamic *out) const {
641 debugC(3, kDebugSaveload, "... Saving TetheredAssignment");
642
643 // Let the base class archive its data
644 ActorAssignment::write(out);
645
646 // Copy data to buffer
647 out->writeSint16LE(_minU);
648 out->writeSint16LE(_minV);
649 out->writeSint16LE(_maxU);
650 out->writeSint16LE(_maxV);
651 }
652
653 /* ===================================================================== *
654 TetheredWanderAssignment member functions
655 * ===================================================================== */
656
657 //----------------------------------------------------------------------
658 // Constructor -- initial assignment construction
659
TetheredWanderAssignment(Actor * a,uint16 until,const TileRegion & reg)660 TetheredWanderAssignment::TetheredWanderAssignment(
661 Actor *a,
662 uint16 until,
663 const TileRegion ®) :
664 TetheredAssignment(a, until, reg) {
665 }
666
667 //----------------------------------------------------------------------
668 // Return an integer representing the class of this object for archival
669 // reasons.
670
type(void) const671 int16 TetheredWanderAssignment::type(void) const {
672 return tetheredWanderAssignment;
673 }
674
675 //----------------------------------------------------------------------
676 // Construct a Task for this assignment
677
getTask(TaskStack * ts)678 Task *TetheredWanderAssignment::getTask(TaskStack *ts) {
679 return new TetheredWanderTask(ts, _minU, _minV, _maxU, _maxV);
680 }
681
682 /* ===================================================================== *
683 AttendAssignment member functions
684 * ===================================================================== */
685
686 //----------------------------------------------------------------------
687 // Constructor -- initial assignment construction
688
AttendAssignment(Actor * a,uint16 until,GameObject * o)689 AttendAssignment::AttendAssignment(Actor *a, uint16 until, GameObject *o) :
690 ActorAssignment(a, until),
691 _obj(o) {
692 }
693
AttendAssignment(Actor * a,Common::SeekableReadStream * stream)694 AttendAssignment::AttendAssignment(Actor *a, Common::SeekableReadStream *stream) : ActorAssignment(a, stream) {
695 debugC(4, kDebugSaveload, "... Loading AttendAssignment");
696
697 ObjectID objID;
698
699 // Get the object ID
700 objID = stream->readUint16LE();
701
702 // Convert the object ID to an object pointer
703 _obj = objID != Nothing ? GameObject::objectAddress(objID) : NULL;
704 }
705
706 //----------------------------------------------------------------------
707 // Return the number of bytes need to archive the data in this
708 // assignment
709
archiveSize(void) const710 inline int32 AttendAssignment::archiveSize(void) const {
711 return ActorAssignment::archiveSize()
712 + sizeof(ObjectID);
713 }
714
write(Common::MemoryWriteStreamDynamic * out) const715 void AttendAssignment::write(Common::MemoryWriteStreamDynamic *out) const {
716 debugC(3, kDebugSaveload, "... Saving AttendAssignment");
717
718 // Let the base class write its data to the buffer
719 ActorAssignment::write(out);
720
721 ObjectID objID;
722
723 // Convert the object pointer to an object ID
724 objID = _obj != NULL ? _obj->thisID() : Nothing;
725
726 // Store the object ID
727 out->writeUint16LE(objID);
728 }
729
730 //----------------------------------------------------------------------
731 // Return an integer representing the class of this object for archival
732 // reasons.
733
type(void) const734 int16 AttendAssignment::type(void) const {
735 return attendAssignment;
736 }
737
738 //----------------------------------------------------------------------
739 // Construct a Task for this assignment
740
getTask(TaskStack * ts)741 Task *AttendAssignment::getTask(TaskStack *ts) {
742 return new AttendTask(ts, _obj);
743 }
744
745 /* ===================================================================== *
746 Misc functions
747 * ===================================================================== */
748
readAssignment(Actor * a,Common::InSaveFile * in)749 void readAssignment(Actor *a, Common::InSaveFile *in) {
750 // Get the type which is the first word in the archive buffer
751 int16 type = in->readSint16LE();
752
753 // Based upon the type, call the correct constructor
754 switch (type) {
755 case patrolRouteAssignment:
756 new PatrolRouteAssignment(a, in);
757 break;
758
759 case huntToBeNearActorAssignment:
760 new HuntToBeNearActorAssignment(a, in);
761 break;
762
763 case huntToBeNearLocationAssignment:
764 new HuntToBeNearLocationAssignment(a, in);
765 break;
766
767 case tetheredWanderAssignment:
768 new TetheredWanderAssignment(a, in);
769 break;
770
771 case attendAssignment:
772 new AttendAssignment(a, in);
773 break;
774 }
775 }
776
777 //----------------------------------------------------------------------
778 // Return the number of bytes necessary to archive this actor's
779 // assignment in an archive buffer
780
assignmentArchiveSize(Actor * a)781 int32 assignmentArchiveSize(Actor *a) {
782 ActorAssignment *assign = a->getAssignment();
783
784 return assign != NULL ? sizeof(int16) + assign->archiveSize() : 0;
785 }
786
writeAssignment(Actor * a,Common::MemoryWriteStreamDynamic * out)787 void writeAssignment(Actor *a, Common::MemoryWriteStreamDynamic *out) {
788 ActorAssignment *assign = a->getAssignment();
789
790 if (assign != NULL) {
791 out->writeSint16LE(assign->type());
792
793 assign->write(out);
794 }
795 }
796
797 }
798