"${CMAKE_CURRENT_SOURCE_DIR}/src/3d/a3f.cc"
"${CMAKE_CURRENT_SOURCE_DIR}/src/3d/a3f_conv.cc"
"${CMAKE_CURRENT_SOURCE_DIR}/src/3d/qm.cc"
+ "${CMAKE_CURRENT_SOURCE_DIR}/src/3d/anims.cc"
"${CMAKE_CURRENT_SOURCE_DIR}/src/3d/anim_concurrent.cc"
"${CMAKE_CURRENT_SOURCE_DIR}/src/3d/anim_sequence.cc"
"${CMAKE_CURRENT_SOURCE_DIR}/src/3d/anim_model_shrink.cc"
"${CMAKE_CURRENT_SOURCE_DIR}/src/3d/anim_model_grow.cc"
"${CMAKE_CURRENT_SOURCE_DIR}/src/3d/anim_model_attack.cc"
+ "${CMAKE_CURRENT_SOURCE_DIR}/src/3d/anim_model_still.cc"
)
set(RPSDuelNative_HEADERS
"${CMAKE_CURRENT_SOURCE_DIR}/src/3d/anim_model_shrink.h"
"${CMAKE_CURRENT_SOURCE_DIR}/src/3d/anim_model_grow.h"
"${CMAKE_CURRENT_SOURCE_DIR}/src/3d/anim_model_attack.h"
+ "${CMAKE_CURRENT_SOURCE_DIR}/src/3d/anim_model_still.h"
)
add_executable(RPSDuelNative ${RPSDuelNative_SOURCES})
AnimConcurrent::~AnimConcurrent() {}
-bool AnimConcurrent::is_done() { return anims.empty(); }
-
void AnimConcurrent::do_update(float dt) {
for (auto iter = anims.begin(); iter != anims.end();) {
(*iter)->do_update(dt);
void AnimConcurrent::push_anim(UPtr &&p) {
anims.emplace_back(std::forward<UPtr>(p));
}
+
+bool AnimConcurrent::is_done_impl() { return anims.empty(); }
AnimConcurrent(Model *model);
~AnimConcurrent() override;
- bool is_done() override;
-
void do_update(float dt) override;
void do_draw() override;
void push_anim(UPtr &&p);
+ protected:
+ bool is_done_impl() override;
+
private:
std::list<UPtr> anims;
};
#include "../helpers.h"
#include "a3f_conv.h"
-AnimModelAttack::AnimModelAttack(Model *model, A3F pos)
+AnimModelAttack::AnimModelAttack(Model *model, A3F pos, bool is_p1)
: Anims(model),
pos(pos),
offset{0.0F, 0.0F, 0.0F},
timer(MODEL_ATTACK_TIME_0),
- state(0) {}
+ state(0),
+ is_p1(is_p1) {}
AnimModelAttack::~AnimModelAttack() {}
-bool AnimModelAttack::is_done() { return state == 3; }
-
void AnimModelAttack::do_update(float dt) {
timer -= dt;
if (timer <= 0.0F) {
1.0F - timer / MODEL_ATTACK_TIME_0);
break;
case 1:
- offset.at(0) = Helpers::lerp(MODEL_ATTACK_0_X, MODEL_ATTACK_1_X,
+ offset.at(0) = Helpers::lerp(MODEL_ATTACK_0_X,
+ MODEL_ATTACK_1_X * (is_p1 ? 1.0F : -1.0F),
1.0F - timer / MODEL_ATTACK_TIME_1);
offset.at(1) = Helpers::lerp(MODEL_ATTACK_0_Y, MODEL_ATTACK_1_Y,
1.0F - timer / MODEL_ATTACK_TIME_1);
break;
case 2:
- offset.at(0) = Helpers::lerp(MODEL_ATTACK_1_X, MODEL_ATTACK_2_X,
- 1.0F - timer / MODEL_ATTACK_TIME_2);
+ offset.at(0) =
+ Helpers::lerp(MODEL_ATTACK_1_X * (is_p1 ? 1.0F : -1.0F),
+ MODEL_ATTACK_2_X, 1.0F - timer / MODEL_ATTACK_TIME_2);
offset.at(1) = Helpers::lerp(MODEL_ATTACK_1_Y, MODEL_ATTACK_2_Y,
1.0F - timer / MODEL_ATTACK_TIME_2);
break;
void AnimModelAttack::do_draw() {
DrawModel(*model, A3FToRV3(pos + offset), 1.0F, WHITE);
}
+
+bool AnimModelAttack::is_done_impl() { return state == 3; }
class AnimModelAttack : public Anims {
public:
- AnimModelAttack(Model *model, A3F pos);
+ AnimModelAttack(Model *model, A3F pos, bool is_p1);
~AnimModelAttack() override;
- bool is_done() override;
-
void do_update(float dt) override;
void do_draw() override;
private:
+ bool is_done_impl() override;
+
A3F pos;
A3F offset;
float timer;
* 3 - done
*/
int state;
+ bool is_p1;
};
#endif
AnimModelGrow::~AnimModelGrow() {}
-bool AnimModelGrow::is_done() { return timer <= 0.0F; }
-
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);
}
+
+bool AnimModelGrow::is_done_impl() { return timer <= 0.0F; }
AnimModelGrow(Model *model, A3F pos);
~AnimModelGrow() override;
- bool is_done() override;
-
void do_update(float dt) override;
void do_draw() override;
private:
+ bool is_done_impl() override;
+
A3F pos;
float timer;
};
AnimModelShrink::~AnimModelShrink() {}
-bool AnimModelShrink::is_done() { return timer <= 0.0F; }
-
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);
}
+
+bool AnimModelShrink::is_done_impl() { return timer <= 0.0F; }
AnimModelShrink(Model *model, A3F pos);
~AnimModelShrink() override;
- bool is_done() override;
-
void do_update(float dt) override;
void do_draw() override;
private:
+ bool is_done_impl() override;
+
A3F pos;
float timer;
};
--- /dev/null
+#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) {}
+
+AnimModelStill::~AnimModelStill() {}
+
+void AnimModelStill::do_update(float dt) { timer -= dt; }
+
+void AnimModelStill::do_draw() {
+ DrawModel(*model, A3FToRV3(pos), 1.0F, WHITE);
+}
+
+bool AnimModelStill::is_done_impl() { return timer <= 0.0F; }
--- /dev/null
+#ifndef ROCK_PAPER_SCISSORS_DUEL_3D_ANIM_MODEL_STILL_H_
+#define ROCK_PAPER_SCISSORS_DUEL_3D_ANIM_MODEL_STILL_H_
+
+#include "a3f.h"
+#include "anims.h"
+
+class AnimModelStill : public Anims {
+ public:
+ AnimModelStill(Model *model, A3F pos, float time);
+ ~AnimModelStill() override;
+
+ void do_update(float dt) override;
+ void do_draw() override;
+
+ private:
+ bool is_done_impl() override;
+
+ A3F pos;
+ float timer;
+};
+
+#endif
AnimSequence::~AnimSequence() {}
-bool AnimSequence::is_done() { return anims.empty(); }
-
void AnimSequence::do_update(float dt) {
if (!anims.empty()) {
anims.front()->do_update(dt);
void AnimSequence::push_anim(UPtr &&p) {
anims.emplace_back(std::forward<UPtr>(p));
}
+
+bool AnimSequence::is_done_impl() { return anims.empty(); }
AnimSequence(Model *model);
~AnimSequence() override;
- bool is_done() override;
-
void do_update(float dt) override;
void do_draw() override;
void push_anim(UPtr &&p);
+ protected:
+ bool is_done_impl() override;
+
private:
std::list<UPtr> anims;
};
--- /dev/null
+#include "anims.h"
+
+Anims::Anims(Model *model)
+ : model(model),
+ userdata(nullptr),
+ function_ptr(nullptr),
+ is_done_finished(false) {}
+
+bool Anims::is_done() {
+ if (is_done_finished) {
+ return true;
+ }
+ bool result = is_done_impl();
+ if (result) {
+ if (function_ptr) {
+ function_ptr(userdata);
+ }
+ is_done_finished = true;
+ }
+ return result;
+}
+
+void Anims::reset_is_done() { is_done_finished = false; }
+
+void Anims::set_end_callback(Anims::FP fp, void *ud) {
+ userdata = ud;
+ function_ptr = fp;
+}
using UPtr = std::unique_ptr<Anims>;
using SPtr = std::shared_ptr<Anims>;
- Anims(Model *model) : model(model) {}
+ using FP = void (*)(void *);
+
+ Anims(Model *model);
virtual ~Anims() {}
- virtual bool is_done() = 0;
+ bool is_done();
+ void reset_is_done();
virtual void do_update(float dt) = 0;
virtual void do_draw() = 0;
+ void set_end_callback(FP function_ptr, void *ud);
+
protected:
+ virtual bool is_done_impl() = 0;
+
Model *model;
+ void *userdata;
+ FP function_ptr;
+ bool is_done_finished;
};
#endif
// third party includes
#include <raylib.h>
+#include <memory>
+
// local includes
#include "3d/a3f_conv.h"
+#include "3d/anim_concurrent.h"
+#include "3d/anim_model_attack.h"
+#include "3d/anim_model_grow.h"
+#include "3d/anim_model_shrink.h"
+#include "3d/anim_model_still.h"
#include "constants.h"
#include "ems.h"
#include "helpers.h"
Renderer3D::Renderer3D()
: qms{},
+ anims(nullptr),
root_pos{0.0F, 0.0F, 0.0F},
overview_timer(OVERVIEW_TIMER_MAX),
button_color_timer(BUTTON_COLOR_TIME),
flags.set(1);
flags.set(4);
flags.set(5);
+ flags.set(14);
qms.at(0).set_model(&qm_model);
qms.at(0).set_pos({-1.0F, 0.0F, 0.0F});
char second_first, char second_second,
char second_third, bool first_ready,
bool second_ready, int pos, int matchup_idx,
- bool gameover) {
+ bool gameover, bool matchup_started) {
if (std::strcmp(playerOne, currentPlayer) == 0) {
flags.set(2);
flags.reset(3);
flags.set(9, first_ready);
flags.set(10, second_ready);
+ flags.set(13, matchup_started);
flags.set(12);
std::cout << "got pos: " << pos << std::endl;
std::cout << "got matchup_idx: " << matchup_idx << std::endl;
std::cout << "camera.target.x: " << camera.target.x << std::endl;
+ std::cout << "matchup started: " << (matchup_started ? "true" : "false")
+ << std::endl;
+ std::cout << "p1 is " << (first_ready ? "ready" : "NOT ready") << "\np2 is "
+ << (second_ready ? "ready" : "NOT ready") << std::endl;
}
- received_pos = pos;
+ if (!flags.test(13)) {
+ received_pos = pos;
+ }
+ if (received_matchup_idx != matchup_idx) {
+ flags.reset(7);
+ }
received_matchup_idx = matchup_idx;
if (second_first != '?') {
- opponent_choices.at(0) = second_first;
- opponent_choices.at(1) = second_second;
- opponent_choices.at(2) = second_third;
+ if (flags.test(2)) {
+ opponent_choices.at(0) = second_first;
+ opponent_choices.at(1) = second_second;
+ opponent_choices.at(2) = second_third;
+ } else {
+ opponent_choices.at(0) = first_first;
+ opponent_choices.at(1) = first_second;
+ opponent_choices.at(2) = first_third;
+ }
}
- if (flags.test(11) && first_first == '?' && second_first == '?') {
+ if (flags.test(11) && first_first == '?' && second_first == '?' &&
+ flags.test(15) && !flags.test(13)) {
choices.at(0) = '?';
choices.at(1) = '?';
choices.at(2) = '?';
flags.reset(11);
flags.reset(8);
flags.reset(0);
+ flags.reset(15);
+ flags.set(14);
overview_timer = OVERVIEW_TIMER_MAX;
set_random_overview();
+ qms.at(0).set_pos_x(received_pos * 2.0F - 1.0F);
+ qms.at(1).set_pos_x(received_pos * 2.0F + 1.0F);
+ camera.target.x = received_pos * 2.0F;
+ if (flags.test(2)) {
+ std::cerr << "RESET STATE for next round" << std::endl;
+ }
+ }
+
+ if (flags.test(2)) {
+ std::cout << flags.to_string().substr(64 - 16) << std::endl;
}
}
button_color_timer += BUTTON_COLOR_TIME;
}
+ if (flags.test(8) && flags.test(9) && flags.test(10) && !flags.test(11)) {
+ char buf[6] = {(char)choices.at(0), 0, (char)choices.at(1), 0,
+ (char)choices.at(2), 0};
+ flags.set(11);
+ flags.set(0);
+ call_js_set_choices(&buf[0], &buf[2], &buf[4]);
+ call_js_request_update();
+ }
+
if (flags.test(12)) {
- if (flags.test(8) && flags.test(11)) {
- call_js_set_ready();
- call_js_request_update();
- } else if (flags.test(8) && flags.test(9) && flags.test(10) &&
- !flags.test(11)) {
- char buf[6] = {(char)choices.at(0), 0, (char)choices.at(1), 0,
- (char)choices.at(2), 0};
- call_js_set_choices(&buf[0], &buf[2], &buf[4]);
- flags.set(11);
- flags.set(0);
+ if (flags.test(11) && !flags.test(7) && flags.test(13) && anims.is_done()) {
+ flags.set(7);
+ flags.reset(14);
+ flags.set(15);
+
+ anims.reset_is_done();
+
+ auto newAnim = std::make_unique<AnimConcurrent>(nullptr);
+ newAnim->push_anim(std::make_unique<AnimModelShrink>(
+ &qm_model, A3F{received_pos * 2.0F - 1.0F, 0.0F, 0.0F}));
+ newAnim->push_anim(std::make_unique<AnimModelShrink>(
+ &qm_model, A3F{received_pos * 2.0F + 1.0F, 0.0F, 0.0F}));
+ anims.push_anim(std::move(newAnim));
+
+ newAnim = std::make_unique<AnimConcurrent>(nullptr);
+ Model *p1_model = &qm_model;
+ Model *p2_model = &qm_model;
+ switch (choices.at(received_matchup_idx)) {
+ case 'r':
+ if (flags.test(2)) {
+ p1_model = &rock_model;
+ } else {
+ p2_model = &rock_model;
+ }
+ break;
+ case 'p':
+ if (flags.test(2)) {
+ p1_model = &paper_model;
+ } else {
+ p2_model = &paper_model;
+ }
+ break;
+ case 's':
+ if (flags.test(2)) {
+ p1_model = &scissors_model;
+ } else {
+ p2_model = &scissors_model;
+ }
+ break;
+ }
+ switch (opponent_choices.at(received_matchup_idx)) {
+ case 'r':
+ if (flags.test(2)) {
+ p2_model = &rock_model;
+ } else {
+ p1_model = &rock_model;
+ }
+ break;
+ case 'p':
+ if (flags.test(2)) {
+ p2_model = &paper_model;
+ } else {
+ p1_model = &paper_model;
+ }
+ break;
+ case 's':
+ if (flags.test(2)) {
+ p2_model = &scissors_model;
+ } else {
+ p1_model = &scissors_model;
+ }
+ break;
+ }
+ newAnim->push_anim(std::make_unique<AnimModelGrow>(
+ p1_model, A3F{received_pos * 2.0F - 1.0F, 0.0F, 0.0F}));
+ newAnim->push_anim(std::make_unique<AnimModelGrow>(
+ p2_model, A3F{received_pos * 2.0F + 1.0F, 0.0F, 0.0F}));
+ anims.push_anim(std::move(newAnim));
+
+ newAnim = std::make_unique<AnimConcurrent>(nullptr);
+
+ const int result = Helpers::a_vs_b(
+ flags.test(2) ? choices.at(received_matchup_idx)
+ : opponent_choices.at(received_matchup_idx),
+ flags.test(2) ? opponent_choices.at(received_matchup_idx)
+ : choices.at(received_matchup_idx));
+
+ switch (result) {
+ case -1:
+ newAnim->push_anim(std::make_unique<AnimModelStill>(
+ p1_model, A3F{received_pos * 2.0F - 1.0F, 0.0F, 0.0F},
+ MODEL_ATTACK_TIME_0 + MODEL_ATTACK_TIME_1 + MODEL_ATTACK_TIME_2));
+ newAnim->push_anim(std::make_unique<AnimModelAttack>(
+ p2_model, A3F{received_pos * 2.0F + 1.0F, 0.0F, 0.0F}, false));
+ break;
+ case 1:
+ newAnim->push_anim(std::make_unique<AnimModelAttack>(
+ p1_model, A3F{received_pos * 2.0F - 1.0F, 0.0F, 0.0F}, true));
+ newAnim->push_anim(std::make_unique<AnimModelStill>(
+ p2_model, A3F{received_pos * 2.0F + 1.0F, 0.0F, 0.0F},
+ MODEL_ATTACK_TIME_0 + MODEL_ATTACK_TIME_1 + MODEL_ATTACK_TIME_2));
+ break;
+ case 0:
+ default:
+ break;
+ }
+
+ if (result != 0) {
+ anims.push_anim(std::move(newAnim));
+ }
+
+ newAnim = std::make_unique<AnimConcurrent>(nullptr);
+ newAnim->push_anim(std::make_unique<AnimModelShrink>(
+ p1_model, A3F{received_pos * 2.0F - 1.0F, 0.0F, 0.0F}));
+ newAnim->push_anim(std::make_unique<AnimModelShrink>(
+ p2_model, A3F{received_pos * 2.0F + 1.0F, 0.0F, 0.0F}));
+
+ using DataT = std::tuple<decltype(flags) *, int *, int>;
+ DataT *data = new DataT{&flags, &received_pos, result};
+ newAnim->set_end_callback(
+ [](void *ud) {
+ auto *d = (std::tuple<decltype(flags) *, int *, int> *)(ud);
+ std::get<0>(*d)->set(14);
+ *std::get<1>(*d) += std::get<2>(*d);
+ delete d;
+ },
+ data);
+
+ anims.push_anim(std::move(newAnim));
+
+ newAnim = std::make_unique<AnimConcurrent>(nullptr);
+ newAnim->push_anim(std::make_unique<AnimModelGrow>(
+ &qm_model, A3F{(result + received_pos) * 2.0F - 1.0F, 0.0F, 0.0F}));
+ newAnim->push_anim(std::make_unique<AnimModelGrow>(
+ &qm_model, A3F{(result + received_pos) * 2.0F + 1.0F, 0.0F, 0.0F}));
+
+ anims.push_anim(std::move(newAnim));
}
}
flags.reset(12);
- qms.at(0).get_pos().at(0) +=
- ((received_pos * 2.0F - 1.0F) - qms.at(0).get_pos().at(0)) / 50.0F;
- qms.at(1).get_pos().at(0) +=
- ((received_pos * 2.0F + 1.0F) - qms.at(1).get_pos().at(0)) / 50.0F;
- camera.target.x += (received_pos * 2.0F - camera.target.x) / 50.0F;
+ if (flags.test(8) && flags.test(11) && flags.test(7) && anims.is_done()) {
+ flags.set(14);
+ call_js_set_ready();
+ call_js_request_update();
+ }
+
+ if (flags.test(14)) {
+ float offset = received_pos * 2.0F - camera.target.x;
+ camera.target.x += offset / 4.0F;
+ }
+
+ anims.do_update(dt);
}
void Renderer3D::draw_impl() {
BeginMode3D(camera);
DrawModel(skybox_model, root_pos, 1.0F, WHITE);
DrawModel(platform_model, root_pos, 1.0F, WHITE);
- for (auto &obj : qms) {
- obj.draw();
+ if (flags.test(0)) {
+ anims.do_draw();
+ } else {
+ for (auto &obj : qms) {
+ obj.draw();
+ }
}
EndMode3D();
#include <raylib.h>
// local includes
+#include "3d/anim_sequence.h"
+#include "3d/anims.h"
#include "3d/qm.h"
class Renderer3D : public GameRenderer {
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, int pos, int matchup_idx,
- bool gameover) override;
+ bool second_ready, int pos, int matchup_idx, bool gameover,
+ bool matchup_started) override;
void do_update() override;
Model paper_model;
Model scissors_model;
+ AnimSequence anims;
+
Vector3 root_pos;
/*
* 101 - UNUSED
* 110 - UNUSED
* 111 - UNUSED
- * 7 - UNUSED
+ * 7 - anims set for current matchup
* 8 - choices locked
* 9 - p1 ready
* 10 - p2 ready
* 11 - choices submitted
* 12 - update received
+ * 13 - matchup started
+ * 14 - do update camera target/pos
+ * 15 - anims was set for matchup
*/
std::bitset<64> flags;
char second_first, char second_second,
char second_third, bool first_ready,
bool second_ready, int pos, int matchup_idx,
- bool gameover) {
+ bool gameover, bool matchup_started) {
// TODO DEBUG
// if (std::strcmp(playerOne, currentPlayer) == 0) {
// std::clog << "update_state:\n"
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, int pos, int matchup_idx,
- bool gameover) override;
+ bool second_ready, int pos, int matchup_idx, bool gameover,
+ bool matchup_started) override;
void do_update() override;
constexpr float MODEL_ATTACK_TIME_2 = 0.4F;
constexpr float MODEL_ATTACK_0_X = 0.0F;
constexpr float MODEL_ATTACK_0_Y = 2.0F;
-constexpr float MODEL_ATTACK_1_X = -1.0F;
+constexpr float MODEL_ATTACK_1_X = 1.0F;
constexpr float MODEL_ATTACK_1_Y = 0.2F;
constexpr float MODEL_ATTACK_2_X = 0.0F;
constexpr float MODEL_ATTACK_2_Y = 0.0F;
char second_first, char second_second,
char second_third, bool first_ready,
bool second_ready, int pos, int matchup_idx,
- bool gameover) = 0;
+ bool gameover, bool matchup_started) = 0;
virtual void do_update() = 0;
out->y = OVERVIEW_ORBIT_Y;
out->z = -(value * value - 1.0F) * OVERVIEW_ORBIT_RADIUS;
}
+
+int Helpers::a_vs_b(char a, char b) {
+ if (a == 'r') {
+ if (b == 'r') {
+ return 0;
+ } else if (b == 'p') {
+ return -1;
+ } else if (b == 's') {
+ return 1;
+ } else {
+ return 0;
+ }
+ } else if (a == 'p') {
+ if (b == 'r') {
+ return 1;
+ } else if (b == 'p') {
+ return 0;
+ } else if (b == 's') {
+ return -1;
+ } else {
+ return 0;
+ }
+ } else if (a == 's') {
+ if (b == 'r') {
+ return -1;
+ } else if (b == 'p') {
+ return 1;
+ } else if (b == 's') {
+ return 0;
+ } else {
+ return 0;
+ }
+ } else {
+ return 0;
+ }
+}
extern void overview_orbit(Vector3 *out, float value, bool is_opposite,
float offset_x);
+extern int a_vs_b(char a, char b);
+
} // namespace Helpers
#endif
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,
- int pos, int matchup_idx, bool gameover) {
+ int pos, int matchup_idx, bool gameover, 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, pos, matchup_idx,
- gameover);
+ gameover, matchup_started);
return 0;
}
../src/3d/a3f.cc \
../src/3d/a3f_conv.cc \
../src/3d/qm.cc \
+ ../src/3d/anims.cc \
../src/3d/anim_concurrent.cc \
../src/3d/anim_sequence.cc \
../src/3d/anim_model_shrink.cc \
../src/3d/anim_model_grow.cc \
- ../src/3d/anim_model_attack.cc
+ ../src/3d/anim_model_attack.cc \
+ ../src/3d/anim_model_still.cc
HEADERS = \
../src/constants.h \
../src/3d/anim_sequence.h \
../src/3d/anim_model_shrink.h \
../src/3d/anim_model_grow.h \
- ../src/3d/anim_model_attack.h
+ ../src/3d/anim_model_attack.h \
+ ../src/3d/anim_model_still.h
CXX = source ${HOME}/git/emsdk/emsdk_env.sh && em++
Rune.initClient({
visualUpdate: ({ newGame, yourPlayerId}) => {
- const { player1, player2, first_choices, second_choices, ready, pos, matchup_idx, gameover } = newGame;
+ const { player1, player2, first_choices, second_choices, ready, pos, matchup_idx, gameover, matchup_started } = newGame;
function is_choices_filled(choices) {
for (let i = 0; i < 3; ++i) {
'number', 'number', 'number',
'number', 'number', 'number',
'boolean', 'boolean',
- 'number', 'number', 'boolean'],
+ 'number', 'number', 'boolean', 'boolean'],
[player1, player2,
yourPlayerId === undefined ? 'undefined' : yourPlayerId,
first_choices[0].charCodeAt(0),
second_choices[1].charCodeAt(0),
second_choices[2].charCodeAt(0),
ready[0], ready[1],
- pos, matchup_idx, gameover]);
+ pos, matchup_idx, gameover, matchup_started]);
} else {
Module.ccall('game_visual_update',
'number',
'number', 'number', 'number',
'number', 'number', 'number',
'boolean', 'boolean',
- 'number', 'number', 'boolean'],
+ 'number', 'number', 'boolean', 'boolean'],
[player1, player2,
yourPlayerId === undefined ? 'undefined' : yourPlayerId,
'?'.charCodeAt(0),
'?'.charCodeAt(0),
'?'.charCodeAt(0),
ready[0], ready[1],
- pos, matchup_idx, gameover]);
+ pos, matchup_idx, gameover, matchup_started]);
}
},
});
pos: 0,
matchup_idx: 0,
gameover: false,
+ matchup_started: false,
}),
actions: {
set_choices: ({first, second, third}, { game, playerId }) => {
}
// Both sides are ready, iterate through matchups
+ if (!game.matchup_started) {
+ game.matchup_started = true;
+ game.ready[0] = false;
+ game.ready[1] = false;
+ return;
+ }
// check if first won the matchup
if ((game.first_choices[game.matchup_idx] === 'r'
}
game.matchup_idx = 0;
}
+ game.matchup_started = false;
}
},
},