package vooga.fighter.model.objects; import java.util.ArrayList; import java.util.List; import java.util.Map; import util.Location; import util.Vector; import vooga.fighter.model.ModelConstants; import vooga.fighter.model.loaders.AttackObjectLoader; import vooga.fighter.model.utils.Counter; import vooga.fighter.model.utils.Effect; import vooga.fighter.model.utils.State; import vooga.fighter.model.utils.UpdatableLocation; /** * Object that can inflict damage on other moveable game objects * * @author James Wei, alanni, David Le * */ public class AttackObject extends GameObject { private Counter myCounter; private GameObject myOwner; private List<Effect> myEffects; /** * Constructs an AttackObject with the given owner. * * @param name of the attack object as labeled in its respective xml * @param pathHierarchy is the path to the game resources folder */ public AttackObject (String name, String pathHierarchy) { super(); myEffects = new ArrayList<Effect>(); myCounter = new Counter(); setLoader(new AttackObjectLoader(name, this, pathHierarchy)); setToDefaultState(); } /** * Creates a deep copy of attack object based on other attack object and character location. * * @param other is the other AttackObject to deep copy * @param center is the location of the new AttackObject */ public AttackObject (AttackObject other, UpdatableLocation center) { super(); addProperty(ModelConstants.ATTACK_PROPERTY_SPEED, other.getProperty(ModelConstants.ATTACK_PROPERTY_SPEED)); addProperty(ModelConstants.ATTACK_PROPERTY_DIRECTION, other.getProperty(ModelConstants.ATTACK_PROPERTY_DIRECTION)); addProperty(ModelConstants.ATTACK_PROPERTY_DAMAGE, other.getProperty(ModelConstants.ATTACK_PROPERTY_DAMAGE)); addProperty(ModelConstants.ATTACK_PROPERTY_DURATION, other.getProperty(ModelConstants.ATTACK_PROPERTY_DURATION)); this.myEffects = other.myEffects; this.myOwner = other.myOwner; this.myCounter = new Counter(getProperty(ModelConstants.ATTACK_PROPERTY_DURATION)); setLocation(center); copyStates(other); setCurrentState(other.getCurrentStateKey()); addStartingAcceleration(); setImageData(); } /** * Creates a deep copy of another AttackObject's state map and sets it as this * object's state map. * @param other is the AttackObject to copy states from. */ public void copyStates(AttackObject other) { Map<String, State> otherStates = other.getStates(); for (String key : otherStates.keySet()) { State otherState = otherStates.get(key); State newState = new State(otherState); newState.setOwner(this); addState(key, newState); } } /** * Move the attack object to the position of its owner. */ public void moveToOwner() { UpdatableLocation copyLocation = myOwner.getLocation(); UpdatableLocation myLocation = getLocation(); Location newLocation = new Location(copyLocation.getLocation()); myLocation.setLocation(newLocation); } /** * Updates the attack object by decreasing its counter. */ @Override public void completeUpdate(){ myCounter.decrementCounter(); } /** * No functionality for update state as of now */ public void updateState(){ } /** * Adds the initial acceleration of the attack object to the location's list * of accelerations. */ public void addStartingAcceleration() { int direction = getProperty(ModelConstants.ATTACK_PROPERTY_DIRECTION); int speed = getProperty(ModelConstants.ATTACK_PROPERTY_SPEED); Vector acceleration = new Vector(direction, speed); getLocation().addAcceleration(acceleration); } /** * Adds an effect to myEffects * @param toAdd is the effect to add to the list */ public void addEffect(Effect toAdd) { myEffects.add(toAdd); } /** * Returns the list of effects carried by this object. */ public List<Effect> getEffects() { return myEffects; } /** * Gets the character who created the attack */ public GameObject getOwner() { return myOwner; } /** * Sets the owner to the creator of the attack * @param owner is the ownern of this attack */ public void setOwner(CharacterObject owner) { myOwner = owner; } /** * Sets the owner for effects * @param owner is the owner for the effects */ public void setOwnerForEffects(CharacterObject owner) { for (Effect effect: myEffects) { effect.setOwner(owner); } } /** * Inflicts damage upon a target player. * @param target is the character taking damage from this object */ public int inflictDamage(CharacterObject target) { int damage = getProperty(ModelConstants.ATTACK_PROPERTY_DAMAGE); return target.changeHealth(-damage); } /** * Designates a character as a target of this attack's effects. * @param target is the target to add this attack's effects to */ public void addTargetForEffects(CharacterObject target) { for (Effect effect : myEffects) { Effect copyOfEffect = effect.getCloneOfEffect(); target.addActiveEffect(copyOfEffect); } } /** * Sets the counter to the current amount * @param amount is the value to set the counter to */ public void setCounter(int amount) { myCounter.setCounter(amount); } /** * Sets the counter to zero. */ public void endCounter() { setCounter(ModelConstants.ATTACK_COUNTER_ZERO); } /** * Returns true if this attack object has expired. */ @Override public boolean shouldBeRemoved() { return !myCounter.hasCountRemaining(); } }