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 
23 #ifndef ASYLUM_RESOURCES_ACTOR_H
24 #define ASYLUM_RESOURCES_ACTOR_H
25 
26 #include "common/array.h"
27 #include "common/rect.h"
28 #include "common/serializer.h"
29 #include "common/stream.h"
30 
31 #include "asylum/shared.h"
32 
33 #include "asylum/resources/inventory.h"
34 
35 namespace Asylum {
36 
37 class AsylumEngine;
38 class GraphicResource;
39 class Screen;
40 
41 struct ActionArea;
42 struct GraphicFrame;
43 
44 struct ActorData : public Common::Serializable {
45 	uint32 count;
46 	int32 current;
47 	Common::Point points[120];
48 	ActorDirection directions[120];
49 
ActorDataActorData50 	ActorData() {
51 		count = 0;
52 		current = 0;
53 		memset(&directions, 0, sizeof(directions));
54 	}
55 
~ActorDataActorData56 	virtual ~ActorData() {}
57 
loadActorData58 	void load(Common::SeekableReadStream *stream) {
59 		count = stream->readUint32LE();
60 
61 		current = stream->readUint32LE();
62 
63 		for (int32 i = 0; i < 120; i++) {
64 			points[i].x = stream->readSint32LE();
65 			points[i].y = stream->readSint32LE();
66 		}
67 
68 		for (int32 i = 0; i < 120; i++)
69 			directions[i] = (ActorDirection)stream->readSint32LE();
70 	}
71 
72 	// Serializable
saveLoadWithSerializerActorData73 	void saveLoadWithSerializer(Common::Serializer &s) {
74 		s.syncAsUint32LE(count);
75 		s.syncAsSint32LE(current);
76 
77 		for (int32 i = 0; i < ARRAYSIZE(points); i++) {
78 			s.syncAsSint32LE(points[i].x);
79 			s.syncAsSint32LE(points[i].y);
80 		}
81 
82 		for (int32 i = 0; i < ARRAYSIZE(directions); i++)
83 			s.syncAsSint32LE(directions[i]);
84 	}
85 };
86 
87 class Actor : public Common::Serializable {
88 public:
89 	Actor(AsylumEngine *engine, ActorIndex index);
~Actor()90 	virtual ~Actor() {};
91 
92 	//////////////////////////////////////////////////////////////////////////
93 	// Public variables & accessors
94 	//////////////////////////////////////////////////////////////////////////
95 	int32 flags;
96 	int32 actionType; // ActionType enum value
97 	Inventory inventory;
98 
setActionIndex2(int32 index)99 	void setActionIndex2(int32 index) { _actionIdx2 = index; }
setObjectIndex(int32 index)100 	void setObjectIndex(int32 index) { _objectIndex = index; }
setDirection(ActorDirection dir)101 	void setDirection(ActorDirection dir) { _direction = dir; }
setFrameCount(int32 count)102 	void setFrameCount(int32 count) { _frameCount = count; }
setFrameIndex(int32 number)103 	void setFrameIndex(int32 number) { _frameIndex = number; }
setLastScreenUpdate(int32 tick)104 	void setLastScreenUpdate(int32 tick) { _lastScreenUpdate = tick; }
setNumberFlag01(int32 number)105 	void setNumberFlag01(int32 number) { _numberFlag01 = number; }
setPriority(int32 priority)106 	void setPriority(int32 priority) { _priority = priority; }
setResourceId(ResourceId id)107 	void setResourceId(ResourceId id) { _resourceId = id; }
setSoundResourceId(ResourceId id)108 	void setSoundResourceId(ResourceId id) { _soundResourceId = id; }
setStatus(ActorStatus status)109 	void setStatus(ActorStatus status) { _status = status; }
setTransparency(int32 val)110 	void setTransparency(int32 val) { _transparency = val; }
setTickCount(int32 tickCount)111 	void setTickCount(int32 tickCount) { _tickCount = tickCount; }
112 
setField934(int32 val)113 	void setField934(int32 val) { _field_934 = val; }
setField938(int32 val)114 	void setField938(int32 val) { _field_938 = val; }
setField944(int32 val)115 	void setField944(int32 val) { _field_944 = val; }
116 
getActionIndex3()117 	int32          getActionIndex3() { return _actionIdx3; }
getBoundingRect()118 	Common::Rect  *getBoundingRect() { return &_boundingRect; }
getDirection()119 	ActorDirection getDirection() { return _direction; }
getFrameCount()120 	uint32         getFrameCount() { return _frameCount; }
getFrameIndex()121 	uint32         getFrameIndex() { return _frameIndex; }
getName()122 	char          *getName() { return (char *)&_name; }
getNextActorIndex()123 	ActorIndex     getNextActorIndex() { return _nextActorIndex; }
getNumberValue01()124 	int32          getNumberValue01() { return _numberValue01; }
getPoint()125 	Common::Point *getPoint() { return &_point; }
getPoint1()126 	Common::Point *getPoint1() { return &_point1; }
getPoint2()127 	Common::Point *getPoint2() { return &_point2; }
getPriority()128 	int32          getPriority() { return _priority; }
getResourceId()129 	ResourceId     getResourceId() { return _resourceId; }
getResourcesId(uint32 index)130 	ResourceId     getResourcesId(uint32 index) { return _graphicResourceIds[index]; }
getScriptIndex()131 	int32          getScriptIndex() { return _scriptIndex; }
shouldInvertPriority()132 	bool           shouldInvertPriority() { return _invertPriority; }
getSoundResourceId()133 	ResourceId     getSoundResourceId() { return _soundResourceId; }
getStatus()134 	ActorStatus    getStatus()    { return _status; }
getTickCount()135 	int32          getTickCount() { return _tickCount; }
136 
getField934()137 	int32          getField934() { return _field_934; }
getField944()138 	int32          getField944() { return _field_944; }
getField948()139 	int32          getField948() { return _field_948; }
getField94C()140 	int32          getField94C() { return _field_94C; }
141 
142 	// For saving
getData()143 	ActorData     *getData() { return &_data; }
144 
145 	/////////////////////////////////////////////////////////////////////////
146 	// Data
147 	/////////////////////////////////////////////////////////////////////////
148 
149 	/**
150 	 * Loads the actor
151 	 *
152 	 * @param stream If non-null, the Common::SeekableReadStream to load from
153 	 */
154 	void load(Common::SeekableReadStream *stream);
155 
156 	/////////////////////////////////////////////////////////////////////////
157 	// Visibility
158 	/////////////////////////////////////////////////////////////////////////
159 
160 	/**
161 	 * Query if this actor is visible.
162 	 *
163 	 * @return true if visible, false if not.
164 	 */
isVisible()165 	bool isVisible() { return flags & kActorFlagVisible; }
166 
167 	/**
168 	 * Query if this actor is on screen.
169 	 *
170 	 * @return true if on screen, false if not.
171 	 */
172 	bool isOnScreen();
173 
174 	/**
175 	 * Shows this actor.
176 	 */
show()177 	void show() { setVisible(true); }
178 
179 	/**
180 	 * Hides this actor.
181 	 */
hide()182 	void hide() { setVisible(false); }
183 
184 	/////////////////////////////////////////////////////////////////////////
185 	// Drawing & update
186 	//////////////////////////////////////////////////////////////////////////
187 
188 	/**
189 	 * Draws the actor
190 	 */
191 	void draw();
192 
193 	/**
194 	 * Draw number text (called on scene drawing)
195 	 */
196 	void drawNumber();
197 
198 	/**
199 	 * Updates the actor.
200 	 */
201 	void update();
202 
203 	/**
204 	 * Enables the actor
205 	 */
enable()206 	void enable() { changeStatus(kActorStatusEnabled); }
207 
208 	/**
209 	 * Changes the actor status.
210 	 *
211 	 * @param status The status.
212 	 */
213 	void changeStatus(ActorStatus status);
214 
215 	/////////////////////////////////////////////////////////////////////////
216 	// Direction & position
217 	/////////////////////////////////////////////////////////////////////////
218 
219 	/**
220 	 * Updates the actor's mirror image.
221 	 */
222 	void updateReflectionData();
223 
224 	/**
225 	 * Updates resource Id using the actor direction.
226 	 *
227 	 * @param direction The direction.
228 	 */
229 	void changeDirection(ActorDirection direction);
230 
231 	/**
232 	 * Face a target from a certain direction
233 	 *
234 	 * @param target Identifier for the target.
235 	 * @param from   direction to face from.
236 	 */
237 	void faceTarget(uint32 target, DirectionFrom from);
238 
239 	/**
240 	 * Initialize the x1/y1 values of the actor, update the active animation frame and, if the current direction isn't 8, update the actor's direction.
241 	 *
242 	 * @param newX 		   The new x coordinate.
243 	 * @param newY 		   The new y coordinate.
244 	 * @param newDirection The new direction.
245 	 * @param frame 	   The frame.
246 	 */
247 	void setPosition(int16 newX, int16 newY, ActorDirection newDirection, uint32 frame);
248 
249 	/**
250 	 * Query if a graphic resource is present.
251 	 *
252 	 * @param index Zero-based index of the graphic resource.
253 	 *
254 	 * @return true if the graphic resource is present.
255 	 */
256 	bool canChangeStatus(int index) const;
257 
258 	/**
259 	 * Adjust coordinates.
260 	 *
261 	 * @param point The point.
262 	 */
263 	void adjustCoordinates(Common::Point *point);
264 
265 	/////////////////////////////////////////////////////////////////////////
266 	// Misc
267 	/////////////////////////////////////////////////////////////////////////
268 
269 	/**
270 	 * Stop the actor related sounds
271 	 */
272 	void stopSound();
273 
274 	/**
275 	 * Convert this object into a string representation.
276 	 *
277 	 * @param shortString toggle whether to output a summary or
278 	 *                    detailed view of the actor object
279 	 * @return A string representation of this object.
280 	 */
281 	Common::String toString(bool shortString = true);
282 
283 	/**
284 	 * Clears actor data fields
285 	 */
286 	void clearFields();
287 
288 	bool canReach(const Common::Point &point);
289 	void forceTo(int16 actorX, int16 actorY, bool doSpeech);
290 	void setupReflectionData(ActorIndex nextActor, int32 actionAreaId, ActorDirection nextDirection, const Common::Point &nextPosition, bool invertPriority, const Common::Point &nextPositionOffset);
291 	bool aNicePlaceToTalk(Common::Point *point, int32* param);
292 	bool canMove(Common::Point *point, ActorDirection direction, uint32 count, bool hasDelta);
293 	void move(ActorDirection dir, uint32 distance);
294 	bool testActorCollision(Common::Point *point, ActorDirection direction);
295 	void drawInventory();
296 	void stopWalking();
297 
298 	/**
299 	 * Query if the object resource is present in the resource table between indices 10 & 20
300 	 *
301 	 * @return true if resource present between 15 & 20, false if not.
302 	 */
303 	bool checkBoredStatus() const;
304 
305 	//////////////////////////////////////////////////////////////////////////
306 	// Static update methods
307 	//////////////////////////////////////////////////////////////////////////
308 	static void crowsReturn(AsylumEngine *engine);
309 
310 	/**
311 	 * Updates the player appearance in chapter 9.
312 	 *
313 	 * @param [in,out] engine If non-null, the engine.
314 	 * @param nextPlayer 	  The next player index
315 	 */
316 	static void morphInto(AsylumEngine *engine, int nextPlayer);
317 
318 	/**
319 	 * Gets a direction using the angle between the two vectors.
320 	 *
321 	 * @param vec1 The first vector.
322 	 * @param vec2 The second vector.
323 	 *
324 	 * @return The direction
325 	 */
326 	static ActorDirection getAngle(const Common::Point &vec1, const Common::Point &vec2);
327 
328 	/**
329 	 * Gets the euclidean distance between two points.
330 	 *
331 	 * @param point1 The first point.
332 	 * @param point2 The second point.
333 	 *
334 	 * @return the distance.
335 	 */
336 	static uint32 euclidianDistance(const Common::Point &point1, const Common::Point &point2);
337 
338 	// Serializable
339 	void saveLoadWithSerializer(Common::Serializer &s);
340 
341 private:
342 	AsylumEngine *_vm;
343 
344 	// Our current index
345 	ActorIndex _index;
346 
347 	//////////////////////////////////////////////////////////////////////////
348 	// Data
349 	//////////////////////////////////////////////////////////////////////////
350 	Common::Point _point;
351 	ResourceId _resourceId;
352 	int32  _objectIndex;
353 	uint32 _frameIndex;
354 	uint32 _frameCount;
355 	Common::Point _point1;
356 	Common::Point _point2;
357 	Common::Rect _boundingRect;
358 	ActorDirection _direction;
359 	int32  _field_3C;
360 	ActorStatus _status;
361 	int32  _field_44;
362 	int32  _priority;
363 	//flags
364 	int32  _field_50;
365 	int32  _field_54;
366 	int32  _field_58;
367 	int32  _field_5C;
368 	int32  _field_60;
369 	int32  _actionIdx3;
370 	// TODO field_68 till field_617
371 	ResourceId _walkingSound1;
372 	ResourceId _walkingSound2;
373 	ResourceId _walkingSound3;
374 	ResourceId _walkingSound4;
375 	uint32  _field_64C;
376 	uint32  _field_650;
377 	ResourceId  _graphicResourceIds[55];
378 	char   _name[256];
379 	int32  _distancesEO[20];
380 	int32  _distancesNS[20];
381 	int32  _distancesNSEO[20];
382 	int32  _actionIdx2;
383 	int32  _field_924;
384 	uint32 _lastScreenUpdate;
385 	int32  _scriptIndex;
386 	//actionType
387 	int32  _field_934;
388 	int32  _field_938;
389 	ResourceId _soundResourceId; // field_93C
390 	int32  _numberValue01;
391 	int32  _field_944; // has collision ?!
392 	int32  _field_948;
393 	int32  _field_94C;
394 	int32  _numberFlag01;
395 	int16  _numberStringWidth;
396 	Common::Point _numberPoint;
397 	char   _numberString01[8];
398 	int32  _field_968;
399 	int32  _transparency;
400 	bool   _processNewDirection;
401 	bool   _invertPriority;
402 	ActorDirection _nextDirection;
403 	int32  _nextActionIndex;
404 	ActorIndex _nextActorIndex;
405 	Common::Point _nextPositionOffset;
406 	Common::Point _nextPosition;
407 	int32  _field_994;
408 	int32  _field_998;
409 	int32  _field_99C;
410 	int32  _field_9A0;
411 
412 	//////////////////////////////////////////////////////////////////////////
413 	// Actor data
414 	//////////////////////////////////////////////////////////////////////////
415 	ActorData _data;
416 
417 	int32 _tickCount;
418 
419 	uint32 _updateCounter;
420 
421 	//////////////////////////////////////////////////////////////////////////
422 	// Update methods
423 	//////////////////////////////////////////////////////////////////////////
424 	void updateStatusInteracting();
425 	void checkPumpkinDeath();
426 	void updatePumpkin(GameFlag flagToCheck, GameFlag flagToSet, ObjectId objectToUpdate, ObjectId objectToDisable);
427 
428 	void updateStatusEnabled();
429 	void updateStatusEnabledProcessStatus(int16 testX, int16 testY, uint32 counter, int16 setX, int16 setY);
430 
431 	void updateStatusBored();
432 
433 	void CrowClosesIn();
434 	void ScareCrowClosesIn();
435 	void TentacleRises();
436 
437 	void updateStatusEnabled2();
438 	void CrowHoveringBeforeKill();
439 	void CrowStatusQuo();
440 	void TentacleWigglesForSarah();
441 
442 	void CrowDives();
443 	void MaxGetsHit();
444 	void MaxAttacks();
445 	void checkScareCrowDeath();
446 	bool checkCrowDeath();
447 	void ScareCrowAttacks();
448 	bool actorsIntersect(ActorIndex actorIndex1, ActorIndex actorIndex2);
449 	void TentacleWhips();
450 	void SarahAttacks();
451 
452 	void MaxGetsSome();
453 	void SarahGetsSome();
454 
455 	void TentacleDies();
456 
457 	void CrowSwoops();
458 	void ScareCrowRetreats();
459 
460 	void updateStatusMorphing();
461 
462 	void actionAreaCheck();
463 
464 	//////////////////////////////////////////////////////////////////////////
465 	// Path finding functions
466 	//////////////////////////////////////////////////////////////////////////
467 	uint32 _frameNumber;
468 	bool findLeftPath(Common::Point source, const Common::Point &destination, Common::Array<int> *actions);
469 	bool findRightPath(Common::Point source,  const Common::Point &destination, Common::Array<int> *actions);
470 	bool findUpPath(Common::Point source,  const Common::Point &destination, Common::Array<int> *actions);
471 	bool findDownPath(Common::Point source, const Common::Point &destination, Common::Array<int> *actions);
472 	bool tryDirection(const Common::Point &source, Common::Array<int> *actions, Common::Point *point, ActorDirection direction, const Common::Point &destination, bool *flag);
473 	bool canGetToDest(Common::Array<int> *actions, const Common::Point &point, ActorDirection direction, int16 loopcount);
474 	bool testPolyInLink(const Common::Point &pt, Common::Array<int> *actions);
475 
476 	//////////////////////////////////////////////////////////////////////////
477 	// Misc
478 	//////////////////////////////////////////////////////////////////////////
479 
480  	/**
481 	 * Sets actor visibility
482 	 *
483 	 * @param value true to set to visible, false to set to hidden.
484 	 */
485 	void setVisible(bool value);
486 
487 	/**
488 	 * Sets the volume.
489 	 */
490 	void setVolume();
491 
492 	void TentacleBlocksSarah(const Common::Point &vec1, Common::Point vec2);
493 	void SarahDies();
494 
495 	/**
496 	 * Updates the actor "number" data if the item is "1".
497 	 *
498 	 * @param item     The item.
499 	 * @param point    The coordinates
500 	 */
501 	void updateNumbers(uint item, const Common::Point &point);
502 
503 	/**
504 	 * Determine if the supplied point is in the action area
505 	 *
506 	 * @param pt 			The point.
507 	 * @param [in,out] area If non-null, the area.
508 	 *
509 	 * @return true if in the action area, false otherwise
510 	 */
511 	bool isInActionArea(const Common::Point &pt, ActionArea *area);
512 
513 	//////////////////////////////////////////////////////////////////////////
514 	// Helper methods
515 	//////////////////////////////////////////////////////////////////////////
516 
517 	/**
518 	 * Updates the actor graphic information
519 	 *
520 	 * @param offset The offset used to get the id from the _graphicResourceIds table
521 	 */
522 	void updateGraphicData(uint32 offset);
523 
524 	/**
525 	 * Gets the graphics flag for queuing the actor graphics (mirrored or normal)
526 	 *
527 	 * @return The graphics flag.
528 	 */
529 	DrawFlags getGraphicsFlags();
530 
531 	/**
532 	 * Gets the absolute value of the walk increment for a frame.
533 	 *
534 	 * @param direction  The direction.
535 	 * @param frameIndex Zero-based index of the frame.
536 	 *
537 	 * @return The absolute value of the walk increment.
538 	 */
539 	int32 getStride(ActorDirection direction, uint32 frameIndex) const;
540 
541 	/**
542 	 * Gets the walk increment for a frame.
543 	 *
544 	 * @param direction  The direction.
545 	 * @param frameIndex Zero-based index of the frame.
546 	 *
547 	 * @return The walk increment.
548 	 */
549 	int32 getWalkIncrement(ActorDirection direction, uint32 frameIndex) const;
550 
551 	/**
552 	 * Updates the coordinates depending on the direction.
553 	 *
554 	 * @param direction 	 The direction.
555 	 * @param delta 		 The delta.
556 	 * @param [in,out] point If non-null, the point.
557 	 */
558 	static void incPosition(ActorDirection direction, int16 delta, Common::Point *point);
559 
560 	/**
561 	 * Get the angle between the two vectors
562 	 *
563 	 * @param p1 The first vector.
564 	 * @param p2 The second vector.
565 	 *
566 	 * @return the angle
567 	 */
568 	static int32 getAngleOfVector(const Common::Point &vec1, const Common::Point &vec2);
569 
570 	/**
571 	 * Computes the Scare Crow's strike zone.
572 	 *
573 	 * @param rect          The strike zone.
574 	 * @param direction 	The direction.
575 	 * @param point 		The point.
576 	 */
577 	static void getCrowStrikeZone(Common::Rect *rect, ActorDirection direction, const Common::Point &point);
578 
579 	/**
580 	 * Determines the direction of the shortest rotation between two vectors.
581 	 *
582 	 * @param vec1 The first vector.
583 	 * @param vec2 The second vector.
584 	 *
585 	 * @return true if CCW, false if CW.
586 	 */
587 	static bool determineLeftOrRight(const Common::Point &vec1, const Common::Point &vec2);
588 
589 	/**
590 	 * Gets the adjustment for the X-coordinate of the supplied point.
591 	 *
592 	 * @param rect  The rectangle.
593 	 * @param point The test point.
594 	 *
595 	 * @return value depending on the horizontal position of the point relative to the rectangle.
596 	 */
597 	static int16 pointInRectXAdjust(const Common::Rect &rect, const Common::Point &point);
598 
599 	/**
600 	 * Gets the adjustment for the Y-coordinate of the supplied point.
601 	 *
602 	 * @param rect  The rectangle.
603 	 * @param point The test point.
604 	 *
605 	 * @return value depending on the vertical position of the point relative to the rectangle.
606 	 */
607 	static int16 pointInRectYAdjust(const Common::Rect &rect, const Common::Point &point);
608 
609 }; // end of class MainActor
610 
611 } // end of namespace Asylum
612 
613 #endif // ASYLUM_RESOURCES_ACTOR_H
614