scummvm/engines/saga2/assign.cpp

798 lines
24 KiB
C++
Raw Normal View History

2021-05-17 20:47:39 +02:00
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*
* Based on the original sources
* Faery Tale II -- The Halls of the Dead
* (c) 1993-1996 The Wyrmkeep Entertainment Co.
*/
2021-06-23 14:41:01 +02:00
#include "saga2/saga2.h"
2021-05-31 21:56:02 +02:00
#include "saga2/actor.h"
2021-05-17 20:47:39 +02:00
#include "saga2/assign.h"
2021-05-31 21:56:02 +02:00
#include "saga2/calender.h"
#include "saga2/task.h"
2021-06-01 21:31:22 +02:00
#include "saga2/tile.h"
2021-05-17 20:47:39 +02:00
namespace Saga2 {
2021-05-31 21:56:02 +02:00
const uint16 indefinitely = CalenderTime::framesPerDay;
2021-05-17 20:47:39 +02:00
/* ===================================================================== *
ActorAssignment member functions
* ===================================================================== */
2021-05-31 21:56:02 +02:00
// Constructor
ActorAssignment::ActorAssignment(Actor *a, uint16 until) :
2021-08-20 00:24:31 +09:00
_startFrame(calender.frameInDay()),
_endFrame(until) {
_actor = a;
2021-06-25 01:16:22 +09:00
debugC(2, kDebugActors, "New assignment for %p (%s) from %d until %d: %p",
2021-08-20 00:24:31 +09:00
(void *)a, a->objName(), _startFrame, _endFrame, (void *)this);
a->_assignment = this;
2021-08-19 06:15:07 +09:00
a->_flags |= hasAssignment;
2021-05-31 21:56:02 +02:00
}
2021-07-08 03:36:19 +09:00
ActorAssignment::ActorAssignment(Actor *ac, Common::SeekableReadStream *stream) {
2021-08-20 00:24:31 +09:00
_startFrame = stream->readUint16LE();
_endFrame = stream->readUint16LE();
2021-07-08 03:36:19 +09:00
_actor = ac;
ac->_assignment = this;
2021-08-19 06:15:07 +09:00
ac->_flags |= hasAssignment;
2021-07-08 03:36:19 +09:00
}
2021-05-17 20:47:39 +02:00
//----------------------------------------------------------------------
// ActorAssignment destructor
ActorAssignment::~ActorAssignment(void) {
Actor *a = getActor();
2021-06-25 01:16:22 +09:00
debugC(2, kDebugActors, "Ending assignment for %p (%s): %p",
2021-06-25 17:58:25 +09:00
(void *)a, a->objName(), (void *)this);
2021-05-17 20:47:39 +02:00
// Determine if the actor has a task initiated by this assignment
2021-08-19 06:15:07 +09:00
if (a->_currentGoal == actorGoalFollowAssignment
&& a->_curTask != NULL) {
2021-05-17 20:47:39 +02:00
// If so, abort it
2021-08-19 06:15:07 +09:00
a->_curTask->abortTask();
delete a->_curTask;
a->_curTask = NULL;
2021-05-17 20:47:39 +02:00
}
2021-06-25 01:16:22 +09:00
2021-08-19 06:15:07 +09:00
a->_flags &= ~hasAssignment;
2021-05-17 20:47:39 +02:00
}
//----------------------------------------------------------------------
// Return the number of bytes need to archive the data in this
// assignment
inline int32 ActorAssignment::archiveSize(void) const {
2021-08-20 00:24:31 +09:00
return sizeof(_startFrame) + sizeof(_endFrame);
2021-05-17 20:47:39 +02:00
}
void ActorAssignment::write(Common::MemoryWriteStreamDynamic *out) const {
2021-08-20 00:24:31 +09:00
out->writeUint16LE(_startFrame);
out->writeUint16LE(_endFrame);
2021-07-07 09:25:04 +09:00
}
2021-05-17 20:47:39 +02:00
//----------------------------------------------------------------------
// Determine if the time limit for this assignment has been exceeded
bool ActorAssignment::isValid(void) {
uint16 frame = calender.frameInDay();
2021-08-20 00:24:31 +09:00
return frame < _endFrame
|| (_startFrame >= _endFrame && frame >= _startFrame);
2021-05-17 20:47:39 +02:00
}
//----------------------------------------------------------------------
// Create a TaskStack for this actor and plug in the assignment's Task.
TaskStack *ActorAssignment::createTask(void) {
if (!taskNeeded()) return NULL;
Actor *a = getActor();
TaskStack *ts = NULL;
if ((ts = newTaskStack(a)) != NULL) {
2021-05-17 20:47:39 +02:00
Task *task = getTask(ts);
if (task != NULL)
ts->setTask(task);
else {
delete ts;
ts = NULL;
}
}
return ts;
}
2021-05-31 21:56:02 +02:00
Actor *ActorAssignment::getActor(void) const {
return _actor;
2021-05-31 21:56:02 +02:00
}
2021-05-17 20:47:39 +02:00
//----------------------------------------------------------------------
// This function is called to notify the assignment of the completion
// of a task which the assignment had created.
void ActorAssignment::handleTaskCompletion(TaskResult) {
// Do nothing
}
//----------------------------------------------------------------------
// Plug a new task into the actor, if the actor is currently following
// his assignment
void ActorAssignment::startTask(void) {
Actor *a = getActor();
2021-08-19 06:15:07 +09:00
if (a->_currentGoal == actorGoalFollowAssignment)
a->_curTask = createTask();
2021-05-17 20:47:39 +02:00
}
//----------------------------------------------------------------------
// Determine if this assignment needs to create a task at this time
bool ActorAssignment::taskNeeded(void) {
2021-06-13 16:56:52 +02:00
return true;
2021-05-17 20:47:39 +02:00
}
/* ===================================================================== *
PatrolRouteAssignment member functions
* ===================================================================== */
//----------------------------------------------------------------------
// Constructor -- initial object construction
PatrolRouteAssignment::PatrolRouteAssignment(
Actor *a,
2021-05-17 20:47:39 +02:00
uint16 until,
int16 rteNo,
uint8 patrolFlags,
int16 start,
int16 end) :
ActorAssignment(a, until),
2021-08-20 00:24:31 +09:00
_routeNo(rteNo),
_startingWayPoint(start),
_endingWayPoint(end),
_routeFlags(patrolFlags),
_flags(0) {
2021-05-17 20:47:39 +02:00
}
2021-07-08 03:36:19 +09:00
PatrolRouteAssignment::PatrolRouteAssignment(Actor *a, Common::SeekableReadStream *stream) :
ActorAssignment(a, stream) {
debugC(4, kDebugSaveload, "... Loading PatrolRouteAssignment");
// Restore route number
2021-08-20 00:24:31 +09:00
_routeNo = stream->readSint16LE();
2021-07-08 03:36:19 +09:00
// Restore the starting way point
2021-08-20 00:24:31 +09:00
_startingWayPoint = stream->readSint16LE();
2021-07-08 03:36:19 +09:00
// Restore the ending way point
2021-08-20 00:24:31 +09:00
_endingWayPoint = stream->readSint16LE();
2021-07-08 03:36:19 +09:00
// Restore the route flags
2021-08-20 00:24:31 +09:00
_routeFlags = stream->readByte();
2021-07-08 03:36:19 +09:00
// Restore the assignment flags
2021-08-20 00:24:31 +09:00
_flags = stream->readByte();
2021-07-08 03:36:19 +09:00
}
2021-05-17 20:47:39 +02:00
//----------------------------------------------------------------------
// Return the number of bytes need to archive the data in this
// assignment
inline int32 PatrolRouteAssignment::archiveSize(void) const {
return ActorAssignment::archiveSize()
2021-08-20 00:24:31 +09:00
+ sizeof(_routeNo)
+ sizeof(_startingWayPoint)
+ sizeof(_endingWayPoint)
+ sizeof(_routeFlags)
+ sizeof(_flags);
2021-05-17 20:47:39 +02:00
}
void PatrolRouteAssignment::write(Common::MemoryWriteStreamDynamic *out) const {
2021-07-08 04:33:37 +09:00
debugC(3, kDebugSaveload, "... Saving PatrolRouteAssignment");
// Let the base class write its data to the buffer
ActorAssignment::write(out);
// Store the route number
2021-08-20 00:24:31 +09:00
out->writeSint16LE(_routeNo);
out->writeSint16LE(_startingWayPoint);
out->writeSint16LE(_endingWayPoint);
2021-07-08 04:33:37 +09:00
// Store the route flags
2021-08-20 00:24:31 +09:00
out->writeByte(_routeFlags);
2021-07-08 04:33:37 +09:00
// Store the assignment flags
2021-08-20 00:24:31 +09:00
out->writeByte(_flags);
2021-07-08 04:33:37 +09:00
}
2021-05-17 20:47:39 +02:00
//----------------------------------------------------------------------
// Return an integer representing the class of this object for archival
// reasons.
int16 PatrolRouteAssignment::type(void) const {
return patrolRouteAssignment;
}
//----------------------------------------------------------------------
// This function is called to notify the assignment of the completion
// of a task which the assignment had created.
void PatrolRouteAssignment::handleTaskCompletion(TaskResult result) {
2021-08-20 00:24:31 +09:00
if (result == taskSucceeded) _flags |= routeCompleted;
2021-05-17 20:47:39 +02:00
}
//----------------------------------------------------------------------
// Determine if assignment is still valid
bool PatrolRouteAssignment::isValid(void) {
// If the route has already been completed, then the assignment is
// no longer valid
2021-08-20 00:24:31 +09:00
if (_flags & routeCompleted) return false;
2021-05-17 20:47:39 +02:00
return ActorAssignment::isValid();
}
//----------------------------------------------------------------------
// Determine if this assignment needs to create a task at this time
bool PatrolRouteAssignment::taskNeeded(void) {
// If the route has already been completed, then no task is needed
2021-08-20 00:24:31 +09:00
return !(_flags & routeCompleted);
2021-05-17 20:47:39 +02:00
}
//----------------------------------------------------------------------
// Construct a Task for this assignment
Task *PatrolRouteAssignment::getTask(TaskStack *ts) {
2021-08-20 00:24:31 +09:00
int16 startPoint = _startingWayPoint;
2021-05-17 20:47:39 +02:00
uint8 mapNum = getActor()->getMapNum();
2021-08-20 00:24:31 +09:00
_startingWayPoint = -1;
2021-05-17 20:47:39 +02:00
if (startPoint == -1) {
int16 i;
uint16 bestDist = maxuint16;
2021-08-20 00:24:31 +09:00
const PatrolRoute &route = patrolRouteList[mapNum]->getRoute(_routeNo);
2021-05-17 20:47:39 +02:00
TilePoint actorLoc = getActor()->getLocation();
for (i = 0; i < route.vertices(); i++) {
2021-06-07 18:19:10 +02:00
uint16 dist = lineDist(route[i], route[(i + 1) % route.vertices()], actorLoc);
2021-05-17 20:47:39 +02:00
if (dist < bestDist) {
bestDist = dist;
2021-08-20 00:24:31 +09:00
startPoint = (_routeFlags & patrolRouteReverse) ? i : (i + 1) % route.vertices();
2021-05-17 20:47:39 +02:00
}
}
}
// Construct a patrol route iterator.
PatrolRouteIterator
iter = PatrolRouteIterator(
mapNum,
2021-08-20 00:24:31 +09:00
_routeNo,
_routeFlags,
2021-05-17 20:47:39 +02:00
startPoint);
// Construct a FollowPatrolRouteTask
2021-08-20 00:24:31 +09:00
return _endingWayPoint != -1
? new FollowPatrolRouteTask(ts, iter, _endingWayPoint)
2021-06-02 16:43:12 +02:00
: new FollowPatrolRouteTask(ts, iter);
2021-05-17 20:47:39 +02:00
}
/* ===================================================================== *
HuntToBeNearLocationAssignment member functions
* ===================================================================== */
HuntToBeNearLocationAssignment::HuntToBeNearLocationAssignment(Actor *a, const TilePoint &tp, uint16 r) :
ActorAssignment(a, indefinitely) {
2021-05-31 21:56:02 +02:00
initialize(LocationTarget(tp), r);
}
// Construct with no time limit and an abstract target
HuntToBeNearLocationAssignment::HuntToBeNearLocationAssignment(Actor *a, const Target &targ, uint16 r) :
ActorAssignment(a, indefinitely) {
2021-05-31 21:56:02 +02:00
initialize(targ, r);
}
2021-05-17 20:47:39 +02:00
//----------------------------------------------------------------------
// An initialization function which provides a common ground for
// the initial constructors.
void HuntToBeNearLocationAssignment::initialize(
const Target &targ,
uint16 r) {
2021-08-20 00:24:31 +09:00
assert(targ.size() <= sizeof(_targetMem));
2021-05-17 20:47:39 +02:00
// Make a copy of the target
2021-08-20 00:24:31 +09:00
targ.clone(_targetMem);
2021-05-17 20:47:39 +02:00
2021-08-20 00:24:31 +09:00
_range = r;
2021-05-17 20:47:39 +02:00
}
2021-07-08 03:36:19 +09:00
HuntToBeNearLocationAssignment::HuntToBeNearLocationAssignment(Actor *a, Common::SeekableReadStream *stream) :
ActorAssignment(a, stream) {
debugC(4, kDebugSaveload, "... Loading HuntToBeNearLocationAssignment");
// Restore the target
2021-08-20 00:24:31 +09:00
readTarget(_targetMem, stream);
2021-07-08 03:36:19 +09:00
// Restore the range
2021-08-20 00:24:31 +09:00
_range = stream->readUint16LE();
2021-07-08 03:36:19 +09:00
}
2021-05-17 20:47:39 +02:00
//----------------------------------------------------------------------
// Return the number of bytes need to archive the data in this
// assignment
inline int32 HuntToBeNearLocationAssignment::archiveSize(void) const {
return ActorAssignment::archiveSize()
+ targetArchiveSize(getTarget())
2021-08-20 00:24:31 +09:00
+ sizeof(_range);
2021-05-17 20:47:39 +02:00
}
void HuntToBeNearLocationAssignment::write(Common::MemoryWriteStreamDynamic *out) const {
2021-07-08 04:33:37 +09:00
debugC(3, kDebugSaveload, "... Saving HuntToBeNearLocationAssignment");
// Let the base class archive its data
ActorAssignment::write(out);
// Store the target
writeTarget(getTarget(), out);
// Store the range
2021-08-20 00:24:31 +09:00
out->writeUint16LE(_range);
2021-07-08 04:33:37 +09:00
}
2021-05-17 20:47:39 +02:00
//----------------------------------------------------------------------
// Return an integer representing the class of this object for archival
// reasons.
int16 HuntToBeNearLocationAssignment::type(void) const {
return huntToBeNearLocationAssignment;
}
//----------------------------------------------------------------------
// Determine if this assignment needs to create a task at this time
bool HuntToBeNearLocationAssignment::taskNeeded(void) {
Actor *a = getActor();
TilePoint actorLoc = a->getLocation();
2021-08-20 00:24:31 +09:00
return !a->inRange(getTarget()->where(a->world(), actorLoc), _range);
2021-05-17 20:47:39 +02:00
}
//----------------------------------------------------------------------
// Construct a Task for this assignment
Task *HuntToBeNearLocationAssignment::getTask(TaskStack *ts) {
2021-08-20 00:24:31 +09:00
return new HuntToBeNearLocationTask(ts, *getTarget(), _range);
2021-05-17 20:47:39 +02:00
}
/* ===================================================================== *
HuntToBeNearActorAssignment member functions
* ===================================================================== */
2021-05-31 21:56:02 +02:00
// Construct with no time limit and specific actor
HuntToBeNearActorAssignment::HuntToBeNearActorAssignment(
Actor *a,
uint16 r,
bool trackFlag) :
ActorAssignment(a, indefinitely) {
2021-05-31 21:56:02 +02:00
assert(isActor(a) && a != getActor());
initialize(SpecificActorTarget(a), r, trackFlag);
}
// Construct with no time limit and abstract actor target
HuntToBeNearActorAssignment::HuntToBeNearActorAssignment(
Actor *a,
2021-05-31 21:56:02 +02:00
const ActorTarget &at,
uint16 r,
bool trackFlag) :
ActorAssignment(a, indefinitely) {
2021-05-31 21:56:02 +02:00
initialize(at, r, trackFlag);
}
2021-05-17 20:47:39 +02:00
//----------------------------------------------------------------------
// An initialization function which provides a common ground for the
// initial constructors.
void HuntToBeNearActorAssignment::initialize(
const ActorTarget &at,
uint16 r,
bool trackFlag) {
2021-08-20 00:24:31 +09:00
assert(at.size() <= sizeof(_targetMem));
2021-05-17 20:47:39 +02:00
// Copy the target
2021-08-20 00:24:31 +09:00
at.clone(_targetMem);
2021-05-17 20:47:39 +02:00
2021-08-20 00:24:31 +09:00
_range = r;
_flags = trackFlag ? track : 0;
2021-05-17 20:47:39 +02:00
}
2021-07-08 03:36:19 +09:00
HuntToBeNearActorAssignment::HuntToBeNearActorAssignment(Actor *a, Common::SeekableReadStream *stream) :
ActorAssignment(a, stream) {
debugC(4, kDebugSaveload, "... Loading HuntToBeNearActorAssignment");
2021-08-20 00:24:31 +09:00
readTarget(_targetMem, stream);
2021-07-08 03:36:19 +09:00
// Restore the range
2021-08-20 00:24:31 +09:00
_range = stream->readUint16LE();
2021-07-08 03:36:19 +09:00
// Restore the flags
2021-08-20 00:24:31 +09:00
_flags = stream->readByte();
2021-07-08 03:36:19 +09:00
}
2021-05-17 20:47:39 +02:00
//----------------------------------------------------------------------
// Return the number of bytes need to archive the data in this
// assignment
inline int32 HuntToBeNearActorAssignment::archiveSize(void) const {
return ActorAssignment::archiveSize()
+ targetArchiveSize(getTarget())
2021-08-20 00:24:31 +09:00
+ sizeof(_range)
+ sizeof(_flags);
2021-05-17 20:47:39 +02:00
}
void HuntToBeNearActorAssignment::write(Common::MemoryWriteStreamDynamic *out) const {
2021-07-08 04:33:37 +09:00
debugC(3, kDebugSaveload, "... Saving HuntToBeNearActorAssignment");
// Let the base class archive its data
ActorAssignment::write(out);
// Store the target
writeTarget(getTarget(), out);
// Store the range
2021-08-20 00:24:31 +09:00
out->writeUint16LE(_range);
2021-07-08 04:33:37 +09:00
// Store the flags
2021-08-20 00:24:31 +09:00
out->writeByte(_flags);
2021-07-08 04:33:37 +09:00
}
2021-05-17 20:47:39 +02:00
//----------------------------------------------------------------------
// Return an integer representing the class of this object for archival
// reasons.
int16 HuntToBeNearActorAssignment::type(void) const {
return huntToBeNearActorAssignment;
}
//----------------------------------------------------------------------
// Determine if this assignment needs to create a task at this time
bool HuntToBeNearActorAssignment::taskNeeded(void) {
Actor *a = getActor();
TilePoint actorLoc = a->getLocation(),
targetLoc = getTarget()->where(a->world(), actorLoc);
2021-08-20 00:24:31 +09:00
return !a->inRange(targetLoc, _range)
2021-05-17 20:47:39 +02:00
|| a->inRange(targetLoc, HuntToBeNearActorTask::tooClose);
}
//----------------------------------------------------------------------
// Construct a Task for this assignment
Task *HuntToBeNearActorAssignment::getTask(TaskStack *ts) {
2021-06-02 16:43:12 +02:00
return new HuntToBeNearActorTask(
2021-05-17 20:47:39 +02:00
ts,
*getTarget(),
2021-08-20 00:24:31 +09:00
_range,
(_flags & track) != false);
2021-05-17 20:47:39 +02:00
}
/* ===================================================================== *
HuntToKillAssignment member functions
* ===================================================================== */
2021-05-31 21:56:02 +02:00
// Construct with no time limit and specific actor
HuntToKillAssignment::HuntToKillAssignment(Actor *a, bool trackFlag) :
ActorAssignment(a, indefinitely) {
2021-05-31 21:56:02 +02:00
assert(isActor(a) && a != getActor());
2021-06-13 16:56:52 +02:00
initialize(SpecificActorTarget(a), trackFlag, true);
2021-05-31 21:56:02 +02:00
}
// Construct with no time limit and abstract actor target
HuntToKillAssignment::HuntToKillAssignment(
Actor *a,
2021-05-31 21:56:02 +02:00
const ActorTarget &at,
bool trackFlag) :
ActorAssignment(a, indefinitely) {
2021-06-13 16:56:52 +02:00
initialize(at, trackFlag, false);
2021-05-31 21:56:02 +02:00
}
2021-05-17 20:47:39 +02:00
//----------------------------------------------------------------------
// An initialization function which provides a common ground for the
// initial constructors.
void HuntToKillAssignment::initialize(
const ActorTarget &at,
bool trackFlag,
bool specificActorFlag) {
2021-08-20 00:24:31 +09:00
assert(at.size() <= sizeof(_targetMem));
2021-05-17 20:47:39 +02:00
// Copy the target
2021-08-20 00:24:31 +09:00
at.clone(_targetMem);
2021-05-17 20:47:39 +02:00
2021-08-20 00:24:31 +09:00
_flags = (trackFlag ? track : 0)
2021-05-17 20:47:39 +02:00
| (specificActorFlag ? specificActor : 0);
}
//----------------------------------------------------------------------
// Return the number of bytes need to archive the data in this
// assignment
inline int32 HuntToKillAssignment::archiveSize(void) const {
return ActorAssignment::archiveSize()
+ targetArchiveSize(getTarget())
2021-08-20 00:24:31 +09:00
+ sizeof(_flags);
2021-05-17 20:47:39 +02:00
}
void HuntToKillAssignment::write(Common::MemoryWriteStreamDynamic *out) const {
2021-07-08 04:33:37 +09:00
debugC(3, kDebugSaveload, "... Saving HuntToKillAssignment");
// Let the base class archive its data
ActorAssignment::write(out);
// Store the target
writeTarget(getTarget(), out);
// Store the flags
2021-08-20 00:24:31 +09:00
out->writeByte(_flags);
2021-07-08 04:33:37 +09:00
}
2021-05-17 20:47:39 +02:00
//----------------------------------------------------------------------
// Determine if this assignment is still valid
bool HuntToKillAssignment::isValid(void) {
// If the target actor is already dead, then this is not a valid
// assignment
2021-08-20 00:24:31 +09:00
if (_flags & specificActor) {
2021-06-22 12:07:14 +02:00
const SpecificActorTarget *sat = (const SpecificActorTarget *)getTarget();
2021-05-17 20:47:39 +02:00
2021-06-13 16:56:52 +02:00
if (sat->getTargetActor()->isDead()) return false;
2021-05-17 20:47:39 +02:00
}
// Otherwise, determine if the base class thinks this is a valid
// assignment
return ActorAssignment::isValid();
}
//----------------------------------------------------------------------
// Return an integer representing the class of this object for archival
// reasons.
int16 HuntToKillAssignment::type(void) const {
return huntToKillAssignment;
}
//----------------------------------------------------------------------
// Determine if this assignment needs to create a task at this time
bool HuntToKillAssignment::taskNeeded(void) {
// If we're hunting a specific actor, we only need a task if that
// actor is still alive.
2021-08-20 00:24:31 +09:00
if (_flags & specificActor) {
2021-06-22 12:07:14 +02:00
const SpecificActorTarget *sat = (const SpecificActorTarget *)getTarget();
2021-05-17 20:47:39 +02:00
return !sat->getTargetActor()->isDead();
}
// Otherwise, we'll always want to create a task
2021-06-13 16:56:52 +02:00
return true;
2021-05-17 20:47:39 +02:00
}
//----------------------------------------------------------------------
// Construct a Task for this assignment
Task *HuntToKillAssignment::getTask(TaskStack *ts) {
2021-06-02 16:43:12 +02:00
return new HuntToKillTask(
2021-05-17 20:47:39 +02:00
ts,
*getTarget(),
2021-08-20 00:24:31 +09:00
(_flags & track) != false);
2021-05-17 20:47:39 +02:00
}
/* ===================================================================== *
TetheredAssignment member functions
* ===================================================================== */
2021-07-08 03:36:19 +09:00
TetheredAssignment::TetheredAssignment(Actor *ac, Common::SeekableReadStream *stream) : ActorAssignment(ac, stream) {
debugC(4, kDebugSaveload, "... Loading TetheredAssignment");
// Read data from buffer
2021-08-20 00:24:31 +09:00
_minU = stream->readSint16LE();
_minV = stream->readSint16LE();
_maxU = stream->readSint16LE();
_maxV = stream->readSint16LE();
2021-07-08 03:36:19 +09:00
}
2021-05-17 20:47:39 +02:00
//----------------------------------------------------------------------
// Return the number of bytes need to archive the data in this
// assignment
inline int32 TetheredAssignment::archiveSize(void) const {
return ActorAssignment::archiveSize()
2021-08-20 00:24:31 +09:00
+ sizeof(_minU)
+ sizeof(_minV)
+ sizeof(_maxU)
+ sizeof(_maxV);
2021-05-17 20:47:39 +02:00
}
void TetheredAssignment::write(Common::MemoryWriteStreamDynamic *out) const {
2021-07-08 04:33:37 +09:00
debugC(3, kDebugSaveload, "... Saving TetheredAssignment");
// Let the base class archive its data
ActorAssignment::write(out);
// Copy data to buffer
2021-08-20 00:24:31 +09:00
out->writeSint16LE(_minU);
out->writeSint16LE(_minV);
out->writeSint16LE(_maxU);
out->writeSint16LE(_maxV);
2021-07-08 04:33:37 +09:00
}
2021-05-17 20:47:39 +02:00
/* ===================================================================== *
TetheredWanderAssignment member functions
* ===================================================================== */
//----------------------------------------------------------------------
// Constructor -- initial assignment construction
TetheredWanderAssignment::TetheredWanderAssignment(
Actor *a,
2021-05-17 20:47:39 +02:00
uint16 until,
const TileRegion &reg) :
TetheredAssignment(a, until, reg) {
2021-05-17 20:47:39 +02:00
}
//----------------------------------------------------------------------
// Return an integer representing the class of this object for archival
// reasons.
int16 TetheredWanderAssignment::type(void) const {
return tetheredWanderAssignment;
}
//----------------------------------------------------------------------
// Construct a Task for this assignment
Task *TetheredWanderAssignment::getTask(TaskStack *ts) {
2021-08-20 00:24:31 +09:00
return new TetheredWanderTask(ts, _minU, _minV, _maxU, _maxV);
2021-05-17 20:47:39 +02:00
}
/* ===================================================================== *
AttendAssignment member functions
* ===================================================================== */
//----------------------------------------------------------------------
// Constructor -- initial assignment construction
AttendAssignment::AttendAssignment(Actor *a, uint16 until, GameObject *o) :
ActorAssignment(a, until),
2021-08-20 00:24:31 +09:00
_obj(o) {
2021-05-17 20:47:39 +02:00
}
2021-07-08 03:36:19 +09:00
AttendAssignment::AttendAssignment(Actor *a, Common::SeekableReadStream *stream) : ActorAssignment(a, stream) {
debugC(4, kDebugSaveload, "... Loading AttendAssignment");
ObjectID objID;
// Get the object ID
objID = stream->readUint16LE();
// Convert the object ID to an object pointer
2021-08-20 00:24:31 +09:00
_obj = objID != Nothing ? GameObject::objectAddress(objID) : NULL;
2021-07-08 03:36:19 +09:00
}
2021-05-17 20:47:39 +02:00
//----------------------------------------------------------------------
// Return the number of bytes need to archive the data in this
// assignment
inline int32 AttendAssignment::archiveSize(void) const {
return ActorAssignment::archiveSize()
+ sizeof(ObjectID);
}
void AttendAssignment::write(Common::MemoryWriteStreamDynamic *out) const {
2021-07-08 04:33:37 +09:00
debugC(3, kDebugSaveload, "... Saving AttendAssignment");
// Let the base class write its data to the buffer
ActorAssignment::write(out);
ObjectID objID;
// Convert the object pointer to an object ID
2021-08-20 00:24:31 +09:00
objID = _obj != NULL ? _obj->thisID() : Nothing;
2021-07-08 04:33:37 +09:00
// Store the object ID
out->writeUint16LE(objID);
}
2021-05-17 20:47:39 +02:00
//----------------------------------------------------------------------
// Return an integer representing the class of this object for archival
// reasons.
int16 AttendAssignment::type(void) const {
return attendAssignment;
}
//----------------------------------------------------------------------
// Construct a Task for this assignment
Task *AttendAssignment::getTask(TaskStack *ts) {
2021-08-20 00:24:31 +09:00
return new AttendTask(ts, _obj);
2021-05-17 20:47:39 +02:00
}
/* ===================================================================== *
Misc functions
* ===================================================================== */
2021-07-08 03:36:19 +09:00
void readAssignment(Actor *a, Common::InSaveFile *in) {
// Get the type which is the first word in the archive buffer
int16 type = in->readSint16LE();
// Based upon the type, call the correct constructor
switch (type) {
case patrolRouteAssignment:
new PatrolRouteAssignment(a, in);
break;
case huntToBeNearActorAssignment:
new HuntToBeNearActorAssignment(a, in);
break;
case huntToBeNearLocationAssignment:
new HuntToBeNearLocationAssignment(a, in);
break;
case tetheredWanderAssignment:
new TetheredWanderAssignment(a, in);
break;
case attendAssignment:
new AttendAssignment(a, in);
break;
}
}
2021-05-17 20:47:39 +02:00
//----------------------------------------------------------------------
// Return the number of bytes necessary to archive this actor's
// assignment in an archive buffer
int32 assignmentArchiveSize(Actor *a) {
ActorAssignment *assign = a->getAssignment();
return assign != NULL ? sizeof(int16) + assign->archiveSize() : 0;
}
void writeAssignment(Actor *a, Common::MemoryWriteStreamDynamic *out) {
2021-07-07 09:25:04 +09:00
ActorAssignment *assign = a->getAssignment();
if (assign != NULL) {
out->writeSint16LE(assign->type());
assign->write(out);
}
}
2021-05-17 20:47:39 +02:00
}