/** * WaveManager.java */ package rampancy_old.management; import rampancy_old.*; import rampancy_old.util.*; import java.util.*; import java.awt.*; import java.awt.geom.Point2D; import robocode.*; /** * This class manages collections of {@link EnemyWave} and {@link BulletWave} * @author Matthew Chun-Lum * */ public class WaveManager implements EnemyListener, TargetingManagerListener { private ArrayList<EnemyWave> enemyWaves; private ArrayList<BulletWave> bulletWaves; private RampantRobot reference; /** * Default constructor */ public WaveManager() { } /** * Sets the initial state by assigning the reference * and dumping the old wave arrays. * @param reference */ public void setInitialState(RampantRobot reference) { this.reference = reference; enemyWaves = new ArrayList<EnemyWave>(); bulletWaves = new ArrayList<BulletWave>(); } public void createVirtualWave(EnemyRobot enemy) { if(enemyWaves.isEmpty()) enemyWaves.add(enemy.getVirtualBullet()); } /** * @return the closest EnemyWave that we could surf */ public EnemyWave getClosestEnemyWave() { double closest = 10000000; EnemyWave closestWave = null; for(EnemyWave wave : enemyWaves) { double dist = wave.distanceFrom(reference.getLocation()); if(dist > wave.getVelocity() && dist < closest) { closestWave = wave; closest = dist; } } return closestWave; } /** * @param location * @return the enemy wave that will hit first. * This is not necessarily the closest wave since * a faster wave will hit us first. */ public EnemyWave getClosestEnemyWaveToImpact(Point2D.Double location) { return getClosestEnemyWaveToImpact(location, null); } /** * @param location * @param ignoreWave * @return the enemy wave that will hit first. * This is not necessarily the closest wave since * a faster wave will hit us first. */ public EnemyWave getClosestEnemyWaveToImpact(Point2D.Double location, EnemyWave ignoreWave) { return getClosestEnemyWaveToImpact(location, ignoreWave, 0); } /** * @param location * @param ignoreWave * @param timeOffset * @return the enemy wave that will hit first. * This is not necessarily the closest wave since * a faster wave will hit us first. */ public EnemyWave getClosestEnemyWaveToImpact(Point2D.Double location, EnemyWave ignoreWave, long timeOffset) { long timeToImpact = 1000000; EnemyWave closest = null; for(EnemyWave wave : enemyWaves) { if(ignoreWave == null || !wave.equals(ignoreWave)) { long time = wave.timeToImpact(location, timeOffset); if(time < timeToImpact && time >= 0) { closest = wave; timeToImpact = time; } } } return closest; } public int getNumWaves() { return enemyWaves.size(); } /** * Processes a bullet hit event. * Finds the wave that hit us and passes the information * on to the statistics manager * @param e */ public void processHitEvent(HitByBulletEvent e) { if(!enemyWaves.isEmpty()) { Point2D.Double hitLocation = new Point2D.Double(e.getBullet().getX(), e.getBullet().getY()); EnemyWave hitWave = null; for(EnemyWave wave : enemyWaves) { if(Math.abs(wave.getDistanceTraveled() - reference.getLocation().distance(wave.getOrigin())) < 50 && Math.round(Util.computeBulletVelocity(e.getBullet().getPower()) * 10) == Math.round(wave.getVelocity() * 10)) { hitWave = wave; break; } } if(hitWave != null) { reference.getStatisticsManager().processHitByBulletEvent(e.getName(), hitWave, hitLocation); enemyWaves.remove(hitWave); } } } /** * Updates the waves in the list */ public void update() { for(int i = enemyWaves.size() - 1; i >= 0; i--) { EnemyWave wave = enemyWaves.get(i); wave.update(reference.getTime()); if(wave.didBreak(reference.getLocation())) { //reference.getStatisticsManager().getMovementStatsForEnemy(wave.getCreator().getName()).logVirtualHit(wave, reference.getLocation()); enemyWaves.remove(i); } } for(int i = bulletWaves.size() - 1; i >= 0; i--) { BulletWave wave = bulletWaves.get(i); if(wave.checkHit(reference.getTime())) bulletWaves.remove(i); } } /** * If an enemy has been updated, check if it has fired. * If it has, then add the wave to the list of EnemyWaves */ public void enemyUpdated(EnemyRobot enemy) { if(enemy.hasFired()) { removeVirtualWaves(); enemyWaves.add(0, enemy.getLastShot()); } } /* (non-Javadoc) * @see rampancy.management.TargetingManagerListener#bulletFired(rampancy.util.BulletWave) */ public void bulletFired(BulletWave wave) { bulletWaves.add(wave); } /* (non-Javadoc) * @see rampancy.management.TargetingManagerListener#bulletsFired(java.util.ArrayList) */ public void bulletsFired(ArrayList<BulletWave> waves) { bulletWaves.addAll(waves); } /** * Draws the waves * @param g */ public void draw(Graphics2D g) { for(EnemyWave wave : enemyWaves) wave.draw(g); for(BulletWave wave : bulletWaves) wave.draw(g); } // --------------- Private ---------------- // /* * Removes the virtual waves from the list */ private void removeVirtualWaves() { Iterator<EnemyWave> waves = enemyWaves.iterator(); while(waves.hasNext()) { EnemyWave wave = waves.next(); if(wave.isVirtual()) waves.remove(); } } }