package lect78_impl.model; import java.util.List; /** * @overview High Explosive projectile that causes area-of-effect damage */ public class ProjectileHE extends Projectile { private Tank directHitTarget; /** * @effects Initialize this as an HEProjectile with given parameters */ public ProjectileHE(int damage, int angle, Tank source) { super(damage, angle, source); this.directHitTarget = null; } /** * @effects Apply damage to the target tank with area effect */ @Override public void applyDamage(Tank target) { // HE projectiles deal slightly less damage to the primary target // But affect multiple targets in area int finalDamage = Math.max(0, (int)(damage * 0.8) - target.getArmor()); target.takeDamage(finalDamage); System.out.println("HE direct damage: " + finalDamage + " to tank at " + target.getPosition()); // Store the directly hit tank to avoid applying splash damage to it later this.directHitTarget = target; } /** * @effects Apply area damage to all tanks in radius * @param board The game board * @param impactPosition The position where projectile hit */ public void applyAreaDamage(Board board, Position impactPosition) { // Get all tanks in explosion radius int explosionRadius = 2; // Affect tanks within 2 cells List tanksInRadius = board.getTanksInRadius(impactPosition, explosionRadius); System.out.println("HE impact at " + impactPosition + " affecting " + tanksInRadius.size() + " tanks"); for (Tank tank : tanksInRadius) { // Skip the source tank to prevent self-damage // Also skip the directly hit tank to avoid double damage if (tank == source || tank == directHitTarget) { System.out.println("Skipping splash damage for " + (tank == source ? "source tank" : "directly hit tank") + " at " + tank.getPosition()); continue; } // Calculate distance from impact double distance = impactPosition.getDistance(tank.getPosition()); // Damage falls off with distance, but not as severely // Use a slower falloff to make area damage more effective double damageFactor = Math.max(0.3, 1.0 - (distance / (explosionRadius * 1.5))); // Calculate base damage - apply less armor reduction for HE // HE is designed to be effective against lightly armored targets int armorEffectiveness = (int)(tank.getArmor() * 0.7); // Reduce armor effectiveness against HE int finalDamage = Math.max(0, (int)(damage * damageFactor) - armorEffectiveness); // Apply damage if (finalDamage > 0) { tank.takeDamage(finalDamage); System.out.println("HE splash damage: " + finalDamage + " to tank at " + tank.getPosition() + " (distance: " + distance + ", damage factor: " + damageFactor + ")"); } else { System.out.println("HE splash blocked by armor for tank at " + tank.getPosition()); } } } }