<commit_before>// ignore_for_file: avoid_renaming_method_parameters

import 'package:flame/components.dart';
import 'package:flame_forge2d/flame_forge2d.dart';
import 'package:pinball/game/game.dart';
import 'package:pinball_components/pinball_components.dart';
import 'package:pinball_flame/pinball_flame.dart';

/// {@template flutter_forest}
/// Area positioned at the top right of the [Board] where the [Ball]
/// can bounce off [DashNestBumper]s.
///
/// When all [DashNestBumper]s are hit at least once, the [GameBonus.dashNest]
/// is awarded, and the [DashNestBumper.main] releases a new [Ball].
/// {@endtemplate}
class FlutterForest extends Component
    with Controls<_FlutterForestController>, HasGameRef<PinballGame> {
  /// {@macro flutter_forest}
  FlutterForest() {
    controller = _FlutterForestController(this);
  }

  @override
  Future<void> onLoad() async {
    await super.onLoad();
    gameRef.addContactCallback(_DashNestBumperBallContactCallback());

    final signpost = Signpost()..initialPosition = Vector2(8.35, -58.3);

    final bigNest = _DashNestBumper.main()
      ..initialPosition = Vector2(18.55, -59.35);
    final smallLeftNest = _DashNestBumper.a()
      ..initialPosition = Vector2(8.95, -51.95);
    final smallRightNest = _DashNestBumper.b()
      ..initialPosition = Vector2(23.3, -46.75);
    final dashAnimatronic = DashAnimatronic()..position = Vector2(20, -66);

    await addAll([
      signpost,
      smallLeftNest,
      smallRightNest,
      bigNest,
      dashAnimatronic,
    ]);
  }
}

class _FlutterForestController extends ComponentController<FlutterForest>
    with HasGameRef<PinballGame> {
  _FlutterForestController(FlutterForest flutterForest) : super(flutterForest);

  final _activatedBumpers = <DashNestBumper>{};

  void activateBumper(DashNestBumper dashNestBumper) {
    if (!_activatedBumpers.add(dashNestBumper)) return;

    dashNestBumper.activate();

    final activatedBonus = _activatedBumpers.length == 3;
    if (activatedBonus) {
      _addBonusBall();

      gameRef.read<GameBloc>().add(const BonusActivated(GameBonus.dashNest));
      _activatedBumpers
        ..forEach((bumper) => bumper.deactivate())
        ..clear();

      component.firstChild<DashAnimatronic>()?.playing = true;
    }
  }

  Future<void> _addBonusBall() async {
    // TODO(alestiago): Remove hardcoded duration.
    await Future<void>.delayed(const Duration(milliseconds: 700));
    await gameRef.add(
      ControlledBall.bonus(theme: gameRef.theme)
        ..initialPosition = Vector2(17.2, -52.7),
    );
  }
}

// TODO(alestiago): Revisit ScorePoints logic once the FlameForge2D
// ContactCallback process is enhanced.
class _DashNestBumper extends DashNestBumper with ScorePoints {
  _DashNestBumper.main() : super.main();

  _DashNestBumper.a() : super.a();

  _DashNestBumper.b() : super.b();

  @override
  int get points => 20;
}

class _DashNestBumperBallContactCallback
    extends ContactCallback<DashNestBumper, Ball> {
  @override
  void begin(DashNestBumper dashNestBumper, _, __) {
    final parent = dashNestBumper.parent;
    if (parent is FlutterForest) {
      parent.controller.activateBumper(dashNestBumper);
    }
  }
}<commit_msg>fix: removed addBonusBall delay (#211)<commit_after>// ignore_for_file: avoid_renaming_method_parameters

import 'package:flame/components.dart';
import 'package:flame_forge2d/flame_forge2d.dart';
import 'package:pinball/game/game.dart';
import 'package:pinball_components/pinball_components.dart';
import 'package:pinball_flame/pinball_flame.dart';

/// {@template flutter_forest}
/// Area positioned at the top right of the [Board] where the [Ball]
/// can bounce off [DashNestBumper]s.
///
/// When all [DashNestBumper]s are hit at least once, the [GameBonus.dashNest]
/// is awarded, and the [DashNestBumper.main] releases a new [Ball].
/// {@endtemplate}
class FlutterForest extends Component
    with Controls<_FlutterForestController>, HasGameRef<PinballGame> {
  /// {@macro flutter_forest}
  FlutterForest() {
    controller = _FlutterForestController(this);
  }

  @override
  Future<void> onLoad() async {
    await super.onLoad();
    gameRef.addContactCallback(_DashNestBumperBallContactCallback());

    final signpost = Signpost()..initialPosition = Vector2(8.35, -58.3);

    final bigNest = _DashNestBumper.main()
      ..initialPosition = Vector2(18.55, -59.35);
    final smallLeftNest = _DashNestBumper.a()
      ..initialPosition = Vector2(8.95, -51.95);
    final smallRightNest = _DashNestBumper.b()
      ..initialPosition = Vector2(23.3, -46.75);
    final dashAnimatronic = DashAnimatronic()..position = Vector2(20, -66);

    await addAll([
      signpost,
      smallLeftNest,
      smallRightNest,
      bigNest,
      dashAnimatronic,
    ]);
  }
}

class _FlutterForestController extends ComponentController<FlutterForest>
    with HasGameRef<PinballGame> {
  _FlutterForestController(FlutterForest flutterForest) : super(flutterForest);

  final _activatedBumpers = <DashNestBumper>{};

  void activateBumper(DashNestBumper dashNestBumper) {
    if (!_activatedBumpers.add(dashNestBumper)) return;

    dashNestBumper.activate();

    final activatedBonus = _activatedBumpers.length == 3;
    if (activatedBonus) {
      _addBonusBall();

      gameRef.read<GameBloc>().add(const BonusActivated(GameBonus.dashNest));
      _activatedBumpers
        ..forEach((bumper) => bumper.deactivate())
        ..clear();

      component.firstChild<DashAnimatronic>()?.playing = true;
    }
  }

  Future<void> _addBonusBall() async {
    await gameRef.add(
      ControlledBall.bonus(theme: gameRef.theme)
        ..initialPosition = Vector2(17.2, -52.7),
    );
  }
}

// TODO(alestiago): Revisit ScorePoints logic once the FlameForge2D
// ContactCallback process is enhanced.
class _DashNestBumper extends DashNestBumper with ScorePoints {
  _DashNestBumper.main() : super.main();

  _DashNestBumper.a() : super.a();

  _DashNestBumper.b() : super.b();

  @override
  int get points => 20;
}

class _DashNestBumperBallContactCallback
    extends ContactCallback<DashNestBumper, Ball> {
  @override
  void begin(DashNestBumper dashNestBumper, _, __) {
    final parent = dashNestBumper.parent;
    if (parent is FlutterForest) {
      parent.controller.activateBumper(dashNestBumper);
    }
  }
}
{'fraction_non_alphanumeric': 0.11890099478919944, 'fraction_numerical': 0.016737723038054635, 'mean_word_length': 4.042993630573249, 'pattern_counts': {'":': 0, '<': 24, '<?xml version=': 0, '>': 28, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4540576', 'n_tokens_mistral': 2244, 'n_tokens_neox': 2129, 'n_words': 400}