Bläddra i källkod

Status class rework. Will need DP update for ballista bomb work correctly.

_DS_ 15 år sedan
förälder
incheckning
2dde463df1

+ 13 - 0
L2_GameServer/java/net/sf/l2j/gameserver/model/actor/L2Attackable.java

@@ -52,6 +52,7 @@ import net.sf.l2j.gameserver.model.actor.instance.L2PetInstance;
 import net.sf.l2j.gameserver.model.actor.instance.L2SiegeGuardInstance;
 import net.sf.l2j.gameserver.model.actor.instance.L2SummonInstance;
 import net.sf.l2j.gameserver.model.actor.knownlist.AttackableKnownList;
+import net.sf.l2j.gameserver.model.actor.status.AttackableStatus;
 import net.sf.l2j.gameserver.model.base.SoulCrystal;
 import net.sf.l2j.gameserver.model.quest.Quest;
 import net.sf.l2j.gameserver.model.quest.QuestState;
@@ -293,6 +294,18 @@ public class L2Attackable extends L2Npc
 		setKnownList(new AttackableKnownList(this));
     }
 
+	@Override
+	public AttackableStatus getStatus()
+	{
+		return (AttackableStatus) super.getStatus();
+	}
+	
+	@Override
+	public void initCharStatus()
+	{
+		setStatus(new AttackableStatus(this));
+	}
+
 	/**
 	 * Return the L2Character AI of the L2Attackable and if its null create a new one.
 	 */

+ 0 - 1
L2_GameServer/java/net/sf/l2j/gameserver/model/actor/instance/L2FortBallistaInstance.java

@@ -32,7 +32,6 @@ public class L2FortBallistaInstance extends L2Npc
 	public L2FortBallistaInstance(int objectId, L2NpcTemplate template)
     {
         super(objectId, template);
-        setIsInvul(false);
     }
 	
     @Override

+ 61 - 0
L2_GameServer/java/net/sf/l2j/gameserver/model/actor/status/AttackableStatus.java

@@ -0,0 +1,61 @@
+/*
+ * 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 net.sf.l2j.gameserver.model.actor.status;
+
+import net.sf.l2j.gameserver.model.actor.L2Attackable;
+import net.sf.l2j.gameserver.model.actor.L2Character;
+
+public class AttackableStatus extends NpcStatus
+{
+	public AttackableStatus(L2Attackable activeChar)
+	{
+		super(activeChar);
+	}
+
+	@Override
+	public final void reduceHp(double value, L2Character attacker)
+	{
+		reduceHp(value, attacker, true, false, false);
+	}
+
+	@Override
+	public final void reduceHp(double value, L2Character attacker, boolean awake, boolean isDOT, boolean isHpConsumption)
+	{
+		if (getActiveChar().isDead())
+			return;
+
+		if (value > 0)
+		{
+			if (getActiveChar().isOverhit())
+				getActiveChar().setOverhitValues(attacker, value);
+			else
+				getActiveChar().overhitEnabled(false);
+        }
+        else
+        	getActiveChar().overhitEnabled(false);
+
+		super.reduceHp(value, attacker, awake, isDOT, isHpConsumption);
+
+		if (!getActiveChar().isDead())
+			// And the attacker's hit didn't kill the mob, clear the over-hit flag
+			getActiveChar().overhitEnabled(false);
+	}
+
+	@Override
+	public L2Attackable getActiveChar()
+	{
+		return (L2Attackable)super.getActiveChar();
+	}
+}

+ 371 - 539
L2_GameServer/java/net/sf/l2j/gameserver/model/actor/status/CharStatus.java

@@ -22,554 +22,386 @@ import java.util.logging.Logger;
 
 import net.sf.l2j.Config;
 import net.sf.l2j.gameserver.ThreadPoolManager;
-import net.sf.l2j.gameserver.ai.CtrlIntention;
-import net.sf.l2j.gameserver.instancemanager.DuelManager;
-import net.sf.l2j.gameserver.model.actor.L2Attackable;
 import net.sf.l2j.gameserver.model.actor.L2Character;
-import net.sf.l2j.gameserver.model.actor.L2Npc;
-import net.sf.l2j.gameserver.model.actor.instance.L2FortBallistaInstance;
 import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
-import net.sf.l2j.gameserver.model.actor.instance.L2SummonInstance;
 import net.sf.l2j.gameserver.model.actor.stat.CharStat;
-import net.sf.l2j.gameserver.model.entity.Duel;
-import net.sf.l2j.gameserver.model.quest.QuestState;
-import net.sf.l2j.gameserver.network.serverpackets.ActionFailed;
 import net.sf.l2j.gameserver.skills.Formulas;
 import net.sf.l2j.util.Rnd;
 
 public class CharStatus
 {
-    protected static final Logger _log = Logger.getLogger(CharStatus.class.getName());
-    
-    // =========================================================
-    // Data Field
-    private L2Character _activeChar;
-    
-    private double _currentCp = 0; //Current CP of the L2Character
-    
-    private double _currentHp = 0; //Current HP of the L2Character
-    
-    private double _currentMp = 0; //Current MP of the L2Character
-    
-    /** Array containing all clients that need to be notified about hp/mp updates of the L2Character */
-    private Set<L2Character> _StatusListener;
-    
-    private Future<?> _regTask;
-    
-    private byte _flagsRegenActive = 0;
-    
-    private static final byte REGEN_FLAG_CP = 4;
-    
-    private static final byte REGEN_FLAG_HP = 1;
-    
-    private static final byte REGEN_FLAG_MP = 2;
-    
-    // =========================================================
-    // Constructor
-    public CharStatus(L2Character activeChar)
-    {
-        _activeChar = activeChar;
-    }
-    
-    /**
-     * Add the object to the list of L2Character that must be informed of HP/MP updates of this L2Character.<BR><BR>
-     *
-     * <B><U> Concept</U> :</B><BR><BR>
-     * Each L2Character owns a list called <B>_statusListener</B> that contains all L2PcInstance to inform of HP/MP updates.
-     * Players who must be informed are players that target this L2Character.
-     * When a RegenTask is in progress sever just need to go through this list to send Server->Client packet StatusUpdate.<BR><BR>
-     *
-     * <B><U> Example of use </U> :</B><BR><BR>
-     * <li> Target a PC or NPC</li><BR><BR>
-     *
-     * @param object L2Character to add to the listener
-     *
-     */
-    public final void addStatusListener(L2Character object)
-    {
-        if (object == getActiveChar())
-            return;
-        
-        synchronized (getStatusListener())
-        {
-            getStatusListener().add(object);
-        }
-    }
-    
-    public final void reduceCp(int value)
-    {
-        if (getCurrentCp() > value)
-            setCurrentCp(getCurrentCp() - value);
-        else
-            setCurrentCp(0);
-    }
-    
-    /**
-     * Reduce the current HP of the L2Character and launch the doDie Task if necessary.<BR><BR>
-     *
-     * <B><U> Overridden in </U> :</B><BR><BR>
-     * <li> L2Attackable : Update the attacker AggroInfo of the L2Attackable _aggroList</li><BR><BR>
-     *
-     * @param i The HP decrease value
-     * @param attacker The L2Character who attacks
-     * @param awake The awake state (If True : stop sleeping)
-     *
-     */
-    public void reduceHp(double value, L2Character attacker)
-    {
-        reduceHp(value, attacker, true, false, false);
-    }
-    
-    public void reduceHp(double value, L2Character attacker, boolean isHpConsumption)
-    {
-    	reduceHp(value, attacker, true, false, isHpConsumption);
-    }
-    
-    public void reduceHp(double value, L2Character attacker, boolean awake, boolean isDOT, boolean isHpConsumption)
-    {
-    	if (getActiveChar() instanceof L2FortBallistaInstance && getActiveChar().getMaxHp() == value){}
-    	else if (getActiveChar().isInvul())
-    	{
-    		if (attacker == getActiveChar())
-    		{
-    			if (!isDOT && !isHpConsumption)
-    				return;
-    		}
-    		else
-    			return;
-    	}
-        if (getActiveChar().isDead())
-            return;
-        
-        if (attacker instanceof L2PcInstance)
+	protected static final Logger _log = Logger.getLogger(CharStatus.class.getName());
+
+	private L2Character _activeChar;
+
+	private double _currentHp = 0; //Current HP of the L2Character
+	private double _currentMp = 0; //Current MP of the L2Character
+
+	/** Array containing all clients that need to be notified about hp/mp updates of the L2Character */
+	private Set<L2Character> _StatusListener;
+
+	private Future<?> _regTask;
+
+	protected byte _flagsRegenActive = 0;
+
+	protected static final byte REGEN_FLAG_CP = 4;
+	private static final byte REGEN_FLAG_HP = 1;
+	private static final byte REGEN_FLAG_MP = 2;
+
+	public CharStatus(L2Character activeChar)
+	{
+		_activeChar = activeChar;
+	}
+
+	/**
+	 * Add the object to the list of L2Character that must be informed of HP/MP updates of this L2Character.<BR><BR>
+	 *
+	 * <B><U> Concept</U> :</B><BR><BR>
+	 * Each L2Character owns a list called <B>_statusListener</B> that contains all L2PcInstance to inform of HP/MP updates.
+	 * Players who must be informed are players that target this L2Character.
+	 * When a RegenTask is in progress sever just need to go through this list to send Server->Client packet StatusUpdate.<BR><BR>
+	 *
+	 * <B><U> Example of use </U> :</B><BR><BR>
+	 * <li> Target a PC or NPC</li><BR><BR>
+	 *
+	 * @param object L2Character to add to the listener
+	 *
+	 */
+	public final void addStatusListener(L2Character object)
+	{
+		if (object == getActiveChar())
+			return;
+
+		synchronized (getStatusListener())
+		{
+			getStatusListener().add(object);
+		}
+	}
+
+	/**
+	 * Remove the object from the list of L2Character that must be informed of HP/MP updates of this L2Character.<BR><BR>
+	 *
+	 * <B><U> Concept</U> :</B><BR><BR>
+	 * Each L2Character owns a list called <B>_statusListener</B> that contains all L2PcInstance to inform of HP/MP updates.
+	 * Players who must be informed are players that target this L2Character.
+	 * When a RegenTask is in progress sever just need to go through this list to send Server->Client packet StatusUpdate.<BR><BR>
+	 *
+	 * <B><U> Example of use </U> :</B><BR><BR>
+	 * <li> Untarget a PC or NPC</li><BR><BR>
+	 *
+	 * @param object L2Character to add to the listener
+	 *
+	 */
+	public final void removeStatusListener(L2Character object)
+	{
+		synchronized (getStatusListener())
+		{
+			getStatusListener().remove(object);
+		}
+	}
+
+	/**
+	 * Return the list of L2Character that must be informed of HP/MP updates of this L2Character.<BR><BR>
+	 *
+	 * <B><U> Concept</U> :</B><BR><BR>
+	 * Each L2Character owns a list called <B>_statusListener</B> that contains all L2PcInstance to inform of HP/MP updates.
+	 * Players who must be informed are players that target this L2Character.
+	 * When a RegenTask is in progress sever just need to go through this list to send Server->Client packet StatusUpdate.<BR><BR>
+	 *
+	 * @return The list of L2Character to inform or null if empty
+	 *
+	 */
+	public final Set<L2Character> getStatusListener()
+	{
+		if (_StatusListener == null)
+			_StatusListener = new CopyOnWriteArraySet<L2Character>();
+		return _StatusListener;
+	}
+
+	// place holder, only PcStatus has CP
+	public void reduceCp(int value)
+	{
+	}
+
+	/**
+	 * Reduce the current HP of the L2Character and launch the doDie Task if necessary.<BR><BR>
+	 *
+	 * <B><U> Overridden in </U> :</B><BR><BR>
+	 * <li> L2Attackable : Set overhit values</li><BR>
+	 * <li> L2Npc : Update the attacker AggroInfo of the L2Attackable _aggroList and clear duel status of the attacking players</li><BR><BR>
+	 *
+	 * @param i The HP decrease value
+	 * @param attacker The L2Character who attacks
+	 * @param awake The awake state (If True : stop sleeping)
+	 *
+	 */
+	public void reduceHp(double value, L2Character attacker)
+	{
+		reduceHp(value, attacker, true, false, false);
+	}
+
+	public void reduceHp(double value, L2Character attacker, boolean isHpConsumption)
+	{
+		reduceHp(value, attacker, true, false, isHpConsumption);
+	}
+
+	public void reduceHp(double value, L2Character attacker, boolean awake, boolean isDOT, boolean isHPConsumption)
+	{
+		if (getActiveChar().isDead())
+			return;
+
+		// invul handling
+		if (getActiveChar().isInvul())
+		{
+			// other chars can't damage
+			if (attacker != getActiveChar())
+				return;
+
+			// only DOT and HP consumption allowed for damage self
+			if (!isDOT && !isHPConsumption)
+				return;
+		}
+
+		if (attacker != null)
+		{
+			final L2PcInstance attackerPlayer = attacker.getActingPlayer();
+			if (attackerPlayer != null
+					&& attackerPlayer.isGM()
+					&& !attackerPlayer.getAccessLevel().canGiveDamage())
+				return;
+		}
+
+		if (!isDOT && !isHPConsumption)
+		{
+			if (awake && getActiveChar().isSleeping())
+				getActiveChar().stopSleeping(null);
+			if (getActiveChar().isStunned() && Rnd.get(10) == 0)
+				getActiveChar().stopStunning(null);
+			if (getActiveChar().isImmobileUntilAttacked())
+				getActiveChar().stopImmobileUntilAttacked(null);
+		}
+
+		if (value > 0) // Reduce Hp if any, and Hp can't be negative
+			setCurrentHp(Math.max(getCurrentHp() - value, 0));
+
+		if (getActiveChar().getCurrentHp() < 0.5) // Die
+		{
+			getActiveChar().abortAttack();
+			getActiveChar().abortCast();
+
+			if (Config.DEBUG)
+				_log.fine("char is dead.");
+
+			getActiveChar().doDie(attacker);
+		}
+	}
+
+	public void reduceMp(double value)
+	{
+		setCurrentMp(Math.max(getCurrentMp() - value, 0));
+	}
+
+	/**
+	 * Start the HP/MP/CP Regeneration task.<BR><BR>
+	 *
+	 * <B><U> Actions</U> :</B><BR><BR>
+	 * <li>Calculate the regen task period </li>
+	 * <li>Launch the HP/MP/CP Regeneration task with Medium priority </li><BR><BR>
+	 *
+	 */
+	public final synchronized void startHpMpRegeneration()
+	{
+		if (_regTask == null && !getActiveChar().isDead())
+		{
+			if (Config.DEBUG)
+				_log.fine("HP/MP regen started");
+
+			// Get the Regeneration periode
+			int period = Formulas.getRegeneratePeriod(getActiveChar());
+
+			// Create the HP/MP/CP Regeneration task
+			_regTask = ThreadPoolManager.getInstance().scheduleEffectAtFixedRate(new RegenTask(), period, period);
+		}
+	}
+
+	/**
+	 * Stop the HP/MP/CP Regeneration task.<BR><BR>
+	 *
+	 * <B><U> Actions</U> :</B><BR><BR>
+	 * <li>Set the RegenActive flag to False </li>
+	 * <li>Stop the HP/MP/CP Regeneration task </li><BR><BR>
+	 *
+	 */
+	public final synchronized void stopHpMpRegeneration()
+	{
+		if (_regTask != null)
+		{
+			if (Config.DEBUG)
+				_log.fine("HP/MP regen stop");
+
+			// Stop the HP/MP/CP Regeneration task
+			_regTask.cancel(false);
+			_regTask = null;
+
+			// Set the RegenActive flag to false
+			_flagsRegenActive = 0;
+		}
+	}
+
+	// place holder, only PcStatus has CP
+	public double getCurrentCp()
+	{
+		return 0;
+	}
+
+	// place holder, only PcStatus has CP
+	public void setCurrentCp(double newCp)
+	{
+	}
+
+	public final double getCurrentHp()
+	{
+		return _currentHp;
+	}
+
+	public final void setCurrentHp(double newHp)
+	{
+		setCurrentHp(newHp, true);
+	}
+
+	public void setCurrentHp(double newHp, boolean broadcastPacket)
+	{
+		// Get the Max HP of the L2Character
+		final double maxHp = getActiveChar().getStat().getMaxHp();
+
+		synchronized (this)
+		{
+			if (getActiveChar().isDead())
+				return;
+
+			if (newHp >= maxHp)
+			{
+				// Set the RegenActive flag to false
+				_currentHp = maxHp;
+				_flagsRegenActive &= ~REGEN_FLAG_HP;
+
+				// Stop the HP/MP/CP Regeneration task
+				if (_flagsRegenActive == 0)
+					stopHpMpRegeneration();
+			}
+			else
+			{
+				// Set the RegenActive flag to true
+				_currentHp = newHp;
+				_flagsRegenActive |= REGEN_FLAG_HP;
+
+				// Start the HP/MP/CP Regeneration task with Medium priority
+				startHpMpRegeneration();
+			}
+		}
+
+		// Send the Server->Client packet StatusUpdate with current HP and MP to all other L2PcInstance to inform
+		if (broadcastPacket)
+			getActiveChar().broadcastStatusUpdate();
+	}
+
+	public final void setCurrentHpMp(double newHp, double newMp)
+	{
+		setCurrentHp(newHp, false);
+		setCurrentMp(newMp, true); //send the StatusUpdate only once
+	}
+
+	public final double getCurrentMp()
+	{
+		return _currentMp;
+	}
+
+	public final void setCurrentMp(double newMp)
+	{
+		setCurrentMp(newMp, true);
+	}
+
+	public final void setCurrentMp(double newMp, boolean broadcastPacket)
+	{
+		// Get the Max MP of the L2Character
+		final int maxMp = getActiveChar().getStat().getMaxMp();
+
+		synchronized (this)
+		{
+			if (getActiveChar().isDead())
+				return;
+
+			if (newMp >= maxMp)
+			{
+				// Set the RegenActive flag to false
+				_currentMp = maxMp;
+				_flagsRegenActive &= ~REGEN_FLAG_MP;
+
+				// Stop the HP/MP/CP Regeneration task
+				if (_flagsRegenActive == 0)
+					stopHpMpRegeneration();
+			}
+			else
+			{
+				// Set the RegenActive flag to true
+				_currentMp = newMp;
+				_flagsRegenActive |= REGEN_FLAG_MP;
+
+				// Start the HP/MP/CP Regeneration task with Medium priority
+				startHpMpRegeneration();
+			}
+		}
+
+		// Send the Server->Client packet StatusUpdate with current HP and MP to all other L2PcInstance to inform
+		if (broadcastPacket)
+			getActiveChar().broadcastStatusUpdate();
+	}
+
+	protected void doRegeneration()
+	{
+		final CharStat charstat = getActiveChar().getStat();
+
+		// Modify the current HP of the L2Character and broadcast Server->Client packet StatusUpdate
+		if (getCurrentHp() < charstat.getMaxHp())
+			setCurrentHp(getCurrentHp()
+					+ Formulas.calcHpRegen(getActiveChar()), false);
+
+		// Modify the current MP of the L2Character and broadcast Server->Client packet StatusUpdate
+		if (getCurrentMp() < charstat.getMaxMp())
+			setCurrentMp(getCurrentMp()
+					+ Formulas.calcMpRegen(getActiveChar()), false);
+
+		if (!getActiveChar().isInActiveRegion())
+		{
+			// no broadcast necessary for characters that are in inactive regions.
+			// stop regeneration for characters who are filled up and in an inactive region.
+			if ((getCurrentCp() == charstat.getMaxCp())
+					&& (getCurrentHp() == charstat.getMaxHp())
+					&& (getCurrentMp() == charstat.getMaxMp()))
+				stopHpMpRegeneration();
+		}
+		else
+			getActiveChar().broadcastStatusUpdate(); //send the StatusUpdate packet
+	}
+
+	/** Task of HP/MP regeneration */
+	class RegenTask implements Runnable
+	{
+		public void run()
 		{
-			L2PcInstance pcInst = (L2PcInstance)attacker;
-			if (pcInst.isGM() && !pcInst.getAccessLevel().canGiveDamage())
-				return ;
+			try
+			{
+				doRegeneration();
+			}
+			catch (Exception e)
+			{
+				_log.log(Level.SEVERE, "", e);
+			}
 		}
+	}
 
-        if (getActiveChar() instanceof L2PcInstance)
-        {
-            if (((L2PcInstance) getActiveChar()).isInDuel())
-            {
-                // the duel is finishing - players do not recive damage
-                if (((L2PcInstance) getActiveChar()).getDuelState() == Duel.DUELSTATE_DEAD)
-                    return;
-                else if (((L2PcInstance) getActiveChar()).getDuelState() == Duel.DUELSTATE_WINNER)
-                    return;
-                
-                // cancel duel if player got hit by another player, that is not part of the duel or a monster
-                if (!(attacker instanceof L2SummonInstance)
-                        && !(attacker instanceof L2PcInstance && ((L2PcInstance) attacker).getDuelId() == ((L2PcInstance) getActiveChar()).getDuelId()))
-                {
-                    ((L2PcInstance) getActiveChar()).setDuelState(Duel.DUELSTATE_INTERRUPTED);
-                }
-            }
-        }
-        else
-        {
-            if (attacker instanceof L2PcInstance
-                    && ((L2PcInstance) attacker).isInDuel()
-                    && !(getActiveChar() instanceof L2SummonInstance && ((L2SummonInstance) getActiveChar()).getOwner().getDuelId() == ((L2PcInstance) attacker).getDuelId())) // Duelling player attacks mob
-            {
-                ((L2PcInstance) attacker).setDuelState(Duel.DUELSTATE_INTERRUPTED);
-            }
-        }
-        if (awake && getActiveChar().isSleeping() && (!isDOT || getActiveChar() instanceof L2PcInstance))
-            getActiveChar().stopSleeping(null);
-        if (getActiveChar().isStunned() && Rnd.get(10) == 0 && !isDOT)
-            getActiveChar().stopStunning(null);
-        if (getActiveChar().isImmobileUntilAttacked() && !isDOT)
-            getActiveChar().stopImmobileUntilAttacked(null);
-        
-        // Add attackers to npc's attacker list
-        if (getActiveChar() instanceof L2Npc)
-            getActiveChar().addAttackerToAttackByList(attacker);
-        
-        if (value > 0) // Reduce Hp if any
-        {
-            // If we're dealing with an L2Attackable Instance and the attacker hit it with an over-hit enabled skill, set the over-hit values.
-            // Anything else, clear the over-hit flag
-            if (getActiveChar() instanceof L2Attackable)
-            {
-                if (((L2Attackable) getActiveChar()).isOverhit())
-                    ((L2Attackable) getActiveChar()).setOverhitValues(attacker, value);
-                else
-                    ((L2Attackable) getActiveChar()).overhitEnabled(false);
-            }
-            value = getCurrentHp() - value; // Get diff of Hp vs value
-            if (value <= 0)
-            {
-                // is the dying a duelist? if so, change his duel state to dead
-                if (getActiveChar() instanceof L2PcInstance
-                        && ((L2PcInstance) getActiveChar()).isInDuel())
-                {
-                    getActiveChar().disableAllSkills();
-                    stopHpMpRegeneration();
-                    attacker.getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
-                    attacker.sendPacket(ActionFailed.STATIC_PACKET);
-                    
-                    // let the DuelManager know of his defeat
-                    DuelManager.getInstance().onPlayerDefeat((L2PcInstance) getActiveChar());
-                    value = 1;
-                }
-                else
-                    value = 0; // Set value to 0 if Hp < 0
-            }
-            setCurrentHp(value); // Set Hp
-        }
-        else
-        {
-            // If we're dealing with an L2Attackable Instance and the attacker's hit didn't kill the mob, clear the over-hit flag
-            if (getActiveChar() instanceof L2Attackable)
-            {
-                ((L2Attackable) getActiveChar()).overhitEnabled(false);
-            }
-        }
-        
-        if (getActiveChar().getCurrentHp() < 0.5) // Die
-        {
-            getActiveChar().abortAttack();
-            getActiveChar().abortCast();
-            
-            if (getActiveChar() instanceof L2PcInstance)
-            {
-                if (((L2PcInstance) getActiveChar()).isInOlympiadMode())
-                {
-                    stopHpMpRegeneration();
-                    getActiveChar().setIsDead(true);
-                    getActiveChar().setIsPendingRevive(true);
-                    if (getActiveChar().getPet() != null)
-                    	getActiveChar().getPet().getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE, null);
-                    return;
-                }
-            }
-            
-            // first die (and calculate rewards), if currentHp < 0,
-            // then overhit may be calculated
-            if (Config.DEBUG)
-                _log.fine("char is dead.");
-            
-            // Start the doDie process
-            getActiveChar().doDie(attacker);
-            
-            if (getActiveChar() instanceof L2PcInstance) 
-            { 
-            	QuestState qs = ((L2PcInstance) getActiveChar()).getQuestState("255_Tutorial"); 
-            	if (qs != null) 
-            		qs.getQuest().notifyEvent("CE30", null, ((L2PcInstance) getActiveChar())); 
-            } 
-        }
-        else
-        {
-            // If we're dealing with an L2Attackable Instance and the attacker's hit didn't kill the mob, clear the over-hit flag
-            if (getActiveChar() instanceof L2Attackable)
-            {
-                ((L2Attackable) getActiveChar()).overhitEnabled(false);
-            }
-        }
-    }
-    
-    public void reduceMp(double value)
-    {
-        value = getCurrentMp() - value;
-        if (value < 0)
-            value = 0;
-        setCurrentMp(value);
-    }
-    
-    /**
-     * Remove the object from the list of L2Character that must be informed of HP/MP updates of this L2Character.<BR><BR>
-     *
-     * <B><U> Concept</U> :</B><BR><BR>
-     * Each L2Character owns a list called <B>_statusListener</B> that contains all L2PcInstance to inform of HP/MP updates.
-     * Players who must be informed are players that target this L2Character.
-     * When a RegenTask is in progress sever just need to go through this list to send Server->Client packet StatusUpdate.<BR><BR>
-     *
-     * <B><U> Example of use </U> :</B><BR><BR>
-     * <li> Untarget a PC or NPC</li><BR><BR>
-     *
-     * @param object L2Character to add to the listener
-     *
-     */
-    public final void removeStatusListener(L2Character object)
-    {
-        synchronized (getStatusListener())
-        {
-            getStatusListener().remove(object);
-        }
-    }
-    
-    /**
-     * Start the HP/MP/CP Regeneration task.<BR><BR>
-     *
-     * <B><U> Actions</U> :</B><BR><BR>
-     * <li>Calculate the regen task period </li>
-     * <li>Launch the HP/MP/CP Regeneration task with Medium priority </li><BR><BR>
-     *
-     */
-    public synchronized final void startHpMpRegeneration()
-    {
-        if (_regTask == null && !getActiveChar().isDead())
-        {
-            if (Config.DEBUG)
-                _log.fine("HP/MP/CP regen started");
-            
-            // Get the Regeneration periode
-            int period = Formulas.getRegeneratePeriod(getActiveChar());
-            
-            // Create the HP/MP/CP Regeneration task
-            _regTask = ThreadPoolManager.getInstance().scheduleEffectAtFixedRate(new RegenTask(), period, period);
-        }
-    }
-    
-    /**
-     * Stop the HP/MP/CP Regeneration task.<BR><BR>
-     *
-     * <B><U> Actions</U> :</B><BR><BR>
-     * <li>Set the RegenActive flag to False </li>
-     * <li>Stop the HP/MP/CP Regeneration task </li><BR><BR>
-     *
-     */
-    public synchronized final void stopHpMpRegeneration()
-    {
-        if (_regTask != null)
-        {
-            if (Config.DEBUG)
-                _log.fine("HP/MP/CP regen stop");
-            
-            // Stop the HP/MP/CP Regeneration task
-            _regTask.cancel(false);
-            _regTask = null;
-            
-            // Set the RegenActive flag to false
-            _flagsRegenActive = 0;
-        }
-    }
-    
-    // =========================================================
-    // Method - Private
-    
-    // =========================================================
-    // Property - Public
-    public L2Character getActiveChar()
-    {
-        return _activeChar;
-    }
-    
-    public final double getCurrentCp()
-    {
-        return _currentCp;
-    }
-    
-    public final void setCurrentCp(double newCp)
-    {
-        setCurrentCp(newCp, true);
-    }
-    
-    public final void setCurrentCp(double newCp, boolean broadcastPacket)
-    {
-    	// Get the Max CP of the L2Character
-        int maxCp = getActiveChar().getStat().getMaxCp();
-
-    	synchronized (this)
-        {
-        	if (getActiveChar().isDead()) return;
-            
-            if (newCp < 0)
-                newCp = 0;
-            
-            if (newCp >= maxCp)
-            {
-                // Set the RegenActive flag to false
-                _currentCp = maxCp;
-                _flagsRegenActive &= ~REGEN_FLAG_CP;
-                
-                // Stop the HP/MP/CP Regeneration task
-                if (_flagsRegenActive == 0)
-                    stopHpMpRegeneration();
-            }
-            else
-            {
-                // Set the RegenActive flag to true
-                _currentCp = newCp;
-                _flagsRegenActive |= REGEN_FLAG_CP;
-                
-                // Start the HP/MP/CP Regeneration task with Medium priority
-                startHpMpRegeneration();
-            }
-        }
-        
-        // Send the Server->Client packet StatusUpdate with current HP and MP to all other L2PcInstance to inform
-        if (broadcastPacket)
-            getActiveChar().broadcastStatusUpdate();
-    }
-    
-    public final double getCurrentHp()
-    {
-        return _currentHp;
-    }
-    
-    public final void setCurrentHp(double newHp)
-    {
-        setCurrentHp(newHp, true);
-    }
-    
-    public final void setCurrentHp(double newHp, boolean broadcastPacket)
-    {
-        // Get the Max HP of the L2Character
-        double maxHp = getActiveChar().getStat().getMaxHp();
-        
-        synchronized (this)
-        {
-            if (getActiveChar().isDead()) return;
-        	if (newHp >= maxHp)
-            {
-                // Set the RegenActive flag to false
-                _currentHp = maxHp;
-                _flagsRegenActive &= ~REGEN_FLAG_HP;
-                
-                // Stop the HP/MP/CP Regeneration task
-                if (_flagsRegenActive == 0)
-                    stopHpMpRegeneration();
-            }
-            else
-            {
-                // Set the RegenActive flag to true
-                _currentHp = newHp;
-                _flagsRegenActive |= REGEN_FLAG_HP;
-                
-                // Start the HP/MP/CP Regeneration task with Medium priority
-                startHpMpRegeneration();
-            }
-        }
-        
-        if (getActiveChar() instanceof L2PcInstance)
-        {
-            if (getCurrentHp() <= maxHp * .3)
-            {
-                QuestState qs = ((L2PcInstance) getActiveChar()).getQuestState("255_Tutorial");
-                if (qs != null)
-                    qs.getQuest().notifyEvent("CE45", null, ((L2PcInstance) getActiveChar()));
-            }
-        }
-        
-        // Send the Server->Client packet StatusUpdate with current HP and MP to all other L2PcInstance to inform
-        if (broadcastPacket)
-            getActiveChar().broadcastStatusUpdate();
-    }
-    
-    public final void setCurrentHpMp(double newHp, double newMp)
-    {
-        setCurrentHp(newHp, false);
-        setCurrentMp(newMp, true); //send the StatusUpdate only once
-    }
-    
-    public final double getCurrentMp()
-    {
-        return _currentMp;
-    }
-    
-    public final void setCurrentMp(double newMp)
-    {
-        setCurrentMp(newMp, true);
-    }
-    
-    public final void setCurrentMp(double newMp, boolean broadcastPacket)
-    {
-    	// Get the Max MP of the L2Character
-        int maxMp = getActiveChar().getStat().getMaxMp();
-        
-    	synchronized (this)
-        {
-        	if (getActiveChar().isDead()) return;
-            
-            if (newMp >= maxMp)
-            {
-                // Set the RegenActive flag to false
-                _currentMp = maxMp;
-                _flagsRegenActive &= ~REGEN_FLAG_MP;
-                
-                // Stop the HP/MP/CP Regeneration task
-                if (_flagsRegenActive == 0)
-                    stopHpMpRegeneration();
-            }
-            else
-            {
-                // Set the RegenActive flag to true
-                _currentMp = newMp;
-                _flagsRegenActive |= REGEN_FLAG_MP;
-                
-                // Start the HP/MP/CP Regeneration task with Medium priority
-                startHpMpRegeneration();
-            }
-        }
-        
-        // Send the Server->Client packet StatusUpdate with current HP and MP to all other L2PcInstance to inform
-        if (broadcastPacket)
-            getActiveChar().broadcastStatusUpdate();
-    }
-    
-    /**
-     * Return the list of L2Character that must be informed of HP/MP updates of this L2Character.<BR><BR>
-     *
-     * <B><U> Concept</U> :</B><BR><BR>
-     * Each L2Character owns a list called <B>_statusListener</B> that contains all L2PcInstance to inform of HP/MP updates.
-     * Players who must be informed are players that target this L2Character.
-     * When a RegenTask is in progress sever just need to go through this list to send Server->Client packet StatusUpdate.<BR><BR>
-     *
-     * @return The list of L2Character to inform or null if empty
-     *
-     */
-    public final Set<L2Character> getStatusListener()
-    {
-        if (_StatusListener == null)
-            _StatusListener = new CopyOnWriteArraySet<L2Character>();
-        return _StatusListener;
-    }
-    
-    // =========================================================
-    // Runnable
-    /** Task of HP/MP/CP regeneration */
-    class RegenTask implements Runnable
-    {
-        public void run()
-        {
-            try
-            {
-                CharStat charstat = getActiveChar().getStat();
-                
-                // Modify the current CP of the L2Character and broadcast Server->Client packet StatusUpdate
-                if (getCurrentCp() < charstat.getMaxCp())
-                    setCurrentCp(getCurrentCp()
-                            + Formulas.calcCpRegen(getActiveChar()), false);
-                
-                // Modify the current HP of the L2Character and broadcast Server->Client packet StatusUpdate
-                if (getCurrentHp() < charstat.getMaxHp())
-                    setCurrentHp(getCurrentHp()
-                            + Formulas.calcHpRegen(getActiveChar()), false);
-                
-                // Modify the current MP of the L2Character and broadcast Server->Client packet StatusUpdate
-                if (getCurrentMp() < charstat.getMaxMp())
-                    setCurrentMp(getCurrentMp()
-                            + Formulas.calcMpRegen(getActiveChar()), false);
-                
-                if (!getActiveChar().isInActiveRegion())
-                {
-                    // no broadcast necessary for characters that are in inactive regions.
-                    // stop regeneration for characters who are filled up and in an inactive region.
-                    if ((getCurrentCp() == charstat.getMaxCp())
-                            && (getCurrentHp() == charstat.getMaxHp())
-                            && (getCurrentMp() == charstat.getMaxMp()))
-                        stopHpMpRegeneration();
-                }
-                else
-                    getActiveChar().broadcastStatusUpdate(); //send the StatusUpdate packet
-            }
-            catch (Exception e)
-            {
-                _log.log(Level.SEVERE, "", e);
-            }
-        }
-    }
+	public L2Character getActiveChar()
+	{
+		return _activeChar;
+	}
 }

+ 9 - 19
L2_GameServer/java/net/sf/l2j/gameserver/model/actor/status/DoorStatus.java

@@ -18,24 +18,14 @@ import net.sf.l2j.gameserver.model.actor.instance.L2DoorInstance;
 
 public class DoorStatus extends CharStatus
 {
-    // =========================================================
-    // Data Field
+	public DoorStatus(L2DoorInstance activeChar)
+	{
+		super(activeChar);
+	}
 
-    // =========================================================
-    // Constructor
-    public DoorStatus(L2DoorInstance activeChar)
-    {
-        super(activeChar);
-    }
-
-    // =========================================================
-    // Method - Public
-
-    // =========================================================
-    // Method - Private
-
-    // =========================================================
-    // Property - Public
-    @Override
-	public L2DoorInstance getActiveChar() { return (L2DoorInstance)super.getActiveChar(); }
+	@Override
+	public L2DoorInstance getActiveChar()
+	{
+		return (L2DoorInstance)super.getActiveChar();
+	}
 }

+ 22 - 23
L2_GameServer/java/net/sf/l2j/gameserver/model/actor/status/FolkStatus.java

@@ -20,31 +20,30 @@ import net.sf.l2j.gameserver.model.actor.instance.L2NpcInstance;
 
 public class FolkStatus extends NpcStatus
 {
-    // =========================================================
-    // Data Field
+	public FolkStatus(L2Npc activeChar)
+	{
+		super(activeChar);
+	}
 
-    // =========================================================
-    // Constructor
-    public FolkStatus(L2Npc activeChar)
-    {
-        super(activeChar);
-    }
+	@Override
+	public final void reduceHp(double value, L2Character attacker)
+	{
+		reduceHp(value, attacker, true, false, false);
+	}
 
-    // =========================================================
-    // Method - Public
-    @Override
-	public final void reduceHp(double value, L2Character attacker) { reduceHp(value, attacker, true, false, false); }
-
-    @Override
+	@Override
 	public final void reduceHp(double value, L2Character attacker, boolean awake, boolean isDOT, boolean isHpConsumption)
-    {
-    }
-    
-    @Override
-    public final void reduceMp(double value)
-    {
-    }
+	{
+	}
+
+	@Override
+	public final void reduceMp(double value)
+	{
+	}
 
-    @Override
-	public L2NpcInstance getActiveChar() { return (L2NpcInstance)super.getActiveChar(); }
+	@Override
+	public L2NpcInstance getActiveChar()
+	{
+		return (L2NpcInstance)super.getActiveChar();
+	}
 }

+ 31 - 35
L2_GameServer/java/net/sf/l2j/gameserver/model/actor/status/NpcStatus.java

@@ -17,47 +17,43 @@ package net.sf.l2j.gameserver.model.actor.status;
 import net.sf.l2j.gameserver.model.actor.L2Character;
 import net.sf.l2j.gameserver.model.actor.L2Npc;
 import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
+import net.sf.l2j.gameserver.model.entity.Duel;
 
 public class NpcStatus extends CharStatus
 {
-    // =========================================================
-    // Data Field
-
-    // =========================================================
-    // Constructor
-    public NpcStatus(L2Npc activeChar)
-    {
-        super(activeChar);
-    }
-
-    // =========================================================
-    // Method - Public
-    @Override
-	public void reduceHp(double value, L2Character attacker) { reduceHp(value, attacker, true, false, false); }
-
-    @Override
+	public NpcStatus(L2Npc activeChar)
+	{
+		super(activeChar);
+	}
+
+	@Override
+	public void reduceHp(double value, L2Character attacker)
+	{
+		reduceHp(value, attacker, true, false, false);
+	}
+
+	@Override
 	public void reduceHp(double value, L2Character attacker, boolean awake, boolean isDOT, boolean isHpConsumption)
-    {
-        if (getActiveChar().isDead()) return;
-        
-        if (attacker instanceof L2PcInstance)
-		{
-			L2PcInstance pcInst = (L2PcInstance)attacker;
-			if (pcInst.isGM() && !pcInst.getAccessLevel().canGiveDamage())
-				return;
-		}
+	{
+		if (getActiveChar().isDead())
+			return;
 
-        // Add attackers to npc's attacker list
-        if (attacker != null) getActiveChar().addAttackerToAttackByList(attacker);
+		if (attacker != null)
+		{
+			final L2PcInstance attackerPlayer = attacker.getActingPlayer();
+			if (attackerPlayer != null && attackerPlayer.isInDuel())
+				attackerPlayer.setDuelState(Duel.DUELSTATE_INTERRUPTED);
 
-        super.reduceHp(value, attacker, awake, isDOT, isHpConsumption);
-    }
+			// Add attackers to npc's attacker list
+			getActiveChar().addAttackerToAttackByList(attacker);
+		}
 
-    // =========================================================
-    // Method - Private
+		super.reduceHp(value, attacker, awake, isDOT, isHpConsumption);
+	}
 
-    // =========================================================
-    // Property - Public
-    @Override
-	public L2Npc getActiveChar() { return (L2Npc)super.getActiveChar(); }
+	@Override
+	public L2Npc getActiveChar()
+	{
+		return (L2Npc)super.getActiveChar();
+	}
 }

+ 170 - 10
L2_GameServer/java/net/sf/l2j/gameserver/model/actor/status/PcStatus.java

@@ -14,43 +14,84 @@
  */
 package net.sf.l2j.gameserver.model.actor.status;
 
+import net.sf.l2j.gameserver.ai.CtrlIntention;
+import net.sf.l2j.gameserver.instancemanager.DuelManager;
 import net.sf.l2j.gameserver.model.actor.L2Character;
 import net.sf.l2j.gameserver.model.actor.L2Playable;
 import net.sf.l2j.gameserver.model.actor.L2Summon;
 import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
 import net.sf.l2j.gameserver.model.actor.instance.L2SummonInstance;
+import net.sf.l2j.gameserver.model.actor.stat.PcStat;
 import net.sf.l2j.gameserver.model.entity.Duel;
+import net.sf.l2j.gameserver.model.quest.QuestState;
 import net.sf.l2j.gameserver.network.SystemMessageId;
+import net.sf.l2j.gameserver.network.serverpackets.ActionFailed;
 import net.sf.l2j.gameserver.network.serverpackets.SystemMessage;
+import net.sf.l2j.gameserver.skills.Formulas;
 import net.sf.l2j.gameserver.skills.Stats;
 import net.sf.l2j.gameserver.util.Util;
+import net.sf.l2j.util.Rnd;
 
 public class PcStatus extends PlayableStatus
 {
+	private double _currentCp = 0; //Current CP of the L2PcInstance
+
 	public PcStatus(L2PcInstance activeChar)
 	{
 		super(activeChar);
 	}
 
 	@Override
-	public final void reduceHp(double value, L2Character attacker) { reduceHp(value, attacker, true, false, false); }
+	public final void reduceCp(int value)
+	{
+		if (getCurrentCp() > value)
+			setCurrentCp(getCurrentCp() - value);
+		else
+			setCurrentCp(0);
+	}
 
 	@Override
-	public final void reduceHp(double value, L2Character attacker, boolean awake, boolean isDOT, boolean isHpConsumption)
+	public final void reduceHp(double value, L2Character attacker)
 	{
+		reduceHp(value, attacker, true, false, false);
+	}
+
+	@Override
+	public final void reduceHp(double value, L2Character attacker, boolean awake, boolean isDOT, boolean isHPConsumption)
+	{
+		if (getActiveChar().isDead())
+			return;
+
 		if (getActiveChar().isInvul())
 		{
 			if (attacker == getActiveChar())
 			{
-				if (!isDOT && !isHpConsumption)
+				if (!isDOT && !isHPConsumption)
 					return;
 			}
 			else
 				return;
 		}
 
-		if (getActiveChar().isDead())
-			return;
+		if (!isHPConsumption)
+		{
+			if (awake && getActiveChar().isSleeping())
+				getActiveChar().stopSleeping(null);
+			
+			if (getActiveChar().isSitting())
+				getActiveChar().standUp();
+
+			if (getActiveChar().isFakeDeath())
+				getActiveChar().stopFakeDeath(null);
+
+			if (!isDOT)
+			{
+				if (getActiveChar().isStunned() && Rnd.get(10) == 0)
+					getActiveChar().stopStunning(null);
+				if (getActiveChar().isImmobileUntilAttacked())
+					getActiveChar().stopImmobileUntilAttacked(null);
+			}
+		}
 
 		int fullValue = (int) value;
 		int tDmg = 0;
@@ -137,13 +178,132 @@ public class PcStatus extends PlayableStatus
 			}
 		}
 
-		if (!getActiveChar().isDead() && getActiveChar().isSitting() && !isDOT)
-			getActiveChar().standUp();
+		if (value > 0)
+		{
+			value = getCurrentHp() - value;
+			if (value <= 0)
+			{
+				if (getActiveChar().isInDuel())
+				{
+					getActiveChar().disableAllSkills();
+					stopHpMpRegeneration();
+					attacker.getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
+					attacker.sendPacket(ActionFailed.STATIC_PACKET);
+
+					// let the DuelManager know of his defeat
+					DuelManager.getInstance().onPlayerDefeat(getActiveChar());
+					value = 1;
+				}
+				else
+					value = 0;
+			}
+			setCurrentHp(value);
+		}
+
+		if (getActiveChar().getCurrentHp() < 0.5)
+		{
+			getActiveChar().abortAttack();
+			getActiveChar().abortCast();
+
+			if (getActiveChar().isInOlympiadMode())
+			{
+				stopHpMpRegeneration();
+				getActiveChar().setIsDead(true);
+				getActiveChar().setIsPendingRevive(true);
+				if (getActiveChar().getPet() != null)
+					getActiveChar().getPet().getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE, null);
+				return;
+			}
+
+			getActiveChar().doDie(attacker);
+			QuestState qs = getActiveChar().getQuestState("255_Tutorial");
+			if (qs != null)
+				qs.getQuest().notifyEvent("CE30", null, getActiveChar());
+		}
+	}
+
+	@Override
+	public final void setCurrentHp(double newHp, boolean broadcastPacket)
+	{
+		super.setCurrentHp(newHp, broadcastPacket);
+
+		if (getCurrentHp() <= getActiveChar().getStat().getMaxHp() * .3)
+		{
+			QuestState qs = getActiveChar().getQuestState("255_Tutorial");
+			if (qs != null)
+				qs.getQuest().notifyEvent("CE45", null, getActiveChar());
+        }
+	}
+
+	@Override
+	public final double getCurrentCp()
+	{
+		return _currentCp;
+	}
+
+	@Override
+	public final void setCurrentCp(double newCp)
+	{
+		setCurrentCp(newCp, true);
+	}
+
+	public final void setCurrentCp(double newCp, boolean broadcastPacket)
+	{
+		// Get the Max CP of the L2Character
+		int maxCp = getActiveChar().getStat().getMaxCp();
+
+		synchronized (this)
+		{
+			if (getActiveChar().isDead())
+				return;
+
+			if (newCp < 0)
+				newCp = 0;
+
+			if (newCp >= maxCp)
+			{
+				// Set the RegenActive flag to false
+				_currentCp = maxCp;
+				_flagsRegenActive &= ~REGEN_FLAG_CP;
+
+				// Stop the HP/MP/CP Regeneration task
+				if (_flagsRegenActive == 0)
+					stopHpMpRegeneration();
+			}
+			else
+			{
+				// Set the RegenActive flag to true
+				_currentCp = newCp;
+				_flagsRegenActive |= REGEN_FLAG_CP;
+
+				// Start the HP/MP/CP Regeneration task with Medium priority
+				startHpMpRegeneration();
+			}
+		}
+
+		// Send the Server->Client packet StatusUpdate with current HP and MP to all other L2PcInstance to inform
+		if (broadcastPacket)
+			getActiveChar().broadcastStatusUpdate();
+	}
+
+	@Override
+	protected void doRegeneration()
+	{
+		final PcStat charstat = getActiveChar().getStat();
+
+		// Modify the current CP of the L2Character and broadcast Server->Client packet StatusUpdate
+		if (getCurrentCp() < charstat.getMaxCp())
+			setCurrentCp(getCurrentCp() + Formulas.calcCpRegen(getActiveChar()), false);
+
+		// Modify the current HP of the L2Character and broadcast Server->Client packet StatusUpdate
+		if (getCurrentHp() < charstat.getMaxHp())
+			setCurrentHp(getCurrentHp() + Formulas.calcHpRegen(getActiveChar()), false);
 
-		if (getActiveChar().isFakeDeath() && !isDOT)
-			getActiveChar().stopFakeDeath(null);
+		// Modify the current MP of the L2Character and broadcast Server->Client packet StatusUpdate
+		if (getCurrentMp() < charstat.getMaxMp())
+			setCurrentMp(getCurrentMp() + Formulas.calcMpRegen(getActiveChar()), false);
 
-		super.reduceHp(value, attacker, awake, isDOT, isHpConsumption);
+		getActiveChar().broadcastStatusUpdate(); //send the StatusUpdate packet
 	}
 
 	@Override

+ 41 - 37
L2_GameServer/java/net/sf/l2j/gameserver/model/actor/status/PetStatus.java

@@ -22,49 +22,53 @@ import net.sf.l2j.gameserver.network.serverpackets.SystemMessage;
 
 public class PetStatus extends SummonStatus
 {
-    // =========================================================
-    // Data Field
-    private int _currentFed               = 0; //Current Fed of the L2PetInstance
+	private int _currentFed               = 0; //Current Fed of the L2PetInstance
 
-    // =========================================================
-    // Constructor
-    public PetStatus(L2PetInstance activeChar)
-    {
-        super(activeChar);
-    }
+	public PetStatus(L2PetInstance activeChar)
+	{
+		super(activeChar);
+	}
 
-    // =========================================================
-    // Method - Public
-    @Override
-	public final void reduceHp(double value, L2Character attacker) { reduceHp(value, attacker, true, false, false); }
-    @Override
+	@Override
+	public final void reduceHp(double value, L2Character attacker)
+	{
+		reduceHp(value, attacker, true, false, false);
+	}
+
+	@Override
 	public final void reduceHp(double value, L2Character attacker, boolean awake, boolean isDOT, boolean isHpConsumption)
-    {
-        if (getActiveChar().isDead()) return;
+	{
+		if (getActiveChar().isDead())
+			return;
 
-        super.reduceHp(value, attacker, awake, isDOT, isHpConsumption);
+		super.reduceHp(value, attacker, awake, isDOT, isHpConsumption);
 
-        if (attacker != null)
-        {
-        	if (!isDOT)
-        	{
-        		SystemMessage sm = new SystemMessage(SystemMessageId.PET_RECEIVED_S2_DAMAGE_BY_C1);
-        		sm.addCharName(attacker);
-        		sm.addNumber((int)value);
-        		getActiveChar().getOwner().sendPacket(sm);
-        	}
-            getActiveChar().getAI().notifyEvent(CtrlEvent.EVT_ATTACKED, attacker);
-        }
-    }
+		if (attacker != null)
+		{
+			if (!isDOT && getActiveChar().getOwner() != null)
+			{
+				SystemMessage sm = new SystemMessage(SystemMessageId.PET_RECEIVED_S2_DAMAGE_BY_C1);
+				sm.addCharName(attacker);
+				sm.addNumber((int)value);
+				getActiveChar().getOwner().sendPacket(sm);
+			}
+			getActiveChar().getAI().notifyEvent(CtrlEvent.EVT_ATTACKED, attacker);
+		}
+	}
 
-    // =========================================================
-    // Method - Private
+	public int getCurrentFed()
+	{
+		return _currentFed;
+	}
 
-    // =========================================================
-    // Property - Public
-    @Override
-	public L2PetInstance getActiveChar() { return (L2PetInstance)super.getActiveChar(); }
+	public void setCurrentFed(int value)
+	{
+		_currentFed = value;
+	}
 
-    public int getCurrentFed() { return _currentFed; }
-    public void setCurrentFed(int value) { _currentFed = value; }
+	@Override
+	public L2PetInstance getActiveChar()
+	{
+		return (L2PetInstance)super.getActiveChar();
+	}
 }

+ 10 - 43
L2_GameServer/java/net/sf/l2j/gameserver/model/actor/status/PlayableStatus.java

@@ -14,51 +14,18 @@
  */
 package net.sf.l2j.gameserver.model.actor.status;
 
-import net.sf.l2j.gameserver.model.actor.L2Character;
 import net.sf.l2j.gameserver.model.actor.L2Playable;
 
 public class PlayableStatus extends CharStatus
 {
-    // =========================================================
-    // Data Field
-
-    // =========================================================
-    // Constructor
-    public PlayableStatus(L2Playable activeChar)
-    {
-        super(activeChar);
-    }
-
-    // =========================================================
-    // Method - Public
-    @Override
-	public void reduceHp(double value, L2Character attacker) { reduceHp(value, attacker, true, false, false); }
-    @Override
-	public void reduceHp(double value, L2Character attacker, boolean awake, boolean isDOT, boolean isHPConsumption)
-    {
-        if (getActiveChar().isDead()) return;
-
-        super.reduceHp(value, attacker, awake, isDOT, isHPConsumption);
-        /*
-        if (attacker != null && attacker != getActiveChar())
-        {
-            // Flag the attacker if it's a L2PcInstance outside a PvP area
-            L2PcInstance player = null;
-            if (attacker instanceof L2PcInstance)
-                player = (L2PcInstance)attacker;
-            else if (attacker instanceof L2Summon)
-                player = ((L2Summon)attacker).getOwner();
-
-            if (player != null) player.updatePvPStatus(getActiveChar());
-        }
-        */
-    }
-
-    // =========================================================
-    // Method - Private
-
-    // =========================================================
-    // Property - Public
-    @Override
-	public L2Playable getActiveChar() { return (L2Playable)super.getActiveChar(); }
+	public PlayableStatus(L2Playable activeChar)
+	{
+		super(activeChar);
+	}
+
+	@Override
+	public L2Playable getActiveChar()
+	{
+		return (L2Playable)super.getActiveChar();
+	}
 }

+ 7 - 4
L2_GameServer/java/net/sf/l2j/gameserver/model/actor/status/SiegeFlagStatus.java

@@ -9,19 +9,22 @@ public class SiegeFlagStatus extends NpcStatus
 	{
 		super(activeChar);
 	}
-	
+
 	@Override
-	public void reduceHp(double value, L2Character attacker) { reduceHp(value, attacker, true, false, false); }
+	public void reduceHp(double value, L2Character attacker)
+	{
+		reduceHp(value, attacker, true, false, false);
+	}
 
 	@Override
 	public void reduceHp(double value, L2Character attacker, boolean awake, boolean isDOT, boolean isHpConsumption)
 	{
 		if (getActiveChar().isAdvancedHeadquarter())
 			value /= 2.;
-		
+
 		super.reduceHp(value, attacker, awake, isDOT, isHpConsumption);
 	}
-	
+
 	@Override
 	public L2SiegeFlagInstance getActiveChar()
 	{

+ 9 - 19
L2_GameServer/java/net/sf/l2j/gameserver/model/actor/status/StaticObjStatus.java

@@ -18,24 +18,14 @@ import net.sf.l2j.gameserver.model.actor.instance.L2StaticObjectInstance;
 
 public class StaticObjStatus extends CharStatus
 {
-    // =========================================================
-    // Data Field
+	public StaticObjStatus(L2StaticObjectInstance activeChar)
+	{
+		super(activeChar);
+	}
 
-    // =========================================================
-    // Constructor
-    public StaticObjStatus(L2StaticObjectInstance activeChar)
-    {
-        super(activeChar);
-    }
-
-    // =========================================================
-    // Method - Public
-
-    // =========================================================
-    // Method - Private
-
-    // =========================================================
-    // Property - Public
-    @Override
-	public L2StaticObjectInstance getActiveChar() { return (L2StaticObjectInstance)super.getActiveChar(); }
+	@Override
+	public L2StaticObjectInstance getActiveChar()
+	{
+		return (L2StaticObjectInstance)super.getActiveChar();
+	}
 }

+ 32 - 16
L2_GameServer/java/net/sf/l2j/gameserver/model/actor/status/SummonStatus.java

@@ -14,28 +14,44 @@
  */
 package net.sf.l2j.gameserver.model.actor.status;
 
+import net.sf.l2j.gameserver.model.actor.L2Character;
 import net.sf.l2j.gameserver.model.actor.L2Summon;
+import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
+import net.sf.l2j.gameserver.model.entity.Duel;
 
 public class SummonStatus extends PlayableStatus
 {
-    // =========================================================
-    // Data Field
+	public SummonStatus(L2Summon activeChar)
+	{
+		super(activeChar);
+	}
 
-    // =========================================================
-    // Constructor
-    public SummonStatus(L2Summon activeChar)
-    {
-        super(activeChar);
-    }
+	@Override
+	public void reduceHp(double value, L2Character attacker)
+	{
+		reduceHp(value, attacker, true, false, false);
+	}
 
-    // =========================================================
-    // Method - Public
+	@Override
+	public void reduceHp(double value, L2Character attacker, boolean awake, boolean isDOT, boolean isHPConsumption)
+	{
+		if (getActiveChar().isDead())
+			return;
 
-    // =========================================================
-    // Method - Private
+		if (attacker != null)
+		{
+			final L2PcInstance attackerPlayer = attacker.getActingPlayer();
+			if (attackerPlayer != null
+					&& (getActiveChar().getOwner() == null
+							|| getActiveChar().getOwner().getDuelId() != attackerPlayer.getDuelId()))
+				attackerPlayer.setDuelState(Duel.DUELSTATE_INTERRUPTED);
+		}
+		super.reduceHp(value, attacker, awake, isDOT, isHPConsumption);
+	}
 
-    // =========================================================
-    // Property - Public
-    @Override
-	public L2Summon getActiveChar() { return (L2Summon)super.getActiveChar(); }
+	@Override
+	public L2Summon getActiveChar()
+	{
+		return (L2Summon)super.getActiveChar();
+	}
 }