Skip to content

Commit

Permalink
Fixed processing V3 sliders (#84)
Browse files Browse the repository at this point in the history
  • Loading branch information
NSGolova authored Jul 27, 2024
1 parent bf3b703 commit fa5eb45
Show file tree
Hide file tree
Showing 2 changed files with 176 additions and 0 deletions.
1 change: 1 addition & 0 deletions include/Constants.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ inline static constexpr const std::string_view LINK = "link";
inline static constexpr const std::string_view TARGET = "target";

inline static constexpr const std::string_view INTERNAL_STARTNOTELINELAYER = "NE_startNoteLineLayer";
inline static constexpr const std::string_view INTERNAL_TAILSTARTNOTELINELAYER = "NE_tailStartNoteLineLayer";
inline static constexpr const std::string_view INTERNAL_FLIPYSIDE = "NE_flipYSide";
inline static constexpr const std::string_view INTERNAL_FLIPLINEINDEX = "NE_flipLineIndex";
inline static constexpr const std::string_view INTERNAL_FAKE_NOTE = "NE_fake";
Expand Down
175 changes: 175 additions & 0 deletions src/Hooks/BeatmapObjectsInTimeRowProcessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@
using namespace GlobalNamespace;
using namespace CustomJSONData;

#include <cmath>
// Port of MathF.Approximately
bool Approximately(float a, float b) {
float const epsilon = 1.17549435E-38f * 8.0f;
float const maxAbs = std::max(std::fabs(a), std::fabs(b));
return std::fabs(b - a) < std::max(1E-06f * maxAbs, epsilon);
}

void BeatmapObjectsInTimeRowProcessor_HandleCurrentTimeSliceAllNotesAndSlidersDidFinishTimeSliceTranspile(
BeatmapObjectsInTimeRowProcessor* self,
GlobalNamespace::BeatmapObjectsInTimeRowProcessor::TimeSliceContainer_1<::GlobalNamespace::BeatmapDataItem*>*
Expand Down Expand Up @@ -164,6 +172,173 @@ MAKE_HOOK_MATCH(
}
}

auto customSliders = NoodleExtensions::of_type<CustomSliderData*>(ListW<GlobalNamespace::BeatmapDataItem*>(items));
auto customTails = NoodleExtensions::of_type<BeatmapObjectsInTimeRowProcessor::SliderTailData*>(
ListW<GlobalNamespace::BeatmapDataItem*>(items));
for (auto slider : customSliders) {
NEJSON::OptPair headPos = NEJSON::OptPair(std::nullopt, std::nullopt);

if (slider->customData->value) {
rapidjson::Value const& sliderCustomData = *slider->customData->value;
headPos = NEJSON::ReadOptionalPair(sliderCustomData, NoodleExtensions::Constants::NOTE_OFFSET.data());
}

float headX = headPos.first.value_or(slider->headLineIndex - offset) + offset;
float headY = headPos.second.value_or(slider->headLineLayer.value__);

for (auto note : customNotes) {
NEJSON::OptPair notePos = NEJSON::OptPair(std::nullopt, std::nullopt);

if (note->customData->value) {
rapidjson::Value const& noteCustomData = *note->customData->value;

notePos = NEJSON::ReadOptionalPair(noteCustomData, NoodleExtensions::Constants::V2_POSITION.data());
if (!notePos.first) {
notePos = NEJSON::ReadOptionalPair(noteCustomData, NoodleExtensions::Constants::NOTE_OFFSET.data());
}
}

float noteX = notePos.first.value_or(note->lineIndex - offset) + offset;
float noteY = notePos.second.value_or(note->noteLineLayer.value__);

if (Approximately(headX, noteX) && Approximately(headY, noteY)) {
slider->SetHasHeadNote(true);

float startNoteLineLayer = note->beforeJumpNoteLineLayer.value__;
if (note->customData->value) {
startNoteLineLayer = getAD(note->customData).startNoteLineLayer;
}
if (slider->customData->value) {
BeatmapObjectAssociatedData& ad = getAD(slider->customData);
ad.startNoteLineLayer = startNoteLineLayer;
} else {
slider->SetHeadBeforeJumpLineLayer(startNoteLineLayer);
}

if (slider->sliderType == CustomSliderData::Type::Burst) {
note->ChangeToBurstSliderHead();

// PC logic, I've no idea why it's there

// if (noteData.cutDirection != sliderData.tailCutDirection)
// {
// continue;
// }

// Vector2 line = SpawnDataManager.Get2DNoteOffset(noteX, ____numberOfLines, noteY) -
// SpawnDataManager.Get2DNoteOffset(tailX, ____numberOfLines, tailY);
// float num = noteData.cutDirection.Direction().SignedAngleToLine(line);
// if (!(Mathf.Abs(num) <= 40f))
// {
// continue;
// }

// noteData.SetCutDirectionAngleOffset(num);
// sliderData.SetCutDirectionAngleOffset(num, num);
} else {
note->MarkAsSliderHead();
}
}
}

for (auto tailSlider : customSliders) {
if (slider == tailSlider || slider->sliderType != CustomSliderData::Type::Normal ||
tailSlider->sliderType != CustomSliderData::Type::Burst)
continue;

NEJSON::OptPair tailPos = NEJSON::OptPair(std::nullopt, std::nullopt);

if (tailSlider->customData->value) {
rapidjson::Value const& tailSliderCustomData = *tailSlider->customData->value;

tailPos = NEJSON::ReadOptionalPair(tailSliderCustomData, NoodleExtensions::Constants::TAIL_NOTE_OFFSET.data());
}
float tailX = tailPos.first.value_or(tailSlider->tailLineIndex - offset) + offset;
float tailY = tailPos.second.value_or(tailSlider->tailLineLayer.value__);

if (Approximately(tailX, headX) && Approximately(tailY, headY)) {
slider->SetHasHeadNote(true);
float startNoteLineLayer = tailSlider->tailBeforeJumpLineLayer.value__;
if (slider->customData->value) {
BeatmapObjectAssociatedData& ad = getAD(slider->customData);
ad.tailStartNoteLineLayer = startNoteLineLayer;
} else {
slider->SetTailBeforeJumpLineLayer(startNoteLineLayer);
}
}
}

for (auto tailSliderData : customTails) {
auto tailSlider = reinterpret_cast<CustomSliderData*>(tailSliderData->slider);
if (!tailSlider || slider->sliderType != CustomSliderData::Type::Normal ||
tailSlider->sliderType != CustomSliderData::Type::Burst)
continue;

NEJSON::OptPair tailPos = NEJSON::OptPair(std::nullopt, std::nullopt);

if (tailSlider->customData->value) {
rapidjson::Value const& tailSliderCustomData = *tailSlider->customData->value;

tailPos = NEJSON::ReadOptionalPair(tailSliderCustomData, NoodleExtensions::Constants::TAIL_NOTE_OFFSET.data());
}
float tailX = tailPos.first.value_or(tailSlider->tailLineIndex - offset) + offset;
float tailY = tailPos.second.value_or(tailSlider->tailLineLayer.value__);

if (Approximately(tailX, headX) && Approximately(tailY, headY)) {
slider->SetHasHeadNote(true);
float startNoteLineLayer = tailSlider->tailBeforeJumpLineLayer.value__;
if (slider->customData->value) {
BeatmapObjectAssociatedData& ad = getAD(slider->customData);
ad.tailStartNoteLineLayer = startNoteLineLayer;
} else {
slider->SetTailBeforeJumpLineLayer(startNoteLineLayer);
}
}
}
}

for (auto customTail : customTails) {
auto slider = reinterpret_cast<CustomSliderData*>(customTail->slider);

if (!slider) continue;

NEJSON::OptPair tailPos = NEJSON::OptPair(std::nullopt, std::nullopt);
if (slider->customData->value) {
rapidjson::Value const& sliderCustomData = *slider->customData->value;

tailPos = NEJSON::ReadOptionalPair(sliderCustomData, NoodleExtensions::Constants::TAIL_NOTE_OFFSET.data());
}
float tailX = tailPos.first.value_or(slider->tailLineIndex - offset) + offset;
float tailY = tailPos.second.value_or(slider->tailLineLayer.value__);

for (auto note : customNotes) {
NEJSON::OptPair notePos = NEJSON::OptPair(std::nullopt, std::nullopt);

if (note->customData->value) {
rapidjson::Value const& noteCustomData = *note->customData->value;

notePos = NEJSON::ReadOptionalPair(noteCustomData, NoodleExtensions::Constants::V2_POSITION.data());
if (!notePos.first)
notePos = NEJSON::ReadOptionalPair(noteCustomData, NoodleExtensions::Constants::NOTE_OFFSET.data());
}

float noteX = notePos.first.value_or(note->lineIndex - offset) + offset;
float noteY = notePos.second.value_or(note->noteLineLayer.value__);

if (Approximately(tailX, noteX) && Approximately(tailY, noteY)) {
slider->SetHasTailNote(true);
note->MarkAsSliderTail();
float startNoteLineLayer = note->beforeJumpNoteLineLayer.value__;
if (slider->customData->value) {
BeatmapObjectAssociatedData& ad = getAD(slider->customData);
ad.tailStartNoteLineLayer = startNoteLineLayer;
} else {
slider->SetTailBeforeJumpLineLayer(startNoteLineLayer);
}
}
}
}

return BeatmapObjectsInTimeRowProcessor_HandleCurrentTimeSliceAllNotesAndSlidersDidFinishTimeSliceTranspile(
self, allObjectsTimeSlice, nextTimeSliceTime);
}
Expand Down

0 comments on commit fa5eb45

Please sign in to comment.