/*
* This program 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. This program 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 this program. If
* not, see <http://www.gnu.org/licenses/>.
*/
package silentium.gameserver.model.actor;
import silentium.gameserver.ai.CtrlEvent;
import silentium.gameserver.model.CharEffectList;
import silentium.gameserver.model.L2Effect;
import silentium.gameserver.model.L2Skill;
import silentium.gameserver.model.actor.instance.L2PcInstance;
import silentium.gameserver.model.actor.knownlist.PlayableKnownList;
import silentium.gameserver.model.actor.stat.PlayableStat;
import silentium.gameserver.model.actor.status.PlayableStatus;
import silentium.gameserver.model.quest.QuestState;
import silentium.gameserver.templates.chars.L2CharTemplate;
import silentium.gameserver.templates.skills.L2EffectType;
/**
* This class represents all Playable characters in the world.<BR>
* <BR>
* L2Playable :<BR>
* <BR>
* <li>L2PcInstance</li> <li>L2Summon</li><BR>
* <BR>
*/
public abstract class L2Playable extends L2Character
{
/**
* Constructor of L2Playable (use L2Character constructor).<BR>
* <BR>
* <B><U> Actions</U> :</B><BR>
* <BR>
* <li>Call the L2Character constructor to create an empty _skills slot and link copy basic Calculator set to this L2Playable</li> <BR>
* <BR>
*
* @param objectId
* Identifier of the object to initialized
* @param template
* The L2CharTemplate to apply to the L2Playable
*/
public L2Playable(int objectId, L2CharTemplate template)
{
super(objectId, template);
}
@Override
public void initKnownList()
{
setKnownList(new PlayableKnownList(this));
}
@Override
public PlayableKnownList getKnownList()
{
return (PlayableKnownList) super.getKnownList();
}
@Override
public void initCharStat()
{
setStat(new PlayableStat(this));
}
@Override
public PlayableStat getStat()
{
return (PlayableStat) super.getStat();
}
@Override
public void initCharStatus()
{
setStatus(new PlayableStatus(this));
}
@Override
public PlayableStatus getStatus()
{
return (PlayableStatus) super.getStatus();
}
@Override
public boolean doDie(L2Character killer)
{
// killing is only possible one time
synchronized (this)
{
if (isDead())
return false;
// now reset currentHp to zero
setCurrentHp(0);
setIsDead(true);
}
// Set target to null and cancel Attack or Cast
setTarget(null);
// Stop movement
stopMove(null);
// Stop HP/MP/CP Regeneration task
getStatus().stopHpMpRegeneration();
// Stop all active skills effects in progress
if (isPhoenixBlessed())
{
// remove Lucky Charm if player has SoulOfThePhoenix/Salvation buff
if (getCharmOfLuck())
stopCharmOfLuck(null);
if (isNoblesseBlessed())
stopNoblesseBlessing(null);
}
// Same thing if the Character isn't a Noblesse Blessed L2Playable
else if (isNoblesseBlessed())
{
stopNoblesseBlessing(null);
// remove Lucky Charm if player have Nobless blessing buff
if (getCharmOfLuck())
stopCharmOfLuck(null);
}
else
stopAllEffectsExceptThoseThatLastThroughDeath();
// Send the Server->Client packet StatusUpdate with current HP and MP to all other L2PcInstance to inform
broadcastStatusUpdate();
if (getWorldRegion() != null)
getWorldRegion().onDeath(this);
// Notify Quest of L2Playable's death
L2PcInstance actingPlayer = getActingPlayer();
if (!actingPlayer.isNotifyQuestOfDeathEmpty())
{
for (QuestState qs : actingPlayer.getNotifyQuestOfDeath())
qs.getQuest().notifyDeath((killer == null ? this : killer), this, qs);
}
if (killer != null)
{
L2PcInstance player = killer.getActingPlayer();
if (player != null)
player.onKillUpdatePvPKarma(this);
}
// Notify L2Character AI
getAI().notifyEvent(CtrlEvent.EVT_DEAD);
return true;
}
public boolean checkIfPvP(L2Character target)
{
if (target == null || target == this)
return false;
if (!(target instanceof L2Playable))
return false;
L2PcInstance player = getActingPlayer();
if (player == null || player.getKarma() != 0)
return false;
L2PcInstance targetPlayer = target.getActingPlayer();
if (targetPlayer == null || targetPlayer == this)
return false;
if (targetPlayer.getKarma() != 0 || targetPlayer.getPvpFlag() == 0)
return false;
return true;
}
/**
* Return True.<BR>
* <BR>
*/
@Override
public boolean isAttackable()
{
return true;
}
// Support for Noblesse Blessing skill, where buffs are retained after resurrect
public final boolean isNoblesseBlessed()
{
return _effects.isAffected(CharEffectList.EFFECT_FLAG_NOBLESS_BLESSING);
}
public final void stopNoblesseBlessing(L2Effect effect)
{
if (effect == null)
stopEffects(L2EffectType.NOBLESSE_BLESSING);
else
removeEffect(effect);
updateAbnormalEffect();
}
// Support for Soul of the Phoenix and Salvation skills
public final boolean isPhoenixBlessed()
{
return _effects.isAffected(CharEffectList.EFFECT_FLAG_PHOENIX_BLESSING);
}
public final void stopPhoenixBlessing(L2Effect effect)
{
if (effect == null)
stopEffects(L2EffectType.PHOENIX_BLESSING);
else
removeEffect(effect);
updateAbnormalEffect();
}
/**
* @return True if the Silent Moving mode is active.
*/
public boolean isSilentMoving()
{
return _effects.isAffected(CharEffectList.EFFECT_FLAG_SILENT_MOVE);
}
// for Newbie Protection Blessing skill, keeps you safe from an attack by a chaotic character >= 10 levels apart from you
public final boolean getProtectionBlessing()
{
return _effects.isAffected(CharEffectList.EFFECT_FLAG_PROTECTION_BLESSING);
}
public void stopProtectionBlessing(L2Effect effect)
{
if (effect == null)
stopEffects(L2EffectType.PROTECTION_BLESSING);
else
removeEffect(effect);
updateAbnormalEffect();
}
// Charm of Luck - During a Raid/Boss war, decreased chance for death penalty
public final boolean getCharmOfLuck()
{
return _effects.isAffected(CharEffectList.EFFECT_FLAG_CHARM_OF_LUCK);
}
public final void stopCharmOfLuck(L2Effect effect)
{
if (effect == null)
stopEffects(L2EffectType.CHARM_OF_LUCK);
else
removeEffect(effect);
updateAbnormalEffect();
}
@Override
public void updateEffectIcons(boolean partyOnly)
{
_effects.updateEffectIcons(partyOnly);
}
/**
* This method allows to easily send relations. Overridden in L2Summon and L2PcInstance.
*/
public void broadcastRelationsChanges()
{
}
public abstract int getKarma();
public abstract byte getPvpFlag();
public abstract boolean useMagic(L2Skill skill, boolean forceUse, boolean dontMove);
}