/*
* This file is part of aion-unique <aion-unique.org>.
*
* aion-unique is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* aion-unique is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with aion-unique. If not, see <http://www.gnu.org/licenses/>.
*/
package com.aionemu.gameserver.model.gameobjects.stats;
import java.util.concurrent.Future;
import java.util.concurrent.locks.ReentrantLock;
import com.aionemu.gameserver.model.gameobjects.player.Player;
import com.aionemu.gameserver.model.gameobjects.state.CreatureState;
import com.aionemu.gameserver.model.group.GroupEvent;
import com.aionemu.gameserver.network.aion.serverpackets.SM_FLY_TIME;
import com.aionemu.gameserver.network.aion.serverpackets.SM_STATUPDATE_HP;
import com.aionemu.gameserver.network.aion.serverpackets.SM_STATUPDATE_MP;
import com.aionemu.gameserver.services.LifeStatsRestoreService;
import com.aionemu.gameserver.taskmanager.tasks.PacketBroadcaster.BroadcastMode;
import com.aionemu.gameserver.utils.PacketSendUtility;
/**
* @author ATracer, sphinx
*
*/
public class PlayerLifeStats extends CreatureLifeStats<Player>
{
protected int currentFp;
private final ReentrantLock fpLock = new ReentrantLock();
private Future<?> flyRestoreTask;
private Future<?> flyReduceTask;
public PlayerLifeStats(Player owner, int currentHp, int currentMp)
{
super(owner,currentHp,currentMp);
this.currentFp = owner.getGameStats().getCurrentStat(StatEnum.FLY_TIME);
}
@Override
protected void onReduceHp()
{
sendHpPacketUpdate();
triggerHpMpRestoreTask();
sendGroupPacketUpdate();
}
@Override
protected void onReduceMp()
{
sendMpPacketUpdate();
triggerHpMpRestoreTask();
sendGroupPacketUpdate();
}
@Override
protected void onIncreaseMp()
{
sendMpPacketUpdate();
sendGroupPacketUpdate();
}
@Override
protected void onIncreaseHp()
{
sendHpPacketUpdate();
sendAttackStatusPacketUpdate();
sendGroupPacketUpdate();
}
private void sendGroupPacketUpdate()
{
Player owner = getOwner();
if(owner.getPlayerGroup() != null)
{
owner.getPlayerGroup().updateGroupUIToEvent(owner, GroupEvent.UNK);
}
}
@Override
public Player getOwner()
{
return (Player) super.getOwner();
}
@Override
public void restoreHp()
{
int currentRegenHp = getOwner().getGameStats().getCurrentStat(StatEnum.REGEN_HP);
if(getOwner().isInState(CreatureState.RESTING))
currentRegenHp *= 8;
increaseHp(currentRegenHp);
}
@Override
public void restoreMp()
{
int currentRegenMp = getOwner().getGameStats().getCurrentStat(StatEnum.REGEN_MP);
if(getOwner().isInState(CreatureState.RESTING))
currentRegenMp *= 8;
increaseMp(currentRegenMp);
}
@Override
public void synchronizeWithMaxStats()
{
if(isAlreadyDead())
return;
super.synchronizeWithMaxStats();
int maxFp = getMaxFp();
if(currentFp != maxFp)
currentFp = maxFp;
}
@Override
public void updateCurrentStats()
{
super.updateCurrentStats();
if(getMaxFp() < currentFp)
currentFp = getMaxFp();
if(!owner.isInState(CreatureState.FLYING))
triggerFpRestore();
}
public void sendHpPacketUpdate()
{
owner.addPacketBroadcastMask(BroadcastMode.UPDATE_PLAYER_HP_STAT);
}
public void sendHpPacketUpdateImpl()
{
if(owner == null)
return;
PacketSendUtility.sendPacket((Player) owner, new SM_STATUPDATE_HP(currentHp, getMaxHp()));
}
public void sendMpPacketUpdate()
{
owner.addPacketBroadcastMask(BroadcastMode.UPDATE_PLAYER_MP_STAT);
}
public void sendMpPacketUpdateImpl()
{
if(owner == null)
return;
PacketSendUtility.sendPacket((Player) owner, new SM_STATUPDATE_MP(currentMp, getMaxMp()));
}
/**
*
* @return the currentFp
*/
public int getCurrentFp()
{
return this.currentFp;
}
/**
*
* @return maxFp of creature according to stats
*/
public int getMaxFp()
{
return owner.getGameStats().getCurrentStat(StatEnum.FLY_TIME);
}
/**
* @return FP percentage 0 - 100
*/
public int getFpPercentage()
{
return 100 * currentFp / getMaxFp();
}
/**
* This method is called whenever caller wants to restore creatures's FP
* @param value
* @return
*/
public int increaseFp(int value)
{
if(value == getMaxFp())
return 0;
fpLock.lock();
try
{
if(isAlreadyDead())
{
return 0;
}
int newFp = this.currentFp + value;
if(newFp > getMaxFp())
{
newFp = getMaxFp();
}
this.currentFp = newFp;
}
finally
{
fpLock.unlock();
}
onIncreaseFp();
return currentFp;
}
/**
* This method is called whenever caller wants to reduce creatures's MP
*
* @param value
* @return
*/
public int reduceFp(int value)
{
fpLock.lock();
try
{
int newFp = this.currentFp - value;
if(newFp < 0)
newFp = 0;
this.currentFp = newFp;
}
finally
{
fpLock.unlock();
}
onReduceFp();
return currentFp;
}
protected void onIncreaseFp()
{
owner.addPacketBroadcastMask(BroadcastMode.UPDATE_PLAYER_FLY_TIME);
}
protected void onReduceFp()
{
owner.addPacketBroadcastMask(BroadcastMode.UPDATE_PLAYER_FLY_TIME);
}
public void sendFpPacketUpdateImpl()
{
if(owner == null)
return;
PacketSendUtility.sendPacket((Player) owner, new SM_FLY_TIME(currentFp, getMaxFp()));
}
/**
* this method should be used only on FlyTimeRestoreService
*/
public void restoreFp()
{
//how much fly time restoring per 2 second.
increaseFp(1);
}
public void triggerFpRestore()
{
cancelFpReduce();
if(flyRestoreTask == null && !alreadyDead && !isFlyTimeFullyRestored())
{
this.flyRestoreTask = LifeStatsRestoreService.getInstance().scheduleFpRestoreTask(this);
}
}
public void cancelFpRestore()
{
if(flyRestoreTask != null && !flyRestoreTask.isCancelled())
{
flyRestoreTask.cancel(false);
this.flyRestoreTask = null;
}
}
public void triggerFpReduce()
{
cancelFpRestore();
if(flyReduceTask == null && !alreadyDead)
{
this.flyReduceTask = LifeStatsRestoreService.getInstance().scheduleFpReduceTask(this);
}
}
public void cancelFpReduce()
{
if(flyReduceTask != null && !flyReduceTask.isCancelled())
{
flyReduceTask.cancel(false);
this.flyReduceTask = null;
}
}
public boolean isFlyTimeFullyRestored()
{
return getMaxFp() == currentFp;
}
@Override
public void cancelAllTasks()
{
super.cancelAllTasks();
cancelFpReduce();
cancelFpRestore();
}
@Override
public void triggerRestoreOnRevive()
{
super.triggerRestoreOnRevive();
triggerFpRestore();
}
}