mirror of
https://github.com/Dingo-Shenanigans/ReSkate.git
synced 2026-10-17 13:57:05 +02:00
Fix Forward Boost direction while riding Fakie
This commit is contained in:
1 parent
2cdc5ee8df
commit
14fd2c97c3
4 files changed
+74
-2
No files matched your search
@@ -105,6 +105,8 @@ if(DINGOSDK_BUILD_MULTIPLAYER_TESTS)
|
||||
add_test(NAME multiplayer_prediction COMMAND dingosdk_multiplayer_prediction_tests)
|
||||
endif()
|
||||
if(DINGOSDK_BUILD_MULTIPLAYER_TESTS AND WIN32)
|
||||
add_executable(dingosdk_velocity_boost_tests Engine/Game/Skater/Test/velocity_boost_tests.cpp)
|
||||
add_test(NAME velocity_boost COMMAND dingosdk_velocity_boost_tests)
|
||||
if(EXISTS "${PROJECT_SOURCE_DIR}/tests/first_person_spring_tests.cpp")
|
||||
add_executable(dingosdk_first_person_spring_tests tests/first_person_spring_tests.cpp)
|
||||
target_include_directories(dingosdk_first_person_spring_tests PRIVATE "${PROJECT_SOURCE_DIR}")
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
#include "Engine/Game/Skater/velocity_boost.h"
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <limits>
|
||||
|
||||
namespace {
|
||||
void check(bool condition, const char* message) {
|
||||
if (!condition) { std::cerr << message << '\n'; std::exit(1); }
|
||||
}
|
||||
bool near(float a, float b) { return std::abs(a - b) < .001f; }
|
||||
}
|
||||
|
||||
int main() {
|
||||
using dingosdk::VelocityBoostDirection;
|
||||
using dingosdk::velocity_boost_delta;
|
||||
constexpr auto forward = VelocityBoostDirection::forward;
|
||||
constexpr auto up = VelocityBoostDirection::up;
|
||||
std::array<float, 16> transform{1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1};
|
||||
// Rotate through world headings; changing preferred stance does not change
|
||||
// this contract: facing-aligned travel boosts forward, fakie travel reverses it.
|
||||
for (int heading = 0; heading < 360; heading += 15) {
|
||||
const float angle = static_cast<float>(heading) * 3.14159265f / 180.f;
|
||||
transform[8] = std::sin(angle);
|
||||
transform[10] = std::cos(angle);
|
||||
for (const float speed : {1.f, 75.f, 300.f}) {
|
||||
for (const float travel : {12.f, -12.f}) {
|
||||
const std::array<float, 3> motion{travel * transform[8], 0, travel * transform[10]};
|
||||
const auto delta = velocity_boost_delta(transform, speed, forward, motion);
|
||||
check(delta.has_value(), "Valid riding boost rejected");
|
||||
const float sign = travel < 0 ? -1.f : 1.f;
|
||||
check(near((*delta)[0], sign * speed * transform[8]) && near((*delta)[2], sign * speed * transform[10]),
|
||||
"Boost opposes riding direction");
|
||||
check(near(std::hypot((*delta)[0], (*delta)[2]), speed), "Configured boost magnitude changed");
|
||||
}
|
||||
}
|
||||
}
|
||||
transform[8] = 0; transform[10] = 1;
|
||||
for (const auto motion : {std::array<float, 3>{0, 0, 0}, {0, 0, -.05f}, {12, 0, 0}, {0, -50, 0}, {0, 50, 0}}) {
|
||||
const auto delta = velocity_boost_delta(transform, 75, forward, motion);
|
||||
check(delta && near((*delta)[2], 75), "Stationary, sideways or vertical motion reversed boost");
|
||||
}
|
||||
// Preserve the original three-dimensional facing axis and magnitude on ramps.
|
||||
transform[9] = .6f; transform[10] = .8f;
|
||||
const auto ramp = velocity_boost_delta(transform, 75, forward, {0, -100, -12});
|
||||
check(ramp && near((*ramp)[1], -45) && near((*ramp)[2], -60), "Fakie ramp direction or magnitude changed");
|
||||
const auto rising = velocity_boost_delta(transform, 75, forward, {0, -100, 12});
|
||||
check(rising && near((*rising)[1], 45) && near((*rising)[2], 60), "Vertical motion overrode forward travel");
|
||||
const auto upward = velocity_boost_delta(transform, 25, up, {0, -100, -12});
|
||||
check(upward && *upward == std::array<float, 3>{0, 25, 0}, "Up Boost changed in fakie");
|
||||
for (const float speed : {0.f, 301.f, std::numeric_limits<float>::quiet_NaN()})
|
||||
check(!velocity_boost_delta(transform, speed, forward), "Invalid forward speed accepted");
|
||||
check(!velocity_boost_delta(transform, 26, up), "Invalid up speed accepted");
|
||||
check(!velocity_boost_delta({}, 75, forward), "Degenerate facing accepted");
|
||||
check(!velocity_boost_delta(transform, 75, forward, {0, 0, std::numeric_limits<float>::infinity()}),
|
||||
"Invalid travel velocity accepted");
|
||||
std::cout << "Velocity boost regressions passed.\n";
|
||||
}
|
||||
@@ -7,7 +7,8 @@ namespace dingosdk {
|
||||
enum class VelocityBoostDirection { forward, up };
|
||||
|
||||
inline std::optional<std::array<float, 3>> velocity_boost_delta(
|
||||
const std::array<float, 16>& transform, float speed, VelocityBoostDirection direction) noexcept {
|
||||
const std::array<float, 16>& transform, float speed, VelocityBoostDirection direction,
|
||||
const std::array<float, 3>& board_velocity = {}) noexcept {
|
||||
const float maximum = direction == VelocityBoostDirection::up ? 25.0f : 300.0f;
|
||||
if (!std::isfinite(speed) || speed < 1.0f || speed > maximum) return {};
|
||||
if (direction == VelocityBoostDirection::up) return std::array<float, 3>{0, speed, 0};
|
||||
@@ -17,6 +18,16 @@ inline std::optional<std::array<float, 3>> velocity_boost_delta(
|
||||
if (!std::isfinite(length) || length <= .01f) return {};
|
||||
const auto scale = speed / std::sqrt(length);
|
||||
for (auto& component : delta) component *= scale;
|
||||
// Fakie travel opposes the skater's facing axis. Use horizontal motion so
|
||||
// falling/rising cannot reverse a boost, and retain facing at rest or sideways.
|
||||
const float horizontal_length = std::hypot(delta[0], delta[2]);
|
||||
if (horizontal_length > .01f) {
|
||||
const float travel = (delta[0] * board_velocity[0] + delta[2] * board_velocity[2]) / horizontal_length;
|
||||
if (!std::isfinite(travel)) return {};
|
||||
// Ignore tiny backwards drift around standstill (0.1 world units/s).
|
||||
if (travel < -.1f)
|
||||
for (auto& component : delta) component = -component;
|
||||
}
|
||||
return delta;
|
||||
}
|
||||
}
|
||||
@@ -488,9 +488,11 @@ void debug_action(SourceTrial& trial, std::uintptr_t client, bool can_control, b
|
||||
SourceReader reader;
|
||||
source_require(reader.value<std::uint8_t>(skater.skater_identity, 0x7e0) == 0,
|
||||
"Wait for the current teleport before using velocity boosts.");
|
||||
const auto board_velocity = up ? std::array<float, 3>{} :
|
||||
reader.value<std::array<float, 3>>(bodies.parts[0], 0x70);
|
||||
reader.verify();
|
||||
const auto velocity = velocity_boost_delta(transform, up ? debug.up_velocity_speed : debug.forward_velocity_speed,
|
||||
up ? VelocityBoostDirection::up : VelocityBoostDirection::forward);
|
||||
up ? VelocityBoostDirection::up : VelocityBoostDirection::forward, board_velocity);
|
||||
source_require(velocity.has_value(), "Velocity boost direction or speed is invalid.");
|
||||
auto& boost = up ? debug.up_velocity : debug.forward_velocity;
|
||||
source_require(!boost.valid, "Velocity boost is already queued.");
|
||||
|
||||
Reference in new issue
Block a user