mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-14 13:58:01 +00:00
356 lines
8.3 KiB
C++
356 lines
8.3 KiB
C++
/* 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 "titanic/pet_control/pet_inventory_glyphs.h"
|
|
#include "titanic/pet_control/pet_control.h"
|
|
#include "titanic/pet_control/pet_inventory.h"
|
|
#include "titanic/messages/pet_messages.h"
|
|
#include "titanic/titanic.h"
|
|
|
|
namespace Titanic {
|
|
|
|
const uint ITEM_MODES[40] = {
|
|
0, 2, 11, 10, 12, 13, 9, 40, 7, 6,
|
|
4, 5, 8, 15, 19, 24, 25, 26, 30, 20,
|
|
21, 22, 23, 36, 39, 39, 31, 31, 32, 32,
|
|
33, 34, 35, 38, 41, 42, 43, 44, 45, 37
|
|
};
|
|
|
|
void CPetInventoryGlyph::enter() {
|
|
startRepeatedMovie();
|
|
}
|
|
|
|
void CPetInventoryGlyph::leave() {
|
|
stopMovie();
|
|
}
|
|
|
|
void CPetInventoryGlyph::drawAt(CScreenManager *screenManager, const Point &pt, bool isHighlighted_) {
|
|
if (!_active)
|
|
return;
|
|
|
|
if (_singular) {
|
|
if (_singular->hasActiveMovie()) {
|
|
if (isHighlighted_)
|
|
_singular->draw(screenManager);
|
|
else
|
|
_singular->draw(screenManager, pt);
|
|
return;
|
|
}
|
|
|
|
_singular = nullptr;
|
|
if (_repeated && isHighlighted_) {
|
|
_repeated->setPosition(pt);
|
|
startRepeatedMovie();
|
|
}
|
|
}
|
|
|
|
if (_repeated) {
|
|
if (isHighlighted_)
|
|
_repeated->draw(screenManager);
|
|
else
|
|
_repeated->draw(screenManager, pt);
|
|
} else if (_singular) {
|
|
_singular->draw(screenManager, pt, Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
|
|
}
|
|
}
|
|
|
|
|
|
void CPetInventoryGlyph::unhighlightCurrent() {
|
|
if (_singular) {
|
|
_singular->setPosition(Point(0, 0));
|
|
stopMovie();
|
|
} else if (_repeated) {
|
|
_repeated->setPosition(Point(0, 0));
|
|
_repeated->loadFrame(0);
|
|
stopMovie();
|
|
}
|
|
}
|
|
|
|
void CPetInventoryGlyph::highlightCurrent(const Point &pt) {
|
|
reposition(pt);
|
|
if (_item) {
|
|
CPETObjectSelectedMsg selectedMsg;
|
|
selectedMsg.execute(_item);
|
|
}
|
|
}
|
|
|
|
void CPetInventoryGlyph::glyphFocused(const Point &topLeft, bool flag) {
|
|
if (_repeated && flag)
|
|
_repeated->setPosition(topLeft);
|
|
}
|
|
|
|
bool CPetInventoryGlyph::dragGlyph(const Point &topLeft, CMouseDragStartMsg *msg) {
|
|
if (!_item)
|
|
return false;
|
|
|
|
if (_repeated) {
|
|
_active = false;
|
|
stopMovie();
|
|
}
|
|
|
|
CPetControl *petControl = getPetControl();
|
|
if (!petControl)
|
|
return false;
|
|
|
|
CGameObject *carryParcel = petControl->getHiddenObject("CarryParcel");
|
|
CGameObject *item = _item;
|
|
|
|
if (petControl->isSuccUBusActive() && carryParcel) {
|
|
petControl->removeFromInventory(_item, carryParcel, false, true);
|
|
petControl->removeFromInventory(_item, false, false);
|
|
|
|
carryParcel->setPosition(Point(msg->_mousePos.x - carryParcel->_bounds.width() / 2,
|
|
msg->_mousePos.y - carryParcel->_bounds.height() / 2));
|
|
carryParcel->setPosition(Point(SCREEN_WIDTH, SCREEN_HEIGHT));
|
|
item = carryParcel;
|
|
} else {
|
|
petControl->removeFromInventory(_item, false, true);
|
|
|
|
_item->setPosition(Point(msg->_mousePos.x - _item->_bounds.width() / 2,
|
|
msg->_mousePos.y - _item->_bounds.height() / 2));
|
|
_item->setVisible(true);
|
|
}
|
|
|
|
msg->_handled = true;
|
|
if (msg->execute(item)) {
|
|
_item = nullptr;
|
|
_repeated = nullptr;
|
|
_active = false;
|
|
petControl->setAreaChangeType(1);
|
|
return true;
|
|
} else {
|
|
petControl->addToInventory(item);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
void CPetInventoryGlyph::getTooltip(CTextControl *text) {
|
|
if (text) {
|
|
text->setText("");
|
|
|
|
if (_active && _item) {
|
|
int itemIndex = populateItem(_item, 0);
|
|
if (itemIndex >= 14 && itemIndex <= 18) {
|
|
// Variations of the chicken
|
|
CPETObjectStateMsg stateMsg(0);
|
|
stateMsg.execute(_item);
|
|
|
|
CString temperature = g_vm->_strings[stateMsg._value ? A_HOT : A_COLD];
|
|
text->setText(CString::format("%s %s", temperature.c_str(),
|
|
g_vm->_itemDescriptions[itemIndex].c_str()
|
|
));
|
|
|
|
} else {
|
|
text->setText(g_vm->_itemDescriptions[itemIndex]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
bool CPetInventoryGlyph::doAction(CGlyphAction *action) {
|
|
CInventoryGlyphAction *invAction = static_cast<CInventoryGlyphAction *>(action);
|
|
CPetInventoryGlyphs *owner = dynamic_cast<CPetInventoryGlyphs *>(_owner);
|
|
if (!invAction)
|
|
return false;
|
|
|
|
switch (invAction->getMode()) {
|
|
case ACTION_REMOVED:
|
|
if (invAction->_item == _item) {
|
|
_item = nullptr;
|
|
_repeated = nullptr;
|
|
_active = false;
|
|
}
|
|
break;
|
|
|
|
case ACTION_CHANGE:
|
|
if (_item == invAction->_item && _owner) {
|
|
int v = populateItem(_item, 0);
|
|
_repeated = owner->getBackground(v);
|
|
|
|
if (isHighlighted()) {
|
|
Point glyphPos = _owner->getHighlightedGlyphPos();
|
|
reposition(glyphPos);
|
|
updateTooltip();
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void CPetInventoryGlyph::setItem(CGameObject *item, bool isLoading) {
|
|
_item = item;
|
|
|
|
if (_owner && item) {
|
|
int idx = populateItem(item, isLoading);
|
|
_repeated = static_cast<CPetInventoryGlyphs *>(_owner)->getBackground(idx);
|
|
_singular = static_cast<CPetInventory *>(getPetSection())->getTransformAnimation(idx);
|
|
}
|
|
}
|
|
|
|
int CPetInventoryGlyph::populateItem(CGameObject *item, bool isLoading) {
|
|
// Scan the master item names list
|
|
CString itemName = item->getName();
|
|
int itemIndex = -1;
|
|
for (int idx = 0; idx < 40 && itemIndex == -1; ++idx) {
|
|
if (itemName == g_vm->_itemIds[idx])
|
|
itemIndex = idx;
|
|
}
|
|
if (itemIndex == -1)
|
|
return -1;
|
|
|
|
// Some objects can be in multiple different states. These are handled
|
|
// below to give each the correct inventory glyph and description
|
|
switch (ITEM_MODES[itemIndex]) {
|
|
case 0:
|
|
// Maitre d'Bot's left arm
|
|
switch (getItemIndex(item, isLoading)) {
|
|
case 0:
|
|
case 1:
|
|
return 0;
|
|
case 2:
|
|
case 3:
|
|
return 1;
|
|
default:
|
|
return 0;
|
|
}
|
|
|
|
case 2:
|
|
// Maitre d'Bot's right arm
|
|
switch (getItemIndex(item, isLoading)) {
|
|
case 0:
|
|
return 2;
|
|
default:
|
|
return 3;
|
|
}
|
|
break;
|
|
|
|
case 15:
|
|
// Chicken
|
|
switch (getItemIndex(item, isLoading)) {
|
|
case 0:
|
|
case 1:
|
|
return 14;
|
|
case 2:
|
|
return 16;
|
|
case 3:
|
|
return 15;
|
|
case 4:
|
|
return 17;
|
|
case 5:
|
|
return 18;
|
|
default:
|
|
return 15;
|
|
}
|
|
break;
|
|
|
|
case 26:
|
|
// Beer glass
|
|
switch (getItemIndex(item, isLoading)) {
|
|
case 0:
|
|
return 26;
|
|
case 1:
|
|
return 29;
|
|
case 2:
|
|
return 28;
|
|
case 3:
|
|
return 27;
|
|
default:
|
|
return 26;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return ITEM_MODES[itemIndex];
|
|
}
|
|
|
|
int CPetInventoryGlyph::getItemIndex(CGameObject *item, bool isLoading) {
|
|
int frameNum = item->getFrameNumber();
|
|
int movieFrame = item->getMovieFrame();
|
|
|
|
if (isLoading && frameNum != -1 && frameNum != movieFrame) {
|
|
item->loadFrame(frameNum);
|
|
movieFrame = frameNum;
|
|
}
|
|
|
|
return movieFrame;
|
|
}
|
|
|
|
void CPetInventoryGlyph::startRepeatedMovie() {
|
|
if (_owner) {
|
|
CPetInventory *section = dynamic_cast<CPetInventory *>(_owner->getOwner());
|
|
if (section)
|
|
section->playMovie(_repeated, true);
|
|
}
|
|
}
|
|
|
|
void CPetInventoryGlyph::startSingularMovie() {
|
|
if (_owner) {
|
|
CPetInventory *section = dynamic_cast<CPetInventory *>(_owner->getOwner());
|
|
if (section)
|
|
section->playMovie(_singular, false);
|
|
}
|
|
}
|
|
|
|
void CPetInventoryGlyph::stopMovie() {
|
|
if (_owner) {
|
|
CPetInventory *section = dynamic_cast<CPetInventory *>(_owner->getOwner());
|
|
if (section)
|
|
section->playMovie(nullptr);
|
|
}
|
|
}
|
|
|
|
void CPetInventoryGlyph::reposition(const Point &pt) {
|
|
if (_singular) {
|
|
// Special transformation of item to piece of Titania
|
|
_singular->setPosition(pt);
|
|
startSingularMovie();
|
|
} else if (_repeated) {
|
|
// Standard repeating animation
|
|
_repeated->setPosition(pt);
|
|
startRepeatedMovie();
|
|
}
|
|
}
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
|
|
bool CPetInventoryGlyphs::doAction(CInventoryGlyphAction *action) {
|
|
for (iterator i = begin(); i != end(); ++i) {
|
|
(*i)->doAction(action);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
CGameObject *CPetInventoryGlyphs::getBackground(int index) {
|
|
return _owner ? _owner->getBackground(index) : nullptr;
|
|
}
|
|
|
|
} // End of namespace Titanic
|