27 #include "common/savefile.h" 29 #include "saga/sprite.h" 30 #include "saga/itedata.h" 31 #include "saga/saga.h" 32 #include "saga/font.h" 41 #define ACTOR_BARRIERS_MAX 16 43 #define ACTOR_MAX_STEPS_COUNT 32 45 #define ACTOR_DIALOGUE_HEIGHT 100 49 #define ACTOR_SPEED 72 51 #define ACTOR_CLIMB_SPEED 8 53 #define ACTOR_COLLISION_WIDTH 32 54 #define ACTOR_COLLISION_HEIGHT 8 56 #define ACTOR_DIRECTIONS_COUNT 4 // for ActorFrameSequence 58 #define ACTOR_SPEECH_STRING_MAX 16 // speech const 59 #define ACTOR_SPEECH_ACTORS_MAX 8 61 #define ACTOR_DRAGON_TURN_MOVES 4 62 #define ACTOR_DRAGON_INDEX 133 64 #define ACTOR_NO_ENTRANCE -1 66 #define ACTOR_EXP_KNOCK_RIF 24 68 #define PATH_NODE_EMPTY -1 70 #define ACTOR_INHM_SIZE 228 72 enum ActorDirections {
81 kActionWalkToPoint = 1,
82 kActionWalkToLink = 2,
88 kActionCycleFrames = 8,
89 kActionPongFrames = 9,
101 kFrameITEGesture = 4,
109 kFrameIHNMGesture = 3,
120 enum ActorFrameTypes {
132 static const int actorDirectionsLUT[8] = {
144 kActorNoCollide = (1 << 0),
145 kActorNoFollow = (1 << 1),
146 kActorCollided = (1 << 2),
147 kActorBackwards = (1 << 3),
148 kActorContinuous = (1 << 4),
149 kActorFinalFace = (1 << 5),
150 kActorFinishLeft = ((1 << 5) | (kDirLeft << 6)),
151 kActorFinishRight = ((1 << 5) | (kDirRight << 6)),
152 kActorFinishUp = ((1 << 5) | (kDirUp << 6)),
153 kActorFinishDown = ((1 << 5) | (kDirDown << 6)),
154 kActorFacingMask = (0xf << 5),
155 kActorRandom = (1 << 10)
161 kPathCellBarrier = 0x57
164 enum DragonMoveTypes {
165 kDragonMoveUpLeft = 0,
166 kDragonMoveUpRight = 1,
167 kDragonMoveDownLeft = 2,
168 kDragonMoveDownRight = 3,
169 kDragonMoveUpLeft_Left = 4,
170 kDragonMoveUpLeft_Right = 5,
171 kDragonMoveUpRight_Left = 6,
172 kDragonMoveUpRight_Right = 7,
173 kDragonMoveDownLeft_Left = 8,
174 kDragonMoveDownLeft_Right = 9,
175 kDragonMoveDownRight_Left = 10,
176 kDragonMoveDownRight_Right = 11,
177 kDragonMoveInvalid = 12
217 int distance(
const Location &location)
const {
218 return MAX(
ABS(x - location.x),
ABS(y - location.y));
236 result.x = x - location.x;
237 result.y = y - location.y;
238 result.z = z - location.z;
240 void addXY(
const Location &location) {
244 void add(
const Location &location) {
249 void fromScreenPoint(
const Point &screenPoint) {
250 x = (screenPoint.
x * ACTOR_LMULT);
251 y = (screenPoint.
y * ACTOR_LMULT);
254 void toScreenPointXY(
Point &screenPoint)
const {
255 screenPoint.
x = x / ACTOR_LMULT;
256 screenPoint.
y = y / ACTOR_LMULT;
258 void toScreenPointUV(
Point &screenPoint)
const {
262 void toScreenPointXYZ(
Point &screenPoint)
const {
263 screenPoint.
x = x / ACTOR_LMULT;
264 screenPoint.
y = y / ACTOR_LMULT - z;
278 int32 _scriptEntrypointNumber;
284 int32 _spriteListResourceId;
287 Point _screenPosition;
296 _location.saveState(out);
307 _location.loadState(in);
317 _scriptEntrypointNumber = 0;
322 _spriteListResourceId = 0;
336 uint16 _interactBits;
350 ActorFrameSequences *_frames;
351 ActorFrameSequences _framesContainer;
352 int _frameListResourceId;
360 int32 _currentAction;
361 int32 _facingDirection;
362 int32 _actionDirection;
364 uint16 _targetObject;
367 int32 _cycleFrameSequence;
369 uint8 _cycleTimeCount;
373 int16 _fallAcceleration;
376 uint8 _dragonBaseFrame;
377 uint8 _dragonStepCycle;
378 uint8 _dragonMoveType;
386 int32 _walkStepsCount;
387 int32 _walkStepIndex;
391 int32 _walkFrameSequence;
399 void cycleWrap(
int cycleLimit);
400 void addWalkStepPoint(
const Point &point);
402 return ((_frames != NULL) && (_frames != &_framesContainer));
409 ActorFrameSequences _frames;
414 int speechColor[ACTOR_SPEECH_ACTORS_MAX];
415 int outlineColor[ACTOR_SPEECH_ACTORS_MAX];
417 const char *strings[ACTOR_SPEECH_STRING_MAX];
421 int slowModeCharIndex;
422 uint16 actorIds[ACTOR_SPEECH_ACTORS_MAX];
424 int sampleResourceId;
429 for (uint i = 0; i < ACTOR_SPEECH_ACTORS_MAX; i++) {
434 for (uint i = 0; i < ACTOR_SPEECH_ACTORS_MAX; i++) {
435 strings[i] =
nullptr;
440 slowModeCharIndex = 0;
441 for (uint i = 0; i < ACTOR_SPEECH_ACTORS_MAX; i++) {
445 sampleResourceId = 0;
450 FontEffectFlags getFontFlags(
int i) {
451 if (outlineColor[i] != 0) {
459 typedef int (*CompareFunction) (
const CommonObjectDataPointer& a,
const CommonObjectDataPointer& b);
470 void cmdActorWalkTo(
int argc,
const char **argv);
472 bool validActorId(uint16
id) {
473 return (
id == ID_PROTAG) || ((
id >= objectIndexToId(kGameObjectActor, 0)) && (
id < objectIndexToId(kGameObjectActor, _actors.size())));
475 int actorIdToIndex(uint16
id) {
return (
id == ID_PROTAG) ? 0 : objectIdToIndex(
id); }
476 uint16 actorIndexToId(
int index) {
return (index == 0) ? ID_PROTAG : objectIndexToId(kGameObjectActor, index); }
481 bool validObjId(uint16
id) {
return (
id >= objectIndexToId(kGameObjectObject, 0)) && (
id < objectIndexToId(kGameObjectObject, _objs.size())); }
482 int objIdToIndex(uint16
id) {
return objectIdToIndex(
id); }
483 uint16 objIndexToId(
int index) {
return objectIndexToId(kGameObjectObject, index); }
486 int getObjectScriptEntrypointNumber(uint16
id) {
488 objectType = objectTypeId(
id);
489 if (!(objectType & (kGameObjectObject | kGameObjectActor))) {
490 error(
"Actor::getObjectScriptEntrypointNumber wrong id 0x%X",
id);
492 return (objectType == kGameObjectObject) ? getObj(
id)->_scriptEntrypointNumber : getActor(
id)->_scriptEntrypointNumber;
494 int getObjectFlags(uint16
id) {
496 objectType = objectTypeId(
id);
497 if (!(objectType & (kGameObjectObject | kGameObjectActor))) {
498 error(
"Actor::getObjectFlags wrong id 0x%X",
id);
500 return (objectType == kGameObjectObject) ? getObj(
id)->_flags : getActor(
id)->_flags;
503 void direct(
int msec);
505 void updateActorsScene(
int actorsEntrance);
513 uint16 hitTest(
const Point &testPoint,
bool skipProtagonist);
514 void takeExit(uint16 actorId,
const HitZone *hitZone);
515 bool actorEndWalk(uint16 actorId,
bool recurse);
516 bool actorWalkTo(uint16 actorId,
const Location &toLocation);
517 int getFrameType(ActorFrameTypes frameType);
519 void actorFaceTowardsPoint(uint16 actorId,
const Location &toLocation);
520 void actorFaceTowardsObject(uint16 actorId, uint16 objectId);
522 void realLocation(
Location &location, uint16 objectId, uint16 walkFlags);
525 void actorSpeech(uint16 actorId,
const char **strings,
int stringsCount,
int sampleResourceId,
int speechFlags);
526 void nonActorSpeech(
const Common::Rect &box,
const char **strings,
int stringsCount,
int sampleResourceId,
int speechFlags);
527 void simulSpeech(
const char *
string, uint16 *actorIds,
int actorIdsCount,
int speechFlags,
int sampleResourceId);
528 void setSpeechColor(
int speechColor,
int outlineColor) {
529 _activeSpeech.speechColor[0] = speechColor;
530 _activeSpeech.outlineColor[0] = outlineColor;
532 void abortAllSpeeches();
535 return _activeSpeech.stringsCount > 0;
538 int isForcedTextShown() {
539 return _activeSpeech.speechFlags & kSpeakForceText;
545 void setProtagState(
int state);
546 int getProtagState() {
return _protagState; }
548 void loadActorList(
int protagonistIdx,
int actorCount,
int actorsResourceID,
549 int protagStatesCount,
int protagStatesResourceID);
550 void loadObjList(
int objectCount,
int objectsResourceID);
554 void loadActorResources(
ActorData *actor);
555 void loadFrameList(
int frameListResourceId, ActorFrameSequences &frames);
557 void stepZoneAction(
ActorData *actor,
const HitZone *hitZone,
bool exit,
bool stopped);
558 void loadActorSpriteList(
ActorData *actor);
560 void drawOrderListAdd(
const CommonObjectDataPointer& element, CompareFunction compareFunction);
561 void createDrawOrderList();
565 bool followProtagonist(
ActorData *actor);
567 void handleSpeech(
int msec);
568 void handleActions(
int msec,
bool setup);
569 bool validPathCellPoint(
const Point &testPoint) {
570 return !((testPoint.
x < 0) || (testPoint.
x >= _xCellCount) ||
571 (testPoint.
y < 0) || (testPoint.
y >= _yCellCount));
573 void setPathCell(
const Point &testPoint, int8 value) {
575 if (!validPathCellPoint(testPoint)) {
576 error(
"Actor::setPathCell wrong point");
579 _pathCell[testPoint.
x + testPoint.
y * _xCellCount] = value;
581 int8 getPathCell(
const Point &testPoint) {
583 if (!validPathCellPoint(testPoint)) {
584 error(
"Actor::getPathCell wrong point");
587 return _pathCell[testPoint.
x + testPoint.
y * _xCellCount];
589 bool scanPathLine(
const Point &point1,
const Point &point2);
590 int fillPathArray(
const Point &fromPoint,
const Point &toPoint,
Point &bestPoint);
593 void condenseNodeList();
596 void removePathPoints();
597 bool validFollowerLocation(
const Location &location);
603 ActorDataArray _actors;
605 ObjectDataArray _objs;
611 CommonObjectOrderList _drawOrderList;
617 int _handleActionDiv;
619 Rect _speechBoxScript;
637 PathNode() : link(0) {}
638 PathNode(
const Point &p) : point(p), link(0) {}
639 PathNode(
const Point &p,
int l) : point(p), link(l) {}
643 Rect _barrierList[ACTOR_BARRIERS_MAX];
654 PathNodeList _pathNodeList;
659 #error You must also define SAGA_DEBUG 666 DebugPoint() : color(0) {}
668 DebugPoint(
const Point &p, byte c): point(p), color(c) {}
672 uint _debugPointsCount;
674 void addDebugPoint(
const Point &point, byte color) {
675 if (_debugPointsCount < _debugPoints.
size()) {
676 _debugPoints[_debugPointsCount].point = point;
677 _debugPoints[_debugPointsCount].color = color;
679 _debugPoints.
push_back(DebugPoint(point, color));
Definition: resource.h:105
uint16 readUint16LE()
Definition: stream.h:459
FORCEINLINE int32 readSint32LE()
Definition: stream.h:555
Definition: savefile.h:54
Definition: objectmap.h:30
void push_back(const T &element)
Definition: array.h:180
void writeUint16LE(uint16 value)
Definition: stream.h:152
size_type size() const
Definition: array.h:315
void NORETURN_PRE error(MSVC_PRINTF const char *s,...) GCC_PRINTF(1
FORCEINLINE int16 readSint16LE()
Definition: stream.h:543
int16 x
Definition: rect.h:46
FORCEINLINE void writeSint16LE(int16 value)
Definition: stream.h:194
int16 y
Definition: rect.h:47
T MAX(T a, T b)
Definition: util.h:62
FORCEINLINE void writeSint32LE(int32 value)
Definition: stream.h:200
T ABS(T x)
Definition: util.h:56