From 7bbbfd2ad0b310497eacecad7e14230eed6bd80b Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 2 Mar 2015 21:39:49 -0500 Subject: XEEN: Implementing more script opcodes --- engines/xeen/debugger.cpp | 5 +- engines/xeen/resources.cpp | 4 + engines/xeen/resources.h | 2 + engines/xeen/screen.cpp | 4 +- engines/xeen/screen.h | 2 +- engines/xeen/scripts.cpp | 182 +++++++++++++++++++++++++++++++++++++++++---- engines/xeen/scripts.h | 6 ++ 7 files changed, 184 insertions(+), 21 deletions(-) (limited to 'engines') diff --git a/engines/xeen/debugger.cpp b/engines/xeen/debugger.cpp index 35cbaeb58c..d9b4990e97 100644 --- a/engines/xeen/debugger.cpp +++ b/engines/xeen/debugger.cpp @@ -52,7 +52,6 @@ Debugger::Debugger(XeenEngine *vm) : GUI::Debugger(), _vm(vm) { } void Debugger::update() { - Combat &combat = *_vm->_combat; Party &party = *_vm->_party; Spells &spells = *_vm->_spells; @@ -60,7 +59,9 @@ void Debugger::update() { // Cast any specified spell MagicSpell spellId = (MagicSpell)_spellId; _spellId = -1; - spells.castSpell(&party._activeParty[0], spellId); + Character *c = &party._activeParty[0]; + c->_currentSp = 99; + spells.castSpell(c, spellId); } onFrame(); diff --git a/engines/xeen/resources.cpp b/engines/xeen/resources.cpp index 544db24385..0b30ce3e8b 100644 --- a/engines/xeen/resources.cpp +++ b/engines/xeen/resources.cpp @@ -1585,4 +1585,8 @@ const char *const MONSTER_SPECIAL_ATTACKS[23] = { const char *const IDENTIFY_MONSTERS = "Name\x3""c\t100HP\t140AC\t177#Atks\x3r\t000Special%s%s%s"; +const char *const EVENT_SAMPLES[6] = { + "ahh.voc", "whereto.voc", "gulp.voc", "null.voc", "scream.voc", "laff1.voc" +}; + } // End of namespace Xeen diff --git a/engines/xeen/resources.h b/engines/xeen/resources.h index e15c509391..6e9ce6ce39 100644 --- a/engines/xeen/resources.h +++ b/engines/xeen/resources.h @@ -562,6 +562,8 @@ extern const char *const MONSTER_SPECIAL_ATTACKS[23]; extern const char *const IDENTIFY_MONSTERS; +extern const char *const EVENT_SAMPLES[6]; + } // End of namespace Xeen #endif /* XEEN_RESOURCES_H */ diff --git a/engines/xeen/screen.cpp b/engines/xeen/screen.cpp index ac1f0c476b..d9dcbf16f1 100644 --- a/engines/xeen/screen.cpp +++ b/engines/xeen/screen.cpp @@ -183,8 +183,8 @@ void Window::fill() { fillRect(_innerBounds, _vm->_screen->_bgColor); } -void Window::writeString(const Common::String &s) { - _vm->_screen->writeString(s, _innerBounds); +Common::String Window::writeString(const Common::String &s) { + return _vm->_screen->writeString(s, _innerBounds); } void Window::drawList(DrawStruct *items, int count) { diff --git a/engines/xeen/screen.h b/engines/xeen/screen.h index f8f11a44a4..901e79b5d4 100644 --- a/engines/xeen/screen.h +++ b/engines/xeen/screen.h @@ -92,7 +92,7 @@ public: void fill(); - void writeString(const Common::String &s); + Common::String writeString(const Common::String &s); void drawList(DrawStruct *items, int count); diff --git a/engines/xeen/scripts.cpp b/engines/xeen/scripts.cpp index ec00327205..c1743ab7ad 100644 --- a/engines/xeen/scripts.cpp +++ b/engines/xeen/scripts.cpp @@ -102,6 +102,8 @@ Scripts::Scripts(XeenEngine *vm) : _vm(vm) { _scriptResult = false; _scriptExecuted = false; _var50 = false; + _redrawDone = false; + _windowIndex = -1; } int Scripts::checkEvents() { @@ -132,7 +134,7 @@ int Scripts::checkEvents() { _lineNum = 0; _scriptResult = false; _animCounter = 0; -// int var4E = 0; + _redrawDone = false; _currentPos = party._mazePosition; _charIndex = 1; _v2 = 1; @@ -366,7 +368,7 @@ void Scripts::cmdSignText(Common::Array ¶ms) { } void Scripts::cmdNPC(Common::Array ¶ms) { - warning("TODO: cmdNPC"); + error("TODO: cmdNPC"); } /** @@ -800,18 +802,123 @@ void Scripts::cmdWhoWill(Common::Array ¶ms) { cmdNoAction(params); } -void Scripts::cmdRndDamage(Common::Array ¶ms) { error("TODO"); } -void Scripts::cmdMoveWallObj(Common::Array ¶ms) { error("TODO"); } -void Scripts::cmdAlterCellFlag(Common::Array ¶ms) { error("TODO"); } -void Scripts::cmdAlterHed(Common::Array ¶ms) { error("TODO"); } -void Scripts::cmdDisplayStat(Common::Array ¶ms) { error("TODO"); } -void Scripts::cmdSeatTextSml(Common::Array ¶ms) { error("TODO"); } -void Scripts::cmdPlayEventVoc(Common::Array ¶ms) { error("TODO"); } -void Scripts::cmdDisplayBottom(Common::Array ¶ms) { error("TODO"); } -void Scripts::cmdIfMapFlag(Common::Array ¶ms) { error("TODO"); } -void Scripts::cmdSelRndChar(Common::Array ¶ms) { error("TODO"); } -void Scripts::cmdGiveEnchanted(Common::Array ¶ms) { error("TODO"); } -void Scripts::cmdItemType(Common::Array ¶ms) { error("TODO"); } +void Scripts::cmdRndDamage(Common::Array ¶ms) { + Combat &combat = *_vm->_combat; + Interface &intf = *_vm->_interface; + + if (!_redrawDone) { + intf.draw3d(true); + _redrawDone = true; + } + + combat.giveCharDamage(_vm->getRandomNumber(1, params[1]), (DamageType)params[0], _charIndex); + cmdNoAction(params); +} + +void Scripts::cmdMoveWallObj(Common::Array ¶ms) { + Map &map = *_vm->_map; + + map._mobData._wallItems[params[0]]._position = Common::Point(params[1], params[2]); + cmdNoAction(params); +} + +void Scripts::cmdAlterCellFlag(Common::Array ¶ms) { + Map &map = *_vm->_map; + Common::Point pt(params[0], params[1]); + map.cellFlagLookup(pt); + + if (map._isOutdoors) { + MazeWallLayers &wallData = map.mazeDataCurrent()._wallData[pt.y][pt.x]; + wallData._data = (wallData._data & 0xFFF0) | params[2]; + } else { + pt.x &= 0xF; + pt.y &= 0xF; + MazeCell &cell = map.mazeDataCurrent()._cells[pt.y][pt.x]; + cell._surfaceId = params[2]; + } + + cmdNoAction(params); +} + +void Scripts::cmdAlterHed(Common::Array ¶ms) { + Map &map = *_vm->_map; + Party &party = *_vm->_party; + + HeadData::HeadEntry &he = map._headData[party._mazePosition.y][party._mazePosition.x]; + he._left = params[0]; + he._right = params[1]; + + cmdNoAction(params); +} + +void Scripts::cmdDisplayStat(Common::Array ¶ms) { + Party &party = *_vm->_party; + Window &w = _vm->_screen->_windows[12]; + Character &c = party._activeParty[_charIndex - 1]; + + if (!w._enabled) + w.open(); + w.writeString(Common::String::format(_message.c_str(), c._name.c_str())); + w.update(); + + cmdNoAction(params); +} + +void Scripts::cmdSeatTextSml(Common::Array ¶ms) { + Interface &intf = *_vm->_interface; + + intf._screenText = Common::String::format("\x2\f08\x3""c\t116\v090%s\x3l\fd\x1", + _message); + intf._upDoorText = true; + intf.draw3d(true); + + cmdNoAction(params); +} + +void Scripts::cmdPlayEventVoc(Common::Array ¶ms) { + SoundManager &sound = *_vm->_sound; + sound.playSample(nullptr, 0); + File f(EVENT_SAMPLES[params[0]]); + sound.playSample(&f, 1); + + cmdNoAction(params); +} + +void Scripts::cmdDisplayBottom(Common::Array ¶ms) { + _windowIndex = 12; + + display(false, 0); + cmdNoAction(params); +} + +void Scripts::cmdIfMapFlag(Common::Array ¶ms) { + Map &map = *_vm->_map; + MazeMonster &monster = map._mobData._monsters[params[0]]; + + if (monster._position.x >= 32 || monster._position.y >= 32) { + _lineNum = params[1] - 1; + } + + cmdNoAction(params); +} + +void Scripts::cmdSelRndChar(Common::Array ¶ms) { + _charIndex = _vm->getRandomNumber(1, _vm->_party->_activeParty.size()); + cmdNoAction(params); +} + +void Scripts::cmdGiveEnchanted(Common::Array ¶ms) { + if (params[0] < 35) { + + } + error("TODO"); +} + +void Scripts::cmdItemType(Common::Array ¶ms) { + _itemType = params[0]; + + cmdNoAction(params); +} /** * Disable all the scripts at the party's current position @@ -840,7 +947,13 @@ void Scripts::cmdCheckProtection(Common::Array ¶ms) { void Scripts::cmdChooseNumeric(Common::Array ¶ms) { error("TODO"); } void Scripts::cmdDisplayBottomTwoLines(Common::Array ¶ms) { error("TODO"); } -void Scripts::cmdDisplayLarge(Common::Array ¶ms) { error("TODO"); } + +void Scripts::cmdDisplayLarge(Common::Array ¶ms) { + error("TODO: Implement event text loading"); + + display(true, 0); + cmdNoAction(params); +} /** * Exchange the positions of two objects in the maze @@ -868,7 +981,8 @@ void Scripts::cmdFallToMap(Common::Array ¶ms) { } void Scripts::cmdDisplayMain(Common::Array ¶ms) { - error("TODO"); + display(false, 0); + cmdNoAction(params); } /** @@ -1333,4 +1447,40 @@ bool Scripts::copyProtectionCheck() { return true; } +void Scripts::display(bool justifyFlag, int var46) { + EventsManager &events = *_vm->_events; + Interface &intf = *_vm->_interface; + Screen &screen = *_vm->_screen; + Window &w = screen._windows[_windowIndex]; + + if (!_redrawDone) { + intf.draw3d(true); + _redrawDone = true; + } + screen._windows[38].close(); + + if (!justifyFlag) + _displayMessage = Common::String::format("\r\x3""c%s", _message.c_str()); + + if (!w._enabled) + w.open(); + + while (!_vm->shouldQuit()) { + _displayMessage = w.writeString(_displayMessage); + w.update(); + if (_displayMessage.empty()) + break; + events.clearEvents(); + + do { + events.updateGameCounter(); + intf.draw3d(true); + + events.wait(1, true); + } while (!_vm->shouldQuit() && !events.isKeyMousePressed()); + + w.writeString(justifyFlag ? "\r" : "\r\x3""c"); + } +} + } // End of namespace Xeen diff --git a/engines/xeen/scripts.h b/engines/xeen/scripts.h index 29de5b8b37..15550dd9c0 100644 --- a/engines/xeen/scripts.h +++ b/engines/xeen/scripts.h @@ -147,9 +147,13 @@ private: int _scriptResult; bool _scriptExecuted; bool _var50; + int _windowIndex; + bool _redrawDone; MazeEvent *_event; Common::Point _currentPos; Common::Stack _stack; + Common::String _message; + Common::String _displayMessage; void doOpcode(MazeEvent &event); void cmdDisplay1(Common::Array ¶ms); @@ -219,6 +223,8 @@ private: bool ifProc(int action, uint32 mask, int mode, int charIndex); bool copyProtectionCheck(); + + void display(bool justifyFlag, int var46); public: int _animCounter; bool _eventSkipped; -- cgit v1.2.3