Skip to content

Commit 0f68e3d

Browse files
committed
add miss window custom window function and a way to stop their evaluation
1 parent b20cf83 commit 0f68e3d

File tree

2 files changed

+84
-5
lines changed

2 files changed

+84
-5
lines changed

src/Etterna/Singletons/ReplayManager.cpp

Lines changed: 67 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ ReplayManager::ReplayManager() {
6666
m_offsetJudgingFunc = ref;
6767
m_tapScoringFunc = ref;
6868
m_totalWifePointsCalcFunc = ref;
69+
m_missWindowFunc = ref;
6970

7071
LUA->Release(L);
7172
}
@@ -530,7 +531,7 @@ ReplayManager::CustomTapScoringFunction(float fOffsetSeconds,
530531
return wife3(fOffsetSeconds, timingScale);
531532
};
532533

533-
if (m_tapScoringFunc.IsNil()) {
534+
if (m_tapScoringFunc.IsNil() || !customScoringFunctionsEnabled) {
534535
return defaultscoring(fOffsetSeconds, timingScale);
535536
} else {
536537
auto output = 0.F;
@@ -578,7 +579,7 @@ ReplayManager::CustomHoldNoteScoreScoringFunction(HoldNoteScore hns) -> float
578579
}
579580
};
580581

581-
if (m_holdNoteScoreScoringFunc.IsNil()) {
582+
if (m_holdNoteScoreScoringFunc.IsNil() || !customScoringFunctionsEnabled) {
582583
return defaultscoring(hns);
583584
} else {
584585
auto output = 0.F;
@@ -612,7 +613,7 @@ ReplayManager::CustomMineScoringFunction() -> float
612613
{
613614
static auto defaultscoring = []() { return wife3_mine_hit_weight; };
614615

615-
if (m_mineScoringFunc.IsNil()) {
616+
if (m_mineScoringFunc.IsNil() || !customScoringFunctionsEnabled) {
616617
return defaultscoring();
617618
} else {
618619
auto output = 0.F;
@@ -654,7 +655,7 @@ ReplayManager::CustomTotalWifePointsCalculation(TapNoteType tnt) -> float
654655
}
655656
};
656657

657-
if (m_totalWifePointsCalcFunc.IsNil()) {
658+
if (m_totalWifePointsCalcFunc.IsNil() || !customScoringFunctionsEnabled) {
658659
return defaultscoring(tnt);
659660
} else {
660661
auto output = 0.F;
@@ -691,7 +692,7 @@ ReplayManager::CustomOffsetJudgingFunction(float fOffsetSeconds, float timingSca
691692
return GetTapNoteScoreForReplay(fOffsetSeconds, timingScale);
692693
};
693694

694-
if (m_offsetJudgingFunc.IsNil()) {
695+
if (m_offsetJudgingFunc.IsNil() || !customScoringFunctionsEnabled) {
695696
return defaultscoring(fOffsetSeconds, timingScale);
696697
} else {
697698
auto output = TNS_None;
@@ -714,6 +715,40 @@ ReplayManager::CustomOffsetJudgingFunction(float fOffsetSeconds, float timingSca
714715
}
715716
}
716717

718+
auto
719+
ReplayManager::CustomMissWindowFunction() -> float
720+
{
721+
static auto defaultscoring = []() { return MISS_WINDOW_BEGIN_SEC; };
722+
723+
if (m_missWindowFunc.IsNil() || !customScoringFunctionsEnabled) {
724+
return defaultscoring();
725+
} else {
726+
auto output = 0.F;
727+
auto L = LUA->Get();
728+
m_missWindowFunc.PushSelf(L);
729+
static std::string err = "Error running custom miss window function";
730+
if (LuaHelpers::RunScriptOnStack(L, err, 0, 1, true)) {
731+
if (lua_isnumber(L, -1)) {
732+
output = std::clamp(static_cast<float>(lua_tonumber(L, -1)),
733+
0.F,
734+
MISS_WINDOW_BEGIN_SEC);
735+
} else {
736+
LuaHelpers::ReportScriptError("You must return a number in the "
737+
"Custom Miss Window Function.");
738+
output = defaultscoring();
739+
}
740+
} else {
741+
output = defaultscoring();
742+
Locator::getLogger()->warn("Failed to run script on stack for "
743+
"custom miss window function. "
744+
"Defaulted to 180ms.");
745+
}
746+
lua_settop(L, 0);
747+
LUA->Release(L);
748+
return output;
749+
}
750+
}
751+
717752
#include "Etterna/Models/Lua/LuaBinding.h"
718753
class LunaReplayManager : public Luna<ReplayManager>
719754
{
@@ -748,6 +783,7 @@ class LunaReplayManager : public Luna<ReplayManager>
748783
p->SetHoldNoteScoringFunction(ref);
749784
p->SetTapScoringFunction(ref);
750785
p->SetOffsetJudgingFunction(ref);
786+
p->SetMissWindowFunction(ref);
751787

752788
COMMON_RETURN_SELF;
753789
}
@@ -868,6 +904,31 @@ class LunaReplayManager : public Luna<ReplayManager>
868904
COMMON_RETURN_SELF;
869905
}
870906

907+
static int SetMissWindowFunction(T* p, lua_State* L) {
908+
// pass a lua function
909+
// that lua function takes no input and returns a number
910+
// the number is usually [0,1]
911+
// 0.180 is the default
912+
913+
// reset if empty
914+
if (lua_isnil(L, 1)) {
915+
LuaReference ref;
916+
lua_pushnil(L);
917+
ref.SetFromStack(L);
918+
// reset
919+
p->SetMissWindowFunction(ref);
920+
} else {
921+
luaL_checktype(L, 1, LUA_TFUNCTION);
922+
LuaReference ref;
923+
lua_pushvalue(L, 1);
924+
ref.SetFromStack(L);
925+
// set
926+
p->SetMissWindowFunction(ref);
927+
}
928+
929+
COMMON_RETURN_SELF;
930+
}
931+
871932
static int RunOffsetJudgingFunction(T* p, lua_State* L) {
872933

873934
// this offset should be [-1,1] rather than [-1000,1000]
@@ -892,6 +953,7 @@ class LunaReplayManager : public Luna<ReplayManager>
892953
ADD_METHOD(SetHoldNoteScoreScoringFunction);
893954
ADD_METHOD(SetTapScoringFunction);
894955
ADD_METHOD(SetOffsetJudgingFunction);
956+
ADD_METHOD(SetMissWindowFunction);
895957

896958
ADD_METHOD(RunOffsetJudgingFunction);
897959
}

src/Etterna/Singletons/ReplayManager.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,13 @@ class ReplayManager
9191
auto GenerateComboListForReplay(Replay& replay, float timingScale = 1.F)
9292
-> std::vector<PlayerStageStats::Combo_t>;
9393

94+
void EnableCustomScoringFunctions() {
95+
customScoringFunctionsEnabled = true;
96+
}
97+
void DisableCustomScoringFunctions() {
98+
customScoringFunctionsEnabled = false;
99+
}
100+
94101
////////
95102
// custom scoring functions
96103
// these will default to base game behavior if the custom functions arent set
@@ -118,6 +125,10 @@ class ReplayManager
118125
/// return: tapnotescore (str)
119126
auto CustomOffsetJudgingFunction(float fOffsetSeconds, float timingScale)
120127
-> TapNoteScore;
128+
/// The time in seconds at which a note is not judged.
129+
/// If a note is further than this distance from a tap, it is not judged.
130+
/// If for some reason an assigned offset is outside this window, it is a miss.
131+
auto CustomMissWindowFunction() -> float;
121132

122133
void SetTotalWifePointsCalcFunction(const LuaReference& ref) {
123134
m_totalWifePointsCalcFunc = ref;
@@ -134,6 +145,9 @@ class ReplayManager
134145
void SetOffsetJudgingFunction(const LuaReference& ref) {
135146
m_offsetJudgingFunc = ref;
136147
}
148+
void SetMissWindowFunction(const LuaReference& ref) {
149+
m_missWindowFunc = ref;
150+
}
137151
//
138152
/////////
139153

@@ -150,6 +164,9 @@ class ReplayManager
150164
LuaReference m_holdNoteScoreScoringFunc;
151165
LuaReference m_tapScoringFunc;
152166
LuaReference m_offsetJudgingFunc;
167+
LuaReference m_missWindowFunc;
168+
169+
bool customScoringFunctionsEnabled = false;
153170

154171
};
155172

0 commit comments

Comments
 (0)