#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() {}
#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),
}
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; }
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;
private:
bool is_done_impl() override;
- A3F pos;
A3F offset;
float timer;
/*
#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() {}
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; }
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;
private:
bool is_done_impl() override;
- A3F pos;
float timer;
};
#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() {}
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; }
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;
private:
bool is_done_impl() override;
- A3F pos;
float timer;
};
#include "anim_model_still.h"
-#include "a3f_conv.h"
-
// third party includes
#include <raylib.h>
-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; }
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;
private:
bool is_done_impl() override;
- A3F pos;
float timer;
};
#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() {}
#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) {}
// standard library includes
#include <memory>
+// local includes
+#include "a3f.h"
+
// forward declarations
struct Model;
using FP = void (*)(void *);
- Anims(Model *model);
+ Anims(Model *model, A3F pos, A4C color);
virtual ~Anims() {}
bool is_done();
protected:
virtual bool is_done_impl() = 0;
+ A3F pos;
+ A4C color;
Model *model;
void *userdata;
FP function_ptr;
#include <cmath>
#include <cstring>
#include <iostream>
+#include <memory>
// third party includes
#include <raylib.h>
-#include <memory>
-
// local includes
#include "3d/a3f_conv.h"
#include "3d/anim_concurrent.h"
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);
<< (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 != '?') {
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;
}
}
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() {
auto newAnim = std::make_unique<AnimConcurrent>(nullptr);
newAnim->push_anim(std::make_unique<AnimModelShrink>(
- &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<AnimModelShrink>(
- &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<AnimConcurrent>(nullptr);
break;
}
newAnim->push_anim(std::make_unique<AnimModelGrow>(
- 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<AnimModelGrow>(
- 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<AnimConcurrent>(nullptr);
case -1:
newAnim->push_anim(std::make_unique<AnimModelStill>(
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<AnimModelAttack>(
- 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<AnimModelAttack>(
- 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<AnimModelStill>(
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:
newAnim = std::make_unique<AnimConcurrent>(nullptr);
newAnim->push_anim(std::make_unique<AnimModelShrink>(
- 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<AnimModelShrink>(
- 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<int *, int>;
DataT *data = new DataT{&received_pos, result};
newAnim = std::make_unique<AnimConcurrent>(nullptr);
newAnim->push_anim(std::make_unique<AnimModelGrow>(
- &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<AnimModelGrow>(
- &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;
+ }
+}
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;
// Returns score after round "idx"
int setup_anims(int idx, int score);
+ void reset_for_next();
+
std::array<QuestionMark, 2> qms;
Camera camera;
float button_color_timer;
int received_pos;
+ int prev_pos;
// int received_matchup_idx;
std::array<unsigned char, 3> choices;
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"
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;
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;
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;
}
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) {
'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),
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',
'number', 'number', 'number',
'boolean', 'boolean',
'boolean', 'boolean',
- 'number', 'boolean', 'boolean'],
+ 'number', 'number', 'boolean', 'boolean'],
[player1, player2,
yourPlayerId === undefined ? 'undefined' : yourPlayerId,
'?'.charCodeAt(0),
'?'.charCodeAt(0),
ready[0], ready[1],
matchup_done[0], matchup_done[1],
- pos, gameover_called, matchup_started]);
+ pos, prev_pos, gameover_called, matchup_started]);
}
},
});
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,
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) {
game.second_choices[0] = '?';
game.second_choices[1] = '?';
game.second_choices[2] = '?';
+ game.prev_pos = game.pos;
}
},
},