diff options
author | Eugene Sandulenko | 2005-05-26 09:45:15 +0000 |
---|---|---|
committer | Eugene Sandulenko | 2005-05-26 09:45:15 +0000 |
commit | ca40942959b494edf8ff4754f7f64215d8cf70f4 (patch) | |
tree | 8633ad61e907a92b0335cdecf9604728b90fdd95 | |
parent | f3f58ec9ebbb91f2e1ccf5a21d7190972cd0cead (diff) | |
download | scummvm-rg350-ca40942959b494edf8ff4754f7f64215d8cf70f4.tar.gz scummvm-rg350-ca40942959b494edf8ff4754f7f64215d8cf70f4.tar.bz2 scummvm-rg350-ca40942959b494edf8ff4754f7f64215d8cf70f4.zip |
Puzzle WIP. No visuals yet.
svn-id: r18255
-rw-r--r-- | saga/puzzle.cpp | 340 | ||||
-rw-r--r-- | saga/puzzle.h | 42 | ||||
-rw-r--r-- | saga/resnames.h | 9 | ||||
-rw-r--r-- | saga/saga.h | 3 |
4 files changed, 386 insertions, 8 deletions
diff --git a/saga/puzzle.cpp b/saga/puzzle.cpp index 7756931f63..791c1325fe 100644 --- a/saga/puzzle.cpp +++ b/saga/puzzle.cpp @@ -21,6 +21,7 @@ #include "saga/saga.h" +#include "saga/actor.h" #include "saga/interface.h" #include "saga/scene.h" #include "saga/puzzle.h" @@ -30,15 +31,180 @@ namespace Saga { +#define PUZZLE_X_OFFSET 72 +#define PUZZLE_Y_OFFSET 46 + +#define PUZZLE_FIT 0x01 // 1 when in correct position +#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), + Point( 19, 51), + Point( 73, 0), + Point( 0, 34), + Point(215, 0), + Point(159, 0), + Point( 9, 69), + Point(288, 18), + Point(112, 0), + Point( 27, 88), + Point( 43, 0), + Point( 0, 0), + Point(262, 0), + Point(271, 10) +}; + +const char *pieceNames[][PUZZLE_PIECES] = { + { "screwdriver", "pliers", "c-clamp", "wood clamp", "level", + "twine", "wood plane", "claw hammer", "tape measure", "hatchet", + "shears", "ruler", "saw", "mallet", "paint brush" + }, + { "Schraubendreher", "Zange", "Schraubzwinge", "Holzzwinge", "Wasserwaage", + "Bindfaden", "Hobel", "Schusterhammer", "Bandma$", "Beil", + "Schere", "Winkel", "S\204ge", "Hammer", "Pinsel" + } +}; + +const char *hintStr[][4] = { + { "Check which pieces could fit in each corner first.", + "Check which corner has the least number of pieces that can fit and start from there.", + "Check each new corner and any new side for pieces that fit.", + "I don't see anything out of place." + }, + { "\232berpr\201fe zun\204chst, welche die Eckteile sein k\224nnten.", + "Schau, in welche Ecke die wenigsten Teile passen, und fang dort an.", + "Untersuche jede Ecke und jede Seite auf Teile, die dort passen k\224nnen.", + "Ich sehe nichts an der falschen Stelle." + } +}; + +#define NUM_SOLICIT_REPLIES 5 +const char *solicitStr[][NUM_SOLICIT_REPLIES] = { + { "Hey, Fox! Would you like a hint?", + "Would you like some help?", + "Umm...Umm...", + "Psst! want a hint?", + "I would have done this differently, you know." + }, + { "Hey, Fuchs! Brauchst Du \047nen Tip?", + "M\224chtest Du etwas Hilfe?" + "\231hm...\216hm..." + "Psst! \047n Tip vielleicht?" + "Ja, wei$t Du... ich h\204tte das anders gemacht." + } +}; + +const char portraitList[] = { + RID_ITE_JFERRET_SERIOUS, + RID_ITE_JFERRET_GOOFY, + RID_ITE_JFERRET_SERIOUS, + RID_ITE_JFERRET_GOOFY, + RID_ITE_JFERRET_ALOOF +}; + +#define NUM_SAKKA 3 +const char *sakkaStr[][NUM_SAKKA] = { + { "Hey, you're not supposed to help the applicants!", + "Guys! This is supposed to be a test!", + "C'mon fellows, that's not in the rules!" + }, + { "Hey, Du darfst dem Pr\201fling nicht helfen!", + "Hallo?! Dies soll eine Pr\201fung sein!", + "Also, Jungs. Schummeln steht nicht in den Regeln!" + } +}; + +#define NUM_WHINES 5 +const char *whineStr[][NUM_WHINES] = { + { "Aww, c'mon Sakka!", + "One hint won't hurt, will it?", + "Sigh...", + "I think that clipboard has gone to your head, Sakka!", + "Well, I don't recall any specific rule against hinting." + }, + { "Och, sei nicht so, Sakka!" + "EIN Tip wird schon nicht schaden, oder?", + "Seufz..." + "Ich glaube, Du hast ein Brett vor dem Kopf, Sakka!", + "Hm, ich kann mich an keine Regel erinnern, die Tips verbietet." + } +}; + +enum rifOptions { + kROLater = 0, + kROAccept = 1, + kRODecline = 2, + kROHint = 3 +}; + +const char *optionsStr[][4] = { + { "\"I'll do this puzzle later.\"", + "\"Yes, I'd like a hint please.\"", + "\"No, thank you, I'd like to try and solve it myself.\"", + "I think the %s is in the wrong place." + }, + { "\"Ich l\224se das Puzzle sp\204ter.\"", + "\"Ja, ich m\224chte einen Tip, bitte.\"", + "\"Nein danke, ich m\224chte das alleine l\224sen.\"", + "Pssst... %s... falsche Stelle..." + } +}; + Puzzle::Puzzle(SagaEngine *vm) : _vm(vm), _solved(false), _active(false) { + _lang = _vm->getFeatures() & GF_LANG_DE ? 1 : 0; + + _hintRqState = kRQNoHint; + _hintOffer = 0; + _hintCount = 0; + _helpCount = 0; + _puzzlePiece = -1; } void Puzzle::execute(void) { _active = true; - Common::g_timer->installTimerProc(&hintTimerCallback, ticksToMSec(30), this); + Common::g_timer->installTimerProc(&hintTimerCallback, kPuzzleHintTime, this); + + initPieces(); - _solved = true; // Cheat - exitPuzzle(); + _vm->_interface->setMode(kPanelConverse); + clearHint(); + //_solved = true; // Cheat + //exitPuzzle(); } void Puzzle::exitPuzzle(void) { @@ -50,19 +216,181 @@ void Puzzle::exitPuzzle(void) { _vm->_interface->setMode(kPanelMain); } +void Puzzle::initPieces(void) { + ActorData *puzzle = _vm->_actor->getActor(RID_ITE_ACTOR_PUZZLE); +} + +void Puzzle::movePiece(Point mousePt) { +} void Puzzle::hintTimerCallback(void *refCon) { - ((Puzzle *)refCon)->hintTimer(); + ((Puzzle *)refCon)->solicitHint(); } -void Puzzle::hintTimer(void) { +void Puzzle::solicitHint(void) { + int i; + + _vm->_actor->setSpeechColor(1, kITEColorBlack); + + Common::g_timer->removeTimerProc(&hintTimerCallback); + + switch(_hintRqState) { + case kRQNoHint: + // Pick a random hint request. + i = _hintOffer++; + if (_hintOffer >= NUM_SOLICIT_REPLIES) + _hintOffer = 0; + + _vm->_actor->nonActorSpeech(&solicitStr[_lang][i], 1, 0); + + // Determine which of the journeymen will offer then + // hint, and then show that character's portrait. + _hintGiver = portraitList[i]; + _vm->_interface->setRightPortrait(_hintGiver); + + // Add Rif's reply to the list. + clearHint(); + + // Roll to see if Sakka scolds + if (_vm->_rnd.getRandomNumber(1)) { + _hintRqState = kRQSakkaDenies; + Common::g_timer->installTimerProc(&hintTimerCallback, 200, this); + } else { + _hintRqState = kRQHintRequested; + Common::g_timer->installTimerProc(&hintTimerCallback, 400, this); + } + + break; + + case kRQHintRequested: + i = _vm->_rnd.getRandomNumber(NUM_SAKKA - 1); + _vm->_actor->nonActorSpeech(&sakkaStr[_lang][i], 1, 0); + + _vm->_interface->setRightPortrait(RID_ITE_SAKKA_APPRAISING); + + _hintRqState = kRQHintRequestedStage2; + Common::g_timer->installTimerProc(&hintTimerCallback, 400, this); + + _vm->_interface->converseClear(); + _vm->_interface->converseAddText(optionsStr[_lang][kROAccept], 1, 0, 0 ); + _vm->_interface->converseAddText(optionsStr[_lang][kRODecline], 2, 0, 0 ); + _vm->_interface->converseAddText(optionsStr[_lang][kROLater], 0, 0, 0 ); + _vm->_interface->converseDisplayText(); + break; + + case kRQHintRequestedStage2: + if (_vm->_rnd.getRandomNumber(1)) { // Skip Reply part + i = _vm->_rnd.getRandomNumber(NUM_WHINES - 1); + _vm->_actor->nonActorSpeech(&whineStr[_lang][i], 1, 0); + } + + _vm->_interface->setRightPortrait(_hintGiver); + + _hintRqState = kRQSakkaDenies; + break; + + case kRQSakkaDenies: + _vm->_interface->converseClear(); + _vm->_interface->converseAddText(optionsStr[_lang][kROAccept], 1, 0, 0); + _vm->_interface->converseAddText(optionsStr[_lang][kRODecline], 2, 0, 0); + _vm->_interface->converseAddText(optionsStr[_lang][kROLater], 0, 0, 0); + _vm->_interface->converseDisplayText(); + + Common::g_timer->installTimerProc(&hintTimerCallback, kPuzzleHintTime, this); + + _hintRqState = kRQSkipEverything; + break; + + default: + break; + } } void Puzzle::handleReply(int reply) { + switch(reply) { + case 0: // Quit the puzzle + exitPuzzle(); + break; + + case 1: // Accept the hint + giveHint(); + break; + + case 2: // Decline the hint + _vm->_actor->abortSpeech(); + _hintRqState = kRQNoHint; + Common::g_timer->removeTimerProc(&hintTimerCallback); + Common::g_timer->installTimerProc(&hintTimerCallback, kPuzzleHintTime * 2, this); + clearHint(); + break; + } } -void Puzzle::movePiece(Point mousePt) { +void Puzzle::giveHint(void) { + int i, total = 0; + + _vm->_interface->converseClear(); + + _vm->_actor->abortSpeech(); + _vm->_interface->setRightPortrait(_hintGiver); + + for (i = 0; i < PUZZLE_PIECES; i++) + total += pieceInfo[i].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) + _hintCount++; + + if (_hintCount == 2 && total > 3) + _hintCount++; + + _vm->_actor->setSpeechColor(1, kITEColorBlack); + + if (_hintCount < 3) { + _vm->_actor->nonActorSpeech(&hintStr[_lang][_hintCount], 1, 0 ); + } else { + int piece; + + for (i = PUZZLE_PIECES - 1; i >= 0; i--) { + piece = _piecePriority[i]; + if (pieceInfo[piece].flag & PUZZLE_MOVED + && !(pieceInfo[piece].flag & PUZZLE_FIT)) { + if (_helpCount < 12) + _helpCount++; + break; + } + } + + if (i >= 0) { + char hintBuf[64]; + const char *hintPtr = hintBuf; + sprintf(hintBuf, optionsStr[_lang][kROHint], pieceNames[piece]); + + _vm->_actor->nonActorSpeech(&hintPtr, 1, 0); + } + else { + // If no pieces are in the wrong place + _vm->_actor->nonActorSpeech(&hintStr[_lang][3], 1, 0); + } + } + _hintCount++; + + _hintRqState = kRQNoHint; + + _vm->_interface->converseAddText(optionsStr[_lang][kROLater], 0, 0, 0); + _vm->_interface->converseDisplayText(); + + Common::g_timer->removeTimerProc(&hintTimerCallback); + Common::g_timer->installTimerProc(&hintTimerCallback, kPuzzleHintTime, this); } +void Puzzle::clearHint(void) { + _vm->_interface->converseClear(); + _vm->_interface->converseAddText(optionsStr[_lang][kROLater], 0, 0, 0); + _vm->_interface->converseDisplayText(); + _vm->_interface->setStatusText(" "); +} } // End of namespace Saga diff --git a/saga/puzzle.h b/saga/puzzle.h index f857f5b969..de8e9146c0 100644 --- a/saga/puzzle.h +++ b/saga/puzzle.h @@ -24,13 +24,34 @@ namespace Saga { +#define PUZZLE_PIECES 15 + class Puzzle { private: + enum kRQStates { + kRQNoHint = 0, + kRQHintRequested = 1, + kRQHintRequestedStage2 = 2, + kRQSakkaDenies = 3, + kRQSkipEverything = 4 + }; + SagaEngine *_vm; bool _solved; bool _active; + kRQStates _hintRqState; + int _hintGiver; + int _hintOffer; + int _hintCount; + int _helpCount; + + int _puzzlePiece; + int _piecePriority[PUZZLE_PIECES]; + + int _lang; + public: Puzzle(SagaEngine *vm); @@ -47,7 +68,26 @@ public: private: static void hintTimerCallback(void *refCon); - void hintTimer(void); + void solicitHint(void); + + void initPieces(void); + + void giveHint(void); + void clearHint(void); + +public: + struct PieceInfo { + int16 curX; + int16 curY; + byte offX; + byte offY; + int16 trgX; + int16 trgY; + uint8 flag; + uint8 count; + Point point[6]; + }; + }; } // End of namespace Saga diff --git a/saga/resnames.h b/saga/resnames.h index a4aee1dcba..9667b47500 100644 --- a/saga/resnames.h +++ b/saga/resnames.h @@ -69,6 +69,13 @@ namespace Saga { #define RID_IHNM_MAIN_PANEL 9 #define RID_IHNM_CONVERSE_PANEL 10 +// Puzzle portraits +#define RID_ITE_SAKKA_APPRAISING 6 +#define RID_ITE_SAKKA_DENIAL 7 +#define RID_ITE_SAKKA_EXCITED 8 +#define RID_ITE_JFERRET_SERIOUS 9 +#define RID_ITE_JFERRET_GOOFY 10 +#define RID_ITE_JFERRET_ALOOF 11 // ITE Scene resource numbers #define RID_ITE_OVERMAP_SCENE 226 @@ -105,6 +112,8 @@ namespace Saga { #define RID_ITE_ENDCREDIT_SCENE_1 1802 +#define RID_ITE_ACTOR_PUZZLE 176 + // ITE_VOICES #define RID_CAVE_VOICE_0 0 #define RID_CAVE_VOICE_1 1 diff --git a/saga/saga.h b/saga/saga.h index 13fa8002a6..b482cd0e4f 100644 --- a/saga/saga.h +++ b/saga/saga.h @@ -107,7 +107,8 @@ enum ScriptTimings { kScriptTimeTicksPerSecond = (728L/10L), kRepeatSpeed = 40, // 25 frames/sec kNormalFadeDuration = 320, // 64 steps, 5 msec each - kQuickFadeDuration = 64 // 64 steps, 1 msec each + kQuickFadeDuration = 64, // 64 steps, 1 msec each + kPuzzleHintTime = 30000 // 30 secs }; enum Directions { |