diff options
Diffstat (limited to 'engines/xeen/scripts.cpp')
-rw-r--r-- | engines/xeen/scripts.cpp | 138 |
1 files changed, 89 insertions, 49 deletions
diff --git a/engines/xeen/scripts.cpp b/engines/xeen/scripts.cpp index 7f78f5bf2c..f126a658a2 100644 --- a/engines/xeen/scripts.cpp +++ b/engines/xeen/scripts.cpp @@ -186,7 +186,7 @@ int Scripts::checkEvents() { if (event._position == _currentPos && event._line == _lineNum && (party._mazeDirection | _currentPos.x | _currentPos.y)) { if (event._direction == party._mazeDirection || event._direction == DIR_ALL) { - _vm->_mode = MODE_RECORD_EVENTS; + _vm->_mode = MODE_SCRIPT_IN_PROGRESS; _scriptExecuted = true; doOpcode(event); break; @@ -214,7 +214,7 @@ int Scripts::checkEvents() { MazeObject &selectedObj = map._mobData._objects[intf._objNumber]; if (selectedObj._spriteId == (ccNum ? 15 : 16)) { - for (uint idx = 0; idx < 16; ++idx) { + for (int idx = 0; idx < MIN((int)map._mobData._objects.size(), 16); ++idx) { MazeObject &obj = map._mobData._objects[idx]; if (obj._spriteId == (ccNum ? 62 : 57)) { selectedObj._id = idx; @@ -223,7 +223,7 @@ int Scripts::checkEvents() { } } } else if (selectedObj._spriteId == 73) { - for (uint idx = 0; idx < 16; ++idx) { + for (int idx = 0; idx < MIN((int)map._mobData._objects.size(), 16); ++idx) { MazeObject &obj = map._mobData._objects[idx]; if (obj._spriteId == 119) { selectedObj._id = idx; @@ -496,7 +496,7 @@ bool Scripts::cmdTeleport(ParamsIterator ¶ms) { party._stepped = true; if (mapId != party._mazeId) { - int spriteId = (intf._objNumber == -1) ? -1 : map._mobData._objects[intf._objNumber - 1]._spriteId; + int spriteId = (intf._objNumber == -1) ? -1 : map._mobData._objects[intf._objNumber]._spriteId; switch (spriteId) { case 47: @@ -596,7 +596,7 @@ bool Scripts::cmdTakeOrGive(ParamsIterator ¶ms) { Combat &combat = *_vm->_combat; Party &party = *_vm->_party; Windows &windows = *_vm->_windows; - int mode1, mode2, mode3, param2; + int mode1, mode2, mode3; uint32 val1, val2, val3; _refreshIcons = true; @@ -618,7 +618,7 @@ bool Scripts::cmdTakeOrGive(ParamsIterator ¶ms) { break; } - param2 = mode2 = params.readByte(); + mode2 = params.readByte(); switch (mode2) { case 16: case 34: @@ -711,7 +711,7 @@ bool Scripts::cmdTakeOrGive(ParamsIterator ¶ms) { if (_charIndex == 0 || _charIndex == 8) { for (uint idx = 0; idx < party._activeParty.size(); ++idx) { if (_charIndex == 0 || (_charIndex == 8 && (int)idx != combat._combatTarget)) { - party.giveTake(mode1, val1, mode2, val2, idx); + bool flag = party.giveTake(mode1, val1, mode2, val2, idx); switch (mode1) { case 8: @@ -719,7 +719,7 @@ bool Scripts::cmdTakeOrGive(ParamsIterator ¶ms) { // fall through case 21: case 66: - if (param2) { + if (flag) { switch (mode2) { case 82: mode1 = 0; @@ -732,13 +732,18 @@ bool Scripts::cmdTakeOrGive(ParamsIterator ¶ms) { case 100: case 101: case 106: - if (param2) + if (flag) continue; // Break out of character loop idx = party._activeParty.size(); break; + default: + break; } + } else { + // Break out of character loop + idx = party._activeParty.size(); } break; @@ -748,7 +753,7 @@ bool Scripts::cmdTakeOrGive(ParamsIterator ¶ms) { case 100: case 101: case 106: - if (param2) { + if (flag) { _lineNum = -1; return false; } @@ -770,7 +775,7 @@ bool Scripts::cmdTakeOrGive(ParamsIterator ¶ms) { case 100: case 101: case 106: - if (param2) + if (flag) continue; // Break out of character loop @@ -849,7 +854,7 @@ bool Scripts::cmdSpawn(ParamsIterator ¶ms) { } bool Scripts::cmdDoTownEvent(ParamsIterator ¶ms) { - _scriptResult = _vm->_locations->doAction((LocationAction)params.readByte()); + _scriptResult = _vm->_locations->doAction(params.readByte()); _vm->_party->_stepped = true; _refreshIcons = true; @@ -934,18 +939,24 @@ bool Scripts::cmdConfirmWord(ParamsIterator ¶ms) { int param2 = params.readByte(); int param3 = params.readByte(); - Common::String msg1 = param2 ? map._events._text[param2] : _message; - Common::String msg2; + Common::String expected2; + Common::String title; if (_event->_opcode == OP_ConfirmWord_2) { - msg2 = ""; + title = ""; } else if (param3) { - msg2 = map._events._text[param3]; + title = map._events._text[param3]; } else { - msg2 = Res.WHATS_THE_PASSWORD; + title = Res.WHATS_THE_PASSWORD; } - _mirrorId = StringInput::show(_vm, inputType, msg1, msg2, _event->_opcode); + if (!param2) { + expected2 = _message; + } else if (param2 < (int)map._events._text.size()) { + expected2 = map._events._text[param2]; + } + + _mirrorId = StringInput::show(_vm, inputType, expected2, title, _event->_opcode); if (_mirrorId) { if (_mirrorId == 33 && files._ccNum) { doDarkSideEnding(); @@ -1037,11 +1048,16 @@ bool Scripts::cmdCallEvent(ParamsIterator ¶ms) { } bool Scripts::cmdReturn(ParamsIterator ¶ms) { - StackEntry se = _stack.pop(); - _currentPos = se; - _lineNum = se.line; + if (_stack.empty()) { + // WORKAROUND: Some scripts in Swords of Xeen use cmdReturn as a substitute for cmdExit + return cmdExit(params); + } else { + StackEntry se = _stack.pop(); + _currentPos = se; + _lineNum = se.line; - return true; + return true; + } } bool Scripts::cmdSetVar(ParamsIterator ¶ms) { @@ -1124,11 +1140,11 @@ bool Scripts::cmdRndDamage(ParamsIterator ¶ms) { bool Scripts::cmdMoveWallObj(ParamsIterator ¶ms) { Map &map = *_vm->_map; - int itemNum = params.readByte(); + int index = params.readByte(); int x = params.readShort(); int y = params.readShort(); - map._mobData._wallItems[itemNum]._position = Common::Point(x, y); + map._mobData._wallItems[index]._position = Common::Point(x, y); return true; } @@ -1207,14 +1223,25 @@ bool Scripts::cmdDisplayBottom(ParamsIterator ¶ms) { bool Scripts::cmdIfMapFlag(ParamsIterator ¶ms) { Map &map = *_vm->_map; - MazeMonster &monster = map._mobData._monsters[params.readByte()]; + int monsterNum = params.readByte(); + int lineNum = params.readByte(); - if (monster._position.x >= 32 || monster._position.y >= 32) { - _lineNum = params.readByte(); - return false; + if (monsterNum == 0xff) { + for (monsterNum = 0; monsterNum < (int)map._mobData._monsters.size(); ++monsterNum) { + MazeMonster &monster = map._mobData._monsters[monsterNum]; + + if ((uint)monster._position.x < 32 && (uint)monster._position.y < 32) + return true; + } + } else { + MazeMonster &monster = map._mobData._monsters[monsterNum]; + + if ((uint)monster._position.x < 32 && (uint)monster._position.y < 32) + return true; } - return true; + _lineNum = lineNum; + return false; } bool Scripts::cmdSelectRandomChar(ParamsIterator ¶ms) { @@ -1224,24 +1251,25 @@ bool Scripts::cmdSelectRandomChar(ParamsIterator ¶ms) { bool Scripts::cmdGiveEnchanted(ParamsIterator ¶ms) { Party &party = *_vm->_party; + int itemOffset = _vm->getGameID() == GType_Swords ? 6 : 0; XeenItem *item; int invIndex; int id = params.readByte(); // Get category of item to add ItemCategory cat = CATEGORY_WEAPON; - if (id < 35) { - } else if (id < 49) { + if (id < (35 + itemOffset)) { + } else if (id < (49 + itemOffset)) { cat = CATEGORY_ARMOR; - id -= 35; - } else if (id < 60) { + id -= 35 + itemOffset; + } else if (id < (60 + itemOffset)) { cat = CATEGORY_ACCESSORY; - id -= 49; - } else if (id < 82) { + id -= 49 + itemOffset; + } else if (id < (82 + itemOffset)) { cat = CATEGORY_MISC; - id -= 60; + id -= 60 + itemOffset; } else { - party._questItems[id - 82]++; + party._questItems[id - (82 + itemOffset)]++; } // Check for an empty slot @@ -1377,6 +1405,8 @@ bool Scripts::cmdFallToMap(ParamsIterator ¶ms) { } bool Scripts::cmdDisplayMain(ParamsIterator ¶ms) { + _windowIndex = 11; + display(false, 0); return true; } @@ -1401,7 +1431,7 @@ bool Scripts::cmdCutsceneEndDarkside(ParamsIterator ¶ms) { Party &party = *_vm->_party; _vm->_saves->_wonDarkSide = true; party._questItems[53] = 1; - party._darkSideEnd = true; + party._darkSideCompleted = true; party._mazeId = 29; party._mazeDirection = DIR_NORTH; party._mazePosition = Common::Point(25, 21); @@ -1422,7 +1452,7 @@ bool Scripts::cmdCutsceneEndWorld(ParamsIterator ¶ms) { g_vm->saveSettings(); _vm->_saves->_wonWorld = true; - _vm->_party->_worldEnd = true; + _vm->_party->_worldCompleted = true; doWorldEnding(); return false; @@ -1436,10 +1466,18 @@ bool Scripts::cmdFlipWorld(ParamsIterator ¶ms) { bool Scripts::cmdPlayCD(ParamsIterator ¶ms) { error("TODO"); } void Scripts::doCloudsEnding() { + g_vm->_party->_cloudsCompleted = true; doEnding("ENDGAME"); + + g_vm->_mode = MODE_INTERACTIVE; + g_vm->_saves->saveGame(); + + g_vm->_gameMode = GMODE_MENU; + g_vm->_mode = MODE_STARTUP; } void Scripts::doDarkSideEnding() { + g_vm->_party->_darkSideCompleted = true; doEnding("ENDGAME2"); } @@ -1556,37 +1594,39 @@ bool Scripts::ifProc(int action, uint32 val, int mode, int charIndex) { assert(val < 512); v = party._gameFlags[val / 256][val % 256] ? val : 0xffffffff; break; - case 21: + case 21: { // Scans inventories for given item number + uint itemOffset = _vm->getGameID() == GType_Swords ? 6 : 0; v = 0xFFFFFFFF; - if (val < 82) { + if (val < (82 + itemOffset)) { for (int idx = 0; idx < 9; ++idx) { - if (val == 35) { + if (val == (35 + itemOffset)) { if (ps->_weapons[idx]._id == val) { v = val; break; } - } else if (val < 49) { + } else if (val < (49 + itemOffset)) { if (ps->_armor[idx]._id == (val - 35)) { v = val; break; } - } else if (val < 60) { - if (ps->_accessories[idx]._id == (val - 49)) { + } else if (val < (60 + itemOffset)) { + if (ps->_accessories[idx]._id == (val - (49 + itemOffset))) { v = val; break; } } else { - if (ps->_misc[idx]._id == (val - 60)) { + if (ps->_misc[idx]._id == (val - (60 + itemOffset))) { v = val; break; } } } - } else if (party._questItems[val - 82]) { + } else if (party._questItems[val - (82 + itemOffset)]) { v = val; } break; + } case 25: // Returns number of minutes elapsed in the day (0-1440) v = party._minutes; @@ -1600,7 +1640,7 @@ bool Scripts::ifProc(int action, uint32 val, int mode, int charIndex) { v = party._gems; break; case 37: - // Might bonus (extra beond base) + // Might bonus (extra beyond base) v = ps->_might._temporary; break; case 38: @@ -1802,7 +1842,7 @@ bool Scripts::ifProc(int action, uint32 val, int mode, int charIndex) { break; case 107: // Get value of character flag - error("Unused"); + v = party._characterFlags[ps->_rosterId][val] ? val : 0xffffffff; break; default: break; |