From b695934a1e5a62aa854bfc02bb4f10f562efe62b Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 24 Jan 2015 23:12:30 -0500 Subject: XEEN: Implemented cmdTeleport opcode --- engines/xeen/dialogs_string_input.cpp | 11 ++++- engines/xeen/items.h | 2 +- engines/xeen/screen.cpp | 4 +- engines/xeen/screen.h | 2 +- engines/xeen/scripts.cpp | 90 ++++++++++++++++++++++++++++++++--- engines/xeen/scripts.h | 14 ++++++ 6 files changed, 110 insertions(+), 13 deletions(-) (limited to 'engines/xeen') diff --git a/engines/xeen/dialogs_string_input.cpp b/engines/xeen/dialogs_string_input.cpp index 03191f877d..ced4ad39ff 100644 --- a/engines/xeen/dialogs_string_input.cpp +++ b/engines/xeen/dialogs_string_input.cpp @@ -21,6 +21,7 @@ */ #include "xeen/dialogs_string_input.h" +#include "xeen/scripts.h" #include "xeen/xeen.h" namespace Xeen { @@ -38,6 +39,7 @@ int StringInput::execute(bool type, const Common::String &expected, const Common::String &title, int opcode) { Interface &intf = *_vm->_interface; Screen &screen = *_vm->_screen; + Scripts &scripts = *_vm->_scripts; Window &w = screen._windows[6]; SoundManager &sound = *_vm->_sound; int result = 0; @@ -58,8 +60,13 @@ int StringInput::execute(bool type, const Common::String &expected, // Load in the mirror list File f(Common::String::format("%smirr.txt", _vm->_files->_isDarkCc ? "dark" : "xeen")); - for (int idx = 0; f.pos() < f.size(); ++idx) { - if (line == f.readLine()) { + MirrorEntry me; + scripts._mirror.clear(); + while (me.synchronize(f)) + scripts._mirror.push_back(me); + + for (uint idx = 0; idx < scripts._mirror.size(); ++idx) { + if (line == scripts._mirror[idx]._name) { result = idx; sound.playFX(_vm->_files->_isDarkCc ? 35 : 61); break; diff --git a/engines/xeen/items.h b/engines/xeen/items.h index 9141deffa2..95a5519400 100644 --- a/engines/xeen/items.h +++ b/engines/xeen/items.h @@ -33,7 +33,7 @@ namespace Xeen { class XeenItem { public: int _material; - int _name; + uint _name; int _bonusFlags; bool _equipped; public: diff --git a/engines/xeen/screen.cpp b/engines/xeen/screen.cpp index 16e4955cde..4eabc2b60a 100644 --- a/engines/xeen/screen.cpp +++ b/engines/xeen/screen.cpp @@ -180,9 +180,7 @@ void Window::drawList(DrawStruct *items, int count) { /** * Allows the user to enter a string */ -int Window::getString(Common::String &line, int maxLen, int maxWidth) { - Interface &intf = *_vm->_interface; - +int Window::getString(Common::String &line, uint maxLen, int maxWidth) { _vm->_noDirectionSense = true; Common::String msg = Common::String::format("\x03""l\t000\x04%03d\x03""c", maxWidth); writeString(msg); diff --git a/engines/xeen/screen.h b/engines/xeen/screen.h index 5e4e46ca21..6e805c2aa3 100644 --- a/engines/xeen/screen.h +++ b/engines/xeen/screen.h @@ -95,7 +95,7 @@ public: void drawList(DrawStruct *items, int count); - int getString(Common::String &line, int maxLen, int maxWidth); + int getString(Common::String &line, uint maxLen, int maxWidth); }; class Screen: public FontSurface { diff --git a/engines/xeen/scripts.cpp b/engines/xeen/scripts.cpp index 57196af8b1..39202c089d 100644 --- a/engines/xeen/scripts.cpp +++ b/engines/xeen/scripts.cpp @@ -69,6 +69,24 @@ void MazeEvents::synchronize(XeenSerializer &s) { /*------------------------------------------------------------------------*/ +bool MirrorEntry::synchronize(Common::SeekableReadStream &s) { + if (s.pos() >= s.size()) + return false; + + char buffer[28]; + s.read(buffer, 28); + buffer[27] = '\0'; + + _name = Common::String(buffer); + _mapId = s.readByte(); + _position.x = s.readSByte(); + _position.y = s.readSByte(); + _direction = s.readSByte(); + return true; +} + +/*------------------------------------------------------------------------*/ + Scripts::Scripts(XeenEngine *vm) : _vm(vm) { Common::fill(&_charFX[0], &_charFX[MAX_ACTIVE_PARTY], 0); _whoWill = 0; @@ -82,6 +100,7 @@ Scripts::Scripts(XeenEngine *vm) : _vm(vm) { _nEdamageType = 0; _animCounter = 0; _eventSkipped = false; + _mirrorId = -1; } void Scripts::checkEvents() { @@ -271,7 +290,67 @@ void Scripts::cmdPlayFX(Common::Array ¶ms) { } void Scripts::cmdTeleport(Common::Array ¶ms) { - error("TODO"); + EventsManager &events = *_vm->_events; + Interface &intf = *_vm->_interface; + Map &map = *_vm->_map; + Party &party = *_vm->_party; + Screen &screen = *_vm->_screen; + SoundManager &sound = *_vm->_sound; + + screen.closeWindows(); + _var4F = true; + + int mapId; + Common::Point pt; + + if (params[0]) { + mapId = params[0]; + pt = Common::Point((int8)params[1], (int8)params[2]); + } else { + assert(_mirrorId > 0); + MirrorEntry &me = _mirror[_mirrorId - 1]; + mapId = me._mapId; + pt = me._position; + if (me._direction != -1) + party._mazeDirection = (Direction)me._direction; + + if (pt.x == 0 && pt.y == 0) + pt.x = 999; + + sound.playFX(51); + } + + party._stepped = true; + if (mapId != party._mazeId) { + switch (map._mobData._objects[intf._objNumber - 1]._spriteId) { + case 47: + sound.playFX(45); + break; + case 48: + sound.playFX(44); + break; + default: + break; + } + + // Load the new map + map.load(mapId); + } + + if (pt.x == 999) { + party._mazePosition = map.mazeData()._runPosition; + } else { + party._mazePosition = pt; + } + + events.clearEvents(); + + if (_event->_opcode == OP_TeleportAndContinue) { + intf.draw3d(true); + _lineNum = 0; + } else { + cmdExit(params); + } } /** @@ -586,7 +665,6 @@ void Scripts::cmdReturn(Common::Array ¶ms) { void Scripts::cmdSetVar(Common::Array ¶ms) { Party &party = *_vm->_party; - bool flag = true; uint val; switch (params[0]) { @@ -898,22 +976,22 @@ bool Scripts::ifProc(int action, uint32 mask, int mode, int charIndex) { if (mask < 82) { for (int idx = 0; idx < 9; ++idx) { if (mask == 35) { - if ((int)ps._weapons[idx]._name == mask) { + if (ps._weapons[idx]._name == mask) { v = mask; break; } } else if (mask < 49) { - if ((int)ps._armor[idx]._name == (mask - 35)) { + if (ps._armor[idx]._name == (mask - 35)) { v = mask; break; } } else if (mask < 60) { - if ((int)ps._accessories[idx]._name == (mask - 49)) { + if (ps._accessories[idx]._name == (mask - 49)) { v = mask; break; } } else { - if ((int)ps._misc[idx]._name == (mask - 60)) { + if (ps._misc[idx]._name == (mask - 60)) { v = mask; break; } diff --git a/engines/xeen/scripts.h b/engines/xeen/scripts.h index 6193153250..c0168e208f 100644 --- a/engines/xeen/scripts.h +++ b/engines/xeen/scripts.h @@ -29,6 +29,7 @@ #include "common/stack.h" #include "common/str-array.h" #include "xeen/files.h" +#include "xeen/party.h" namespace Xeen { @@ -124,6 +125,17 @@ struct StackEntry : public Common::Point { StackEntry(const Common::Point &pt, int l) : Common::Point(pt), line(l) {} }; +struct MirrorEntry { + Common::String _name; + int _mapId; + Common::Point _position; + int _direction; + + MirrorEntry() : _mapId(0), _direction(DIR_ALL) {} + + bool synchronize(Common::SeekableReadStream &s); +}; + class Scripts { private: XeenEngine *_vm; @@ -134,6 +146,7 @@ private: int _treasureGems; int _lineNum; int _charIndex; + int _mirrorId; int _v2; int _var4F; @@ -214,6 +227,7 @@ public: bool _eventSkipped; int _whoWill; int _nEdamageType; + Common::Array _mirror; public: Scripts(XeenEngine *vm); -- cgit v1.2.3