#pragma once #include "plugin_effects.h" #include "plugin_wave.h" #include "Engine/Core/Json/json.h" #include "Extension/AnimationStudio/anim_core.h" #include "Extension/Skater/pose_place.h" #include "Extension/Throwdowns/throwdown_kit.h" #include #include #include #include #include #include #include #include #include #include // The game behind the wider set of the plugin API (docs: ReSkate Plugin System Design): what plugins // may read and change of the skater, the world, the session and the rest. Every function has an // "unavailable" default, so the host runs without a game (the tests give it a fake one) and the // game side fills in what it can (plugin_game_runtime.cpp). Client thread throughout. // // A string a function returns is empty when it worked, and otherwise says why not, for the plugin. namespace dingosdk::plugins { using Vec3 = std::array; inline constexpr char unavailable[] = "unavailable here"; // The game's camera as it is now: where it is, the way it looks, and its vertical field of view. struct CameraView { Vec3 position{}, forward{}; float fov{}; Vec3 right{}, up{}; bool free_camera{}; // the view is Freecam's, verified selected (not just asked for) }; // What a game layer reads of the local skater each tick (reskate.skater.telemetry): the trainer's // telemetry and its last measured jump, the physics state the skater's selector chose (with No // Bail's wipeout and runout counts), the Bone Cam's slams and where the body is during a bail. struct SkaterTelemetry { bool skater{}, airborne{}; Vec3 position{}; float heading{}; // the trainer's degrees: 0 faces +Z, forward (sin, 0, cos) float speed{}, vertical{}, air_time{}, height{}, top_speed{}; std::uint32_t physics_state{}; struct Jump { std::uint64_t serial{}; float takeoff_speed{}, takeoff_angle{}, air_time{}, height{}, distance{}, drop{}, landing_speed{}; float spin{}, spin_rate{}, flip{}, board_turn{}; std::uint32_t state{}; Vec3 takeoff{}, landing{}; } last; struct Watch { bool valid{}, ragdoll_known{}, ragdoll{}; std::uint32_t state{}, previous{}; float previous_seconds{}; std::uint64_t changes{}, wipeouts{}, runouts{}; } watch; bool teleport_pending{}, slam{}, struck{}; std::optional body; // the hips, during a bail (Bone Cam) }; struct TrickNote { std::uint64_t entry{}; char kind{}; // 'n' name, 's' side, 'l' landing, 'b' body spin, 'r' board spin, 'k' stance, 'm' modifier std::string text; }; // Input for a plugin that flies something: the flight keys and mouse look (as Freecam reads them), // a gamepad's sticks, triggers and buttons (XInput's bits), a joystick or radio's axes and buttons. struct FlightInput { float right{}, up{}, forward{}, look_x{}, look_y{}; bool boost{}; }; struct PadInput { float left_x{}, left_y{}, right_x{}, right_y{}, left_trigger{}, right_trigger{}; std::uint32_t buttons{}; bool playstation{}; }; struct StickInput { std::array axes{}; std::uint32_t buttons{}; std::string name; }; // A sound a plugin plays (reskate.audio): its wave, or the motor synth when it has none. struct SoundStart { std::shared_ptr wave; float volume{1}, pitch{1}, range{40}, throttle{}, speed{}; bool loop{}; std::optional position; // empty: at the local skater }; struct SoundChange { std::optional volume, pitch, range, throttle, speed; std::optional> position; }; // What the local skater's physics did since the last tick (events.skater). struct SkaterNews { struct Landing { float down_speed{}, speed{}; bool rail{}; }; struct Hit { std::string bone; // as the game names its body ("Left forearm") float impact{}; bool vehicle{}, board{}; }; struct Fall { float seconds{}, left{}, right{}; struct Bone { std::string name; float impact{}, slide{}; }; std::vector bones; // those that hit or slid }; std::vector landings; std::vector hits; std::vector falls; }; // One physics step of the local skater (events.physics): when (the steady clock, ms, as // reskate.time.now), how long it simulated, contacts, and available body poses even in the air. struct PhysicsStep { double at{}; float seconds{}; bool wipeout{}, airborne{}; std::optional ragdoll; std::optional velocity; std::optional spin; struct Body { std::string name; // as body_hit names it float impact{}, slide{}; bool board{}, vehicle{}, world{}; // world: anything but the board and vehicles std::optional point, normal; }; std::vector bodies; struct Pose { EffectMatrix transform{}; Vec3 velocity{}; }; std::map> poses; // all available local bodies, including airborne ones std::optional state; }; // What a plugin sets of a launch into the air, m/s, each if given: across the direction of travel // (+ its left), along it, and up. And a launch as it went (Extension/Skater/launches.h). struct LaunchShape { std::optional across, along, up; }; struct LaunchNews { std::string from; // "grind", "ollie", "no_comply", "boneless" or "other" Vec3 game{}, velocity{}; // as the game made it, as it left std::optional> travel; // the horizontal direction of travel (x, z), when moving float travel_speed{}; std::string reason; // "applied", "none", "slow", "not_ours" std::string by; // the plugin whose shape applied }; // The last slam: its force and the game's cause number, and how long ago (ms). struct SlamNews { float force{}; int cause{-1}; double ago_ms{}; }; struct CatalogItem { std::string key, title, category; }; // A park editor object on the map being played: its layout id, the item, where and how it sits. struct GameObject { std::uint64_t id{}; std::string item; Vec3 position{}; std::array rotation{0, 0, 0, 1}; // x, y, z, w float scale{1}; }; struct Destination { std::string id, name, map; // fast travel }; struct LevelInfo { std::string asset, name; bool can_load{}; }; // A skater's body as capsules: `part` indexes body_part_names; a and b are its ends in the world. struct BodyCapsule { std::uint8_t part{}; Vec3 a{}, b{}; float radius{}; }; struct Body { std::uint64_t player{}; // 0: the local skater std::vector capsules; }; inline constexpr std::array body_part_names{"head", "body", "left_arm", "right_arm", "left_leg", "right_leg", "board"}; // Another player's skater as the session last heard it. struct PeerSkater { std::uint64_t id{}; Vec3 position{}; float heading{}; // as the local skater's double age_ms{}; // since its pose arrived }; struct ChatLine { std::uint64_t sequence{}, sender{}; std::string name, text; bool local{}, server{}; }; struct Track { bool available{}, playing{}; std::string app, title, artist, album; std::uint64_t revision{}; }; struct ThrowdownState { bool active{}, host{}; struct Player { std::string name; int letters{}; bool up{}, out{}; }; std::vector skate; // S.K.A.T.E.'s players and letters, while one is shown }; // A throwdown mode on the game's Throwdowns page: a card on its picker, the game's own setup page // (relabelled from the plugin's setup document) and the game's start flag. The plugin runs it. struct ThrowdownMode { std::string id, name, description; std::string art; // the logo: a texture or image asset the plugin's mod adds, by path; empty: the card's own std::string flag; // the placement-preview prefab its native flag shows, by path; empty: Spot Battle's std::string card = "spot"; // the stock card it is cloned from: "skate", "spot" or "jam" std::string replaces; // the stock throwdown whose place it takes: "skate", "spot", "jam" or empty std::uint32_t color{}; int order{}; // among the plugin modes on the picker int min_players = 1, max_players = 6, players = 4; float cursor_height{}; // > 0: its flag's placement cursor may rise this far (metres) }; // reskate.ui.dialog: an overlay dialog over the game (plugin_dialog.cpp). Its answers come back to // the plugin as throwdown_ui events with action "dialog" (throwdown_kit.h). struct DialogSpec { std::string id, title, message; struct Field { bool present{}; std::string text; std::size_t max{64}; } field; struct Row { std::string text, sub; std::vector buttons; // each answers with its name and the row }; bool list{}; std::vector rows; std::string empty; // shown in a list with no rows struct Button { std::string id, label; }; std::vector