Skip to content

Commit ea76de7

Browse files
committed
fix player 2 orbs
1 parent 6e8f2dd commit ea76de7

File tree

5 files changed

+51
-21
lines changed

5 files changed

+51
-21
lines changed

src/Replay.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ void Replay::save(const std::string& path) {
5353
file << format_magic << format_ver << type;
5454
bin_write(file, fps);
5555
for (const auto& action : actions) {
56-
uint8_t state = action.hold | action.player2 << 1;
56+
uint8_t state = static_cast<uint8_t>(action.hold) | static_cast<uint8_t>(action.player2) << 1;
5757
if (type == ReplayType::XPOS)
5858
bin_write(file, action.x);
5959
else if (type == ReplayType::FRAME)
@@ -90,7 +90,12 @@ Replay Replay::load(const std::string& path) {
9090
auto state = bin_read<uint8_t>(file);
9191
bool hold = state & 1;
9292
bool player2 = state & 2;
93-
replay.add_action({ replay.type == ReplayType::XPOS ? x : frame, hold, player2 });
93+
Action action = { 0, hold, player2 };
94+
if (replay.type == ReplayType::XPOS)
95+
action.x = x;
96+
else if (replay.type == ReplayType::FRAME)
97+
action.frame = frame;
98+
replay.add_action(action);
9499
}
95100
}
96101
} else {

src/hooks.cpp

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ void Hooks::init() {
3636

3737
ADD_GD_HOOK(0x1f4ff0, PlayerObject_ringJump);
3838
ADD_GD_HOOK(0xef0e0, GameObject_activateObject);
39+
ADD_GD_HOOK(0x10ed50, GJBaseGameLayer_bumpPlayer);
3940
}
4041

4142
void __fastcall Hooks::CCScheduler_update_H(CCScheduler* self, int, float dt) {
@@ -180,20 +181,34 @@ bool __fastcall Hooks::PauseLayer_init_H(gd::PauseLayer* self, int) {
180181
return false;
181182
}
182183

183-
void __fastcall Hooks::PlayerObject_ringJump_H(gd::PlayerObject* self, int, gd::GameObject* ring) {
184-
PlayerObject_ringJump(self, ring);
185-
auto& rs = ReplaySystem::get_instance();
184+
void _handle_activated_object(bool a, bool b, gd::GameObject* object) {
186185
auto play_layer = gd::GameManager::sharedState()->getPlayLayer();
187-
if (play_layer && play_layer->is_practice_mode && rs.is_recording() && ring->m_hasBeenActivated) {
188-
rs.get_practice_fixes().add_activated_object(ring);
186+
auto& rs = ReplaySystem::get_instance();
187+
if (play_layer && play_layer->is_practice_mode && rs.is_recording()) {
188+
if (object->m_hasBeenActivated && !a)
189+
rs.get_practice_fixes().add_activated_object(object);
190+
if (object->m_hasBeenActivatedP2 && !b)
191+
rs.get_practice_fixes().add_activated_object_p2(object);
189192
}
190193
}
191194

195+
void __fastcall Hooks::PlayerObject_ringJump_H(gd::PlayerObject* self, int, gd::GameObject* ring) {
196+
bool a = ring->m_hasBeenActivated;
197+
bool b = ring->m_hasBeenActivatedP2;
198+
PlayerObject_ringJump(self, ring);
199+
_handle_activated_object(a, b, ring);
200+
}
201+
192202
void __fastcall Hooks::GameObject_activateObject_H(gd::GameObject* self, int, gd::PlayerObject* player) {
203+
bool a = self->m_hasBeenActivated;
204+
bool b = self->m_hasBeenActivatedP2;
193205
GameObject_activateObject(self, player);
194-
auto& rs = ReplaySystem::get_instance();
195-
auto play_layer = gd::GameManager::sharedState()->getPlayLayer();
196-
if (play_layer && play_layer->is_practice_mode && rs.is_recording() && self->m_hasBeenActivated) {
197-
rs.get_practice_fixes().add_activated_object(self);
198-
}
206+
_handle_activated_object(a, b, self);
207+
}
208+
209+
void __fastcall Hooks::GJBaseGameLayer_bumpPlayer_H(gd::GJBaseGameLayer* self, int, gd::PlayerObject* player, gd::GameObject* object) {
210+
bool a = object->m_hasBeenActivated;
211+
bool b = object->m_hasBeenActivatedP2;
212+
GJBaseGameLayer_bumpPlayer(self, player, object);
213+
_handle_activated_object(a, b, object);
199214
}

src/hooks.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,5 @@ namespace Hooks {
3636

3737
_THISCALL_HOOK(PlayerObject_ringJump, void, gd::PlayerObject, gd::GameObject* ring)
3838
_THISCALL_HOOK(GameObject_activateObject, void, gd::GameObject, gd::PlayerObject* player)
39+
_THISCALL_HOOK(GJBaseGameLayer_bumpPlayer, void, gd::GJBaseGameLayer, gd::PlayerObject* player, gd::GameObject* object)
3940
}

src/practice_fixes.hpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,22 +19,23 @@ struct Checkpoint {
1919
CheckpointData player1;
2020
CheckpointData player2;
2121
size_t activated_objects_size;
22+
size_t activated_objects_p2_size;
2223
unsigned frame;
2324
};
2425

2526
class PracticeFixes {
2627
std::stack<Checkpoint> checkpoints;
2728
std::vector<gd::GameObject*> activated_objects;
29+
std::vector<gd::GameObject*> activated_objects_p2;
2830
friend class ReplaySystem;
2931
public:
30-
PracticeFixes() {}
31-
3232
void add_checkpoint(unsigned frame = 0) {
3333
auto play_layer = gd::GameManager::sharedState()->getPlayLayer();
3434
checkpoints.push({
3535
CheckpointData::from_player(play_layer->m_player1),
3636
CheckpointData::from_player(play_layer->m_player2),
3737
activated_objects.size(),
38+
activated_objects_p2.size(),
3839
frame
3940
});
4041
}
@@ -67,4 +68,7 @@ class PracticeFixes {
6768
void add_activated_object(gd::GameObject* object) {
6869
activated_objects.push_back(object);
6970
}
71+
void add_activated_object_p2(gd::GameObject* object) {
72+
activated_objects_p2.push_back(object);
73+
}
7074
};

src/replay_system.cpp

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,19 +40,24 @@ void ReplaySystem::on_reset() {
4040
Hooks::PlayLayer::releaseButton(play_layer, 0, true);
4141
action_index = 0;
4242
} else if (is_recording()) {
43-
auto& activated_objects = practice_fixes.activated_objects;
4443
if (practice_fixes.checkpoints.empty()) {
45-
activated_objects.clear();
44+
practice_fixes.activated_objects.clear();
45+
practice_fixes.activated_objects_p2.clear();
4646
frame_offset = 0;
4747
} else {
4848
frame_offset = practice_fixes.checkpoints.top().frame;
49-
activated_objects.erase(
50-
activated_objects.begin() + practice_fixes.checkpoints.top().activated_objects_size,
51-
activated_objects.end()
52-
);
53-
for (const auto object : activated_objects) {
49+
constexpr auto delete_from = [&](auto& vec, size_t index) {
50+
vec.erase(vec.begin() + index, vec.end());
51+
};
52+
const auto& checkpoint = practice_fixes.checkpoints.top();
53+
delete_from(practice_fixes.activated_objects, checkpoint.activated_objects_size);
54+
delete_from(practice_fixes.activated_objects_p2, checkpoint.activated_objects_p2_size);
55+
for (const auto& object : practice_fixes.activated_objects) {
5456
object->m_hasBeenActivated = true;
5557
}
58+
for (const auto& object : practice_fixes.activated_objects_p2) {
59+
object->m_hasBeenActivatedP2 = true;
60+
}
5661
}
5762
if (replay.get_type() == ReplayType::XPOS)
5863
replay.remove_actions_after(play_layer->m_player1->position.x);

0 commit comments

Comments
 (0)