/**
*
*/
package org.timerescue.action;
import org.timerescue.element.Coordinate;
import org.timerescue.element.agent.Agent;
import org.timerescue.element.agent.PropertyHolder;
import org.timerescue.element.agent.StateHolder;
import org.timerescue.element.agent.Agent.Constants;
import org.timerescue.exception.InvalidPropertyException;
import org.timerescue.exception.InvalidSerialException;
import org.timerescue.information.InformationParameters;
/**
* This is the default attack action, it is meant to
* trigger an state "attacking" to the user
* @author chamanx
*
*/
public class DefaultAttackAction extends Action{
/*
* Non Serial properties
*/
/**
* Radio distance in which the target needs to be
* for be suitable for an attack
*/
private int range;
/*
* Methods
*/
//TODO setters for properties
/**
* Default constructor
* @param source
*/
public DefaultAttackAction() {
super();
setRange(Constants.Default.RANGE);
}
/**
* Get the targeted agent
* @return target
*/
public Agent getTarget() {
try {
return (Agent) getParam(
DefaultAttackAction.Constants.Parameter.TARGET);
} catch (InvalidPropertyException e) { }
return null;
}
/**
* Get the attacker agent
* @return
*/
public Agent getAttacker() {
try {
return (Agent) getParam(
DefaultAttackAction.Constants.Parameter.ATTACKER);
} catch (InvalidPropertyException e) { }
return null;
}
/**
* Get range of attack
* @return
*/
public int getRange() {
return range;
}
/**
* Sets the attacker
* @param attacker
*/
public void setTarget(Agent target) {
this.addParamData(
Constants.Parameter.TARGET,
target);
}
/**
* Sets the attacker
* @param attacker
*/
public void setAttacker(Agent attacker) {
this.addParamData(
Constants.Parameter.ATTACKER,
attacker);
}
/**
* Sets the attacker
* @param attacker
*/
public void setRange(int range) {
this.range = range;
}
@Override
protected InformationParameters executeEnvironment() {
// TODO Auto-generated method stub
return null;
}
@Override
protected InformationParameters executeAgent() {
Agent target = null, attacker = null;
int range = 0, target_life, attacker_attack, target_defense, speed;
PropertyHolder target_property_holder, attacker_property_holder;
StateHolder target_state_holder, attacker_state_holder;
//Get target and the attacker
target = getTarget();
attacker = getAttacker();
//states holders
target_state_holder = target.getState_holder();
attacker_state_holder = attacker.getState_holder();
//Range
range = getRange();
Coordinate target_position = target.getCoordinate(),
attacker_position = attacker.getCoordinate();
//Properties
target_property_holder = target.getProperty_holder();
attacker_property_holder = attacker.getProperty_holder();
//TODO Is the target visible?
int visibility = attacker.getVisibility();
if(target_position.isClose(attacker_position, visibility)){
//If the target is close enough for a close range attack
if (target_position.isClose(attacker_position, range)){
//Attack the target properties!
target_life = target.getLife();
if(target_life > 0) {//is it alive?
//TODO define a method to obtain the properties casted
//TODO Define a practical formulas, this is just for testing
target_defense = target.getArmor();
attacker_attack = attacker.getStrength()* 2;
target_life -= attacker_attack - target_defense;
target.setLife(target_life);
//Add states
target_state_holder.addState(this);
attacker_state_holder.addState(this);
return this;
}else{
//Remove states if the target is dead
removeStates();
}
}else{ //It's too far, lets get closer
speed = attacker.getSpeed();
attacker.move(target.getCoordinate(), speed);
}
}else{
//Remove states if the target is far away
removeStates();
}
return null;
}
@Override
protected InformationParameters executeOther() {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean removeStates() {
Agent target = null, attacker = null;
StateHolder target_state_holder, attacker_state_holder;
try {
target = getTarget();
attacker = getAttacker();
target_state_holder = target.getState_holder();
attacker_state_holder = attacker.getState_holder();
target_state_holder.removeState(this);
attacker_state_holder.removeState(this);
} catch (Exception e) {
// TODO Log this
return false;
}
return true;
}
@Override
public String toSerial() {
// TODO add range
return super.toSerial();
}
@Override
public void fromSerial(String serialized) throws InvalidSerialException {
// TODO add range
super.fromSerial(serialized);
}
/**
* Constants
*/
public static class Constants{
/**
* Default values
*/
public static class Default{
public static int RANGE = 1;
}
/**
* Parameters that are expected to be included for this action
*/
public static class Parameter{
/**
* This is the target for the attack
*/
public static final String TARGET = "TARGET";
/**
* This is the agent which must execute the action
*/
public static final String ATTACKER = "ATTACKER";
}
}
}