Files
itgmania212121/Themes/_fallback/Scripts/05 ScoringEngine2.lua
T
Jason Felds b71caa445c hgeol I bet.
2012-05-10 02:02:37 -04:00

118 lines
3.9 KiB
Lua

--ScoringEngine2 by FSX v1.41
--essentially a really chunky layer to make SetScore elegant(ish)
--arguments for scorekeepers: JudgmentMessageCommand,PlayerStageStats,PlayerNumber,State
--[[changelog
v1.41 6 May 2012
*Not really sure.
*Included in SM5 for alpha 3.
v1.4 18 Apr 2012
*Support for judgment filtering.
*Minor changes.
*First public release (in SE2 Dev Kit) (didn't happen)
v1.3 17 Apr 2012
*First complete release.
*Error reporting in FinalizeScoreKeepers()
*Bug fixes.]]
--scoring modes written for the old ad-hoc system don't work, but don't cause crashes either.
--SM5 has some glue code for them, though
local stageKey = nil
local ReadiedScoreKeepers = {}
local JudgmentFilters = {}
local function CoroutineIsGood(cr)
return coroutine.status(cr)=="suspended"
end
function InitScoreKeepers(p1Mode, p2Mode)
local newStgK = {pcall(GameState.GetStageSeed,GAMESTATE)}
assert(newStgK[1], "it's too early to initialize the ScoreKeepers, the GameState isn't ready yet")
if newStgK[2] == stageKey then
Log "[InitScoreKeepers] unnecessary call"
return true
end
ReadiedScoreKeepers={}
JudgmentFilters={}
stageKey = newStgK
local intab = {}
if p1Mode ~= nil then
intab.P1 = p1Mode
end
if p2Mode ~= nil then
intab.P2 = p2Mode
end
assert(next(intab), "InitScoreKeepers didn't get any args")
for k,v in pairs(intab) do
if not ScoringModes[v] then
--SPOILER: UndocumentedFeature crashes the game intentionally.
UndocumentedFeature(k.."'s scoring mode \""..v.."\" doesn't exist.")
end
ReadiedScoreKeepers[k] = coroutine.create(ScoringModes[v])
--call each scoring mode one time in init mode
checks={coroutine.resume(ReadiedScoreKeepers[k],nil,STATSMAN:GetCurStageStats():GetPlayerStageStats("PlayerNumber_"..k), "PlayerNumber_"..k, "init")}
if not CoroutineIsGood(ReadiedScoreKeepers[k]) then SCREENMAN:SystemMessage("scoring init error: "..checks[2]) return false end
--very very very very safe filtering rule load code
if type(checks[2])=="table" then
if type(checks[2][1])..type(checks[2][2]) == "tabletable" then
local isGood=false
local tapscan = Enum.Reverse(TapNoteScore)
local holdscan = Enum.Reverse(HoldNoteScore)
local finaltable = {{},{}}
for i=1,2 do
for k,v in pairs(checks[2][i]) do
finaltable[i][v]=true
if (not (i==2 and holdscan[v] or tapscan[v])) or v==nil then isGood=false break end
isGood=true
end
if not isGood then break end
end
if isGood then
JudgmentFilters[k]=finaltable
end
end
end
end
return true
end
function UpdateScoreKeepers(JMC)
assert(JMC,"pass args, please")
runplayer = ToEnumShortString(JMC.Player)
if ReadiedScoreKeepers[runplayer] then
if JudgmentFilters[runplayer] and (JudgmentFilters[runplayer][1][JMC.TapNoteScore] or JudgmentFilters[runplayer][2][JMC.HoldNoteScore]) then
return true
end
local pss = STATSMAN:GetCurStageStats():GetPlayerStageStats(JMC.Player)
local newscores = {coroutine.resume(ReadiedScoreKeepers[runplayer],JMC,pss,JMC.Player,"update")}
if CoroutineIsGood(ReadiedScoreKeepers[runplayer]) then
pss:SetScore(newscores[2])
pss:SetCurMaxScore(newscores[3])
return true
else
SCREENMAN:SystemMessage("scoring update error: "..newscores[2])
ReadiedScoreKeepers[runplayer]=nil
return false
end
end
end
function FinalizeScoreKeepers()
for k,v in pairs(ReadiedScoreKeepers) do
local pss = STATSMAN:GetCurStageStats():GetPlayerStageStats("PlayerNumber_"..k)
local newscores = {coroutine.resume(v,nil,pss,"PlayerNumber_"..k,"finalize")}
local status = coroutine.status(v)
--kill the scorekeeper now, we don't need it again
ReadiedScoreKeepers[k] = nil
if status=="dead" then
if newscores[1]==true then
pss:SetScore(newscores[2])
pss:SetCurMaxScore(newscores[3])
else
SCREENMAN:SystemMessage("scoring finalize error: "..newscores[2])
return false
end
else
return false
end
end
return true
end