Auto-sync: 20260323_000000
This commit is contained in:
parent
95a0fddaba
commit
c3390609c3
1 changed files with 30 additions and 25 deletions
|
|
@ -157,23 +157,19 @@ class GameController extends ChangeNotifier {
|
|||
|
||||
// --- LOGICA TIMER ---
|
||||
if (this.isVsCPU) {
|
||||
// La CPU usa sempre la sua formula basata sul Livello Profilo
|
||||
int pLevel = StorageService.instance.playerLevel;
|
||||
int calculatedTime = 15 - ((pLevel - 1) * 12 / 14).round();
|
||||
maxTime = calculatedTime.clamp(3, 15);
|
||||
} else {
|
||||
// Multiplayer e Locale
|
||||
if (timeModeSetting == 'dynamic') {
|
||||
// Parte da 10s e toglie 2s per ogni rivincita (Minimo 2s)
|
||||
maxTime = max(2, 10 - (consecutiveRematches * 2));
|
||||
} else if (timeModeSetting == 'relax') {
|
||||
maxTime = 0; // Il timer non scatterà
|
||||
maxTime = 0;
|
||||
} else {
|
||||
maxTime = 10; // Fisso 10s
|
||||
maxTime = 10;
|
||||
}
|
||||
}
|
||||
timeLeft = maxTime;
|
||||
// -------------------
|
||||
|
||||
int finalRadius = radius;
|
||||
ArenaShape finalShape = shape;
|
||||
|
|
@ -407,10 +403,12 @@ class GameController extends ChangeNotifier {
|
|||
onlineHostName = data['hostName'] ?? "ROSSO";
|
||||
onlineGuestName = (data['guestName'] != null && data['guestName'] != '') ? data['guestName'] : "BLU";
|
||||
|
||||
// 1. GESTIONE ABBANDONO
|
||||
if (data['status'] == 'abandoned' && !board.isGameOver && !opponentLeft) {
|
||||
opponentLeft = true; notifyListeners(); return;
|
||||
}
|
||||
|
||||
// 2. GESTIONE REAZIONI
|
||||
String? p1React = data['p1_reaction'];
|
||||
Timestamp? p1Time = data['p1_reaction_time'] as Timestamp?;
|
||||
String? p2React = data['p2_reaction'];
|
||||
|
|
@ -424,30 +422,39 @@ class GameController extends ChangeNotifier {
|
|||
_showReaction(false, p1React);
|
||||
}
|
||||
|
||||
// 3. LOGICA RIVINCITA MIGLIORATA
|
||||
bool p1Rematch = data['p1_rematch'] ?? false;
|
||||
bool p2Rematch = data['p2_rematch'] ?? false;
|
||||
opponentWantsRematch = isHost ? p2Rematch : p1Rematch;
|
||||
|
||||
// === LA RIVINCITA INCREMENTA IL CONTATORE DELLA MODALITA' DINAMICA ===
|
||||
if (data['status'] == 'playing' && (data['moves'] as List).isEmpty && rematchRequested) {
|
||||
currentSeed = data['seed'];
|
||||
consecutiveRematches++;
|
||||
|
||||
String tMode = data['timeMode'] is String ? data['timeMode'] : (data['timeMode'] == true ? 'fixed' : 'relax');
|
||||
|
||||
startNewGame(data['radius'], isOnline: true, roomCode: roomCode, isHost: isHost, shape: ArenaShape.values.firstWhere((e) => e.name == data['shape']), timeMode: tMode, isRematch: true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (p1Rematch && p2Rematch && isHost && data['status'] != 'playing') {
|
||||
// SOLO L'HOST si occupa di chiamare resetMatch sul server
|
||||
if (isHost && p1Rematch && p2Rematch && data['status'] != 'playing') {
|
||||
currentMatchLevel++;
|
||||
int newSeed = DateTime.now().millisecondsSinceEpoch % 1000000;
|
||||
final rand = Random();
|
||||
int newRadius = rand.nextInt(4) + 3;
|
||||
ArenaShape newShape = ArenaShape.values[rand.nextInt(ArenaShape.values.length)];
|
||||
|
||||
// Questo cambierà lo status in 'playing' e svuoterà l'array moves.
|
||||
MultiplayerService().resetMatch(roomCode!, newRadius, newShape.name, newSeed);
|
||||
return; // L'host aspetterà il prossimo trigger dal server con il nuovo seed.
|
||||
}
|
||||
|
||||
int? hostSeed = data['seed'];
|
||||
int hostRadius = data['radius'] ?? board.radius;
|
||||
String shapeStr = data['shape'] ?? 'classic';
|
||||
ArenaShape hostShape = ArenaShape.values.firstWhere((e) => e.name == shapeStr, orElse: () => ArenaShape.classic);
|
||||
String hostTimeMode = data['timeMode'] is String ? data['timeMode'] : (data['timeMode'] == true ? 'fixed' : 'relax');
|
||||
|
||||
// TUTTI (Host e Guest) ripartono SOLO quando vedono il reset effettivo (nuovo seed e status 'playing')
|
||||
if (rematchRequested && data['status'] == 'playing' && hostSeed != null && hostSeed != currentSeed) {
|
||||
currentSeed = hostSeed;
|
||||
consecutiveRematches++;
|
||||
startNewGame(hostRadius, isOnline: true, roomCode: roomCode, isHost: isHost, shape: hostShape, timeMode: hostTimeMode, isRematch: true);
|
||||
return;
|
||||
}
|
||||
|
||||
// 4. GESTIONE FASE INIZIALE (JOLLY)
|
||||
if (isSetupPhase) {
|
||||
if (!isHost && data['p1_joker'] != null && !oppJokerPlaced) {
|
||||
int jx = data['p1_joker']['x']; int jy = data['p1_joker']['y'];
|
||||
|
|
@ -461,15 +468,9 @@ class GameController extends ChangeNotifier {
|
|||
}
|
||||
}
|
||||
|
||||
List<dynamic> moves = data['moves'] ?? [];
|
||||
// 5. AGGIORNAMENTO LIVELLO / SEED (se non in rivincita)
|
||||
int hostLevel = data['matchLevel'] ?? 1;
|
||||
int? hostSeed = data['seed'];
|
||||
int hostRadius = data['radius'] ?? board.radius;
|
||||
String shapeStr = data['shape'] ?? 'classic';
|
||||
ArenaShape hostShape = ArenaShape.values.firstWhere((e) => e.name == shapeStr, orElse: () => ArenaShape.classic);
|
||||
onlineShape = hostShape;
|
||||
|
||||
String hostTimeMode = data['timeMode'] is String ? data['timeMode'] : (data['timeMode'] == true ? 'fixed' : 'relax');
|
||||
timeModeSetting = hostTimeMode;
|
||||
|
||||
if (!rematchRequested && (hostLevel > currentMatchLevel || (isOnline && currentSeed == null && hostSeed != null) || (hostSeed != null && hostSeed != currentSeed))) {
|
||||
|
|
@ -480,9 +481,12 @@ class GameController extends ChangeNotifier {
|
|||
isCPUThinking = false; notifyListeners(); return;
|
||||
}
|
||||
|
||||
// 6. GESTIONE MOSSE
|
||||
List<dynamic> moves = data['moves'] ?? [];
|
||||
int firebaseMovesCount = moves.length;
|
||||
int localMovesCount = board.lines.where((l) => l.owner != Player.none).length;
|
||||
|
||||
// Resilienza: se il locale ha mosse e il server no (e non stiamo aspettando una rivincita), pulisci.
|
||||
if (firebaseMovesCount == 0 && localMovesCount > 0 && !rematchRequested) {
|
||||
int levelToUse = (currentMatchLevel == 1) ? 2 : currentMatchLevel;
|
||||
board = GameBoard(radius: hostRadius, level: levelToUse, seed: currentSeed, shape: onlineShape);
|
||||
|
|
@ -490,6 +494,7 @@ class GameController extends ChangeNotifier {
|
|||
notifyListeners(); return;
|
||||
}
|
||||
|
||||
// Applica mosse remote
|
||||
if (firebaseMovesCount > localMovesCount) {
|
||||
bool newMovesApplied = false;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue