mirror of
https://github.com/libretro/scummvm.git
synced 2025-03-04 09:18:38 +00:00
SHERLOCK: RT: Implement inventory handleEvents
This commit is contained in:
parent
371d5e1d90
commit
3adaf2f999
@ -62,7 +62,11 @@ struct InventoryItem {
|
||||
Common::String _examine;
|
||||
int _lookFlag;
|
||||
|
||||
InventoryItem() : _requiredFlag(0), _lookFlag(0) {}
|
||||
// Rose Tattoo fields
|
||||
int _requiredFlag1;
|
||||
UseType _verb;
|
||||
|
||||
InventoryItem() : _requiredFlag(0), _lookFlag(0), _requiredFlag1(0) {}
|
||||
InventoryItem(int requiredFlag, const Common::String &name,
|
||||
const Common::String &description, const Common::String &examine);
|
||||
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "sherlock/tattoo/tattoo.h"
|
||||
#include "sherlock/tattoo/tattoo_resources.h"
|
||||
#include "sherlock/tattoo/tattoo_scene.h"
|
||||
#include "sherlock/tattoo/widget_base.h"
|
||||
#include "sherlock/people.h"
|
||||
|
||||
namespace Sherlock {
|
||||
@ -38,6 +39,10 @@ TattooEngine::TattooEngine(OSystem *syst, const SherlockGameDescription *gameDes
|
||||
_allowFastMode = true;
|
||||
}
|
||||
|
||||
TattooEngine::~TattooEngine() {
|
||||
WidgetBase::freeInterfaceImages();
|
||||
}
|
||||
|
||||
void TattooEngine::showOpening() {
|
||||
// TODO
|
||||
}
|
||||
@ -48,6 +53,9 @@ void TattooEngine::initialize() {
|
||||
// Initialize the base engine
|
||||
SherlockEngine::initialize();
|
||||
|
||||
// Further initialization
|
||||
WidgetBase::setInterfaceImages(new ImageFile("intrface.vgs"));
|
||||
|
||||
// Initialise the global flags
|
||||
_flags.resize(3200);
|
||||
_flags[1] = _flags[4] = _flags[76] = true;
|
||||
@ -105,6 +113,10 @@ void TattooEngine::eraseCredits() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void TattooEngine::doHangManPuzzle() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
} // End of namespace Tattoo
|
||||
|
||||
} // End of namespace Sherlock
|
||||
|
@ -59,7 +59,7 @@ public:
|
||||
bool _fastMode, _allowFastMode;
|
||||
public:
|
||||
TattooEngine(OSystem *syst, const SherlockGameDescription *gameDesc);
|
||||
virtual ~TattooEngine() {}
|
||||
virtual ~TattooEngine();
|
||||
|
||||
/**
|
||||
* Draw credits on the screen
|
||||
@ -75,6 +75,8 @@ public:
|
||||
* Erase any area of the screen covered by credits
|
||||
*/
|
||||
void eraseCredits();
|
||||
|
||||
void doHangManPuzzle();
|
||||
};
|
||||
|
||||
} // End of namespace Tattoo
|
||||
|
@ -306,7 +306,6 @@ void TattooMap::drawMapIcons() {
|
||||
|
||||
void TattooMap::checkMapNames(bool slamIt) {
|
||||
Events &events = *_vm->_events;
|
||||
Screen &screen = *_vm->_screen;
|
||||
Common::Point mousePos = events.mousePos() + _currentScroll;
|
||||
|
||||
// See if the mouse is pointing at any of the map locations
|
||||
|
@ -575,7 +575,7 @@ void TattooUserInterface::doFileControl() {
|
||||
}
|
||||
|
||||
void TattooUserInterface::doInventoryControl() {
|
||||
warning("TODO: ui control (inventory)");
|
||||
_inventoryWidget.handleEvents();
|
||||
}
|
||||
|
||||
void TattooUserInterface::doVerbControl() {
|
||||
@ -644,6 +644,10 @@ void TattooUserInterface::freeMenu() {
|
||||
}
|
||||
}
|
||||
|
||||
void TattooUserInterface::putMessage(const Common::String &str) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
} // End of namespace Tattoo
|
||||
|
||||
} // End of namespace Sherlock
|
||||
|
@ -188,6 +188,8 @@ public:
|
||||
* Pick up the selected object
|
||||
*/
|
||||
void pickUpObject(int objNum);
|
||||
|
||||
void putMessage(const Common::String &str);
|
||||
public:
|
||||
/**
|
||||
* Resets the user interface
|
||||
|
@ -29,8 +29,18 @@ namespace Sherlock {
|
||||
|
||||
namespace Tattoo {
|
||||
|
||||
ImageFile *WidgetBase::_interfaceImages;
|
||||
|
||||
void WidgetBase::setInterfaceImages(ImageFile *images) {
|
||||
_interfaceImages = images;
|
||||
}
|
||||
|
||||
void WidgetBase::freeInterfaceImages() {
|
||||
delete _interfaceImages;
|
||||
_interfaceImages = nullptr;
|
||||
}
|
||||
|
||||
WidgetBase::WidgetBase(SherlockEngine *vm) : _vm(vm) {
|
||||
_images = nullptr;
|
||||
}
|
||||
|
||||
void WidgetBase::summonWindow() {
|
||||
@ -135,32 +145,38 @@ void WidgetBase::checkMenuPosition() {
|
||||
_bounds.moveTo(_bounds.left, SHERLOCK_SCREEN_HEIGHT - _bounds.height());
|
||||
}
|
||||
|
||||
void WidgetBase::makeInfoArea() {
|
||||
void WidgetBase::makeInfoArea(Surface &s) {
|
||||
ImageFile &images = *_interfaceImages;
|
||||
|
||||
// Draw the four corners of the Info Box
|
||||
_surface.transBlitFrom((*_images)[0], Common::Point(0, 0));
|
||||
_surface.transBlitFrom((*_images)[1], Common::Point(_bounds.width() - (*_images)[1]._width, 0));
|
||||
_surface.transBlitFrom((*_images)[2], Common::Point(0, _bounds.height() - (*_images)[2]._height));
|
||||
_surface.transBlitFrom((*_images)[3], Common::Point(_bounds.width() - (*_images)[3]._width, _bounds.height()));
|
||||
s.transBlitFrom(images[0], Common::Point(0, 0));
|
||||
s.transBlitFrom(images[1], Common::Point(s.w() - images[1]._width, 0));
|
||||
s.transBlitFrom(images[2], Common::Point(0, s.h() - images[2]._height));
|
||||
s.transBlitFrom(images[3], Common::Point(s.w() - images[3]._width, s.h()));
|
||||
|
||||
// Draw the top of the Info Box
|
||||
_surface.hLine((*_images)[0]._width, 0, _bounds.width() - (*_images)[1]._width, INFO_TOP);
|
||||
_surface.hLine((*_images)[0]._width, 1, _bounds.width() - (*_images)[1]._width, INFO_MIDDLE);
|
||||
_surface.hLine((*_images)[0]._width, 2, _bounds.width() - (*_images)[1]._width, INFO_BOTTOM);
|
||||
s.hLine(images[0]._width, 0, s.w() - images[1]._width, INFO_TOP);
|
||||
s.hLine(images[0]._width, 1, s.w() - images[1]._width, INFO_MIDDLE);
|
||||
s.hLine(images[0]._width, 2, s.w() - images[1]._width, INFO_BOTTOM);
|
||||
|
||||
// Draw the bottom of the Info Box
|
||||
_surface.hLine((*_images)[0]._width, _bounds.height()- 3, _bounds.width() - (*_images)[1]._width, INFO_TOP);
|
||||
_surface.hLine((*_images)[0]._width, _bounds.height()- 2, _bounds.width() - (*_images)[1]._width, INFO_MIDDLE);
|
||||
_surface.hLine((*_images)[0]._width, _bounds.height()- 1, _bounds.width() - (*_images)[1]._width, INFO_BOTTOM);
|
||||
s.hLine(images[0]._width, s.h()- 3, s.w() - images[1]._width, INFO_TOP);
|
||||
s.hLine(images[0]._width, s.h()- 2, s.w() - images[1]._width, INFO_MIDDLE);
|
||||
s.hLine(images[0]._width, s.h()- 1, s.w() - images[1]._width, INFO_BOTTOM);
|
||||
|
||||
// Draw the left Side of the Info Box
|
||||
_surface.vLine(0, (*_images)[0]._height, _bounds.height()- (*_images)[2]._height, INFO_TOP);
|
||||
_surface.vLine(1, (*_images)[0]._height, _bounds.height()- (*_images)[2]._height, INFO_MIDDLE);
|
||||
_surface.vLine(2, (*_images)[0]._height, _bounds.height()- (*_images)[2]._height, INFO_BOTTOM);
|
||||
s.vLine(0, images[0]._height, s.h()- images[2]._height, INFO_TOP);
|
||||
s.vLine(1, images[0]._height, s.h()- images[2]._height, INFO_MIDDLE);
|
||||
s.vLine(2, images[0]._height, s.h()- images[2]._height, INFO_BOTTOM);
|
||||
|
||||
// Draw the right Side of the Info Box
|
||||
_surface.vLine(_bounds.width() - 3, (*_images)[0]._height, _bounds.height()- (*_images)[2]._height, INFO_TOP);
|
||||
_surface.vLine(_bounds.width() - 2, (*_images)[0]._height, _bounds.height()- (*_images)[2]._height, INFO_MIDDLE);
|
||||
_surface.vLine(_bounds.width() - 1, (*_images)[0]._height, _bounds.height()- (*_images)[2]._height, INFO_BOTTOM);
|
||||
s.vLine(s.w() - 3, images[0]._height, s.h()- images[2]._height, INFO_TOP);
|
||||
s.vLine(s.w() - 2, images[0]._height, s.h()- images[2]._height, INFO_MIDDLE);
|
||||
s.vLine(s.w() - 1, images[0]._height, s.h()- images[2]._height, INFO_BOTTOM);
|
||||
}
|
||||
|
||||
void WidgetBase::makeInfoArea() {
|
||||
makeInfoArea(_surface);
|
||||
}
|
||||
|
||||
const Common::Point &WidgetBase::getCurrentScroll() const {
|
||||
@ -168,6 +184,9 @@ const Common::Point &WidgetBase::getCurrentScroll() const {
|
||||
return ui._currentScroll;
|
||||
}
|
||||
|
||||
void WidgetBase::checkTabbingKeys(int numOptions) {
|
||||
}
|
||||
|
||||
} // End of namespace Tattoo
|
||||
|
||||
} // End of namespace Sherlock
|
||||
|
@ -38,11 +38,12 @@ namespace Tattoo {
|
||||
class WidgetBase {
|
||||
private:
|
||||
Common::Rect _oldBounds;
|
||||
protected:
|
||||
static ImageFile *_interfaceImages;
|
||||
protected:
|
||||
SherlockEngine *_vm;
|
||||
Common::Rect _bounds;
|
||||
Surface _surface;
|
||||
ImageFile *_images;
|
||||
bool _outsideMenu;
|
||||
|
||||
/**
|
||||
@ -55,12 +56,30 @@ protected:
|
||||
*/
|
||||
void checkMenuPosition();
|
||||
|
||||
/**
|
||||
* Draw a window frame around the dges of the passed surface
|
||||
*/
|
||||
void makeInfoArea(Surface &s);
|
||||
|
||||
/**
|
||||
* Draw a window frame around the widget's surface
|
||||
*/
|
||||
void makeInfoArea();
|
||||
|
||||
/**
|
||||
* Returns the current scroll position
|
||||
*/
|
||||
virtual const Common::Point &getCurrentScroll() const;
|
||||
public:
|
||||
/**
|
||||
* Sets the interface images used for drawing the various types of window elements
|
||||
*/
|
||||
static void setInterfaceImages(ImageFile *images);
|
||||
|
||||
/**
|
||||
* Frees the interface images
|
||||
*/
|
||||
static void freeInterfaceImages();
|
||||
public:
|
||||
WidgetBase(SherlockEngine *vm);
|
||||
virtual ~WidgetBase() {}
|
||||
@ -75,6 +94,11 @@ public:
|
||||
*/
|
||||
void draw();
|
||||
|
||||
/**
|
||||
* Used by some descendents to check for keys to mouse the mouse within the dialog
|
||||
*/
|
||||
void checkTabbingKeys(int numOptions);
|
||||
|
||||
/**
|
||||
* Summon the window
|
||||
*/
|
||||
|
@ -21,6 +21,7 @@
|
||||
*/
|
||||
|
||||
#include "sherlock/tattoo/widget_inventory.h"
|
||||
#include "sherlock/tattoo/tattoo_scene.h"
|
||||
#include "sherlock/tattoo/tattoo_user_interface.h"
|
||||
#include "sherlock/tattoo/tattoo.h"
|
||||
|
||||
@ -31,14 +32,26 @@ namespace Tattoo {
|
||||
#define INVENTORY_XSIZE 70 // Width of the box that surrounds inventory items
|
||||
#define INVENTORY_YSIZE 70 // Height of the box that surrounds inventory items
|
||||
#define NUM_INVENTORY_SHOWN 8 // Number of Inventory Items Shown
|
||||
#define MAX_INV_COMMANDS 10 // Maximum elements in dialog
|
||||
#define BUTTON_SIZE 15 // Button width/height
|
||||
|
||||
WidgetInventory::WidgetInventory(SherlockEngine *vm) : WidgetBase(vm) {
|
||||
// TODO: Refactor into FixedText
|
||||
#define S_INV6 "Foolscap"
|
||||
#define S_INV7 "Damp Paper"
|
||||
#define S_SOLVE "Solve"
|
||||
#define S_LOOK "Look"
|
||||
#define S_NO_EFFECT "No effect..."
|
||||
#define S_WITH "with"
|
||||
|
||||
WidgetInventory::WidgetInventory(SherlockEngine *vm) : WidgetBase(vm), _tooltipWidget(vm) {
|
||||
_invMode = 0;
|
||||
_invVerbMode = 0;
|
||||
_invSelect = _oldInvSelect = 0;
|
||||
_selector = _oldSelector = 0;
|
||||
_invVerbSelect = _oldInvVerbSelect = -1;
|
||||
_dialogTimer = -1;
|
||||
_scrollHighlight = 0;
|
||||
_swapItems = false;
|
||||
}
|
||||
|
||||
void WidgetInventory::load(int mode) {
|
||||
@ -72,7 +85,7 @@ void WidgetInventory::load(int mode) {
|
||||
_surface.fill(TRANSPARENCY);
|
||||
|
||||
// Draw the window background and then the inventory on top of it
|
||||
makeInfoArea();
|
||||
makeInfoArea(_surface);
|
||||
drawInventory();
|
||||
}
|
||||
|
||||
@ -187,6 +200,354 @@ void WidgetInventory::drawDialogRect(const Common::Rect &r, bool raised) {
|
||||
}
|
||||
}
|
||||
|
||||
void WidgetInventory::handleEvents() {
|
||||
TattooEngine &vm = *(TattooEngine *)_vm;
|
||||
Events &events = *_vm->_events;
|
||||
Inventory &inv = *_vm->_inventory;
|
||||
People &people = *_vm->_people;
|
||||
TattooScene &scene = *(TattooScene *)_vm->_scene;
|
||||
TattooUserInterface &ui = *(TattooUserInterface *)_vm->_ui;
|
||||
Common::Point mousePos = events.mousePos();
|
||||
|
||||
if (_invVerbMode == 1)
|
||||
checkTabbingKeys(MAX_INV_COMMANDS);
|
||||
else if (_invVerbMode == 0)
|
||||
checkInvTabbingKeys();
|
||||
|
||||
if (_invVerbMode != 1)
|
||||
updateDescription();
|
||||
|
||||
// Flag is they started pressing outside of the menu
|
||||
if (events._firstPress && !_bounds.contains(mousePos))
|
||||
_outsideMenu = true;
|
||||
|
||||
if (_invVerbMode != 3)
|
||||
highlightControls();
|
||||
|
||||
// See if they released a mouse button button
|
||||
if (events._released || events._rightReleased || ui._keyState.keycode == Common::KEYCODE_ESCAPE) {
|
||||
_dialogTimer = -1;
|
||||
_scrollHighlight = 0;
|
||||
|
||||
// See if they have a Verb List open for an Inventry Item
|
||||
if (_invVerbMode == 1) {
|
||||
// An inventory item's Verb List is open
|
||||
|
||||
// See if they want to close the menu (by clicking outside the menu)
|
||||
Common::Rect innerBounds = _bounds;
|
||||
innerBounds.grow(-3);
|
||||
|
||||
if (_outsideMenu && !innerBounds.contains(mousePos)) {
|
||||
banishWindow();
|
||||
_invVerbMode = 0;
|
||||
} else if (innerBounds.contains(mousePos)) {
|
||||
_outsideMenu = false;
|
||||
|
||||
// Check if they are trying to solve the Foolscap puzzle, or looking at the completed puzzle
|
||||
bool doHangman = !inv[_invSelect]._name.compareToIgnoreCase(S_INV6) &&
|
||||
!_inventCommands[_invVerbSelect].compareToIgnoreCase(S_SOLVE);
|
||||
doHangman |= (!inv[_invSelect]._name.compareToIgnoreCase(S_INV6) || !inv[_invSelect]._name.compareToIgnoreCase(S_INV7))
|
||||
&& _inventCommands[_invVerbSelect].compareToIgnoreCase(S_LOOK) && vm.readFlags(299);
|
||||
|
||||
if (doHangman) {
|
||||
// Close the entire Inventory and return to Standard Mode
|
||||
banishWindow();
|
||||
_invVerbMode = 0;
|
||||
|
||||
_tooltipWidget.banishWindow();
|
||||
banishWindow();
|
||||
inv.freeInv();
|
||||
|
||||
events.clearEvents();
|
||||
events.setCursor(ARROW);
|
||||
ui._menuMode = scene._labTableScene ? LAB_MODE : STD_MODE;
|
||||
|
||||
scene.doBgAnim();
|
||||
vm.doHangManPuzzle();
|
||||
} else if (_invVerbSelect == 0) {
|
||||
// They have released the mouse on the Look Verb command, so Look at the inventory item
|
||||
ui._invLookFlag = true;
|
||||
inv.freeInv();
|
||||
ui._windowOpen = false;
|
||||
ui._lookPos = mousePos;
|
||||
ui.printObjectDesc(inv[_invSelect]._examine, true);
|
||||
} else {
|
||||
// Clear the window
|
||||
banishWindow();
|
||||
_invVerbMode = 3;
|
||||
ui._oldBgFound = -1;
|
||||
|
||||
// See if the selected Verb with the selected Iventory Item, is to be used by itself
|
||||
if (!_inventCommands[_invVerbSelect].compareToIgnoreCase(inv[_invSelect]._verb._verb) ||
|
||||
!inv[_invSelect]._verb._target.compareToIgnoreCase("*SELF")) {
|
||||
inv.freeInv();
|
||||
|
||||
ui._menuMode = scene._labTableScene ? LAB_MODE : STD_MODE;
|
||||
events.clearEvents();
|
||||
ui.checkAction(inv[_invSelect]._verb, 2000);
|
||||
} else {
|
||||
_invVerb = _inventCommands[_invVerbSelect];
|
||||
}
|
||||
}
|
||||
|
||||
// If we are still in Inventory Mode, setup the graphic to float in front of the mouse cursor
|
||||
if (ui._menuMode == INV_MODE) {
|
||||
ImageFrame &imgFrame = (*inv._invShapes[_invSelect - inv._invIndex])[0];
|
||||
_invGraphicBounds = Common::Rect(imgFrame._width, imgFrame._height);
|
||||
_invGraphicBounds.moveTo(mousePos.x - _invGraphicBounds.width() / 2,
|
||||
mousePos.y - _invGraphicBounds.height() / 2);
|
||||
|
||||
// Constrain it to the screen
|
||||
if (_invGraphicBounds.left < 0)
|
||||
_invGraphicBounds.moveTo(0, _invGraphicBounds.top);
|
||||
if (_invGraphicBounds.top < 0)
|
||||
_invGraphicBounds.moveTo(_invGraphicBounds.left, 0);
|
||||
if (_invGraphicBounds.right > SHERLOCK_SCREEN_WIDTH)
|
||||
_invGraphicBounds.moveTo(SHERLOCK_SCREEN_WIDTH - _invGraphicBounds.width(), _invGraphicBounds.top);
|
||||
if (_invGraphicBounds.bottom > SHERLOCK_SCREEN_HEIGHT)
|
||||
_invGraphicBounds.moveTo(_invGraphicBounds.left, SHERLOCK_SCREEN_HEIGHT - _invGraphicBounds.height());
|
||||
|
||||
// Make a copy of the inventory image
|
||||
_invGraphic.create(imgFrame._width, imgFrame._height);
|
||||
_invGraphic.blitFrom(imgFrame, Common::Point(0, 0));
|
||||
}
|
||||
}
|
||||
} else if (_invVerbMode == 3) {
|
||||
// Selecting object after inventory verb has been selected
|
||||
_tooltipWidget.banishWindow();
|
||||
_invGraphic.free();
|
||||
inv.freeInv();
|
||||
|
||||
ui._menuMode = scene._labTableScene ? LAB_MODE : STD_MODE;
|
||||
events.clearEvents();
|
||||
|
||||
if (ui._keyState.keycode != Common::KEYCODE_ESCAPE) {
|
||||
// If user pointed at an item, use the selected inventory item with this item
|
||||
bool found = false;
|
||||
if (ui._bgFound != -1) {
|
||||
if (ui._personFound) {
|
||||
for (int idx = 0; idx < 2; ++idx) {
|
||||
if (!people[ui._bgFound - 1000]._use[idx]._verb.compareToIgnoreCase(_invVerb) &&
|
||||
!people[ui._bgFound - 1000]._use[idx]._target.compareToIgnoreCase(_invTarget)) {
|
||||
ui.checkAction(people[ui._bgFound - 1000]._use[idx], ui._bgFound);
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int idx = 0; idx < 6; ++idx) {
|
||||
if (!ui._bgShape->_use[idx]._verb.compareToIgnoreCase(_invVerb) &&
|
||||
!ui._bgShape->_use[idx]._target.compareToIgnoreCase(_invTarget)) {
|
||||
ui.checkAction(ui._bgShape->_use[idx], ui._bgFound);
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
ui.putMessage(S_NO_EFFECT);
|
||||
}
|
||||
} else if ((_outsideMenu && !_bounds.contains(mousePos)) || ui._keyState.keycode == Common::KEYCODE_ESCAPE) {
|
||||
// Want to close the window (clicked outside of it). So close the window and return to Standard
|
||||
banishWindow();
|
||||
inv.freeInv();
|
||||
|
||||
events.clearEvents();
|
||||
events.setCursor(ARROW);
|
||||
banishWindow();
|
||||
ui._menuMode = scene._labTableScene ? LAB_MODE : STD_MODE;
|
||||
} else if (_bounds.contains(mousePos)) {
|
||||
// Mouse button was released inside the inventory window
|
||||
_outsideMenu = false;
|
||||
|
||||
// See if they are pointing at one of the inventory items
|
||||
if (_invSelect != -1) {
|
||||
// See if they are in Use Obj with Inv. Mode (they right clicked on an item
|
||||
// in the room and selected "Use with Inv.")
|
||||
if (_invMode == 1) {
|
||||
_tooltipWidget.banishWindow();
|
||||
banishWindow();
|
||||
|
||||
// See if the item in the room that they started with was a person
|
||||
bool found = false;
|
||||
if (ui._activeObj >= 1000) {
|
||||
// Object was a person, activate anything in his two verb fields
|
||||
for (int idx = 0; idx < 2; ++idx) {
|
||||
if (!people[ui._activeObj - 1000]._use[idx]._target.compareToIgnoreCase(inv[_invSelect]._name)) {
|
||||
ui.checkAction(people[ui._activeObj - 1000]._use[idx], ui._activeObj);
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Object was a regular object, activate anything in its verb fields
|
||||
for (int idx = 0; idx < 6; ++idx) {
|
||||
if (!scene._bgShapes[ui._activeObj]._use[idx]._target.compareToIgnoreCase(inv[_invSelect]._name)) {
|
||||
ui.checkAction(scene._bgShapes[ui._activeObj]._use[idx], ui._activeObj);
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
ui.putMessage(S_NO_EFFECT);
|
||||
|
||||
} else {
|
||||
// See if they right clicked on an item
|
||||
if (events._rightReleased) {
|
||||
_invVerbMode = 1;
|
||||
_oldInvVerbSelect = -1;
|
||||
_tooltipWidget.banishWindow();
|
||||
|
||||
// Keep track of the name of the inventory object so we can check it against the target fields
|
||||
// of verbs when we activate it
|
||||
_invTarget = inv[_invSelect]._name;
|
||||
|
||||
// Make the Verb List for this Inventory Item
|
||||
_inventCommands.clear();
|
||||
_inventCommands.push_back(S_LOOK);
|
||||
|
||||
// Default the Action word to "with"
|
||||
_action = _vm->getLanguage() == Common::GR_GRE ? "" : S_WITH;
|
||||
_swapItems = false;
|
||||
|
||||
// Search all the bgshapes for any matching Target Fields
|
||||
for (uint idx = 0; idx < scene._bgShapes.size(); ++idx) {
|
||||
Object &obj = scene._bgShapes[idx];
|
||||
|
||||
if (obj._type != INVALID && obj._type != HIDDEN) {
|
||||
for (int useNum = 0; useNum < 6; ++useNum) {
|
||||
if (obj._use[useNum]._verb.hasPrefix("*") &&
|
||||
!obj._use[useNum]._target.compareToIgnoreCase(inv[_invSelect]._name)) {
|
||||
// Make sure the Verb is not already in the list
|
||||
bool found1 = false;
|
||||
for (uint cmdNum = 0; cmdNum < _inventCommands.size() && !found1; ++cmdNum) {
|
||||
if (!_inventCommands[cmdNum].compareToIgnoreCase(obj._use[useNum]._verb))
|
||||
found1 = true;
|
||||
}
|
||||
|
||||
if (!found1) {
|
||||
_inventCommands.push_back(obj._use[useNum]._verb);
|
||||
|
||||
// Check for any Special Action commands
|
||||
for (int nameNum = 0; nameNum < 4; ++nameNum) {
|
||||
if (!scumm_strnicmp(obj._use[useNum]._names[nameNum].c_str(), "*V", 2)) {
|
||||
if (!scumm_strnicmp(obj._use[useNum]._names[nameNum].c_str(), "*VSWAP", 6))
|
||||
_swapItems = true;
|
||||
else
|
||||
_action = Common::String(obj._use[useNum]._names[nameNum].c_str() + 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Search the NPCs for matches as well
|
||||
for (int idx = 1; idx < MAX_CHARACTERS; ++idx) {
|
||||
for (int useNum = 0; useNum < 2; ++useNum) {
|
||||
if (!people[idx]._use[useNum]._target.compareToIgnoreCase(inv[_invSelect]._name) &&
|
||||
!people[idx]._use[useNum]._verb.empty() && !people[idx]._use[useNum]._verb.hasPrefix(" ")) {
|
||||
bool found1 = false;
|
||||
for (uint cmdNum = 0; cmdNum < _inventCommands.size() && !found1; ++cmdNum) {
|
||||
if (!_inventCommands[cmdNum].compareToIgnoreCase(people[idx]._use[cmdNum]._verb))
|
||||
found1 = true;
|
||||
}
|
||||
|
||||
if (!found1)
|
||||
_inventCommands.push_back(people[idx]._use[useNum]._verb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Finally see if the item itself has a verb
|
||||
if (!inv[_invSelect]._verb._verb.empty()) {
|
||||
// Don't add "Solve" to the Foolscap if it's already been "Solved"
|
||||
if (inv[_invSelect]._verb._verb.compareToIgnoreCase(S_SOLVE) || !vm.readFlags(299))
|
||||
_inventCommands.push_back(inv[_invSelect]._verb._verb);
|
||||
}
|
||||
|
||||
// Now find the widest command in the _inventCommands array
|
||||
int width = 0;
|
||||
for (uint idx = 0; idx < _inventCommands.size(); ++idx)
|
||||
width = MAX(width, _surface.stringWidth(_inventCommands[idx]));
|
||||
|
||||
// Set up bounds for the menu
|
||||
_menuBounds = Common::Rect(width + _surface.widestChar() * 2 + 6,
|
||||
(_surface.fontHeight() + 7) * _inventCommands.size() + 3);
|
||||
_menuBounds.moveTo(mousePos.x + _menuBounds.width() / 2, mousePos.y + _menuBounds.height() / 2);
|
||||
|
||||
// Create the surface
|
||||
_menuSurface.create(_menuBounds.width(), _menuBounds.height());
|
||||
_surface.fill(TRANSPARENCY);
|
||||
makeInfoArea(_menuSurface);
|
||||
|
||||
// Draw the Verb commands and the lines separating them
|
||||
ImageFile &images = *_interfaceImages;
|
||||
for (int idx = 0; idx < (int)_inventCommands.size(); ++idx) {
|
||||
_menuSurface.writeString(_inventCommands[idx], Common::Point((_menuBounds.width() -
|
||||
_menuSurface.stringWidth(_inventCommands[idx])) / 2, (_menuSurface.fontHeight() + 7) * idx + 5), INFO_TOP);
|
||||
|
||||
if (idx < (int)_inventCommands.size()- 1) {
|
||||
_menuSurface.vLine(3, (_menuSurface.fontHeight() + 7) * (idx + 1), _menuBounds.right - 4, INFO_TOP);
|
||||
_menuSurface.vLine(3, (_menuSurface.fontHeight() + 7) * (idx + 1) + 1, _menuBounds.right - 4, INFO_MIDDLE);
|
||||
_menuSurface.vLine(3, (_menuSurface.fontHeight() + 7) * (idx + 1) + 2, _menuBounds.right - 4, INFO_BOTTOM);
|
||||
|
||||
_menuSurface.transBlitFrom(images[4], Common::Point(0, (_menuSurface.fontHeight() + 7) * (idx + 1)));
|
||||
_menuSurface.transBlitFrom(images[5], Common::Point(_menuBounds.width() - images[5]._width,
|
||||
(_menuSurface.fontHeight() + 7) * (idx + 1) - 1));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// They left clicked on an inventory item, so Look at it
|
||||
|
||||
// Check if they are looking at the solved Foolscap
|
||||
if ((!inv[_invSelect]._name.compareToIgnoreCase(S_INV6) || !inv[_invSelect]._name.compareToIgnoreCase(S_INV7))
|
||||
&& vm.readFlags(299)) {
|
||||
banishWindow();
|
||||
_tooltipWidget.erase();
|
||||
|
||||
_invVerbMode = 0;
|
||||
inv.freeInv();
|
||||
|
||||
events.clearEvents();
|
||||
events.setCursor(ARROW);
|
||||
ui._menuMode = scene._labTableScene ? LAB_MODE : STD_MODE;
|
||||
|
||||
scene.doBgAnim();
|
||||
vm.doHangManPuzzle();
|
||||
} else {
|
||||
ui._invLookFlag = true;
|
||||
inv.freeInv();
|
||||
|
||||
_tooltipWidget.banishWindow();
|
||||
ui._windowOpen = false;
|
||||
ui._lookPos = mousePos;
|
||||
ui.printObjectDesc(inv[_invSelect]._examine, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WidgetInventory::updateDescription() {
|
||||
|
||||
}
|
||||
|
||||
void WidgetInventory::checkInvTabbingKeys() {
|
||||
}
|
||||
|
||||
void WidgetInventory::highlightControls() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void WidgetInventory::banishWindow() {
|
||||
WidgetBase::banishWindow();
|
||||
|
||||
_menuSurface.free();
|
||||
_menuBounds = _oldMenuBounds = Common::Rect(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
} // End of namespace Tattoo
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
|
||||
#include "common/scummsys.h"
|
||||
#include "sherlock/tattoo/widget_base.h"
|
||||
#include "sherlock/tattoo/widget_tooltip.h"
|
||||
|
||||
namespace Sherlock {
|
||||
|
||||
@ -37,7 +38,19 @@ private:
|
||||
int _invVerbMode;
|
||||
int _invSelect, _oldInvSelect;
|
||||
int _selector, _oldSelector;
|
||||
int _invVerbSelect, _oldInvVerbSelect;
|
||||
int _dialogTimer;
|
||||
int _scrollHighlight;
|
||||
Common::StringArray _inventCommands;
|
||||
WidgetTooltip _tooltipWidget;
|
||||
Common::String _invVerb;
|
||||
Common::String _invTarget;
|
||||
Common::String _action;
|
||||
Common::Rect _invGraphicBounds;
|
||||
Surface _invGraphic;
|
||||
bool _swapItems;
|
||||
Common::Rect _menuBounds, _oldMenuBounds;
|
||||
Surface _menuSurface;
|
||||
|
||||
/**
|
||||
* Draw the scrollbar for the dialog
|
||||
@ -48,6 +61,21 @@ private:
|
||||
* Draws all the dialog rectangles for any items that need them
|
||||
*/
|
||||
void drawDialogRect(const Common::Rect &r, bool raised);
|
||||
|
||||
/**
|
||||
* Displays the description of any inventory item the moues cursor is over
|
||||
*/
|
||||
void updateDescription();
|
||||
|
||||
/**
|
||||
* Check for keys to mouse the mouse within the inventory dialog
|
||||
*/
|
||||
void checkInvTabbingKeys();
|
||||
|
||||
/**
|
||||
* Highlights the controls
|
||||
*/
|
||||
void highlightControls();
|
||||
public:
|
||||
int _invMode;
|
||||
public:
|
||||
@ -60,6 +88,16 @@ public:
|
||||
* Draw the inventory on the surface
|
||||
*/
|
||||
void drawInventory();
|
||||
|
||||
/**
|
||||
* Handle events whilst the widget is on-screen
|
||||
*/
|
||||
virtual void handleEvents();
|
||||
|
||||
/**
|
||||
* Close a currently active menu
|
||||
*/
|
||||
virtual void banishWindow();
|
||||
};
|
||||
|
||||
} // End of namespace Tattoo
|
||||
|
@ -230,10 +230,6 @@ void WidgetVerbs::execute() {
|
||||
}
|
||||
}
|
||||
|
||||
void WidgetVerbs::checkTabbingKeys(int numOptions) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void WidgetVerbs::highlightVerbControls() {
|
||||
Events &events = *_vm->_events;
|
||||
Screen &screen = *_vm->_screen;
|
||||
|
@ -58,8 +58,6 @@ public:
|
||||
* Process input for the dialog
|
||||
*/
|
||||
void execute();
|
||||
|
||||
void checkTabbingKeys(int numOptions);
|
||||
};
|
||||
|
||||
} // End of namespace Tattoo
|
||||
|
Loading…
x
Reference in New Issue
Block a user