Jousway

04 Scoring.lua

Jan 13th, 2012
188
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 13.72 KB | None | 0 0
  1. --internals table
  2. local Shared = {};
  3. --Special Scoring types.
  4. local r = {};
  5. local DisabledScoringModes = { '[SSC] Radar Master' };
  6. --the following metatable makes any missing value in a table 0 instead of nil.
  7. local ZeroIfNotFound = { __index = function() return 0 end; };
  8.  
  9. -- Retrieve the amount of taps/holds/rolls involved. Used for some formulas.
  10. function GetTotalItems(radars)
  11.     local total = radars:GetValue('RadarCategory_TapsAndHolds')
  12.     total = total + radars:GetValue('RadarCategory_Holds')
  13.     total = total + radars:GetValue('RadarCategory_Rolls')
  14.     -- [ja] Liftを加えると一部二重加算になるため除外する。
  15.     -- total = total + radars:GetValue('RadarCategory_Lifts')
  16.  
  17.     -- [en] prevent divide by 0
  18.     -- [ja] 0除算対策(しなくても動作するけど満点になっちゃうんで)
  19.     return math.max(1,total);
  20. end;
  21.  
  22. -- Determine whether marvelous timing is to be considered.
  23. function IsW1Allowed(tapScore)
  24.     return tapScore == 'TapNoteScore_W2'
  25.         and (PREFSMAN:GetPreference("AllowW1") ~= 'AllowW1_Never'
  26.         or not (GAMESTATE:IsCourseMode() and
  27.         PREFSMAN:GetPreference("AllowW1") == 'AllowW1_CoursesOnly'));
  28. end;
  29.  
  30. -- Get the radar values directly. The individual steps aren't used much.
  31. function GetDirectRadar(player)
  32.     return GAMESTATE:GetCurrentSteps(player):GetRadarValues(player);
  33. end;
  34.  
  35. -----------------------------------------------------------
  36. --Oldschool scoring, best described as a modified 4th mix scheme
  37. --with a little 1st mix influence
  38. -----------------------------------------------------------
  39. r['Oldschool'] = function(params, pss)
  40.   local bestPoints = 999
  41.     local scoreLookupTable =
  42.     {
  43.         ['TapNoteScore_W1']=999,
  44.         ['TapNoteScore_W2']=IsW1Allowed('TapNoteScore_W2') and 888 or 999,
  45.         ['TapNoteScore_W3']=777,
  46.         ['TapNoteScore_W4']=555,
  47.         ['TapNoteScore_W5']=111,
  48.     };
  49.     setmetatable(scoreLookupTable, ZeroIfNotFound);
  50.     local comboBonusForThisStep = (pss:GetCurrentCombo()*111)^1.1;
  51.     local capScore = 1000000000;
  52.     pss:SetCurMaxScore(capScore); --i don't really care about weird scoring modes -fsx
  53.     local pointsGot = comboBonusForThisStep + scoreLookupTable[params.TapNoteScore] + (params.HoldNoteScore == 'HoldNoteScore_Held' and 777 or 0);
  54.     pss:SetScore(clamp(pss:GetScore()+pointsGot,0,capScore));
  55. end;
  56.  
  57. -----------------------------------------------------------
  58. --DDR MAX2/Extreme(-esque) Scoring by @sakuraponila
  59. -----------------------------------------------------------
  60. local ext_Steps = {0,0};
  61. r['DDR Extreme'] = function(params, pss)
  62.     local multLookup =
  63.     {
  64.         ['TapNoteScore_W1'] = 10,
  65.         ['TapNoteScore_W2'] = 9,
  66.         ['TapNoteScore_W3'] = 5
  67.     };
  68.     setmetatable(multLookup, ZeroIfNotFound);
  69.     local steps = GAMESTATE:GetCurrentSteps(params.Player);
  70.     local radarValues = GetDirectRadar(params.Player);
  71.     local totalItems = GetTotalItems(radarValues);
  72.     -- 1 + 2 + 3 + ... + totalItems value/の値
  73.     local sTotal = (totalItems + 1) * totalItems / 2;
  74.     local meter = steps:GetMeter();
  75.     if (steps:IsAnEdit()) then
  76.         meter = 5;
  77.     else
  78.         meter = math.min(10,meter);
  79.     end;
  80.     -- [en] score for one step
  81.     -- [ja] 1ステップあたりのスコア
  82.     local baseScore = meter * 1000000
  83.     if (GAMESTATE:GetCurrentSong():IsMarathon()) then
  84.         baseScore = baseScore * 3;
  85.     elseif (GAMESTATE:GetCurrentSong():IsLong()) then
  86.         baseScore = baseScore * 2;
  87.     end;
  88.     local sOne = math.floor(baseScore / sTotal);
  89.     -- [en] measures for 5 points of units
  90.     -- [ja] 5点単位のための処置
  91.     sOne = sOne - sOne % 5;
  92.     -- [en] because fractions are added by the last step, get value
  93.     -- [ja] 端数は最後の1ステップで加算するのでその値を取得
  94.     local sLast = baseScore - (sOne * sTotal);
  95.  
  96.     local p = (params.Player == 'PlayerNumber_P1') and 1 or 2;
  97.     -- [en] initialized when score is 0
  98.     -- [ja] スコアが0の時に初期化
  99.     if pss:GetScore() == 0 then
  100.         ext_Steps[p] = 0;
  101.     end;
  102.     -- [en] now step count
  103.     -- [ja] 現在のステップ数
  104.     ext_Steps[p] = ext_Steps[p] + 1;
  105.     -- [en] current score
  106.     -- [ja] 今回加算するスコア(W1の時)
  107.     local vScore = sOne * ext_Steps[p];
  108.     pss:SetCurMaxScore(pss:GetCurMaxScore() + vScore);
  109.     -- [ja] 判定によって加算量を変更
  110.     if (params.HoldNoteScore == 'HoldNoteScore_Held') then
  111.     -- [ja] O.K.判定時は問答無用で満点
  112.         vScore = vScore;
  113.     else
  114.         -- [ja] N.G.判定時は問答無用で0点
  115.         if (params.HoldNoteScore == 'HoldNoteScore_LetGo') then
  116.             vScore = 0;
  117.         -- [en] non-long note scoring
  118.         -- [ja] それ以外ということは、ロングノート以外の判定である
  119.         else
  120.             vScore = vScore * multLookup[params.TapNoteScore] / 10
  121.         end;
  122.     end;
  123.     -- [en] measures for 5 points of units
  124.     -- [ja] ここでも5点単位のための処置
  125.     vScore = vScore - vScore % 5
  126.     pss:SetScore(pss:GetScore() + vScore);
  127.     -- if one of the last step, add the fractions
  128.     -- [ja] 最後の1ステップの場合、端数を加算する
  129.     if ((vScore > 0) and (ext_Steps[p] == totalItems)) then
  130.         pss:SetScore(pss:GetScore() + sLast);
  131.     end;
  132. end;
  133.  
  134. -----------------------------------------------------------
  135. --HYBRID Scoring, contributed by @waiei
  136. -----------------------------------------------------------
  137. local hyb_Steps={0,0};
  138. r['Hybrid'] = function(params, pss)
  139.     local multLookup =
  140.     {
  141.         ['TapNoteScore_W1'] = 10,
  142.         ['TapNoteScore_W2'] = 9,
  143.         ['TapNoteScore_W3'] = 5
  144.     };
  145.     setmetatable(multLookup, ZeroIfNotFound);
  146.     local radarValues = GetDirectRadar(params.Player);
  147.     local totalItems = GetTotalItems(radarValues);
  148.     -- 1+2+3+...+totalItems value/の値
  149.     local sTotal = (totalItems+1)*totalItems/2;
  150.     -- [en] Score for one song
  151.     -- [ja] 1ステップあたりのスコア
  152.     local sOne = math.floor(100000000/sTotal);
  153.     -- [ja] 端数は最後の1ステップで加算するのでその値を取得
  154.     local sLast = 100000000-(sOne*sTotal);
  155.  
  156.     local p = (params.Player == 'PlayerNumber_P1') and 1 or 2;
  157.  
  158.     -- [ja] スコアが0の時に初期化
  159.     if pss:GetScore()==0 then
  160.         hyb_Steps[p]=0;
  161.     end;
  162.  
  163.     -- [ja] 現在のステップ数
  164.     hyb_Steps[p]=hyb_Steps[p]+1;
  165.     -- [en] current score
  166.     -- [ja] 今回加算するスコア(W1の時)
  167.     local vScore = sOne*hyb_Steps[p];
  168.     pss:SetCurMaxScore(pss:GetCurMaxScore()+vScore);
  169.     -- [ja] 判定によって加算量を変更
  170.     if (params.HoldNoteScore == 'HoldNoteScore_Held') then
  171.         vScore = vScore;
  172.     else
  173.         if (params.HoldNoteScore == 'HoldNoteScore_LetGo') then
  174.             vScore = 0;
  175.         else
  176.             vScore = vScore*multLookup[params.TapNoteScore]/10;
  177.         end;
  178.     end;
  179.     pss:SetScore(pss:GetScore()+vScore);
  180.  
  181.     -- [ja] 最後の1ステップの場合、端数を加算する
  182.     if ((vScore > 0) and (hyb_Steps[p] == totalItems)) then
  183.         pss:SetScore(pss:GetScore()+sLast);
  184.     end;
  185. end;
  186.  
  187. -----------------------------------------------------------
  188. --DDR SuperNOVA scoring (Use MARVELOUS) by @sakuraponila
  189. -----------------------------------------------------------
  190. local sntmp_Score = {0,0};
  191. local sntmp_Steps = {0,0};
  192. r['DDR SuperNOVA'] = function(params, pss)
  193.     local multLookup =
  194.     {
  195.         ['TapNoteScore_W1'] = 3,
  196.         ['TapNoteScore_W2'] = 2,
  197.         ['TapNoteScore_W3'] = 1
  198.     };
  199.     setmetatable(multLookup, ZeroIfNotFound);
  200.     local radarValues = GetDirectRadar(params.Player);
  201.     local totalItems = GetTotalItems(radarValues)
  202.     local p = (params.Player == 'PlayerNumber_P1') and 1 or 2;
  203.  
  204.     -- initialized when score is 0
  205.     -- [ja] スコアが0の時に初期化
  206.     if pss:GetScore() == 0 then
  207.         sntmp_Score[p] = 0;
  208.         sntmp_Steps[p] = 0;
  209.     end;
  210.  
  211.     -- [ja] 判定によって加算量を変更
  212.     local maxAdd = 0;
  213.     -- [ja] O.K.判定時は問答無用で満点
  214.     if params.HoldNoteScore == 'HoldNoteScore_Held' then
  215.         maxAdd = 3;
  216.     else
  217.         -- [ja] N.G.判定時は問答無用で0点
  218.         if params.HoldNoteScore == 'HoldNoteScore_LetGo' then
  219.             maxAdd = 0;
  220.         -- [ja] それ以外ということは、ロングノート以外の判定である
  221.         else
  222.             maxAdd = multLookup[params.TapNoteScore];
  223.         end
  224.     end;
  225.     sntmp_Score[p] = sntmp_Score[p] + maxAdd;
  226.  
  227.     -- [ja] 踏み踏みしたステップ数
  228.     sntmp_Steps[p] = sntmp_Steps[p] + 1;
  229.     -- [ja] 現時点での、All W1判定の時のスコア
  230.     pss:SetCurMaxScore(math.floor(10000000 * sntmp_Steps[p] / totalItems / 3));
  231.     -- [ja] 計算して代入
  232.     pss:SetScore(math.floor(10000000 * sntmp_Score[p] / totalItems / 3));
  233. end;
  234.  
  235. -----------------------------------------------------------
  236. --DDR SuperNOVA 2 scoring by @waiei
  237. -----------------------------------------------------------
  238. local sn2tmp_Sub={0,0};
  239. local sn2tmp_Score={0,0};
  240. local sn2tmp_Steps={0,0};
  241. r['DDR SuperNOVA 2'] = function(params, pss)
  242.     local multLookup =
  243.     {
  244.         ['TapNoteScore_W1'] = 10,
  245.         ['TapNoteScore_W2'] = 10,
  246.         ['TapNoteScore_W3'] = 5
  247.     };
  248.     setmetatable(multLookup, ZeroIfNotFound);
  249.     local radarValues = GetDirectRadar(params.Player);
  250.     local totalItems = GetTotalItems(radarValues);
  251.     local p = (params.Player == 'PlayerNumber_P1') and 1 or 2;
  252.  
  253.     -- [ja] スコアが0の時に初期化
  254.     if pss:GetScore()==0 then
  255.         sn2tmp_Sub[p]=0;
  256.         sn2tmp_Score[p]=0;
  257.         sn2tmp_Steps[p]=0;
  258.     end;
  259.  
  260.     -- [ja] maxAdd は 加算する最高点を 10 とした時の値(つまり、10=100% / 5=50%)
  261.     local maxAdd = 0;
  262.     -- [ja] O.K.判定時は問答無用で満点
  263.     if params.HoldNoteScore == 'HoldNoteScore_Held' then
  264.         maxAdd = 10;
  265.     else
  266.         -- [ja] N.G.判定時は問答無用で0点
  267.         if params.HoldNoteScore == 'HoldNoteScore_LetGo' then
  268.             maxAdd = 0;
  269.         -- [ja] それ以外ということは、ロングノート以外の判定である
  270.         else
  271.             maxAdd = multLookup[params.TapNoteScore];
  272.             if (params.TapNoteScore == 'TapNoteScore_W2') or (params.TapNoteScore=='TapNoteScore_W3') then
  273.                 -- [ja] W2とW3の数を記録
  274.                 sn2tmp_Sub[p]=sn2tmp_Sub[p]+1;
  275.             end;
  276.         end
  277.     end;
  278.     sn2tmp_Score[p]=sn2tmp_Score[p]+maxAdd;
  279.     -- [ja] 踏み踏みしたステップ数
  280.     sn2tmp_Steps[p]=sn2tmp_Steps[p]+1;
  281.     -- [ja] 現時点での、All W1判定の時のスコア
  282.     pss:SetCurMaxScore(math.floor(10000*sn2tmp_Steps[p]/totalItems) * 10);
  283.  
  284.     -- [ja] 計算して代入
  285.     pss:SetScore((math.floor(10000*sn2tmp_Score[p]/totalItems) * 10) - (sn2tmp_Sub[p]*10) );
  286. end;
  287.  
  288. -----------------------------------------------------------
  289. --Radar Master (disabled; todo: get this working with StepMania 5)
  290. -----------------------------------------------------------
  291. r['[SSC] Radar Master'] = function(params, pss)
  292.     local masterTable = {
  293.         ['RadarCategory_Stream'] = 0,
  294.         ['RadarCategory_Voltage'] = 0,
  295.         ['RadarCategory_Air'] = 0,
  296.         ['RadarCategory_Freeze'] = 0,
  297.         ['RadarCategory_Chaos'] = 0
  298.     };
  299.     local totalRadar = 0;
  300.     local finalScore = 0;
  301.     for k,v in pairs(masterTable) do
  302.         local firstRadar = GetDirectRadar(params.Player):GetValue(k);
  303.         if firstRadar == 0 then
  304.             masterTable[k] = nil;
  305.         else
  306.             masterTable[k] = firstRadar;
  307.             totalRadar = totalRadar + firstRadar;
  308.         end;
  309.     end;
  310.     --two loops are needed because we need to calculate totalRadar
  311.     --to actually calculate any part of the score
  312.     for k,v in pairs(masterTable) do
  313.         local curPortion = pss:GetRadarActual():GetValue(k) / v;
  314.         finalScore = finalScore + curPortion*(500000000*(v/totalRadar));
  315.     end;
  316.     pss:SetScore(finalScore);
  317. end;
  318. ------------------------------------------------------------
  319. --Marvelous Incorporated Grading System (or MIGS for short)
  320. --basically like DP scoring with locked DP values
  321. ------------------------------------------------------------
  322. r['MIGS'] = function(params,pss)
  323.     local curScore = 0;
  324.     local tapScoreTable =
  325.     {
  326.         ['TapNoteScore_W1'] = 3,
  327.         ['TapNoteScore_W2'] = 2,
  328.         ['TapNoteScore_W3'] = 1,
  329.         ['TapNoteScore_W5'] = -4,
  330.         ['TapNoteScore_Miss'] = -8
  331.     };
  332.     for k,v in pairs(tapScoreTable) do
  333.         curScore = curScore + ( pss:GetTapNoteScores(k) * v );
  334.     end;
  335.   curScore = math.max(0,curScore + ( pss:GetHoldNoteScores('HoldNoteScore_Held') * 6 ));
  336.   pss:SetScore(curScore);
  337. end;
  338.  
  339. --------------------------------------------------------------
  340. --1bilDP scoring because I can.
  341. --------------------------------------------------------------
  342. r['Billions DP']= function(params,pss)
  343.   local poss = pss:GetPossibleDancePoints()
  344.   pss:SetScore(math.floor((pss:GetActualDancePoints()/poss)*1000000000))
  345.   pss:SetCurMaxScore(math.floor((pss:GetCurrentPossibleDancePoints()/poss)*1000000000))
  346. end
  347. -------------------------------------------------------------------------------
  348. -- Formulas end here.
  349. for v in ivalues(DisabledScoringModes) do r[v] = nil end
  350. Scoring = r;
  351.  
  352. function UserPrefScoringMode()
  353.   local baseChoices = {}
  354.   for k,v in pairs(Scoring) do table.insert(baseChoices,k) end
  355.   if next(baseChoices) == nil then UndocumentedFeature "No scoring modes available" end
  356.     local t = {
  357.         Name = "UserPrefScoringMode";
  358.         LayoutType = "ShowAllInRow";
  359.         SelectType = "SelectOne";
  360.         OneChoiceForAllPlayers = true;
  361.         ExportOnChange = false;
  362.         Choices = baseChoices;
  363.         LoadSelections = function(self, list, pn)
  364.             if ReadPrefFromFile("UserPrefScoringMode") ~= nil then
  365.         --Load the saved scoring mode from UserPrefs.
  366.                 local theValue = ReadPrefFromFile("UserPrefScoringMode");
  367.                 local success = false;
  368.         --HACK: Preview 4 took out 1st and 4th scoring. Replace with a close equivalent.
  369.         if theValue == "DDR 1stMIX" or theValue == "DDR 4thMIX" then theValue = "Oldschool" end
  370.         --Search the list of scoring modes for the saved scoring mode.        
  371.                 for k,v in ipairs(baseChoices) do if v == theValue then list[k] = true success = true break end end;
  372.         --We couldn't find it, pick the first available scoring mode as a sane default.
  373.                 if success == false then list[1] = true end;
  374.             else
  375.         WritePrefToFile("UserPrefScoringMode", baseChoices[1]);
  376.                 list[1] = true;
  377.             end;
  378.         end;
  379.         SaveSelections = function(self, list, pn)
  380.             for k,v in ipairs(list) do if v then WritePrefToFile("UserPrefScoringMode", baseChoices[k]) break end end;
  381.         end;
  382.     };
  383.     setmetatable( t, t );
  384.     return t;
  385. end
Add Comment
Please, Sign In to add comment