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_OBJECTS_H
28 #define SAGA2_OBJECTS_H
29 
30 #include "saga2/objproto.h"
31 #include "saga2/property.h"
32 
33 namespace Saga2 {
34 
35 /* ======================================================================= *
36    GameObject: Describes an instance of an object
37  * ======================================================================= */
38 
39 class GameWorld;
40 
41 const uint16 unlimitedCapacity = maxuint16;
42 
43 enum ActorManaID {
44 	manaIDRed = 0,
45 	manaIDOrange,
46 	manaIDYellow,
47 	manaIDGreen,
48 	manaIDBlue,
49 	manaIDViolet,
50 
51 	numManas
52 };
53 
54 //  Used to indicate if objects can be stacked or merged
55 enum {
56 	cannotStackOrMerge = 0,
57 	canStack,
58 	canMerge
59 };
60 
61 //  The ResourceGameObject structure represents the game object data as
62 //  it is structured in the resource file.
63 
64 struct ResourceGameObject {
65 	int16           protoIndex;
66 	TilePoint       location;
67 	uint16          nameIndex;
68 	ObjectID        parentID;
69 	uint16          script;
70 	uint16          objectFlags;
71 	uint8           hitPoints;
72 	uint16          misc;
73 
74 	ResourceGameObject(Common::SeekableReadStream *stream);
75 };
76 
77 //  Base class of all objects
78 //
79 //  Unlike the object prototypes, the only subclass of GameObject is
80 //  the actor subclass, which is kept in an entirely seperate table.
81 //  This allows all objects to be kept in an array (indexed by ID number)
82 
83 #include "common/pack-start.h"
84 
85 struct ObjectData {
86 	uint32 projectDummy;
87 	TilePoint       location;               // where object is located.
88 	uint16          nameIndex;              // object's proper name, if any
89 	ObjectID        parentID,               // ID of parent object
90 	                siblingID,              // ID of next in chain
91 	                childID;                // ID of 1st child
92 	uint16          script;                 // script attached to this object
93 	uint16          objectFlags;            // various flags
94 	uint8           hitPoints;              // object hit points
95 	uint8           bParam;                 // number of spell charges an object has
96 	// (also generator radius in metatiles)
97 	union {
98 		uint16      massCount;              // for mergeables, object count
99 		uint16      textStringID;           // inscription for documents
100 		uint16      enchantmentType;        // for enchantments
101 		uint16      generatorFrequency;     // for encounter and mission generators
102 	};
103 
104 	uint8           missileFacing;
105 	ActiveItemID    currentTAG;             // ActiveItem object is on
106 	uint8           sightCtr;               // Line of sight counter
107 
108 	uint8           reserved[2];
109 
110 	GameObject *obj;
111 } PACKED_STRUCT;
112 
113 #include "common/pack-end.h"
114 
115 void     initActors(void);
116 void     saveActors(Common::OutSaveFile *outS);
117 void     loadActors(Common::InSaveFile *in);
118 void     cleanupActors(void);
119 class GameObject {
120 
121 	friend void     initWorlds(void);
122 	friend void     cleanupWorlds(void);
123 
124 	friend void     initObjects(void);
125 	friend void     saveObjects(Common::OutSaveFile *out);
126 	friend void     loadObjects(Common::InSaveFile *in);
127 	friend void     cleanupObjects(void);
128 
129 	friend void     buildDisplayList(void);
130 	friend void     drawDisplayList(void);
131 	friend void     setMindContainer(int NewContainerClass, IntangibleContainerWindow &cw);
132 	friend class    EnchantmentContainerWindow;
133 	friend bool     Enchantment(ObjectID, ObjectID);
134 	friend class    ProtoObj;
135 	friend class    PhysicalContainerProto;
136 	friend class    IntangibleContainerProto;
137 	friend class    KeyProto;
138 	friend class    BottleProto;
139 	friend class    SkillProto;
140 	friend class    ActorProto;
141 	friend class    MotionTask;
142 	friend class    MotionTaskList;
143 	friend class    ObjectIterator;
144 	friend class    ContainerIterator;
145 	friend class    RecursiveContainerIterator;
146 	friend class    ShopMode;
147 
148 
149 
150 private:
151 
152 	// container info
153 	enum {
154 		maxRow      = 20,
155 		maxCol      = 4
156 	};
157 
158 public:
159 
160 	ObjectID thisID(void);               // calculate our own ID value
161 
162 	static const char *nameText(uint16 index);
163 
164 protected:
165 	//  get address of head-of-chain id.
166 	static ObjectID *getHeadPtr(ObjectID parentID, TilePoint &l);
167 
168 	//  Object list management functions
169 	void remove(void);                   // removes from old list
170 	void append(ObjectID newParent);         // adds to new list (no remove)
171 	void insert(ObjectID newPrev);           // inserts after this item (no remove)
172 
173 	ProtoObj        *prototype;             // object that defines our behavior
174 public:
175 	ObjectData _data;
176 	uint _index;
177 	bool _godmode;
178 	//  Default constructor
179 	GameObject(void);
180 
181 	//  Constructor -- initial construction
182 	GameObject(const ResourceGameObject &res);
183 
184 	GameObject(Common::InSaveFile *in);
185 
186 	void read(Common::InSaveFile *in, bool expandProto);
187 
188 	//  Return the number of bytes needed to archive this object in
189 	//  a buffer
190 	int32 archiveSize(void);
191 
192 	void write(Common::MemoryWriteStreamDynamic *out, bool expandProto);
193 
194 	//  returns the address of the object based on the ID, and this
195 	//  includes accounting for actors.
196 	static GameObject *objectAddress(ObjectID id);
197 
198 	//  Converts object ID into prototype address...
199 	static ProtoObj *protoAddress(ObjectID id);
200 
201 	// Returns first object id found associate with the given name index
202 	static int32 nameIndexToID(uint16 ind);
203 
204 	// Returns first object id found assciated with the given name
205 	static Common::Array<ObjectID> nameToID(Common::String name);
206 
207 	//  object creation and deletion
208 	static GameObject *newObject(void);      // get a newly created object
209 	void deleteObject(void);                 // delete this object and remove
210 	void deleteObjectRecursive(void);        // delete this object and every
211 	// object it contains
212 
213 	//  Return pointer to parent/child/next sibling object, if any
parent(void)214 	GameObject *parent(void) {
215 		return _data.parentID == Nothing ? NULL : objectAddress(_data.parentID);
216 	}
next(void)217 	GameObject *next(void) {
218 		return _data.siblingID == Nothing ? NULL : objectAddress(_data.siblingID);
219 	}
child(void)220 	GameObject *child(void) {
221 		return _data.childID == Nothing ? NULL : objectAddress(_data.childID);
222 	}
223 
224 	//  Return ID of parent/child/next sibling object, if any
IDParent(void)225 	ObjectID IDParent(void) {
226 		return _data.parentID ;
227 	}
IDNext(void)228 	ObjectID IDNext(void) {
229 		return _data.siblingID;
230 	}
IDChild(void)231 	ObjectID IDChild(void) {
232 		return _data.childID  ;
233 	}
234 
235 	//  Return a pointer to the world on which this object resides
236 	GameWorld *world(void);
237 
238 	//  Return the number of the map of the world on which this object
239 	//  resides
240 	int16 getMapNum(void);
241 
242 	//  graphics functions
243 	int16 sprNum(int16 state);               // returns current sprite number
244 
245 	// gets the offset to the spr image according to masscount for mergeables
246 	int32 getSprOffset(int16 num = -1);
247 
248 	// completely restore the magical energy of a magical object
249 	void recharge(void);
250 
251 	// returns the type of charge an object has
252 	// be it none, red, violet, etc...
253 	int16 getChargeType(void);
254 
255 	// use charge of this object
256 	bool deductCharge(ActorManaID manaID, uint16 manaCost);
257 
258 	// check charge of this object
259 	bool hasCharge(ActorManaID manaID, uint16 manaCost);
260 
261 	//  context-changing functions
262 	void setLocation(const Location &loc);  // move to new location in world
263 	void setLocation(const TilePoint &tp);  // move to new location in world
264 	void move(const Location &loc);          // move to new location in world
265 	void move(const Location &loc, int16 num);       // move to new location in world
266 	void move(const TilePoint &tp);          // move to new location in world
267 	void updateImage(ObjectID);              // move to new location in world,
268 	// (assumes setLocation has been called)
269 
270 	//  Remove an object from a stack of objects. Returns true if it was in a stack.
271 	bool unstack(void);
272 
273 	// this correctly moves merged or stacked objects
274 	bool moveMerged(const Location &loc);
275 	bool moveMerged(const Location &loc, int16 num = 1);
276 	bool moveMerged(const TilePoint &tp);
277 
278 	//  Extract a merged object with specified merge number from another
279 	//  merged object and return its ID
280 	ObjectID extractMerged(const Location &loc, int16 num);
281 	GameObject *extractMerged(int16 num);
282 
283 	void moveRandom(const TilePoint &minLoc, const TilePoint &maxLoc);  //move to random location Between Two Points
284 
285 	ObjectID copy(const Location &loc);      // copy item to new context
286 	ObjectID copy(const Location &loc, int16 num);   // copy item to new context
287 
288 	//  Create an alias of this object
289 	ObjectID makeAlias(const Location &loc);
290 
291 	//  move the item with a given context
292 	void move(int16 slot);                   // move to new slot in container
293 
294 	//  Activate the object
295 	void activate(void);
296 
297 	//  Deactivate this object
298 	void deactivate(void);
299 
300 	//  Determine if this object is an alias for another object
isAlias()301 	bool isAlias() {
302 		return (_data.objectFlags & objectAlias) != 0;
303 	}
304 
305 	//  check to see if item can be contained by this object
canContain(ObjectID item)306 	bool canContain(ObjectID item) {
307 		return prototype->canContain(thisID(), item);
308 	}
309 
310 	//  check to see if item is contained by the object
311 	bool isContaining(GameObject *item);
312 
313 	//  check if an instance of the specified target is contained in
314 	//  this object
315 	bool isContaining(ObjectTarget *objTarget);
316 
317 	//  determine wether this object has a specified property
hasProperty(const ObjectProperty & objProp)318 	bool hasProperty(const ObjectProperty &objProp) {
319 		return objProp.operator()(this);
320 	}
321 
322 	//  Return the location of the first empty slot
323 	TilePoint getFirstEmptySlot(GameObject *obj);
324 
325 	//  Return the location of the first available slot within this object
326 	//  in which to place the specified object
327 	bool getAvailableSlot(
328 	    GameObject  *obj,
329 	    TilePoint   *slot,
330 	    bool        canMerge = false,
331 	    GameObject  **mergeObj = NULL);
332 
333 	//  Find a slot to place the specified object within this object and
334 	//  drop it in that slot
335 	//  If merge count == 0, then no auto-merging allowed
336 	bool placeObject(
337 	    ObjectID    enactor,
338 	    ObjectID    objID,
339 	    bool        canMerge = false,
340 	    int16       num = 1);
341 
342 	//  Drop the specified object on the ground in a semi-random location
343 	void dropInventoryObject(GameObject *obj, int16 count = 1);
344 
345 	//Get Specific Container From Object
346 	GameObject *getIntangibleContainer(int containerType);
347 
348 	//  generic actions
use(ObjectID enactor)349 	bool use(ObjectID enactor) {
350 		return prototype->use(thisID(), enactor);
351 	}
useOn(ObjectID enactor,ObjectID item)352 	bool useOn(ObjectID enactor, ObjectID item) {
353 		return prototype->useOn(thisID(), enactor, item);
354 	}
355 
useOn(ObjectID enactor,ActiveItem * item)356 	bool useOn(ObjectID enactor, ActiveItem *item) {
357 		return prototype->useOn(thisID(), enactor, item);
358 	}
359 
useOn(ObjectID enactor,Location & loc)360 	bool useOn(ObjectID enactor, Location &loc) {
361 		return prototype->useOn(thisID(), enactor, loc);
362 	}
363 
364 	//  various verb actions that can take place
365 	bool take(ObjectID enactor, int16 num = 1) {
366 		return prototype->take(thisID(), enactor, num);
367 	}
368 	bool drop(ObjectID enactor, const Location &l, int16 num = 1) {
369 		return prototype->drop(thisID(), enactor, l, num);
370 	}
371 	//  drop an object onto another object and handle the result.
372 	bool dropOn(ObjectID enactor, ObjectID target, int16 num = 1) {
373 		return prototype->dropOn(thisID(), enactor, target, num);
374 	}
375 	//  drop this object on a TAG
376 	bool dropOn(ObjectID enactor, ActiveItem *target, const Location &loc, int16 num = 1) {
377 		return prototype->dropOn(thisID(), enactor, target, loc, num);
378 	}
open(ObjectID enactor)379 	bool open(ObjectID enactor) {
380 		return prototype->open(thisID(), enactor);
381 	}
close(ObjectID enactor)382 	bool close(ObjectID enactor) {
383 		return prototype->close(thisID(), enactor);
384 	}
strike(ObjectID enactor,ObjectID item)385 	bool strike(ObjectID enactor, ObjectID item) {
386 		return prototype->strike(thisID(), enactor, item);
387 	}
damage(ObjectID enactor,ObjectID target)388 	bool damage(ObjectID enactor, ObjectID target) {
389 		return prototype->damage(thisID(), enactor, target);
390 	}
eat(ObjectID enactor)391 	bool eat(ObjectID enactor) {
392 		return prototype->eat(thisID(), enactor);
393 	}
insert(ObjectID enactor,ObjectID item)394 	bool insert(ObjectID enactor, ObjectID item) {
395 		return prototype->insert(thisID(), enactor, item);
396 	}
remove(ObjectID enactor)397 	bool remove(ObjectID enactor) {
398 		return prototype->remove(thisID(), enactor);
399 	}
acceptDrop(ObjectID enactor,ObjectID droppedObj,int count)400 	bool acceptDrop(ObjectID enactor, ObjectID droppedObj, int count) {
401 		return prototype->acceptDrop(thisID(), enactor, droppedObj, count);
402 	}
403 	bool acceptDamage(
404 	    ObjectID            enactor,
405 	    int8                absDamage,
406 	    effectDamageTypes   dType = kDamageOther,
407 	    int8                dice = 0,
408 	    uint8               sides = 1,
409 	    int8                perDieMod = 0) {
410 		if (_godmode)
411 			return false;
412 
413 		return  prototype->acceptDamage(
414 		            thisID(),
415 		            enactor,
416 		            absDamage,
417 		            dType,
418 		            dice,
419 		            sides,
420 		            perDieMod);
421 	}
422 	bool acceptHealing(ObjectID enactor, int8 absDamage, int8 dice = 0, uint8 sides = 1, int8 perDieMod = 0) {
423 		return prototype->acceptHealing(thisID(), enactor, absDamage, dice, sides, perDieMod);
424 	}
acceptStrike(ObjectID enactor,ObjectID strikingObj,uint8 skillIndex)425 	bool acceptStrike(
426 	    ObjectID            enactor,
427 	    ObjectID            strikingObj,
428 	    uint8               skillIndex) {
429 		return  prototype->acceptStrike(
430 		            thisID(),
431 		            enactor,
432 		            strikingObj,
433 		            skillIndex);
434 	}
acceptLockToggle(ObjectID enactor,uint8 keyCode)435 	bool acceptLockToggle(ObjectID enactor, uint8 keyCode) {
436 		return prototype->acceptLockToggle(thisID(), enactor, keyCode);
437 	}
acceptMix(ObjectID enactor,ObjectID mixObj)438 	bool acceptMix(ObjectID enactor, ObjectID mixObj) {
439 		return prototype->acceptMix(thisID(), enactor, mixObj);
440 	}
acceptInsertion(ObjectID enactor,ObjectID item,int16 count)441 	bool acceptInsertion(ObjectID enactor, ObjectID item, int16 count) {
442 		return prototype->acceptInsertion(thisID(), enactor, item, count);
443 	}
444 	bool acceptInsertionAt(ObjectID enactor, ObjectID item, const TilePoint &where, int16 num = 1) {
445 		return prototype->acceptInsertionAt(thisID(), enactor, item, where, num);
446 	}
447 
448 	//  query functions:
449 	ObjectID possessor(void);                // return actor posessing this object
450 
451 	//  Access functions
proto(void)452 	ProtoObj *proto(void) {
453 		return prototype;
454 	}
getLocation(void)455 	TilePoint getLocation(void) const {
456 		return _data.location;
457 	}
458 	TilePoint getWorldLocation(void);
459 	bool getWorldLocation(Location &loc);
460 	Location notGetLocation(void);
461 	Location notGetWorldLocation(void);
462 
463 	//  Return the name of this object (proper noun if it has one)
objName(void)464 	const char *objName(void) {
465 		if (_data.nameIndex > 0)
466 			return nameText((int16)_data.nameIndex);
467 		else if (prototype)
468 			return nameText((int16)prototype->nameIndex);
469 
470 		return nameText(0);
471 	}
472 
473 	// return name of object, and it's quantity if merged
474 	void objCursorText(char nameBuf[], const int8 size, int16 count = -1);
475 
476 	// find out if this is a trueskill
477 	bool isTrueSkill(void);
478 
479 	//  Access functions for name index
getNameIndex(void)480 	uint16 getNameIndex(void) {
481 		return _data.nameIndex;
482 	}
setNameIndex(uint16 n)483 	void setNameIndex(uint16 n) {
484 		_data.nameIndex = n;
485 	}
486 
487 	//  Return the name of this type of object
protoName(void)488 	const char *protoName(void) {
489 		return nameText(prototype->nameIndex);
490 	}
491 
492 	//  Update the state of this object.  This function is called every
493 	//  frame for every active object.
494 	void updateState(void);
495 
496 	//  Flag test functions
isOpen(void)497 	bool isOpen(void) {
498 		return (int16)(_data.objectFlags & objectOpen);
499 	}
isLocked(void)500 	bool isLocked(void) {
501 		return (int16)(_data.objectFlags & objectLocked);
502 	}
isImportant(void)503 	bool isImportant(void) {
504 		return (int16)(_data.objectFlags & objectImportant);
505 	}
isGhosted(void)506 	bool isGhosted(void) {
507 		return (_data.objectFlags & objectGhosted)
508 		       || (prototype->flags & ResourceObjectPrototype::objPropGhosted);
509 	}
isInvisible(void)510 	bool isInvisible(void) {
511 		return (_data.objectFlags & objectInvisible)
512 		       || (prototype->flags & ResourceObjectPrototype::objPropHidden);
513 	}
isMoving(void)514 	bool isMoving(void) {
515 		return (int16)(_data.objectFlags & objectMoving);
516 	}
isActivated(void)517 	bool isActivated(void) {
518 		return (int16)(_data.objectFlags & objectActivated);
519 	}
520 
setScavengable(bool val)521 	void setScavengable(bool val) {
522 		if (val)
523 			_data.objectFlags |= objectScavengable;
524 		else
525 			_data.objectFlags &= ~objectScavengable;
526 	}
isScavengable(void)527 	bool isScavengable(void) {
528 		return (_data.objectFlags & objectScavengable) != 0;
529 	}
530 
setObscured(bool val)531 	void setObscured(bool val) {
532 		if (val)
533 			_data.objectFlags |= objectObscured;
534 		else
535 			_data.objectFlags &= ~objectObscured;
536 	}
isObscured(void)537 	bool isObscured(void) {
538 		return (_data.objectFlags & objectObscured) != 0;
539 	}
540 
setTriggeringTAG(bool val)541 	void setTriggeringTAG(bool val) {
542 		if (val)
543 			_data.objectFlags |= objectTriggeringTAG;
544 		else
545 			_data.objectFlags &= ~objectTriggeringTAG;
546 	}
isTriggeringTAG(void)547 	bool isTriggeringTAG(void) {
548 		return (_data.objectFlags & objectTriggeringTAG) != 0;
549 	}
550 
setOnScreen(bool val)551 	void setOnScreen(bool val) {
552 		if (val)
553 			_data.objectFlags |= objectOnScreen;
554 		else
555 			_data.objectFlags &= ~objectOnScreen;
556 	}
isOnScreen(void)557 	bool isOnScreen(void) {
558 		return (_data.objectFlags & objectOnScreen) != 0;
559 	}
560 
setSightedByCenter(bool val)561 	void setSightedByCenter(bool val) {
562 		if (val)
563 			_data.objectFlags |= objectSightedByCenter;
564 		else
565 			_data.objectFlags &= ~objectSightedByCenter;
566 	}
isSightedByCenter(void)567 	bool isSightedByCenter(void) {
568 		return (_data.objectFlags & objectSightedByCenter) != 0;
569 	}
570 
isMissile(void)571 	bool isMissile(void) {
572 		return prototype->isMissile();
573 	}
574 
575 	// image data
576 	Sprite *getIconSprite(void);    // sprite when in inventory + cursor
577 	Sprite *getGroundSprite(void);  // sprite when on ground
578 
579 	// world interaction type flags
580 	uint16 containmentSet(void);
581 
scriptClass(void)582 	uint16 scriptClass(void) {
583 		if (_data.script)
584 			return _data.script;
585 		if (prototype)
586 			return prototype->script;
587 		return 0;
588 	}
589 
590 	//  General access functions
591 
592 	//  Script access functions
getScript(void)593 	uint16 getScript(void) {
594 		return _data.script;
595 	}
setScript(uint16 scr)596 	void setScript(uint16 scr) {
597 		_data.script = scr;
598 	}
599 
600 	//  access function to set object flags
setFlags(uint8 newval,uint8 changeMask)601 	void setFlags(uint8 newval, uint8 changeMask) {
602 		//  Only change the flags spec'd by changeFlags
603 		_data.objectFlags = (newval & changeMask)
604 		              | (_data.objectFlags & ~changeMask);
605 	}
606 
607 	//  Access functions for hit points
getHitPoints(void)608 	uint8 getHitPoints(void) {
609 		return _data.hitPoints;
610 	}
setHitPoints(uint8 hp)611 	void setHitPoints(uint8 hp) {
612 		_data.hitPoints = hp;
613 	}
614 
615 	//  Builds the color remapping for this object based on the
616 	//  prototype's color map
getColorTranslation(ColorTable map)617 	void getColorTranslation(ColorTable map) {
618 		prototype->getColorTranslation(map);
619 	}
620 
621 	//  Functions to get and set prototype (used by scripts)
622 	int32 getProtoNum(void);
623 	void setProtoNum(int32 nProto);
624 
625 	//  Acess functions for extra data
getExtra(void)626 	uint16 getExtra(void) {
627 		return _data.massCount;
628 	}
setExtra(uint16 x)629 	void setExtra(uint16 x) {
630 		_data.massCount = x;
631 	}
632 
633 	//  Function to evaluate the effects of all enchantments
634 	void evalEnchantments(void);
635 
makeSavingThrow(void)636 	bool makeSavingThrow(void) {
637 		return prototype->makeSavingThrow();
638 	}
639 
640 	//  Generic range checking function
641 	bool inRange(const TilePoint &tp, uint16 range);
642 
643 	//  Generic function to test if object can be picked up
isCarryable(void)644 	bool isCarryable(void) {
645 		return prototype->mass <= 200 && prototype->bulk <= 200;
646 	}
647 
isMergeable(void)648 	bool isMergeable(void) {
649 		return (prototype->flags & ResourceObjectPrototype::objPropMergeable) != 0;
650 	}
651 
652 	//  A timer for this object has ticked
653 	void timerTick(TimerID timer);
654 
655 	//  A sensor for this object has sensed an object
656 	void senseObject(SensorID sensor, ObjectID sensedObj);
657 
658 	//  A sensor for this object has sensed an event
659 	void senseEvent(
660 	    SensorID        sensor,
661 	    int16           type,
662 	    ObjectID        directObject,
663 	    ObjectID        indirectObject);
664 
665 	//  Timer related member functions
666 	bool addTimer(TimerID id);
667 	bool addTimer(TimerID id, int16 frameInterval);
668 	void removeTimer(TimerID id);
669 	void removeAllTimers(void);
670 
671 	//  Sensor related member functions
672 private:
673 	bool addSensor(Sensor *newSensor);
674 public:
675 	bool addProtaganistSensor(SensorID id, int16 range);
676 	bool addSpecificActorSensor(SensorID id, int16 range, Actor *a);
677 	bool addSpecificObjectSensor(SensorID id, int16 range, ObjectID obj);
678 	bool addActorPropertySensor(
679 	    SensorID            id,
680 	    int16               range,
681 	    ActorPropertyID     prop);
682 	bool addObjectPropertySensor(
683 	    SensorID            id,
684 	    int16               range,
685 	    ObjectPropertyID    prop);
686 	bool addEventSensor(SensorID id, int16 range, int16 eventType);
687 	void removeSensor(SensorID id);
688 	void removeAllSensors(void);
689 
690 	bool canSenseProtaganist(SenseInfo &info, int16 range);
691 	bool canSenseSpecificActor(SenseInfo &info, int16 range, Actor *a);
692 	bool canSenseSpecificObject(SenseInfo &info, int16 range, ObjectID obj);
693 	bool canSenseActorProperty(
694 	    SenseInfo           &info,
695 	    int16               range,
696 	    ActorPropertyID     prop);
697 	bool canSenseObjectProperty(
698 	    SenseInfo           &info,
699 	    int16               range,
700 	    ObjectPropertyID    prop);
701 
702 	static int32 canStackOrMerge(GameObject *dropObj, GameObject *target);
703 	static void mergeWith(GameObject *dropObj, GameObject *target, int16 count);
704 
705 	bool merge(ObjectID enactor, ObjectID objToMergeID, int16 count);
706 	bool stack(ObjectID enactor, ObjectID objToStackID);
707 
canFitBulkwise(GameObject * obj)708 	bool canFitBulkwise(GameObject *obj) {
709 		return prototype->canFitBulkwise(this, obj);
710 	}
canFitMasswise(GameObject * obj)711 	bool canFitMasswise(GameObject *obj) {
712 		return prototype->canFitMasswise(this, obj);
713 	}
714 
715 	uint16 totalContainedMass(void);
716 	uint16 totalContainedBulk(void);
717 
totalMass(void)718 	uint16 totalMass(void) {
719 		return      prototype->mass * (isMergeable() ? getExtra() : 1)
720 		            +   totalContainedMass();
721 	}
totalBulk(void)722 	uint16 totalBulk(void) {
723 		return prototype->bulk * (isMergeable() ? getExtra() : 1);
724 	}
725 
massCapacity(void)726 	uint16 massCapacity(void) {
727 		return prototype->massCapacity(this);
728 	}
bulkCapacity(void)729 	uint16 bulkCapacity(void) {
730 		return prototype->bulkCapacity(this);
731 	}
732 };
733 
734 /* ===================================================================== *
735    Sector struct
736  * ===================================================================== */
737 
738 class Sector {
739 public:
740 	uint16          activationCount;
741 	ObjectID        childID;
742 
Sector(void)743 	Sector(void) :
744 		activationCount(0),
745 		childID(Nothing) {
746 	}
747 
isActivated(void)748 	bool isActivated(void) {
749 		return activationCount != 0;
750 	}
751 
752 	void activate(void);
753 	void deactivate(void);
754 
755 	void write(Common::MemoryWriteStreamDynamic *out);
756 	void read(Common::InSaveFile *in);
757 };
758 
759 /* ======================================================================= *
760    GameWorld: Describes a world within the game
761  * ======================================================================= */
762 
763 //  Terminology note: A "sector" is a small portion of a map.
764 //  All objects within a sector are stored on a single list.
765 
766 //  The size of a sector (length of side) in UV coodinates.
767 //  A sector is an area of about 4x4 metatiles.
768 
769 class GameWorld : public GameObject {
770 
771 	friend void     initWorlds(void);
772 	friend void     cleanupWorlds(void);
773 	friend void     buildDisplayList(void);
774 
775 	friend class    ProtoObj;
776 	friend class    GameObject;
777 	friend class    ObjectIterator;
778 
779 public:
780 	TilePoint       size;                   // size of world in U/V coords
781 	int16           sectorArraySize;        // size of sector array
782 	Sector          *sectorArray;          // array of sectors
783 	int16           mapNum;                 // map number for this world.
784 
785 	//  Default constructor
GameWorld(void)786 	GameWorld(void) : sectorArraySize(0), sectorArray(nullptr), mapNum(0) {}
787 
788 	//  Initial constructor
789 	GameWorld(int16 map);
790 
791 	GameWorld(Common::SeekableReadStream *stream);
792 
793 	~GameWorld();
794 
795 	int32 archiveSize(void);
796 
797 	void cleanup(void);
798 
getSector(int16 u,int16 v)799 	Sector *getSector(int16 u, int16 v) {
800 		if (u == -1 && v == -1)
801 			return nullptr;
802 
803 		if (v * sectorArraySize + u >= sectorArraySize * sectorArraySize ||
804 		    v * sectorArraySize + u < 0) {
805 			warning("Sector::getSector: Invalid sector: (%d, %d) (sectorArraySize = %d)", u, v, sectorArraySize);
806 			return nullptr;
807 		}
808 
809 		return &(sectorArray)[v * sectorArraySize + u];
810 	}
811 
sectorSize(void)812 	TilePoint sectorSize(void) {         // size of map in sectors
813 		return TilePoint(sectorArraySize, sectorArraySize, 0);
814 	}
815 
IDtoMapNum(ObjectID id)816 	static uint32 IDtoMapNum(ObjectID id) {
817 		assert(isWorld(id));
818 		return ((GameWorld *)GameObject::objectAddress(id))->mapNum;
819 	}
820 };
821 
822 void setCurrentWorld(ObjectID worldID);
823 
824 extern GameWorld    *currentWorld;
825 
826 /* ======================================================================= *
827    GameObject inline member function
828  * ======================================================================= */
829 
830 //------------------------------------------------------------------------
831 //	Return the number of the map of the world on which this object resides.
832 
getMapNum(void)833 inline int16 GameObject::getMapNum(void) {
834 	if (world())
835 		return world()->mapNum;
836 	else if (_data.siblingID) {
837 		GameObject *sibling = GameObject::objectAddress(_data.siblingID);
838 		return sibling->getMapNum();
839 	} else
840 		return currentWorld->mapNum;
841 }
842 
843 /* ======================================================================= *
844    Enchantment Class
845  * ======================================================================= */
846 //class Enchantment {
847 //
848 //public:
849 //	Enchantment(ObjectID Skill,ObjectID Obj);
850 //	~Enchantment();
851 //
852 //};
853 
854 /* ===================================================================== *
855    ActiveRegion class
856  * ===================================================================== */
857 
858 class ActiveRegion {
859 
860 	friend void initActiveRegions(void);
861 	friend void cleanupActiveRegions(void);
862 
863 	friend class ActiveRegionObjectIterator;
864 
865 	ObjectID        anchor;     //  ID of object this region is attached to
866 	TilePoint       anchorLoc;  //  Location of anchor
867 	ObjectID        worldID;
868 	TileRegion      region;     //  Region coords ( in sectors )
869 
870 public:
871 
872 	enum {
873 		kActiveRegionSize = 22
874 	};
875 
ActiveRegion()876 	ActiveRegion() : anchor(0), worldID(0) {}
877 	void update(void);
878 
879 	void read(Common::InSaveFile *in);
880 	void write(Common::MemoryWriteStreamDynamic *out);
881 
882 	//  Return the current region in tile point coords
getRegion(void)883 	TileRegion getRegion(void) {
884 		TileRegion      tReg;
885 
886 		tReg.min.u = region.min.u << kSectorShift;
887 		tReg.min.v = region.min.v << kSectorShift;
888 		tReg.max.u = region.max.u << kSectorShift;
889 		tReg.max.v = region.max.v << kSectorShift;
890 		tReg.min.z = tReg.max.z = 0;
891 
892 		return tReg;
893 	}
894 
895 	//  Return the region world
getWorld(void)896 	GameWorld *getWorld(void) {
897 		return (GameWorld *)GameObject::objectAddress(worldID);
898 	}
899 };
900 
901 void updateActiveRegions(void);
902 
903 //  Return a pointer to an active region given its PlayerActor's ID
904 ActiveRegion *getActiveRegion(PlayerActorID id);
905 
906 void initActiveRegions(void);
907 void saveActiveRegions(Common::OutSaveFile *outS);
908 void loadActiveRegions(Common::InSaveFile *in);
cleanupActiveRegions(void)909 inline void cleanupActiveRegions(void) {}
910 
911 /* ======================================================================= *
912    ObjectIterator Class
913  * ======================================================================= */
914 
915 //  This class simply defines a standard interface for all derived
916 //  object iterator classes.
917 
918 class ObjectIterator {
919 public:
920 	//  Virtual destructor
~ObjectIterator(void)921 	virtual ~ObjectIterator(void) {}
922 
923 	//  Iteration functions
924 	virtual ObjectID first(GameObject **obj) = 0;
925 	virtual ObjectID next(GameObject **obj) = 0;
926 };
927 
928 /* ======================================================================= *
929    SectorRegionObjectIterator Class
930  * ======================================================================= */
931 
932 //  This class iterates through every object within a given region of
933 //  sectors.
934 
935 class SectorRegionObjectIterator : public ObjectIterator {
936 
937 	TilePoint       minSector,
938 	                maxSector,
939 	                sectorCoords;
940 	GameWorld       *searchWorld;
941 	GameObject      *_currentObject;
942 
943 public:
944 	//  Constructor
945 	SectorRegionObjectIterator(GameWorld *world);
946 
947 	//  Constructor
SectorRegionObjectIterator(GameWorld * world,const TileRegion & sectorRegion)948 	SectorRegionObjectIterator(
949 	    GameWorld           *world,
950 	    const TileRegion    &sectorRegion) :
951 		searchWorld(world),
952 		minSector(sectorRegion.min),
953 		maxSector(sectorRegion.max),
954 		_currentObject(nullptr) {
955 		assert(searchWorld != NULL);
956 		assert(isWorld(searchWorld));
957 	}
958 
959 protected:
getSearchWorld(void)960 	GameWorld *getSearchWorld(void) {
961 		return searchWorld;
962 	}
963 
964 public:
965 	//  Iteration functions
966 	ObjectID first(GameObject **obj);
967 	ObjectID next(GameObject **obj);
968 };
969 
970 /* ======================================================================= *
971    RadialObjectIterator Class
972  * ======================================================================= */
973 
974 //	This class will iterate through all objects within a given radius of
975 //	a given center point.
976 
977 class RadialObjectIterator : public SectorRegionObjectIterator {
978 private:
979 
980 	TilePoint       center;
981 	int16           radius;
982 
983 	//  Compute the region of sectors to pass to the ObjectIterator
984 	//  constructor
985 	static TileRegion computeSectorRegion(
986 	    const TilePoint &sectors,
987 	    const TilePoint &center,
988 	    int16           radius);
989 
990 	//  Compute the distance to the specified point from the search
991 	//  center
992 	virtual int16 computeDist(const TilePoint &tp) = 0;
993 
994 protected:
995 
996 	//  Simply return the center coordinates
getCenter(void)997 	TilePoint getCenter(void) {
998 		return center;
999 	}
1000 
1001 public:
1002 
1003 	//  Constructor
RadialObjectIterator(GameWorld * world,const TilePoint & searchCenter,int16 distance)1004 	RadialObjectIterator(
1005 	    GameWorld       *world,
1006 	    const TilePoint &searchCenter,
1007 	    int16           distance) :
1008 		SectorRegionObjectIterator(
1009 		    world,
1010 		    computeSectorRegion(
1011 		        world->sectorSize(),
1012 		        searchCenter,
1013 		        distance)),
1014 		center(searchCenter),
1015 		radius(distance) {
1016 	}
1017 
1018 	//  Return the first object found
1019 	ObjectID first(GameObject **obj, int16 *dist);
1020 	//  Return the next object found
1021 	ObjectID next(GameObject **obj, int16 *dist);
1022 
1023 	//  Return the first object found
first(GameObject ** obj)1024 	ObjectID first(GameObject **obj) {
1025 		return first(obj, NULL);
1026 	}
1027 	//  Return the next object found
next(GameObject ** obj)1028 	ObjectID next(GameObject **obj) {
1029 		return next(obj, NULL);
1030 	}
1031 };
1032 
1033 /* ======================================================================= *
1034    CircularObjectIterator Class
1035  * ======================================================================= */
1036 
1037 //	Iterate through all objects within a circular region
1038 
1039 class CircularObjectIterator : public RadialObjectIterator {
1040 protected:
1041 
1042 	//  Compute the distance to the specified point from the center
1043 	int16 computeDist(const TilePoint &tp);
1044 
1045 public:
1046 	//  Constructor
CircularObjectIterator(GameWorld * world,const TilePoint & searchCenter,int16 distance)1047 	CircularObjectIterator(
1048 	    GameWorld       *world,
1049 	    const TilePoint &searchCenter,
1050 	    int16           distance) :
1051 		RadialObjectIterator(world, searchCenter, distance) {
1052 	}
1053 };
1054 
1055 /* ======================================================================= *
1056    RingObjectIterator Class
1057  * ======================================================================= */
1058 
1059 //	Iterate through all objects within a circular region
1060 
1061 class RingObjectIterator : public CircularObjectIterator {
1062 private:
1063 
1064 	int16 innerDist;
1065 
1066 public:
1067 	//  Constructor
RingObjectIterator(GameWorld * world,const TilePoint & searchCenter,int16 outerDistance,int16 innerDistance)1068 	RingObjectIterator(
1069 	    GameWorld       *world,
1070 	    const TilePoint &searchCenter,
1071 	    int16           outerDistance,
1072 	    int16           innerDistance) :
1073 		CircularObjectIterator(world, searchCenter, outerDistance) {
1074 		innerDist = innerDistance;
1075 	}
1076 
1077 	ObjectID first(GameObject **obj);
1078 	ObjectID next(GameObject **obj);
1079 };
1080 
1081 /* ======================================================================= *
1082    DispRegionObjectIterator Class
1083  * ======================================================================= */
1084 
1085 //	Iterate through all objects within a region parallel to the display
1086 //	area
1087 
1088 class DispRegionObjectIterator : public RadialObjectIterator {
1089 private:
1090 
1091 	//  Compute the distance to the specified point from the center
1092 	int16 computeDist(const TilePoint &tp);
1093 
1094 public:
1095 	//  Constructor
DispRegionObjectIterator(GameWorld * world,const TilePoint & searchCenter,int16 distance)1096 	DispRegionObjectIterator(
1097 	    GameWorld       *world,
1098 	    const TilePoint &searchCenter,
1099 	    int16           distance) :
1100 		RadialObjectIterator(world, searchCenter, distance) {
1101 	}
1102 };
1103 
1104 /* ======================================================================= *
1105    RegionalObjectIterator Class
1106  * ======================================================================= */
1107 
1108 //	Iterate through all objects within a rectangular region
1109 
1110 class RegionalObjectIterator : public SectorRegionObjectIterator {
1111 
1112 	TilePoint       minCoords,
1113 	                maxCoords;
1114 
1115 	//  Calculate the sector region to pass to the ObjectIterator
1116 	//  constructor
1117 	static TileRegion computeSectorRegion(
1118 	    const TilePoint &sectors,
1119 	    const TilePoint &min,
1120 	    const TilePoint &max);
1121 
1122 	//  Test to see if the specified point is within the region
1123 	bool inRegion(const TilePoint &tp);
1124 
1125 public:
1126 	//  Constructor
RegionalObjectIterator(GameWorld * world,const TilePoint & min,const TilePoint & max)1127 	RegionalObjectIterator(
1128 	    GameWorld *world,
1129 	    const TilePoint &min,
1130 	    const TilePoint &max) :
1131 		SectorRegionObjectIterator(
1132 		    world,
1133 		    computeSectorRegion(world->sectorSize(), min, max)),
1134 		minCoords(min),
1135 		maxCoords(max) {
1136 	}
1137 
1138 	//  Iteration functions
1139 	virtual ObjectID first(GameObject **obj);
1140 	virtual ObjectID next(GameObject **obj);
1141 };
1142 
1143 /* ======================================================================= *
1144    RectangularObjectIterator Class
1145  * ======================================================================= */
1146 
1147 //	Iterate through all objects within a rectangular region
1148 
1149 class RectangularObjectIterator : public RegionalObjectIterator {
1150 
1151 	TilePoint center,
1152 	          coords1,
1153 	          coords2,
1154 	          coords3,
1155 	          coords4;
1156 
1157 	//  Test to see if the specified point is within the region
1158 	bool inRegion(const TilePoint &tp);
1159 
1160 public:
1161 	//  Constructor
1162 	RectangularObjectIterator(
1163 	    GameWorld *world,
1164 	    const TilePoint &c,
1165 	    const TilePoint &cdelta1,
1166 	    const TilePoint &cdelta2);
1167 
1168 	virtual ObjectID first(GameObject **obj);
1169 	virtual ObjectID next(GameObject **obj);
1170 
1171 };
1172 
1173 /* ======================================================================= *
1174    TriangularObjectIterator Class
1175  * ======================================================================= */
1176 
1177 //	Iterate through all objects within a rectangular region
1178 
1179 class TriangularObjectIterator : public RegionalObjectIterator {
1180 
1181 	TilePoint       coords1,
1182 	                coords2,
1183 	                coords3;
1184 
1185 	//  Test to see if the specified point is within the region
1186 	bool inRegion(const TilePoint &tp);
1187 
1188 public:
1189 	//  Constructor
1190 	TriangularObjectIterator(
1191 	    GameWorld *world,
1192 	    const TilePoint &c1,
1193 	    const TilePoint &c2,
1194 	    const TilePoint &c3);
1195 
1196 	//  Iteration functions
1197 	ObjectID first(GameObject **obj);
1198 	ObjectID next(GameObject **obj);
1199 };
1200 
1201 /* ======================================================================= *
1202    CenterRegionObjectIterator Class
1203  * ======================================================================= */
1204 
1205 class CenterRegionObjectIterator : public RegionalObjectIterator {
1206 
1207 	static GameWorld *CenterWorld(void);
1208 	static TilePoint MinCenterRegion(void);
1209 	static TilePoint MaxCenterRegion(void);
1210 
1211 public:
1212 	//  Constructor
CenterRegionObjectIterator(void)1213 	CenterRegionObjectIterator(void) :
1214 		RegionalObjectIterator(CenterWorld(),
1215 		                       MinCenterRegion(),
1216 		                       MaxCenterRegion()) {}
1217 
1218 };
1219 
1220 /* ======================================================================= *
1221    ActiveRegionObjectIterator Class
1222  * ======================================================================= */
1223 
1224 class ActiveRegionObjectIterator : public ObjectIterator {
1225 
1226 	int16           activeRegionIndex;
1227 	TilePoint       baseSectorCoords,
1228 	                size,
1229 	                sectorCoords;
1230 	uint8           sectorBitMask;
1231 	GameWorld       *currentWorld;
1232 	GameObject      *_currentObject;
1233 
1234 	bool firstActiveRegion(void);
1235 	bool nextActiveRegion(void);
1236 	bool firstSector(void);
1237 	bool nextSector(void);
1238 
1239 public:
1240 	//  Constructor
ActiveRegionObjectIterator(void)1241 	ActiveRegionObjectIterator(void) : activeRegionIndex(-1), sectorBitMask(0), currentWorld(nullptr), _currentObject(nullptr) {}
1242 
1243 	//  Iteration functions
1244 	ObjectID first(GameObject **obj);
1245 	ObjectID next(GameObject **obj);
1246 };
1247 
1248 /* ============================================================================ *
1249    Container Iterator Class
1250  * ============================================================================ */
1251 
1252 //  This class iterates through every object within a container
1253 
1254 class ContainerIterator {
1255 	ObjectID         nextID;
1256 
1257 public:
1258 	GameObject      *object;
1259 
1260 	//  Constructor
1261 	ContainerIterator(GameObject *container);
1262 
1263 	//  Iteration function
1264 	ObjectID        next(GameObject **obj);
1265 };
1266 
1267 /* ============================================================================ *
1268    Recursive Container iterator Class
1269  * ============================================================================ */
1270 
1271 //  This class iterates through every object within a container and
1272 //  all of the containers within the container
1273 
1274 #if 0
1275 class RecursiveContainerIterator {
1276 	ObjectID                    id;
1277 	RecursiveContainerIterator  *subIter;
1278 
1279 public:
1280 	//  Constructor
1281 	RecursiveContainerIterator(GameObject *container) :
1282 		id(container->IDChild()),
1283 		subIter(NULL) {
1284 	}
1285 	~RecursiveContainerIterator(void);
1286 
1287 	//  Iteration functions
1288 	ObjectID first(GameObject **obj);
1289 	ObjectID next(GameObject **obj);
1290 };
1291 #else
1292 
1293 class RecursiveContainerIterator {
1294 	ObjectID                    id,
1295 	                            root;
1296 
1297 public:
1298 	//  Constructor
RecursiveContainerIterator(GameObject * container)1299 	RecursiveContainerIterator(GameObject *container) :
1300 		root(container->thisID()), id(0) {}
1301 
1302 	//  Iteration functions
1303 	ObjectID first(GameObject **obj);
1304 	ObjectID next(GameObject **obj);
1305 };
1306 
1307 #endif
1308 
1309 /* ============================================================================ *
1310    Object sound effect struct
1311  * ============================================================================ */
1312 
1313 struct ObjectSoundFXs {
1314 	uint8           soundFXHitFlesh,
1315 	                soundFXHitHard,
1316 	                soundFXParried,
1317 	                soundFXMissed;
1318 };
1319 
1320 /* ======================================================================= *
1321    Misc Prototypes
1322  * ======================================================================= */
1323 
1324 
1325 //  Defines values for sixteen missile facings, plus a value for no
1326 //  missile facing.
1327 enum MissileFacings {
1328 	missileUp,
1329 	missileUpUpLf,
1330 	missileUpLf,
1331 	missileUpLfLf,
1332 	missileLf,
1333 	missileDnLfLf,
1334 	missileDnLf,
1335 	missileDnDnLf,
1336 	missileDn,
1337 	missileDnDnRt,
1338 	missileDnRt,
1339 	missileDnRtRt,
1340 	missileRt,
1341 	missileUpRtRt,
1342 	missileUpRt,
1343 	missileUpUpRt,
1344 	missileNoFacing
1345 };
1346 
1347 enum blockageType {
1348 	blockageNone = 0,
1349 	blockageTerrain,
1350 	blockageObject
1351 };
1352 
1353 uint32 objectTerrain(GameObject *obj);
1354 
1355 //  Return an object which is in collision with another object.
1356 GameObject *objectCollision(GameObject *obj, GameWorld *world, const TilePoint &loc);
1357 
1358 //  Test for line of sight between two objects
1359 bool lineOfSight(GameObject *obj1, GameObject *obj2, uint32 terrainMask);
1360 bool lineOfSight(GameObject *obj, const TilePoint &loc, uint32 terrainMask);
1361 bool lineOfSight(
1362     GameWorld       *world,
1363     const TilePoint &loc1,
1364     const TilePoint &loc2,
1365     uint32          terrainMask);
1366 
1367 //  Test if object is obscured by terrain
1368 bool objObscured(GameObject *testObj);
1369 
1370 //  Determine which object mouse pointer is picking
1371 ObjectID pickObject(const StaticPoint32 &mouse, StaticTilePoint &objPos);
1372 
1373 //  Create enchantment attach it to object
1374 ObjectID EnchantObject(
1375     ObjectID        target,
1376     int             enchantmentType,
1377     int             duration);
1378 
1379 //  Find an enchantment of a particular type
1380 ObjectID FindObjectEnchantment(
1381     ObjectID        target,
1382     int             enchantmentType);
1383 
1384 //  Remove an enchantment of a particular type
1385 bool DispelObjectEnchantment(
1386     ObjectID        target,
1387     int             enchantmentType);
1388 
1389 //  Function to eval the enchantments on an actor
1390 void evalActorEnchantments(Actor *a);
1391 
1392 //  Function to eval the enchantments on an actor
1393 void evalObjectEnchantments(GameObject *obj);
1394 
1395 //  Load prototypes from resource file
1396 void initPrototypes(void);
1397 
1398 //  Cleanup the prototype lists
1399 void cleanupPrototypes(void);
1400 
1401 //  Load the sound effects table
1402 void initObjectSoundFXTable(void);
1403 
1404 //  Cleanup the sound effects table
1405 void cleanupObjectSoundFXTable(void);
1406 
1407 //  Allocate array to hold the counts of the temp actors
1408 void initTempActorCount(void);
1409 
1410 //  Save the array of temp actor counts
1411 void saveTempActorCount(Common::OutSaveFile *outS);
1412 
1413 //  Load the array of temp actor counts
1414 void loadTempActorCount(Common::InSaveFile *in, int32 chunkSize);
1415 
1416 //  Cleanup the array to temp actor counts
1417 void cleanupTempActorCount(void);
1418 
1419 //  Increment the temporary actor count for the specified prototype
1420 void incTempActorCount(uint16 protoNum);
1421 
1422 //  Decrement the temporary actor count for the specified prototype
1423 void decTempActorCount(uint16 protoNum);
1424 
1425 //  Return the number of temporary actors for the specified prototype
1426 uint16 getTempActorCount(uint16 protoNum);
1427 
1428 //  Init game worlds
1429 void initWorlds(void);
1430 
1431 //  Save worlds to the save file
1432 void saveWorlds(Common::OutSaveFile *outS);
1433 
1434 //  Load worlds from the save file
1435 void loadWorlds(Common::InSaveFile *in);
1436 
1437 //  Cleanup game worlds
1438 void cleanupWorlds(void);
1439 
1440 //  Initialize object list
1441 void initObjects(void);
1442 
1443 //  Save the objects to the save file
1444 void saveObjects(Common::OutSaveFile *outS);
1445 
1446 //  Load the objects from the save file
1447 void loadObjects(Common::InSaveFile *in);
1448 
1449 //  Cleanup object list
1450 void cleanupObjects(void);
1451 
1452 //  Do background processing for objects
1453 void doBackgroundSimulation(void);
1454 
1455 void pauseBackgroundSimulation(void);
1456 void resumeBackgroundSimulation(void);
1457 
1458 // cleanup the ready container stuff
1459 void cleanupReadyContainers(void);
1460 
1461 //  This function simply calls the GameObject::updateState() method
1462 //  for all active objects directly within a world.
1463 void updateObjectStates(void);
1464 
1465 void pauseObjectStates(void);
1466 void resumeObjectStates(void);
1467 
1468 void readyContainerSetup(void);
1469 void cleanupReadyContainers(void);
1470 
1471 } // end of namespace Saga2
1472 
1473 #endif
1474