package vooga.towerdefense.action.attack;
import vooga.towerdefense.action.TargetedAction;
import vooga.towerdefense.attributes.Attribute;
import vooga.towerdefense.factories.elementfactories.GameElementFactory;
import vooga.towerdefense.gameelements.GameElement;
import vooga.towerdefense.model.GameMap;
import util.Location;
/**
* Creates projectiles aimed at a target. Targets info pass on to projectiles
* created. Projectiles created gave its own follow up action predfined by XML.
*
* @author Xu Rui
*/
public class ShootProjectile extends TargetedAction {
private Attribute myUnitsRemaining;
private Attribute myNumShots;
private Attribute myCooldown;
private GameElementFactory myProjectileFactory;
private Location mySource;
private GameMap myMap;
private double myTimer;
private boolean targetDetectionOn; // true if fire only upon target
// detection
public ShootProjectile(Attribute cooldown, Attribute numProjectiles,
Attribute numShots, Location startLocation,
GameElementFactory projectileFactory, GameMap map,
boolean targetdetection) {
super();
myCooldown = cooldown;
myUnitsRemaining = numProjectiles;
myNumShots = numShots;
mySource = startLocation;
myProjectileFactory = projectileFactory;
myMap = map;
myTimer = 0;
targetDetectionOn = targetdetection;
}
@Override
public void update(double elapsedTime) {
setEnabled(checkLaunchCondition());
if (isEnabled()) {
executeAction(elapsedTime);
}
}
@Override
public void executeAction(double elapsedTime) {
if (myTimer > myCooldown.getValue()) {
spawnProjectile((int) myNumShots.getValue());
myTimer = 0;
}
myTimer += elapsedTime;
}
/**
* Returns true only if remaining projectiles >0 and there are targets.
*
* @return
*/
public boolean checkLaunchCondition() {
boolean checker = !(myUnitsRemaining.getValue() <= 0);
if (targetDetectionOn) {
checker = checker && !getTargets().isEmpty();
}
return checker;
}
/**
* Creates a projectile with action of shooting at targets.
*
* @param elapsedTime
*/
public void spawnProjectile(int num) {
int n = num;
while (n > 0) {
GameElement projectile = myProjectileFactory
.createElement(mySource);
for (TargetedAction a : projectile.getTargetedActions()) {
a.setSingleTarget(getSingleTarget());
}
myMap.addGameElement(projectile);
myUnitsRemaining.modifyValue(-1);
n--;
}
}
}