scummvm/engines/tony/inventory.cpp
2020-08-21 09:39:00 +02:00

936 lines
21 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.
*
*/
/*
* This code is based on original Tony Tough source code
*
* Copyright (c) 1997-2003 Nayma Software
*/
#include "common/textconsole.h"
#include "tony/mpal/mpalutils.h"
#include "tony/inventory.h"
#include "tony/game.h"
#include "tony/tony.h"
namespace Tony {
/****************************************************************************\
* RMInventory Methods
\****************************************************************************/
RMInventory::RMInventory() {
_items = NULL;
_state = CLOSED;
_bCombining = false;
_nItems = 0;
Common::fill(_inv, _inv + 256, 0);
_nInv = 0;
_curPutY = 0;
_curPutTime = 0;
_curPos = 0;
_bHasFocus = false;
_nSelectObj = 0;
_nCombine = 0;
_bBlinkingRight = false;
_bBlinkingLeft = false;
_miniAction = 0;
}
RMInventory::~RMInventory() {
close();
}
bool RMInventory::checkPointInside(const RMPoint &pt) {
if (!GLOBALS._bCfgInvUp)
return pt._y > RM_SY - 70;
else
return pt._y < 70;
}
void RMInventory::init() {
// Create the main buffer
create(RM_SX, 68);
setPriority(185);
// Setup the inventory
_nInv = 0;
_curPos = 0;
_bCombining = false;
// New items
_nItems = 78; // @@@ Number of takeable items
_items = new RMInventoryItem[_nItems + 1];
int curres = 10500;
// Loop through the items
for (int i = 0; i <= _nItems; i++) {
// Load the items from the resource
RMRes res(curres);
assert(res.isValid());
Common::SeekableReadStream *ds = res.getReadStream();
// Initialize the MPAL inventory item by reading it in.
_items[i]._icon.setInitCurPattern(false);
_items[i]._icon.readFromStream(*ds);
delete ds;
// Puts in the default pattern 1
_items[i]._pointer = NULL;
_items[i]._status = 1;
_items[i]._icon.setPattern(1);
_items[i]._icon.doFrame(this, false);
curres++;
if (i == 0 || i == 28 || i == 29)
continue;
_items[i]._pointer = new RMGfxSourceBuffer8RLEByteAA[_items[i]._icon.numPattern()];
for (int j = 0; j < _items[i]._icon.numPattern(); j++) {
RMResRaw raw(curres);
assert(raw.isValid());
_items[i]._pointer[j].init((const byte *)raw, raw.width(), raw.height(), true);
curres++;
}
}
_items[28]._icon.setPattern(1);
_items[29]._icon.setPattern(1);
// Download interface
RMRes res(RES_I_MINIINTER);
assert(res.isValid());
Common::SeekableReadStream *ds = res.getReadStream();
_miniInterface.readFromStream(*ds);
_miniInterface.setPattern(1);
delete ds;
// Create the text for hints on the mini interface
_hints[0].setAlignType(RMText::HCENTER, RMText::VTOP);
_hints[1].setAlignType(RMText::HCENTER, RMText::VTOP);
_hints[2].setAlignType(RMText::HCENTER, RMText::VTOP);
// The text is taken from MPAL for translation
RMMessage msg1(15);
RMMessage msg2(13);
RMMessage msg3(14);
_hints[0].writeText(msg1[0], 1); // Examine
_hints[1].writeText(msg2[0], 1); // Take
_hints[2].writeText(msg3[0], 1); // Use
// Prepare initial inventory
prepare();
drawOT(Common::nullContext);
clearOT();
}
void RMInventory::close() {
// Has memory
if (_items != NULL) {
// Delete the item pointers
for (int i = 0; i <= _nItems; i++)
delete[] _items[i]._pointer;
// Delete the items array
delete[] _items;
_items = NULL;
}
destroy();
}
void RMInventory::reset() {
_state = CLOSED;
endCombine();
}
void RMInventory::draw(CORO_PARAM, RMGfxTargetBuffer &bigBuf, RMGfxPrimitive *prim) {
CORO_BEGIN_CONTEXT;
RMPoint pos;
RMPoint pos2;
RMGfxPrimitive *p;
RMGfxPrimitive *p2;
CORO_END_CONTEXT(_ctx);
CORO_BEGIN_CODE(_ctx);
prim->setDst(RMPoint(0, _curPutY));
_csModifyInterface.lock();
CORO_INVOKE_2(RMGfxWoodyBuffer::draw, bigBuf, prim);
_csModifyInterface.unlock();
if (_state == SELECTING) {
if (!GLOBALS._bCfgInvUp) {
_ctx->pos.set((_nSelectObj + 1) * 64 - 20, RM_SY - 113);
_ctx->pos2.set((_nSelectObj + 1) * 64 + 34, RM_SY - 150);
} else {
_ctx->pos.set((_nSelectObj + 1) * 64 - 20, 72 - 4); // The brown part is at the top :(
_ctx->pos2.set((_nSelectObj + 1) * 64 + 34, 119 - 4);
}
_ctx->p = new RMGfxPrimitive(prim->_task, _ctx->pos);
_ctx->p2 = new RMGfxPrimitive(prim->_task, _ctx->pos2);
// Draw the mini interface
CORO_INVOKE_2(_miniInterface.draw, bigBuf, _ctx->p);
if (GLOBALS._bCfgInterTips) {
if (_miniAction == 1) // Examine
CORO_INVOKE_2(_hints[0].draw, bigBuf, _ctx->p2);
else if (_miniAction == 2) // Talk
CORO_INVOKE_2(_hints[1].draw, bigBuf, _ctx->p2);
else if (_miniAction == 3) // Use
CORO_INVOKE_2(_hints[2].draw, bigBuf, _ctx->p2);
}
delete _ctx->p;
delete _ctx->p2;
}
CORO_END_CODE;
}
void RMInventory::removeThis(CORO_PARAM, bool &result) {
if (_state == CLOSED)
result = true;
else
result = false;
}
void RMInventory::removeItem(int code) {
for (int i = 0; i < _nInv; i++) {
if (_inv[i] == code - 10000) {
_csModifyInterface.lock();
Common::copy(&_inv[i + 1], &_inv[i + 1] + (_nInv - i), &_inv[i]);
_nInv--;
prepare();
drawOT(Common::nullContext);
clearOT();
_csModifyInterface.unlock();
return;
}
}
}
void RMInventory::addItem(int code) {
if (code <= 10000 || code >= 10101) {
// If we are here, it means that we are adding an item that should not be in the inventory
warning("RMInventory::addItem(%d) - Cannot find a valid icon for this item, and then it will not be added to the inventory", code);
} else {
_csModifyInterface.lock();
if (_curPos + 8 == _nInv) {
// Break through the inventory! On the flashing pattern
_items[28]._icon.setPattern(2);
}
_inv[_nInv++] = code - 10000;
prepare();
drawOT(Common::nullContext);
clearOT();
_csModifyInterface.unlock();
}
}
void RMInventory::changeItemStatus(uint32 code, uint32 dwStatus) {
if (code <= 10000 || code >= 10101) {
error("RMInventory::changeItemStatus(%d) - Specified object code is not valid", code);
} else {
_csModifyInterface.lock();
_items[code - 10000]._icon.setPattern(dwStatus);
_items[code - 10000]._status = dwStatus;
prepare();
drawOT(Common::nullContext);
clearOT();
_csModifyInterface.unlock();
}
}
void RMInventory::prepare() {
for (int i = 1; i < RM_SX / 64 - 1; i++) {
if (i - 1 + _curPos < _nInv)
addPrim(new RMGfxPrimitive(&_items[_inv[i - 1 + _curPos]]._icon, RMPoint(i * 64, 0)));
else
addPrim(new RMGfxPrimitive(&_items[0]._icon, RMPoint(i * 64, 0)));
}
// Frecce
addPrim(new RMGfxPrimitive(&_items[29]._icon, RMPoint(0, 0)));
addPrim(new RMGfxPrimitive(&_items[28]._icon, RMPoint(640 - 64, 0)));
}
bool RMInventory::miniActive() {
return _state == SELECTING;
}
bool RMInventory::haveFocus(const RMPoint &mpos) {
// When we combine, have the focus only if we are on an arrow (to scroll)
if (_state == OPENED && _bCombining && checkPointInside(mpos) && (mpos._x < 64 || mpos._x > RM_SX - 64))
return true;
// If the inventory is open, focus we we go over it
if (_state == OPENED && !_bCombining && checkPointInside(mpos))
return true;
// If we are selecting a verb (and then right down), we always focus
if (_state == SELECTING)
return true;
return false;
}
void RMInventory::endCombine() {
_bCombining = false;
}
bool RMInventory::leftClick(const RMPoint &mpos, int &nCombineObj) {
// The left click picks an item from your inventory to use it with the background
int n = mpos._x / 64;
if (_state == OPENED) {
if (n > 0 && n < RM_SX / 64 - 1 && _inv[n - 1 + _curPos] != 0) {
_bCombining = true; //m_state = COMBINING;
_nCombine = _inv[n - 1 + _curPos];
nCombineObj = _nCombine + 10000;
g_vm->playUtilSFX(1);
return true;
}
}
// Click the right arrow
if ((_state == OPENED) && _bBlinkingRight) {
_csModifyInterface.lock();
_curPos++;
if (_curPos + 8 >= _nInv) {
_bBlinkingRight = false;
_items[28]._icon.setPattern(1);
}
if (_curPos > 0) {
_bBlinkingLeft = true;
_items[29]._icon.setPattern(2);
}
prepare();
drawOT(Common::nullContext);
clearOT();
_csModifyInterface.unlock();
}
// Click the left arrow
else if ((_state == OPENED) && _bBlinkingLeft) {
assert(_curPos > 0);
_csModifyInterface.lock();
_curPos--;
if (_curPos == 0) {
_bBlinkingLeft = false;
_items[29]._icon.setPattern(1);
}
if (_curPos + 8 < _nInv) {
_bBlinkingRight = true;
_items[28]._icon.setPattern(2);
}
prepare();
drawOT(Common::nullContext);
clearOT();
_csModifyInterface.unlock();
}
return false;
}
void RMInventory::rightClick(const RMPoint &mpos) {
assert(checkPointInside(mpos));
if (_state == OPENED && !_bCombining) {
// Open the context interface
int n = mpos._x / 64;
if (n > 0 && n < RM_SX / 64 - 1 && _inv[n - 1 + _curPos] != 0) {
_state = SELECTING;
_miniAction = 0;
_nSelectObj = n - 1;
g_vm->playUtilSFX(0);
}
}
if ((_state == OPENED) && _bBlinkingRight) {
_csModifyInterface.lock();
_curPos += 7;
if (_curPos + 8 > _nInv)
_curPos = _nInv - 8;
if (_curPos + 8 <= _nInv) {
_bBlinkingRight = false;
_items[28]._icon.setPattern(1);
}
if (_curPos > 0) {
_bBlinkingLeft = true;
_items[29]._icon.setPattern(2);
}
prepare();
drawOT(Common::nullContext);
clearOT();
_csModifyInterface.unlock();
} else if ((_state == OPENED) && _bBlinkingLeft) {
assert(_curPos > 0);
_csModifyInterface.lock();
_curPos -= 7;
if (_curPos < 0)
_curPos = 0;
if (_curPos == 0) {
_bBlinkingLeft = false;
_items[29]._icon.setPattern(1);
}
if (_curPos + 8 < _nInv) {
_bBlinkingRight = true;
_items[28]._icon.setPattern(2);
}
prepare();
drawOT(Common::nullContext);
clearOT();
_csModifyInterface.unlock();
}
}
bool RMInventory::rightRelease(const RMPoint &mpos, RMTonyAction &curAction) {
if (_state == SELECTING) {
_state = OPENED;
if (_miniAction == 1) { // Examine
curAction = TA_EXAMINE;
return true;
} else if (_miniAction == 2) { // Talk
curAction = TA_TALK;
return true;
} else if (_miniAction == 3) { // Use
curAction = TA_USE;
return true;
}
}
return false;
}
#define INVSPEED 20
void RMInventory::doFrame(RMGfxTargetBuffer &bigBuf, RMPointer &ptr, RMPoint mpos, bool bCanOpen) {
if (_state != CLOSED) {
// Clean up the OT list
_csModifyInterface.lock();
clearOT();
// DoFrame makes all the objects currently in the inventory be displayed
// @@@ Maybe we should do all takeable objects? Please does not help
bool bNeedRedraw = false;
for (int i = 0; i < _nInv; i++) {
if (_items[_inv[i]]._icon.doFrame(this, false) && (i >= _curPos && i <= _curPos + 7))
bNeedRedraw = true;
}
if ((_state == CLOSING || _state == OPENING || _state == OPENED) && checkPointInside(mpos)) {
if (mpos._x > RM_SX - 64) {
if (_curPos + 8 < _nInv && !_bBlinkingRight) {
_items[28]._icon.setPattern(3);
_bBlinkingRight = true;
bNeedRedraw = true;
}
} else if (_bBlinkingRight) {
_items[28]._icon.setPattern(2);
_bBlinkingRight = false;
bNeedRedraw = true;
}
if (mpos._x < 64) {
if (_curPos > 0 && !_bBlinkingLeft) {
_items[29]._icon.setPattern(3);
_bBlinkingLeft = true;
bNeedRedraw = true;
}
} else if (_bBlinkingLeft) {
_items[29]._icon.setPattern(2);
_bBlinkingLeft = false;
bNeedRedraw = true;
}
}
if (_items[28]._icon.doFrame(this, false))
bNeedRedraw = true;
if (_items[29]._icon.doFrame(this, false))
bNeedRedraw = true;
if (bNeedRedraw)
prepare();
_csModifyInterface.unlock();
}
if (g_vm->getEngine()->getInput().getAsyncKeyState(Common::KEYCODE_i)) {
GLOBALS._bCfgInvLocked = !GLOBALS._bCfgInvLocked;
}
if (_bCombining) { // m_state == COMBINING)
ptr.setCustomPointer(&_items[_nCombine]._pointer[_items[_nCombine]._status - 1]);
ptr.setSpecialPointer(RMPointer::PTR_CUSTOM);
}
if (!GLOBALS._bCfgInvUp) {
if ((_state == CLOSED) && (mpos._y > RM_SY - 10 || GLOBALS._bCfgInvLocked) && bCanOpen) {
if (!GLOBALS._bCfgInvNoScroll) {
_state = OPENING;
_curPutY = RM_SY - 1;
_curPutTime = g_vm->getTime();
} else {
_state = OPENED;
_curPutY = RM_SY - 68;
}
} else if (_state == OPENED) {
if ((mpos._y < RM_SY - 70 && !GLOBALS._bCfgInvLocked) || !bCanOpen) {
if (!GLOBALS._bCfgInvNoScroll) {
_state = CLOSING;
_curPutY = RM_SY - 68;
_curPutTime = g_vm->getTime();
} else {
_state = CLOSED;
}
}
} else if (_state == OPENING) {
while (_curPutTime + INVSPEED < g_vm->getTime()) {
_curPutY -= 3;
_curPutTime += INVSPEED;
}
if (_curPutY <= RM_SY - 68) {
_state = OPENED;
_curPutY = RM_SY - 68;
}
} else if (_state == CLOSING) {
while (_curPutTime + INVSPEED < g_vm->getTime()) {
_curPutY += 3;
_curPutTime += INVSPEED;
}
if (_curPutY > 480)
_state = CLOSED;
}
} else {
if ((_state == CLOSED) && (mpos._y < 10 || GLOBALS._bCfgInvLocked) && bCanOpen) {
if (!GLOBALS._bCfgInvNoScroll) {
_state = OPENING;
_curPutY = - 68;
_curPutTime = g_vm->getTime();
} else {
_state = OPENED;
_curPutY = 0;
}
} else if (_state == OPENED) {
if ((mpos._y > 70 && !GLOBALS._bCfgInvLocked) || !bCanOpen) {
if (!GLOBALS._bCfgInvNoScroll) {
_state = CLOSING;
_curPutY = -2;
_curPutTime = g_vm->getTime();
} else {
_state = CLOSED;
}
}
} else if (_state == OPENING) {
while (_curPutTime + INVSPEED < g_vm->getTime()) {
_curPutY += 3;
_curPutTime += INVSPEED;
}
if (_curPutY >= 0) {
_state = OPENED;
_curPutY = 0;
}
} else if (_state == CLOSING) {
while (_curPutTime + INVSPEED < g_vm->getTime()) {
_curPutY -= 3;
_curPutTime += INVSPEED;
}
if (_curPutY < -68)
_state = CLOSED;
}
}
if (_state == SELECTING) {
int startx = (_nSelectObj + 1) * 64 - 20;
int starty;
if (!GLOBALS._bCfgInvUp)
starty = RM_SY - 109;
else
starty = 70;
// Make sure it is on one of the verbs
if (mpos._y > starty && mpos._y < starty + 45) {
if (mpos._x > startx && mpos._x < startx + 40) {
if (_miniAction != 1) {
_miniInterface.setPattern(2);
_miniAction = 1;
g_vm->playUtilSFX(1);
}
} else if (mpos._x >= startx + 40 && mpos._x < startx + 80) {
if (_miniAction != 2) {
_miniInterface.setPattern(3);
_miniAction = 2;
g_vm->playUtilSFX(1);
}
} else if (mpos._x >= startx + 80 && mpos._x < startx + 108) {
if (_miniAction != 3) {
_miniInterface.setPattern(4);
_miniAction = 3;
g_vm->playUtilSFX(1);
}
} else {
_miniInterface.setPattern(1);
_miniAction = 0;
}
} else {
_miniInterface.setPattern(1);
_miniAction = 0;
}
// Update the mini-interface
_miniInterface.doFrame(&bigBuf, false);
}
if ((_state != CLOSED) && !_nInList) {
bigBuf.addPrim(new RMGfxPrimitive(this));
}
}
bool RMInventory::itemInFocus(const RMPoint &mpt) {
if ((_state == OPENED || _state == OPENING) && checkPointInside(mpt))
return true;
else
return false;
}
RMItem *RMInventory::whichItemIsIn(const RMPoint &mpt) {
if (_state == OPENED) {
if (checkPointInside(mpt)) {
int n = mpt._x / 64;
if (n > 0 && n < RM_SX / 64 - 1 && _inv[n - 1 + _curPos] != 0 && (!_bCombining || _inv[n - 1 + _curPos] != _nCombine))
return &_items[_inv[n - 1 + _curPos]]._icon;
}
}
return NULL;
}
int RMInventory::getSaveStateSize() {
// m_inv pattern m_nInv
return 256 * 4 + 256 * 4 + 4;
}
void RMInventory::saveState(byte *state) {
WRITE_LE_UINT32(state, _nInv);
state += 4;
for (int i = 0; i < 256; ++i) {
WRITE_LE_UINT32(state, _inv[i]);
state += 4;
}
int x;
for (int i = 0; i < 256; i++) {
if (i < _nItems)
x = _items[i]._status;
else
x = 0;
WRITE_LE_UINT32(state, x);
state += 4;
}
}
int RMInventory::loadState(byte *state) {
_nInv = READ_LE_UINT32(state);
state += 4;
for (int i = 0; i < 256; ++i) {
_inv[i] = READ_LE_UINT32(state);
state += 4;
}
for (int i = 0; i < 256; i++) {
int x = READ_LE_UINT32(state);
state += 4;
if (i < _nItems) {
_items[i]._status = x;
_items[i]._icon.setPattern(x);
}
}
_curPos = 0;
_bCombining = false;
_items[29]._icon.setPattern(1);
if (_nInv > 8)
_items[28]._icon.setPattern(2);
else
_items[28]._icon.setPattern(1);
prepare();
drawOT(Common::nullContext);
clearOT();
return getSaveStateSize();
}
RMInventory &RMInventory::operator+=(RMItem *item) {
addItem(item->mpalCode());
return *this;
}
RMInventory &RMInventory::operator+=(RMItem &item) {
addItem(item.mpalCode());
return *this;
}
RMInventory &RMInventory::operator+=(int code) {
addItem(code);
return *this;
}
/****************************************************************************\
* RMInterface methods
\****************************************************************************/
RMInterface::RMInterface() : RMGfxSourceBuffer8RLEByte() {
_bActive = _bPerorate = false;
_lastHotZone = -1;
}
RMInterface::~RMInterface() {
}
bool RMInterface::active() {
return _bActive;
}
int RMInterface::onWhichBox(RMPoint pt) {
pt -= _openStart;
// Check how many verbs you have to consider
int max = 4;
if (_bPerorate)
max = 5;
// Find the verb
for (int i = 0; i < max; i++) {
if (_hotbbox[i].ptInRect(pt))
return i;
}
// Found no verb
return -1;
}
void RMInterface::draw(CORO_PARAM, RMGfxTargetBuffer &bigBuf, RMGfxPrimitive *prim) {
CORO_BEGIN_CONTEXT;
int h;
CORO_END_CONTEXT(_ctx);
CORO_BEGIN_CODE(_ctx);
prim->getDst().topLeft() = _openStart;
CORO_INVOKE_2(RMGfxSourceBuffer8RLEByte::draw, bigBuf, prim);
// Check if there is a draw hot zone
_ctx->h = onWhichBox(_mpos);
if (_ctx->h != -1) {
prim->getDst().topLeft() = _openStart;
CORO_INVOKE_2(_hotzone[_ctx->h].draw, bigBuf, prim);
if (_lastHotZone != _ctx->h) {
_lastHotZone = _ctx->h;
g_vm->playUtilSFX(1);
}
if (GLOBALS._bCfgInterTips) {
prim->getDst().topLeft() = _openStart + RMPoint(70, 177);
CORO_INVOKE_2(_hints[_ctx->h].draw, bigBuf, prim);
}
} else
_lastHotZone = -1;
CORO_END_CODE;
}
void RMInterface::doFrame(RMGfxTargetBuffer &bigBuf, RMPoint mousepos) {
// If needed, add to the OT schedule list
if (!_nInList && _bActive)
bigBuf.addPrim(new RMGfxPrimitive(this));
_mpos = mousepos;
}
void RMInterface::clicked(const RMPoint &mousepos) {
_bActive = true;
_openPos = mousepos;
// Calculate the top left corner of the interface
_openStart = _openPos - RMPoint(_dimx / 2, _dimy / 2);
_lastHotZone = -1;
// Keep it inside the screen
if (_openStart._x < 0)
_openStart._x = 0;
if (_openStart._y < 0)
_openStart._y = 0;
if (_openStart._x + _dimx > RM_SX)
_openStart._x = RM_SX - _dimx;
if (_openStart._y + _dimy > RM_SY)
_openStart._y = RM_SY - _dimy;
// Play the sound effect
g_vm->playUtilSFX(0);
}
bool RMInterface::released(const RMPoint &mousepos, RMTonyAction &action) {
if (!_bActive)
return false;
_bActive = false;
switch (onWhichBox(mousepos)) {
case 0:
action = TA_TAKE;
break;
case 1:
action = TA_TALK;
break;
case 2:
action = TA_USE;
break;
case 3:
action = TA_EXAMINE;
break;
case 4:
action = TA_PERORATE;
break;
default: // No verb
return false;
}
return true;
}
void RMInterface::reset() {
_bActive = false;
}
void RMInterface::setPerorate(bool bOn) {
_bPerorate = bOn;
}
bool RMInterface::getPerorate() {
return _bPerorate;
}
void RMInterface::init() {
RMResRaw inter(RES_I_INTERFACE);
RMRes pal(RES_I_INTERPPAL);
setPriority(191);
RMGfxSourceBuffer::init(inter, inter.width(), inter.height());
loadPaletteWA(RES_I_INTERPAL);
for (int i = 0; i < 5; i++) {
RMResRaw part(RES_I_INTERP1 + i);
_hotzone[i].init(part, part.width(), part.height());
_hotzone[i].loadPaletteWA(pal);
}
_hotbbox[0].setRect(126, 123, 159, 208); // Take
_hotbbox[1].setRect(90, 130, 125, 186); // About
_hotbbox[2].setRect(110, 60, 152, 125);
_hotbbox[3].setRect(56, 51, 93, 99);
_hotbbox[4].setRect(51, 105, 82, 172);
_hints[0].setAlignType(RMText::HRIGHT, RMText::VTOP);
_hints[1].setAlignType(RMText::HRIGHT, RMText::VTOP);
_hints[2].setAlignType(RMText::HRIGHT, RMText::VTOP);
_hints[3].setAlignType(RMText::HRIGHT, RMText::VTOP);
_hints[4].setAlignType(RMText::HRIGHT, RMText::VTOP);
// The text is taken from MPAL for translation
RMMessage msg0(12);
RMMessage msg1(13);
RMMessage msg2(14);
RMMessage msg3(15);
RMMessage msg4(16);
_hints[0].writeText(msg0[0], 1); // Take
_hints[1].writeText(msg1[0], 1); // Talk
_hints[2].writeText(msg2[0], 1); // Use
_hints[3].writeText(msg3[0], 1); // Examine
_hints[4].writeText(msg4[0], 1); // Show Yourself
_bActive = false;
_bPerorate = false;
_lastHotZone = 0;
}
void RMInterface::close() {
destroy();
for (int i = 0; i < 5; i++)
_hotzone[i].destroy();
}
} // End of namespace Tony