/* * 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 . */ package com.l2jserver.gameserver.model.actor; import com.l2jserver.gameserver.ai.CtrlEvent; import com.l2jserver.gameserver.model.CharEffectList; import com.l2jserver.gameserver.model.L2Effect; import com.l2jserver.gameserver.model.L2Skill; import com.l2jserver.gameserver.model.actor.instance.L2PcInstance; import com.l2jserver.gameserver.model.actor.knownlist.PlayableKnownList; import com.l2jserver.gameserver.model.actor.stat.PlayableStat; import com.l2jserver.gameserver.model.actor.status.PlayableStatus; import com.l2jserver.gameserver.model.quest.QuestState; import com.l2jserver.gameserver.templates.chars.L2CharTemplate; import com.l2jserver.gameserver.templates.skills.L2EffectType; /** * This class represents all Playable characters in the world.

* * L2PlayableInstance :

*
  • L2PcInstance
  • *
  • L2Summon


  • * */ public abstract class L2Playable extends L2Character { private L2Character _lockedTarget = null; /** * Constructor of L2PlayableInstance (use L2Character constructor).

    * * Actions :

    *
  • Call the L2Character constructor to create an empty _skills slot and link copy basic Calculator set to this L2PlayableInstance


  • * * @param objectId Identifier of the object to initialized * @param template The L2CharTemplate to apply to the L2PlayableInstance * */ public L2Playable(int objectId, L2CharTemplate template) { super(objectId, template); setInstanceType(InstanceType.L2Playable); setIsInvul(false); } @Override public PlayableKnownList getKnownList() { return (PlayableKnownList)super.getKnownList(); } @Override public void initKnownList() { setKnownList(new PlayableKnownList(this)); } @Override public PlayableStat getStat() { return (PlayableStat)super.getStat(); } @Override public void initCharStat() { setStat(new PlayableStat(this)); } @Override public PlayableStatus getStatus() { return (PlayableStatus)super.getStatus(); } @Override public void initCharStatus() { setStatus(new PlayableStatus(this)); } @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 on the L2Character, // if the Character isn't affected by Soul of The Phoenix or Salvation if (isPhoenixBlessed()) { if (getCharmOfLuck()) //remove Lucky Charm if player has SoulOfThePhoenix/Salvation buff stopCharmOfLuck(null); if (isNoblesseBlessed()) stopNoblesseBlessing(null); } // Same thing if the Character isn't a Noblesse Blessed L2PlayableInstance else if (isNoblesseBlessed()) { stopNoblesseBlessing(null); if (getCharmOfLuck()) //remove Lucky Charm if player have Nobless blessing buff 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) return false; // Target is null if (target == this) return false; // Target is self if (!(target instanceof L2Playable)) return false; // Target is not a L2PlayableInstance L2PcInstance player = null; if (this instanceof L2PcInstance) player = (L2PcInstance)this; else if (this instanceof L2Summon) player = ((L2Summon)this).getOwner(); if (player == null) return false; // Active player is null if (player.getKarma() != 0) return false; // Active player has karma L2PcInstance targetPlayer = null; if (target instanceof L2PcInstance) targetPlayer = (L2PcInstance)target; else if (target instanceof L2Summon) targetPlayer = ((L2Summon)target).getOwner(); if (targetPlayer == null) return false; // Target player is null if (targetPlayer == this) return false; // Target player is self if (targetPlayer.getKarma() != 0) return false; // Target player has karma if (targetPlayer.getPvpFlag() == 0) return false; return true; /* Even at war, there should be PvP flag if( player.getClan() == null || targetPlayer.getClan() == null || ( !targetPlayer.getClan().isAtWarWith(player.getClanId()) && targetPlayer.getWantsPeace() == 0 && player.getWantsPeace() == 0 ) ) { return true; } return false; */ } /** * Return True.

    */ @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); } /** * @param 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); } public boolean isLockedTarget() { return _lockedTarget != null; } public L2Character getLockedTarget() { return _lockedTarget; } public void setLockedTarget(L2Character cha) { _lockedTarget = cha; } public abstract int getKarma(); public abstract byte getPvpFlag(); public abstract boolean useMagic(L2Skill skill, boolean forceUse, boolean dontMove); }