feat: Implement pause/resume conversation actions

When paused, conversation entries cannot be skipped by clicking the
mouse.
This commit is contained in:
Vsevolod Kremianskii 2021-03-14 09:50:47 +07:00
parent 77adec041f
commit 3d29f31eb2
5 changed files with 36 additions and 3 deletions

View file

@ -99,6 +99,16 @@ void ActionExecutor::executeActions(const shared_ptr<Object> &object, float dt)
case ActionType::PlayAnimation: case ActionType::PlayAnimation:
executePlayAnimation(object, dynamic_pointer_cast<PlayAnimationAction>(action), dt); executePlayAnimation(object, dynamic_pointer_cast<PlayAnimationAction>(action), dt);
break; break;
case ActionType::PauseConversation: {
_game->conversation().pause();
action->complete();
break;
}
case ActionType::ResumeConversation: {
_game->conversation().resume();
action->complete();
break;
}
default: default:
debug("ActionExecutor: action not implemented: " + to_string(static_cast<int>(type)), 2); debug("ActionExecutor: action not implemented: " + to_string(static_cast<int>(type)), 2);
action->complete(); action->complete();

View file

@ -108,6 +108,7 @@ public:
CharacterGeneration &characterGeneration() { return *_charGen; } CharacterGeneration &characterGeneration() { return *_charGen; }
CameraType cameraType() const { return _cameraType; } CameraType cameraType() const { return _cameraType; }
ScriptRunner &scriptRunner() { return _scriptRunner; } ScriptRunner &scriptRunner() { return _scriptRunner; }
Conversation &conversation() { return *_conversation; }
void setCursorType(CursorType type); void setCursorType(CursorType type);
void setLoadFromSaveGame(bool load); void setLoadFromSaveGame(bool load);

View file

@ -273,13 +273,17 @@ bool Conversation::handle(const SDL_Event &event) {
} }
bool Conversation::handleMouseButtonDown(const SDL_MouseButtonEvent &event) { bool Conversation::handleMouseButtonDown(const SDL_MouseButtonEvent &event) {
if (event.button == SDL_BUTTON_LEFT && !_entryEnded && (_dialog->isSkippable() || g_allEntriesSkippable)) { if (event.button == SDL_BUTTON_LEFT && !_entryEnded && isSkippableEntry()) {
endCurrentEntry(); endCurrentEntry();
return true; return true;
} }
return false; return false;
} }
bool Conversation::isSkippableEntry() const {
return g_allEntriesSkippable || (_dialog->isSkippable() && !_paused);
}
void Conversation::endCurrentEntry() { void Conversation::endCurrentEntry() {
_entryEnded = true; _entryEnded = true;
@ -306,7 +310,7 @@ bool Conversation::handleKeyUp(const SDL_KeyboardEvent &event) {
SDL_Scancode key = event.keysym.scancode; SDL_Scancode key = event.keysym.scancode;
if (key >= SDL_SCANCODE_1 && key <= SDL_SCANCODE_9) { if (key >= SDL_SCANCODE_1 && key <= SDL_SCANCODE_9) {
int index = key - SDL_SCANCODE_1; int index = key - SDL_SCANCODE_1;
if (_entryEnded || _dialog->isSkippable() || g_allEntriesSkippable) { if (_entryEnded) {
pickReply(index); pickReply(index);
return true; return true;
} }
@ -337,6 +341,14 @@ CameraType Conversation::getCamera(int &cameraId) const {
return CameraType::Dialog; return CameraType::Dialog;
} }
void Conversation::pause() {
_paused = true;
}
void Conversation::resume() {
_paused = false;
}
} // namespace game } // namespace game
} // namespace reone } // namespace reone

View file

@ -61,6 +61,13 @@ public:
*/ */
CameraType getCamera(int &cameraId) const; CameraType getCamera(int &cameraId) const;
/**
* Pause this conversation. When paused, entries cannot be skipped by clicking the mouse.
*/
void pause();
void resume();
protected: protected:
Game *_game; Game *_game;
std::string _repliesControlTag; std::string _repliesControlTag;
@ -71,6 +78,7 @@ protected:
std::shared_ptr<render::LipAnimation> _lipAnimation; std::shared_ptr<render::LipAnimation> _lipAnimation;
const Dialog::EntryReply *_currentEntry { nullptr }; const Dialog::EntryReply *_currentEntry { nullptr };
bool _entryEnded { false }; bool _entryEnded { false };
bool _paused { false };
virtual void onStart(); virtual void onStart();
virtual void onFinish(); virtual void onFinish();
@ -99,6 +107,8 @@ private:
void scheduleEndOfEntry(); void scheduleEndOfEntry();
void loadReplies(); void loadReplies();
bool isSkippableEntry() const;
/** /**
* Replaces text in the message control. * Replaces text in the message control.
*/ */

View file

@ -243,7 +243,7 @@ void Routines::addKotorRoutines() {
add("ActionWait", Void, { Float }, &Routines::actionWait); add("ActionWait", Void, { Float }, &Routines::actionWait);
add("SetAreaTransitionBMP", Void, { Int, String }); add("SetAreaTransitionBMP", Void, { Int, String });
add("ActionStartConversation", Void, { Object, String, Int, Int, Int, String, String, String, String, String, String, Int }, &Routines::actionStartConversation); add("ActionStartConversation", Void, { Object, String, Int, Int, Int, String, String, String, String, String, String, Int }, &Routines::actionStartConversation);
add("ActionPauseConversation", Void, { }), &Routines::actionPauseConversation; add("ActionPauseConversation", Void, { }, &Routines::actionPauseConversation);
add("ActionResumeConversation", Void, { }, &Routines::actionResumeConversation); add("ActionResumeConversation", Void, { }, &Routines::actionResumeConversation);
add("EffectBeam", Effect, { Int, Object, Int, Int }, &Routines::effectBeam); add("EffectBeam", Effect, { Int, Object, Int, Int }, &Routines::effectBeam);
add("GetReputation", Int, { Object, Object }); add("GetReputation", Int, { Object, Object });