View difference between Paste ID: GzkYs445 and MUN9xCcH
SHOW: | | - or go back to the newest paste.
1
-----------------------------------------------------------
2
--StepMania 3.9 (Plus) Scorings by @803832
3
--3.9 MAX2
4
--3.9 5TH
5
--3.9Plus HYBRID
6
--3.9Plus SN
7
--3.9Plus SN2
8
-----------------------------------------------------------
9
local function isW2OrAbove(tns)
10
	if tns == 'TapNoteScore_W1' or
11
	   tns == 'TapNoteScore_W2' then
12
		return true;
13
	end;
14
	return false;
15
end
16
17
local sm3_Steps = {0,0};
18
local sm3_Score = {0,0};
19
local sm3_CurMaxScore = {0,0};
20
local sm3_Combo = {0,0};
21
local sm3_CurMaxCombo = {0,0};
22
local sm3_GradePoints = {0,0};
23
local sm3_Bonus = {0,0};
24
local sm3_MaxBonus = {0,0};
25
26
r["3.9 MAX2"] = function(params, pss)
27
	local multLookup =
28
	{
29
		['TapNoteScore_W1'] = 10,
30
		['TapNoteScore_W2'] = GAMESTATE:ShowW1() and 9 or 10,
31
		['TapNoteScore_W3'] = 5
32
	};
33
	setmetatable(multLookup, ZeroIfNotFound);
34
	local radarValues = GetDirectRadar(params.Player);
35
	local totalItems = GetTotalItems(radarValues);
36
	-- 1+2+3+...+totalItems value/の値
37
	local sTotal = (totalItems+1)*totalItems/2;
38
	local steps = GAMESTATE:GetCurrentSteps(params.Player);
39
	local meter = steps:GetMeter();
40
	meter = clamp(meter,1,10);
41
42
	-- [ja] 満点を求める
43
	local length = 1;
44
	if (GAMESTATE:GetCurrentSong():IsMarathon()) then
45
		length = 3;
46
	elseif (GAMESTATE:GetCurrentSong():IsLong()) then
47
		length = 2;
48
	end;
49
	local baseScore = meter * 10000000 * length;
50
51
	local sOne = baseScore/sTotal;
52
53
	local p = (params.Player == 'PlayerNumber_P1') and 1 or 2;
54
55
	-- [ja] スコアが0の時に初期化
56
	if pss:GetScore()==0 then
57-
	sm3_Steps[p]=sm3_Steps[p]+1;
57+
58
	end;
59
60
	-- [ja] 現在のステップ数
61
	-- [ja] 地雷とHoldCheckpointsの場合は加算しない
62
	if params.TapNoteScore ~= "TapNoteScore_HitMine" and
63
	   params.TapNoteScore ~= "TapNoteScore_AvoidMine" and
64
	   params.TapNoteScore ~= "TapNoteScore_CheckpointHit" and
65
	   params.TapNoteScore ~= "TapNoteScore_CheckpointMiss"
66
	then
67
		sm3_Steps[p]=sm3_Steps[p]+1;
68
	end;
69
70
	-- [en] current score
71
	-- [ja] 今回加算するスコア(W1の時)
72
	local vScore = sOne*sm3_Steps[p];
73
	pss:SetCurMaxScore(pss:GetCurMaxScore()+math.floor(vScore));
74
	-- [ja] 判定によって加算量を変更
75
	if (params.HoldNoteScore == 'HoldNoteScore_Held') then
76
		vScore = vScore;
77
	else
78
		if (params.HoldNoteScore == 'HoldNoteScore_LetGo') then
79
			vScore = 0;
80
		else
81
			vScore = vScore*multLookup[params.TapNoteScore]/10;
82
		end;
83
	end;
84-
			-- [ja] 5点単位の処理がなぜかここでされる
84+
85-
			if multLookup[params.TapNoteScore] > 0 then
85+
86-
				pss:SetScore(math.floor((pss:GetScore() + 2) / 5) * 5);
86+
87
		if (params.HoldNoteScore == 'HoldNoteScore_Held') then
88
			-- [ja] O.K.判定時は10点
89
			sm3_Score[p] = sm3_Score[p]+10;
90
		elseif (params.HoldNoteScore ~= 'HoldNoteScore_LetGo') then
91
			-- [ja] O.K.でもN.G.でもない場合のスコア:
92
			-- W1 (Marvelous): 10
93
			-- W2 (Perfect):    9
94
			-- W3 (Great):      5
95
			sm3_Score[p] = sm3_Score[p]+multLookup[params.TapNoteScore];
96
		end;
97
98
		-- [ja] 5点単位の処理がなぜかここでされる
99
		if multLookup[params.TapNoteScore] > 0 then
100
			sm3_Score[p] = math.floor((sm3_Score[p] + 2) / 5) * 5;
101
		end;
102
	else
103
		pss:SetScore(pss:GetScore()+math.floor(vScore));
104
	end;
105
106
	if (sm3_Steps[p] == totalItems and not pss:GetFailed()) then
107
		-- [ja] 最後の1ステップがW2以上の場合、端数を加算する
108
		-- [ja] 端数は設定上の満点と最終ステップ時点での満点の差から求める
109
		if (isW2OrAbove(params.TapNoteScore) or params.HoldNoteScore == 'HoldNoteScore_Held') then
110
			pss:SetScore(pss:GetScore()+(baseScore-pss:GetCurMaxScore()));
111
			pss:SetCurMaxScore(pss:GetCurMaxScore()+(baseScore-pss:GetCurMaxScore()));
112
		end;
113
	end;
114
end;
115
116
-- TODO: Don't add combo bonus if autoplay
117
r["3.9 5TH"] = function(params, pss)
118
	local multLookup =
119
	{
120
		['TapNoteScore_W1'] = 10,
121
		['TapNoteScore_W2'] = GAMESTATE:ShowW1() and 9 or 10,
122
		['TapNoteScore_W3'] = 5
123
	};
124
	setmetatable(multLookup, ZeroIfNotFound);
125
	local radarValues = GetDirectRadar(params.Player);
126
	local totalItems = GetTotalItems(radarValues);
127
	-- 1+2+3+...+totalItems value/の値
128
	local sTotal = (totalItems+1)*totalItems/2;
129
	local steps = GAMESTATE:GetCurrentSteps(params.Player);
130
	local meter = steps:GetMeter();
131
	meter = clamp(meter,1,10);
132
133
	-- [ja] 満点を求める
134
	local length = 1;
135
	if (GAMESTATE:GetCurrentSong():IsMarathon()) then
136
		length = 3;
137
	elseif (GAMESTATE:GetCurrentSong():IsLong()) then
138
		length = 2;
139
	end;
140
	local baseScore = (meter * length + 1) * 5000000;
141-
	sm3_Steps[p]=sm3_Steps[p]+1;
141+
142
	local sOne = baseScore/sTotal;
143
144
	local p = (params.Player == 'PlayerNumber_P1') and 1 or 2;
145
146
	-- [ja] スコアが0の時に初期化
147
	if pss:GetScore()==0 then
148
		sm3_Steps[p] = 0;
149
		sm3_Score[p] = 0;
150
		sm3_CurMaxScore[p] = 0;
151
		sm3_Combo[p] = 0;
152
		sm3_CurMaxCombo[p] = 0;
153
		sm3_GradePoints[p] = 0;
154
		sm3_Bonus[p] = 0;
155
		sm3_MaxBonus[p] = 0;
156
	end;
157
158
	-- [ja] 現在のステップ数
159
	-- [ja] 地雷とHoldCheckpointsの場合は加算しない
160
	if params.TapNoteScore ~= "TapNoteScore_HitMine" and
161
	   params.TapNoteScore ~= "TapNoteScore_AvoidMine" and
162
	   params.TapNoteScore ~= "TapNoteScore_CheckpointHit" and
163
	   params.TapNoteScore ~= "TapNoteScore_CheckpointMiss"
164
	then
165
		sm3_Steps[p]=sm3_Steps[p]+1;
166
	end;
167
168
	-- [en] current score
169
	-- [ja] 今回加算するスコア(W1の時)
170
	local vScore = sOne*sm3_Steps[p];
171
	sm3_CurMaxScore[p] = sm3_CurMaxScore[p]+math.floor(vScore);
172
173
	-- [ja] グレードの計算は5THではなくMAX2方式
174
	local gradeWeightTable = {
175
		['TapNoteScore_W1'] = 2,
176-
			-- [ja] 5点単位の処理がなぜかここでされる
176+
		['TapNoteScore_W2'] = 2,
177-
			if multLookup[params.TapNoteScore] > 0 then
177+
		['TapNoteScore_W3'] = 1,
178-
				sm3_Score[p] = math.floor((sm3_Score[p] + 2) / 5) * 5;
178+
		['TapNoteScore_W5'] = -4,
179
		['TapNoteScore_Miss'] = -8,
180
	};
181
	setmetatable(gradeWeightTable, ZeroIfNotFound);
182
183-
		sm3_Bonus[p] = sm3_Bonus[p]+multLookup[params.TapNoteScore]*pss:GetCurrentCombo();
183+
184
	if (params.HoldNoteScore == 'HoldNoteScore_Held') then
185
		vScore = vScore;
186
		sm3_GradePoints[p] = sm3_GradePoints[p] + 6;
187
	else
188
		if (params.HoldNoteScore == 'HoldNoteScore_LetGo') then
189
			vScore = 0;
190
		else
191
			vScore = vScore*multLookup[params.TapNoteScore]/10;
192
			sm3_GradePoints[p] = sm3_GradePoints[p] + gradeWeightTable[params.TapNoteScore];
193
		end;
194
	end;
195-
		sm3_Score[p] = sm3_Score[p]+sm3_Bonus[p];
195+
196-
		sm3_CurMaxScore[p] = sm3_CurMaxScore[p]+totalItems*sTotal;
196+
	-- [ja] コンボは自前で処理する
197
	if not params.HoldNoteScore then
198
		if params.TapNoteScore == 'TapNoteScore_W1' or
199-
			['Grade_Tier01'] = 10000000,
199+
		   params.TapNoteScore == 'TapNoteScore_W2' or
200-
			['Grade_Tier02'] = 10000000,
200+
		   (
201-
			['Grade_Tier03'] = 1000000,
201+
		   	GAMESTATE:GetPlayMode() ~= 'PlayMode_Oni' and
202-
			['Grade_Tier04'] = 100000,
202+
		   	params.TapNoteScore == 'TapNoteScore_W3'
203-
			['Grade_Tier05'] = 10000,
203+
		   )
204-
			['Grade_Tier06'] = 1000,
204+
		then
205-
			['Grade_Tier07'] = 100,
205+
			sm3_Combo[p] = sm3_Combo[p] + 1;
206
		-- [ja] 地雷とHoldCheckpointsの場合はリセットしない
207-
		setmetatable(gradeBonusTable, ZeroIfNotFound);
207+
		elseif params.TapNoteScore ~= "TapNoteScore_HitMine" and
208
		       params.TapNoteScore ~= "TapNoteScore_AvoidMine" and
209-
		sm3_Score[p] = sm3_Score[p]+gradeBonusTable[pss:GetGrade()];
209+
		       params.TapNoteScore ~= "TapNoteScore_CheckpointHit" and
210-
		sm3_CurMaxScore[p] = sm3_CurMaxScore[p]+10000000;
210+
		       params.TapNoteScore ~= "TapNoteScore_CheckpointMiss"
211
		then
212
			sm3_Combo[p] = 0;
213
		end;
214
		sm3_CurMaxCombo[p] = sm3_CurMaxCombo[p] + 1;
215
	end;
216
217
	local bonusTable =
218
	{
219
		['TapNoteScore_W1'] = 55,
220
		['TapNoteScore_W2'] = 55,
221
		['TapNoteScore_W3'] = 33
222
	};
223
	setmetatable(bonusTable, ZeroIfNotFound);
224
225
	-- [ja] 落ちていた場合は入るスコアが減る
226
	if (pss:GetFailed()) then
227
		if (params.HoldNoteScore == 'HoldNoteScore_Held') then
228
			-- [ja] O.K.判定時は10点
229
			sm3_Score[p] = sm3_Score[p]+10;
230
		elseif (params.HoldNoteScore ~= 'HoldNoteScore_LetGo') then
231
			-- [ja] O.K.でもN.G.でもない場合のスコア:
232
			-- W1 (Marvelous): 10
233
			-- W2 (Perfect):    9
234
			-- W3 (Great):      5
235
			sm3_Score[p] = sm3_Score[p]+multLookup[params.TapNoteScore];
236
		end;
237
238
		-- [ja] 5点単位の処理がなぜかここでされる
239
		if multLookup[params.TapNoteScore] > 0 then
240
			sm3_Score[p] = math.floor((sm3_Score[p] + 2) / 5) * 5;
241
		end;
242
	else
243
		sm3_Score[p] = sm3_Score[p]+math.floor(vScore);
244
		if (params.HoldNoteScore == 'HoldNoteScore_Held') then
245
			sm3_Bonus[p] = sm3_Bonus[p]+55*sm3_Combo[p];
246
		elseif (params.HoldNoteScore ~= 'HoldNoteScore_LetGo') then
247
			sm3_Bonus[p] = sm3_Bonus[p]+bonusTable[params.TapNoteScore]*sm3_Combo[p];
248
		end;
249
		sm3_MaxBonus[p] = sm3_MaxBonus[p]+55*sm3_CurMaxCombo[p];
250
	end;
251
252
	if (sm3_Steps[p] == totalItems and not pss:GetFailed()) then
253-
	sm3_Steps[p]=sm3_Steps[p]+1;
253+
254
		-- [ja] 端数は設定上の満点と最終ステップ時点での満点の差から求める
255
		if (isW2OrAbove(params.TapNoteScore) or params.HoldNoteScore == 'HoldNoteScore_Held') then
256
			sm3_Score[p] = sm3_Score[p]+(baseScore-sm3_CurMaxScore[p]);
257
			sm3_CurMaxScore[p] = sm3_CurMaxScore[p]+(baseScore-sm3_CurMaxScore[p]);
258
		end;
259
	end;
260
261
	-- [ja] 5点単位の処理は5TH方式のみでされる
262
	pss:SetScore(sm3_Score[p] - sm3_Score[p] % 5);
263
	pss:SetCurMaxScore(sm3_CurMaxScore[p] - sm3_CurMaxScore[p] % 5);
264
265
	if (sm3_Steps[p] == totalItems and not pss:GetFailed()) then
266
		-- [ja] コンボボーナスとグレードボーナスを加算
267
		-- [ja] 本当はリザルト画面でやりたいんだけどね
268
		local totalTaps = radarValues:GetValue('RadarCategory_TapsAndHolds');
269
		local totalHolds = radarValues:GetValue('RadarCategory_Holds') + radarValues:GetValue('RadarCategory_Rolls');
270
271
		local gradeBonusTable = {
272
			-- Threshold: sm3_GradePoints[p] / (totalTaps * 2 + totalHolds * 6) * 100
273
			{ Threshold = 100, Bonus = 10000000 },
274
			{ Threshold =  93, Bonus =  1000000 },
275
			{ Threshold =  80, Bonus =   100000 },
276
			{ Threshold =  65, Bonus =    10000 },
277
			{ Threshold =  45, Bonus =     1000 },
278
			-- [ja] 45%に達していない場合は100点とする
279
		};
280-
			-- [ja] 5点単位の処理がなぜかここでされる
280+
281-
			if multLookup[params.TapNoteScore] > 0 then
281+
		local gradeBonus = 100;
282-
				pss:SetScore(math.floor((pss:GetScore() + 2) / 5) * 5);
282+
283
		for i = 1,#gradeBonusTable do
284
			if (sm3_GradePoints[p] / (totalTaps * 2 + totalHolds * 6) * 100 >= gradeBonusTable[i].Threshold) then
285
				gradeBonus = gradeBonusTable[i].Bonus;
286
				break;
287
			end;
288
		end;
289
290
		if pss:GetFailed() then
291
			gradeBonus = 0;
292
		end;
293
294
		pss:SetScore(pss:GetScore()+sm3_Bonus[p]+gradeBonus);
295
		pss:SetCurMaxScore(pss:GetCurMaxScore()+sm3_MaxBonus[p]+10000000);
296
	end;
297
end;
298
299
r["3.9Plus HYBRID"] = function(params, pss)
300
	local multLookup =
301
	{
302
		['TapNoteScore_W1'] = 10,
303
		['TapNoteScore_W2'] = GAMESTATE:ShowW1() and 9 or 10,
304
		['TapNoteScore_W3'] = 5
305
	};
306
	setmetatable(multLookup, ZeroIfNotFound);
307
	local radarValues = GetDirectRadar(params.Player);
308
	local totalItems = GetTotalItems(radarValues);
309
	-- 1+2+3+...+totalItems value/の値
310
	local sTotal = (totalItems+1)*totalItems/2;
311
	local steps = GAMESTATE:GetCurrentSteps(params.Player);
312
	local meter = steps:GetMeter();
313
	meter = clamp(meter,1,10);
314
315
	-- [ja] 満点を求める
316
	local length = 1;
317
	if (GAMESTATE:GetCurrentSong():IsMarathon()) then
318
		length = 3;
319
	elseif (GAMESTATE:GetCurrentSong():IsLong()) then
320
		length = 2;
321
	end;
322
	local baseScore = 100000000 * length;
323
324
	local sOne = baseScore/sTotal;
325
326
	local p = (params.Player == 'PlayerNumber_P1') and 1 or 2;
327
328
	-- [ja] スコアが0の時に初期化
329
	if pss:GetScore()==0 then
330
		sm3_Steps[p] = 0;
331
	end;
332
333
	-- [ja] 現在のステップ数
334
	-- [ja] 地雷とHoldCheckpointsの場合は加算しない
335
	if params.TapNoteScore ~= "TapNoteScore_HitMine" and
336
	   params.TapNoteScore ~= "TapNoteScore_AvoidMine" and
337
	   params.TapNoteScore ~= "TapNoteScore_CheckpointHit" and
338
	   params.TapNoteScore ~= "TapNoteScore_CheckpointMiss"
339
	then
340
		sm3_Steps[p]=sm3_Steps[p]+1;
341
	end;
342
343
	-- [en] current score
344
	-- [ja] 今回加算するスコア(W1の時)
345
	local vScore = sOne*sm3_Steps[p];
346
	pss:SetCurMaxScore(pss:GetCurMaxScore()+math.floor(vScore));
347
	-- [ja] 判定によって加算量を変更
348
	if (params.HoldNoteScore == 'HoldNoteScore_Held') then
349
		vScore = vScore;
350
	else
351
		if (params.HoldNoteScore == 'HoldNoteScore_LetGo') then
352
			vScore = 0;
353
		else
354
			vScore = vScore*multLookup[params.TapNoteScore]/10;
355
		end;
356
	end;
357
358
	-- [ja] 落ちていた場合は入るスコアが減る
359
	if (pss:GetFailed()) then
360
		if (params.HoldNoteScore == 'HoldNoteScore_Held') then
361
			-- [ja] O.K.判定時は10点
362
			pss:SetScore(pss:GetScore()+10);
363
		elseif (params.HoldNoteScore ~= 'HoldNoteScore_LetGo') then
364
			-- [ja] O.K.でもN.G.でもない場合のスコア:
365
			-- W1 (Marvelous): 10
366
			-- W2 (Perfect):    9
367
			-- W3 (Great):      5
368
			pss:SetScore(pss:GetScore()+multLookup[params.TapNoteScore]);
369
		end;
370
371
		-- [ja] 5点単位の処理がなぜかここでされる
372
		if multLookup[params.TapNoteScore] > 0 then
373
			pss:SetScore(math.floor((pss:GetScore() + 2) / 5) * 5);
374
		end;
375
	else
376
		pss:SetScore(pss:GetScore()+math.floor(vScore));
377
	end;
378
379-
-- 3.9Plus PIU Scoring cannot be implemented due to no NumTapsInRow in JudgmentMessage
379+
380
		-- [ja] 最後の1ステップがW2以上の場合、端数を加算する
381
		-- [ja] 端数は設定上の満点と最終ステップ時点での満点の差から求める
382
		if (isW2OrAbove(params.TapNoteScore) or params.HoldNoteScore == 'HoldNoteScore_Held') then
383
			pss:SetScore(pss:GetScore()+(baseScore-pss:GetCurMaxScore()));
384
			pss:SetCurMaxScore(pss:GetCurMaxScore()+(baseScore-pss:GetCurMaxScore()));
385
		end;
386
	end;
387
end;
388
389
r["3.9Plus SN"] = function(params, pss)
390
	local radarValues = GetDirectRadar(params.Player);
391
	local totalItems = GetTotalItems(radarValues);
392
393
	-- [ja] 満点を求める
394
	local length = 1;
395
	if (GAMESTATE:GetCurrentSong():IsMarathon()) then
396
		length = 3;
397
	elseif (GAMESTATE:GetCurrentSong():IsLong()) then
398
		length = 2;
399
	end;
400
	local baseScore = 10000000 * length;
401
402
	-- [en] current score
403
	-- [ja] 今回加算するスコア
404
	local multLookup =
405
	{
406
		['TapNoteScore_W1'] = math.floor(baseScore / totalItems),
407
		['TapNoteScore_W2'] = math.floor(baseScore / totalItems),
408
		['TapNoteScore_W3'] = math.floor(math.floor(baseScore / 2) / totalItems)
409
	};
410
	setmetatable(multLookup, ZeroIfNotFound);
411
	local vScore = multLookup[params.TapNoteScore];
412
	pss:SetCurMaxScore(pss:GetCurMaxScore()+multLookup['TapNoteScore_W1']);
413
414
	-- [ja] 判定によって加算量を変更
415
	if (params.HoldNoteScore == 'HoldNoteScore_Held') then
416
		vScore = multLookup['TapNoteScore_W1'];
417
	elseif (params.HoldNoteScore == 'HoldNoteScore_LetGo') then
418
		vScore = 0;
419
	end;
420
421
	-- [ja] 落ちていた場合は入るスコアが減る
422
	if (not pss:GetFailed()) then
423
		pss:SetScore(pss:GetScore()+math.floor(vScore));
424
	end;
425
426
	-- [ja] 端数の処理はされていないようだ
427
end;
428
429
r["3.9Plus SN2"] = function(params, pss)
430
	local radarValues = GetDirectRadar(params.Player);
431
	local totalItems = GetTotalItems(radarValues);
432
433
	-- [ja] 満点を求める
434
	local length = 1;
435
	if (GAMESTATE:GetCurrentSong():IsMarathon()) then
436
		length = 3;
437
	elseif (GAMESTATE:GetCurrentSong():IsLong()) then
438
		length = 2;
439
	end;
440
	local baseScore = 1000000 * length;
441
442
	-- [en] current score
443
	-- [ja] 今回加算するスコア
444
	local multLookup =
445
	{
446
		['TapNoteScore_W1'] = math.floor(baseScore / totalItems),
447
		['TapNoteScore_W2'] = math.floor(baseScore / totalItems) - 10,
448
		['TapNoteScore_W3'] = math.floor(math.floor(baseScore / 2) / totalItems) - 10
449
	};
450
	setmetatable(multLookup, ZeroIfNotFound);
451
	local vScore = multLookup[params.TapNoteScore];
452
	pss:SetCurMaxScore(pss:GetCurMaxScore()+multLookup['TapNoteScore_W1']);
453
454
	-- [ja] 判定によって加算量を変更
455
	if (params.HoldNoteScore == 'HoldNoteScore_Held') then
456
		vScore = multLookup['TapNoteScore_W1'];
457
	elseif (params.HoldNoteScore == 'HoldNoteScore_LetGo') then
458
		vScore = 0;
459
	end;
460
461
	-- [ja] 落ちていた場合は入るスコアが減る
462
	if (not pss:GetFailed()) then
463
		pss:SetScore(pss:GetScore()+math.floor(vScore));
464
	end;
465
466
	-- [ja] 端数の処理はされていないようだ
467
end;
468
469
-- 3.9Plus PIU Scoring cannot be implemented because no NumTapsInRow in JudgmentMessage