aboutsummaryrefslogtreecommitdiff
path: root/engines/xeen/scripts.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/xeen/scripts.cpp')
-rw-r--r--engines/xeen/scripts.cpp138
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 &params) {
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 &params) {
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 &params) {
break;
}
- param2 = mode2 = params.readByte();
+ mode2 = params.readByte();
switch (mode2) {
case 16:
case 34:
@@ -711,7 +711,7 @@ bool Scripts::cmdTakeOrGive(ParamsIterator &params) {
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 &params) {
// fall through
case 21:
case 66:
- if (param2) {
+ if (flag) {
switch (mode2) {
case 82:
mode1 = 0;
@@ -732,13 +732,18 @@ bool Scripts::cmdTakeOrGive(ParamsIterator &params) {
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 &params) {
case 100:
case 101:
case 106:
- if (param2) {
+ if (flag) {
_lineNum = -1;
return false;
}
@@ -770,7 +775,7 @@ bool Scripts::cmdTakeOrGive(ParamsIterator &params) {
case 100:
case 101:
case 106:
- if (param2)
+ if (flag)
continue;
// Break out of character loop
@@ -849,7 +854,7 @@ bool Scripts::cmdSpawn(ParamsIterator &params) {
}
bool Scripts::cmdDoTownEvent(ParamsIterator &params) {
- _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 &params) {
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 &params) {
}
bool Scripts::cmdReturn(ParamsIterator &params) {
- 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 &params) {
@@ -1124,11 +1140,11 @@ bool Scripts::cmdRndDamage(ParamsIterator &params) {
bool Scripts::cmdMoveWallObj(ParamsIterator &params) {
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 &params) {
bool Scripts::cmdIfMapFlag(ParamsIterator &params) {
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 &params) {
@@ -1224,24 +1251,25 @@ bool Scripts::cmdSelectRandomChar(ParamsIterator &params) {
bool Scripts::cmdGiveEnchanted(ParamsIterator &params) {
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 &params) {
}
bool Scripts::cmdDisplayMain(ParamsIterator &params) {
+ _windowIndex = 11;
+
display(false, 0);
return true;
}
@@ -1401,7 +1431,7 @@ bool Scripts::cmdCutsceneEndDarkside(ParamsIterator &params) {
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 &params) {
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 &params) {
bool Scripts::cmdPlayCD(ParamsIterator &params) { 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;