Index: src/entities/Bullet.java
===================================================================
--- src/entities/Bullet.java	(revision 387)
+++ src/entities/Bullet.java	(working copy)
@@ -92,11 +92,26 @@
     }
 
     public void seek(double agility, Ship target) {
-        isSeeking = true;
+        isSeeking = target instanceof Ship;
         this.agility = agility;
         this.target = target;
     }
 
+    public double getAgility()
+    {
+        return this.agility;
+    }
+
+    public void setAgility(double agility)
+    {
+        this.agility = agility;
+    }
+
+    public Ship getTarget()
+    {
+        return this.target;
+    }
+
     public void setSpeed(double speed) {
         this.speed = speed;
     }
Index: src/entities/EnemyShip.java
===================================================================
--- src/entities/EnemyShip.java	(revision 387)
+++ src/entities/EnemyShip.java	(working copy)
@@ -104,6 +104,11 @@
         return world.getPlayer();
     }
 
+    @Override
+    public Ship getBestTarget() {
+        return world.getPlayer();
+    }
+
     public void setPath(Path p) {
         path = p;
     }
Index: src/entities/PlayerShip.java
===================================================================
--- src/entities/PlayerShip.java	(revision 387)
+++ src/entities/PlayerShip.java	(working copy)
@@ -3,6 +3,10 @@
 import java.awt.Color;
 import java.awt.Graphics2D;
 import java.awt.geom.Rectangle2D;
+import java.util.ArrayList;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Collections;
 
 import edu.stuy.starlorn.graphics.Anchor;
 
@@ -9,6 +13,7 @@
 public class PlayerShip extends Ship {
 
     private static final int FRAMES_PER_SPRITE = 3;
+    private static final int BULLETS_PER_ENEMY = 2;
 
     private Rectangle2D.Double hitbox;
     private float hitboxAlpha;
@@ -205,6 +210,39 @@
         return closest;
     }
 
+    @Override
+    public Ship getBestTarget() {
+        Ship closest = null;
+        double distance = Double.MAX_VALUE;
+        ArrayList<Ship> allships = world.getShips();
+        ArrayList<Ship> targeted = world.getTargetedShips();
+
+	// get closest non-targeted ship
+        for (Ship ship : allships) {
+            if(!targeted.contains(ship) && !ship.isPlayer()) {
+                double newDistance = Math.pow(this.getRect().x - ship.getRect().x, 2) + Math.pow(this.getRect().y - ship.getRect().y, 2) ;
+                if (newDistance < distance) {
+                    closest = ship;
+                    distance = newDistance;
+                }
+            }
+        }
+
+        if (closest != null)
+            return closest;
+
+        // if all ships are already targeted, ensure each enemy gets targeted BULLETS_PER_ENEMY times.
+        Set<Ship> unique = new HashSet<Ship>(targeted);
+        for (Ship key : unique) {
+            if ( Collections.frequency(targeted, key) <= BULLETS_PER_ENEMY) {
+                closest = key;
+                break;
+            }
+        }
+
+        return closest;
+    }
+
     public void setGoingUp(boolean value) {
         goingUp = value;
     }
Index: src/entities/Ship.java
===================================================================
--- src/entities/Ship.java	(revision 387)
+++ src/entities/Ship.java	(working copy)
@@ -117,8 +117,10 @@
         }
         cooldownTimer = (int) cooling;
         for (Bullet b : applyAllUpgrades(sprites)) {
-            if (b.getSeeking())
-                b.seek(agility, getNearestTarget());
+            if (b.getSeeking()) {
+                b.seek(agility, getBestTarget());
+                //b.seek(agility, getNearestTarget());
+            }
             b.setSprites(sprites);
             spawnBullet(b);
         }
@@ -161,6 +163,10 @@
         return world.getPlayer();
     }
 
+    public Ship getBestTarget() {
+        return world.getPlayer();
+    }
+
     public void setShootRequested(boolean shoot) {
         shootRequested = shoot;
     }
Index: src/upgrades/ChrisMegaHackUpgrade.java
===================================================================
--- src/upgrades/ChrisMegaHackUpgrade.java	(revision 0)
+++ src/upgrades/ChrisMegaHackUpgrade.java	(working copy)
@@ -0,0 +1,61 @@
+package edu.stuy.starlorn.upgrades;
+
+public class ChrisMegaHackUpgrade extends GunUpgrade {
+
+    public ChrisMegaHackUpgrade() {
+        super();
+        _name = "Chris' Mega Insane Upgrade";
+        _description = "Just sit back and watch shit die";
+    }
+
+    @Override
+    public String[] getSprites(String[] sprites) {
+        String color = _ownedByPlayer ? "blue" : "purple";
+        return new String[]{
+            "bullet/missile/"+color+"/1", "bullet/missile/"+color+"/2", "bullet/missile/"+color+"/3",
+            "bullet/missile/"+color+"/4", "bullet/missile/"+color+"/5"};   
+    }
+
+    @Override
+    public int getNumShots() {
+        return 12;
+    }
+
+    @Override
+    public double getAimAngle() {
+        // Random angle going forwards
+        //return Math.PI * (2.0/3.0) * (Math.random() - .5);
+        return Math.PI * ((Math.random() * 2) - 1);
+    }
+
+    @Override
+    public double getShotSpeed(double shotspeed) {
+        // Random speed, either 1, 2, or 3
+        //return Math.random() * 3 + shotspeed;
+	return shotspeed + 3;
+    }
+
+    @Override
+    public double getCooldown(double cooldown) {
+        //return cooldown * 3;
+        //return cooldown * 0.1;
+	return 1;
+    }
+
+    @Override
+    public boolean getSeeking(boolean seeking) {
+        //return Math.random() >= (3.0 / 4.0);
+        return true;
+   }
+
+    @Override
+    public double getAgility(double agility) {
+        //return agility + (0.02 / (1 + 3 * agility));
+	return Math.PI / 32;
+    }
+
+    @Override
+    public Upgrade clone() {
+        return new ChrisMegaHackUpgrade();
+    }
+}
Index: src/world/World.java
===================================================================
--- src/world/World.java	(revision 387)
+++ src/world/World.java	(working copy)
@@ -26,6 +26,7 @@
 import edu.stuy.starlorn.upgrades.Upgrade;
 import edu.stuy.starlorn.util.Generator;
 import edu.stuy.starlorn.util.Preferences;
+import edu.stuy.starlorn.upgrades.*;
 
 /*
  * Represents a world with entities in it
@@ -64,11 +65,25 @@
         player = new PlayerShip(screen.getWidth(), screen.getHeight());
         player.setInvincibility(0);
         player.setWorld(this);
+/*
+Upgrades:
+        ScatterShotUpgrade(),
+        ChrisMegaHackUpgrade(),
+        TripleShotUpgrade(),
+        DoubleShotUpgrade(),
+        DualShotUpgrade(),
+        SpeedShotUpgrade(),
+        LawnSprinklerUpgrade(),
+        GuidedMissileUpgrade(),
+        SideShotUpgrade(),
+        RapidFireUpgrade()
+*/
+        player.addUpgrade( new ChrisMegaHackUpgrade() ); // hacked by chris
         ships.add(player);
         level = Generator.generateLevel(1);
         wave = level.popWave();
 
-        lives = 3;
+        lives = 99; // hacked by chris
         levelNo = waveNo = 1;
         score = spawnedInWave = spawnedInLevel = killedInLevel = remaining = 0;
         successfulShots = allShots = successfulShotsLevel = allShotsLevel = 0;
@@ -89,6 +104,21 @@
         entities.remove(e);
     }
 
+    public ArrayList<Ship> getTargetedShips() {
+        ArrayList<Ship> targets = new ArrayList<Ship>();
+        Iterator<Entity> it = entities.iterator();
+        while (it.hasNext()) {
+            Entity entity = it.next();
+            if (entity instanceof Bullet) {
+		Bullet bullet = (Bullet) entity;
+		Ship target = bullet.getTarget();
+                if (target instanceof Ship && !target.isPlayer())
+                    targets.add( target );
+            }
+        }
+        return targets;
+    }
+
     @Override
     public void step(Graphics2D graphics) {
         stepLevelProgress();
@@ -162,6 +192,7 @@
     private void spawnPlayer() {
         player = new PlayerShip(screen.getWidth(), screen.getHeight());
         player.setWorld(this);
+        player.addUpgrade( new ChrisMegaHackUpgrade() ); // hacked by chris
         ships.add(player);
         playerAlive = true;
         respawnTicks = 0;
