Still no inf SDF, incorrect SRS kicks, issues with incoming garbage and lots of shit
shit
This commit is contained in:
parent
f0d4d809a3
commit
f5baf493ca
|
@ -123,6 +123,17 @@ class Board{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool wasATSpin(Tetromino type, Coords coords, int rot){
|
||||||
|
if (!(positionIsValid(type, Coords(coords.x+1, coords.y), rot) ||
|
||||||
|
positionIsValid(type, Coords(coords.x-1, coords.y), rot) ||
|
||||||
|
positionIsValid(type, Coords(coords.x, coords.y+1), rot) ||
|
||||||
|
positionIsValid(type, Coords(coords.x, coords.y-1), rot))
|
||||||
|
){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void writeToBoard(Tetromino type, Coords coords, int rot) {
|
void writeToBoard(Tetromino type, Coords coords, int rot) {
|
||||||
if (!positionIsValid(type, coords, rot)) throw Exception("Attempted to write $type to $coords in $rot rot");
|
if (!positionIsValid(type, coords, rot)) throw Exception("Attempted to write $type to $coords in $rot rot");
|
||||||
List<Coords> shape = shapes[type.index][rot];
|
List<Coords> shape = shapes[type.index][rot];
|
||||||
|
@ -131,6 +142,117 @@ class Board{
|
||||||
board[finalCoords.y][finalCoords.x] = type;
|
board[finalCoords.y][finalCoords.x] = type;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void writeGarbage(GarbageData data, [int? amt]){
|
||||||
|
List<List<Tetromino>> garbage = [for (int i = 0; i < (amt??data.amt!); i++) [for (int k = 0; k < width; k++) k == data.column! ? Tetromino.empty : Tetromino.garbage]];
|
||||||
|
board.insertAll(0, garbage);
|
||||||
|
board.removeRange(height-garbage.length, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<int> clearFullLines(){
|
||||||
|
int linesCleared = 0;
|
||||||
|
int garbageLines = 0;
|
||||||
|
int difficultLineClear = 0;
|
||||||
|
for (int i = 0; i < board.length; i++){
|
||||||
|
if (board[i-linesCleared].every((element) => element != Tetromino.empty)){
|
||||||
|
if (board[i-linesCleared].any((element) => element == Tetromino.garbage)) garbageLines++;
|
||||||
|
board.removeAt(i-linesCleared);
|
||||||
|
List<Tetromino> emptyRow = [for (int t = 0; t < width; t++) Tetromino.empty];
|
||||||
|
board.add(emptyRow);
|
||||||
|
linesCleared += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (linesCleared >= 4) difficultLineClear = 1;
|
||||||
|
return [linesCleared, garbageLines, difficultLineClear];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class IncomingGarbage{
|
||||||
|
int? frameOfThreat; // will enter board after this frame, null if unconfirmed
|
||||||
|
GarbageData data;
|
||||||
|
|
||||||
|
IncomingGarbage(this.data);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString(){
|
||||||
|
return "f$frameOfThreat: col${data.column} amt${data.amt}";
|
||||||
|
}
|
||||||
|
|
||||||
|
void confirm(int confirmationFrame, int garbageSpeed){
|
||||||
|
frameOfThreat = confirmationFrame+garbageSpeed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class LineClearResult{
|
||||||
|
int linesCleared;
|
||||||
|
Tetromino piece;
|
||||||
|
bool spin;
|
||||||
|
int garbageCleared;
|
||||||
|
int column;
|
||||||
|
int attackProduced;
|
||||||
|
|
||||||
|
LineClearResult(this.linesCleared, this.piece, this.spin, this.garbageCleared, this.column, this.attackProduced);
|
||||||
|
}
|
||||||
|
|
||||||
|
class Stats{
|
||||||
|
int combo = -1;
|
||||||
|
int btb = -1;
|
||||||
|
int attackRecived = 0;
|
||||||
|
int attackTanked = 0;
|
||||||
|
|
||||||
|
LineClearResult processLineClear(List<int> clearFullLinesResult, Tetromino current, Coords pos, bool spinWasLastMove, bool tspin){
|
||||||
|
if (clearFullLinesResult[0] > 0) combo++;
|
||||||
|
else combo = -1;
|
||||||
|
if (clearFullLinesResult[2] > 0) btb++;
|
||||||
|
else btb = -1;
|
||||||
|
int attack = 0;
|
||||||
|
switch (clearFullLinesResult[0]){
|
||||||
|
case 0:
|
||||||
|
if (spinWasLastMove && tspin) {
|
||||||
|
attack = garbage['t-spin']!;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
if (spinWasLastMove && tspin) {
|
||||||
|
attack = garbage['t-spin single']!;
|
||||||
|
}else{
|
||||||
|
attack = garbage['single']!;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
if (spinWasLastMove && tspin) {
|
||||||
|
attack = garbage['t-spin double']!;
|
||||||
|
}else{
|
||||||
|
attack = garbage['double']!;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
if (spinWasLastMove && tspin) {
|
||||||
|
attack = garbage['t-spin triple']!;
|
||||||
|
}else{
|
||||||
|
attack = garbage['triple']!;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
if (spinWasLastMove && tspin) {
|
||||||
|
attack = garbage['t-spin quad']!;
|
||||||
|
}else{
|
||||||
|
attack = garbage['quad']!;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
if (spinWasLastMove && tspin) {
|
||||||
|
attack = garbage['t-spin penta']!;
|
||||||
|
}else{
|
||||||
|
attack = garbage['penta']!;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case _:
|
||||||
|
developer.log("${clearFullLinesResult[0]} lines cleared");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return LineClearResult(clearFullLinesResult[0], Tetromino.empty, false, clearFullLinesResult[1], 0, attack);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Simulation{
|
class Simulation{
|
||||||
|
@ -150,9 +272,13 @@ void main() async {
|
||||||
int currentFrame = 0;
|
int currentFrame = 0;
|
||||||
events.removeAt(0); // get rig of Event.start
|
events.removeAt(0); // get rig of Event.start
|
||||||
Event nextEvent = events.removeAt(0);
|
Event nextEvent = events.removeAt(0);
|
||||||
|
Stats stats = Stats();
|
||||||
Board board = Board(10, 20, 20);
|
Board board = Board(10, 20, 20);
|
||||||
|
KicksetBase kickset = SRSPlus();
|
||||||
|
List<IncomingGarbage> garbageQueue = [];
|
||||||
Tetromino? hold;
|
Tetromino? hold;
|
||||||
int rot = 0;
|
int rot = 0;
|
||||||
|
bool spinWasLastMove = false;
|
||||||
Coords coords = Coords(3, 21);
|
Coords coords = Coords(3, 21);
|
||||||
double gravityBucket = 0.00000000000000;
|
double gravityBucket = 0.00000000000000;
|
||||||
|
|
||||||
|
@ -180,6 +306,20 @@ void main() async {
|
||||||
return queue.removeAt(0);
|
return queue.removeAt(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool handleRotation(int r){
|
||||||
|
if (r == 0) return true;
|
||||||
|
int future_rotation = (rot + r) % 4;
|
||||||
|
List<Coords> tests = (current == Tetromino.I ? kickset.kickTableI : kickset.kickTable)[rot][r == -1 ? 0 : r];
|
||||||
|
for (Coords test in tests){
|
||||||
|
if (board.positionIsValid(current, coords+test, future_rotation)){
|
||||||
|
coords += test;
|
||||||
|
rot = future_rotation;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
coords += spawnPositionFixes[current.index];
|
coords += spawnPositionFixes[current.index];
|
||||||
for (currentFrame; currentFrame <= replay.roundLengths[0]; currentFrame++){
|
for (currentFrame; currentFrame <= replay.roundLengths[0]; currentFrame++){
|
||||||
gravityBucket += settings != null ? (handling!.sdfActive ? settings.g! * settings.handling!.sdf : settings.g!) : 0;
|
gravityBucket += settings != null ? (handling!.sdfActive ? settings.g! * settings.handling!.sdf : settings.g!) : 0;
|
||||||
|
@ -194,7 +334,7 @@ void main() async {
|
||||||
}
|
}
|
||||||
if (board.positionIsValid(current, Coords(coords.x, coords.y-gravityImpact), rot)) coords.y -= gravityImpact;
|
if (board.positionIsValid(current, Coords(coords.x, coords.y-gravityImpact), rot)) coords.y -= gravityImpact;
|
||||||
print("$currentFrame: $current at $coords\n$board");
|
print("$currentFrame: $current at $coords\n$board");
|
||||||
|
//print(stats.combo);
|
||||||
if (currentFrame == nextEvent.frame){
|
if (currentFrame == nextEvent.frame){
|
||||||
while (currentFrame == nextEvent.frame){
|
while (currentFrame == nextEvent.frame){
|
||||||
print("Processing $nextEvent");
|
print("Processing $nextEvent");
|
||||||
|
@ -212,13 +352,13 @@ void main() async {
|
||||||
activeKeypresses[nextEvent.data.key] = nextEvent;
|
activeKeypresses[nextEvent.data.key] = nextEvent;
|
||||||
switch (nextEvent.data.key){
|
switch (nextEvent.data.key){
|
||||||
case KeyType.rotateCCW:
|
case KeyType.rotateCCW:
|
||||||
rot = (rot-1)%4;
|
handleRotation(-1);
|
||||||
break;
|
break;
|
||||||
case KeyType.rotateCW:
|
case KeyType.rotateCW:
|
||||||
rot = (rot+1)%4;
|
handleRotation(1);
|
||||||
break;
|
break;
|
||||||
case KeyType.rotate180:
|
case KeyType.rotate180:
|
||||||
rot = (rot+2)%4;
|
handleRotation(2);
|
||||||
break;
|
break;
|
||||||
case KeyType.moveLeft:
|
case KeyType.moveLeft:
|
||||||
case KeyType.moveRight:
|
case KeyType.moveRight:
|
||||||
|
@ -231,9 +371,42 @@ void main() async {
|
||||||
case KeyType.hardDrop:
|
case KeyType.hardDrop:
|
||||||
coords.y = sonicDrop();
|
coords.y = sonicDrop();
|
||||||
board.writeToBoard(current, coords, rot);
|
board.writeToBoard(current, coords, rot);
|
||||||
|
bool tspin = board.wasATSpin(current, coords, rot);
|
||||||
|
LineClearResult lineClear = stats.processLineClear(board.clearFullLines(), current, coords, spinWasLastMove, tspin);
|
||||||
|
print("${lineClear.linesCleared} lines, ${lineClear.garbageCleared} garbage");
|
||||||
|
if (garbageQueue.isNotEmpty) {
|
||||||
|
if (lineClear.linesCleared > 0){
|
||||||
|
int garbageToDelete = lineClear.attackProduced;
|
||||||
|
for (IncomingGarbage garbage in garbageQueue){
|
||||||
|
if (garbage.data.amt! >= garbageToDelete) {
|
||||||
|
garbageToDelete -= garbage.data.amt!;
|
||||||
|
lineClear.attackProduced = garbageToDelete;
|
||||||
|
garbage.data.amt = 0;
|
||||||
|
}else{
|
||||||
|
garbage.data.amt = garbage.data.amt! - garbageToDelete;
|
||||||
|
lineClear.attackProduced = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
int needToTake = settings!.garbageCap!;
|
||||||
|
for (IncomingGarbage garbage in garbageQueue){
|
||||||
|
if ((garbage.frameOfThreat??99999999) > currentFrame) break;
|
||||||
|
if (garbage.data.amt! > needToTake) {
|
||||||
|
board.writeGarbage(garbage.data, needToTake);
|
||||||
|
garbage.data.amt = garbage.data.amt! - needToTake;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
board.writeGarbage(garbage.data);
|
||||||
|
needToTake -= garbage.data.amt!;
|
||||||
|
garbage.data.amt = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
garbageQueue.removeWhere((element) => element.data.amt == 0);
|
||||||
|
}
|
||||||
current = getNewOne();
|
current = getNewOne();
|
||||||
coords = Coords(3, 21) + spawnPositionFixes[current.index];
|
coords = Coords(3, 21) + spawnPositionFixes[current.index];
|
||||||
//handling!.movementKeyReleased(true, true);
|
|
||||||
case KeyType.hold:
|
case KeyType.hold:
|
||||||
switch (hold){
|
switch (hold){
|
||||||
case null:
|
case null:
|
||||||
|
@ -247,6 +420,7 @@ void main() async {
|
||||||
current = temp;
|
current = temp;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
rot = 0;
|
||||||
coords = Coords(3, 21) + spawnPositionFixes[current.index];
|
coords = Coords(3, 21) + spawnPositionFixes[current.index];
|
||||||
break;
|
break;
|
||||||
case KeyType.chat:
|
case KeyType.chat:
|
||||||
|
@ -258,6 +432,11 @@ void main() async {
|
||||||
default:
|
default:
|
||||||
developer.log(nextEvent.data.key.name);
|
developer.log(nextEvent.data.key.name);
|
||||||
}
|
}
|
||||||
|
if (nextEvent.data.key == KeyType.rotateCW && nextEvent.data.key == KeyType.rotateCW && nextEvent.data.key == KeyType.rotateCW){
|
||||||
|
spinWasLastMove = true;
|
||||||
|
}else{
|
||||||
|
spinWasLastMove = false;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case EventType.keyup:
|
case EventType.keyup:
|
||||||
nextEvent as EventKeyPress;
|
nextEvent as EventKeyPress;
|
||||||
|
@ -292,6 +471,22 @@ void main() async {
|
||||||
case EventType.end:
|
case EventType.end:
|
||||||
currentFrame = replay.roundLengths[0]+1;
|
currentFrame = replay.roundLengths[0]+1;
|
||||||
break;
|
break;
|
||||||
|
case EventType.ige:
|
||||||
|
nextEvent as EventIGE;
|
||||||
|
switch (nextEvent.data.data.type){
|
||||||
|
case "interaction":
|
||||||
|
garbageQueue.add(IncomingGarbage((nextEvent.data.data as IGEdataInteraction).data));
|
||||||
|
case "interaction_confirm":
|
||||||
|
GarbageData data = (nextEvent.data.data as IGEdataInteraction).data;
|
||||||
|
if(data.type != "targeted") garbageQueue.firstWhere((element) => element.data.iid == data.iid).confirm(currentFrame, settings!.garbageSpeed!);
|
||||||
|
case "allow_targeting":
|
||||||
|
case "target":
|
||||||
|
default:
|
||||||
|
developer.log("Unknown IGE type: ${nextEvent.data.type}", level: 900);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// garbage speed counts from interaction comfirm
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
developer.log("Event wasn't processed: ${nextEvent}", level: 900);
|
developer.log("Event wasn't processed: ${nextEvent}", level: 900);
|
||||||
}
|
}
|
||||||
|
|
|
@ -590,6 +590,7 @@ class DataFullOptions{
|
||||||
gMargin = json["gmargin"];
|
gMargin = json["gmargin"];
|
||||||
gIncrease = json["gincrease"];
|
gIncrease = json["gincrease"];
|
||||||
garbageMultiplier = json["garbagemultiplier"].toDouble();
|
garbageMultiplier = json["garbagemultiplier"].toDouble();
|
||||||
|
garbageCap = json["garbagecap"];
|
||||||
garbageCapIncrease = json["garbagecapincrease"].toDouble();
|
garbageCapIncrease = json["garbagecapincrease"].toDouble();
|
||||||
garbageCapMax = json["garbagecapmax"];
|
garbageCapMax = json["garbagecapmax"];
|
||||||
garbageHoleSize = json["garbageholesize"];
|
garbageHoleSize = json["garbageholesize"];
|
||||||
|
@ -815,9 +816,9 @@ List<List<List<Coords>>> shapes = [
|
||||||
[Coords(0, 1), Coords(1, 0), Coords(1, 1), Coords(1, 2)]
|
[Coords(0, 1), Coords(1, 0), Coords(1, 1), Coords(1, 2)]
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
List<Coords> spawnPositionFixes = [Coords(0, 0), Coords(0, 0), Coords(2, 1), Coords(0, 0), Coords(0, -1), Coords(0, 0), Coords(0, 0)];
|
List<Coords> spawnPositionFixes = [Coords(0, 0), Coords(0, 0), Coords(1, 1), Coords(0, 0), Coords(0, -1), Coords(0, 0), Coords(0, 0)];
|
||||||
|
|
||||||
const Map<String, double> garbage = {
|
const Map<String, int> garbage = {
|
||||||
"single": 0,
|
"single": 0,
|
||||||
"double": 1,
|
"double": 1,
|
||||||
"triple": 2,
|
"triple": 2,
|
||||||
|
@ -840,3 +841,61 @@ double comboBonus = 0.25;
|
||||||
int comboMinifier = 1;
|
int comboMinifier = 1;
|
||||||
double comboMinifierLog = 1.25;
|
double comboMinifierLog = 1.25;
|
||||||
List<int> comboTable = [0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5];
|
List<int> comboTable = [0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5];
|
||||||
|
|
||||||
|
class KicksetBase {
|
||||||
|
List<Coords>? additionalOffsets;
|
||||||
|
late List<Coords> additionalOffsetEmpty;
|
||||||
|
List<int>? spawnRotation;
|
||||||
|
late List<List<List<Coords>>> kickTable; //kickTable[initRot][rotDirection-1][kick]
|
||||||
|
late List<List<List<Coords>>> kickTableI;
|
||||||
|
}
|
||||||
|
|
||||||
|
class SRSPlus extends KicksetBase{
|
||||||
|
SRSPlus(){
|
||||||
|
kickTable = [
|
||||||
|
[
|
||||||
|
[Coords( 0, 0), Coords( 1, 0), Coords( 1, 1), Coords( 0,-2), Coords( 1,-2)], // 0 -> 270
|
||||||
|
[Coords( 0, 0), Coords(-1, 0), Coords(-1, 1), Coords( 0,-2), Coords(-1,-2)], // 0 -> 90
|
||||||
|
[Coords( 0, 0), Coords(-1, 0), Coords(-1, 1), Coords( 0,-2), Coords(-1,-2)], // 0 -> 180
|
||||||
|
],
|
||||||
|
[
|
||||||
|
[Coords( 0, 0), Coords( 1, 0), Coords( 1,-1), Coords( 0, 2), Coords( 1, 2)], // 90 -> 0
|
||||||
|
[Coords( 0, 0), Coords( 1, 0), Coords( 1,-1), Coords( 0, 2), Coords( 1, 2)], // 90 -> 180
|
||||||
|
[Coords( 0, 0), Coords( 1, 0), Coords( 1,-1), Coords( 0, 2), Coords( 1, 2)], // 90 -> 270
|
||||||
|
],
|
||||||
|
[
|
||||||
|
[Coords( 0, 0), Coords(-1, 0), Coords(-1, 1), Coords( 0,-2), Coords(-1,-2)], // 180 -> 90
|
||||||
|
[Coords( 0, 0), Coords( 1, 0), Coords( 1, 1), Coords( 0,-2), Coords( 1,-2)], // 180 -> 270
|
||||||
|
[Coords( 0, 0), Coords( 1, 0), Coords( 1, 1), Coords( 0,-2), Coords( 1,-2)], // 180 -> 0
|
||||||
|
],
|
||||||
|
[
|
||||||
|
[Coords( 0, 0), Coords(-1, 0), Coords(-1,-1), Coords( 0, 2), Coords(-1, 2)], // 270 -> 180
|
||||||
|
[Coords( 0, 0), Coords(-1, 0), Coords(-1,-1), Coords( 0, 2), Coords(-1, 2)], // 270 -> 0
|
||||||
|
[Coords( 0, 0), Coords(-1, 0), Coords(-1,-1), Coords( 0, 2), Coords(-1, 2)], // 270 -> 90
|
||||||
|
]
|
||||||
|
];
|
||||||
|
kickTableI = [
|
||||||
|
[
|
||||||
|
[Coords( 0, 0), Coords( 1, 0), Coords( 1, 1), Coords( 0,-2), Coords( 1,-2)], // 0 -> 270
|
||||||
|
[Coords( 0, 0), Coords(-1, 0), Coords(-1, 1), Coords( 0,-2), Coords(-1,-2)], // 0 -> 90
|
||||||
|
[Coords( 0, 0), Coords( 1, 0), Coords( 1, 1), Coords( 0,-2), Coords( 1,-2)], // 0 -> 180
|
||||||
|
],
|
||||||
|
[
|
||||||
|
[Coords( 0, 0), Coords( 1, 0), Coords( 1,-1), Coords( 0, 2), Coords( 1, 2)], // 90 -> 0
|
||||||
|
[Coords( 0, 0), Coords( 1, 0), Coords( 1,-1), Coords( 0, 2), Coords( 1, 2)], // 90 -> 180
|
||||||
|
[Coords( 0, 0), Coords( 1, 0), Coords( 1, 1), Coords( 0,-2), Coords( 1,-2)], // 90 -> 270
|
||||||
|
],
|
||||||
|
[
|
||||||
|
[Coords( 0, 0), Coords(-1, 0), Coords(-1, 1), Coords( 0,-2), Coords(-1,-2)], // 180 -> 90
|
||||||
|
[Coords( 0, 0), Coords( 1, 0), Coords( 1, 1), Coords( 0,-2), Coords( 1,-2)], // 180 -> 270
|
||||||
|
[Coords( 0, 0), Coords(-1, 0), Coords(-1, 1), Coords( 0,-2), Coords(-1,-2)], // 180 -> 0
|
||||||
|
],
|
||||||
|
[
|
||||||
|
[Coords( 0, 0), Coords(-1, 0), Coords(-1,-1), Coords( 0, 2), Coords(-1, 2)], // 270 -> 180
|
||||||
|
[Coords( 0, 0), Coords(-1, 0), Coords(-1,-1), Coords( 0, 2), Coords(-1, 2)], // 270 -> 0
|
||||||
|
[Coords( 0, 0), Coords(-1, 0), Coords(-1,-1), Coords( 0, 2), Coords(-1, 2)], // 270 -> 90
|
||||||
|
]
|
||||||
|
];
|
||||||
|
additionalOffsetEmpty = [Coords( 0, 0),Coords( 0, 0),Coords( 0, 0),Coords( 0, 0)];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1184,7 +1184,7 @@ class _TwoRecordsThingy extends StatelessWidget {
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
for (int i = 1; i < sprintStream.records.length; i++) ListTile(
|
for (int i = 1; i < blitzStream.records.length; i++) ListTile(
|
||||||
onTap: () => Navigator.push(context, MaterialPageRoute(builder: (context) => SingleplayerRecordView(record: blitzStream.records[i]))),
|
onTap: () => Navigator.push(context, MaterialPageRoute(builder: (context) => SingleplayerRecordView(record: blitzStream.records[i]))),
|
||||||
leading: Text("#${i+1}", style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 28, shadows: textShadow, height: 0.9) ),
|
leading: Text("#${i+1}", style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 28, shadows: textShadow, height: 0.9) ),
|
||||||
title: Text("${NumberFormat.decimalPattern().format(blitzStream.records[i].endContext.score)} points",
|
title: Text("${NumberFormat.decimalPattern().format(blitzStream.records[i].endContext.score)} points",
|
||||||
|
|
Loading…
Reference in New Issue