aboutsummaryrefslogtreecommitdiff
path: root/engines/kyra/gui_eob.cpp
diff options
context:
space:
mode:
authorathrxx2011-11-06 17:35:27 +0100
committerJohannes Schickel2011-12-26 16:18:12 +0100
commitb7f7635876d3621b11d66cddca9babc1b5f1a1c6 (patch)
tree39b54d7e9a7b5cfa66aabbf7a1ce718632466192 /engines/kyra/gui_eob.cpp
parentd7f2720b5709b1b4a93f81163752d2da148d2fd9 (diff)
downloadscummvm-rg350-b7f7635876d3621b11d66cddca9babc1b5f1a1c6.tar.gz
scummvm-rg350-b7f7635876d3621b11d66cddca9babc1b5f1a1c6.tar.bz2
scummvm-rg350-b7f7635876d3621b11d66cddca9babc1b5f1a1c6.zip
KYRA: (EOB) - implement memorize/pray spells menu
Diffstat (limited to 'engines/kyra/gui_eob.cpp')
-rw-r--r--engines/kyra/gui_eob.cpp324
1 files changed, 314 insertions, 10 deletions
diff --git a/engines/kyra/gui_eob.cpp b/engines/kyra/gui_eob.cpp
index 4fe5b6bed9..5d86b9c589 100644
--- a/engines/kyra/gui_eob.cpp
+++ b/engines/kyra/gui_eob.cpp
@@ -1445,11 +1445,18 @@ GUI_Eob::GUI_Eob(EobCoreEngine *vm) : GUI_v1(vm), _vm(vm), _screen(vm->_screen)
_cflag = 0xffff;
_menuLineSpacing = 0;
- _menuUnk1 = 0;
+ //_menuUnk1 = 0;
_menuLastInFlags = 0;
_menuCur = 0;
_menuNumItems = 0;
+ _numPages = (_vm->game() == GI_EOB2) ? 8 : 5;
+ _numVisPages = (_vm->game() == GI_EOB2) ? 6 : 5;
+ _clericSpellAvltyFlags = (_vm->game() == GI_EOB2) ? 0xf7ffffff : 0x7bffff;
+ _paladinSpellAvltyFlags = (_vm->game() == GI_EOB2) ? 0xa9bbd1d : 0x800ff2;
+ _numAssignedSpellsOfType = new int8[72];
+ memset(_numAssignedSpellsOfType, 0, 72);
+
_charSelectRedraw = false;
_updateBoxIndex = -1;
@@ -1463,6 +1470,8 @@ GUI_Eob::~GUI_Eob() {
delete _menuStringsPrefsTemp[i];
delete[] _menuStringsPrefsTemp;
}
+
+ delete[] _numAssignedSpellsOfType;
}
void GUI_Eob::processButton(Button *button) {
@@ -1970,7 +1979,7 @@ void GUI_Eob::simpleMenu_setup(int sd, int maxItem, const char *const *strings,
_screen->updateScreen();
_menuLineSpacing = lineSpacing;
- _menuUnk1 = 0;
+ //_menuUnk1 = 0;
_menuLastInFlags = 0;
_vm->removeInputTop();
}
@@ -2284,7 +2293,7 @@ int GUI_Eob::runLoadMenu(int x, int y) {
return 0;
}
-void GUI_Eob::highLightBoxFrame(int box) {
+void GUI_Eob::updateBoxFrameHighLight(int box) {
static const uint8 colorTable[] = { 0x0F, 0xB0, 0xB2, 0xB4, 0xB6,
0xB8, 0xBA, 0xBC, 0x0C, 0xBC, 0xBA, 0xB8, 0xB6, 0xB4, 0xB2, 0xB0, 0x00
};
@@ -2299,7 +2308,7 @@ void GUI_Eob::highLightBoxFrame(int box) {
if (!colorTable[_updateBoxColorIndex])
_updateBoxColorIndex = 0;
- const EobRect16 *r = &_highLightBoxFrames[_updateBoxIndex];
+ const EobRect16 *r = &_updateBoxFrameHighLights[_updateBoxIndex];
_screen->drawBox(r->x1, r->y1, r->x2, r->y2, colorTable[_updateBoxColorIndex++]);
_screen->updateScreen();
@@ -2307,7 +2316,7 @@ void GUI_Eob::highLightBoxFrame(int box) {
} else {
if (_updateBoxIndex != -1) {
- const EobRect16 *r = &_highLightBoxFrames[_updateBoxIndex];
+ const EobRect16 *r = &_updateBoxFrameHighLights[_updateBoxIndex];
_screen->drawBox(r->x1, r->y1, r->x2, r->y2, 12);
_screen->updateScreen();
}
@@ -2458,9 +2467,283 @@ void GUI_Eob::runSaveMenu() {
}
void GUI_Eob::runMemorizePrayMenu(int charIndex, int spellType) {
+ if (charIndex == -1)
+ return;
+
+ uint8 np[8];
+ memset(np, 0, sizeof(np));
+ uint32 avltyFlags = 0;
+ int li = 0;
+ int lv = 0;
+
+ EobCharacter *c = &_vm->_characters[charIndex];
+ int8 wm = c->wisdomCur - 12;
+ if (wm < 0)
+ wm = 0;
+
+ if (spellType) {
+ li = _vm->getCharacterLevelIndex(2, c->cClass);
+
+ if (li == -1) {
+ li = _vm->getCharacterLevelIndex(4, c->cClass);
+
+ if (li != -1) {
+ lv = c->level[li] - 1;
+ if (lv < 0)
+ lv = 0;
+
+ for (int i = 0; i < _numPages; i++)
+ np[i] = _vm->_numSpellsPal[lv * _numPages + i];
+
+ avltyFlags = _paladinSpellAvltyFlags;
+ }
+
+ } else {
+ lv = c->level[li] - 1;
+ for (int i = 0; i < _numPages; i++) {
+ np[i] = _vm->_numSpellsCleric[lv * _numPages + i];
+ if (np[i])
+ np[i] += _vm->_numSpellsWisAdj[wm * _numPages + i];
+ }
+ avltyFlags = _clericSpellAvltyFlags;
+ }
+
+ } else {
+ li = _vm->getCharacterLevelIndex(1, c->cClass);
+
+ if (li == -1) {
+ if (_vm->checkInventoryForRings(charIndex, 1)) {
+ np[3] <<= 1;
+ np[4] <<= 1;
+ }
+
+ } else {
+ lv = c->level[li] - 1;
+ for (int i = 0; i < _numPages; i++)
+ np[i] = _vm->_numSpellsMage[lv * _numPages + i];
+
+ avltyFlags = c->mageSpellsAvailabilityFlags;
+ }
+ }
+
+ int8 *menuSpellMap = new int8[88];
+ memset(menuSpellMap, 0, 88);
+ int8 *numAssignedSpellsPerBookPage = new int8[8];
+ memset(numAssignedSpellsPerBookPage, 0, 8);
+ memset(_numAssignedSpellsOfType, 0, 72);
+ int8 *lh = new int8[40];
+ memset(lh, 0, 40);
+
+ memcpy(lh, spellType ? _vm->_spellLevelsCleric : _vm->_spellLevelsMage, spellType ? _vm->_spellLevelsClericSize : _vm->_spellLevelsMageSize);
+ int8 *charSpellList = spellType ? c->clericSpells : c->mageSpells;
+
+ for (int i = 0; i < 80; i++) {
+ int8 s = charSpellList[i];
+ if (s == 0 || s == _vm->_spellLevelsClericSize)
+ continue;
+
+ if (s < 0)
+ s = -s;
+ else
+ _numAssignedSpellsOfType[s * 2 - 1]++;
+
+ s--;
+ _numAssignedSpellsOfType[s * 2]++;
+ numAssignedSpellsPerBookPage[lh[s] - 1]++;
+ }
+
+ for (int i = 0; i < 32; i++) {
+ if (!(avltyFlags & (1 << i)))
+ continue;
+
+ int d = lh[i] - 1;
+ if (d < 0)
+ continue;
+
+ if (!spellType || (spellType && np[d])) {
+ menuSpellMap[d * 11]++;
+ menuSpellMap[d * 11 + menuSpellMap[d * 11]] = i + 1;
+ }
+ }
+
+ Button *buttonList = initMenu(4);
+
+ int lastHighLightText = -1;
+ int lastHighLightButton = -1;
+ int newHighLightButton = 0;
+ int newHighLightText = 0;
+ bool updateDesc = true;
+ bool updateList = true;
+
+ for (bool runLoop = true; runLoop && !_vm->shouldQuit(); ) {
+ updateBoxFrameHighLight(charIndex);
+
+ if (newHighLightButton < 0)
+ newHighLightButton = 7;
+ if (newHighLightButton > 7)
+ newHighLightButton = 0;
+
+ Button *b = 0;
+
+ if (lastHighLightButton != newHighLightButton) {
+ if (lastHighLightButton >= 0)
+ drawMenuButton(_vm->gui_getButton(buttonList, lastHighLightButton + 26), false, false, true);
+ drawMenuButton(_vm->gui_getButton(buttonList, newHighLightButton + 26), false, true, true);
+ newHighLightText = 0;
+ lastHighLightText = -1;
+ lastHighLightButton = newHighLightButton;
+ updateDesc = updateList = true;
+ }
+
+ if (updateList) {
+ updateList = false;
+ _screen->setCurPage(2);
+ for (int ii = 1; ii < 9; ii++)
+ memorizePrayMenuPrintString(menuSpellMap[lastHighLightButton * 11 + ii], ii - 1, spellType, false, false);
+
+ _screen->setCurPage(0);
+ _screen->copyRegion(0, 50, 0, 50, 176, 72, 2, 0, Screen::CR_NO_P_CHECK);
+ lastHighLightText = -1;
+ }
+
+ if (updateDesc) {
+ updateDesc = false;
+ _screen->printShadedText(Common::String::format(_vm->_menuStringsMgc[1], np[lastHighLightButton] - numAssignedSpellsPerBookPage[lastHighLightButton], np[lastHighLightButton]).c_str(), 8, 38, 9, _vm->_bkgColor_1);
+ }
+
+ if (newHighLightText < 0)
+ newHighLightText = menuSpellMap[lastHighLightButton * 11] - 1;
+
+ if (menuSpellMap[lastHighLightButton * 11] <= newHighLightText)
+ newHighLightText = 0;
+
+ if (newHighLightText != lastHighLightText) {
+ memorizePrayMenuPrintString(menuSpellMap[lastHighLightButton * 11 + lastHighLightText + 1], lastHighLightText, spellType, true, false);
+ memorizePrayMenuPrintString(menuSpellMap[lastHighLightButton * 11 + newHighLightText + 1], newHighLightText, spellType, true, true);
+ lastHighLightText = newHighLightText;
+ }
+
+ int inputFlag = _vm->checkInput(buttonList, false, 0) & 0x80ff;
+ _vm->removeInputTop();
+
+ if (inputFlag == _vm->_keyMap[Common::KEYCODE_KP6] || inputFlag == _vm->_keyMap[Common::KEYCODE_RIGHT]) {
+ inputFlag = 0x801a + ((lastHighLightButton + 1) % _numVisPages);
+ } else if (inputFlag == _vm->_keyMap[Common::KEYCODE_KP4] || inputFlag == _vm->_keyMap[Common::KEYCODE_LEFT]) {
+ inputFlag = lastHighLightButton ? 0x8019 + lastHighLightButton : 0x8019 + _numVisPages;
+ } else if (inputFlag == _vm->_keyMap[Common::KEYCODE_ESCAPE]) {
+ inputFlag = 0x8018;
+ } else {
+ Common::Point p = _vm->getMousePos();
+ if (_vm->posWithinRect(p.x, p.y, 8, 50, 168, 122)) {
+ newHighLightText = (p.y - 50 ) / 9;
+ if (menuSpellMap[lastHighLightButton * 11] - 1 < newHighLightText)
+ newHighLightText = menuSpellMap[lastHighLightButton * 11] - 1;
+ }
+ }
+
+ if (inputFlag & 0x8000) {
+ Button *b = _vm->gui_getButton(buttonList, inputFlag & 0x7fff);
+ drawMenuButton(b, true, true, true);
+ _screen->updateScreen();
+ _vm->_system->delayMillis(80);
+ drawMenuButton(b, false, false, true);
+ _screen->updateScreen();
+ }
+ if (inputFlag == 0x8019 || inputFlag == _vm->_keyMap[Common::KEYCODE_KP_PLUS] || inputFlag == _vm->_keyMap[Common::KEYCODE_PLUS] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP5] || inputFlag == _vm->_keyMap[Common::KEYCODE_SPACE] || inputFlag == _vm->_keyMap[Common::KEYCODE_RETURN]) {
+ if (np[lastHighLightButton] > numAssignedSpellsPerBookPage[lastHighLightButton] && lastHighLightText != -1) {
+ _numAssignedSpellsOfType[menuSpellMap[lastHighLightButton * 11 + lastHighLightText + 1] * 2 - 2]++;
+ numAssignedSpellsPerBookPage[lastHighLightButton]++;
+ memorizePrayMenuPrintString(menuSpellMap[lastHighLightButton * 11 + lastHighLightText + 1], lastHighLightText, spellType, false, true);
+ updateDesc = true;
+ }
+
+ } else if (inputFlag == _vm->_keyMap[Common::KEYCODE_KP_MINUS] || inputFlag == _vm->_keyMap[Common::KEYCODE_MINUS] /*|| inputFlag == _vm->_keyMap[Common::KEYCODE_*/) {
+ if (np[lastHighLightButton] && _numAssignedSpellsOfType[menuSpellMap[lastHighLightButton * 11 + lastHighLightText + 1] * 2 - 2]) {
+ _numAssignedSpellsOfType[menuSpellMap[lastHighLightButton * 11 + lastHighLightText + 1] * 2 - 2]--;
+ numAssignedSpellsPerBookPage[lastHighLightButton]--;
+ memorizePrayMenuPrintString(menuSpellMap[lastHighLightButton * 11 + lastHighLightText + 1], lastHighLightText, spellType, false, true);
+ updateDesc = true;
+ }
+
+ } else if (inputFlag == _vm->_keyMap[Common::KEYCODE_UP] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP8]) {
+ newHighLightText = lastHighLightText - 1;
+ } else if (inputFlag == _vm->_keyMap[Common::KEYCODE_DOWN] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP2]) {
+ newHighLightText = lastHighLightText + 1;
+ } else if (inputFlag == _vm->_keyMap[Common::KEYCODE_END] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP1]) {
+ newHighLightText = menuSpellMap[lastHighLightButton * 11] - 1;
+ } else if (inputFlag == _vm->_keyMap[Common::KEYCODE_HOME] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP7]) {
+ newHighLightText = 0;
+ } else if (inputFlag == 0x8017) {
+ if (numAssignedSpellsPerBookPage[lastHighLightButton]) {
+ for (int i = 1; i <= menuSpellMap[lastHighLightButton * 11]; i++) {
+ numAssignedSpellsPerBookPage[lastHighLightButton] -= _numAssignedSpellsOfType[menuSpellMap[lastHighLightButton * 11 + i] * 2 - 2];
+ _numAssignedSpellsOfType[menuSpellMap[lastHighLightButton * 11 + i] * 2 - 2] = 0;
+ }
+
+ updateDesc = updateList = true;
+ }
+
+ } else if (inputFlag == 0x8018) {
+ _vm->gui_drawAllCharPortraitsWithStats();
+ runLoop = false;
+
+ } else if (inputFlag & 0x8000) {
+ newHighLightButton = inputFlag - 0x801a;
+ if (newHighLightButton == lastHighLightButton)
+ drawMenuButton(_vm->gui_getButton(buttonList, inputFlag & 0x7fff), false, true, true);
+ }
+ }
+
+ releaseButtons(buttonList);
+ updateBoxFrameHighLight(-1);
+
+ _screen->setFont(Screen::FID_6_FNT);
+ _vm->gui_drawCharPortraitWithStats(charIndex);
+ _screen->setFont(Screen::FID_8_FNT);
+
+ memset(charSpellList, 0, 80);
+ if (spellType)
+ charSpellList[0] = _vm->_spellLevelsClericSize;
+
+ for (int i = 0; i < 32; i++) {
+ if (_numAssignedSpellsOfType[i * 2] < _numAssignedSpellsOfType[i * 2 + 1])
+ _numAssignedSpellsOfType[i * 2 + 1] = _numAssignedSpellsOfType[i * 2];
+
+ if (_numAssignedSpellsOfType[i * 2 + 1]) {
+ _numAssignedSpellsOfType[i * 2]--;
+ _numAssignedSpellsOfType[i * 2 + 1]--;
+
+ int pg = lh[i] - 1;
+ for (int ii = 0; ii < 10; ii++) {
+ if (!charSpellList[pg * 10 + ii]) {
+ charSpellList[pg * 10 + ii] = i + 1;
+ break;
+ }
+ }
+ i--;
+
+ } else if (_numAssignedSpellsOfType[i * 2]) {
+ _numAssignedSpellsOfType[i * 2]--;
+
+ _vm->_resting = true;
+ int pg = lh[i] - 1;
+ for (int ii = 0; ii < 10; ii++) {
+ if (!charSpellList[pg * 10 + ii]) {
+ charSpellList[pg * 10 + ii] = -(i + 1);
+ break;
+ }
+ }
+ i--;
+ }
+ }
+
+ delete[] menuSpellMap;
+ delete[] numAssignedSpellsPerBookPage;
+ delete[] lh;
}
+
void GUI_Eob::scribeScrollDialogue() {
}
@@ -2606,10 +2889,10 @@ int GUI_Eob::selectCharacterDialogue(int id) {
int inputFlag = _vm->checkInput(buttonList, false, 0);
_vm->removeInputTop();
- highLightBoxFrame(hlCur);
+ updateBoxFrameHighLight(hlCur);
if (inputFlag == _vm->_keyMap[Common::KEYCODE_KP4] || inputFlag == _vm->_keyMap[Common::KEYCODE_LEFT] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP8] || inputFlag == _vm->_keyMap[Common::KEYCODE_UP] || inputFlag == _vm->_keyMap[Common::KEYCODE_a] || inputFlag == _vm->_keyMap[Common::KEYCODE_w]) {
- highLightBoxFrame(-1);
+ updateBoxFrameHighLight(-1);
_vm->gui_drawCharPortraitWithStats(hlCur--);
if (hlCur < 0)
hlCur = 5;
@@ -2619,7 +2902,7 @@ int GUI_Eob::selectCharacterDialogue(int id) {
}
} else if (inputFlag == _vm->_keyMap[Common::KEYCODE_KP6] || inputFlag == _vm->_keyMap[Common::KEYCODE_RIGHT] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP2] || inputFlag == _vm->_keyMap[Common::KEYCODE_DOWN] || inputFlag == _vm->_keyMap[Common::KEYCODE_z] || inputFlag == _vm->_keyMap[Common::KEYCODE_s]) {
- highLightBoxFrame(-1);
+ updateBoxFrameHighLight(-1);
_vm->gui_drawCharPortraitWithStats(hlCur++);
if (hlCur == 6)
hlCur = 0;
@@ -2649,7 +2932,7 @@ int GUI_Eob::selectCharacterDialogue(int id) {
}
}
- highLightBoxFrame(-1);
+ updateBoxFrameHighLight(-1);
if (hlCur >= 0)
_vm->gui_drawCharPortraitWithStats(hlCur);
@@ -2718,7 +3001,10 @@ Button *GUI_Eob::initMenu(int id) {
for (int i = 0; i < m->numButtons; i++) {
const EobMenuButtonDef *df = &_vm->_menuButtonDefs[m->firstButtonStrId + i];
Button *b = new Button;
- b->index = m->firstButtonStrId + i + 1;
+ b->index = m->firstButtonStrId + i + 1;
+ if (id == 4 && _vm->game() == GI_EOB1)
+ b->index -= 14;
+
b->data0Val2 = 12;
b->data1Val2 = b->data2Val2 = 15;
b->data3Val2 = 8;
@@ -2782,6 +3068,24 @@ void GUI_Eob::drawMenuButtonBox(int x, int y, int w, int h, bool clicked, bool n
_vm->gui_drawBox(x + 1, y + 1, w - 2, h - 2, _vm->_color1_1, _vm->_color2_1, noFill ? -1 : _vm->_bkgColor_1);
}
+void GUI_Eob::memorizePrayMenuPrintString(int spellId, int bookPageIndex, int spellType, bool noFill, bool highLight) {
+ if (bookPageIndex < 0)
+ return;
+
+ int y = bookPageIndex * 9 + 50;
+
+ if (spellId) {
+ Common::String s(Common::String::format(_vm->_menuStringsMgc[0], spellType ? _vm->_clericSpellList[spellId] : _vm->_mageSpellList[spellId], _numAssignedSpellsOfType[spellId * 2 - 2]));
+ if (noFill)
+ _screen->printText(s.c_str(), 8, y, highLight ? 6 : 15, 0);
+ else
+ _screen->printShadedText(s.c_str(), 8, y, highLight ? 6 : 15, _vm->_bkgColor_1);
+
+ } else {
+ _screen->fillRect(6, y, 168, y + 8, _vm->_bkgColor_1);
+ }
+}
+
void GUI_Eob::updateOptionsStrings() {
for (int i = 0; i < 4; i++) {
delete _menuStringsPrefsTemp[i];