aboutsummaryrefslogtreecommitdiff
path: root/engines/mutationofjb/gamescreen.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/mutationofjb/gamescreen.cpp')
-rw-r--r--engines/mutationofjb/gamescreen.cpp214
1 files changed, 201 insertions, 13 deletions
diff --git a/engines/mutationofjb/gamescreen.cpp b/engines/mutationofjb/gamescreen.cpp
index 3c007f415f..ef7e50baeb 100644
--- a/engines/mutationofjb/gamescreen.cpp
+++ b/engines/mutationofjb/gamescreen.cpp
@@ -26,13 +26,16 @@
#include "mutationofjb/encryptedfile.h"
#include "mutationofjb/game.h"
#include "mutationofjb/gamedata.h"
+#include "mutationofjb/mutationofjb.h"
#include "mutationofjb/inventory.h"
#include "mutationofjb/util.h"
-#include "mutationofjb/widgets/widget.h"
-#include "mutationofjb/widgets/inventorywidget.h"
-#include "mutationofjb/widgets/imagewidget.h"
#include "mutationofjb/widgets/conversationwidget.h"
+#include "mutationofjb/widgets/gamewidget.h"
+#include "mutationofjb/widgets/imagewidget.h"
+#include "mutationofjb/widgets/inventorywidget.h"
+#include "mutationofjb/widgets/labelwidget.h"
+#include "common/events.h"
#include "common/rect.h"
#include "graphics/screen.h"
@@ -61,14 +64,20 @@ enum {
CONVERSATION_X = 0,
CONVERSATION_Y = 139,
CONVERSATION_WIDTH = 320,
- CONVERSATION_HEIGHT = 61
+ CONVERSATION_HEIGHT = 61,
+ STATUS_BAR_X = 0,
+ STATUS_BAR_Y = 140,
+ STATUS_BAR_WIDTH = 320,
+ STATUS_BAR_HEIGHT = 8
};
GameScreen::GameScreen(Game &game, Graphics::Screen *screen)
: GuiScreen(game, screen),
_inventoryWidget(nullptr),
- _conversationWidget(nullptr) {}
+ _conversationWidget(nullptr),
+ _statusBarWidget(nullptr),
+ _currentAction(ActionInfo::Walk) {}
GameScreen::~GameScreen() {}
@@ -111,22 +120,105 @@ bool GameScreen::init() {
ButtonWidget *button = new ButtonWidget(*this, ButtonRects[i], normalSurface, pressedSurface);
button->setId(i);
button->setCallback(this);
+ _buttons.push_back(button);
addWidget(button);
}
+ const Common::Rect statusBarRect(STATUS_BAR_X, STATUS_BAR_Y, STATUS_BAR_X + STATUS_BAR_WIDTH, STATUS_BAR_Y + STATUS_BAR_HEIGHT);
+ _statusBarWidget = new LabelWidget(*this, statusBarRect);
+ addWidget(_statusBarWidget);
+
const Common::Rect conversationRect(CONVERSATION_X, CONVERSATION_Y, CONVERSATION_X + CONVERSATION_WIDTH, CONVERSATION_Y + CONVERSATION_HEIGHT);
const Graphics::Surface conversationSurface = _hudSurfaces[2].getSubArea(conversationRect);
_conversationWidget = new ConversationWidget(*this, conversationRect, conversationSurface);
_conversationWidget->setVisible(false);
addWidget(_conversationWidget);
+ _gameWidget = new GameWidget(*this);
+ _gameWidget->setCallback(this);
+ addWidget(_gameWidget);
+
return true;
}
+void GameScreen::handleEvent(const Common::Event &event) {
+ switch (event.type) {
+ case Common::EVENT_KEYUP: {
+ switch (event.kbd.ascii) {
+ case 'g':
+ _currentAction = ActionInfo::Walk;
+ break;
+ case 'r':
+ _currentAction = ActionInfo::Talk;
+ break;
+ case 's':
+ _currentAction = ActionInfo::Look;
+ break;
+ case 'b':
+ _currentAction = ActionInfo::Use;
+ break;
+ case 'n':
+ _currentAction = ActionInfo::PickUp;
+ break;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+
+ GuiScreen::handleEvent(event);
+}
+
ConversationWidget &GameScreen::getConversationWidget() {
return *_conversationWidget;
}
+void GameScreen::showConversationWidget(bool show) {
+ _gameWidget->setEnabled(!show);
+ _conversationWidget->setVisible(show);
+ _statusBarWidget->setText(Common::String());
+
+ for (Common::Array<ButtonWidget *>::const_iterator it = _buttons.begin(); it != _buttons.end(); ++it) {
+ (*it)->setVisible(!show);
+ }
+ _inventoryWidget->setVisible(!show);
+}
+
+void GameScreen::refreshAfterSceneChanged() {
+ const Widgets &widgets = getWidgets();
+
+ if (!getGame().isCurrentSceneMap()) {
+ _gameWidget->setArea(Common::Rect(GameWidget::GAME_NORMAL_AREA_WIDTH, GameWidget::GAME_NORMAL_AREA_HEIGHT));
+
+ for (Widgets::const_iterator it = widgets.begin(); it != widgets.end(); ++it) {
+ if (*it == _gameWidget || *it == _conversationWidget)
+ continue;
+
+ (*it)->setVisible(true);
+ }
+ } else {
+ _gameWidget->setArea(Common::Rect(GameWidget::GAME_FULL_AREA_WIDTH, GameWidget::GAME_FULL_AREA_HEIGHT));
+ for (Widgets::const_iterator it = widgets.begin(); it != widgets.end(); ++it) {
+ if (*it == _gameWidget || *it == _conversationWidget)
+ continue;
+
+ (*it)->setVisible(false);
+ }
+ }
+
+ _gameWidget->clearState();
+
+ // Fake mouse move event to update the cursor.
+ Common::Event event;
+ event.type = Common::EVENT_MOUSEMOVE;
+ event.mouse = _game.getEngine().getEventManager()->getMousePos();
+ _gameWidget->handleEvent(event);
+
+ _gameWidget->markDirty();
+ _gameWidget->update(*_screen); // Force immediate update.
+}
+
class InventoryAnimationDecoderCallback : public AnimationDecoderCallback {
public:
InventoryAnimationDecoderCallback(GameScreen &gui) : _gui(gui) {}
@@ -180,6 +272,56 @@ bool GameScreen::loadHudGfx() {
return decoder.decode(&callback);
}
+void GameScreen::updateStatusBarText(const Common::String &entity, bool inventory) {
+ const bool hasPrevPickedItem = !_currentPickedItem.empty();
+ const bool hasCurrentItem = !entity.empty();
+
+ if (!hasPrevPickedItem && !hasCurrentItem) {
+ _statusBarWidget->setText(Common::String());
+ return;
+ }
+
+ HardcodedStrings::StringType actionStringType = HardcodedStrings::LOOK;
+
+ if (inventory) {
+ switch (_currentAction) {
+ case ActionInfo::Use:
+ actionStringType = HardcodedStrings::USE;
+ break;
+ default:
+ actionStringType = HardcodedStrings::LOOK;
+ break;
+ }
+ } else {
+ switch (_currentAction) {
+ case ActionInfo::Look:
+ actionStringType = HardcodedStrings::LOOK;
+ break;
+ case ActionInfo::Walk:
+ actionStringType = HardcodedStrings::WALK;
+ break;
+ case ActionInfo::Talk:
+ actionStringType = HardcodedStrings::TALK;
+ break;
+ case ActionInfo::Use:
+ actionStringType = HardcodedStrings::USE;
+ break;
+ case ActionInfo::PickUp:
+ actionStringType = HardcodedStrings::PICKUP;
+ break;
+ }
+ }
+
+ Common::String text = _game.getAssets().getHardcodedStrings().getString(actionStringType);
+
+ if (hasPrevPickedItem)
+ text += " " + _currentPickedItem;
+ if (hasCurrentItem)
+ text += " " + entity;
+
+ _statusBarWidget->setText(text);
+}
+
void GameScreen::onInventoryChanged() {
_inventoryWidget->markDirty();
}
@@ -188,7 +330,8 @@ void GameScreen::onButtonClicked(ButtonWidget *button) {
const int buttonId = button->getId();
if (buttonId <= BUTTON_PICKUP) {
const ActionInfo::Action actions[] = {ActionInfo::Walk, ActionInfo::Talk, ActionInfo::Look, ActionInfo::Use, ActionInfo::PickUp};
- _game.setCurrentAction(actions[buttonId]);
+ _currentAction = actions[buttonId];
+ _currentPickedItem.clear();
} else if (buttonId == BUTTON_SCROLL_LEFT) {
_game.getGameData().getInventory().scrollLeft();
} else if (buttonId == BUTTON_SCROLL_RIGHT) {
@@ -196,19 +339,64 @@ void GameScreen::onButtonClicked(ButtonWidget *button) {
}
}
-void GameScreen::onInventoryItemHovered(InventoryWidget *widget, int posInWidget) {
- // TODO
+void GameScreen::onInventoryItemHovered(InventoryWidget *, int posInWidget) {
+ if (posInWidget == -1) {
+ updateStatusBarText(Common::String(), true);
+ } else {
+ const Common::String &item = _game.getGameData().getInventory().getItems()[posInWidget];
+ updateStatusBarText(item, true);
+ }
}
-void GameScreen::onInventoryItemClicked(InventoryWidget *widget, int posInWidget) {
+void GameScreen::onInventoryItemClicked(InventoryWidget *, int posInWidget) {
// Position in widget should match the position in inventory.
- const Common::String &item = getGame().getGameData().getInventory().getItems()[posInWidget];
-
- if (_game.getCurrentAction() == ActionInfo::Use) {
- // TODO
+ const Common::String &item = _game.getGameData().getInventory().getItems()[posInWidget];
+
+ if (_currentAction == ActionInfo::Use) {
+ if (_currentPickedItem.empty()) {
+ // Inventory items ending with '[' aren't supposed to be combined (e.g. Fisher's mask).
+ if (item.lastChar() == '[')
+ _game.startActionSection(ActionInfo::Look, item);
+ else
+ _currentPickedItem = item;
+ } else {
+ _game.startActionSection(ActionInfo::Use, _currentPickedItem, item);
+ _currentPickedItem.clear();
+ }
} else {
_game.startActionSection(ActionInfo::Look, item);
}
}
+void GameScreen::onGameDoorClicked(GameWidget *, const Door *door) {
+ if (!_currentPickedItem.empty()) {
+ _game.startActionSection(_currentAction, _currentPickedItem, door->_name);
+ return;
+ }
+
+ if (!_game.startActionSection(_currentAction, door->_name) && _currentAction == ActionInfo::Walk && door->_destSceneId != 0) {
+ _game.changeScene(door->_destSceneId, _game.getGameData()._partB);
+ }
+}
+
+void GameScreen::onGameStaticClicked(GameWidget *, const Static *stat) {
+ if (_currentAction == ActionInfo::Use) {
+ if (_currentPickedItem.empty()) {
+ if (stat->isCombinable())
+ _currentPickedItem = stat->_name;
+ else
+ _game.startActionSection(ActionInfo::Use, stat->_name);
+ } else {
+ _game.startActionSection(_currentAction, _currentPickedItem, stat->_name);
+ _currentPickedItem.clear();
+ }
+ } else {
+ _game.startActionSection(_currentAction, stat->_name);
+ }
+}
+
+void GameScreen::onGameEntityHovered(GameWidget *, const Common::String &entity) {
+ updateStatusBarText(entity, false);
+}
+
}