package org.reunionemu.jreunion.game.skills.aidia;
import java.util.Timer;
import java.util.TimerTask;
import org.reunionemu.jreunion.game.AidiaPlayer;
import org.reunionemu.jreunion.game.Castable;
import org.reunionemu.jreunion.game.Effectable;
import org.reunionemu.jreunion.game.LivingObject;
import org.reunionemu.jreunion.game.Npc;
import org.reunionemu.jreunion.game.Player;
import org.reunionemu.jreunion.game.Skill;
import org.reunionemu.jreunion.game.skills.Modifier;
import org.reunionemu.jreunion.game.skills.Modifier.ValueType;
import org.reunionemu.jreunion.server.SkillManager;
import org.reunionemu.jreunion.server.Tools;
import org.reunionemu.jreunion.server.PacketFactory.Type;
public class SafetyShield extends Skill implements Castable, Effectable{
private int effectModifier = 0;
private Timer timer = null;
public SafetyShield(SkillManager skillManager,int id) {
super(skillManager,id);
}
public ValueType getValueType() {
return Modifier.ValueType.SHIELD;
}
@Override
public int getMaxLevel() {
return 25;
}
@Override
public int getLevelRequirement(int skillLevel) {
return 14+skillLevel;
}
@Override
public int getAffectedTargets() {
return 1;
}
public int getEffectModifier(){
return effectModifier;
}
public void setEffectModifier(int effectModifier){
this.effectModifier = effectModifier;
}
public boolean isActivated(){
return getEffectModifier()>0;
}
public float getDamageAbsorbModifier(){
/* level 1 = 1%
* level 2 =
* ...
* level 25 = 20%
*/
return 0.19f / (getMaxLevel() - 1);
}
public float getDamageAbsorbModifier(Player player){
float modifier = 0;
int level = player.getSkillLevel(this);
if(level>0){
modifier += (0.01f+((level-1) * getDamageAbsorbModifier()));
}
return modifier;
}
public float getDefenceBonusModifier(){
/* level 1 = 10%
* level 2 =
* ...
* level 25 = 70%
*/
return 0.6f / (getMaxLevel() - 1);
}
public float getDefenceBonusModifier(Player player){
float modifier = 0;
int level = player.getSkillLevel(this);
if(level>0){
modifier += (0.1f+((level-1) * getDamageAbsorbModifier()));
}
return modifier;
}
public float getManaModifier(){
/* mana spent:
* level 1 = 10
* level 2 = 12
* level 3 = 14
* ...
* level 25 = 60
*/
return 50f/(getMaxLevel()-1);
}
long getManaModifier(Player player){
long modifier = 0;
int level = player.getSkillLevel(this);
if(level>0){
modifier += (10 + ((level-1) * getManaModifier()));
}
return modifier;
}
public float getDurationModifier(){
/* mana spent:
* level 1 = 6
* level 2 = 7
* level 3 = 8
* ...
* level 25 = 30
*/
return 24f/(getMaxLevel()-1);
}
long getDurationModifier(Player player){
long modifier = 0;
int level = player.getSkillLevel(this);
if(level>0){
modifier += (6 + ((level-1) * getDurationModifier()));
}
return modifier;
}
public float getAccumulatedTimeModifier(){
/* mana spent:
* level 1 = 110
* level 2 = 120
* level 3 = 130
* ...
* level 25 = 350
*/
return 240f/(getMaxLevel()-1);
}
long getAccumulatedTimeModifier(Player player){
long modifier = 0;
int level = player.getSkillLevel(this);
if(level>0){
modifier += (110 + ((level-1) * getAccumulatedTimeModifier()));
}
return modifier;
}
@Override
//TODO: handle with DefenceBonus and DamageAbsorb
//TODO: implement damage reflection
public boolean cast(LivingObject caster, LivingObject victim, String[] arguments) {
if(caster instanceof AidiaPlayer){
final Player player = (Player) caster;
long newMana = player.getMana() - getManaModifier(player);
long durationModifier = getDurationModifier(player);
if(getEffectModifier()+durationModifier > getAccumulatedTimeModifier(player)){
player.getClient().sendPacket(Type.SAY, "SafetyShield skill acumulated time, already at maximum.");
return false;
}
if(getEffectModifier() == 0)
player.getClient().sendPacket(Type.SAY, "SafetyShield skill activated.");
player.setMana(newMana);
setEffectModifier(Tools.between(getEffectModifier()+(int)durationModifier, 0, (int)getAccumulatedTimeModifier(player)));
if(timer != null)
timer.cancel();
timer = new Timer();
final Skill skill = (Skill)this;
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
if (getEffectModifier() > 0) {
setEffectModifier(getEffectModifier() - 1);
if(getEffectModifier() == 20){
player.getClient().sendPacket(Type.SAY, "SafetyShield skill will end soon...");
player.getClient().sendPacket(Type.SKILL, player, skill);
}
} else {
player.getClient().sendPacket(Type.SAY, "SafetyShield skill deactivated.");
player.getClient().sendPacket(Type.SKILL, player, skill);
timer.cancel();
}
}
}, 1, 1 * 1000);
player.getClient().sendPacket(Type.SKILL, player, skill);
return true;
}
return false;
}
@Override
public boolean work(LivingObject target, LivingObject attacker){
if(!isActivated())
return false;
if(target instanceof Player){
Player player = (Player) target;
Npc<?> npc = null;
if(attacker instanceof Npc){
npc = (Npc<?>)attacker;
} else {
player.getClient().sendPacket(Type.SAY, "Shield not implemented for the attacker type.");
return false;
}
long damage = npc.getDamage((int)player.getDef());
long playerMana = player.getMana();
long manaLoss = (playerMana - damage < 0 ? 0 : damage);
long hpLoss = (manaLoss==0 ? damage : 0);
player.setMana(player.getMana() - manaLoss);
player.setHp(player.getHp() - hpLoss);
}
return true;
}
}