Bladeren bron

BETA: Reworking Attack server packet:
* Fixed wrong logic causing to write more hits then it should (How the hell it was even working until now lol).
* Moved Hit class into own file.
* Sorted flag creation by mask id.
* Reworked a little hit creation.
* Added getter for soulshot - hasSoulshot().
* Added new method in L2GameServerPacket writeLoc(Location) it will write 3 32bit int values (x, y, z).
* Reviewed by: Zoey76

Rumen Nikiforov 12 jaren geleden
bovenliggende
commit
2a2b746637

+ 75 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/Hit.java

@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2004-2013 L2J Server
+ * 
+ * This file is part of L2J Server.
+ * 
+ * L2J Server 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.
+ * 
+ * L2J Server 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 com.l2jserver.gameserver.model;
+
+/**
+ * @author UnAfraid
+ */
+public class Hit
+{
+	private static final int HITFLAG_USESS = 0x10;
+	private static final int HITFLAG_CRIT = 0x20;
+	private static final int HITFLAG_SHLD = 0x40;
+	private static final int HITFLAG_MISS = 0x80;
+	
+	private final int _targetId;
+	private final int _damage;
+	private int _flags = 0;
+	
+	public Hit(L2Object target, int damage, boolean miss, boolean crit, byte shld, boolean soulshot, int ssGrade)
+	{
+		_targetId = target.getObjectId();
+		_damage = damage;
+		
+		if (soulshot)
+		{
+			_flags |= HITFLAG_USESS | ssGrade;
+		}
+		
+		if (crit)
+		{
+			_flags |= HITFLAG_CRIT;
+		}
+		
+		if (shld > 0)
+		{
+			_flags |= HITFLAG_SHLD;
+		}
+		
+		if (miss)
+		{
+			_flags |= HITFLAG_MISS;
+		}
+	}
+	
+	public int getTargetId()
+	{
+		return _targetId;
+	}
+	
+	public int getDamage()
+	{
+		return _damage;
+	}
+	
+	public int getFlags()
+	{
+		return _flags;
+	}
+}

+ 15 - 14
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/L2Character.java

@@ -1184,7 +1184,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder
 			crit1 = Formulas.calcCrit(getStat().getCriticalHit(target, null), false, target);
 			
 			// Calculate physical damages
-			damage1 = (int) Formulas.calcPhysDam(this, target, null, shld1, crit1, attack.soulshot);
+			damage1 = (int) Formulas.calcPhysDam(this, target, null, shld1, crit1, attack.hasSoulshot());
 			
 			// Bows Ranged Damage Formula (Damage gradually decreases when 60% or lower than full hit range, and increases when 60% or higher).
 			// full hit range is 500 which is the base bow range, and the 60% of this is 800.
@@ -1198,13 +1198,13 @@ public abstract class L2Character extends L2Object implements ISkillsHolder
 		}
 		
 		// Create a new hit task with Medium priority
-		ThreadPoolManager.getInstance().scheduleAi(new HitTask(target, damage1, crit1, miss1, attack.soulshot, shld1), sAtk);
+		ThreadPoolManager.getInstance().scheduleAi(new HitTask(target, damage1, crit1, miss1, attack.hasSoulshot(), shld1), sAtk);
 		
 		// Calculate and set the disable delay of the bow in function of the Attack Speed
 		_disableBowAttackEndTime = ((sAtk + reuse) / GameTimeController.MILLIS_IN_TICK) + GameTimeController.getInstance().getGameTicks();
 		
 		// Add this hit to the Server-Client packet Attack
-		attack.hit(attack.createHit(target, damage1, miss1, crit1, shld1));
+		attack.addHit(target, damage1, miss1, crit1, shld1);
 		
 		// Return true if hit isn't missed
 		return !miss1;
@@ -1253,7 +1253,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder
 			crit1 = Formulas.calcCrit(getStat().getCriticalHit(target, null), false, target);
 			
 			// Calculate physical damages
-			damage1 = (int) Formulas.calcPhysDam(this, target, null, shld1, crit1, attack.soulshot);
+			damage1 = (int) Formulas.calcPhysDam(this, target, null, shld1, crit1, attack.hasSoulshot());
 		}
 		
 		// Check if the L2Character is a L2PcInstance
@@ -1268,13 +1268,13 @@ public abstract class L2Character extends L2Object implements ISkillsHolder
 		}
 		
 		// Create a new hit task with Medium priority
-		ThreadPoolManager.getInstance().scheduleAi(new HitTask(target, damage1, crit1, miss1, attack.soulshot, shld1), sAtk);
+		ThreadPoolManager.getInstance().scheduleAi(new HitTask(target, damage1, crit1, miss1, attack.hasSoulshot(), shld1), sAtk);
 		
 		// Calculate and set the disable delay of the bow in function of the Attack Speed
 		_disableCrossBowAttackEndTime = ((sAtk + reuse) / GameTimeController.MILLIS_IN_TICK) + GameTimeController.getInstance().getGameTicks();
 		
 		// Add this hit to the Server-Client packet Attack
-		attack.hit(attack.createHit(target, damage1, miss1, crit1, shld1));
+		attack.addHit(target, damage1, miss1, crit1, shld1);
 		
 		// Return true if hit isn't missed
 		return !miss1;
@@ -1319,7 +1319,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder
 			crit1 = Formulas.calcCrit(getStat().getCriticalHit(target, null), false, target);
 			
 			// Calculate physical damages of hit 1
-			damage1 = (int) Formulas.calcPhysDam(this, target, null, shld1, crit1, attack.soulshot);
+			damage1 = (int) Formulas.calcPhysDam(this, target, null, shld1, crit1, attack.hasSoulshot());
 			damage1 /= 2;
 		}
 		
@@ -1333,18 +1333,19 @@ public abstract class L2Character extends L2Object implements ISkillsHolder
 			crit2 = Formulas.calcCrit(getStat().getCriticalHit(target, null), false, target);
 			
 			// Calculate physical damages of hit 2
-			damage2 = (int) Formulas.calcPhysDam(this, target, null, shld2, crit2, attack.soulshot);
+			damage2 = (int) Formulas.calcPhysDam(this, target, null, shld2, crit2, attack.hasSoulshot());
 			damage2 /= 2;
 		}
 		
 		// Create a new hit task with Medium priority for hit 1
-		ThreadPoolManager.getInstance().scheduleAi(new HitTask(target, damage1, crit1, miss1, attack.soulshot, shld1), sAtk / 2);
+		ThreadPoolManager.getInstance().scheduleAi(new HitTask(target, damage1, crit1, miss1, attack.hasSoulshot(), shld1), sAtk / 2);
 		
 		// Create a new hit task with Medium priority for hit 2 with a higher delay
-		ThreadPoolManager.getInstance().scheduleAi(new HitTask(target, damage2, crit2, miss2, attack.soulshot, shld2), sAtk);
+		ThreadPoolManager.getInstance().scheduleAi(new HitTask(target, damage2, crit2, miss2, attack.hasSoulshot(), shld2), sAtk);
 		
 		// Add those hits to the Server-Client packet Attack
-		attack.hit(attack.createHit(target, damage1, miss1, crit1, shld1), attack.createHit(target, damage2, miss2, crit2, shld2));
+		attack.addHit(target, damage1, miss1, crit1, shld1);
+		attack.addHit(target, damage2, miss2, crit2, shld2);
 		
 		// Return true if hit 1 or hit 2 isn't missed
 		return (!miss1 || !miss2);
@@ -1513,7 +1514,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder
 			crit1 = Formulas.calcCrit(getStat().getCriticalHit(target, null), false, target);
 			
 			// Calculate physical damages
-			damage1 = (int) Formulas.calcPhysDam(this, target, null, shld1, crit1, attack.soulshot);
+			damage1 = (int) Formulas.calcPhysDam(this, target, null, shld1, crit1, attack.hasSoulshot());
 			
 			if (attackpercent != 100)
 			{
@@ -1522,10 +1523,10 @@ public abstract class L2Character extends L2Object implements ISkillsHolder
 		}
 		
 		// Create a new hit task with Medium priority
-		ThreadPoolManager.getInstance().scheduleAi(new HitTask(target, damage1, crit1, miss1, attack.soulshot, shld1), sAtk);
+		ThreadPoolManager.getInstance().scheduleAi(new HitTask(target, damage1, crit1, miss1, attack.hasSoulshot(), shld1), sAtk);
 		
 		// Add this hit to the Server-Client packet Attack
-		attack.hit(attack.createHit(target, damage1, miss1, crit1, shld1));
+		attack.addHit(target, damage1, miss1, crit1, shld1);
 		
 		// Return true if hit isn't missed
 		return !miss1;

+ 55 - 98
L2J_Server_BETA/java/com/l2jserver/gameserver/network/serverpackets/Attack.java

@@ -18,137 +18,94 @@
  */
 package com.l2jserver.gameserver.network.serverpackets;
 
-import com.l2jserver.gameserver.model.L2Object;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import com.l2jserver.gameserver.model.Hit;
+import com.l2jserver.gameserver.model.Location;
 import com.l2jserver.gameserver.model.actor.L2Character;
-import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
 
 public class Attack extends L2GameServerPacket
 {
-	public static final int HITFLAG_USESS = 0x10;
-	public static final int HITFLAG_CRIT = 0x20;
-	public static final int HITFLAG_SHLD = 0x40;
-	public static final int HITFLAG_MISS = 0x80;
-	
-	public class Hit
-	{
-		protected final int _targetId;
-		protected final int _damage;
-		protected int _flags;
-		
-		Hit(L2Object target, int damage, boolean miss, boolean crit, byte shld)
-		{
-			_targetId = target.getObjectId();
-			_damage = damage;
-			if (miss)
-			{
-				_flags = HITFLAG_MISS;
-				return;
-			}
-			if (soulshot)
-			{
-				_flags = HITFLAG_USESS | _ssGrade;
-			}
-			if (crit)
-			{
-				_flags |= HITFLAG_CRIT;
-			}
-			// dirty fix for lags on olympiad
-			if ((shld > 0) && !((target instanceof L2PcInstance) && ((L2PcInstance) target).isInOlympiadMode()))
-			{
-				_flags |= HITFLAG_SHLD;
-				// if (shld > 0)
-				// _flags |= HITFLAG_SHLD;
-			}
-		}
-	}
-	
 	private final int _attackerObjId;
-	private final int _targetObjId;
-	public final boolean soulshot;
-	public final int _ssGrade;
-	private final int _x;
-	private final int _y;
-	private final int _z;
-	private final int _tx;
-	private final int _ty;
-	private final int _tz;
-	private Hit[] _hits;
+	private final boolean _soulshot;
+	private final int _ssGrade;
+	private final Location _attackerLoc;
+	private final Location _targetLoc;
+	private final List<Hit> _hits = new ArrayList<>();
 	
 	/**
-	 * @param attacker the attacking L2Character<br>
-	 * @param target the target L2Object<br>
-	 * @param useShots true if soulshots used
-	 * @param ssGrade the grade of the soulshots
+	 * @param attacker
+	 * @param target
+	 * @param useShots
+	 * @param ssGrade
 	 */
-	public Attack(L2Character attacker, L2Object target, boolean useShots, int ssGrade)
+	public Attack(L2Character attacker, L2Character target, boolean useShots, int ssGrade)
 	{
 		_attackerObjId = attacker.getObjectId();
-		_targetObjId = target.getObjectId();
-		soulshot = useShots;
+		_soulshot = useShots;
 		_ssGrade = ssGrade;
-		_x = attacker.getX();
-		_y = attacker.getY();
-		_z = attacker.getZ();
-		_tx = target.getX();
-		_ty = target.getY();
-		_tz = target.getZ();
+		_attackerLoc = new Location(attacker);
+		_targetLoc = new Location(target);
+	}
+	
+	/**
+	 * Adds hit to the attack (Attacks such as dual dagger/sword/fist has two hits)
+	 * @param target
+	 * @param damage
+	 * @param miss
+	 * @param crit
+	 * @param shld
+	 */
+	public void addHit(L2Character target, int damage, boolean miss, boolean crit, byte shld)
+	{
+		_hits.add(new Hit(target, damage, miss, crit, shld, _soulshot, _ssGrade));
 	}
 	
-	public Hit createHit(L2Object target, int damage, boolean miss, boolean crit, byte shld)
+	/**
+	 * @return {@code true} if current attack contains at least 1 hit.
+	 */
+	public boolean hasHits()
 	{
-		return new Hit(target, damage, miss, crit, shld);
+		return !_hits.isEmpty();
 	}
 	
-	public void hit(Hit... hits)
+	/**
+	 * @return {@code true} if attack has soul shot charged.
+	 */
+	public boolean hasSoulshot()
 	{
-		if (_hits == null)
-		{
-			_hits = hits;
-			return;
-		}
-		
-		// this will only happen with pole attacks
-		Hit[] tmp = new Hit[hits.length + _hits.length];
-		System.arraycopy(_hits, 0, tmp, 0, _hits.length);
-		System.arraycopy(hits, 0, tmp, _hits.length, hits.length);
-		_hits = tmp;
+		return _soulshot;
 	}
 	
 	/**
-	 * @return True if the Server-Client packet Attack contains at least 1 hit.
+	 * Writes current hit
+	 * @param hit
 	 */
-	public boolean hasHits()
+	private void writeHit(Hit hit)
 	{
-		return _hits != null;
+		writeD(hit.getTargetId());
+		writeD(hit.getDamage());
+		writeC(hit.getFlags());
 	}
 	
 	@Override
 	protected final void writeImpl()
 	{
+		final Iterator<Hit> it = _hits.iterator();
 		writeC(0x33);
 		
 		writeD(_attackerObjId);
-		writeD(_targetObjId);
-		writeD(_hits[0]._damage);
-		writeC(_hits[0]._flags);
-		writeD(_x);
-		writeD(_y);
-		writeD(_z);
+		writeHit(it.next());
+		writeLoc(_attackerLoc);
 		
-		writeH(_hits.length - 1);
-		// prevent sending useless packet while there is only one target.
-		if (_hits.length > 1)
+		writeH(_hits.size() - 1);
+		while (it.hasNext())
 		{
-			for (Hit hit : _hits)
-			{
-				writeD(hit._targetId);
-				writeD(hit._damage);
-				writeC(hit._flags);
-			}
+			writeHit(it.next());
 		}
 		
-		writeD(_tx);
-		writeD(_ty);
-		writeD(_tz);
+		writeLoc(_targetLoc);
 	}
 }

+ 12 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/network/serverpackets/L2GameServerPacket.java

@@ -24,6 +24,7 @@ import java.util.logging.Logger;
 import org.mmocore.network.SendablePacket;
 
 import com.l2jserver.Config;
+import com.l2jserver.gameserver.model.Location;
 import com.l2jserver.gameserver.network.L2GameClient;
 
 /**
@@ -53,6 +54,17 @@ public abstract class L2GameServerPacket extends SendablePacket<L2GameClient>
 		_invisible = b;
 	}
 	
+	/**
+	 * Writes 3 D (int32) with current location x, y, z
+	 * @param loc
+	 */
+	protected void writeLoc(Location loc)
+	{
+		writeD(loc.getX());
+		writeD(loc.getY());
+		writeD(loc.getZ());
+	}
+	
 	@Override
 	protected void write()
 	{