feat(state): coordinate booster use with inventory in the session
This commit is contained in:
@@ -2,12 +2,15 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
import '../game/engine/game_engine.dart';
|
||||
import '../game/engine/piece_generator.dart';
|
||||
import '../game/models/booster.dart';
|
||||
import '../game/models/grid.dart';
|
||||
import '../game/models/objective.dart';
|
||||
import '../game/models/piece.dart';
|
||||
import '../game/models/stage.dart';
|
||||
import 'providers.dart';
|
||||
|
||||
enum BoosterUseResult { success, noBooster, invalidTarget }
|
||||
|
||||
/// Immutable snapshot of one engine moment; the only game state the UI sees.
|
||||
class GameViewState {
|
||||
const GameViewState({
|
||||
@@ -117,6 +120,41 @@ class GameSessionNotifier extends Notifier<GameViewState?> {
|
||||
_publish(lastPlacement: null);
|
||||
}
|
||||
|
||||
Future<BoosterUseResult> useHammer(int x, int y) =>
|
||||
_useBooster(BoosterType.hammer, () {
|
||||
final engine = _engine;
|
||||
if (engine == null) return false;
|
||||
return engine.useHammer(x, y);
|
||||
});
|
||||
|
||||
Future<BoosterUseResult> useShuffle() =>
|
||||
_useBooster(BoosterType.shuffle, () {
|
||||
final engine = _engine;
|
||||
if (engine == null) return false;
|
||||
return engine.useShuffle();
|
||||
});
|
||||
|
||||
Future<BoosterUseResult> useLineBomb({int? row, int? col}) =>
|
||||
_useBooster(BoosterType.lineBomb, () {
|
||||
final engine = _engine;
|
||||
if (engine == null) return false;
|
||||
return engine.useLineBomb(row: row, col: col);
|
||||
});
|
||||
|
||||
Future<BoosterUseResult> _useBooster(
|
||||
BoosterType type, bool Function() apply) async {
|
||||
final engine = _engine;
|
||||
if (engine == null) return BoosterUseResult.noBooster;
|
||||
final inv = ref.read(boosterInventoryProvider.notifier);
|
||||
if ((ref.read(boosterInventoryProvider)[type] ?? 0) <= 0) {
|
||||
return BoosterUseResult.noBooster;
|
||||
}
|
||||
if (!apply()) return BoosterUseResult.invalidTarget;
|
||||
await inv.consume(type);
|
||||
_publish(lastPlacement: null);
|
||||
return BoosterUseResult.success;
|
||||
}
|
||||
|
||||
void _publish({required PlacementResult? lastPlacement}) {
|
||||
final engine = _engine!;
|
||||
state = GameViewState(
|
||||
|
||||
Reference in New Issue
Block a user