PINK: added implementation of item using

This commit is contained in:
whiterandrek 2018-05-11 17:53:55 +03:00 committed by Eugene Sandulenko
parent 604c74ab07
commit 181b89035a
14 changed files with 144 additions and 44 deletions

View File

@ -20,19 +20,23 @@
*
*/
#include <engines/pink/objects/actors/actor.h>
#include <engines/pink/objects/actions/action_cel.h>
#include <engines/pink/cel_decoder.h>
#include "cursor_mgr.h"
#include "pink.h"
#include "objects/pages/game_page.h"
namespace Pink {
CursorMgr::CursorMgr(PinkEngine *game, GamePage *page)
: _actor(nullptr), _page(page), _game(game),
: _actor(nullptr), _action(nullptr), _page(page), _game(game),
_isPlayingAnimation(0), _firstFrameIndex(0)
{}
CursorMgr::~CursorMgr() {}
void CursorMgr::setCursor(uint index, Common::Point point) {
void CursorMgr::setCursor(uint index, Common::Point point, const Common::String &itemName) {
if (index == kClickableFirstFrameCursor) {
if (!_isPlayingAnimation) {
_isPlayingAnimation = 1;
@ -41,11 +45,30 @@ void CursorMgr::setCursor(uint index, Common::Point point) {
_isSecondFrame = 0;
_game->setCursor(index);
}
return;
}
else {
if (index != kHoldingItemCursor){
_isPlayingAnimation = 0;
_game->setCursor(index);
return;
}
_game->setCursor(index);
_actor = _actor ? _actor : _page->findActor(kCursor);
assert(_actor);
Action *action = _actor->findAction(itemName);
assert(action);
if (action != _action) {
_action = action;
_actor->setAction(action, 0);
}
assert(dynamic_cast<ActionCEL*>(action));
CelDecoder *decoder = static_cast<ActionCEL*>(_action)->getDecoder();
// this is buggy
//decoder->setX(point.x);
//decoder->setY(point.y);
}
void CursorMgr::update() {
@ -68,11 +91,12 @@ void CursorMgr::setCursor(Common::String &cursorName, Common::Point point) {
else if (cursorName == kCursorNameExitRight){
index = kExitRightCursor;
}
else if (cursorName == kCursorNameExitForward || cursorName == kCursorNameExitUp)
else //if (cursorName == kCursorNameExitForward || cursorName == kCursorNameExitUp)
index = kExitForwardCursor;
else assert(0);
//else assert(0);
setCursor(index, point);
setCursor(index, point, Common::String());
}
} // End of namespace Pink

View File

@ -29,8 +29,8 @@
namespace Pink {
class Actor;
class Action;
class GamePage;
class PinkEngine;
@ -40,11 +40,15 @@ public:
~CursorMgr();
void update();
void setCursor(uint index, Common::Point point);
void setCursor(uint index, Common::Point point, const Common::String &itemName);
void setCursor(Common::String &cursorName, Common::Point point);
private:
void hideItem();
void stopAnimation();
Actor *_actor;
Action *_action;
GamePage *_page;
PinkEngine *_game;

View File

@ -125,7 +125,7 @@ bool Actor::initPallete(Director *director) {
}
void Actor::onMouseOver(Common::Point point, CursorMgr *mgr) {
mgr->setCursor(kDefaultCursor, point);
mgr->setCursor(kDefaultCursor, point, Common::String());
}
Actor::~Actor() {
@ -159,4 +159,8 @@ void Actor::unpause() {
_action->unpause();
}
void Actor::onHover(Common::Point point, const Common::String &itemName, CursorMgr *cursorMgr) {
cursorMgr->setCursor(kHoldingItemCursor, point, itemName);
}
} // End of namespace Pink

View File

@ -34,6 +34,8 @@ class Action;
class Sequencer;
class Director;
class CursorMgr;
class InventoryItem;
class InventoryMgr;
class Actor : public NamedObject {
public:
@ -68,6 +70,7 @@ public:
virtual void update() {};
virtual void onMouseOver(Common::Point point, CursorMgr *mgr);
virtual void onHover(Common::Point point, const Common::String &itemName, CursorMgr *cursorMgr);
virtual bool isClickable() { return 0;}

View File

@ -161,19 +161,26 @@ void LeadActor::updateCursor(Common::Point point) {
case kMoving: {
Director *director = _page->getGame()->getDirector();
Actor *actor = director->getActorByPoint(point);
if (actor)
InventoryItem *item = _page->getModule()->getInventoryMgr()->getCurrentItem();
if (_isHaveItem) {
if (actor) {
actor->onHover(point, item->getName(), _cursorMgr);
}
else _cursorMgr->setCursor(kHoldingItemCursor, point, item->getName());
}
else if (actor)
actor->onMouseOver(point, _cursorMgr);
else _cursorMgr->setCursor(kDefaultCursor, point);
else _cursorMgr->setCursor(kDefaultCursor, point, Common::String());
break;
}
case kInDialog1:
case kInDialog2:
case kPlayingVideo:
_cursorMgr->setCursor(kNotClickableCursor, point);
_cursorMgr->setCursor(kNotClickableCursor, point, Common::String());
break;
case kPDA:
case kInventory:
_cursorMgr->setCursor(kDefaultCursor, point);
_cursorMgr->setCursor(kDefaultCursor, point, Common::String());
break;
default:
break;
@ -181,6 +188,8 @@ void LeadActor::updateCursor(Common::Point point) {
}
void LeadActor::onLeftButtonClick(Common::Point point) {
InventoryMgr *invMgr = _page->getModule()->getInventoryMgr();
switch (_state) {
case kReady:
case kMoving: {
@ -192,9 +201,8 @@ void LeadActor::onLeftButtonClick(Common::Point point) {
}
_recipient = (SupportingActor*) actor;
if (actor->isClickable() &&
_recipient->isLeftClickHandlers()) {
WalkLocation *location = _walkMgr->findLocation(_recipient->getLocation());
if (actor->isClickable() && isInteractingWith(_recipient)) {
WalkLocation *location = getWalkDestination();
if (location) {
_state = kMoving;
_nextState = kInDialog1;
@ -213,7 +221,7 @@ void LeadActor::onLeftButtonClick(Common::Point point) {
break;
case kInventory:
_page->getModule()->getInventoryMgr()->onClick(point);
invMgr->onClick(point);
break;
default:
break;
@ -222,7 +230,7 @@ void LeadActor::onLeftButtonClick(Common::Point point) {
void LeadActor::onMouseOver(Common::Point point, CursorMgr *mgr) {
if (_page->getModule()->getInventoryMgr()->isPinkOwnsAnyItems())
_cursorMgr->setCursor(kClickableFirstFrameCursor, point);
_cursorMgr->setCursor(kClickableFirstFrameCursor, point, Common::String());
else Actor::onMouseOver(point, mgr);
}
@ -238,7 +246,14 @@ void LeadActor::onWalkEnd() {
}
bool LeadActor::sendUseClickMessage(SupportingActor *actor) {
return false;
InventoryMgr *mgr = _page->getModule()->getInventoryMgr();
_nextState = _state != kPlayingVideo ? kReady : kPlayingVideo;
_state = kInDialog1;
actor->onUseClickMessage(mgr->getCurrentItem(), mgr);
if (mgr->getCurrentItem() == nullptr
|| mgr->getCurrentItem()->getCurrentOwner() != this->_name)
_isHaveItem = false;
return true;
}
bool LeadActor::sendLeftClickMessage(SupportingActor *actor) {
@ -286,6 +301,17 @@ void LeadActor::forceUpdateCursor() {
updateCursor(point);
}
WalkLocation *LeadActor::getWalkDestination() {
return _walkMgr->findLocation(_recipient->getLocation());
}
bool LeadActor::isInteractingWith(SupportingActor *actor) {
if (!_isHaveItem)
return actor->isLeftClickHandlers();
return actor->isUseClickHandlers(_page->getModule()->getInventoryMgr()->getCurrentItem());
}
void ParlSqPink::toConsole() {
debug("ParlSqPink: _name = %s", _name.c_str());
for (int i = 0; i < _actions.size(); ++i) {

View File

@ -68,18 +68,22 @@ public:
void onLeftButtonClick(Common::Point point);
void onMouseMove(Common::Point point);
void onWalkEnd();
void onClick();
virtual void onClick();
void onInventoryClosed(bool isItemClicked);
virtual void onMouseOver(Common::Point point, CursorMgr *mgr);
private:
void updateCursor(Common::Point point);
bool isInteractingWith(SupportingActor *actor);
protected:
virtual void updateCursor(Common::Point point);
void forceUpdateCursor();
bool sendUseClickMessage(SupportingActor *actor);
virtual bool sendUseClickMessage(SupportingActor *actor);
bool sendLeftClickMessage(SupportingActor *actor);
virtual WalkLocation *getWalkDestination();
State _state;
State _nextState;
State _stateCopy;

View File

@ -25,6 +25,7 @@
#include <engines/pink/objects/actions/action.h>
#include <engines/pink/constants.h>
#include "pink/cursor_mgr.h"
#include "../inventory.h"
namespace Pink {
@ -48,7 +49,7 @@ void SupportingActor::onMouseOver(Common::Point point, CursorMgr *mgr) {
if (!_cursor.empty()){
mgr->setCursor(_cursor, point);
}
else mgr->setCursor(kClickableFirstFrameCursor, point);
else mgr->setCursor(kClickableFirstFrameCursor, point, Common::String());
}
else Actor::onMouseOver(point, mgr);
}
@ -57,6 +58,10 @@ bool SupportingActor::isLeftClickHandlers() {
return _handlerMgr.isLeftClickHandler(this);
}
bool SupportingActor::isUseClickHandlers(InventoryItem *item) {
return _handlerMgr.isUseClickHandler(this, item->getName());
}
void SupportingActor::onTimerMessage() {
_handlerMgr.onTimerMessage(this);
}
@ -73,8 +78,14 @@ const Common::String &SupportingActor::getLocation() const {
return _location;
}
SupportingActor::~SupportingActor() {
SupportingActor::~SupportingActor() {}
void SupportingActor::onHover(Common::Point point, const Common::String &itemName, CursorMgr *cursorMgr) {
Common::String item = itemName;
if (_handlerMgr.isUseClickHandler(this, itemName)) {
item += kClickable;
}
Actor::onHover(point, item, cursorMgr);
}
} // End of namespace Pink

View File

@ -41,11 +41,14 @@ public:
virtual bool isClickable() { return 1; }
bool isLeftClickHandlers();
bool isUseClickHandlers(InventoryItem *item);
void onTimerMessage();
bool onLeftClickMessage();
bool onUseClickMessage(InventoryItem *item, InventoryMgr *mgr);
virtual void onHover(Common::Point point, const Common::String &itemName, CursorMgr *cursorMgr);
const Common::String &getLocation() const;

View File

@ -22,9 +22,7 @@
#include "handler_mgr.h"
#include "handler.h"
#include "handler_timer.h"
#include <pink/archive.h>
#include <common/debug.h>
#include <pink/objects/inventory.h>
namespace Pink {
@ -55,6 +53,17 @@ bool HandlerMgr::isLeftClickHandler(Actor *actor) {
return false;
}
bool HandlerMgr::isUseClickHandler(Actor *actor, const Common::String &itemName){
for (int i = 0; i < _useClickHandlers.size(); ++i) {
if (itemName == _useClickHandlers[i]->getInventoryItem() &&
_useClickHandlers[i]->isSuitable(actor))
return true;
}
return false;
}
void HandlerMgr::onTimerMessage(Actor *actor) {
Handler *handler = findSuitableHandlerTimer(actor);
if (handler)
@ -71,10 +80,10 @@ bool HandlerMgr::onLeftClickMessage(Actor *actor) {
}
bool HandlerMgr::onUseClickMessage(Actor *actor, InventoryItem *item, InventoryMgr *mgr) {
HandlerUseClick *handler = (HandlerUseClick*) findSuitableHandlerUseClick(actor);
HandlerUseClick *handler = findSuitableHandlerUseClick(actor, item);
if (handler) {
handler->handle(actor);
mgr->setItemOwner(handler->getRecepient(), item);
if (!handler->getRecepient().empty())
mgr->setItemOwner(handler->getRecepient(), item);
handler->handle(actor);
return true;
}
@ -90,7 +99,7 @@ Handler *HandlerMgr::findSuitableHandlerTimer(Actor *actor) {
return nullptr;
}
Handler *HandlerMgr::findSuitableHandlerLeftClick(Actor *actor) {
HandlerLeftClick *HandlerMgr::findSuitableHandlerLeftClick(Actor *actor) {
for (int i = 0; i < _leftClickHandlers.size(); ++i) {
if (_leftClickHandlers[i]->isSuitable(actor))
return _leftClickHandlers[i];
@ -99,9 +108,9 @@ Handler *HandlerMgr::findSuitableHandlerLeftClick(Actor *actor) {
return nullptr;
}
Handler *HandlerMgr::findSuitableHandlerUseClick(Actor *actor) {
HandlerUseClick *HandlerMgr::findSuitableHandlerUseClick(Actor *actor, InventoryItem *item) {
for (int i = 0; i < _useClickHandlers.size(); ++i) {
if (_useClickHandlers[i]->isSuitable(actor))
if (item->getName() == _useClickHandlers[i]->getInventoryItem() && _useClickHandlers[i]->isSuitable(actor))
return _useClickHandlers[i];
}

View File

@ -46,6 +46,7 @@ public:
virtual void toConsole();
bool isLeftClickHandler(Actor *actor);
bool isUseClickHandler(Actor *actor, const Common::String &itemName);
void onTimerMessage(Actor *actor);
bool onLeftClickMessage(Actor *actor);
@ -53,12 +54,12 @@ public:
private:
Handler *findSuitableHandlerTimer(Actor *actor);
Handler *findSuitableHandlerLeftClick(Actor *actor);
Handler *findSuitableHandlerUseClick(Actor *actor);
HandlerLeftClick *findSuitableHandlerLeftClick(Actor *actor);
HandlerUseClick *findSuitableHandlerUseClick(Actor *actor, InventoryItem *item);
Common::Array<HandlerLeftClick*> _leftClickHandlers;
Common::Array<HandlerUseClick*> _useClickHandlers;
Common::Array<HandlerTimer*> _timerHandlers;
Common::Array<Handler*> _timerHandlers;
};
}

View File

@ -100,10 +100,11 @@ void InventoryMgr::setItemOwner(const Common::String &owner, InventoryItem *item
if (item == _item && _lead->getName() != owner)
_item = nullptr;
else if (_lead->getName() == owner)
_item = item;
item->_currentOwner = owner;
if (_lead->getName() == owner)
_item = item;
}
bool InventoryMgr::start(bool playOpening) {
@ -194,6 +195,10 @@ void InventoryMgr::showNextItem(bool direction) {
}
}
InventoryItem *InventoryMgr::getCurrentItem() {
return _item;
}
} // End of namespace Pink

View File

@ -66,6 +66,8 @@ public:
bool isPinkOwnsAnyItems();
void setItemOwner(const Common::String &owner, InventoryItem *item);
InventoryItem *getCurrentItem();
private:
void close();
enum Direction {

View File

@ -133,7 +133,7 @@ Module *GamePage::getModule() const {
return _module;
}
bool GamePage::checkValueOfVariable(Common::String &variable, Common::String &value) {
bool GamePage::checkValueOfVariable(const Common::String &variable, const Common::String &value) {
if (!_variables.contains(variable))
return value == kUndefined;
return _variables[variable] == value;
@ -141,6 +141,7 @@ bool GamePage::checkValueOfVariable(Common::String &variable, Common::String &va
void GamePage::setVariable(Common::String &variable, Common::String &value) {
_variables[variable] = value;
_leadActor->onVariableSet();
}
WalkMgr *GamePage::getWalkMgr() {
@ -149,8 +150,11 @@ WalkMgr *GamePage::getWalkMgr() {
void GamePage::loadState() {
Archive archive(static_cast<Common::SeekableReadStream*>(_memFile));
_variables.clear(0);
archive >> _variables;
//_variables.clear(1);
Common::StringMap mapTest; // HACK. Without it isn't working
//archive >> _variables;
archive >> mapTest;
_variables = mapTest;
uint16 actorCount;
archive >> actorCount;
@ -177,7 +181,7 @@ void GamePage::saveState() {
}
void GamePage::unload() {
_leadActor->setAction(_leadActor->findAction("Idle"));
_leadActor->setAction(_leadActor->findAction(kIdleAction));
saveState();
clear();
@ -187,7 +191,7 @@ void GamePage::unload() {
void GamePage::clear() {
Page::clear();
_variables.clear(1);
//_variables.clear(1);
for (int i = 0; i < _handlers.size(); ++i) {
delete _handlers[i];

View File

@ -50,7 +50,7 @@ public:
WalkMgr *getWalkMgr();
Module *getModule() const;
bool checkValueOfVariable(Common::String &variable, Common::String &value);
bool checkValueOfVariable(const Common::String &variable, const Common::String &value);
void setVariable(Common::String &variable, Common::String &value);
virtual void clear();