package com.iBaby;
import java.lang.reflect.Field;
import java.util.ArrayList;
import org.bukkit.Material;
import org.bukkit.craftbukkit.inventory.CraftItemStack;
import net.minecraft.server.ItemStack;
import net.minecraft.server.PathfinderGoalMeleeAttack;
import net.minecraft.server.PathfinderGoalMoveTowardsTarget;
import net.minecraft.server.PathfinderGoalSelector;
import com.iBaby.abilities.Ability;
import com.iBaby.abilities.ArmorAbility;
import com.iBaby.abilities.DamageAbility;
import com.iBaby.abilities.SprintAbility;
import com.iBaby.abilities.ThrowAbility;
import com.iBaby.reflection.EntityIronBaby;
import com.iBaby.reflection.PathfinderFollowBaby;
/**
* Class which manages all special abilities of iBabys
* @author steffengy
*
*/
public class iBabyAbilities {
private ArrayList<Ability> abilities = new ArrayList<Ability>();
private EntityIronBaby entity;
/**
* Public Constructor
* @param baby The entity which represents an iBaby
*/
public iBabyAbilities(EntityIronBaby baby) {
this.entity = baby;
}
/**
* Adds an ability
* @param ability instanceof Ability
*/
public void addAbility(Ability ability) {
abilities.add(ability);
}
/**
* Removes an ability
* @param ability instanceof Ability
*/
public void removeAbility(Ability ability) {
abilities.remove(ability);
}
/**
* Gets the additional maximum health of an entity
* @return int
*/
public int getAdditionalHealth() {
int basic = 0;
for(Ability ability : abilities) {
basic += ability.getAdditionalHealth();
}
return basic;
}
/**
* Gets the additional damage of an entity
* @return int
*/
public int getAdditionalDamage() {
int basic = 0;
for(Ability ability : abilities) {
basic += ability.getAdditionalDamage();
}
return basic;
}
/**
* Gets the additional height, the golem will throw entitys
* @return Float, see above
*/
public float getAdditionalThrowHeight() {
float basic = 0;
for(Ability ability : abilities) {
basic += ability.getAdditionalThrowHeight();
}
return basic;
}
/**
* Gets the additional movement speed, the golem will do on melee attacks
* @return float, see above
*/
public float getAdditionalMeleeMovementSpeed() {
float basic = 0;
for(Ability ability : abilities) {
basic += ability.getAdditionalMeleeMovementSpeed();
}
return basic;
}
/**
* Gets the additional movement speed, the golem will have while moving towards a target
* @return float, see above
*/
public float getAdditionalMoveTowardsTargetSpeed() {
float basic = 0;
for(Ability ability : abilities) {
basic += ability.getAdditionalMoveTowardsTargetSpeed();
}
return basic;
}
/**
* Gets the additional movement speed, the golem will have while following its baby (baby = the player (owner))
* @return float, see above
*/
public float getAdditionalFollowBabySpeed() {
float basic = 0;
for(Ability ability : abilities) {
basic += ability.getAdditionalFollowBabySpeed();
}
return basic;
}
/**
* Match abilities - Items
* @param itemstack
*/
public void updateAbilities(ItemStack itemstack, boolean add) {
Ability handle = null;
Ability tmp = null;
/*
* @ABILITY
* Feather : ThrowAbility
*/
if(new CraftItemStack(itemstack).getType() == Material.FEATHER) {
handle = new ThrowAbility();
}
/**
* @ABILITY
* Water-Bucket:Sprint
*/
else if(new CraftItemStack(itemstack).getType() == Material.WATER_BUCKET) {
handle = new SprintAbility();
}
/**
* @ABILITY
* Armor: ArmorAbility
* Calculation of Damage Value: Durabilty / 9
* or if cheap (@NERF) material Durability / 14
* or if too OP (@NERF2) material Durability / 20
*/
else if((tmp = ArmorAbility.matches(itemstack)) != null) {
handle = tmp;
}
/**
* @ABILITY
* Weapons: DamageAbility
* Calculation of Damage Value: hearts NO FLOATS
*/
else if((tmp = DamageAbility.matches(itemstack)) != null) {
handle = tmp;
}
if(handle != null) {
if(add)
this.addAbility(handle);
else
this.removeAbility(handle);
}
updatePathFinders();
}
/**
* Update the path finders
*/
@SuppressWarnings("unchecked")
private void updatePathFinders() {
float additionalMelee = getAdditionalMeleeMovementSpeed();
float additionalFollow = getAdditionalFollowBabySpeed();
float additionalTowards = getAdditionalMoveTowardsTargetSpeed();
//Reflection...
PathfinderGoalSelector GS = entity.getGoalSelector();
try{
Field aField = GS.getClass().getDeclaredField("a");
aField.setAccessible(true);
@SuppressWarnings("rawtypes")
ArrayList a = (ArrayList) aField.get(GS);
a.set(1, new PathfinderGoalMeleeAttack(this.entity, 0.42F + additionalMelee, true));
a.set(2, new PathfinderGoalMoveTowardsTarget(this.entity, 0.37F + additionalTowards, 32.0F));
a.set(3, new PathfinderFollowBaby(this.entity, 0.3F + additionalFollow, 5.0F, 4.0F));
}catch(Exception e) {
e.printStackTrace();
}
}
@SuppressWarnings("unchecked")
public ArrayList<Ability> get() {
return new ArrayList<Ability>((ArrayList<Ability>) this.abilities.clone());
}
}