import 'dart:math' as math; import 'package:wolf_dart/classes/linear_coordinates.dart'; import 'package:wolf_dart/features/entities/collectible.dart'; import 'package:wolf_dart/features/player/weapon.dart'; import 'package:wolf_dart/features/player/weapons/knife.dart'; import 'package:wolf_dart/features/player/weapons/machine_gun.dart'; import 'package:wolf_dart/features/player/weapons/pistol.dart'; class Player { // Spatial double x; double y; double angle; // Stats int health = 100; int ammo = 8; int score = 0; // Inventory bool hasGoldKey = false; bool hasSilverKey = false; bool hasMachineGun = false; bool hasChainGun = false; // Weapon late Weapon currentWeapon; final List availableWeapons = []; Player({ required this.x, required this.y, required this.angle, }) { // Start with Knife and Pistol availableWeapons.add(Knife()); availableWeapons.add(Pistol()); currentWeapon = availableWeapons[1]; } // Helper getter to interface with the RaycasterPainter LinearCoordinates get position => (x: x, y: y); // Helper methods to keep state manipulation safe void takeDamage(int damage) { health = math.max(0, health - damage); if (health <= 0) { print("YOU DIED!"); } else { print("Ouch! ($health)"); } } void heal(int amount) { final int newHealth = math.min(100, health + amount); if (health < 100) { print("Feelin' better. ($newHealth)"); } health = newHealth; } void addAmmo(int amount) { final int newAmmo = math.min(99, ammo + amount); if (ammo < 99) { print("Hell yeah. ($newAmmo)"); } ammo = newAmmo; } bool tryPickup(Collectible item) { bool pickedUp = false; switch (item.type) { case CollectibleType.health: if (health >= 100) return false; // Map IDs 47 (Dog Food) and 48 (Medkit) heal(item.mapId == 47 ? 4 : 25); pickedUp = true; break; case CollectibleType.ammo: if (ammo >= 99) return false; addAmmo(8); pickedUp = true; break; case CollectibleType.treasure: // Score values for Cross (52), Chalice (53), Chest (54), Crown (55) if (item.mapId == 52) score += 100; if (item.mapId == 53) score += 500; if (item.mapId == 54) score += 1000; if (item.mapId == 55) score += 5000; if (item.mapId == 56) { // 1-Up heal(100); addAmmo(25); } pickedUp = true; break; case CollectibleType.weapon: if (item.mapId == 50) hasMachineGun = true; if (item.mapId == 51) hasChainGun = true; pickedUp = true; break; case CollectibleType.key: if (item.mapId == 43) hasGoldKey = true; if (item.mapId == 44) hasSilverKey = true; pickedUp = true; break; } return pickedUp; } void fire(int currentTime) { // Only spend ammo if the weapon isn't a knife bool shotFired = currentWeapon.fire(currentTime, currentAmmo: ammo); if (shotFired && currentWeapon is! Knife) { ammo--; } } /// Returns true only on the specific frame where the hit should be calculated bool updateWeapon(int currentTime) { int oldFrame = currentWeapon.frameIndex; currentWeapon.update(currentTime); // In your Pistol (Indices 212-215), Index 213 is the flash. // This translates to frameIndex == 1 in our fireFrames list. if (currentWeapon.state == WeaponState.firing && oldFrame == 0 && currentWeapon.frameIndex == 1) { return true; } return false; } // Logic to switch weapons (e.g., picking up the Machine Gun) void equipBestWeapon() { if (hasChainGun) { /* set chain gun */ } else if (hasMachineGun) { currentWeapon = MachineGun(); } } }