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 ---
|
// --- LOGICA TIMER ---
|
||||||
if (this.isVsCPU) {
|
if (this.isVsCPU) {
|
||||||
// La CPU usa sempre la sua formula basata sul Livello Profilo
|
|
||||||
int pLevel = StorageService.instance.playerLevel;
|
int pLevel = StorageService.instance.playerLevel;
|
||||||
int calculatedTime = 15 - ((pLevel - 1) * 12 / 14).round();
|
int calculatedTime = 15 - ((pLevel - 1) * 12 / 14).round();
|
||||||
maxTime = calculatedTime.clamp(3, 15);
|
maxTime = calculatedTime.clamp(3, 15);
|
||||||
} else {
|
} else {
|
||||||
// Multiplayer e Locale
|
|
||||||
if (timeModeSetting == 'dynamic') {
|
if (timeModeSetting == 'dynamic') {
|
||||||
// Parte da 10s e toglie 2s per ogni rivincita (Minimo 2s)
|
|
||||||
maxTime = max(2, 10 - (consecutiveRematches * 2));
|
maxTime = max(2, 10 - (consecutiveRematches * 2));
|
||||||
} else if (timeModeSetting == 'relax') {
|
} else if (timeModeSetting == 'relax') {
|
||||||
maxTime = 0; // Il timer non scatterà
|
maxTime = 0;
|
||||||
} else {
|
} else {
|
||||||
maxTime = 10; // Fisso 10s
|
maxTime = 10;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
timeLeft = maxTime;
|
timeLeft = maxTime;
|
||||||
// -------------------
|
|
||||||
|
|
||||||
int finalRadius = radius;
|
int finalRadius = radius;
|
||||||
ArenaShape finalShape = shape;
|
ArenaShape finalShape = shape;
|
||||||
|
|
@ -407,10 +403,12 @@ class GameController extends ChangeNotifier {
|
||||||
onlineHostName = data['hostName'] ?? "ROSSO";
|
onlineHostName = data['hostName'] ?? "ROSSO";
|
||||||
onlineGuestName = (data['guestName'] != null && data['guestName'] != '') ? data['guestName'] : "BLU";
|
onlineGuestName = (data['guestName'] != null && data['guestName'] != '') ? data['guestName'] : "BLU";
|
||||||
|
|
||||||
|
// 1. GESTIONE ABBANDONO
|
||||||
if (data['status'] == 'abandoned' && !board.isGameOver && !opponentLeft) {
|
if (data['status'] == 'abandoned' && !board.isGameOver && !opponentLeft) {
|
||||||
opponentLeft = true; notifyListeners(); return;
|
opponentLeft = true; notifyListeners(); return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 2. GESTIONE REAZIONI
|
||||||
String? p1React = data['p1_reaction'];
|
String? p1React = data['p1_reaction'];
|
||||||
Timestamp? p1Time = data['p1_reaction_time'] as Timestamp?;
|
Timestamp? p1Time = data['p1_reaction_time'] as Timestamp?;
|
||||||
String? p2React = data['p2_reaction'];
|
String? p2React = data['p2_reaction'];
|
||||||
|
|
@ -424,30 +422,39 @@ class GameController extends ChangeNotifier {
|
||||||
_showReaction(false, p1React);
|
_showReaction(false, p1React);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 3. LOGICA RIVINCITA MIGLIORATA
|
||||||
bool p1Rematch = data['p1_rematch'] ?? false;
|
bool p1Rematch = data['p1_rematch'] ?? false;
|
||||||
bool p2Rematch = data['p2_rematch'] ?? false;
|
bool p2Rematch = data['p2_rematch'] ?? false;
|
||||||
opponentWantsRematch = isHost ? p2Rematch : p1Rematch;
|
opponentWantsRematch = isHost ? p2Rematch : p1Rematch;
|
||||||
|
|
||||||
// === LA RIVINCITA INCREMENTA IL CONTATORE DELLA MODALITA' DINAMICA ===
|
// SOLO L'HOST si occupa di chiamare resetMatch sul server
|
||||||
if (data['status'] == 'playing' && (data['moves'] as List).isEmpty && rematchRequested) {
|
if (isHost && p1Rematch && p2Rematch && data['status'] != 'playing') {
|
||||||
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') {
|
|
||||||
currentMatchLevel++;
|
currentMatchLevel++;
|
||||||
int newSeed = DateTime.now().millisecondsSinceEpoch % 1000000;
|
int newSeed = DateTime.now().millisecondsSinceEpoch % 1000000;
|
||||||
final rand = Random();
|
final rand = Random();
|
||||||
int newRadius = rand.nextInt(4) + 3;
|
int newRadius = rand.nextInt(4) + 3;
|
||||||
ArenaShape newShape = ArenaShape.values[rand.nextInt(ArenaShape.values.length)];
|
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);
|
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 (isSetupPhase) {
|
||||||
if (!isHost && data['p1_joker'] != null && !oppJokerPlaced) {
|
if (!isHost && data['p1_joker'] != null && !oppJokerPlaced) {
|
||||||
int jx = data['p1_joker']['x']; int jy = data['p1_joker']['y'];
|
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 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;
|
onlineShape = hostShape;
|
||||||
|
|
||||||
String hostTimeMode = data['timeMode'] is String ? data['timeMode'] : (data['timeMode'] == true ? 'fixed' : 'relax');
|
|
||||||
timeModeSetting = hostTimeMode;
|
timeModeSetting = hostTimeMode;
|
||||||
|
|
||||||
if (!rematchRequested && (hostLevel > currentMatchLevel || (isOnline && currentSeed == null && hostSeed != null) || (hostSeed != null && hostSeed != currentSeed))) {
|
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;
|
isCPUThinking = false; notifyListeners(); return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 6. GESTIONE MOSSE
|
||||||
|
List<dynamic> moves = data['moves'] ?? [];
|
||||||
int firebaseMovesCount = moves.length;
|
int firebaseMovesCount = moves.length;
|
||||||
int localMovesCount = board.lines.where((l) => l.owner != Player.none).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) {
|
if (firebaseMovesCount == 0 && localMovesCount > 0 && !rematchRequested) {
|
||||||
int levelToUse = (currentMatchLevel == 1) ? 2 : currentMatchLevel;
|
int levelToUse = (currentMatchLevel == 1) ? 2 : currentMatchLevel;
|
||||||
board = GameBoard(radius: hostRadius, level: levelToUse, seed: currentSeed, shape: onlineShape);
|
board = GameBoard(radius: hostRadius, level: levelToUse, seed: currentSeed, shape: onlineShape);
|
||||||
|
|
@ -490,6 +494,7 @@ class GameController extends ChangeNotifier {
|
||||||
notifyListeners(); return;
|
notifyListeners(); return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Applica mosse remote
|
||||||
if (firebaseMovesCount > localMovesCount) {
|
if (firebaseMovesCount > localMovesCount) {
|
||||||
bool newMovesApplied = false;
|
bool newMovesApplied = false;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue