From 5237987c50a944484bdab15b1c88fdb286e1d8fd Mon Sep 17 00:00:00 2001 From: Stephen Seo Date: Wed, 18 Jan 2023 14:49:24 +0900 Subject: [PATCH] Refactorings, fix ? color, fix spectator mode --- src/3d/anim_concurrent.cc | 3 +- src/3d/anim_model_attack.cc | 7 ++- src/3d/anim_model_attack.h | 3 +- src/3d/anim_model_grow.cc | 7 +-- src/3d/anim_model_grow.h | 3 +- src/3d/anim_model_shrink.cc | 6 +-- src/3d/anim_model_shrink.h | 3 +- src/3d/anim_model_still.cc | 11 +++-- src/3d/anim_model_still.h | 3 +- src/3d/anim_sequence.cc | 3 +- src/3d/anims.cc | 6 ++- src/3d/anims.h | 7 ++- src/3d_renderer.cc | 96 +++++++++++++++++++++++-------------- src/3d_renderer.h | 7 ++- src/basic_renderer.cc | 14 +++--- src/basic_renderer.h | 4 +- src/game_renderer.h | 2 +- src/main.cc | 4 +- wasm_build/client.js | 10 ++-- wasm_build/logic.js | 3 ++ 20 files changed, 117 insertions(+), 85 deletions(-) diff --git a/src/3d/anim_concurrent.cc b/src/3d/anim_concurrent.cc index 3d9c5d8..05bf247 100644 --- a/src/3d/anim_concurrent.cc +++ b/src/3d/anim_concurrent.cc @@ -1,6 +1,7 @@ #include "anim_concurrent.h" -AnimConcurrent::AnimConcurrent(Model *model) : Anims(model) {} +AnimConcurrent::AnimConcurrent(Model *model) + : Anims(model, {0.0F, 0.0F, 0.0F}, {255, 255, 255, 255}) {} AnimConcurrent::~AnimConcurrent() {} diff --git a/src/3d/anim_model_attack.cc b/src/3d/anim_model_attack.cc index 950cddf..bb93a88 100644 --- a/src/3d/anim_model_attack.cc +++ b/src/3d/anim_model_attack.cc @@ -8,9 +8,8 @@ #include "../helpers.h" #include "a3f_conv.h" -AnimModelAttack::AnimModelAttack(Model *model, A3F pos, bool is_p1) - : Anims(model), - pos(pos), +AnimModelAttack::AnimModelAttack(Model *model, A3F pos, A4C color, bool is_p1) + : Anims(model, pos, color), offset{0.0F, 0.0F, 0.0F}, timer(MODEL_ATTACK_TIME_0), state(0), @@ -63,7 +62,7 @@ void AnimModelAttack::do_update(float dt) { } void AnimModelAttack::do_draw() { - DrawModel(*model, A3FToRV3(pos + offset), 1.0F, WHITE); + DrawModel(*model, A3FToRV3(pos + offset), 1.0F, A4CToC(color)); } bool AnimModelAttack::is_done_impl() { return state == 3; } diff --git a/src/3d/anim_model_attack.h b/src/3d/anim_model_attack.h index c07e8ce..f5bcf7c 100644 --- a/src/3d/anim_model_attack.h +++ b/src/3d/anim_model_attack.h @@ -6,7 +6,7 @@ class AnimModelAttack : public Anims { public: - AnimModelAttack(Model *model, A3F pos, bool is_p1); + AnimModelAttack(Model *model, A3F pos, A4C color, bool is_p1); ~AnimModelAttack() override; void do_update(float dt) override; @@ -15,7 +15,6 @@ class AnimModelAttack : public Anims { private: bool is_done_impl() override; - A3F pos; A3F offset; float timer; /* diff --git a/src/3d/anim_model_grow.cc b/src/3d/anim_model_grow.cc index f06fb79..469366a 100644 --- a/src/3d/anim_model_grow.cc +++ b/src/3d/anim_model_grow.cc @@ -7,8 +7,8 @@ #include "../constants.h" #include "a3f_conv.h" -AnimModelGrow::AnimModelGrow(Model *model, A3F pos) - : Anims(model), pos(pos), timer(MODEL_GROW_TIME) {} +AnimModelGrow::AnimModelGrow(Model *model, A3F pos, A4C color) + : Anims(model, pos, color), timer(MODEL_GROW_TIME) {} AnimModelGrow::~AnimModelGrow() {} @@ -16,7 +16,8 @@ void AnimModelGrow::do_update(float dt) { timer -= dt; } void AnimModelGrow::do_draw() { DrawModel(*model, A3FToRV3(pos), - timer >= 0.0F ? (1.0F - timer / MODEL_GROW_TIME) : 1.0F, WHITE); + timer >= 0.0F ? (1.0F - timer / MODEL_GROW_TIME) : 1.0F, + A4CToC(color)); } bool AnimModelGrow::is_done_impl() { return timer <= 0.0F; } diff --git a/src/3d/anim_model_grow.h b/src/3d/anim_model_grow.h index f881e4f..faf98ec 100644 --- a/src/3d/anim_model_grow.h +++ b/src/3d/anim_model_grow.h @@ -6,7 +6,7 @@ class AnimModelGrow : public Anims { public: - AnimModelGrow(Model *model, A3F pos); + AnimModelGrow(Model *model, A3F pos, A4C color); ~AnimModelGrow() override; void do_update(float dt) override; @@ -15,7 +15,6 @@ class AnimModelGrow : public Anims { private: bool is_done_impl() override; - A3F pos; float timer; }; diff --git a/src/3d/anim_model_shrink.cc b/src/3d/anim_model_shrink.cc index 5924b82..1459efe 100644 --- a/src/3d/anim_model_shrink.cc +++ b/src/3d/anim_model_shrink.cc @@ -7,8 +7,8 @@ #include "../constants.h" #include "a3f_conv.h" -AnimModelShrink::AnimModelShrink(Model *model, A3F pos) - : Anims(model), pos(pos), timer(MODEL_SHRINK_TIME) {} +AnimModelShrink::AnimModelShrink(Model *model, A3F pos, A4C color) + : Anims(model, pos, color), timer(MODEL_SHRINK_TIME) {} AnimModelShrink::~AnimModelShrink() {} @@ -16,7 +16,7 @@ void AnimModelShrink::do_update(float dt) { timer -= dt; } void AnimModelShrink::do_draw() { DrawModel(*model, A3FToRV3(pos), - timer >= 0.0F ? (timer / MODEL_SHRINK_TIME) : 0.0F, WHITE); + timer >= 0.0F ? (timer / MODEL_SHRINK_TIME) : 0.0F, A4CToC(color)); } bool AnimModelShrink::is_done_impl() { return timer <= 0.0F; } diff --git a/src/3d/anim_model_shrink.h b/src/3d/anim_model_shrink.h index 4af0e7d..89a458e 100644 --- a/src/3d/anim_model_shrink.h +++ b/src/3d/anim_model_shrink.h @@ -6,7 +6,7 @@ class AnimModelShrink : public Anims { public: - AnimModelShrink(Model *model, A3F pos); + AnimModelShrink(Model *model, A3F pos, A4C color); ~AnimModelShrink() override; void do_update(float dt) override; @@ -15,7 +15,6 @@ class AnimModelShrink : public Anims { private: bool is_done_impl() override; - A3F pos; float timer; }; diff --git a/src/3d/anim_model_still.cc b/src/3d/anim_model_still.cc index 87f9d37..eba90e8 100644 --- a/src/3d/anim_model_still.cc +++ b/src/3d/anim_model_still.cc @@ -1,19 +1,20 @@ #include "anim_model_still.h" -#include "a3f_conv.h" - // third party includes #include -AnimModelStill::AnimModelStill(Model *model, A3F pos, float time) - : Anims(model), pos(pos), timer(time) {} +// local includes +#include "a3f_conv.h" + +AnimModelStill::AnimModelStill(Model *model, A3F pos, A4C color, float time) + : Anims(model, pos, color), timer(time) {} AnimModelStill::~AnimModelStill() {} void AnimModelStill::do_update(float dt) { timer -= dt; } void AnimModelStill::do_draw() { - DrawModel(*model, A3FToRV3(pos), 1.0F, WHITE); + DrawModel(*model, A3FToRV3(pos), 1.0F, A4CToC(color)); } bool AnimModelStill::is_done_impl() { return timer <= 0.0F; } diff --git a/src/3d/anim_model_still.h b/src/3d/anim_model_still.h index b59505f..664a8c5 100644 --- a/src/3d/anim_model_still.h +++ b/src/3d/anim_model_still.h @@ -6,7 +6,7 @@ class AnimModelStill : public Anims { public: - AnimModelStill(Model *model, A3F pos, float time); + AnimModelStill(Model *model, A3F pos, A4C color, float time); ~AnimModelStill() override; void do_update(float dt) override; @@ -15,7 +15,6 @@ class AnimModelStill : public Anims { private: bool is_done_impl() override; - A3F pos; float timer; }; diff --git a/src/3d/anim_sequence.cc b/src/3d/anim_sequence.cc index 6695475..ad5a7ab 100644 --- a/src/3d/anim_sequence.cc +++ b/src/3d/anim_sequence.cc @@ -1,6 +1,7 @@ #include "anim_sequence.h" -AnimSequence::AnimSequence(Model *model) : Anims(model) {} +AnimSequence::AnimSequence(Model *model) + : Anims(model, {0.0F, 0.0F, 0.0F}, {255, 255, 255, 255}) {} AnimSequence::~AnimSequence() {} diff --git a/src/3d/anims.cc b/src/3d/anims.cc index 57d765d..e9ef0b7 100644 --- a/src/3d/anims.cc +++ b/src/3d/anims.cc @@ -1,7 +1,9 @@ #include "anims.h" -Anims::Anims(Model *model) - : model(model), +Anims::Anims(Model *model, A3F pos, A4C color) + : pos(pos), + color(color), + model(model), userdata(nullptr), function_ptr(nullptr), is_done_finished(false) {} diff --git a/src/3d/anims.h b/src/3d/anims.h index d24efc0..ec96615 100644 --- a/src/3d/anims.h +++ b/src/3d/anims.h @@ -4,6 +4,9 @@ // standard library includes #include +// local includes +#include "a3f.h" + // forward declarations struct Model; @@ -14,7 +17,7 @@ class Anims { using FP = void (*)(void *); - Anims(Model *model); + Anims(Model *model, A3F pos, A4C color); virtual ~Anims() {} bool is_done(); @@ -28,6 +31,8 @@ class Anims { protected: virtual bool is_done_impl() = 0; + A3F pos; + A4C color; Model *model; void *userdata; FP function_ptr; diff --git a/src/3d_renderer.cc b/src/3d_renderer.cc index 7947c7a..249273b 100644 --- a/src/3d_renderer.cc +++ b/src/3d_renderer.cc @@ -4,12 +4,11 @@ #include #include #include +#include // third party includes #include -#include - // local includes #include "3d/a3f_conv.h" #include "3d/anim_concurrent.h" @@ -114,7 +113,7 @@ void Renderer3D::update_state(const char *playerOne, const char *playerTwo, char second_first, char second_second, char second_third, bool first_ready, bool second_ready, bool first_matchup_done, - bool second_matchup_done, int pos, + bool second_matchup_done, int pos, int prev_pos, bool gameover_called, bool matchup_started) { if (std::strcmp(playerOne, currentPlayer) == 0) { flags.set(2); @@ -143,8 +142,11 @@ void Renderer3D::update_state(const char *playerOne, const char *playerTwo, << (second_ready ? "ready" : "NOT ready") << std::endl; } - if (!flags.test(13)) { + this->prev_pos = prev_pos; + if (!flags.test(13) && anims.is_done()) { received_pos = pos; + } else if (flags.test(3) && anims.is_done()) { + received_pos = prev_pos; } if (second_first != '?') { @@ -166,33 +168,13 @@ void Renderer3D::update_state(const char *playerOne, const char *playerTwo, opponent_choices.at(0) = second_first; opponent_choices.at(1) = second_second; opponent_choices.at(2) = second_third; - flags.set(0, flags.test(13)); } - if ((flags.test(11) || flags.test(3)) && first_first == '?' && - second_first == '?' && flags.test(15) && !flags.test(13)) { - choices.at(0) = '?'; - choices.at(1) = '?'; - choices.at(2) = '?'; - opponent_choices.at(0) = '?'; - opponent_choices.at(1) = '?'; - opponent_choices.at(2) = '?'; - flags.reset(11); - flags.reset(8); - flags.reset(0); - flags.reset(15); - flags.reset(7); - overview_timer = OVERVIEW_TIMER_MAX; - set_random_overview(); - camera.target.x = received_pos * 2.0F; - if (flags.test(3)) { - std::cerr << "RESET STATE for next round" << std::endl; - } + if (flags.test(11) && first_first == '?' && second_first == '?' && + flags.test(15) && !flags.test(13)) { + reset_for_next(); } - qms.at(0).set_pos_x(received_pos * 2.0F - 1.0F); - qms.at(1).set_pos_x(received_pos * 2.0F + 1.0F); - if (flags.test(3)) { std::cout << flags.to_string().substr(64 - 16) << std::endl; } @@ -382,6 +364,20 @@ void Renderer3D::update_impl() { } anims.do_update(dt); + + if (flags.test(3)) { + if (flags.test(0)) { + if (anims.is_done()) { + reset_for_next(); + received_pos = prev_pos; + } + } else if (flags.test(13)) { + flags.set(0); + } + } + + qms.at(0).set_pos_x(received_pos * 2.0F - 1.0F); + qms.at(1).set_pos_x(received_pos * 2.0F + 1.0F); } void Renderer3D::draw_impl() { @@ -567,9 +563,9 @@ int Renderer3D::setup_anims(int idx, int score) { auto newAnim = std::make_unique(nullptr); newAnim->push_anim(std::make_unique( - &qm_model, A3F{score * 2.0F - 1.0F, 0.0F, 0.0F})); + &qm_model, A3F{score * 2.0F - 1.0F, 0.0F, 0.0F}, A4C{255, 0, 0, 255})); newAnim->push_anim(std::make_unique( - &qm_model, A3F{score * 2.0F + 1.0F, 0.0F, 0.0F})); + &qm_model, A3F{score * 2.0F + 1.0F, 0.0F, 0.0F}, A4C{0, 0, 255, 255})); anims.push_anim(std::move(newAnim)); newAnim = std::make_unique(nullptr); @@ -622,9 +618,9 @@ int Renderer3D::setup_anims(int idx, int score) { break; } newAnim->push_anim(std::make_unique( - p1_model, A3F{score * 2.0F - 1.0F, 0.0F, 0.0F})); + p1_model, A3F{score * 2.0F - 1.0F, 0.0F, 0.0F}, A4C{255, 255, 255, 255})); newAnim->push_anim(std::make_unique( - p2_model, A3F{score * 2.0F + 1.0F, 0.0F, 0.0F})); + p2_model, A3F{score * 2.0F + 1.0F, 0.0F, 0.0F}, A4C{255, 255, 255, 255})); anims.push_anim(std::move(newAnim)); newAnim = std::make_unique(nullptr); @@ -639,15 +635,19 @@ int Renderer3D::setup_anims(int idx, int score) { case -1: newAnim->push_anim(std::make_unique( p1_model, A3F{score * 2.0F - 1.0F, 0.0F, 0.0F}, + A4C{255, 255, 255, 255}, MODEL_ATTACK_TIME_0 + MODEL_ATTACK_TIME_1 + MODEL_ATTACK_TIME_2)); newAnim->push_anim(std::make_unique( - p2_model, A3F{score * 2.0F + 1.0F, 0.0F, 0.0F}, false)); + p2_model, A3F{score * 2.0F + 1.0F, 0.0F, 0.0F}, + A4C{255, 255, 255, 255}, false)); break; case 1: newAnim->push_anim(std::make_unique( - p1_model, A3F{score * 2.0F - 1.0F, 0.0F, 0.0F}, true)); + p1_model, A3F{score * 2.0F - 1.0F, 0.0F, 0.0F}, + A4C{255, 255, 255, 255}, true)); newAnim->push_anim(std::make_unique( p2_model, A3F{score * 2.0F + 1.0F, 0.0F, 0.0F}, + A4C{255, 255, 255, 255}, MODEL_ATTACK_TIME_0 + MODEL_ATTACK_TIME_1 + MODEL_ATTACK_TIME_2)); break; case 0: @@ -661,9 +661,9 @@ int Renderer3D::setup_anims(int idx, int score) { newAnim = std::make_unique(nullptr); newAnim->push_anim(std::make_unique( - p1_model, A3F{score * 2.0F - 1.0F, 0.0F, 0.0F})); + p1_model, A3F{score * 2.0F - 1.0F, 0.0F, 0.0F}, A4C{255, 255, 255, 255})); newAnim->push_anim(std::make_unique( - p2_model, A3F{score * 2.0F + 1.0F, 0.0F, 0.0F})); + p2_model, A3F{score * 2.0F + 1.0F, 0.0F, 0.0F}, A4C{255, 255, 255, 255})); using DataT = std::tuple; DataT *data = new DataT{&received_pos, result}; @@ -679,11 +679,33 @@ int Renderer3D::setup_anims(int idx, int score) { newAnim = std::make_unique(nullptr); newAnim->push_anim(std::make_unique( - &qm_model, A3F{(result + score) * 2.0F - 1.0F, 0.0F, 0.0F})); + &qm_model, A3F{(result + score) * 2.0F - 1.0F, 0.0F, 0.0F}, + A4C{255, 0, 0, 255})); newAnim->push_anim(std::make_unique( - &qm_model, A3F{(result + score) * 2.0F + 1.0F, 0.0F, 0.0F})); + &qm_model, A3F{(result + score) * 2.0F + 1.0F, 0.0F, 0.0F}, + A4C{0, 0, 255, 255})); anims.push_anim(std::move(newAnim)); return score + result; } + +void Renderer3D::reset_for_next() { + choices.at(0) = '?'; + choices.at(1) = '?'; + choices.at(2) = '?'; + opponent_choices.at(0) = '?'; + opponent_choices.at(1) = '?'; + opponent_choices.at(2) = '?'; + flags.reset(11); + flags.reset(8); + flags.reset(0); + flags.reset(15); + flags.reset(7); + overview_timer = OVERVIEW_TIMER_MAX; + set_random_overview(); + camera.target.x = received_pos * 2.0F; + if (flags.test(3)) { + std::cerr << "RESET STATE for next round" << std::endl; + } +} diff --git a/src/3d_renderer.h b/src/3d_renderer.h index b023344..2a4d08b 100644 --- a/src/3d_renderer.h +++ b/src/3d_renderer.h @@ -26,8 +26,8 @@ class Renderer3D : public GameRenderer { char first_second, char first_third, char second_first, char second_second, char second_third, bool first_ready, bool second_ready, bool first_matchup_done, - bool second_matchup_done, int pos, bool gameover_called, - bool matchup_started) override; + bool second_matchup_done, int pos, int prev_pos, + bool gameover_called, bool matchup_started) override; void do_update() override; @@ -42,6 +42,8 @@ class Renderer3D : public GameRenderer { // Returns score after round "idx" int setup_anims(int idx, int score); + void reset_for_next(); + std::array qms; Camera camera; @@ -97,6 +99,7 @@ class Renderer3D : public GameRenderer { float button_color_timer; int received_pos; + int prev_pos; // int received_matchup_idx; std::array choices; diff --git a/src/basic_renderer.cc b/src/basic_renderer.cc index d9a6ac7..5fb1157 100644 --- a/src/basic_renderer.cc +++ b/src/basic_renderer.cc @@ -33,14 +33,12 @@ BasicRenderer::BasicRenderer() opponentPicked[2] = 0; } -void BasicRenderer::update_state(const char *playerOne, const char *playerTwo, - const char *currentPlayer, char first_first, - char first_second, char first_third, - char second_first, char second_second, - char second_third, bool first_ready, - bool second_ready, bool first_matchup_done, - bool second_matchup_done, int pos, - bool gameover_called, bool matchup_started) { +void BasicRenderer::update_state( + const char *playerOne, const char *playerTwo, const char *currentPlayer, + char first_first, char first_second, char first_third, char second_first, + char second_second, char second_third, bool first_ready, bool second_ready, + bool first_matchup_done, bool second_matchup_done, int pos, int prev_pos, + bool gameover_called, bool matchup_started) { // TODO DEBUG // if (std::strcmp(playerOne, currentPlayer) == 0) { // std::clog << "update_state:\n" diff --git a/src/basic_renderer.h b/src/basic_renderer.h index bd2d21d..10b5aed 100644 --- a/src/basic_renderer.h +++ b/src/basic_renderer.h @@ -22,8 +22,8 @@ class BasicRenderer : public GameRenderer { char first_second, char first_third, char second_first, char second_second, char second_third, bool first_ready, bool second_ready, bool first_matchup_done, - bool second_matchup_done, int pos, bool gameover_called, - bool matchup_started) override; + bool second_matchup_done, int pos, int prev_pos, + bool gameover_called, bool matchup_started) override; void do_update() override; diff --git a/src/game_renderer.h b/src/game_renderer.h index 247436d..31197c5 100644 --- a/src/game_renderer.h +++ b/src/game_renderer.h @@ -12,7 +12,7 @@ class GameRenderer { char second_first, char second_second, char second_third, bool first_ready, bool second_ready, bool first_matchup_done, - bool second_matchup_done, int pos, + bool second_matchup_done, int pos, int prev_pos, bool gameover_called, bool matchup_started) = 0; virtual void do_update() = 0; diff --git a/src/main.cc b/src/main.cc index b947b9d..7dd1899 100644 --- a/src/main.cc +++ b/src/main.cc @@ -30,13 +30,13 @@ int EMSCRIPTEN_KEEPALIVE game_visual_update( const char *playerOne, const char *playerTwo, const char *currentPlayer, char first_first, char first_second, char first_third, char second_first, char second_second, char second_third, bool first_ready, bool second_ready, - bool first_matchup_done, bool second_matchup_done, int pos, + bool first_matchup_done, bool second_matchup_done, int pos, int prev_pos, bool gameover_called, bool matchup_started) { ((GameRenderer *)global_game_ptr) ->update_state(playerOne, playerTwo, currentPlayer, first_first, first_second, first_third, second_first, second_second, second_third, first_ready, second_ready, - first_matchup_done, second_matchup_done, pos, + first_matchup_done, second_matchup_done, pos, prev_pos, gameover_called, matchup_started); return 0; } diff --git a/wasm_build/client.js b/wasm_build/client.js index 071512b..51a74f6 100644 --- a/wasm_build/client.js +++ b/wasm_build/client.js @@ -1,6 +1,6 @@ Rune.initClient({ visualUpdate: ({ newGame, yourPlayerId}) => { - const { player1, player2, first_choices, second_choices, ready, matchup_done, pos, gameover, gameover_called, matchup_started } = newGame; + const { player1, player2, first_choices, second_choices, ready, matchup_done, pos, prev_pos, gameover, gameover_called, matchup_started } = newGame; function is_choices_filled(choices) { for (let i = 0; i < 3; ++i) { @@ -19,7 +19,7 @@ Rune.initClient({ 'number', 'number', 'number', 'boolean', 'boolean', 'boolean', 'boolean', - 'number', 'boolean', 'boolean'], + 'number', 'number', 'boolean', 'boolean'], [player1, player2, yourPlayerId === undefined ? 'undefined' : yourPlayerId, first_choices[0].charCodeAt(0), @@ -30,7 +30,7 @@ Rune.initClient({ second_choices[2].charCodeAt(0), ready[0], ready[1], matchup_done[0], matchup_done[1], - pos, gameover_called, matchup_started]); + pos, prev_pos, gameover_called, matchup_started]); } else { Module.ccall('game_visual_update', 'number', @@ -39,7 +39,7 @@ Rune.initClient({ 'number', 'number', 'number', 'boolean', 'boolean', 'boolean', 'boolean', - 'number', 'boolean', 'boolean'], + 'number', 'number', 'boolean', 'boolean'], [player1, player2, yourPlayerId === undefined ? 'undefined' : yourPlayerId, '?'.charCodeAt(0), @@ -50,7 +50,7 @@ Rune.initClient({ '?'.charCodeAt(0), ready[0], ready[1], matchup_done[0], matchup_done[1], - pos, gameover_called, matchup_started]); + pos, prev_pos, gameover_called, matchup_started]); } }, }); diff --git a/wasm_build/logic.js b/wasm_build/logic.js index 24c8cfb..c123121 100644 --- a/wasm_build/logic.js +++ b/wasm_build/logic.js @@ -9,6 +9,7 @@ Rune.initLogic({ ready: new Array(2).fill(false), matchup_done: new Array(2).fill(false), pos: 0, + prev_pos: 0, gameover: false, gameover_called: false, matchup_started: false, @@ -94,6 +95,7 @@ Rune.initLogic({ if (is_choices_filled(game.first_choices) && is_choices_filled(game.second_choices)) { game.matchup_started = true; + game.prev_pos = game.pos; for (let i = 0; i < 3; ++i) { let result = check_matchup(game.first_choices[i], game.second_choices[i]); if (result > 0) { @@ -152,6 +154,7 @@ Rune.initLogic({ game.second_choices[0] = '?'; game.second_choices[1] = '?'; game.second_choices[2] = '?'; + game.prev_pos = game.pos; } }, }, -- 2.49.0