I figured out what's wrong with damage calculator

This commit is contained in:
dan63047 2024-10-13 01:08:29 +03:00
parent 3c83a6c244
commit 298f12e060
2 changed files with 34 additions and 55 deletions

View File

@ -640,7 +640,7 @@ class CompareState extends State<CompareView> {
child: Column( child: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
for (int l = 0; l < formattedValues[i][k].length; l++) Container(decoration: BoxDecoration(color: (rawValues[i][k][l] != null && best[i][l] == rawValues[i][k][l]) ? Colors.cyanAccent.withAlpha(96) : null), child: formattedValues[i][k][l]), for (int l = 0; l < formattedValues[i][k].length; l++) Container(decoration: BoxDecoration(color: (rawValues[0].length > 1 && rawValues[i][k][l] != null && best[i][l] == rawValues[i][k][l]) ? Colors.cyanAccent.withAlpha(96) : null), child: formattedValues[i][k][l]),
], ],
), ),
), ),

View File

@ -285,67 +285,42 @@ class ClearData{
perfectClear = !perfectClear; perfectClear = !perfectClear;
} }
Damage dealsDamage(int combo, int b2b, Rules rules){ int dealsDamage(int combo, int b2b, int previousB2B, Rules rules){
if (lines == 0) return Damage(0,0,0,0,0,rules.multiplier); if (lines == 0) return 0;
int clearDamage = 0; double damage = 0;
if (spin){ if (spin){
if (lines <= 5) clearDamage += garbage[lineclear]!; if (lines <= 5) damage += garbage[lineclear]!;
else clearDamage += garbage[Lineclears.TSPIN_PENTA]! + 2 * (lines - 5); else damage += garbage[Lineclears.TSPIN_PENTA]! + 2 * (lines - 5);
} else if (miniSpin){ } else if (miniSpin){
clearDamage += garbage[lineclear]!; damage += garbage[lineclear]!;
} else { } else {
if (lines <= 5) clearDamage += garbage[lineclear]!; if (lines <= 5) damage += garbage[lineclear]!;
else clearDamage += garbage[Lineclears.PENTA]! + (lines - 5); else damage += garbage[Lineclears.PENTA]! + (lines - 5);
} }
// Ok i can't figure out how b2b and combo works
// From tetrio.js:
// const n = e.cm.constants.garbage.BACKTOBACK_BONUS * (Math.floor(1 + Math.log1p((t.stats.btb - 1) * e.cm.constants.garbage.BACKTOBACK_BONUS_LOG)) + (t.stats.btb - 1 == 1 ? 0 : (1 + Math.log1p((t.stats.btb - 1) * e.cm.constants.garbage.BACKTOBACK_BONUS_LOG) % 1) / 3));
// if (h && (d += n),
double b2bDamage = 0;
if (difficultClear && b2b >= 1 && rules.b2b){ if (difficultClear && b2b >= 1 && rules.b2b){
if (rules.b2bChaining) b2bDamage += BACKTOBACK_BONUS * ((1 + log((b2b+1) * BACKTOBACK_BONUS_LOG)).floor() + (b2b+1 == 1 ? 0 : (1 + log((b2b+1) * BACKTOBACK_BONUS_LOG) % 1) / 3)); // but it should be b2b-1 ??? if (rules.b2bChaining) damage += BACKTOBACK_BONUS * ((1 + log(1 + (b2b) * BACKTOBACK_BONUS_LOG)).floor() + (b2b == 1 ? 0 : (1 + log(1 +(b2b) * BACKTOBACK_BONUS_LOG) % 1) / 3)); // but it should be b2b-1 ???
else b2bDamage += 1; // if b2b chaining off else damage += 1; // if b2b chaining off
} }
int surgeDamage = 0; if (rules.combo && rules.comboTable != ComboTables.none) {
if (combo >= 1){
if (!difficultClear && rules.surge){ if (lines == 1 && rules.comboTable != ComboTables.multiplier) damage += combotable[rules.comboTable]![max(0, min(combo - 1, combotable[rules.comboTable]!.length - 1))];
else damage *= (1 + COMBO_BONUS * (combo));
}
// From tetrio.js:
// if (t.stats.combo > 1)
// if (p += e.cm.constants.scoring.COMBO * (t.stats.combo - 1),
// "multiplier" === t.setoptions.combotable)
// d *= 1 + e.cm.constants.garbage.COMBO_BONUS * (t.stats.combo - 1),
// t.stats.combo > 2 && (d = Math.max(Math.log1p(e.cm.constants.garbage.COMBO_MINIFIER * (t.stats.combo - 1) * e.cm.constants.garbage.COMBO_MINIFIER_LOG), d));
// else {
// const n = e.cm.constants.garbage.combotable[t.setoptions.combotable] || [0];
// d += n[Math.max(0, Math.min(t.stats.combo - 2, n.length - 1))]
// }
double comboDamage = 0;
if (rules.combo) {
if (combo > 1){
if (lines == 1 && rules.comboTable != ComboTables.multiplier) comboDamage += combotable[rules.comboTable]![max(0, min(combo - 1, combotable[rules.comboTable]!.length - 1))];
else comboDamage = (clearDamage + b2bDamage) * (1 + COMBO_BONUS * (combo-1));
} }
if (combo > 2) { if (combo >= 2) {
comboDamage = max(log(COMBO_MINIFIER * (combo-1) * COMBO_MINIFIER_LOG), comboDamage); damage = max(log(1 + COMBO_MINIFIER * (combo) * COMBO_MINIFIER_LOG), damage);
} }
} }
int pcDamage = 0; if (!difficultClear && rules.surge && previousB2B >= rules.surgeInitAtB2b && b2b == -1){
damage += rules.surgeInitAmount + (previousB2B - rules.surgeInitAtB2b);
}
if (perfectClear) pcDamage += rules.pcDamage; if (perfectClear) damage += rules.pcDamage;
return Damage(clearDamage, comboDamage, b2bDamage, surgeDamage, pcDamage, rules.multiplier); return (damage * rules.multiplier).floor();
} }
} }
@ -518,7 +493,7 @@ class _DestinationCalculatorState extends State<DestinationCalculator> {
for (ClearData data in clearsExisting[key]!) rSideWidgets.add(Card( for (ClearData data in clearsExisting[key]!) rSideWidgets.add(Card(
child: ListTile( child: ListTile(
title: Text(data.title), title: Text(data.title),
subtitle: Text("${data.dealsDamage(0, 0, rules)} damage${data.difficultClear ? ", difficult" : ""}", style: TextStyle(color: Colors.grey)), subtitle: Text("${data.dealsDamage(0, 0, 0, rules)} damage${data.difficultClear ? ", difficult" : ""}", style: TextStyle(color: Colors.grey)),
trailing: Icon(Icons.arrow_forward_ios), trailing: Icon(Icons.arrow_forward_ios),
onTap: (){ onTap: (){
setState((){ setState((){
@ -557,13 +532,14 @@ class _DestinationCalculatorState extends State<DestinationCalculator> {
int combo = -1; int combo = -1;
int b2b = -1; int b2b = -1;
Damage totalDamage = Damage(0,0,0,0,0,rules.multiplier); int previousB2B = -1;
int totalDamageNumber = 0; int totalDamage = 0;
for (ClearData lineclear in clears){ for (ClearData lineclear in clears){
previousB2B = b2b;
if (lineclear.difficultClear) b2b++; else if (lineclear.lines > 0) b2b = -1; if (lineclear.difficultClear) b2b++; else if (lineclear.lines > 0) b2b = -1;
if (lineclear.lines > 0) combo++; else combo = -1; if (lineclear.lines > 0) combo++; else combo = -1;
Damage dmg = lineclear.dealsDamage(combo, b2b, rules); int dmg = lineclear.dealsDamage(combo, b2b, previousB2B, rules);
lSideWidgets.add( lSideWidgets.add(
ListTile( ListTile(
key: ValueKey(lineclear.id), key: ValueKey(lineclear.id),
@ -575,7 +551,7 @@ class _DestinationCalculatorState extends State<DestinationCalculator> {
], ],
), ),
title: Text("${lineclear.title}${lineclear.perfectClear ? " PC" : ""}${combo > 0 ? ", ${combo} combo" : ""}${b2b > 0 ? ", B2Bx${b2b}" : ""}"), title: Text("${lineclear.title}${lineclear.perfectClear ? " PC" : ""}${combo > 0 ? ", ${combo} combo" : ""}${b2b > 0 ? ", B2Bx${b2b}" : ""}"),
subtitle: lineclear.lines > 0 ? Text("${dmg.clear} from clear, ${dmg.combo} from combo, ${dmg.b2b} from B2B, ${dmg.surge} from Surge and ${dmg.pc} from PC", style: TextStyle(color: Colors.grey)) : null, subtitle: lineclear.lines > 0 ? Text("What should i write here?", style: TextStyle(color: Colors.grey)) : null,
trailing: lineclear.lines > 0 ? Padding( trailing: lineclear.lines > 0 ? Padding(
padding: const EdgeInsets.only(right: 10.0), padding: const EdgeInsets.only(right: 10.0),
child: Text(dmg.toString(), style: TextStyle(fontSize: 36, fontWeight: ui.FontWeight.w100)), child: Text(dmg.toString(), style: TextStyle(fontSize: 36, fontWeight: ui.FontWeight.w100)),
@ -583,7 +559,6 @@ class _DestinationCalculatorState extends State<DestinationCalculator> {
) )
); );
totalDamage += dmg; totalDamage += dmg;
totalDamageNumber += dmg.total;
} }
return Column( return Column(
@ -644,6 +619,11 @@ class _DestinationCalculatorState extends State<DestinationCalculator> {
), ),
if (rules.combo) ListTile( if (rules.combo) ListTile(
title: Text("Combo Table"), title: Text("Combo Table"),
trailing: DropdownButton(
items: [for (var v in ComboTables.values) DropdownMenuItem(value: v.index, child: Text(v.name))],
value: rules.comboTable.index,
onChanged: (v) => setState((){rules.comboTable = ComboTables.values[v!];}),
),
) )
], ],
), ),
@ -730,11 +710,10 @@ class _DestinationCalculatorState extends State<DestinationCalculator> {
children: [ children: [
Text("Total damage:", style: TextStyle(fontSize: 36, fontWeight: ui.FontWeight.w100)), Text("Total damage:", style: TextStyle(fontSize: 36, fontWeight: ui.FontWeight.w100)),
Spacer(), Spacer(),
Text(totalDamageNumber.toString(), style: TextStyle(fontFamily: "Eurostile Round Extended", fontSize: 36, fontWeight: ui.FontWeight.w100)) Text(totalDamage.toString(), style: TextStyle(fontFamily: "Eurostile Round Extended", fontSize: 36, fontWeight: ui.FontWeight.w100))
], ],
), ),
), ),
Text(totalDamage.toString(), style: TextStyle(fontFamily: "Eurostile Round Extended", fontSize: 36, fontWeight: ui.FontWeight.w100)),
ElevatedButton.icon(onPressed: (){setState((){clears.clear();});}, icon: const Icon(Icons.clear), label: Text("Clear all"), style: const ButtonStyle(shape: WidgetStatePropertyAll(RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(12.0)))))) ElevatedButton.icon(onPressed: (){setState((){clears.clear();});}, icon: const Icon(Icons.clear), label: Text("Clear all"), style: const ButtonStyle(shape: WidgetStatePropertyAll(RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(12.0))))))
], ],
) )