diff options
Diffstat (limited to 'engines/kyra/items_v2.cpp')
-rw-r--r-- | engines/kyra/items_v2.cpp | 467 |
1 files changed, 38 insertions, 429 deletions
diff --git a/engines/kyra/items_v2.cpp b/engines/kyra/items_v2.cpp index ee010b62e6..78768c70ab 100644 --- a/engines/kyra/items_v2.cpp +++ b/engines/kyra/items_v2.cpp @@ -24,12 +24,25 @@ */ #include "kyra/kyra_v2.h" +#include "kyra/screen_v2.h" namespace Kyra { +void KyraEngine_v2::initItemList(int size) { + debugC(9, kDebugLevelMain, "KyraEngine_v2::initItemList(%d)", size); + delete [] _itemList; + + _itemList = new Item[size]; + assert(_itemList); + memset(_itemList, 0, sizeof(Item)*size); + _itemListSize = size; + + resetItemList(); +} + int KyraEngine_v2::findFreeItem() { debugC(9, kDebugLevelMain, "KyraEngine_v2::findFreeItem()"); - for (int i = 0; i < 30; ++i) { + for (int i = 0; i < _itemListSize; ++i) { if (_itemList[i].id == 0xFFFF) return i; } @@ -39,7 +52,7 @@ int KyraEngine_v2::findFreeItem() { int KyraEngine_v2::countAllItems() { debugC(9, kDebugLevelMain, "KyraEngine_v2::countAllItems()"); int num = 0; - for (int i = 0; i < 30; ++i) { + for (int i = 0; i < _itemListSize; ++i) { if (_itemList[i].id != 0xFFFF) ++num; } @@ -48,435 +61,40 @@ int KyraEngine_v2::countAllItems() { int KyraEngine_v2::findItem(uint16 sceneId, uint16 id) { debugC(9, kDebugLevelMain, "KyraEngine_v2::findItem(%u, %u)", sceneId, id); - for (int i = 0; i < 30; ++i) { + for (int i = 0; i < _itemListSize; ++i) { if (_itemList[i].id == id && _itemList[i].sceneId == sceneId) return i; } return -1; } -int KyraEngine_v2::checkItemCollision(int x, int y) { - debugC(9, kDebugLevelMain, "KyraEngine_v2::checkItemCollision(%d, %d)", x, y); - int itemPos = -1, yPos = -1; - - for (int i = 0; i < 30; ++i) { - const Item &curItem = _itemList[i]; - - if (curItem.id == 0xFFFF || curItem.sceneId != _mainCharacter.sceneId) - continue; - - int itemX1 = curItem.x - 8 - 3; - int itemX2 = curItem.x + 7 + 3; - - if (x < itemX1 || x > itemX2) - continue; - - int itemY1 = curItem.y - _itemHtDat[curItem.id] - 3; - int itemY2 = curItem.y + 3; - - if (y < itemY1 || y > itemY2) - continue; - - if (curItem.y >= yPos) { - itemPos = i; - yPos = curItem.y; - } +int KyraEngine_v2::findItem(uint16 item) { + debugC(9, kDebugLevelMain, "KyraEngine_v2::findItem(%u)", item); + for (int i = 0; i < _itemListSize; ++i) { + if (_itemList[i].id == item) + return i; } - - return itemPos; + return -1; } void KyraEngine_v2::resetItemList() { debugC(9, kDebugLevelMain, "KyraEngine_v2::resetItemList()"); - for (int i = 0; i < 30; ++i) { - _itemList[i].id = 0xFFFF; - _itemList[i].sceneId = 0xFFFF; - _itemList[i].x = 0; - _itemList[i].y = 0; - _itemList[i].unk7 = 0; - } + for (int i = 0; i < _itemListSize; ++i) + resetItem(i); } -void KyraEngine_v2::updateWaterFlasks() { - debugC(9, kDebugLevelMain, "KyraEngine_v2::updateWaterFlasks()"); - for (int i = 22; i < 24; i++) { - if (_itemInHand == i) - setHandItem(i - 1); - - for (int ii = 0; ii < 20; ii++) { - if (_mainCharacter.inventory[ii] == i) { - _mainCharacter.inventory[ii]--; - if (ii < 10) { - clearInventorySlot(ii, 0); - _screen->drawShape(0, getShapePtr(i + 63), _inventoryX[ii], _inventoryY[ii], 0, 0); - } - } - } - - for (int ii = 0; ii < 30; ii++) { - if (_itemList[ii].id == i) - _itemList[ii].id--; - } - } -} - -bool KyraEngine_v2::dropItem(int unk1, uint16 item, int x, int y, int unk2) { - debugC(9, kDebugLevelMain, "KyraEngine_v2::dropItem(%d, %u, %d, %d, %d)", unk1, item, x, y, unk2); - if (_handItemSet <= -1) - return false; - - bool success = processItemDrop(_mainCharacter.sceneId, item, x, y, unk1, unk2); - if (!success) { - snd_playSoundEffect(0x0d); - if (countAllItems() >= 30) - showMessageFromCCode(5, 0x84, 0); - } - - return success; -} - -bool KyraEngine_v2::processItemDrop(uint16 sceneId, uint16 item, int x, int y, int unk1, int unk2) { - debugC(9, kDebugLevelMain, "KyraEngine_v2::processItemDrop(%u, %u, %d, %d, %d, %d)", sceneId, item, x, y, unk1, unk2); - int itemPos = checkItemCollision(x, y); - - if (unk1) - itemPos = -1; - - if (itemPos >= 0) { - exchangeMouseItem(itemPos); - return false; - } - - int freeItemSlot = -1; - - if (unk1 != 3) { - for (int i = 0; i < 30; ++i) { - if (_itemList[i].id == 0xFFFF) { - freeItemSlot = i; - break; - } - } - } - - if (freeItemSlot == -1) - return false; - - if (sceneId != _mainCharacter.sceneId) { - _itemList[freeItemSlot].x = x; - _itemList[freeItemSlot].y = y; - _itemList[freeItemSlot].id = item; - _itemList[freeItemSlot].unk7 = 1; - _itemList[freeItemSlot].sceneId = sceneId; - return true; - } - - int itemHeight = _itemHtDat[item]; - - // no idea why it's '&&' here and not single checks for x and y - if (x == -1 && y == -1) { - x = _rnd.getRandomNumberRng(0x10, 0x130); - y = _rnd.getRandomNumberRng(0x10, 0x87); - } - - int posX = x, posY = y; - int itemX = -1, itemY = -1; - bool needRepositioning = true; - - while (needRepositioning) { - if ((_screen->getDrawLayer(posX, posY) <= 1 && _screen->getDrawLayer2(posX, posY, itemHeight) <= 1 && isDropable(posX, posY)) || posY == 136) { - int posX2 = posX, posX3 = posX; - bool repositioning = true; - - while (repositioning) { - if (isDropable(posX3, posY) && _screen->getDrawLayer(posX3, posY) < 7 && checkItemCollision(posX3, posY) == -1) { - itemX = posX3; - itemY = posY; - needRepositioning = false; - repositioning = false; - } - - if (isDropable(posX2, posY) && _screen->getDrawLayer(posX2, posY) < 7 && checkItemCollision(posX2, posY) == -1) { - itemX = posX2; - itemY = posY; - needRepositioning = false; - repositioning = false; - } - - if (repositioning) { - posX3 = MAX(posX3 - 2, 16); - posX2 = MIN(posX2 + 2, 304); - - if (posX3 <= 16 && posX2 >= 304) - repositioning = false; - } - } - } - - if (posY == 136) - needRepositioning = false; - else - posY = MIN(posY + 2, 136); - } - - if (itemX == -1 || itemY == -1) - return false; - - if (unk1 == 3) { - _itemList[freeItemSlot].x = itemX; - _itemList[freeItemSlot].y = itemY; - return true; - } else if (unk1 == 2) { - itemDropDown(x, y, itemX, itemY, freeItemSlot, item); - } - - if (!unk1) - removeHandItem(); - - itemDropDown(x, y, itemX, itemY, freeItemSlot, item); - - if (!unk1 && unk2) { - int itemStr = 3; - if (_lang == 1) - itemStr = getItemCommandStringDrop(item); - updateCommandLineEx(item+54, itemStr, 0xD6); - } - - return true; -} - -void KyraEngine_v2::itemDropDown(int startX, int startY, int dstX, int dstY, int itemSlot, uint16 item) { - debugC(9, kDebugLevelMain, "KyraEngine_v2::itemDropDown(%d, %d, %d, %d, %d, %u)", startX, startY, dstX, dstY, itemSlot, item); - uint8 *itemShape = getShapePtr(item + 64); - - if (startX == dstX && startY == dstY) { - if (_layerFlagTable[_screen->getLayer(dstX, dstY)] && item != 13) { - updateCharFacing(); - snd_playSoundEffect(0x2d); - removeHandItem(); - objectChat(getTableString(0xFF, _cCodeBuffer, 1), 0, 0x83, 0xFF); - } else { - _itemList[itemSlot].x = dstX; - _itemList[itemSlot].y = dstY; - _itemList[itemSlot].id = item; - _itemList[itemSlot].sceneId = _mainCharacter.sceneId; - snd_playSoundEffect(0x0c); - addItemToAnimList(itemSlot); - } - } else { - _screen->hideMouse(); - - if (startY <= dstY) { - int speed = 2; - int curY = startY; - int curX = startX - 8; - - backUpGfxRect24x24(curX, curY-16); - while (curY < dstY) { - restoreGfxRect24x24(curX, curY-16); - - curY = MIN(curY + speed, dstY); - ++speed; - - backUpGfxRect24x24(curX, curY-16); - uint32 endDelay = _system->getMillis() + _tickLength; - - _screen->drawShape(0, itemShape, curX, curY-16, 0, 0); - _screen->updateScreen(); - - // XXX: original doesn't update game state while delaying - // our implementation *could* do it, so maybe check this again - delayUntil(endDelay); - } - - if (dstX != dstY || (dstY - startY > 16)) { - snd_playSoundEffect(0x69); - speed = MAX(speed, 6); - int speedX = ((dstX - startX) << 4) / speed; - int origSpeed = speed; - speed >>= 1; - - if (dstY - startY <= 8) - speed >>= 1; - - speed = -speed; - - curX = startX << 4; - - int x = 0, y = 0; - while (--origSpeed) { - x = (curX >> 4) - 8; - y = curY - 16; - - restoreGfxRect24x24(x, y); - curY = MIN(curY + speed, dstY); - curX += speedX; - ++speed; - - x = (curX >> 4) - 8; - y = curY - 16; - backUpGfxRect24x24(x, y); - - uint16 endDelay = _system->getMillis() + _tickLength; - _screen->drawShape(0, itemShape, x, y, 0, 0); - _screen->updateScreen(); - - // XXX: original doesn't update game state while delaying - // our implementation *could* do it, so maybe check this again - delayUntil(endDelay); - } - - restoreGfxRect24x24(x, y); - } else { - restoreGfxRect24x24(curX, curY-16); - } - } - - if (_layerFlagTable[_screen->getLayer(dstX, dstY)] && item != 13) { - updateCharFacing(); - snd_playSoundEffect(0x2d); - removeHandItem(); - _screen->showMouse(); - objectChat(getTableString(0xFF, _cCodeBuffer, 1), 0, 0x83, 0xFF); - } else { - _itemList[itemSlot].x = dstX; - _itemList[itemSlot].y = dstY; - _itemList[itemSlot].id = item; - _itemList[itemSlot].sceneId = _mainCharacter.sceneId; - snd_playSoundEffect(0x0c); - addItemToAnimList(itemSlot); - _screen->showMouse(); - } - } -} - -void KyraEngine_v2::exchangeMouseItem(int itemPos) { - debugC(9, kDebugLevelMain, "KyraEngine_v2::exchangeMouseItem(%d)", itemPos); - _screen->hideMouse(); - - deleteItemAnimEntry(itemPos); - - int itemId = _itemList[itemPos].id; - _itemList[itemPos].id = _itemInHand; - _itemInHand = itemId; - - addItemToAnimList(itemPos); - snd_playSoundEffect(0x0b); - setMouseCursor(_itemInHand); - int str2 = 7; - - if (_lang == 1) - str2 = getItemCommandStringPickUp(itemId); - - updateCommandLineEx(itemId + 54, str2, 0xD6); - _screen->showMouse(); - - runSceneScript6(); -} - -bool KyraEngine_v2::pickUpItem(int x, int y) { - debugC(9, kDebugLevelMain, "KyraEngine_v2::pickUpItem(%d, %d)", x, y); - int itemPos = checkItemCollision(x, y); - - if (itemPos <= -1) - return false; - - if (_itemInHand >= 0) { - exchangeMouseItem(itemPos); - } else { - _screen->hideMouse(); - deleteItemAnimEntry(itemPos); - int itemId = _itemList[itemPos].id; - _itemList[itemPos].id = 0xFFFF; - snd_playSoundEffect(0x0b); - setMouseCursor(itemId); - int str2 = 7; - - if (_lang == 1) - str2 = getItemCommandStringPickUp(itemId); - - updateCommandLineEx(itemId + 54, str2, 0xD6); - _itemInHand = itemId; - _screen->showMouse(); - - runSceneScript6(); - } - - return true; -} - -bool KyraEngine_v2::isDropable(int x, int y) { - debugC(9, kDebugLevelMain, "KyraEngine_v2::isDropable(%d, %d)", x, y); - if (x < 14 || x > 304 || y < 14 || y > 136) - return false; - - x -= 8; - y -= 1; - - for (int xpos = x; xpos < x + 16; ++xpos) { - if (_screen->getShapeFlag1(xpos, y) == 0) - return false; - } - - return true; -} - -int KyraEngine_v2::getItemCommandStringDrop(uint16 item) { - debugC(9, kDebugLevelMain, "KyraEngine_v2::getItemCommandStringDrop(%u)", item); - assert(item < _itemStringMapSize); - int stringId = _itemStringMap[item]; - - static const int dropStringIds[] = { - 0x2D, 0x103, 0x003, 0x106 - }; - assert(stringId < ARRAYSIZE(dropStringIds)); - - return dropStringIds[stringId]; -} - -int KyraEngine_v2::getItemCommandStringPickUp(uint16 item) { - debugC(9, kDebugLevelMain, "KyraEngine_v2::getItemCommandStringPickUp(%u)", item); - assert(item < _itemStringMapSize); - int stringId = _itemStringMap[item]; - - static const int pickUpStringIds[] = { - 0x02B, 0x102, 0x007, 0x105 - }; - assert(stringId < ARRAYSIZE(pickUpStringIds)); - - return pickUpStringIds[stringId]; -} - -int KyraEngine_v2::getItemCommandStringInv(uint16 item) { - debugC(9, kDebugLevelMain, "KyraEngine_v2::getItemCommandStringInv(%u)", item); - assert(item < _itemStringMapSize); - int stringId = _itemStringMap[item]; - - static const int pickUpStringIds[] = { - 0x02C, 0x104, 0x008, 0x107 - }; - assert(stringId < ARRAYSIZE(pickUpStringIds)); - - return pickUpStringIds[stringId]; -} - -void KyraEngine_v2::setMouseCursor(uint16 item) { - debugC(9, kDebugLevelMain, "KyraEngine_v2::setMouseCursor(%u)", item); - int shape = 0; - int hotX = 1; - int hotY = 1; - - if (item != 0xFFFF) { - hotX = 8; - hotY = 15; - shape = item+64; - } - - _screen->setMouseCursor(hotX, hotY, getShapePtr(shape)); +void KyraEngine_v2::resetItem(int index) { + debugC(9, kDebugLevelMain, "KyraEngine_v2::resetItem(%d)", index); + _itemList[index].id = 0xFFFF; + _itemList[index].sceneId = 0xFFFF; + _itemList[index].x = 0; + _itemList[index].y = 0; } void KyraEngine_v2::setHandItem(uint16 item) { debugC(9, kDebugLevelMain, "KyraEngine_v2::setHandItem(%u)", item); - _screen->hideMouse(); + Screen *scr = screen(); + scr->hideMouse(); if (item == 0xFFFF) { removeHandItem(); @@ -485,27 +103,18 @@ void KyraEngine_v2::setHandItem(uint16 item) { _itemInHand = item; } - _screen->showMouse(); + scr->showMouse(); } void KyraEngine_v2::removeHandItem() { debugC(9, kDebugLevelMain, "KyraEngine_v2::removeHandItem()"); - _screen->hideMouse(); - _screen->setMouseCursor(0, 0, _defaultShapeTable[0]); + Screen *scr = screen(); + scr->hideMouse(); + scr->setMouseCursor(0, 0, getShapePtr(0)); _itemInHand = -1; _handItemSet = -1; - _screen->showMouse(); -} - -bool KyraEngine_v2::itemIsFlask(int item) { - debugC(9, kDebugLevelMain, "KyraEngine_v2::itemIsFlask(%d)", item); - for (int i = 0; _flaskTable[i] != -1; ++i) { - if (_flaskTable[i] == item) - return true; - } - - return false; + scr->showMouse(); } -} // end of namespace Kyra +} // end of namesapce Kyra |