mirror of
https://github.com/Dingo-Shenanigans/ReSkate.git
synced 2026-10-17 16:17:06 +02:00
PRACTICE > TELEPORT now shows the waypoint the player placed on the game's pause map, with a "Go to map waypoint" button. The console gets `trainer waypoint [info]` and `trainer ground <x> <z>`. Reading the waypoint (trainer_waypoint.cpp) - It is a point of interest in the map's registry, the one ReSkate's party markers register into (addr::native_party::map_manager), with kind DingoMapPOIType_Waypoint (3) and its world matrix at @0. - The registry is walked only while the TELEPORT card is drawn (the page notes it, like the class list) or the command runs, every 250 ms at most. A player who never opens the card pays nothing. - A registry the map has filled without a waypoint means it was removed; an empty or unreadable one keeps the last waypoint seen. A new level forgets it. Landing on the surface (trainer_landing.h) - The waypoint's height is not the ground: teleporting to it dropped the skater through the map. local_ground_height() casts the park editor's downward ray (editor::cast_surface) through the client physics world and takes the topmost hit. - The first ray starts at 1500 or 500 above the hint. A custom map can sit higher than that (a waypoint at Y 12 over ground at Y 1939 was seen in game), so a miss is cast again from 20000. - If collision there is still streaming in, the teleport goes to the hint's height and a 12 s watch puts the skater on the surface when it arrives (at most 6 corrections; the teleport is re-sent up to 3 times if it never arrives). - Teleports still go through go_to(), so they follow the host's noclip / teleport permission in a session. The decisions (ray spans, the watch, remember/forget) have no game in them and are tested by trainer_landing (DINGOSDK_BUILD_TRAINER_TESTS). README and CHANGELOG updated.
47 lines
1.5 KiB
C++
47 lines
1.5 KiB
C++
#include "trainer.h"
|
|
#include <atomic>
|
|
#include <mutex>
|
|
|
|
// The snapshots the menu and HUD read. Kept apart from trainer.cpp so the overlay library
|
|
// links without the game-facing half.
|
|
namespace dingosdk::trainer {
|
|
namespace {
|
|
struct Feed {
|
|
std::mutex mutex;
|
|
std::shared_ptr<const View> view = std::make_shared<const View>();
|
|
Telemetry telemetry;
|
|
std::atomic<bool> class_list_shown{};
|
|
std::atomic<bool> teleport_card_shown{};
|
|
};
|
|
Feed &feed() {
|
|
static auto *value = new Feed;
|
|
return *value;
|
|
}
|
|
} // namespace
|
|
std::shared_ptr<const View> view() noexcept {
|
|
auto &f = feed();
|
|
std::lock_guard lock(f.mutex);
|
|
return f.view;
|
|
}
|
|
Telemetry telemetry() noexcept {
|
|
auto &f = feed();
|
|
std::lock_guard lock(f.mutex);
|
|
return f.telemetry;
|
|
}
|
|
void publish(std::shared_ptr<const View> next) noexcept {
|
|
if (!next) return;
|
|
auto &f = feed();
|
|
std::lock_guard lock(f.mutex);
|
|
f.view = std::move(next);
|
|
}
|
|
void publish(const Telemetry &next) noexcept {
|
|
auto &f = feed();
|
|
std::lock_guard lock(f.mutex);
|
|
f.telemetry = next;
|
|
}
|
|
void note_class_list_shown() noexcept { feed().class_list_shown.store(true, std::memory_order_release); }
|
|
bool take_class_list_shown() noexcept { return feed().class_list_shown.exchange(false, std::memory_order_acq_rel); }
|
|
void note_teleport_card_shown() noexcept { feed().teleport_card_shown.store(true, std::memory_order_release); }
|
|
bool take_teleport_card_shown() noexcept { return feed().teleport_card_shown.exchange(false, std::memory_order_acq_rel); }
|
|
} // namespace dingosdk::trainer
|