diff options
Diffstat (limited to 'engines/fullpipe/inventory.cpp')
-rw-r--r-- | engines/fullpipe/inventory.cpp | 437 |
1 files changed, 437 insertions, 0 deletions
diff --git a/engines/fullpipe/inventory.cpp b/engines/fullpipe/inventory.cpp new file mode 100644 index 0000000000..18ef3c4d97 --- /dev/null +++ b/engines/fullpipe/inventory.cpp @@ -0,0 +1,437 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "fullpipe/fullpipe.h" + +#include "fullpipe/utils.h" +#include "fullpipe/inventory.h" +#include "fullpipe/gameloader.h" +#include "fullpipe/statics.h" +#include "fullpipe/input.h" + +namespace Fullpipe { + +bool Inventory::load(MfcArchive &file) { + debug(5, "Inventory::load()"); + + _sceneId = file.readUint16LE(); + int numInvs = file.readUint32LE(); + + for (int i = 0; i < numInvs; i++) { + InventoryPoolItem *t = new InventoryPoolItem(); + t->id = file.readUint16LE(); + t->pictureObjectNormal = file.readUint16LE(); + t->pictureObjectId1 = file.readUint16LE(); + t->pictureObjectHover = file.readUint16LE(); + t->pictureObjectSelected = file.readUint16LE(); + t->flags = file.readUint32LE(); + t->field_C = 0; + t->field_A = -536; + _itemsPool.push_back(t); + } + + return true; +} + +int Inventory::getInventoryPoolItemIndexById(int itemId) { + if (_itemsPool.size() <= 0) + return -1; + + for (uint i = 0; i < _itemsPool.size(); i++) { + if (_itemsPool[i]->id == itemId) + return i; + } + + return 0; +} + +bool Inventory::setItemFlags(int itemId, int flags) { + int idx = getInventoryPoolItemIndexById(itemId); + + if (idx < 0) + return false; + else + _itemsPool[idx]->flags = flags; + + return true; +} + +Inventory2::Inventory2() { + _selectedId = -1; + _field_48 = -1; + _scene = 0; + _picture = 0; + _isInventoryOut = false; + _isLocked = 0; + _topOffset = -65; +} + +bool Inventory2::loadPartial(MfcArchive &file) { // Inventory2_SerializePartially + int numInvs = file.readUint32LE(); + + for (int i = 0; i < numInvs; i++) { + InventoryItem *t = new InventoryItem(); + t->itemId = file.readUint16LE(); + t->count = file.readUint16LE(); + _inventoryItems.push_back(t); + } + + return true; +} + +void Inventory2::addItem(int itemId, int count) { + if (getInventoryPoolItemIndexById(itemId) >= 0) + _inventoryItems.push_back(new InventoryItem(itemId, count)); +} + +void Inventory2::addItem2(StaticANIObject *obj) { + if (getInventoryPoolItemIndexById(obj->_id) >= 0 && getInventoryPoolItemFieldCById(obj->_id) != 2) { + addItem(obj->_id, 1); + obj->hide(); + } +} + +void Inventory2::removeItem(int itemId, int count) { + warning("STUB: Inventory2::removeItem(%d, %d)", itemId, count); +} + +void Inventory2::removeItem2(Scene *sceneObj, int itemId, int x, int y, int priority) { + warning("STUB: void removeItem2(sc, %d, %d, %d, %d)", itemId, x, y, priority); +} + +int Inventory2::getCountItemsWithId(int itemId) { + int res = 0; + + for (uint i = 0; i < _inventoryItems.size(); i++) { + if (_inventoryItems[i]->itemId == itemId) + res += _inventoryItems[i]->count; + } + + return res; +} + +int Inventory2::getInventoryItemIndexById(int itemId) { + for (uint i = 0; i < _inventoryItems.size(); i++) { + if (_inventoryItems[i]->itemId == itemId) + return i; + } + + return -1; +} + +int Inventory2::getInventoryPoolItemIdAtIndex(int itemId) { + return _itemsPool[itemId]->id; +} + +int Inventory2::getInventoryPoolItemFieldCById(int itemId) { + for (uint i = 0; i < _itemsPool.size(); i++) { + if (_itemsPool[i]->id == itemId) + return _itemsPool[i]->field_C; + } + + return 0; +} + +int Inventory2::getItemFlags(int itemId) { + int idx = getInventoryPoolItemIndexById(itemId); + + if (idx < 0) + return 0; + + return _itemsPool[idx]->flags; +} + +void Inventory2::rebuildItemRects() { + _scene = g_fullpipe->accessScene(_sceneId); + + if (!_scene) + return; + + _picture = _scene->getBigPicture(0, 0); + _picture->setAlpha(50); + + int itemX = 9; + int itemY = 0; + + for (uint i = 0; i < _scene->_picObjList.size(); i++) { + PictureObject *pic = (PictureObject *)_scene->_picObjList[i]; + + for (uint j = 0; j < _itemsPool.size(); j++) { + if (_itemsPool[j]->pictureObjectNormal == pic->_id) { + if (pic->_okeyCode) + _scene->deletePictureObject(pic); + else + pic->_flags &= 0xFFFB; + } + } + } + + for (uint i = 0; i < _inventoryItems.size(); i++) { + Common::Point point; + + int idx = getInventoryPoolItemIndexById(_inventoryItems[i]->itemId); + + InventoryIcon *icn = new InventoryIcon(); + + icn->inventoryItemId = _itemsPool[idx]->id; + + icn->pictureObjectNormal = _scene->getPictureObjectById(_itemsPool[idx]->pictureObjectNormal, 0); + icn->pictureObjectHover = _scene->getPictureObjectById(_itemsPool[idx]->pictureObjectHover, 0); + icn->pictureObjectSelected = _scene->getPictureObjectById(_itemsPool[idx]->pictureObjectSelected, 0); + + icn->pictureObjectNormal->getDimensions(&point); + + if (_itemsPool[idx]->flags & 0x10000) { + icn->x1 = 730; + icn->y1 = itemY; + icn->x2 = point.x + 730; + icn->y2 = point.y + itemY + 10; + } else { + icn->x1 = itemX; + icn->y1 = itemY; + icn->x2 = itemX + point.x; + itemX = icn->x2 + 1; + icn->y2 = point.y + itemY + 10; + } + + _inventoryIcons.push_back(icn); + + if (itemX >= 2 * (icn->x1 - icn->x2) + 800) { + itemX = 9; + itemY = icn->y2 + 1; + } + } +} + +void Inventory2::draw() { + if (!_scene) + return; + + int oldScLeft = g_fullpipe->_sceneRect.left; + int oldScTop = g_fullpipe->_sceneRect.top; + + g_fullpipe->_sceneRect.top = -_topOffset; + g_fullpipe->_sceneRect.left = 0; + + _picture->draw(-1, -1, 0, 0); + + for (uint i = 0; i < _inventoryIcons.size(); i++) { + InventoryIcon *icn = _inventoryIcons[i]; + + if (icn->isSelected) { + icn->pictureObjectSelected->drawAt(icn->x1, icn->y1 + 10); + } else { + if (icn->isMouseHover) + icn->pictureObjectHover->drawAt(icn->x1, icn->y1 + 10); + else + icn->pictureObjectNormal->drawAt(icn->x1, icn->y1 + 10); + } + } + + if (!_isInventoryOut) + goto LABEL_30; + + int v10, v11, v12; + + if (_topOffset != -10) { + if (_topOffset < -10) { + v10 = -10; + goto LABEL_13; + } + if (_topOffset + 10 >= 20) { + v11 = -20; +cont: + _topOffset += v11; + goto reset; + } + v12 = -10; + goto LABEL_25; + } + if (!_isInventoryOut) { +LABEL_30: + if (_topOffset != -65) { + if (_topOffset < -65) { + v10 = -65; +LABEL_13: + v11 = v10 - _topOffset; + if (v11 >= 20) + v11 = 20; + goto cont; + } + if (_topOffset + 65 >= 20) { + v11 = -20; + goto cont; + } + v12 = -65; +LABEL_25: + v11 = v12 - _topOffset; + goto cont; + } + } + +reset: + + g_fullpipe->_sceneRect.top = oldScTop; + g_fullpipe->_sceneRect.left = oldScLeft; + +} + +void Inventory2::slideIn() { + _isInventoryOut = false; + + ExCommand *ex = new ExCommand(0, 17, 65, 0, 0, 0, 1, 0, 0, 0); + + ex->_field_2C = 10; + ex->_field_14 = _isInventoryOut; + ex->_field_20 = !_isInventoryOut; + ex->_excFlags |= 3; + ex->postMessage(); +} + +void Inventory2::slideOut() { + _isInventoryOut = true; + + ExCommand *ex = new ExCommand(0, 17, 65, 0, 0, 0, 1, 0, 0, 0); + + ex->_field_2C = 10; + ex->_field_14 = _isInventoryOut; + ex->_field_20 = !_isInventoryOut; + ex->_excFlags |= 3; + ex->postMessage(); +} + +bool Inventory2::handleLeftClick(ExCommand *cmd) { + if (!_isInventoryOut) + return false; + + bool res = false; + + for (uint i = 0; i < _inventoryIcons.size(); i++) { + if (cmd->_x >= _inventoryIcons[i]->x1 && cmd->_x <= _inventoryIcons[i]->x2 && + cmd->_y >= _inventoryIcons[i]->y1 && cmd->_y <= _inventoryIcons[i]->y2) { + if (getSelectedItemId()) { + if (getSelectedItemId() != _inventoryIcons[i]->inventoryItemId) + unselectItem(0); + } + if (getItemFlags(_inventoryIcons[i]->inventoryItemId) & 1) { + ExCommand *ex = new ExCommand(0, 17, 65, 0, 0, 0, 1, 0, 0, 0); + ex->_field_2C = 11; + ex->_field_14 = _inventoryIcons[i]->inventoryItemId; + ex->_excFlags |= 3; + ex->postMessage(); + } + if (!(getItemFlags(_inventoryIcons[i]->inventoryItemId) & 2)) { + selectItem(_inventoryIcons[i]->inventoryItemId); + _inventoryIcons[i]->isSelected = true; + } + res = true; + } + } + + if (!res) + unselectItem(0); + + return res; +} + +int Inventory2::selectItem(int itemId) { + if (getInventoryItemIndexById(itemId) < 0) + return -1; + + unselectItem(0); + + _selectedId = itemId; + + if (_scene) { + int idx = getInventoryPoolItemIndexById(itemId); + + Picture *pic = _scene->getPictureObjectById(_itemsPool[idx]->pictureObjectId1, 0)->_picture; + g_fullpipe->getGameLoaderInputController()->setCursorItemPicture(pic); + } + + return _selectedId; +} + +bool Inventory2::unselectItem(bool flag) { + if (_selectedId < 0) + return false; + + _selectedId = -1; + + for (uint i = 0; i < _inventoryIcons.size(); i++) { + if (_inventoryIcons[i]->isSelected) + _inventoryIcons[i]->isSelected = false; + } + + g_fullpipe->getGameLoaderInputController()->setCursorItemPicture(0); + + return true; +} + +int Inventory2::getHoveredItem(Common::Point *point) { + int selId = getSelectedItemId(); + + if (point->y <= 20 && !_isInventoryOut && !_isLocked) + slideOut(); + + if (!selId && point->y >= 55) { + if (!_isInventoryOut) + return 0; + + if (!_isLocked) + slideIn(); + } + + if (!_isInventoryOut) + return 0; + + for (uint i = 0; i < _inventoryIcons.size(); i++) { + InventoryIcon *icn = _inventoryIcons[i]; + if (selId || + point->x < icn->x1 || + point->x > icn->x2 || + point->y < _topOffset + icn->y1 || + point->y > _topOffset + icn->y2) { + icn->isMouseHover = false; + } else { + icn->isMouseHover = true; + return icn->inventoryItemId; + } + } + + return 0; +} + +void FullpipeEngine::getAllInventory() { + Inventory2 *inv = getGameLoaderInventory(); + + for (uint i = 0; i < inv->getItemsPoolCount(); ++i ) { + int id = inv->getInventoryPoolItemIdAtIndex(i); + + if (inv->getCountItemsWithId(id) < 1) + inv->addItem(id, 1); + } + + inv->rebuildItemRects(); +} + +} // End of namespace Fullpipe |