From 66dc9ac74645da3aec55edc85c59b73d5724ba43 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 3 Mar 2015 21:26:20 -0500 Subject: XEEN: Implement give/take script opcodes --- engines/xeen/party.cpp | 5 ++ engines/xeen/party.h | 2 + engines/xeen/scripts.cpp | 219 ++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 222 insertions(+), 4 deletions(-) (limited to 'engines/xeen') diff --git a/engines/xeen/party.cpp b/engines/xeen/party.cpp index 5e111e61b4..9f56b98c4c 100644 --- a/engines/xeen/party.cpp +++ b/engines/xeen/party.cpp @@ -744,4 +744,9 @@ bool Party::canShoot() const { return false; } +bool Party::giveTake(int mode1, uint32 mask1, int mode2, int mask2, int charIdx) { + error("TODO"); +} + + } // End of namespace Xeen diff --git a/engines/xeen/party.h b/engines/xeen/party.h index 483c3f43ec..445380b893 100644 --- a/engines/xeen/party.h +++ b/engines/xeen/party.h @@ -175,6 +175,8 @@ public: bool arePacksFull() const; bool canShoot() const; + + bool giveTake(int mode1, uint32 mask1, int mode2, int mask2, int charIdx); }; } // End of namespace Xeen diff --git a/engines/xeen/scripts.cpp b/engines/xeen/scripts.cpp index 53eebb9675..7cb487c89d 100644 --- a/engines/xeen/scripts.cpp +++ b/engines/xeen/scripts.cpp @@ -372,7 +372,9 @@ void Scripts::cmdNPC(Common::Array ¶ms) { if (TownMessage::show(_vm, params[2], _message, map._events._text[params[1]], params[3])) - _lineNum = params[4]; + _lineNum = params[4] - 1; + + cmdNoAction(params); } /** @@ -484,7 +486,7 @@ void Scripts::cmdIf(Common::Array ¶ms) { } else { result = false; for (int idx = 0; idx < (int)party._activeParty.size() && !result; ++idx) { - if (_charIndex == 0 || (_charIndex == 8 && idx != _v2)) { + if (_charIndex == 0 || (_charIndex == 8 && (int)idx != _v2)) { result = ifProc(params[0], mask, _event->_opcode - 8, idx); } } @@ -511,7 +513,213 @@ void Scripts::cmdMoveObj(Common::Array ¶ms) { } } -void Scripts::cmdTakeOrGive(Common::Array ¶ms) { error("TODO"); } +void Scripts::cmdTakeOrGive(Common::Array ¶ms) { + Party &party = *_vm->_party; + Screen &screen = *_vm->_screen; + int mode1, mode2, mode3; + uint32 mask1, mask2, mask3; + byte *extraP; + // TODO: See if this needs to maintain values set in other opcodes + int param2 = 0; + + mode1 = params[0]; + switch (mode1) { + case 16: + case 34: + case 100: + mask1 = (params[4] << 24) | (params[3] << 16) | (params[2] << 8) | params[1]; + extraP = ¶ms[5]; + break; + case 25: + case 35: + case 101: + case 106: + mask1 = (params[2] << 8) | params[1]; + extraP = ¶ms[3]; + break; + default: + mask1 = params[1]; + extraP = ¶ms[2]; + break; + } + + mode2 = *extraP++; + switch (mode2) { + case 16: + case 34: + case 100: + mask2 = (extraP[3] << 24) | (extraP[2] << 16) | (extraP[1] << 8) | extraP[0]; + extraP += 4; + break; + case 25: + case 35: + case 101: + case 106: + mask2 = (extraP[1] << 8) | extraP[0]; + extraP += 2; + break; + default: + mask2 = extraP[0]; + extraP++; + break; + } + + mode3 = *extraP++; + switch (mode3) { + case 16: + case 34: + case 100: + mask3 = (extraP[3] << 24) | (extraP[2] << 16) | (extraP[1] << 8) | extraP[0]; + break; + case 25: + case 35: + case 101: + case 106: + mask3 = (extraP[1] << 8) | extraP[0]; + break; + default: + mask3 = extraP[0]; + break; + } + + if (mode2) + screen.closeWindows(); + + switch (_event->_opcode) { + case OP_TakeOrGive_2: + if (_charIndex == 0 || _charIndex == 8) { + for (uint idx = 0; idx < party._activeParty.size(); ++idx) { + if (_charIndex == 0 || (_charIndex == 8 && (int)idx != _v2)) { + if (ifProc(params[0], mask1, _event->_opcode == OP_TakeOrGive_4 ? 2 : 1, idx)) { + party.giveTake(0, 0, mode2, mask2, idx); + if (mode2 == 82) + break; + } + } + } + } else if (ifProc(params[0], mask1, _event->_opcode == OP_TakeOrGive_4 ? 2 : 1, _charIndex - 1)) { + party.giveTake(0, 0, mode2, mask2, _charIndex - 1); + } + break; + + case OP_TakeOrGive_3: + if (_charIndex == 0 || _charIndex == 8) { + for (uint idx = 0; idx < party._activeParty.size(); ++idx) { + if (_charIndex == 0 || (_charIndex == 8 && (int)idx != _v2)) { + if (ifProc(params[0], mask1, 1, idx) && ifProc(mode2, mask2, 1, idx)) { + party.giveTake(0, 0, mode2, mask3, idx); + if (mode2 == 82) + break; + } + } + } + } else if (ifProc(params[0], mask1, 1, _charIndex - 1) && + ifProc(mode2, mask2, 1, _charIndex - 1)) { + party.giveTake(0, 0, mode2, mask3, _charIndex - 1); + } + break; + + case OP_TakeOrGive_4: + if (_charIndex == 0 || _charIndex == 8) { + for (uint idx = 0; idx < party._activeParty.size(); ++idx) { + if (_charIndex == 0 || (_charIndex == 8 && (int)idx != _v2)) { + if (ifProc(params[0], mask1, _event->_opcode == OP_TakeOrGive_4 ? 2 : 1, idx)) { + party.giveTake(0, 0, mode2, mask2, idx); + if (mode2 == 82) + break; + } + } + } + } else if (ifProc(params[0], mask1, 1, _charIndex - 1)) { + party.giveTake(0, 0, mode2, mask2, _charIndex - 1); + } + break; + + default: + if (_charIndex == 0 || _charIndex == 8) { + for (uint idx = 0; idx < party._activeParty.size(); ++idx) { + if (_charIndex == 0 || (_charIndex == 8 && (int)idx != _v2)) { + party.giveTake(mode1, mask1, mode1, mask2, idx); + + switch (mode1) { + case 8: + mode1 = 0; + // Deliberate fall-through + case 21: + case 66: + if (param2) { + switch (mode2) { + case 82: + mode1 = 0; + // Deliberate fall-through + case 21: + case 34: + case 35: + case 65: + case 66: + case 100: + case 101: + case 106: + if (param2) + continue; + + // Break out of character loop + idx = party._activeParty.size(); + break; + } + } + break; + + case 34: + case 35: + case 65: + case 100: + case 101: + case 106: + if (param2) { + _lineNum = -1; + return; + } + + // Break out of character loop + idx = party._activeParty.size(); + break; + + default: + switch (mode2) { + case 82: + mode1 = 0; + // Deliberate fall-through + case 21: + case 34: + case 35: + case 65: + case 66: + case 100: + case 101: + case 106: + if (param2) + continue; + + // Break out of character loop + idx = party._activeParty.size(); + break; + } + break; + } + } + } + } else { + if (!party.giveTake(mode1, mask1, mode2, mask2, _charIndex - 1)) { + if (mode2 == 79) + screen.closeWindows(); + } + } + break; + } + + cmdNoAction(params); +} /** * Move to the next line of the script @@ -949,7 +1157,10 @@ void Scripts::cmdCheckProtection(Common::Array ¶ms) { cmdExit(params); } -void Scripts::cmdChooseNumeric(Common::Array ¶ms) { error("TODO"); } +void Scripts::cmdChooseNumeric(Common::Array ¶ms) { + error("TODO"); +} + void Scripts::cmdDisplayBottomTwoLines(Common::Array ¶ms) { error("TODO"); } void Scripts::cmdDisplayLarge(Common::Array ¶ms) { -- cgit v1.2.3