Moving attacks to Domain-Driven Design and Entity-Component architecture
Signed-off-by: Hans Kokx <hans.d.kokx@gmail.com>
This commit is contained in:
@@ -1,3 +1,9 @@
|
||||
import 'dart:math' as math;
|
||||
|
||||
import 'package:wolf_dart/classes/linear_coordinates.dart';
|
||||
import 'package:wolf_dart/features/entities/enemies/enemy.dart';
|
||||
import 'package:wolf_dart/features/entities/entity.dart';
|
||||
|
||||
enum WeaponState { idle, firing }
|
||||
|
||||
enum WeaponType { knife, pistol, machineGun, chainGun }
|
||||
@@ -24,7 +30,6 @@ abstract class Weapon {
|
||||
int get currentSprite =>
|
||||
state == WeaponState.idle ? idleSprite : fireFrames[frameIndex];
|
||||
|
||||
/// Core firing logic. Returns true if a bullet was spent.
|
||||
bool fire(int currentTime, {required int currentAmmo}) {
|
||||
if (state == WeaponState.idle && currentAmmo > 0) {
|
||||
state = WeaponState.firing;
|
||||
@@ -47,4 +52,60 @@ abstract class Weapon {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NEW: The weapon calculates its own hits and applies damage!
|
||||
void performHitscan({
|
||||
required double playerX,
|
||||
required double playerY,
|
||||
required double playerAngle,
|
||||
required List<Entity> entities,
|
||||
required bool Function(int x, int y) isWalkable,
|
||||
required int currentTime,
|
||||
required void Function(int scoreToAdd) onEnemyKilled,
|
||||
}) {
|
||||
Enemy? closestEnemy;
|
||||
double minDistance = 15.0;
|
||||
|
||||
for (Entity entity in entities) {
|
||||
if (entity is Enemy && entity.state != EntityState.dead) {
|
||||
double dx = entity.x - playerX;
|
||||
double dy = entity.y - playerY;
|
||||
double angleToEnemy = math.atan2(dy, dx);
|
||||
|
||||
double angleDiff = playerAngle - angleToEnemy;
|
||||
while (angleDiff <= -math.pi) {
|
||||
angleDiff += 2 * math.pi;
|
||||
}
|
||||
while (angleDiff > math.pi) {
|
||||
angleDiff -= 2 * math.pi;
|
||||
}
|
||||
double dist = math.sqrt(dx * dx + dy * dy);
|
||||
double threshold = 0.2 / dist;
|
||||
|
||||
if (angleDiff.abs() < threshold) {
|
||||
LinearCoordinates source = (x: playerX, y: playerY);
|
||||
|
||||
// Delegate to the enemy to check if it's visible
|
||||
if (entity.hasLineOfSightFrom(
|
||||
source,
|
||||
playerAngle,
|
||||
dist,
|
||||
isWalkable,
|
||||
)) {
|
||||
if (dist < minDistance) {
|
||||
minDistance = dist;
|
||||
closestEnemy = entity;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (closestEnemy != null) {
|
||||
closestEnemy.takeDamage(damage, currentTime);
|
||||
if (closestEnemy.state == EntityState.dead) {
|
||||
onEnemyKilled(100);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user