mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-19 00:15:30 +00:00
PINK: basic walk, left click and seqTimer implementation
This commit is contained in:
parent
4b7c75607a
commit
cad72b1532
@ -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);
|
||||
|
@ -42,10 +42,11 @@ void Director::draw() {
|
||||
void Director::drawSprite(ActionCEL *sprite) {
|
||||
CelDecoder *decoder = sprite->getDecoder();
|
||||
const Graphics::Surface *surface;
|
||||
if (decoder->needsUpdate())
|
||||
surface = decoder->decodeNextFrame();
|
||||
else surface = decoder->getCurrentFrame();
|
||||
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();
|
||||
|
@ -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)
|
||||
|
@ -48,6 +48,8 @@ void ActionStill::onStart() {
|
||||
for (int i = 0; i < _startFrame; ++i) {
|
||||
_decoder->decodeNextFrame();
|
||||
}
|
||||
_decoder->stop();
|
||||
_actor->endAction();
|
||||
}
|
||||
|
||||
} // End of namespace Pink
|
@ -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
|
@ -33,6 +33,9 @@ public:
|
||||
|
||||
virtual void toConsole();
|
||||
|
||||
protected:
|
||||
void onStart() override;
|
||||
|
||||
private:
|
||||
bool _toCalcFramePositions;
|
||||
};
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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");
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -71,4 +71,8 @@ Page::~Page() {
|
||||
}
|
||||
}
|
||||
|
||||
LeadActor *Page::getLeadActor() {
|
||||
return _leadActor;
|
||||
}
|
||||
|
||||
} // End of namespace Pink
|
||||
|
@ -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;
|
||||
|
@ -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
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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;
|
@ -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;
|
||||
};
|
||||
|
@ -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
|
@ -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
|
||||
|
159
engines/pink/objects/walk/walk_shortest_path.cpp
Normal file
159
engines/pink/objects/walk/walk_shortest_path.cpp
Normal file
@ -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
|
61
engines/pink/objects/walk/walk_shortest_path.h
Normal file
61
engines/pink/objects/walk/walk_shortest_path.h
Normal file
@ -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
|
@ -30,6 +30,7 @@
|
||||
#include <graphics/surface.h>
|
||||
#include <graphics/cursorman.h>
|
||||
#include <common/winexe_pe.h>
|
||||
#include <common/config-manager.h>
|
||||
|
||||
|
||||
namespace Pink {
|
||||
|
@ -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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user