aboutsummaryrefslogtreecommitdiff
path: root/engines/pink
diff options
context:
space:
mode:
authorwhiterandrek2018-04-05 08:15:14 +0300
committerEugene Sandulenko2018-06-28 23:51:32 +0200
commitcad72b1532faa96c68848392766f25a4a58398ab (patch)
tree04d5e0cbda2aadb79fce35a1ddd45f0f0798f60f /engines/pink
parent4b7c75607a5d54d95c383fabf381d82d4ac77b94 (diff)
downloadscummvm-rg350-cad72b1532faa96c68848392766f25a4a58398ab.tar.gz
scummvm-rg350-cad72b1532faa96c68848392766f25a4a58398ab.tar.bz2
scummvm-rg350-cad72b1532faa96c68848392766f25a4a58398ab.zip
PINK: basic walk, left click and seqTimer implementation
Diffstat (limited to 'engines/pink')
-rw-r--r--engines/pink/cursor_mgr.cpp2
-rw-r--r--engines/pink/director.cpp7
-rw-r--r--engines/pink/module.mk1
-rw-r--r--engines/pink/objects/actions/action_still.cpp2
-rw-r--r--engines/pink/objects/actions/walk_action.cpp5
-rw-r--r--engines/pink/objects/actions/walk_action.h3
-rw-r--r--engines/pink/objects/actors/lead_actor.cpp46
-rw-r--r--engines/pink/objects/actors/lead_actor.h11
-rw-r--r--engines/pink/objects/actors/supporting_actor.cpp16
-rw-r--r--engines/pink/objects/actors/supporting_actor.h7
-rw-r--r--engines/pink/objects/handlers/handler.cpp14
-rw-r--r--engines/pink/objects/handlers/handler.h14
-rw-r--r--engines/pink/objects/handlers/handler_mgr.cpp51
-rw-r--r--engines/pink/objects/handlers/handler_mgr.h9
-rw-r--r--engines/pink/objects/handlers/handler_timer.cpp6
-rw-r--r--engines/pink/objects/handlers/handler_timer.h4
-rw-r--r--engines/pink/objects/module.cpp4
-rw-r--r--engines/pink/objects/pages/game_page.cpp2
-rw-r--r--engines/pink/objects/pages/page.cpp4
-rw-r--r--engines/pink/objects/pages/page.h4
-rw-r--r--engines/pink/objects/sequences/seq_timer.cpp22
-rw-r--r--engines/pink/objects/sequences/seq_timer.h8
-rw-r--r--engines/pink/objects/sequences/sequence.cpp2
-rw-r--r--engines/pink/objects/sequences/sequence_item.cpp21
-rw-r--r--engines/pink/objects/sequences/sequencer.cpp33
-rw-r--r--engines/pink/objects/sequences/sequencer.h7
-rw-r--r--engines/pink/objects/side_effect.cpp23
-rw-r--r--engines/pink/objects/side_effect.h20
-rw-r--r--engines/pink/objects/walk/walk_location.cpp15
-rw-r--r--engines/pink/objects/walk/walk_location.h2
-rw-r--r--engines/pink/objects/walk/walk_mgr.cpp147
-rw-r--r--engines/pink/objects/walk/walk_mgr.h31
-rw-r--r--engines/pink/objects/walk/walk_shortest_path.cpp159
-rw-r--r--engines/pink/objects/walk/walk_shortest_path.h61
-rw-r--r--engines/pink/pink.cpp1
-rw-r--r--engines/pink/sound.cpp2
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) {