Compare commits
2 Commits
54a5cc683c
...
8f5b7c018d
Author | SHA1 | Date |
---|---|---|
dan63047 | 8f5b7c018d | |
dan63047 | 86ac390e05 |
|
@ -123,6 +123,7 @@
|
|||
// }
|
||||
|
||||
// bool wasATSpin(Tetromino type, Coords coords, int rot){
|
||||
// if (type != Tetromino.T) return false;
|
||||
// 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) ||
|
||||
|
@ -200,10 +201,6 @@
|
|||
// 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:
|
||||
|
@ -215,7 +212,8 @@
|
|||
// if (spinWasLastMove && tspin) {
|
||||
// attack = garbage['t-spin single']!;
|
||||
// }else{
|
||||
// attack = garbage['single']!;
|
||||
// if (combo == -1) attack = garbage['single']!;
|
||||
// else attack = comboTable[combo];
|
||||
// }
|
||||
// break;
|
||||
// case 2:
|
||||
|
@ -250,6 +248,10 @@
|
|||
// developer.log("${clearFullLinesResult[0]} lines cleared");
|
||||
// break;
|
||||
// }
|
||||
// if (clearFullLinesResult[0] > 0) combo++;
|
||||
// else combo = -1;
|
||||
// if (clearFullLinesResult[2] > 0) btb++;
|
||||
// else btb = -1;
|
||||
// return LineClearResult(clearFullLinesResult[0], Tetromino.empty, false, clearFullLinesResult[1], 0, attack);
|
||||
// }
|
||||
// }
|
||||
|
@ -269,7 +271,7 @@
|
|||
// List<Event> events = readEventList(replay.rawJson);
|
||||
// DataFullOptions? settings;
|
||||
// HandlingHandler? handling;
|
||||
// Map<KeyType, EventKeyPress> activeKeypresses = {};
|
||||
// //Map<KeyType, EventKeyPress> activeKeypresses = {};
|
||||
// int currentFrame = 0;
|
||||
// double subframesWent = 0;
|
||||
// events.removeAt(0); // get rig of Event.start
|
||||
|
@ -278,6 +280,7 @@
|
|||
// Board board = Board(10, 20, 20);
|
||||
// KicksetBase kickset = SRSPlus();
|
||||
// List<IncomingGarbage> garbageQueue = [];
|
||||
// List<GarbageData> outcomingGarbage = [];
|
||||
// Tetromino? hold;
|
||||
// int rot = 0;
|
||||
// bool spinWasLastMove = false;
|
||||
|
@ -287,9 +290,9 @@
|
|||
// bool floored = false;
|
||||
// double gravityBucket = 1.0;
|
||||
|
||||
// developer.log("Seed is ${replay.stats[0][0].seed}, first bag is $queue");
|
||||
// //developer.log("Seed is ${replay.stats[0][0].seed}, first bag is $queue");
|
||||
// Tetromino current = queue.removeAt(0);
|
||||
// //developer.log("Second bag is ${rng.shuffleList(tetrominoes)}");
|
||||
// //developer.log("Handling is ");
|
||||
|
||||
// int sonicDrop(){
|
||||
// int height = coords.y;
|
||||
|
@ -333,12 +336,13 @@
|
|||
// 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 (lineClear.attackProduced > 0) outcomingGarbage.add(GarbageData());
|
||||
// //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) {
|
||||
// if (garbage.data.amt! < garbageToDelete) {
|
||||
// garbageToDelete -= garbage.data.amt!;
|
||||
// lineClear.attackProduced = garbageToDelete;
|
||||
// garbage.data.amt = 0;
|
||||
|
@ -367,11 +371,17 @@
|
|||
// }
|
||||
// current = getNewOne();
|
||||
// coords = Coords(3, 21) + spawnPositionFixes[current.index];
|
||||
// print("${lineClear.linesCleared} lines, ${lineClear.attackProduced} atk, ${lineClear.spin}, combo ${stats.combo}, btb ${stats.btb}");
|
||||
// }
|
||||
|
||||
// void handleGravity(double frames){
|
||||
// if (frames == 0) return;
|
||||
// gravityBucket += settings != null ? (handling!.sdfActive ? max(settings.g! * settings.handling!.sdf, 0.05 * settings.handling!.sdf) : settings.g!) * frames : 0;
|
||||
// gravityBucket += settings != null ?
|
||||
// (handling!.sdfActive ?
|
||||
// max(settings.g! * settings.handling!.sdf, 0.05 * settings.handling!.sdf) :
|
||||
// settings.g!
|
||||
// ) * frames
|
||||
// : 0;
|
||||
// int gravityImpact = 0;
|
||||
// if (gravityBucket >= 1.0){
|
||||
// gravityImpact = gravityBucket.truncate();
|
||||
|
@ -404,17 +414,17 @@
|
|||
// subframesWent = 0;
|
||||
|
||||
// if (settings?.handling?.sdf == 41) coords.y = sonicDrop();
|
||||
// print("$currentFrame: $current at $coords\n$board");
|
||||
// //print(stats.combo);
|
||||
// if (currentFrame == nextEvent.frame){
|
||||
// while (currentFrame == nextEvent.frame){
|
||||
// print("Processing $nextEvent");
|
||||
// //print("Processing $nextEvent");
|
||||
// switch (nextEvent.type){
|
||||
// case EventType.start:
|
||||
// developer.log("go");
|
||||
// break;
|
||||
// case EventType.full:
|
||||
// settings = (nextEvent as EventFull).data.options;
|
||||
// developer.log("SDF is ${settings?.handling?.sdf}, replay version is ${settings?.version}");
|
||||
// handling = HandlingHandler(settings!.handling!.das.toDouble(), settings.handling!.arr.toDouble());
|
||||
// lockDelay = settings.locktime!.toDouble();
|
||||
// lockResets = settings.lockresets!;
|
||||
|
@ -446,6 +456,7 @@
|
|||
// break;
|
||||
// case KeyType.hardDrop:
|
||||
// coords.y = sonicDrop();
|
||||
// print("$currentFrame: $current at $coords, garbage queue $garbageQueue\n$board");
|
||||
// handleHardDrop();
|
||||
// case KeyType.hold:
|
||||
// switch (hold){
|
||||
|
@ -513,7 +524,7 @@
|
|||
// case KeyType.retry:
|
||||
// // TODO: Handle this case.
|
||||
// }
|
||||
// activeKeypresses.remove(nextEvent.data.key);
|
||||
// //activeKeypresses.remove(nextEvent.data.key);
|
||||
// break;
|
||||
// case EventType.end:
|
||||
// currentFrame = replay.roundLengths[0]+1;
|
||||
|
|
|
@ -60,6 +60,7 @@ const Map<String, double> rankTargets = {
|
|||
"d+": 606,
|
||||
"d": 0,
|
||||
};
|
||||
DateTime seasonEnd = DateTime.utc(2024, 07, 26, 15);
|
||||
enum Stats {
|
||||
tr,
|
||||
glicko,
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
/// To regenerate, run: `dart run slang`
|
||||
///
|
||||
/// Locales: 2
|
||||
/// Strings: 1182 (591 per locale)
|
||||
/// Strings: 1186 (593 per locale)
|
||||
///
|
||||
/// Built on 2024-07-10 at 15:23 UTC
|
||||
/// Built on 2024-07-20 at 13:24 UTC
|
||||
|
||||
// coverage:ignore-file
|
||||
// ignore_for_file: type=lint
|
||||
|
@ -222,6 +222,8 @@ class Translations implements BaseTranslations<AppLocale, Translations> {
|
|||
String get verdictBetter => 'better';
|
||||
String get verdictWorse => 'worse';
|
||||
String get smooth => 'Smooth';
|
||||
String seasonEnds({required Object countdown}) => 'Season ends in ${countdown}';
|
||||
String get seasonEnded => 'Season has ended';
|
||||
String gamesUntilRanked({required Object left}) => '${left} games until being ranked';
|
||||
String numOfVictories({required Object wins}) => '~${wins} victories';
|
||||
String get promotionOnNextWin => 'Promotion on next win';
|
||||
|
@ -917,6 +919,8 @@ class _StringsRu implements Translations {
|
|||
@override String get verdictBetter => 'Лучше';
|
||||
@override String get verdictWorse => 'Хуже';
|
||||
@override String get smooth => 'Гладкий';
|
||||
@override String seasonEnds({required Object countdown}) => 'Сезон закончится через ${countdown}';
|
||||
@override String get seasonEnded => 'Сезон закончился';
|
||||
@override String gamesUntilRanked({required Object left}) => '${left} матчей до получения рейтинга';
|
||||
@override String numOfVictories({required Object wins}) => '~${wins} побед';
|
||||
@override String get promotionOnNextWin => 'Повышение после следующей победы';
|
||||
|
@ -1604,6 +1608,8 @@ extension on Translations {
|
|||
case 'verdictBetter': return 'better';
|
||||
case 'verdictWorse': return 'worse';
|
||||
case 'smooth': return 'Smooth';
|
||||
case 'seasonEnds': return ({required Object countdown}) => 'Season ends in ${countdown}';
|
||||
case 'seasonEnded': return 'Season has ended';
|
||||
case 'gamesUntilRanked': return ({required Object left}) => '${left} games until being ranked';
|
||||
case 'numOfVictories': return ({required Object wins}) => '~${wins} victories';
|
||||
case 'promotionOnNextWin': return 'Promotion on next win';
|
||||
|
@ -2215,6 +2221,8 @@ extension on _StringsRu {
|
|||
case 'verdictBetter': return 'Лучше';
|
||||
case 'verdictWorse': return 'Хуже';
|
||||
case 'smooth': return 'Гладкий';
|
||||
case 'seasonEnds': return ({required Object countdown}) => 'Сезон закончится через ${countdown}';
|
||||
case 'seasonEnded': return 'Сезон закончился';
|
||||
case 'gamesUntilRanked': return ({required Object left}) => '${left} матчей до получения рейтинга';
|
||||
case 'numOfVictories': return ({required Object wins}) => '~${wins} побед';
|
||||
case 'promotionOnNextWin': return 'Повышение после следующей победы';
|
||||
|
|
|
@ -3,6 +3,7 @@ import 'package:tetra_stats/gen/strings.g.dart';
|
|||
import 'package:tetra_stats/utils/numers_formats.dart';
|
||||
|
||||
final NumberFormat secs = NumberFormat("00.###", LocaleSettings.currentLocale.languageCode);
|
||||
final NumberFormat nonsecs = NumberFormat("00.###", LocaleSettings.currentLocale.languageCode);
|
||||
final NumberFormat _timeInSec = NumberFormat("#,###.###s.", LocaleSettings.currentLocale.languageCode);
|
||||
|
||||
/// Returns string, that represents time difference between [dateTime] and now
|
||||
|
@ -73,4 +74,8 @@ String readableTimeDifference(Duration a, Duration b){
|
|||
Duration result = a - b;
|
||||
|
||||
return NumberFormat("0.000s;0.000s", LocaleSettings.currentLocale.languageCode).format(result.inMilliseconds/1000);
|
||||
}
|
||||
|
||||
String countdown(Duration difference){
|
||||
return "${difference.inDays}:${nonsecs.format(difference.inHours%24)}:${nonsecs.format(difference.inMinutes%60)}:${secs.format(difference.inSeconds%60)}";
|
||||
}
|
|
@ -1013,7 +1013,6 @@ class _TwoRecordsThingy extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
//if (record == null) return Center(child: Text(t.noRecord, textAlign: TextAlign.center, style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 28)));
|
||||
late MapEntry closestAverageBlitz;
|
||||
late bool blitzBetterThanClosestAverage;
|
||||
bool? blitzBetterThanRankAverage = (rank != null && rank != "z" && blitz != null) ? blitz!.endContext.score > blitzAverages[rank]! : null;
|
||||
|
@ -1186,13 +1185,13 @@ class _TwoRecordsThingy extends StatelessWidget {
|
|||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
for (int i = 1; i < blitzStream.records.length; i++) ListTile(
|
||||
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) ),
|
||||
title: Text("${NumberFormat.decimalPattern().format(blitzStream.records[i].endContext.score)} points",
|
||||
style: const TextStyle(fontSize: 18)),
|
||||
subtitle: Text(timestamp(blitzStream.records[i].timestamp), style: const TextStyle(color: Colors.grey, height: 0.85)),
|
||||
trailing: SpTrailingStats(blitzStream.records[i].endContext)
|
||||
)
|
||||
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) ),
|
||||
title: Text("${NumberFormat.decimalPattern().format(blitzStream.records[i].endContext.score)} points",
|
||||
style: const TextStyle(fontSize: 18)),
|
||||
subtitle: Text(timestamp(blitzStream.records[i].timestamp), style: const TextStyle(color: Colors.grey, height: 0.85)),
|
||||
trailing: SpTrailingStats(blitzStream.records[i].endContext)
|
||||
)
|
||||
],
|
||||
),
|
||||
)
|
||||
|
|
|
@ -8,7 +8,6 @@ import 'package:tetra_stats/main.dart' show prefs;
|
|||
import 'package:tetra_stats/utils/numers_formats.dart';
|
||||
|
||||
var fDiff = NumberFormat("+#,###.####;-#,###.####");
|
||||
DateTime seasonEnd = DateTime.utc(2024, 07, 26);
|
||||
|
||||
class TLRatingThingy extends StatelessWidget{
|
||||
final String userID;
|
||||
|
@ -30,7 +29,6 @@ class TLRatingThingy extends StatelessWidget{
|
|||
DateTime now = DateTime.now();
|
||||
bool beforeS1end = now.isBefore(seasonEnd);
|
||||
int daysLeft = seasonEnd.difference(now).inDays;
|
||||
print(max(0, 7 - (lastMatchPlayed != null ? now.difference(lastMatchPlayed!).inDays : 7)));
|
||||
int safeRD = min(100, (100 + ((tlData.rd! >= 100 && tlData.decaying) ? 7 : max(0, 7 - (lastMatchPlayed != null ? now.difference(lastMatchPlayed!).inDays : 7))) - daysLeft).toInt());
|
||||
return Wrap(
|
||||
direction: Axis.horizontal,
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:tetra_stats/data_objects/tetrio.dart';
|
||||
|
@ -5,6 +7,7 @@ import 'package:syncfusion_flutter_gauges/gauges.dart';
|
|||
import 'package:tetra_stats/gen/strings.g.dart';
|
||||
import 'package:tetra_stats/utils/colors_functions.dart';
|
||||
import 'package:tetra_stats/utils/numers_formats.dart';
|
||||
import 'package:tetra_stats/utils/relative_timestamps.dart';
|
||||
import 'package:tetra_stats/widgets/gauget_num.dart';
|
||||
import 'package:tetra_stats/widgets/graphs.dart';
|
||||
import 'package:tetra_stats/widgets/stat_sell_num.dart';
|
||||
|
@ -38,12 +41,14 @@ class TLThingy extends StatefulWidget {
|
|||
State<TLThingy> createState() => _TLThingyState();
|
||||
}
|
||||
|
||||
class _TLThingyState extends State<TLThingy> {
|
||||
class _TLThingyState extends State<TLThingy> with TickerProviderStateMixin {
|
||||
late bool oskKagariGimmick;
|
||||
late TetraLeagueAlpha? oldTl;
|
||||
late TetraLeagueAlpha currentTl;
|
||||
late RangeValues _currentRangeValues;
|
||||
late List<TetrioPlayer> sortedStates;
|
||||
late Timer _countdownTimer;
|
||||
Duration seasonLeft = seasonEnd.difference(DateTime.now());
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
|
@ -52,8 +57,23 @@ class _TLThingyState extends State<TLThingy> {
|
|||
oldTl = sortedStates.elementAtOrNull(1)?.tlSeason1;
|
||||
currentTl = widget.tl;
|
||||
super.initState();
|
||||
_countdownTimer = Timer.periodic(
|
||||
Durations.extralong4,
|
||||
(Timer timer) {
|
||||
setState(() {
|
||||
seasonLeft = seasonEnd.difference(DateTime.now());
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_countdownTimer.cancel();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final t = Translations.of(context);
|
||||
|
@ -70,6 +90,8 @@ class _TLThingyState extends State<TLThingy> {
|
|||
return Column(
|
||||
children: [
|
||||
if (widget.showTitle) Text(t.tetraLeague, style: TextStyle(fontFamily: "Eurostile Round Extended", fontSize: bigScreen ? 42 : 28)),
|
||||
if (DateTime.now().isBefore(seasonEnd)) Text(t.seasonEnds(countdown: countdown(seasonLeft)))
|
||||
else Text(t.seasonEnded),
|
||||
if (oldTl != null) Text(t.comparingWith(newDate: timestamp(currentTl.timestamp), oldDate: timestamp(oldTl!.timestamp)),
|
||||
textAlign: TextAlign.center,),
|
||||
if (oldTl != null) RangeSlider(values: _currentRangeValues, max: widget.states.length.toDouble(),
|
||||
|
|
|
@ -2,7 +2,7 @@ name: tetra_stats
|
|||
description: Track your and other player stats in TETR.IO
|
||||
publish_to: 'none'
|
||||
|
||||
version: 1.6.1+21
|
||||
version: 1.6.2+22
|
||||
|
||||
environment:
|
||||
sdk: '>=3.0.0'
|
||||
|
|
|
@ -87,6 +87,8 @@
|
|||
"verdictBetter": "better",
|
||||
"verdictWorse": "worse",
|
||||
"smooth": "Smooth",
|
||||
"seasonEnds": "Season ends in ${countdown}",
|
||||
"seasonEnded": "Season has ended",
|
||||
"gamesUntilRanked": "${left} games until being ranked",
|
||||
"numOfVictories": "~${wins} victories",
|
||||
"promotionOnNextWin": "Promotion on next win",
|
||||
|
|
|
@ -87,6 +87,8 @@
|
|||
"verdictBetter": "Лучше",
|
||||
"verdictWorse": "Хуже",
|
||||
"smooth": "Гладкий",
|
||||
"seasonEnds": "Сезон закончится через ${countdown}",
|
||||
"seasonEnded": "Сезон закончился",
|
||||
"gamesUntilRanked": "${left} матчей до получения рейтинга",
|
||||
"numOfVictories": "~${wins} побед",
|
||||
"promotionOnNextWin": "Повышение после следующей победы",
|
||||
|
|
|
@ -152,12 +152,18 @@
|
|||
// Promoting Tetra Stats "native"
|
||||
"Want a better perfomance?<br><a href=\"https://github.com/dan63047/TetraStats/releases\">Try out Tetra Stats \"Native\"</a>",
|
||||
"Imagine a world, where Tetra Stats was written in JS",
|
||||
"Did you know, that Flutter for web sucks?",
|
||||
"Welcome to fullscreen canvas",
|
||||
|
||||
// An actual tips
|
||||
"You can interact with most objects that have an accent color",
|
||||
"Like Sheetbot graphs? Go to three dots menu → Settings → Customization",
|
||||
"Click and hold on line chart graph, then start dragging to zoom in"
|
||||
"Click and hold on line chart graph, then start dragging to zoom in",
|
||||
"Discord userID ≠ Discord username. It should look like a bunch of digits",
|
||||
|
||||
// :droidsmile:
|
||||
"Is she real?",
|
||||
"Check out <a href=\"https://github.com/dan63047/TetraStats/wiki\">wiki</a> for more information"
|
||||
];
|
||||
tip.innerHTML = tips[Math.floor(Math.random() * tips.length)];
|
||||
try{
|
||||
|
|
Loading…
Reference in New Issue