mirror of
https://github.com/Dingo-Shenanigans/ReSkate.git
synced 2026-10-23 16:25:58 +02:00
PR 343's Filmer becomes a Luau plugin mod (kept in contrib/plugins/filmer) on general APIs instead of
its own C++:
- reskate.skater.carry: something held out in one or both hands and aimed, the body crouched (feet
kept) and hunched over it, turned on the spot after it (Extension/Skater/carry.cpp, from the PR's
filmer_hold.cpp, with tests)
- shown = "everyone" | "others" | "me" on skater.pose, reach and carry: the pose sent to the other
players and the one drawn here are split when asked
- reskate.camera.cycle and the camera_cycle event: a plugin's camera as the last step of the camera
height button's cycle, after first person
- reskate.session.nametags(false) holds the names over the other players off
- board.hide(bone, {others = true}) hides it in the board the others are sent too (a sent-pose filter)
- outfit.set takes hand wear slots; input.bind takes an action with no key of its own
111 lines
5.1 KiB
C++
111 lines
5.1 KiB
C++
#include "Engine/Game/Skater/first_person_cycle.h"
|
|
|
|
#include <cstdio>
|
|
#include <string_view>
|
|
|
|
// First person in the camera cycle (first_person::cycle_height_write): the game's camera height
|
|
// button flips UseHighCam; the option turns that into high -> low -> first person -> high.
|
|
namespace {
|
|
using namespace dingosdk::first_person;
|
|
int failures = 0;
|
|
|
|
void expect(bool condition, std::string_view what) {
|
|
if (condition) return;
|
|
++failures;
|
|
std::printf("FAIL: %.*s\n", static_cast<int>(what.size()), what.data());
|
|
}
|
|
bool same(const CycleWrite& write, bool high, CycleStep step) { return write.high == high && write.step == step; }
|
|
|
|
void off() {
|
|
for (const bool first_person : {false, true})
|
|
for (const bool high : {false, true})
|
|
expect(same(cycle_height_write({false, first_person, true}, high), high, CycleStep::none),
|
|
"with the option off the game's height passes through and first person is left alone");
|
|
}
|
|
|
|
void steps() {
|
|
expect(same(cycle_height_write({true, false, true}, false), false, CycleStep::none), "high -> low is the game's own step");
|
|
expect(same(cycle_height_write({true, false, true}, true), false, CycleStep::enter),
|
|
"low -> first person keeps the low camera behind it");
|
|
expect(same(cycle_height_write({true, true, false}, true), true, CycleStep::leave),
|
|
"first person (low behind it) -> the high camera");
|
|
expect(same(cycle_height_write({true, true, false}, false), true, CycleStep::leave),
|
|
"first person switched on in the menu over the high camera still lands on high");
|
|
expect(same(cycle_height_write({true, false, false}, true), true, CycleStep::none),
|
|
"where first person cannot start (on foot, Freecam) low -> high is the game's own step");
|
|
}
|
|
|
|
// The game reads the height it keeps and writes the opposite on every press.
|
|
void presses() {
|
|
for (const bool start_high : {true, false}) {
|
|
bool high = start_high, first_person = false;
|
|
const auto press = [&] {
|
|
const auto write = cycle_height_write({true, first_person, !first_person}, !high);
|
|
high = write.high;
|
|
if (write.step == CycleStep::enter) first_person = true;
|
|
if (write.step == CycleStep::leave) first_person = false;
|
|
};
|
|
if (!start_high) press(); // low -> first person
|
|
if (!start_high) press(); // first person -> high
|
|
for (int round = 0; round < 3; ++round) {
|
|
expect(high && !first_person, "the cycle starts each round on the high camera");
|
|
press();
|
|
expect(!high && !first_person, "first press: low camera");
|
|
press();
|
|
expect(!high && first_person, "second press: first person over the low camera");
|
|
press();
|
|
}
|
|
expect(high && !first_person, "the third press of each round returns to the high camera");
|
|
}
|
|
}
|
|
|
|
// With a plugin's camera in the cycle: high -> low -> first person -> the plugin's camera -> high, and
|
|
// without first person (or on foot, where it cannot start) high -> low -> the plugin's camera -> high.
|
|
void plugin() {
|
|
for (const bool with_first_person : {true, false}) {
|
|
bool high = true, first_person = false, on = false;
|
|
const auto press = [&] {
|
|
CycleState state{with_first_person, first_person, !first_person && !on, true, on, !on};
|
|
const auto write = cycle_height_write(state, !high);
|
|
high = write.high;
|
|
if (write.step == CycleStep::enter) first_person = true;
|
|
if (write.step == CycleStep::leave) first_person = false;
|
|
if (write.plugin == CycleStep::enter) on = true;
|
|
if (write.plugin == CycleStep::leave) on = false;
|
|
};
|
|
for (int round = 0; round < 3; ++round) {
|
|
expect(high && !first_person && !on, "each round starts on the high camera");
|
|
press();
|
|
expect(!high && !first_person && !on, "first press: low camera");
|
|
if (with_first_person) {
|
|
press();
|
|
expect(!high && first_person && !on, "second press: first person");
|
|
}
|
|
press();
|
|
expect(!high && !first_person && on, "then the plugin's camera, the low camera behind it");
|
|
press();
|
|
}
|
|
expect(high && !first_person && !on, "out of the plugin's camera: the high camera");
|
|
}
|
|
// No plugin in the cycle: the first-person cycle as before.
|
|
expect(same(cycle_height_write({true, true, false, false, false, true}, true), true, CycleStep::leave),
|
|
"without a plugin's camera, first person -> high");
|
|
// Turned on by the plugin itself over the high camera: the button still takes it out to high.
|
|
const auto out = cycle_height_write({false, false, true, true, true, false}, false);
|
|
expect(out.high && out.plugin == CycleStep::leave, "a plugin's camera on by itself: the button leaves it for high");
|
|
}
|
|
} // namespace
|
|
|
|
int main() {
|
|
off();
|
|
steps();
|
|
presses();
|
|
plugin();
|
|
if (failures) {
|
|
std::printf("%d first-person cycle test(s) failed\n", failures);
|
|
return 1;
|
|
}
|
|
std::printf("first-person cycle tests passed\n");
|
|
return 0;
|
|
}
|