mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-13 21:31:53 +00:00
Almost complete implementation of Puzzle. Now it is possible to solve it
successfully. Things to do: o non-actors speech, it just doesn't get displayed, though generated o support for CD voices svn-id: r18301
This commit is contained in:
parent
e5ab68c0db
commit
0eb4e94116
@ -514,8 +514,10 @@ ObjectData *Actor::getObj(uint16 objId) {
|
||||
ActorData *Actor::getActor(uint16 actorId) {
|
||||
ActorData *actor;
|
||||
|
||||
if (!validActorId(actorId))
|
||||
error("Actor::getActor Wrong actorId 0x%X", actorId);
|
||||
if (!validActorId(actorId)) {
|
||||
warning("Actor::getActor Wrong actorId 0x%X", actorId);
|
||||
assert(0);
|
||||
}
|
||||
|
||||
if (actorId == ID_PROTAG) {
|
||||
if (_protagonist == NULL) {
|
||||
|
@ -135,6 +135,8 @@ struct ActorFrameSequence {
|
||||
ActorFrameRange directions[ACTOR_DIRECTIONS_COUNT];
|
||||
};
|
||||
|
||||
int pathLine(Point *pointList, const Point &point1, const Point &point2);
|
||||
|
||||
struct Location {
|
||||
int32 x; // logical coordinates
|
||||
int32 y; //
|
||||
|
@ -1128,6 +1128,10 @@ void Interface::update(const Point& mousePoint, int updateFlag) {
|
||||
if (updateFlag & UPDATE_MOUSECLICK) {
|
||||
handleConverseClick(mousePoint);
|
||||
}
|
||||
|
||||
if (_vm->_puzzle->isActive()) {
|
||||
_vm->_puzzle->handleClick(mousePoint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
321
saga/puzzle.cpp
321
saga/puzzle.cpp
@ -24,9 +24,12 @@
|
||||
#include "saga/actor.h"
|
||||
#include "saga/interface.h"
|
||||
#include "saga/scene.h"
|
||||
#include "saga/sprite.h"
|
||||
#include "saga/puzzle.h"
|
||||
#include "saga/render.h"
|
||||
#include "saga/resnames.h"
|
||||
|
||||
#include "common/system.h"
|
||||
#include "common/timer.h"
|
||||
|
||||
namespace Saga {
|
||||
@ -38,39 +41,6 @@ namespace Saga {
|
||||
#define PUZZLE_MOVED 0x04 // 1 when somewhere in the box
|
||||
#define PUZZLE_ALL_SET PUZZLE_FIT | PUZZLE_MOVED
|
||||
|
||||
static Puzzle::PieceInfo pieceInfo[PUZZLE_PIECES] = {
|
||||
{268, 18, 0, 0, 0 + PUZZLE_X_OFFSET, 0 + PUZZLE_Y_OFFSET, 0, 3,
|
||||
Point(0, 1), Point(0, 62), Point(15, 31), Point(0, 0), Point(0, 0), Point(0,0)},
|
||||
{270, 52, 0, 0, 0 + PUZZLE_X_OFFSET, 32 + PUZZLE_Y_OFFSET, 0, 4,
|
||||
Point(0, 31), Point(0, 47), Point(39, 47), Point(15, 1), Point(0, 0), Point(0, 0)},
|
||||
{19, 51, 0, 0, 0 + PUZZLE_X_OFFSET, 0 + PUZZLE_Y_OFFSET, 0, 4,
|
||||
Point(0, 0), Point(23, 46), Point(39, 15), Point(31, 0), Point(0, 0), Point(0, 0)},
|
||||
{73, 0, 0, 0, 32 + PUZZLE_X_OFFSET, 0 + PUZZLE_Y_OFFSET, 0, 6,
|
||||
Point(0, 0), Point(8, 16), Point(0, 31), Point(31, 31), Point(39, 15), Point(31, 0)},
|
||||
{0, 35, 0, 0, 64 + PUZZLE_X_OFFSET, 16 + PUZZLE_Y_OFFSET, 0, 4,
|
||||
Point(0, 15), Point(15, 46), Point(23, 32), Point(7, 1), Point(0, 0), Point(0, 0)},
|
||||
{215, 0, 0, 0, 24 + PUZZLE_X_OFFSET, 32 + PUZZLE_Y_OFFSET, 0, 6,
|
||||
Point(0, 15), Point(8, 31), Point(39, 31), Point(47, 16), Point(39, 0), Point(8, 0)},
|
||||
{159, 0, 0, 0, 32 + PUZZLE_X_OFFSET, 48 + PUZZLE_Y_OFFSET, 0, 5,
|
||||
Point(0, 16), Point(8, 31), Point(55, 31), Point(39, 1), Point(32, 15), Point(0, 0)},
|
||||
{9, 70, 0, 0, 80 + PUZZLE_X_OFFSET, 32 + PUZZLE_Y_OFFSET, 0, 5,
|
||||
Point(0, 31), Point(8, 47), Point(23, 47), Point(31, 31), Point(15, 1), Point(0, 0)},
|
||||
{288, 18, 0, 0, 96 + PUZZLE_X_OFFSET, 0 + PUZZLE_Y_OFFSET, 0, 4,
|
||||
Point(0, 31), Point(15, 62), Point(31, 32), Point(15, 1), Point(0, 0), Point(0, 0)},
|
||||
{112, 0, 0, 0, 112 + PUZZLE_X_OFFSET, 0 + PUZZLE_Y_OFFSET, 0, 4,
|
||||
Point(0, 0), Point(16, 31), Point(47, 31), Point(31, 0), Point(0, 0), Point(0, 0)},
|
||||
{27, 89, 0, 0, 104 + PUZZLE_X_OFFSET, 32 + PUZZLE_Y_OFFSET, 0, 4,
|
||||
Point(0, 47), Point(31, 47), Point(31, 0), Point(24, 0), Point(0, 0), Point(0, 0)},
|
||||
{43, 0, 0, 0, 136 + PUZZLE_X_OFFSET, 32 + PUZZLE_Y_OFFSET, 0, 6,
|
||||
Point(0, 0), Point(0, 47), Point(15, 47), Point(15, 15), Point(31, 15), Point(23, 0)},
|
||||
{0, 0, 0, 0, 144 + PUZZLE_X_OFFSET, 0 + PUZZLE_Y_OFFSET, 0, 4,
|
||||
Point(0, 0), Point(24, 47), Point(39, 47), Point(39, 0), Point(0, 0), Point(0, 0)},
|
||||
{262, 0, 0, 0, 64 + PUZZLE_X_OFFSET, 0 + PUZZLE_Y_OFFSET, 0, 3,
|
||||
Point(0, 0), Point(23, 46), Point(47, 0), Point(0, 0), Point(0, 0), Point(0, 0)},
|
||||
{271, 103, 0, 0, 152 + PUZZLE_X_OFFSET, 48 + PUZZLE_Y_OFFSET, 0, 4,
|
||||
Point(0, 0), Point(0, 31), Point(31, 31), Point(31, 0), Point(0, 0), Point(0, 0)}
|
||||
};
|
||||
|
||||
static Point pieceOrigins[PUZZLE_PIECES] = {
|
||||
Point(268, 18),
|
||||
Point(270, 51),
|
||||
@ -86,7 +56,7 @@ static Point pieceOrigins[PUZZLE_PIECES] = {
|
||||
Point( 43, 0),
|
||||
Point( 0, 0),
|
||||
Point(262, 0),
|
||||
Point(271, 10)
|
||||
Point(271, 103)
|
||||
};
|
||||
|
||||
const char *pieceNames[][PUZZLE_PIECES] = {
|
||||
@ -193,14 +163,69 @@ Puzzle::Puzzle(SagaEngine *vm) : _vm(vm), _solved(false), _active(false) {
|
||||
_hintCount = 0;
|
||||
_helpCount = 0;
|
||||
_puzzlePiece = -1;
|
||||
_newPuzzle = true;
|
||||
_sliding = false;
|
||||
|
||||
initPieceInfo( 0, 268, 18, 0, 0, 0 + PUZZLE_X_OFFSET, 0 + PUZZLE_Y_OFFSET, 0, 3,
|
||||
Point(0, 1), Point(0, 62), Point(15, 31), Point(0, 0), Point(0, 0), Point(0,0));
|
||||
initPieceInfo( 1, 270, 52, 0, 0, 0 + PUZZLE_X_OFFSET, 32 + PUZZLE_Y_OFFSET, 0, 4,
|
||||
Point(0, 31), Point(0, 47), Point(39, 47), Point(15, 1), Point(0, 0), Point(0, 0));
|
||||
initPieceInfo( 2, 19, 51, 0, 0, 0 + PUZZLE_X_OFFSET, 0 + PUZZLE_Y_OFFSET, 0, 4,
|
||||
Point(0, 0), Point(23, 46), Point(39, 15), Point(31, 0), Point(0, 0), Point(0, 0));
|
||||
initPieceInfo( 3, 73, 0, 0, 0, 32 + PUZZLE_X_OFFSET, 0 + PUZZLE_Y_OFFSET, 0, 6,
|
||||
Point(0, 0), Point(8, 16), Point(0, 31), Point(31, 31), Point(39, 15), Point(31, 0));
|
||||
initPieceInfo( 4, 0, 35, 0, 0, 64 + PUZZLE_X_OFFSET, 16 + PUZZLE_Y_OFFSET, 0, 4,
|
||||
Point(0, 15), Point(15, 46), Point(23, 32), Point(7, 1), Point(0, 0), Point(0, 0));
|
||||
initPieceInfo( 5, 215, 0, 0, 0, 24 + PUZZLE_X_OFFSET, 32 + PUZZLE_Y_OFFSET, 0, 6,
|
||||
Point(0, 15), Point(8, 31), Point(39, 31), Point(47, 16), Point(39, 0), Point(8, 0));
|
||||
initPieceInfo( 6, 159, 0, 0, 0, 32 + PUZZLE_X_OFFSET, 48 + PUZZLE_Y_OFFSET, 0, 5,
|
||||
Point(0, 16), Point(8, 31), Point(55, 31), Point(39, 1), Point(32, 15), Point(0, 0));
|
||||
initPieceInfo( 7, 9, 70, 0, 0, 80 + PUZZLE_X_OFFSET, 32 + PUZZLE_Y_OFFSET, 0, 5,
|
||||
Point(0, 31), Point(8, 47), Point(23, 47), Point(31, 31), Point(15, 1), Point(0, 0));
|
||||
initPieceInfo( 8, 288, 18, 0, 0, 96 + PUZZLE_X_OFFSET, 0 + PUZZLE_Y_OFFSET, 0, 4,
|
||||
Point(0, 31), Point(15, 62), Point(31, 32), Point(15, 1), Point(0, 0), Point(0, 0));
|
||||
initPieceInfo( 9, 112, 0, 0, 0, 112 + PUZZLE_X_OFFSET, 0 + PUZZLE_Y_OFFSET, 0, 4,
|
||||
Point(0, 0), Point(16, 31), Point(47, 31), Point(31, 0), Point(0, 0), Point(0, 0));
|
||||
initPieceInfo(10, 27, 89, 0, 0, 104 + PUZZLE_X_OFFSET, 32 + PUZZLE_Y_OFFSET, 0, 4,
|
||||
Point(0, 47), Point(31, 47), Point(31, 0), Point(24, 0), Point(0, 0), Point(0, 0));
|
||||
initPieceInfo(11, 43, 0, 0, 0, 136 + PUZZLE_X_OFFSET, 32 + PUZZLE_Y_OFFSET, 0, 6,
|
||||
Point(0, 0), Point(0, 47), Point(15, 47), Point(15, 15), Point(31, 15), Point(23, 0));
|
||||
initPieceInfo(12, 0, 0, 0, 0, 144 + PUZZLE_X_OFFSET, 0 + PUZZLE_Y_OFFSET, 0, 4,
|
||||
Point(0, 0), Point(24, 47), Point(39, 47), Point(39, 0), Point(0, 0), Point(0, 0));
|
||||
initPieceInfo(13, 262, 0, 0, 0, 64 + PUZZLE_X_OFFSET, 0 + PUZZLE_Y_OFFSET, 0, 3,
|
||||
Point(0, 0), Point(23, 46), Point(47, 0), Point(0, 0), Point(0, 0), Point(0, 0));
|
||||
initPieceInfo(14, 271, 103, 0, 0, 152 + PUZZLE_X_OFFSET, 48 + PUZZLE_Y_OFFSET, 0, 4,
|
||||
Point(0, 0), Point(0, 31), Point(31, 31), Point(31, 0), Point(0, 0), Point(0, 0));
|
||||
}
|
||||
|
||||
void Puzzle::initPieceInfo(int i, int16 curX, int16 curY, byte offX, byte offY, int16 trgX,
|
||||
int16 trgY, uint8 flag, uint8 count, Point point0, Point point1,
|
||||
Point point2, Point point3, Point point4, Point point5) {
|
||||
_pieceInfo[i].curX = curX;
|
||||
_pieceInfo[i].curY = curY;
|
||||
_pieceInfo[i].offX = offX;
|
||||
_pieceInfo[i].offY = offY;
|
||||
_pieceInfo[i].trgX = trgX;
|
||||
_pieceInfo[i].trgY = trgY;
|
||||
_pieceInfo[i].flag = flag;
|
||||
_pieceInfo[i].count = count;
|
||||
_pieceInfo[i].point[0] = point0;
|
||||
_pieceInfo[i].point[1] = point1;
|
||||
_pieceInfo[i].point[2] = point2;
|
||||
_pieceInfo[i].point[3] = point3;
|
||||
_pieceInfo[i].point[4] = point4;
|
||||
_pieceInfo[i].point[5] = point5;
|
||||
}
|
||||
|
||||
|
||||
void Puzzle::execute(void) {
|
||||
_active = true;
|
||||
Common::g_timer->installTimerProc(&hintTimerCallback, kPuzzleHintTime, this);
|
||||
|
||||
initPieces();
|
||||
|
||||
showPieces();
|
||||
|
||||
_vm->_interface->setMode(kPanelConverse);
|
||||
clearHint();
|
||||
//_solved = true; // Cheat
|
||||
@ -217,10 +242,224 @@ void Puzzle::exitPuzzle(void) {
|
||||
}
|
||||
|
||||
void Puzzle::initPieces(void) {
|
||||
// ActorData *puzzle = _vm->_actor->getActor(RID_ITE_ACTOR_PUZZLE);
|
||||
ActorData *puzzle = _vm->_actor->getActor(_vm->_actor->actorIndexToId(RID_ITE_ACTOR_PUZZLE));
|
||||
SpriteInfo *spI;
|
||||
|
||||
for (int i = 0; i < PUZZLE_PIECES; i++) {
|
||||
spI = &puzzle->spriteList.infoList[i];
|
||||
_pieceInfo[i].offX = (byte)(spI->width >> 1);
|
||||
_pieceInfo[i].offY = (byte)(spI->height >> 1);
|
||||
|
||||
if (_newPuzzle) {
|
||||
_pieceInfo[i].curX = pieceOrigins[i].x;
|
||||
_pieceInfo[i].curY = pieceOrigins[i].y;
|
||||
}
|
||||
_piecePriority[i] = i;
|
||||
}
|
||||
_newPuzzle = false;
|
||||
}
|
||||
|
||||
void Puzzle::showPieces(void) {
|
||||
ActorData *puzzle = _vm->_actor->getActor(_vm->_actor->actorIndexToId(RID_ITE_ACTOR_PUZZLE));
|
||||
SURFACE *backBuffer = _vm->_gfx->getBackBuffer();
|
||||
|
||||
for (int j = PUZZLE_PIECES - 1 ; j >= 0; j--) {
|
||||
int num = _piecePriority[j];
|
||||
|
||||
if (_puzzlePiece != num) {
|
||||
_vm->_sprite->draw(backBuffer, puzzle->spriteList, num, Point(_pieceInfo[num].curX, _pieceInfo[num].curY), 256);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Puzzle::drawCurrentPiece() {
|
||||
ActorData *puzzle = _vm->_actor->getActor(_vm->_actor->actorIndexToId(RID_ITE_ACTOR_PUZZLE));
|
||||
SURFACE *backBuffer = _vm->_gfx->getBackBuffer();
|
||||
|
||||
_vm->_sprite->draw(backBuffer, puzzle->spriteList, _puzzlePiece,
|
||||
Point(_pieceInfo[_puzzlePiece].curX, _pieceInfo[_puzzlePiece].curY), 256);
|
||||
}
|
||||
|
||||
void Puzzle::movePiece(Point mousePt) {
|
||||
int newx, newy;
|
||||
|
||||
showPieces();
|
||||
|
||||
if (_puzzlePiece == -1)
|
||||
return;
|
||||
|
||||
if (_sliding) {
|
||||
newx = _slidePointX;
|
||||
newy = _slidePointY;
|
||||
} else {
|
||||
if (mousePt.y >= 137)
|
||||
return;
|
||||
|
||||
newx = mousePt.x;
|
||||
newy = mousePt.y;
|
||||
}
|
||||
|
||||
newx -= _pieceInfo[_puzzlePiece].offX;
|
||||
newy -= _pieceInfo[_puzzlePiece].offY;
|
||||
|
||||
_pieceInfo[_puzzlePiece].curX = newx;
|
||||
_pieceInfo[_puzzlePiece].curY = newy;
|
||||
|
||||
drawCurrentPiece();
|
||||
}
|
||||
|
||||
void Puzzle::handleClick(Point mousePt) {
|
||||
if (_puzzlePiece != -1) {
|
||||
dropPiece(mousePt);
|
||||
|
||||
if (!_active)
|
||||
return; // we won
|
||||
|
||||
drawCurrentPiece();
|
||||
_puzzlePiece = -1;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
for (int j = 0; j < PUZZLE_PIECES; j++) {
|
||||
int i = _piecePriority[j];
|
||||
int adjX = mousePt.x - _pieceInfo[i].curX;
|
||||
int adjY = mousePt.y - _pieceInfo[i].curY;
|
||||
|
||||
if (hitTestPoly(&_pieceInfo[i].point[0], _pieceInfo[i].count, Point(adjX, adjY))) {
|
||||
_puzzlePiece = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (_puzzlePiece == -1)
|
||||
return;
|
||||
|
||||
alterPiecePriority();
|
||||
|
||||
// Display scene background
|
||||
_vm->_scene->draw();
|
||||
showPieces();
|
||||
|
||||
int newx = mousePt.x - _pieceInfo[_puzzlePiece].offX;
|
||||
int newy = mousePt.y - _pieceInfo[_puzzlePiece].offY;
|
||||
|
||||
if (newx != _pieceInfo[_puzzlePiece].curX
|
||||
|| newy != _pieceInfo[_puzzlePiece].curY) {
|
||||
_pieceInfo[_puzzlePiece].curX = newx;
|
||||
_pieceInfo[_puzzlePiece].curY = newy;
|
||||
}
|
||||
_vm->_interface->setStatusText(pieceNames[_lang][_puzzlePiece]);
|
||||
}
|
||||
|
||||
void Puzzle::alterPiecePriority(void) {
|
||||
for (int i = 1; i < PUZZLE_PIECES; i++) {
|
||||
if (_puzzlePiece == _piecePriority[i]) {
|
||||
for (int j = i - 1; j >= 0; j--)
|
||||
_piecePriority[j+1] = _piecePriority[j];
|
||||
_piecePriority[0] = _puzzlePiece;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Puzzle::slidePiece(int x1, int y1, int x2, int y2) {
|
||||
int count;
|
||||
Point slidePoints[320];
|
||||
|
||||
x1 += _pieceInfo[_puzzlePiece].offX;
|
||||
y1 += _pieceInfo[_puzzlePiece].offY;
|
||||
|
||||
count = pathLine(&slidePoints[0], Point(x1, y1),
|
||||
Point(x2 + _pieceInfo[_puzzlePiece].offX, y2 + _pieceInfo[_puzzlePiece].offY));
|
||||
|
||||
if (count > 1) {
|
||||
int factor = count / 4;
|
||||
_sliding = true;
|
||||
|
||||
if (!factor)
|
||||
factor++;
|
||||
|
||||
for (int i = 1; i < count; i += factor) {
|
||||
_slidePointX = slidePoints[i].x;
|
||||
_slidePointY = slidePoints[i].y;
|
||||
_vm->_render->drawScene();
|
||||
_vm->_system->delayMillis(10);
|
||||
}
|
||||
_sliding = false;
|
||||
}
|
||||
|
||||
_pieceInfo[_puzzlePiece].curX = x2;
|
||||
_pieceInfo[_puzzlePiece].curY = y2;
|
||||
}
|
||||
|
||||
void Puzzle::dropPiece(Point mousePt) {
|
||||
int boxx = PUZZLE_X_OFFSET;
|
||||
int boxy = PUZZLE_Y_OFFSET;
|
||||
int boxw = boxx + 184;
|
||||
int boxh = boxy + 80;
|
||||
|
||||
// if the center is within the box quantize within
|
||||
// else move it back to its original start point
|
||||
if (mousePt.x >= boxx && mousePt.x < boxw && mousePt.y >= boxy && mousePt.y <= boxh) {
|
||||
ActorData *puzzle = _vm->_actor->getActor(_vm->_actor->actorIndexToId(RID_ITE_ACTOR_PUZZLE));
|
||||
SpriteInfo *spI;
|
||||
int newx = mousePt.x - _pieceInfo[_puzzlePiece].offX;
|
||||
int newy = mousePt.y - _pieceInfo[_puzzlePiece].offY;
|
||||
|
||||
if (newx < boxx)
|
||||
newx = PUZZLE_X_OFFSET;
|
||||
if (newy < boxy)
|
||||
newy = PUZZLE_Y_OFFSET;
|
||||
|
||||
spI = &puzzle->spriteList.infoList[_puzzlePiece];
|
||||
|
||||
if (newx + spI->width > boxw)
|
||||
newx = boxw - spI->width ;
|
||||
if (newy + spI->height > boxh)
|
||||
newy = boxh - spI->height ;
|
||||
|
||||
int x1 = ((newx - PUZZLE_X_OFFSET) & ~7) + PUZZLE_X_OFFSET;
|
||||
int y1 = ((newy - PUZZLE_Y_OFFSET) & ~7) + PUZZLE_Y_OFFSET;
|
||||
int x2 = x1 + 8;
|
||||
int y2 = y1 + 8;
|
||||
newx = (x2 - newx < newx - x1) ? x2 : x1;
|
||||
newy = (y2 - newy < newy - y1) ? y2 : y1;
|
||||
|
||||
// if any part of the puzzle piece falls outside the box
|
||||
// force it back in
|
||||
|
||||
// is the piece at the target location
|
||||
if (newx == _pieceInfo[_puzzlePiece].trgX
|
||||
&& newy == _pieceInfo[_puzzlePiece].trgY) {
|
||||
_pieceInfo[_puzzlePiece].flag |= (PUZZLE_MOVED | PUZZLE_FIT);
|
||||
} else {
|
||||
_pieceInfo[_puzzlePiece].flag &= ~PUZZLE_FIT;
|
||||
_pieceInfo[_puzzlePiece].flag |= PUZZLE_MOVED;
|
||||
}
|
||||
_pieceInfo[_puzzlePiece].curX = newx;
|
||||
_pieceInfo[_puzzlePiece].curY = newy;
|
||||
} else {
|
||||
int newx = pieceOrigins[_puzzlePiece].x;
|
||||
int newy = pieceOrigins[_puzzlePiece].y;
|
||||
_pieceInfo[_puzzlePiece].flag &= ~(PUZZLE_FIT | PUZZLE_MOVED);
|
||||
|
||||
// slide piece from current position to new position
|
||||
slidePiece(_pieceInfo[_puzzlePiece].curX, _pieceInfo[_puzzlePiece].curY,
|
||||
newx, newy);
|
||||
}
|
||||
|
||||
// is the puzzle completed?
|
||||
|
||||
_solved = true;
|
||||
for (int i = 0; i < PUZZLE_PIECES; i++)
|
||||
if ((_pieceInfo[i].flag & PUZZLE_FIT) == 0) {
|
||||
_solved = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (_solved)
|
||||
exitPuzzle();
|
||||
}
|
||||
|
||||
void Puzzle::hintTimerCallback(void *refCon) {
|
||||
@ -335,12 +574,12 @@ void Puzzle::giveHint(void) {
|
||||
_vm->_interface->setRightPortrait(_hintGiver);
|
||||
|
||||
for (i = 0; i < PUZZLE_PIECES; i++)
|
||||
total += pieceInfo[i].flag & PUZZLE_FIT;
|
||||
total += _pieceInfo[i].flag & PUZZLE_FIT;
|
||||
|
||||
if (_hintCount == 0 && (pieceInfo[1].flag & PUZZLE_FIT
|
||||
|| pieceInfo[12].flag & PUZZLE_FIT))
|
||||
if (_hintCount == 0 && (_pieceInfo[1].flag & PUZZLE_FIT
|
||||
|| _pieceInfo[12].flag & PUZZLE_FIT))
|
||||
_hintCount++;
|
||||
if (_hintCount == 1 && pieceInfo[14].flag & PUZZLE_FIT)
|
||||
if (_hintCount == 1 && _pieceInfo[14].flag & PUZZLE_FIT)
|
||||
_hintCount++;
|
||||
|
||||
if (_hintCount == 2 && total > 3)
|
||||
@ -355,8 +594,8 @@ void Puzzle::giveHint(void) {
|
||||
|
||||
for (i = PUZZLE_PIECES - 1; i >= 0; i--) {
|
||||
piece = _piecePriority[i];
|
||||
if (pieceInfo[piece].flag & PUZZLE_MOVED
|
||||
&& !(pieceInfo[piece].flag & PUZZLE_FIT)) {
|
||||
if (_pieceInfo[piece].flag & PUZZLE_MOVED
|
||||
&& !(_pieceInfo[piece].flag & PUZZLE_FIT)) {
|
||||
if (_helpCount < 12)
|
||||
_helpCount++;
|
||||
break;
|
||||
|
@ -40,6 +40,8 @@ private:
|
||||
|
||||
bool _solved;
|
||||
bool _active;
|
||||
bool _newPuzzle;
|
||||
bool _sliding;
|
||||
|
||||
kRQStates _hintRqState;
|
||||
int _hintGiver;
|
||||
@ -62,20 +64,30 @@ public:
|
||||
bool isActive(void) { return _active; }
|
||||
|
||||
void handleReply(int reply);
|
||||
void handleClick(Point mousePt);
|
||||
|
||||
void movePiece(Point mousePt);
|
||||
|
||||
private:
|
||||
void initPieceInfo(int i, int16 curX, int16 curY, byte offX, byte offY, int16 trgX,
|
||||
int16 trgY, uint8 flag, uint8 count, Point point0, Point point1,
|
||||
Point point2, Point point3, Point point4, Point point5);
|
||||
|
||||
static void hintTimerCallback(void *refCon);
|
||||
|
||||
void solicitHint(void);
|
||||
|
||||
void initPieces(void);
|
||||
void showPieces(void);
|
||||
void slidePiece(int x1, int y1, int x2, int y2);
|
||||
void dropPiece(Point mousePt);
|
||||
void alterPiecePriority(void);
|
||||
void drawCurrentPiece(void);
|
||||
|
||||
void giveHint(void);
|
||||
void clearHint(void);
|
||||
|
||||
public:
|
||||
private:
|
||||
struct PieceInfo {
|
||||
int16 curX;
|
||||
int16 curY;
|
||||
@ -88,6 +100,8 @@ public:
|
||||
Point point[6];
|
||||
};
|
||||
|
||||
PieceInfo _pieceInfo[PUZZLE_PIECES];
|
||||
int _slidePointX, _slidePointY;
|
||||
};
|
||||
|
||||
} // End of namespace Saga
|
||||
|
@ -116,12 +116,12 @@ int Render::drawScene() {
|
||||
_vm->_scene->draw();
|
||||
|
||||
if (_vm->_interface->getMode() != kPanelFade) {
|
||||
// Draw queued actors
|
||||
_vm->_actor->drawActors();
|
||||
|
||||
if (_vm->_puzzle->isActive()) {
|
||||
_vm->_puzzle->movePiece(mouse_pt);
|
||||
_vm->_actor->drawSpeech();
|
||||
} else {
|
||||
// Draw queued actors
|
||||
_vm->_actor->drawActors();
|
||||
}
|
||||
|
||||
if (getFlags() & RF_OBJECTMAP_TEST) {
|
||||
|
@ -327,14 +327,14 @@ int SagaEngine::go() {
|
||||
}
|
||||
|
||||
// Since Puzzle is actorless, we do it here
|
||||
if (_puzzle->isActive())
|
||||
if (_puzzle->isActive()) {
|
||||
_actor->handleSpeech(msec);
|
||||
|
||||
if (!_scene->isInDemo() && getGameType() == GType_ITE)
|
||||
} else if (!_scene->isInDemo() && getGameType() == GType_ITE) {
|
||||
if (_interface->getMode() == kPanelMain ||
|
||||
_interface->getMode() == kPanelConverse ||
|
||||
_interface->getMode() == kPanelNull)
|
||||
_actor->direct(msec);
|
||||
}
|
||||
|
||||
_events->handleEvents(msec);
|
||||
_script->executeThreads(msec);
|
||||
|
Loading…
Reference in New Issue
Block a user