package vooga.rts.gamedesign.strategy.attackstrategy; import java.util.ArrayList; import java.util.List; import vooga.rts.gamedesign.sprite.gamesprites.IAttackable; import vooga.rts.gamedesign.sprite.gamesprites.Projectile; import vooga.rts.gamedesign.sprite.gamesprites.interactive.InteractiveEntity; import vooga.rts.gamedesign.strategy.Strategy; import vooga.rts.gamedesign.weapon.Weapon; import vooga.rts.util.Location3D; /** * This class implements AttackStrategy and is used as an instance in * InteractiveEntity for objects that are able to attack. The attack method in * this class will specify how the interactive will attack. * * @author Ryan Fishel * @author Kevin Oh * @author Francesco Agosti * @author Wenshun Liu * */ public class CanAttack implements AttackStrategy { private static final Location3D DEFAULTLOCATION = new Location3D(0, 0, 0); private static final int DEFAULTTEAM = 0; private List<Weapon> myWeapons; private int myWeaponIndex; /** * Creates a new attack strategy that represents an entity that can attack. * This strategy is created with a weapon so that the entity will be able * to attack. * * @param worldLocation is the location of the entity that has this * strategy (it is needed for the position of the weapon) * @param PlayerID is the team that the entity with this strategy is on */ public CanAttack (Location3D worldLocation, int PlayerID) { myWeapons = new ArrayList<Weapon>(); myWeaponIndex = 0; } public CanAttack () { this(DEFAULTLOCATION, DEFAULTTEAM); } /** * Attacks the given IAttackable object by first judging whether the Weapon * is in range for the attack action. * * @param enemy the IAttackable object being attacked. * @param distance the distance between the CanAttack object and the enemy. */ public void attack (IAttackable enemy, double distance) { if (inWeaponRange((InteractiveEntity) enemy, distance)) { myWeapons.get(myWeaponIndex).fire((InteractiveEntity) enemy); } } public void setWeaponLocation (Location3D newLocation) { for (Weapon weapon : myWeapons) { weapon.setCenter(newLocation); } } /** * Determines if the IAttackable object is in the range of the currently * activated Weapon. * * @param enemy the IAttackable object being attacked. * @param distance the distance between the CanAttack object and the enemy. * @return whether the IAttackable object is in the range of the currently * activated Weapon. */ private boolean inWeaponRange (InteractiveEntity enemy, double distance) { return (!myWeapons.isEmpty() && myWeapons.get(myWeaponIndex).inRange(enemy, distance)); } /** * Returns the list of Weapon stored in this CanAttack object. * * @return the list of Weapon stored */ public List<Weapon> getWeapons () { return myWeapons; } /** * Sets myWeapons to the new list of weapons. */ public void setWeapons (List<Weapon> newWeapons) { myWeapons = newWeapons; } /** * Returns the index of the Weapon that's currently been activated in the * list of Weapons belonged to this CanAttack object. * * @return the index of the Weapon that's currently been activated */ public int getWeaponIndex () { return myWeaponIndex; } /** * Changes the currently activated Weapon by setting its index as * WeaponIndex. * * @param weaponIndex */ public void setWeaponIndex (int weaponIndex) { myWeaponIndex = weaponIndex; } /** * Adds a Weapon to the list of Weapons belonged to this AttackStrategy. * * @param weapon the new Weapon to be added into the list. */ public void addWeapon (Weapon weapon) { myWeapons.add(weapon); } public Weapon getCurrentWeapon () { return myWeapons.get(myWeaponIndex); } public boolean hasWeapon () { return true; } public void copyStrategy (InteractiveEntity other) { CanAttack toAdd = new CanAttack(); toAdd.setWeaponIndex(0); toAdd.setWeapons(this.getWeaponCopies()); other.setAttackStrategy(toAdd); } private List<Weapon> getWeaponCopies () { ArrayList<Weapon> weaponList = new ArrayList<Weapon>(); for (Weapon w : myWeapons) { weaponList.add(w.copy()); } return weaponList; } @Override public void setPlayerID (int playerID) { for (Weapon weapon : myWeapons) { weapon.getProjectile().setPlayerID(playerID); } } }