aboutsummaryrefslogtreecommitdiff
path: root/engines/kyra/gui_lol.cpp
diff options
context:
space:
mode:
authorFlorian Kagerer2009-02-21 17:24:50 +0000
committerFlorian Kagerer2009-02-21 17:24:50 +0000
commit8a95f02abfabb04972a6c85fbc655e53ae7a54f6 (patch)
tree66acc3d8e8b616b7f329888c8a529f922bfb370c /engines/kyra/gui_lol.cpp
parent51bb24626a422664684e1d70484944b7c9809557 (diff)
downloadscummvm-rg350-8a95f02abfabb04972a6c85fbc655e53ae7a54f6.tar.gz
scummvm-rg350-8a95f02abfabb04972a6c85fbc655e53ae7a54f6.tar.bz2
scummvm-rg350-8a95f02abfabb04972a6c85fbc655e53ae7a54f6.zip
LOL: some work on inventory/item handling
svn-id: r38711
Diffstat (limited to 'engines/kyra/gui_lol.cpp')
-rw-r--r--engines/kyra/gui_lol.cpp387
1 files changed, 372 insertions, 15 deletions
diff --git a/engines/kyra/gui_lol.cpp b/engines/kyra/gui_lol.cpp
index cdef2bcd30..8581b47d86 100644
--- a/engines/kyra/gui_lol.cpp
+++ b/engines/kyra/gui_lol.cpp
@@ -82,16 +82,14 @@ void LoLEngine::gui_drawInventoryItem(int index) {
static const uint16 inventoryXpos[] = { 0x6A, 0x7F, 0x94, 0xA9, 0xBE, 0xD3, 0xE8, 0xFD, 0x112 };
int x = inventoryXpos[index];
int item = _inventoryCurItem + index;
- if (item > 48)
+ if (item > 47)
item -= 48;
int flag = item & 1 ? 0 : 1;
- _screen->hideMouse();
_screen->drawShape(_screen->_curPage, _gameShapes[4], x, 179, 0, flag);
- if (_inventory[index])
- _screen->drawShape(_screen->_curPage, getItemIconShapePtr(_inventory[index]), x + 1, 180, 0, 0);
- _screen->showMouse();
+ if (_inventory[item])
+ _screen->drawShape(_screen->_curPage, getItemIconShapePtr(_inventory[item]), x + 1, 180, 0, 0);
}
void LoLEngine::gui_drawScroll() {
@@ -128,6 +126,198 @@ void LoLEngine::gui_highlightSelectedSpell(int unk) {
}
+void LoLEngine::gui_displayCharInventory(int charNum) {
+ static const uint8 inventoryTypes[] = { 0, 1, 2, 6, 3, 1, 1, 3, 5, 4 };
+
+ int cp = _screen->setCurPage(2);
+ LoLCharacter *l = &_characters[charNum];
+
+ int id = l->id;
+ if (id < 0)
+ id = -id;
+
+ if (id != _lastCharInventory) {
+ char file[13];
+ sprintf(file, "invent%d.cps", inventoryTypes[id]);
+ _screen->loadBitmap(file, 3, 3, 0);
+ _screen->copyRegion(0, 0, 112, 0, 208, 120, 2, 6);
+ } else {
+ _screen->copyRegion(112, 0, 0, 0, 208, 120, 6, 2);
+ }
+
+ _screen->copyRegion(80, 143, 80, 143, 232, 35, 0, 2);
+ gui_drawAllCharPortraitsWithStats();
+
+ _screen->fprintString(l->name, 157, 9, 254, 0, 5);
+
+ gui_printCharInventoryStats(charNum);
+
+ for (int i = 0; i < 11; i++)
+ gui_drawCharInventoryItem(i);
+
+ _screen->fprintString(getLangString(0x4033), 182, 103, 172, 0, 5);
+
+ static const uint16 skillFlags[] = { 0x0080, 0x0000, 0x1000, 0x0002, 0x100, 0x0001, 0x0000, 0x0000 };
+ uint16 tmp[6];
+ memset(tmp, -1, 6);
+ int x = 0;
+ int32 c = 0;
+
+ for (int i = 0; i < 3; i++) {
+ if (!(l->flags & skillFlags[i << 1]))
+ continue;
+
+ uint8 *shp = _gameShapes[skillFlags[(i << 1) + 1]];
+ _screen->drawShape(_screen->_curPage, shp, 108 + x, 98, 0, 0);
+ x += (shp[3] + 2);
+ tmp[c] = skillFlags[(i << 1) + 1];
+ c++;
+ }
+
+ for (int i = 0; i < 3; i++) {
+ int32 b = l->experiencePts[i] - _expRequirements[l->skillLevels[i] - 1];
+ int32 e = _expRequirements[l->skillLevels[i]] - _expRequirements[l->skillLevels[i] - 1];
+
+ while (e & 0xffff8000) {
+ e >>= 1;
+ c = b;
+ b >>= 1;
+
+ if (c && !b)
+ b = 1;
+ }
+
+ gui_drawBarGraph(154, 64 + i * 10, 34, 5, b, e, 132, 0);
+ }
+
+ _screen->drawClippedLine(14, 120, 194, 120, 1);
+ _screen->copyRegion(0, 0, 112, 0, 208, 121, 2, 0);
+ _screen->copyRegion(80, 143, 80, 143, 232, 35, 2, 0);
+
+ _screen->setCurPage(cp);
+}
+
+void LoLEngine::gui_printCharInventoryStats(int charNum) {
+ for (int i = 0; i < 5; i++)
+ gui_printCharacterStats(i, 1, calculateCharacterStats(charNum, i));
+
+ _charInventoryUnk |= (1 << charNum);
+}
+
+void LoLEngine::gui_printCharacterStats(int index, int redraw, int value) {
+ uint32 offs = _screen->_curPage ? 0 : 112;
+ int y = 0;
+ int col = 0;
+
+ if (index < 2) {
+ // might
+ // protection
+ y = index * 10 + 22;
+ col = 158;
+ if (redraw)
+ _screen->fprintString(getLangString(0x4014 + index), offs + 108, y, col, 0, 4);
+ } else {
+ //skills
+ int s = index - 2;
+ y = s * 10 + 62;
+ col = _characters[_selectedCharacter].flags & (0x200 << s) ? 254 : 180;
+ if (redraw)
+ _screen->fprintString(getLangString(0x4014 + index), offs + 108, y, col, 0, 4);
+ }
+
+ if (offs)
+ _screen->copyRegion(294, y, 182 + offs, y, 18, 8, 6, _screen->_curPage, Screen::CR_NO_P_CHECK);
+
+ _screen->fprintString("%d", 200 + offs, y, col, 0, 6, value);
+}
+
+void LoLEngine::gui_changeCharacterStats(int charNum) {
+ int tmp[5];
+ int inc[5];
+ bool prc = false;
+
+ for (int i = 0; i < 5; i++) {
+ tmp[i] = calculateCharacterStats(charNum, i);
+ int diff = tmp[i] - _charStatsTemp[i];
+ inc[i] = diff / 15;
+
+ if (diff) {
+ prc = true;
+ if (!inc[i])
+ inc[i] = (diff < 0) ? -1 : 1;
+ }
+ }
+
+ if (!prc)
+ return;
+
+ do {
+ prc = false;
+
+ for (int i = 0; i < 5; i++) {
+ if (tmp[i] == _charStatsTemp[i])
+ continue;
+
+ _charStatsTemp[i] += inc[i];
+
+ if ((inc[i] > 0 && tmp[i] < _charStatsTemp[i]) || (inc[i] < 0 && tmp[i] > _charStatsTemp[i]))
+ _charStatsTemp[i] = tmp[i];
+
+ gui_printCharacterStats(i, 0, _charStatsTemp[i]);
+ prc = true;
+ }
+
+ delay(_tickLength, true);
+
+ } while (prc);
+}
+
+void LoLEngine::gui_drawCharInventoryItem(int itemIndex) {
+ static const uint8 slotShapes[] = { 0x30, 0x34, 0x30, 0x34, 0x2E, 0x2F, 0x32, 0x33, 0x31, 0x35, 0x35 };
+
+ const int8 *coords = &_charInvDefs[_charInvIndex[_characters[_selectedCharacter].raceClassSex] * 22 + itemIndex * 2];
+ int8 x = *coords++;
+ int8 y = *coords;
+
+ if (y == -1)
+ return;
+
+ if (!_screen->_curPage)
+ x += 112;
+
+ int i = _characters[_selectedCharacter].items[itemIndex];
+ int shapeNum = i ? ((itemIndex < 9) ? 4 : 5) : slotShapes[itemIndex];
+ _screen->drawShape(_screen->_curPage, _gameShapes[shapeNum], x, y, 0, 0);
+
+ if (i)
+ _screen->drawShape(_screen->_curPage, getItemIconShapePtr(i), x + 1, y + 1, 0, 0);
+}
+
+void LoLEngine::gui_drawBarGraph(int x, int y, int w, int h, int32 cur, int32 max, int col1, int col2) {
+ if (max < 1)
+ return;
+ if (cur < 0)
+ cur = 0;
+
+ int32 e = MIN(cur, max);
+
+ if (!--w)
+ return;
+ if (!--h)
+ return;
+
+ int32 t = (e * w) / max;
+
+ if (!t && e)
+ t++;
+
+ if (t)
+ _screen->fillRect(x, y, x + t - 1, y + h, col1);
+
+ if (t < w && col2)
+ _screen->fillRect(x + t, y, x + w, y + h, col2);
+}
+
void LoLEngine::gui_drawAllCharPortraitsWithStats() {
int numChars = countActiveCharacters();
if (!numChars)
@@ -171,11 +361,11 @@ void LoLEngine::gui_drawCharPortraitWithStats(int charNum) {
// magic submenu closed
int handIndex = 0;
if (_characters[charNum].items[0]) {
- if (_itemProperties[_itemsInPlay[_characters[charNum].items[0]].itemPropertyIndex].unk8 != -1)
+ if (_itemProperties[_itemsInPlay[_characters[charNum].items[0]].itemPropertyIndex].might != -1)
handIndex = _itemsInPlay[_characters[charNum].items[0]].itemPropertyIndex;
}
- handIndex = _gameShapeMap[_itemProperties[handIndex].shpIndex << 1];
+ handIndex = _gameShapeMap[(_itemProperties[handIndex].shpIndex << 1) + 1];
if (handIndex == 0x5a) { // draw raceClassSex specific hand shape
handIndex = _characters[charNum].raceClassSex - 1;
if (handIndex < 0)
@@ -637,6 +827,13 @@ void LoLEngine::gui_enableSequenceButtons(int x, int y, int w, int h, int enable
gui_initButtonsFromList(_buttonList5);
}
+void LoLEngine::gui_enableCharInventoryButtons(int charNum) {
+ gui_resetButtonList();
+ gui_initButtonsFromList(_buttonList2);
+ gui_initCharInventorySpecialButtons(charNum);
+ gui_initCharacterControlButtons(21, 0);
+}
+
void LoLEngine::gui_resetButtonList() {
while (_activeButtons) {
Button *n = _activeButtons->nextButton;
@@ -659,6 +856,16 @@ void LoLEngine::gui_initCharacterControlButtons(int index, int xOffs) {
gui_initButton(index + i, _activeCharsXpos[i] + xOffs);
}
+void LoLEngine::gui_initCharInventorySpecialButtons(int charNum) {
+ const int8 *s = &_charInvDefs[_charInvIndex[_characters[charNum].raceClassSex] * 22];
+
+ for (int i = 0; i < 11; i++) {
+ if (*s != -1)
+ gui_initButton(33 + i, s[0], s[1], i);
+ s += 2;
+ }
+}
+
void LoLEngine::gui_initMagicScrollButtons() {
}
@@ -669,7 +876,7 @@ void LoLEngine::gui_initMagicSubmenu(int charNum) {
gui_initButtonsFromList(_buttonList7);
}
-void LoLEngine::gui_initButton(int index, int x) {
+void LoLEngine::gui_initButton(int index, int x, int y, int val) {
Button *b = new Button;
memset (b, 0, sizeof(Button));
@@ -703,7 +910,7 @@ void LoLEngine::gui_initButton(int index, int x) {
b->dimTableIndex = _buttonData[index].screenDim;
b->flags = _buttonData[index].buttonflags;
- b->data2Val2 = _buttonData[index].index;
+ b->data2Val2 = (val != -1) ? (uint8)(val & 0xff) : _buttonData[index].index;
if (index == 15) {
// magic sub menu
@@ -720,7 +927,7 @@ void LoLEngine::gui_initButton(int index, int x) {
b->height = _sceneWindowButton.h - 1;
} else {
b->x = x != -1 ? x : _buttonData[index].x;
- b->y = _buttonData[index].y;
+ b->y = y != -1 ? y : _buttonData[index].y;
b->width = _buttonData[index].w - 1;
b->height = _buttonData[index].h - 1;
}
@@ -877,6 +1084,21 @@ int LoLEngine::clickedScreen(Button *button) {
}
int LoLEngine::clickedPortraitLeft(Button *button) {
+ removeUnkFlags(2);
+
+ if (!_weaponsDisabled) {
+ _screen->copyRegionToBuffer(2, 0, 0, 320, 200, _pageBuffer2);
+ _screen->copyPage(0, 2);
+ _screen->copyRegionToBuffer(2, 0, 0, 320, 200, _pageBuffer1);
+ _updateFlags |= 0x0C;
+ gui_disableControls(1);
+ }
+
+ _selectedCharacter = button->data2Val2;
+ _weaponsDisabled = true;
+ gui_displayCharInventory(_selectedCharacter);
+ gui_enableCharInventoryButtons(_selectedCharacter);
+
return 1;
}
@@ -891,11 +1113,79 @@ int LoLEngine::clickedPortraitEtcRight(Button *button) {
return 1;
}
-int LoLEngine::clickedUnk14(Button *button) {
+int LoLEngine::clickedCharInventorySlot(Button *button) {
+ if (_itemInHand) {
+ uint16 sl = 1 << button->data2Val2;
+ int type = _itemProperties[_itemsInPlay[_itemInHand].itemPropertyIndex].type;
+ if (!(sl & type)) {
+ bool f = false;
+
+ for (int i = 0; i < 11; i++) {
+ if (!(type & (1 << i)))
+ continue;
+
+ _txt->printMessage(0, getLangString(i > 3 ? 0x418A : 0x418B), getLangString(_itemProperties[_itemsInPlay[_itemInHand].itemPropertyIndex].nameStringId), getLangString(_inventorySlotDesc[i]));
+ f = true;
+ }
+
+ if (!f)
+ _txt->printMessage(_itemsInPlay[_itemInHand].itemPropertyIndex == 231 ? 2 : 0, getLangString(0x418C));
+
+ return 1;
+ }
+ } else {
+ if (!_characters[_selectedCharacter].items[button->data2Val2]) {
+ _txt->printMessage(0, getLangString(_inventorySlotDesc[button->data2Val2] + 8));
+ return 1;
+ }
+ }
+
+ int ih = _itemInHand;
+
+ pickupItem(_characters[_selectedCharacter].items[button->data2Val2]);
+ _characters[_selectedCharacter].items[button->data2Val2] = ih;
+ gui_drawCharInventoryItem(button->data2Val2);
+
+ recalcCharacterStats(_selectedCharacter);
+
+ if (_itemInHand)
+ runItemScript(_selectedCharacter, _itemInHand, 0x100, 0, 0);
+ if (ih)
+ runItemScript(_selectedCharacter, ih, 0x80, 0, 0);
+
+ gui_drawCharInventoryItem(button->data2Val2);
+ gui_drawCharPortraitWithStats(_selectedCharacter);
+ gui_changeCharacterStats(_selectedCharacter);
+
return 1;
}
-int LoLEngine::clickedUnk15(Button *button) {
+int LoLEngine::clickedExitCharInventory(Button *button) {
+ _updateFlags &= 0xfff3;
+ gui_enableDefaultPlayfieldButtons();
+ _weaponsDisabled = false;
+
+ for (int i = 0; i < 4; i++) {
+ if (_charInventoryUnk & (1 << i))
+ _characters[i].flags &= 0xf1ff;
+ }
+
+ _screen->copyBlockToPage(2, 0, 0, 320, 200, _pageBuffer1);
+
+ int cp = _screen->setCurPage(2);
+ gui_drawAllCharPortraitsWithStats();
+ gui_drawInventory();
+ _screen->setCurPage(cp);
+
+ _screen->copyPage(2, 0);
+ _screen->updateScreen();
+ gui_enableControls();
+ _screen->copyBlockToPage(2, 0, 0, 320, 200, _pageBuffer2);
+
+ _lastCharInventory = -1;
+ updateSceneWindow();
+ setUnkFlags(2);
+
return 1;
}
@@ -903,21 +1193,88 @@ int LoLEngine::clickedUnk16(Button *button) {
return 1;
}
-int LoLEngine::clickedUnk17(Button *button) {
+int LoLEngine::clickedScene1(Button *button) {
+ if (_updateFlags & 1)
+ return 0;
+ int cp = _screen->setCurPage(_sceneDrawPage1);
+
+ _screen->setCurPage(cp);
+
return 1;
}
int LoLEngine::clickedInventorySlot(Button *button) {
+ int slot = _inventoryCurItem + button->data2Val2;
+ if (slot > 47)
+ slot -= 48;
+
+ uint16 slotItem = _inventory[slot];
+ int hItem = _itemInHand;
+
+ if ((_itemsInPlay[hItem].itemPropertyIndex == 281 || _itemsInPlay[slotItem].itemPropertyIndex == 281) &&
+ (_itemsInPlay[hItem].itemPropertyIndex == 220 || _itemsInPlay[slotItem].itemPropertyIndex == 220)) {
+ // merge ruby of truth
+
+ WSAMovie_v2 *wsa = new WSAMovie_v2(this, _screen);
+ wsa->open("truth.wsa", 0, 0);
+ wsa->setDrawPage(2);
+ wsa->setX(0);
+ wsa->setY(0);
+
+ _screen->hideMouse();
+
+ _inventory[slot] = 0;
+ gui_drawInventoryItem(button->data2Val2);
+ _screen->copyRegion(button->x, button->y - 3, button->x, button->y - 3, 25, 27, 0, 2);
+ KyraEngine_v1::snd_playSoundEffect(99);
+
+ for (int i = 0; i < 25; i++) {
+ _smoothScrollTimer = _system->getMillis() + 7 * _tickLength;
+ _screen->copyRegion(button->x, button->y - 3, 0, 0, 25, 27, 2, 2);
+ wsa->displayFrame(i, 0x4000);
+ _screen->copyRegion(0, 0, button->x, button->y - 3, 25, 27, 2, 0);
+ _screen->updateScreen();
+ delayUntil(_smoothScrollTimer);
+ }
+
+ _screen->showMouse();
+
+ wsa->close();
+ delete wsa;
+
+ deleteItem(slotItem);
+ deleteItem(hItem);
+
+ pickupItem(0);
+ _inventory[slot] = makeItem(280, 0, 0);
+ } else {
+ pickupItem(slotItem);
+ _inventory[slot] = hItem;
+ }
+
+ gui_drawInventoryItem(button->data2Val2);
+
return 1;
}
int LoLEngine::clickedInventoryScroll(Button *button) {
- int8 dir = (int8) button->data2Val2;
- int shp = (dir == 1) ? 75 : 74;
+ int8 inc = (int8)button->data2Val2;
+ int shp = (inc == 1) ? 75 : 74;
+ if (button->flags2 & 0x1000)
+ inc *= 9;
+
+ _inventoryCurItem += inc;
gui_toggleButtonDisplayMode(shp, 1);
+ if (_inventoryCurItem < 0)
+ _inventoryCurItem += 48;
+ if (_inventoryCurItem > 47)
+ _inventoryCurItem -= 48;
+
+ gui_drawInventory();
gui_toggleButtonDisplayMode(shp, 0);
+
return 1;
}