diff options
Diffstat (limited to 'engines')
36 files changed, 680 insertions, 86 deletions
diff --git a/engines/pink/cursor_mgr.cpp b/engines/pink/cursor_mgr.cpp index b1a2182c41..a07f577996 100644 --- a/engines/pink/cursor_mgr.cpp +++ b/engines/pink/cursor_mgr.cpp @@ -68,7 +68,7 @@ void CursorMgr::setCursor(Common::String &cursorName, Common::Point point) { else if (cursorName == "ExitRight"){ index = kExitRightCursor; } - else if (cursorName == "ExitForward") + else if (cursorName == "ExitForward" || cursorName == "ExitUp") index = kExitForwardCursor; else assert(0); setCursor(index, point); diff --git a/engines/pink/director.cpp b/engines/pink/director.cpp index 455690ec5b..4003ca5073 100644 --- a/engines/pink/director.cpp +++ b/engines/pink/director.cpp @@ -42,11 +42,12 @@ void Director::draw() { void Director::drawSprite(ActionCEL *sprite) { CelDecoder *decoder = sprite->getDecoder(); const Graphics::Surface *surface; - if (decoder->needsUpdate()) + if (decoder->needsUpdate()) { + surface = decoder->decodeNextFrame(); + } else surface = decoder->getCurrentFrame(); - if (!showBounds) { Graphics::Surface *screen = _system->lockScreen(); @@ -116,7 +117,7 @@ void Director::clear() { } Actor *Director::getActorByPoint(Common::Point point) { - for (int i = _sprites.size() - 1; i > 0; --i) { + for (int i = _sprites.size() - 1; i >= 0; --i) { CelDecoder *decoder = _sprites[i]->getDecoder(); const Graphics::Surface *frame = decoder->getCurrentFrame(); Common::Rect &rect = decoder->getRectangle(); diff --git a/engines/pink/module.mk b/engines/pink/module.mk index 4bff006ed0..53627ec05f 100644 --- a/engines/pink/module.mk +++ b/engines/pink/module.mk @@ -42,6 +42,7 @@ MODULE_OBJS = \ objects/sequences/sequencer.o \ objects/walk/walk_mgr.o \ objects/walk/walk_location.o \ + objects/walk/walk_shortest_path.o \ # This module can be built as a plugin ifeq ($(ENABLE_PINK), DYNAMIC_PLUGIN) diff --git a/engines/pink/objects/actions/action_still.cpp b/engines/pink/objects/actions/action_still.cpp index 442fe85330..0af57a0fee 100644 --- a/engines/pink/objects/actions/action_still.cpp +++ b/engines/pink/objects/actions/action_still.cpp @@ -48,6 +48,8 @@ void ActionStill::onStart() { for (int i = 0; i < _startFrame; ++i) { _decoder->decodeNextFrame(); } + _decoder->stop(); + _actor->endAction(); } } // End of namespace Pink
\ No newline at end of file diff --git a/engines/pink/objects/actions/walk_action.cpp b/engines/pink/objects/actions/walk_action.cpp index 7b7c3e39e3..9c5dac561f 100644 --- a/engines/pink/objects/actions/walk_action.cpp +++ b/engines/pink/objects/actions/walk_action.cpp @@ -22,6 +22,7 @@ #include "walk_action.h" #include <engines/pink/archive.h> +#include "pink/cel_decoder.h" namespace Pink { @@ -36,4 +37,8 @@ void WalkAction::toConsole() { _name.c_str(), _fileName.c_str(), _toCalcFramePositions); } +void WalkAction::onStart() { + _decoder->start(); +} + } // End of namespace Pink
\ No newline at end of file diff --git a/engines/pink/objects/actions/walk_action.h b/engines/pink/objects/actions/walk_action.h index 6dbc6a9059..f74adb8264 100644 --- a/engines/pink/objects/actions/walk_action.h +++ b/engines/pink/objects/actions/walk_action.h @@ -33,6 +33,9 @@ public: virtual void toConsole(); +protected: + void onStart() override; + private: bool _toCalcFramePositions; }; diff --git a/engines/pink/objects/actors/lead_actor.cpp b/engines/pink/objects/actors/lead_actor.cpp index c583d9a7c4..faa0d5aada 100644 --- a/engines/pink/objects/actors/lead_actor.cpp +++ b/engines/pink/objects/actors/lead_actor.cpp @@ -71,16 +71,20 @@ LeadActor::State LeadActor::getState() const { void LeadActor::update() { switch (_state) { case kReady: - _sequencer->update(); - //fall-through intended + _cursorMgr->update(); + break; case kMoving: - + _walkMgr->update(); _cursorMgr->update(); break; case kInDialog1: case kInDialog2: _sequencer->update(); + if (!_sequencer->_context){ + _state = _nextState; + _nextState = kUnk_Loading; + } break; case kInventory: @@ -136,7 +140,8 @@ void LeadActor::onKeyboardButtonClick(Common::KeyCode code) { void LeadActor::start(bool isHandler) { if (isHandler && _state != kPlayingVideo){ - _state = kReady; + _state = kInDialog1; + _nextState = kReady; } updateCursor({0,0}); } @@ -177,17 +182,19 @@ void LeadActor::onLeftButtonClick(Common::Point point) { case kReady: case kMoving: { Actor *actor = _page->getGame()->getDirector()->getActorByPoint(point); + if (this == actor){ // inventory is not implemented return; } + _recipient = (SupportingActor*) actor; if (actor->isClickable() && - ((SupportingActor*) actor)->isLeftClickHandlers()) - - - - + _recipient->isLeftClickHandlers()){ + _state = kMoving; + _nextState = kInDialog1; + _walkMgr->start(_walkMgr->findLocation(_recipient->getLocation())); + } break; } case kPDA: @@ -207,6 +214,27 @@ void LeadActor::onMouseOver(Common::Point point, CursorMgr *mgr) { else Actor::onMouseOver(point, mgr); } +void LeadActor::onWalkEnd() { + State oldNextState = _nextState; + _state = kReady; + _nextState = kUnk_Loading; + if (_recipient && oldNextState == kInDialog1){ + // if use click not impl + sendLeftClickMessage(_recipient); + } +} + +bool LeadActor::sendUseClickMessage(SupportingActor *actor) { + return false; +} + +bool LeadActor::sendLeftClickMessage(SupportingActor *actor) { + actor->onLeftClickMessage(); + _nextState = _state != kPlayingVideo ? kReady : kPlayingVideo; + _state = kInDialog1; + return false; +} + void ParlSqPink::toConsole() { debug("ParlSqPink: _name = %s", _name.c_str()); for (int i = 0; i < _actions.size(); ++i) { diff --git a/engines/pink/objects/actors/lead_actor.h b/engines/pink/objects/actors/lead_actor.h index 208bfaad24..261b5dcf25 100644 --- a/engines/pink/objects/actors/lead_actor.h +++ b/engines/pink/objects/actors/lead_actor.h @@ -27,12 +27,15 @@ #include <common/rect.h> #include "actor.h" + namespace Pink { class CursorMgr; class WalkMgr; class Sequencer; +class SupportingActor; + class LeadActor : public Actor { public: enum State { @@ -62,14 +65,22 @@ public: void onKeyboardButtonClick(Common::KeyCode code); void onLeftButtonClick(Common::Point point); void onMouseMove(Common::Point point); + void onWalkEnd(); virtual void onMouseOver(Common::Point point, CursorMgr *mgr); private: void updateCursor(Common::Point point); + bool sendUseClickMessage(SupportingActor *actor); + bool sendLeftClickMessage(SupportingActor *actor); + State _state; + State _nextState; + + SupportingActor *_recipient; + CursorMgr *_cursorMgr; WalkMgr *_walkMgr; Sequencer *_sequencer; diff --git a/engines/pink/objects/actors/supporting_actor.cpp b/engines/pink/objects/actors/supporting_actor.cpp index a7e1b79954..d43f871c6f 100644 --- a/engines/pink/objects/actors/supporting_actor.cpp +++ b/engines/pink/objects/actors/supporting_actor.cpp @@ -57,4 +57,20 @@ bool SupportingActor::isLeftClickHandlers() { return _handlerMgr.isLeftClickHandler(this); } +void SupportingActor::onTimerMessage() { + _handlerMgr.onTimerMessage(this); +} + +bool SupportingActor::onLeftClickMessage() { + return _handlerMgr.onLeftClickMessage(this); +} + +bool SupportingActor::onUseClickMessage() { + return _handlerMgr.onUseClickMessage(this); +} + +const Common::String &SupportingActor::getLocation() const { + return _location; +} + } // End of namespace Pink
\ No newline at end of file diff --git a/engines/pink/objects/actors/supporting_actor.h b/engines/pink/objects/actors/supporting_actor.h index bfee083dbd..2888582041 100644 --- a/engines/pink/objects/actors/supporting_actor.h +++ b/engines/pink/objects/actors/supporting_actor.h @@ -38,6 +38,13 @@ public: virtual bool isClickable() { return 1; } bool isLeftClickHandlers(); + void onTimerMessage(); + bool onLeftClickMessage(); + bool onUseClickMessage(); + + const Common::String &getLocation() const; + + private: HandlerMgr _handlerMgr; Common::String _location; diff --git a/engines/pink/objects/handlers/handler.cpp b/engines/pink/objects/handlers/handler.cpp index 8916bc0b3b..7c2bcaad8d 100644 --- a/engines/pink/objects/handlers/handler.cpp +++ b/engines/pink/objects/handlers/handler.cpp @@ -46,13 +46,13 @@ bool Handler::isSuitable(Actor *actor) { return true; } -void Handler::executeSideEffects(LeadActor *actor) { +void Handler::executeSideEffects(Actor *actor) { for (int i = 0; i < _sideEffects.size(); ++i) { _sideEffects[i]->execute(actor); } } -void Handler::onMessage(LeadActor *actor) { +void Handler::handle(Actor *actor) { executeSideEffects(actor); } @@ -70,8 +70,8 @@ void HandlerSequences::deserialize(Archive &archive) { archive >> _sequences; } -void HandlerSequences::onMessage(LeadActor *actor) { - Handler::onMessage(actor); +void HandlerSequences::handle(Actor *actor) { + Handler::handle(actor); Sequencer *sequencer = actor->getSequencer(); assert(!_sequences.empty()); @@ -84,10 +84,10 @@ void HandlerSequences::onMessage(LeadActor *actor) { assert(sequence); sequencer->authorSequence(sequence, 0); - handle(sequence); + execute(sequence); } -void HandlerStartPage::handle(Sequence *sequence) { +void HandlerStartPage::execute(Sequence *sequence) { sequence->_unk = 1; } @@ -152,7 +152,7 @@ void HandlerUseClick::toConsole() { } } -void HandlerUseClick::handle(Sequence *sequence) { +void HandlerUseClick::execute(Sequence *sequence) { } diff --git a/engines/pink/objects/handlers/handler.h b/engines/pink/objects/handlers/handler.h index ed42ed7cde..47f9ab8df5 100644 --- a/engines/pink/objects/handlers/handler.h +++ b/engines/pink/objects/handlers/handler.h @@ -39,11 +39,11 @@ class Handler : public Object { public: ~Handler(); virtual void deserialize(Archive &archive); - virtual void onMessage(LeadActor *actor); + virtual void handle(Actor *actor); bool isSuitable(Actor *actor); protected: - void executeSideEffects(LeadActor *actor); + void executeSideEffects(Actor *actor); Common::Array<Condition*> _conditions; Common::Array<SideEffect*> _sideEffects; @@ -54,10 +54,10 @@ class Sequence; class HandlerSequences : public Handler { public: virtual void deserialize(Archive &archive); - virtual void onMessage(LeadActor *actor); + virtual void handle(Actor *actor); protected: - virtual void handle(Sequence *sequence) = 0; + virtual void execute(Sequence *sequence) = 0; Common::StringArray _sequences; }; @@ -67,7 +67,7 @@ public: virtual void toConsole(); private: - virtual void handle(Sequence *sequence); + virtual void execute(Sequence *sequence); }; class HandlerLeftClick : public HandlerSequences { @@ -75,7 +75,7 @@ public: virtual void toConsole(); private: - virtual void handle(Sequence *sequence) {} + virtual void execute(Sequence *sequence) {} }; class HandlerUseClick : public HandlerSequences { @@ -84,7 +84,7 @@ public: virtual void toConsole(); private: - virtual void handle(Sequence *sequence); + virtual void execute(Sequence *sequence); Common::String _inventoryItem; Common::String _recepient; diff --git a/engines/pink/objects/handlers/handler_mgr.cpp b/engines/pink/objects/handlers/handler_mgr.cpp index 83236de6a1..76c2cf6834 100644 --- a/engines/pink/objects/handlers/handler_mgr.cpp +++ b/engines/pink/objects/handlers/handler_mgr.cpp @@ -36,4 +36,55 @@ bool HandlerMgr::isLeftClickHandler(Actor *actor) { return false; } +void HandlerMgr::onTimerMessage(Actor *actor) { + Handler *handler = findSuitableHandlerTimer(actor); + if (handler) + handler->handle(actor); +} + +bool HandlerMgr::onLeftClickMessage(Actor *actor) { + Handler *handler = findSuitableHandlerLeftClick(actor); + if (handler) { + handler->handle(actor); + return 1; + } + return 0; +} + +bool HandlerMgr::onUseClickMessage(Actor *actor) { + Handler *handler = findSuitableHandlerUseClick(actor); + if (handler) { + handler->handle(actor); + return 1; + } + return 0; +} + +Handler *HandlerMgr::findSuitableHandlerTimer(Actor *actor) { + for (int i = 0; i < _timerHandlers.size(); ++i) { + if (_timerHandlers[i]->isSuitable(actor)) + return _timerHandlers[i]; + } + + return nullptr; +} + +Handler *HandlerMgr::findSuitableHandlerLeftClick(Actor *actor) { + for (int i = 0; i < _leftClickHandlers.size(); ++i) { + if (_leftClickHandlers[i]->isSuitable(actor)) + return _leftClickHandlers[i]; + } + + return nullptr; +} + +Handler *HandlerMgr::findSuitableHandlerUseClick(Actor *actor) { + for (int i = 0; i < _useClickHandlers.size(); ++i) { + if (_useClickHandlers[i]->isSuitable(actor)) + return _useClickHandlers[i]; + } + + return nullptr; +} + } diff --git a/engines/pink/objects/handlers/handler_mgr.h b/engines/pink/objects/handlers/handler_mgr.h index f939d592da..08160870da 100644 --- a/engines/pink/objects/handlers/handler_mgr.h +++ b/engines/pink/objects/handlers/handler_mgr.h @@ -28,6 +28,7 @@ namespace Pink { +class Handler; class HandlerLeftClick; class HandlerUseClick; class HandlerTimer; @@ -41,7 +42,15 @@ public: bool isLeftClickHandler(Actor *actor); + void onTimerMessage(Actor *actor); + bool onLeftClickMessage(Actor *actor); + bool onUseClickMessage(Actor *actor); + private: + Handler *findSuitableHandlerTimer(Actor *actor); + Handler *findSuitableHandlerLeftClick(Actor *actor); + Handler *findSuitableHandlerUseClick(Actor *actor); + Common::Array<HandlerLeftClick*> _leftClickHandlers; Common::Array<HandlerUseClick*> _useClickHandlers; Common::Array<HandlerTimer*> _timerHandlers; diff --git a/engines/pink/objects/handlers/handler_timer.cpp b/engines/pink/objects/handlers/handler_timer.cpp index 44d58c2b32..6fdbce1c5f 100644 --- a/engines/pink/objects/handlers/handler_timer.cpp +++ b/engines/pink/objects/handlers/handler_timer.cpp @@ -59,8 +59,8 @@ void HandlerTimerActions::toConsole() { } } -void HandlerTimerActions::onMessage(LeadActor *actor) { - Handler::onMessage(actor); +void HandlerTimerActions::handle(Actor *actor) { + Handler::handle(actor); assert(_actions.size()); if (!actor->isPlaying()){ Common::RandomSource &rnd = actor->getPage()->getGame()->getRnd(); @@ -72,7 +72,7 @@ void HandlerTimerActions::onMessage(LeadActor *actor) { } -void HandlerTimerSequences::handle(Sequence *sequence) { +void HandlerTimerSequences::execute(Sequence *sequence) { debug("HandlerTimerSequences function is not implemented"); } diff --git a/engines/pink/objects/handlers/handler_timer.h b/engines/pink/objects/handlers/handler_timer.h index 1147431e4b..540c7dcc6c 100644 --- a/engines/pink/objects/handlers/handler_timer.h +++ b/engines/pink/objects/handlers/handler_timer.h @@ -42,7 +42,7 @@ class HandlerTimerActions : public HandlerTimer { public: virtual void toConsole(); virtual void deserialize(Archive &archive); - virtual void onMessage(LeadActor *actor); + virtual void handle(Actor *actor); private: Common::StringArray _actions; @@ -53,7 +53,7 @@ class HandlerTimerSequences : public HandlerSequences { //originally it was inhe public: virtual void toConsole(); protected: - virtual void handle(Sequence *sequence); // very big and hard function + virtual void execute(Sequence *sequence); // very big and hard function }; } // End of namespace Pink diff --git a/engines/pink/objects/module.cpp b/engines/pink/objects/module.cpp index f7b6adda87..dc9a06ec1e 100644 --- a/engines/pink/objects/module.cpp +++ b/engines/pink/objects/module.cpp @@ -65,7 +65,9 @@ void Module::changePage(const Common::String &pageName) { //_page->clear - page->init(kLoadingNewGame); + + _page = page; + _page->init(kLoadingNewGame); } GamePage *Module::findPage(const Common::String &pageName) const { diff --git a/engines/pink/objects/pages/game_page.cpp b/engines/pink/objects/pages/game_page.cpp index 6a90b4887b..c878180c4a 100644 --- a/engines/pink/objects/pages/game_page.cpp +++ b/engines/pink/objects/pages/game_page.cpp @@ -83,7 +83,7 @@ void GamePage::init(bool isLoadingSave) { bool GamePage::initHandler() { for (uint i = 0; i < _handlers.size(); ++i) { if (_handlers[i]->isSuitable(_leadActor)){ - _handlers[i]->onMessage(_leadActor); + _handlers[i]->handle(_leadActor); return true; } } diff --git a/engines/pink/objects/pages/page.cpp b/engines/pink/objects/pages/page.cpp index a579d19d5f..471cf8736b 100644 --- a/engines/pink/objects/pages/page.cpp +++ b/engines/pink/objects/pages/page.cpp @@ -71,4 +71,8 @@ Page::~Page() { } } +LeadActor *Page::getLeadActor() { + return _leadActor; +} + } // End of namespace Pink diff --git a/engines/pink/objects/pages/page.h b/engines/pink/objects/pages/page.h index 81a49db9f6..7eb1a335f3 100644 --- a/engines/pink/objects/pages/page.h +++ b/engines/pink/objects/pages/page.h @@ -39,11 +39,13 @@ public: ~Page(); void load(Archive &archive); Actor *findActor(Common::String &name); - Sound* loadSound(Common::String &fileName); + Sound *loadSound(Common::String &fileName); CelDecoder *loadCel(Common::String &fileName); virtual void toConsole(); + LeadActor *getLeadActor(); + protected: void init(); Common::Array<Actor*> _actors; diff --git a/engines/pink/objects/sequences/seq_timer.cpp b/engines/pink/objects/sequences/seq_timer.cpp index d2b761cfed..d5029e60fb 100644 --- a/engines/pink/objects/sequences/seq_timer.cpp +++ b/engines/pink/objects/sequences/seq_timer.cpp @@ -24,11 +24,14 @@ #include <engines/pink/archive.h> #include "./sequencer.h" #include <common/debug.h> +#include <engines/pink/objects/actors/supporting_actor.h> +#include "pink/objects/pages/game_page.h" +#include "pink/pink.h" namespace Pink { SeqTimer::SeqTimer() - : _unk(0) { + : _updatesToMessage(0) { } @@ -43,4 +46,21 @@ void SeqTimer::toConsole() { debug("\tSeqTimer: _actor=%s _period=%u _range=%u", _actor.c_str(), _period, _range); } +void SeqTimer::update() { + Common::RandomSource &random =_sequencer->_page->getGame()->getRnd(); + if (_updatesToMessage--) + return; + + calculateUpdatesCount(); + SupportingActor *actor = static_cast<SupportingActor*>(_sequencer->_page->findActor(_actor)); + if (!_sequencer->findSequenceActorState(actor->getName())){ + actor->onTimerMessage(); + } +} + +void SeqTimer::calculateUpdatesCount() { + Common::RandomSource &random =_sequencer->_page->getGame()->getRnd(); + _updatesToMessage = _range ? _period + random.getRandomNumber(_range) : _period; +} + } // End of namespace Pink
\ No newline at end of file diff --git a/engines/pink/objects/sequences/seq_timer.h b/engines/pink/objects/sequences/seq_timer.h index 4319b9279a..0b961c0c25 100644 --- a/engines/pink/objects/sequences/seq_timer.h +++ b/engines/pink/objects/sequences/seq_timer.h @@ -35,12 +35,16 @@ public: virtual void deserialize(Archive &archive); virtual void toConsole(); + virtual void update(); + + private: + void calculateUpdatesCount(); Common::String _actor; + Sequencer *_sequencer; int _period; int _range; - int _unk; - Sequencer *_sequencer; + int _updatesToMessage; }; } // End of namespace Pink diff --git a/engines/pink/objects/sequences/sequence.cpp b/engines/pink/objects/sequences/sequence.cpp index 098330bf03..b95605758c 100644 --- a/engines/pink/objects/sequences/sequence.cpp +++ b/engines/pink/objects/sequences/sequence.cpp @@ -119,7 +119,7 @@ void Sequence::restart() { void Sequence::skipToLastSubSequence() { if (_unk && _context->getNextItemIndex() < _items.size()){ int i = _items.size() - 1; - while(i >= 0 && !_items[i--]->isLeader()); + while(i >= 0 && !_items[--i]->isLeader()); assert(i >= 0); _context->setNextItemIndex(i); _context->clearActionsFromActorStates(); diff --git a/engines/pink/objects/sequences/sequence_item.cpp b/engines/pink/objects/sequences/sequence_item.cpp index 5ea7b7468d..c7b5213f3e 100644 --- a/engines/pink/objects/sequences/sequence_item.cpp +++ b/engines/pink/objects/sequences/sequence_item.cpp @@ -58,14 +58,10 @@ bool SequenceItem::execute(int index, Sequence *sequence, bool unk2) { } actor->setAction(action, unk2); - Common::Array<SequenceActorState> &states = sequence->_context->_states; - for (int i = 0; i < sequence->_context->_states.size(); ++i) { - if (states[i]._actorName == _actor){ - states[i]._index = index; - sequence->_context->_actor = isLeader() ? actor : sequence->_context->_actor; - break; - } - } + + SequenceActorState *state = sequence->_sequencer->findSequenceActorState(_actor); + state->_index = index; + sequence->_context->_actor = isLeader() ? actor : sequence->_context->_actor; return true; } @@ -97,13 +93,8 @@ uint32 SequenceItemLeaderAudio::getSample() { } bool SequenceItemDefaultAction::execute(int index, Sequence *sequence, bool unk2) { - Common::Array<SequenceActorState> &actorStates = sequence->_context->_states; - for (int i = 0; i < actorStates.size(); ++i) { - if (actorStates[i]._actorName == _actor){ - actorStates[i]._actionName = _action; - break; - } - } + SequenceActorState *state = sequence->_sequencer->findSequenceActorState(_actor); + state->_actionName = _action; return true; } diff --git a/engines/pink/objects/sequences/sequencer.cpp b/engines/pink/objects/sequences/sequencer.cpp index 871a2e2621..f996dc1b1e 100644 --- a/engines/pink/objects/sequences/sequencer.cpp +++ b/engines/pink/objects/sequences/sequencer.cpp @@ -27,11 +27,14 @@ #include "sequence_context.h" #include "pink/objects/actors/actor.h" #include "engines/pink/archive.h" +#include "pink/objects/pages/game_page.h" +#include "pink/pink.h" +#include "pink/objects/sequences/seq_timer.h" namespace Pink { Sequencer::Sequencer(GamePage *page) - : _context(nullptr), _page(page) + : _context(nullptr), _page(page), _time(0) {} Sequencer::~Sequencer() { @@ -70,11 +73,15 @@ void Sequencer::toConsole() { for (int i = 0; i < _sequences.size(); ++i) { _sequences[i]->toConsole(); } + for (int i = 0; i < _timers.size(); ++i) { + _timers[i]->toConsole(); + } } void Sequencer::update() { if (_context) _context->_sequence->update(); + updateTimers(); } void Sequencer::removeContext(SequenceContext *context) { @@ -95,4 +102,28 @@ void Sequencer::skipToLastSubSequence() { _context->getSequence()->skipToLastSubSequence(); } +void Sequencer::updateTimers() { + uint time = _page->getGame()->getTotalPlayTime(); + if (time - _time <= 0x64) { + return; + } + + _time = time; + for (int i = 0; i < _timers.size(); ++i) { + _timers[i]->update(); + } +} + +SequenceActorState *Sequencer::findSequenceActorState(const Common::String &name) { + if (!_context) + return nullptr; + + for (int i = 0; i < _context->_states.size(); ++i) { + if (_context->_states[i].getActor() == name) + return &_context->_states[i]; + } + + return nullptr; +} + } // End of namespace Pink
\ No newline at end of file diff --git a/engines/pink/objects/sequences/sequencer.h b/engines/pink/objects/sequences/sequencer.h index f453ffbf22..1ae4689114 100644 --- a/engines/pink/objects/sequences/sequencer.h +++ b/engines/pink/objects/sequences/sequencer.h @@ -33,6 +33,7 @@ class Sequence; class SequenceContext; class GamePage; class SeqTimer; +class SequenceActorState; class Sequencer : public Object { public: @@ -43,6 +44,8 @@ public: virtual void deserialize(Archive &archive); Sequence* findSequence(const Common::String &name); + SequenceActorState *findSequenceActorState(const Common::String &name); + void authorSequence(Sequence *sequence, bool unk); void removeContext(SequenceContext *context); @@ -54,13 +57,15 @@ public: void skipToLastSubSequence(); public: + void updateTimers(); + SequenceContext *_context; // context array Common::Array<Sequence*> _sequences; Common::String _currentSequenceName; Common::Array<SeqTimer*> _timers; GamePage *_page; - int unk; + uint _time; }; } // End of namespace Pink diff --git a/engines/pink/objects/side_effect.cpp b/engines/pink/objects/side_effect.cpp index 124ba8a1a0..1790917dd2 100644 --- a/engines/pink/objects/side_effect.cpp +++ b/engines/pink/objects/side_effect.cpp @@ -36,8 +36,8 @@ void SideEffectExit::deserialize(Archive &archive) { archive >> _nextModule >> _nextPage; } -void SideEffectExit::execute(LeadActor *actor) { - actor->setNextExecutors(_nextModule, _nextPage); +void SideEffectExit::execute(Actor *actor) { + actor->getPage()->getLeadActor()->setNextExecutors(_nextModule, _nextPage); } void SideEffectExit::toConsole() { @@ -48,10 +48,11 @@ void SideEffectLocation::deserialize(Archive &archive) { archive >> _location; } -void SideEffectLocation::execute(LeadActor *actor) { +void SideEffectLocation::execute(Actor *actor) { WalkMgr *mgr = actor->getPage()->getWalkMgr(); WalkLocation *location = mgr->findLocation(_location); - //TODO end this method + assert(location); + mgr->setCurrentWayPoint(location); } void SideEffectLocation::toConsole() { @@ -62,8 +63,10 @@ void SideEffectInventoryItemOwner::deserialize(Archive &archive) { archive >> _item >> _owner; } -void SideEffectInventoryItemOwner::execute(LeadActor *actor) { - //TODO +void SideEffectInventoryItemOwner::execute(Actor *actor) { + InventoryMgr *mgr = actor->getPage()->getModule()->getInventoryMgr(); + InventoryItem *item = mgr->findInventoryItem(_item); + mgr->setItemOwner(_item, item); } void SideEffectInventoryItemOwner::toConsole() { @@ -74,7 +77,7 @@ void SideEffectVariable::deserialize(Pink::Archive &archive) { archive >> _name >> _value; } -void SideEffectGameVariable::execute(LeadActor *actor) { +void SideEffectGameVariable::execute(Actor *actor) { actor->getPage()->getGame()->setVariable(_name, _value); } @@ -82,7 +85,7 @@ void SideEffectGameVariable::toConsole() { debug("\t\tSideEffectGameVariable: _name=%s, _value=%s", _name.c_str(), _value.c_str()); } -void SideEffectModuleVariable::execute(LeadActor *actor) { +void SideEffectModuleVariable::execute(Actor *actor) { actor->getPage()->getModule()->setVariable(_name, _value); } @@ -90,7 +93,7 @@ void SideEffectModuleVariable::toConsole() { debug("\t\tSideEffectModuleVariable: _name=%s, _value=%s", _name.c_str(), _value.c_str()); } -void SideEffectPageVariable::execute(LeadActor *actor) { +void SideEffectPageVariable::execute(Actor *actor) { actor->getPage()->setVariable(_name, _value); } @@ -102,7 +105,7 @@ void SideEffectRandomPageVariable::deserialize(Archive &archive) { archive >> _name >> _values; } -void SideEffectRandomPageVariable::execute(LeadActor *actor) { +void SideEffectRandomPageVariable::execute(Actor *actor) { assert(!_values.empty()); Common::RandomSource &rnd = actor->getPage()->getGame()->getRnd(); diff --git a/engines/pink/objects/side_effect.h b/engines/pink/objects/side_effect.h index 4542b7f9e1..b184eb68bf 100644 --- a/engines/pink/objects/side_effect.h +++ b/engines/pink/objects/side_effect.h @@ -28,19 +28,19 @@ namespace Pink { -class LeadActor; +class Actor; class SideEffect : public Object { public: virtual void deserialize(Archive &archive) = 0; - virtual void execute(LeadActor *actor) = 0; + virtual void execute(Actor *actor) = 0; }; class SideEffectExit : public SideEffect { public: virtual void deserialize(Archive &archive); virtual void toConsole(); - virtual void execute(LeadActor *actor); + virtual void execute(Actor *actor); private: Common::String _nextModule; @@ -50,7 +50,7 @@ private: class SideEffectLocation : public SideEffect { public: virtual void deserialize(Archive &archive); - virtual void execute(LeadActor *actor); + virtual void execute(Actor *actor); virtual void toConsole(); private: @@ -60,7 +60,7 @@ private: class SideEffectInventoryItemOwner : public SideEffect { public: virtual void deserialize(Archive &archive); - virtual void execute(LeadActor *actor); + virtual void execute(Actor *actor); virtual void toConsole(); private: @@ -71,7 +71,7 @@ private: class SideEffectVariable : public SideEffect { public: virtual void deserialize(Archive &archive); - virtual void execute(LeadActor *actor) = 0; + virtual void execute(Actor *actor) = 0; protected: Common::String _name; @@ -81,19 +81,19 @@ protected: class SideEffectGameVariable : public SideEffectVariable { public: virtual void toConsole(); - virtual void execute(LeadActor *actor); + virtual void execute(Actor *actor); }; class SideEffectModuleVariable : public SideEffectVariable { public: virtual void toConsole(); - virtual void execute(LeadActor *actor); + virtual void execute(Actor *actor); }; class SideEffectPageVariable : public SideEffectVariable { public: virtual void toConsole(); - virtual void execute(LeadActor *actor); + virtual void execute(Actor *actor); }; class SideEffectRandomPageVariable : public SideEffect @@ -101,7 +101,7 @@ class SideEffectRandomPageVariable : public SideEffect public: virtual void deserialize(Archive &archive); virtual void toConsole(); - virtual void execute(LeadActor *actor); + virtual void execute(Actor *actor); private: Common::String _name; diff --git a/engines/pink/objects/walk/walk_location.cpp b/engines/pink/objects/walk/walk_location.cpp index e5f5ea7535..c4b56d95db 100644 --- a/engines/pink/objects/walk/walk_location.cpp +++ b/engines/pink/objects/walk/walk_location.cpp @@ -20,10 +20,23 @@ * */ +#include <common/debug.h> #include "walk_location.h" #include "engines/pink/archive.h" -void Pink::WalkLocation::deserialize(Pink::Archive &archive) { +namespace Pink { + +void WalkLocation::deserialize(Pink::Archive &archive) { NamedObject::deserialize(archive); archive >> _neighbors; } + +void WalkLocation::toConsole() { + debug("\tWalkLocation: _name =%s", _name.c_str()); + debug("\tNeighbors:"); + for (int i = 0; i < _neighbors.size(); ++i) { + debug("\t\t%s", _neighbors[i].c_str()); + } +} + +} // End of namespace Pink;
\ No newline at end of file diff --git a/engines/pink/objects/walk/walk_location.h b/engines/pink/objects/walk/walk_location.h index 82e6436b77..b9515cdc10 100644 --- a/engines/pink/objects/walk/walk_location.h +++ b/engines/pink/objects/walk/walk_location.h @@ -33,6 +33,8 @@ class WalkLocation : public NamedObject { public: virtual void deserialize(Archive &archive); + void toConsole() override; + Common::StringArray &getNeigbors() { return _neighbors;} private: Common::StringArray _neighbors; }; diff --git a/engines/pink/objects/walk/walk_mgr.cpp b/engines/pink/objects/walk/walk_mgr.cpp index 1b5ceef210..0cacbd07f6 100644 --- a/engines/pink/objects/walk/walk_mgr.cpp +++ b/engines/pink/objects/walk/walk_mgr.cpp @@ -1,20 +1,153 @@ -// -// Created by andrei on 3/17/18. -// +/* 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 "walk_mgr.h" #include "walk_location.h" +#include "engines/pink/objects/actions/walk_action.h" #include "engines/pink/objects/actors/lead_actor.h" #include "engines/pink/archive.h" +#include "pink/cel_decoder.h" +namespace Pink { -void Pink::WalkMgr::deserialize(Pink::Archive &archive) { - _leadActor = static_cast<LeadActor*>(archive.readObject()); +WalkMgr::WalkMgr() + : _isWalking(false), _leadActor(nullptr) +{ + +} + +void WalkMgr::deserialize(Pink::Archive &archive) { + _leadActor = static_cast<LeadActor *>(archive.readObject()); archive >> _locations; } -Pink::WalkLocation *Pink::WalkMgr::findLocation(Common::String &name) { - return *Common::find_if(_locations.begin(), _locations.end(), [&name] (WalkLocation *location) { +WalkLocation *WalkMgr::findLocation(const Common::String &name) { + auto it = Common::find_if(_locations.begin(), _locations.end(), [&name](WalkLocation *location) { return location->getName() == name; }); + if (it == _locations.end()) + return nullptr; + + return *it; +} + +void WalkMgr::toConsole() { + debug("WalkMgr:"); + for (int i = 0; i < _locations.size(); ++i) { + _locations[i]->toConsole(); + } +} + +void WalkMgr::start(WalkLocation *destination) { + if (_isWalking) + return; + + if (_current.name.empty()) { + _current.name = _locations[0]->getName(); + _current.coord = getLocationCoordinates(_locations[0]->getName()); + } + + _destination = destination; + + if (_current.name == _destination->getName()) { + end(); + } + else { + _isWalking = true; + WalkLocation *currentLocation = findLocation(_current.name); + WalkShortestPath path(this); + WalkLocation *nextLocation = path.next(currentLocation, _destination); + initNextWayPoint(nextLocation); + _leadActor->setAction(getWalkAction(), 0); + } +} + +void WalkMgr::initNextWayPoint(WalkLocation *location) { + _next.name = location->getName(); + _next.coord = getLocationCoordinates(location->getName()); +} + +WalkAction *WalkMgr::getWalkAction() { + Common::String walkActionName; + if (_current.coord.z == _next.coord.z){ + if (_next.coord.x > _current.coord.x){ + walkActionName = Common::String::format("%dRight", _current.coord.z); + } + else walkActionName = Common::String::format("%dLeft", _next.coord.z); + } + else walkActionName = Common::String::format("%dTo%d", _current.coord.z, _next.coord.z); + + Action *action = _leadActor->findAction(walkActionName); + + + return static_cast<WalkAction*>(action); } + +double WalkMgr::getLengthBetweenLocations(WalkLocation *first, WalkLocation *second) { + Coordinates firstCoord = getLocationCoordinates(first->getName()); + Coordinates secondCoord = getLocationCoordinates(second->getName()); + return sqrt((secondCoord.x - firstCoord.x) * (secondCoord.x - firstCoord.x) + + (secondCoord.y - firstCoord.y) * (secondCoord.y - firstCoord.y)); +} + +WalkMgr::Coordinates WalkMgr::getLocationCoordinates(const Common::String &locationName) { + Coordinates coords; + ActionCEL *action = static_cast<ActionCEL*>(_leadActor->findAction(locationName)); + + action->start(0); + CelDecoder *decoder = action->getDecoder(); + + coords.x = decoder->getX() + decoder->getWidth() / 2; + coords.y = decoder->getY() + decoder->getHeight() / 2; + coords.z = action->getZ(); + + action->end(); + + return coords; +} + +void WalkMgr::setCurrentWayPoint(WalkLocation *location) { + _current.name = location->getName(); + _current.coord = getLocationCoordinates(_current.name); +} + +void WalkMgr::update() { + if (_leadActor->isPlaying()) + return; + + WalkShortestPath path(this); + _current = _next; + WalkLocation *next = path.next(findLocation(_current.name), _destination); + if (next){ + initNextWayPoint(next); + _leadActor->setAction(getWalkAction(), 0); + } + else end(); + +} + +void WalkMgr::end() { + _isWalking = false; + _leadActor->onWalkEnd(); +} + +} // End of namespace Pink
\ No newline at end of file diff --git a/engines/pink/objects/walk/walk_mgr.h b/engines/pink/objects/walk/walk_mgr.h index 0ae7ef6194..403cc7ee2e 100644 --- a/engines/pink/objects/walk/walk_mgr.h +++ b/engines/pink/objects/walk/walk_mgr.h @@ -25,20 +25,49 @@ #include <common/array.h> #include "engines/pink/objects/object.h" +#include "walk_shortest_path.h" namespace Pink { class WalkLocation; class LeadActor; +class WalkAction; class WalkMgr : public Object { public: + WalkMgr(); virtual void deserialize(Archive &archive); - WalkLocation *findLocation(Common::String &name); + void toConsole() override; + + WalkLocation *findLocation(const Common::String &name); + void start(WalkLocation *destination); + void update(); + + double getLengthBetweenLocations(WalkLocation *first, WalkLocation *second); + void setCurrentWayPoint(WalkLocation *location); private: + struct Coordinates { + int x; + int y; + int z; + }; + struct WayPoint { + Common::String name; + Coordinates coord; + }; + + Coordinates getLocationCoordinates(const Common::String &locationName); + void end(); + void initNextWayPoint(WalkLocation *location); + WalkAction *getWalkAction(); + LeadActor *_leadActor; + WalkLocation *_destination; Common::Array<WalkLocation*> _locations; + WayPoint _current; + WayPoint _next; + bool _isWalking; }; } // End of namespace Pink diff --git a/engines/pink/objects/walk/walk_shortest_path.cpp b/engines/pink/objects/walk/walk_shortest_path.cpp new file mode 100644 index 0000000000..77562e81cb --- /dev/null +++ b/engines/pink/objects/walk/walk_shortest_path.cpp @@ -0,0 +1,159 @@ +/* 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 "walk_shortest_path.h" +#include "walk_mgr.h" +#include "walk_location.h" + +namespace Pink { + +WalkShortestPath::WalkShortestPath(WalkMgr *manager) + : _manager(manager) +{} + +WalkLocation *WalkShortestPath::next(WalkLocation *start, WalkLocation *destination) { + if (start == destination) + return nullptr; + add(start, 0.0, 0); + while (build() != destination); + return getNearestNeighbor(destination); +} + +void WalkShortestPath::add(WalkLocation *wl, double val, WalkLocation *nearest) { + _locations.push_back(wl); + _visited.push_back(wl); + _weight.push_back(val); + _nearestNeigbor.push_back(nearest); +} + +WalkLocation *WalkShortestPath::build() { + WalkLocation *nearest = nullptr; + WalkLocation *location = nullptr; + double len = -1.0; + addLocationsToVisit(); + for (int i = 0; i < _toVisit.size(); ++i) { + double curLen = getLengthToNearestNeigbor(_toVisit[i]); + if (curLen < 0) { + remove(_toVisit[i]); + continue; + } + curLen += getWeight(_toVisit[i]); + if (len < 0.0 || len > curLen) { + len = curLen; + location = _toVisit[i]; + nearest = getNearestNeighbor(_toVisit[i]); + if (!nearest) + nearest = findNearestNeighbor(_toVisit[i]); + } + } + + WalkLocation *neighbor = findNearestNeighbor(location); + if (neighbor) + add(neighbor, len, nearest); + + return neighbor; +} + +WalkLocation *WalkShortestPath::getNearestNeighbor(WalkLocation *location) { + for(int i = 0; i < _visited.size(); ++i){ + if (_visited[i] == location) + return _nearestNeigbor[i]; + } + + return nullptr; +} + +void WalkShortestPath::addLocationsToVisit() { + _toVisit.resize(_locations.size()); + for (int i = 0; i < _locations.size(); ++i) { + _toVisit[i] = _locations[i]; + } +} + +double WalkShortestPath::getLengthToNearestNeigbor(WalkLocation *location) { + double minLength = -1.0; + auto &neighbors = location->getNeigbors(); + for (int i = 0; i < neighbors.size(); ++i) { + WalkLocation *neighbor = _manager->findLocation(neighbors[i]); + if (!isLocationVisited(neighbor)){ + double length = _manager->getLengthBetweenLocations(location, neighbor); + if (minLength >= 0.0) { + if (length < minLength) + minLength = length; + } + else minLength = length; + } + } + + return minLength; +} + +WalkLocation *WalkShortestPath::findNearestNeighbor(WalkLocation *location) { + double minLength = -1.0; + WalkLocation *nearest = nullptr; + auto neighbors = location->getNeigbors(); + for (int i = 0; i < neighbors.size(); ++i) { + WalkLocation *neighbor = _manager->findLocation(neighbors[i]); + if (!isLocationVisited(neighbor)){ + double length = _manager->getLengthBetweenLocations(location, neighbor); + if (minLength >= 0.0) { + if (length < minLength) { + nearest = neighbor; + minLength = length; + } + } + else { + nearest = neighbor; + minLength = length; + } + } + } + + return nearest; +} + +double WalkShortestPath::getWeight(WalkLocation *location) { + for (int i = 0; i < _locations.size(); ++i) { + if (_locations[i] == location) + return _weight[i]; + } + return 0.0; +} + +bool WalkShortestPath::isLocationVisited(WalkLocation *location) { + for (int i = 0; i < _visited.size(); ++i) { + if (_visited[i] == location) + return 1; + } + return 0; +} + +void WalkShortestPath::remove(WalkLocation *location) { + for (int i = 0; i < _locations.size(); ++i) { + if (_locations[i] == location){ + _locations.remove_at(i); + _weight.remove_at(i); + } + } +} + +} // End of namespace Pink
\ No newline at end of file diff --git a/engines/pink/objects/walk/walk_shortest_path.h b/engines/pink/objects/walk/walk_shortest_path.h new file mode 100644 index 0000000000..8b7dc803b4 --- /dev/null +++ b/engines/pink/objects/walk/walk_shortest_path.h @@ -0,0 +1,61 @@ +/* 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. + * + */ + +#ifndef PINK_WALK_SHORTEST_PATH_H +#define PINK_WALK_SHORTEST_PATH_H + +#include <common/array.h> + +namespace Pink { + +class WalkLocation; +class WalkMgr; + +class WalkShortestPath { +public: + WalkShortestPath(WalkMgr *manager); + WalkLocation *next(WalkLocation *start, WalkLocation *destination); + +private: + void add(WalkLocation *wl, double val, WalkLocation *nearest); + void remove(WalkLocation *location); + WalkLocation *build(); + WalkLocation *getNearestNeighbor(WalkLocation *location); + WalkLocation *findNearestNeighbor(WalkLocation *location); + double getLengthToNearestNeigbor(WalkLocation *location); + double getWeight(WalkLocation *location); + void addLocationsToVisit(); + bool isLocationVisited(WalkLocation *location); + + + WalkMgr *_manager; + Common::Array<WalkLocation*> _locations; + Common::Array<WalkLocation*> _toVisit; + Common::Array<double> _weight; + Common::Array<WalkLocation*> _visited; + Common::Array<WalkLocation*> _nearestNeigbor; +}; + +} // End of namespace Pink + + +#endif diff --git a/engines/pink/pink.cpp b/engines/pink/pink.cpp index 9cc0ee5145..008f8277d9 100644 --- a/engines/pink/pink.cpp +++ b/engines/pink/pink.cpp @@ -30,6 +30,7 @@ #include <graphics/surface.h> #include <graphics/cursorman.h> #include <common/winexe_pe.h> +#include <common/config-manager.h> namespace Pink { diff --git a/engines/pink/sound.cpp b/engines/pink/sound.cpp index fda91e548a..a4a47bebf2 100644 --- a/engines/pink/sound.cpp +++ b/engines/pink/sound.cpp @@ -68,7 +68,7 @@ void Sound::play(Audio::Mixer::SoundType type, int volume, bool isLoop) { } else audioStream = wavStream; - _mixer->playStream(type, &_handle , audioStream, -1 , Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::YES); + _mixer->playStream(type, &_handle , audioStream, -1 , 50, 0, DisposeAfterUse::YES); } void Sound::setBalance(int8 balance) { |