浏览代码

BETA: Skills rework:
* L2PcInstance:
* Removed isUsingDualWeapon() not used anymore.
* Removed custom check for Strider Siege Assault skill (new condition will be added soon).
* Fixed double system message when you use Soul Rage skill.
* Stats:
* Removed useless stats (LETHAL_RATE, AGGRESSION_VULN, AGGRESSION_PROF, CRIT_PROF, NONE_WPN_VULN, transformId).
* !SystemMessageId:
* Updated system message when you done damage on target.
* Added missing system message for Seven Signs quests (quests will be added soon).
* Formulas:
* Moved calcLethalHit in proper effect handler.
* Cleanup and fixes some methods.
* Fixing blow bonus when you hitting from the side of target.
* L2Character:
* Removed !CpConsume check and fixed skill Over the Body.
* L2CubicInstance:
* Added !CubicDrain method.
* Removed useless comment.
* Fixed Magical Critical Rate calculation.
* L2Skill:
* Removed staticDamage variable, now have own effect like retail.
* Removed canBeReflected variable, now have his proper checks.
* Cleanup and fixes some methods.
* L2SkillType:
* Deleted PDAM, MDAM, MANADAM, CPDAMPERCENT, DRAIN, DEATHLINK, FATAL, BLOW, STRSIEGEASSAULT and CHARGEDAM.
* L2EffectType:
* Added new effects DEATH_LINK, ENERGY_ATTACK, FATAL_BLOW, HP_DRAIN, LETHAL, MAGICAL_ATTACK, MAGICAL_ATTACK_MP, PHYSICAL_ATTACK, PHYSICAL_ATTACK_HP_LINK and STATIC_DAMAGE.
* Renamed !IncreaseCharges to !FocusEnergy and made effect retail like.
* Added new effect !FocusMaxEnergy.
* Effecthandlers
* Removed !StatusUpdate from some effect because is already updated by setCurrentHp, setCurrentMp and setCurrentCp methods.

'''NOTE''': New skill debugging will be added soon.

Reviewed by: MELERIX, Zoey76

Adry_85 12 年之前
父节点
当前提交
a3b7036391

+ 32 - 39
L2J_Server_BETA/java/com/l2jserver/gameserver/ai/L2AttackableAI.java

@@ -1614,44 +1614,6 @@ public class L2AttackableAI extends L2CharacterAI implements Runnable
 				}
 				break;
 			}
-			case PDAM:
-			case MDAM:
-			case BLOW:
-			case DRAIN:
-			case CHARGEDAM:
-			case FATAL:
-			case DEATHLINK:
-			case MANADAM:
-			case CPDAMPERCENT:
-			{
-				if (!canAura(sk))
-				{
-					if (GeoData.getInstance().canSeeTarget(caster, attackTarget) && !attackTarget.isDead() && (dist2 <= srange))
-					{
-						clientStopMoving(null);
-						caster.doCast(sk);
-						return true;
-					}
-					
-					L2Character target = skillTargetReconsider(sk);
-					if (target != null)
-					{
-						clientStopMoving(null);
-						L2Object targets = attackTarget;
-						caster.setTarget(target);
-						caster.doCast(sk);
-						caster.setTarget(targets);
-						return true;
-					}
-				}
-				else
-				{
-					clientStopMoving(null);
-					caster.doCast(sk);
-					return true;
-				}
-				break;
-			}
 			default:
 			{
 				if (sk.hasEffectType(L2EffectType.CANCEL, L2EffectType.CANCEL_ALL, L2EffectType.NEGATE))
@@ -1704,6 +1666,7 @@ public class L2AttackableAI extends L2CharacterAI implements Runnable
 						}
 					}
 				}
+				
 				if (sk.hasEffectType(L2EffectType.HEAL, L2EffectType.HEAL_PERCENT))
 				{
 					double percentage = (caster.getCurrentHp() / caster.getMaxHp()) * 100;
@@ -1782,6 +1745,36 @@ public class L2AttackableAI extends L2CharacterAI implements Runnable
 						}
 					}
 				}
+				
+				if (sk.hasEffectType(L2EffectType.PHYSICAL_ATTACK, L2EffectType.PHYSICAL_ATTACK_HP_LINK, L2EffectType.FATAL_BLOW, L2EffectType.ENERGY_ATTACK, L2EffectType.MAGICAL_ATTACK_MP, L2EffectType.MAGICAL_ATTACK, L2EffectType.DEATH_LINK, L2EffectType.HP_DRAIN))
+				{
+					if (!canAura(sk))
+					{
+						if (GeoData.getInstance().canSeeTarget(caster, attackTarget) && !attackTarget.isDead() && (dist2 <= srange))
+						{
+							clientStopMoving(null);
+							caster.doCast(sk);
+							return true;
+						}
+						
+						L2Character target = skillTargetReconsider(sk);
+						if (target != null)
+						{
+							clientStopMoving(null);
+							L2Object targets = attackTarget;
+							caster.setTarget(target);
+							caster.doCast(sk);
+							caster.setTarget(targets);
+							return true;
+						}
+					}
+					else
+					{
+						clientStopMoving(null);
+						caster.doCast(sk);
+						return true;
+					}
+				}
 				if (!canAura(sk))
 				{
 					
@@ -1812,8 +1805,8 @@ public class L2AttackableAI extends L2CharacterAI implements Runnable
 					// _actor.setTarget(targets);
 					return true;
 				}
-			}
 				break;
+			}
 		}
 		
 		return false;

+ 5 - 21
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, false, attack.soulshot);
+			damage1 = (int) Formulas.calcPhysDam(this, target, null, shld1, crit1, attack.soulshot);
 			
 			// 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.
@@ -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, false, attack.soulshot);
+			damage1 = (int) Formulas.calcPhysDam(this, target, null, shld1, crit1, attack.soulshot);
 		}
 		
 		// Check if the L2Character is a L2PcInstance
@@ -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, true, attack.soulshot);
+			damage1 = (int) Formulas.calcPhysDam(this, target, null, shld1, crit1, attack.soulshot);
 			damage1 /= 2;
 		}
 		
@@ -1333,7 +1333,7 @@ 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, true, attack.soulshot);
+			damage2 = (int) Formulas.calcPhysDam(this, target, null, shld2, crit2, attack.soulshot);
 			damage2 /= 2;
 		}
 		
@@ -1513,7 +1513,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, false, attack.soulshot);
+			damage1 = (int) Formulas.calcPhysDam(this, target, null, shld1, crit1, attack.soulshot);
 			
 			if (attackpercent != 100)
 			{
@@ -6254,22 +6254,6 @@ public abstract class L2Character extends L2Object implements ISkillsHolder
 				isSendStatus = true;
 			}
 			
-			// Consume CP if necessary and Send the Server->Client packet StatusUpdate with current CP/HP and MP to all other L2PcInstance to inform
-			if (skill.getCpConsume() > 0)
-			{
-				double consumeCp;
-				
-				consumeCp = skill.getCpConsume();
-				if ((consumeCp + 1) >= getCurrentHp())
-				{
-					consumeCp = getCurrentHp() - 1.0;
-				}
-				
-				getStatus().reduceCp((int) consumeCp);
-				su.addAttribute(StatusUpdate.CUR_CP, (int) getCurrentCp());
-				isSendStatus = true;
-			}
-			
 			// Send a Server->Client packet StatusUpdate with MP modification to the L2PcInstance
 			if (isSendStatus)
 			{

+ 1 - 1
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/L2Summon.java

@@ -802,7 +802,7 @@ public abstract class L2Summon extends L2Playable
 			}
 			else
 			{
-				sm = SystemMessage.getSystemMessage(SystemMessageId.C1_GAVE_C2_DAMAGE_OF_S3);
+				sm = SystemMessage.getSystemMessage(SystemMessageId.C1_DONE_S3_DAMAGE_TO_C2);
 				sm.addNpcName(this);
 				sm.addCharName(target);
 				sm.addNumber(damage);

+ 81 - 115
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/instance/L2CubicInstance.java

@@ -38,13 +38,13 @@ import com.l2jserver.gameserver.model.actor.L2Attackable;
 import com.l2jserver.gameserver.model.actor.L2Character;
 import com.l2jserver.gameserver.model.actor.L2Playable;
 import com.l2jserver.gameserver.model.effects.L2Effect;
+import com.l2jserver.gameserver.model.effects.L2EffectType;
 import com.l2jserver.gameserver.model.entity.TvTEvent;
 import com.l2jserver.gameserver.model.entity.TvTEventTeam;
 import com.l2jserver.gameserver.model.skills.L2Skill;
 import com.l2jserver.gameserver.model.skills.L2SkillType;
-import com.l2jserver.gameserver.model.skills.l2skills.L2SkillDrain;
-import com.l2jserver.gameserver.model.stats.BaseStats;
 import com.l2jserver.gameserver.model.stats.Formulas;
+import com.l2jserver.gameserver.model.stats.Stats;
 import com.l2jserver.gameserver.model.zone.ZoneId;
 import com.l2jserver.gameserver.network.SystemMessageId;
 import com.l2jserver.gameserver.network.serverpackets.MagicSkillUse;
@@ -144,84 +144,24 @@ public final class L2CubicInstance
 				_skills.add(SkillTable.getInstance().getInfo(5116, level));
 				break;
 			case SMART_CUBIC_ARCANALORD:
-				// _skills.add(SkillTable.getInstance().getInfo(4049,8)); no animation
-				// _skills.add(SkillTable.getInstance().getInfo(4050,7)); no animation
-				_skills.add(SkillTable.getInstance().getInfo(4051, 7)); // have animation
-				// _skills.add(SkillTable.getInstance().getInfo(4052,6)); no animation
-				// _skills.add(SkillTable.getInstance().getInfo(4053,8)); no animation
-				// _skills.add(SkillTable.getInstance().getInfo(4054,8)); no animation
-				// _skills.add(SkillTable.getInstance().getInfo(4055,8)); no animation
-				// _skills.add(SkillTable.getInstance().getInfo(4164,9)); no animation
-				_skills.add(SkillTable.getInstance().getInfo(4165, 9)); // have animation
-				// _skills.add(SkillTable.getInstance().getInfo(4166,9)); no animation
-				// _skills.add(SkillTable.getInstance().getInfo(5115,4)); no animation
-				// _skills.add(SkillTable.getInstance().getInfo(5116,4)); no animation
-				// _skills.add(SkillTable.getInstance().getInfo(5579,4)); no need to add to the
-				// cubic skills list
+				_skills.add(SkillTable.getInstance().getInfo(4051, 7));
+				_skills.add(SkillTable.getInstance().getInfo(4165, 9));
 				break;
 			case SMART_CUBIC_ELEMENTALMASTER:
-				_skills.add(SkillTable.getInstance().getInfo(4049, 8)); // have animation
-				// _skills.add(SkillTable.getInstance().getInfo(4050,7)); no animation
-				// _skills.add(SkillTable.getInstance().getInfo(4051,7)); no animation
-				// _skills.add(SkillTable.getInstance().getInfo(4052,6)); no animation
-				// _skills.add(SkillTable.getInstance().getInfo(4053,8)); no animation
-				// _skills.add(SkillTable.getInstance().getInfo(4054,8)); no animation
-				// _skills.add(SkillTable.getInstance().getInfo(4055,8)); no animation
-				// _skills.add(SkillTable.getInstance().getInfo(4164,9)); no animation
-				// _skills.add(SkillTable.getInstance().getInfo(4165,9)); no animation
-				_skills.add(SkillTable.getInstance().getInfo(4166, 9)); // have animation
-				// _skills.add(SkillTable.getInstance().getInfo(5115,4)); no animation
-				// _skills.add(SkillTable.getInstance().getInfo(5116,4)); no animation
-				// _skills.add(SkillTable.getInstance().getInfo(5579,4)); no need to add to the
-				// cubic skills list
+				_skills.add(SkillTable.getInstance().getInfo(4049, 8));
+				_skills.add(SkillTable.getInstance().getInfo(4166, 9));
 				break;
 			case SMART_CUBIC_SPECTRALMASTER:
-				_skills.add(SkillTable.getInstance().getInfo(4049, 8)); // have animation
-				// _skills.add(SkillTable.getInstance().getInfo(4050,7)); no animation
-				// _skills.add(SkillTable.getInstance().getInfo(4051,7)); no animation
-				_skills.add(SkillTable.getInstance().getInfo(4052, 6)); // have animation
-				// _skills.add(SkillTable.getInstance().getInfo(4053,8)); no animation
-				// _skills.add(SkillTable.getInstance().getInfo(4054,8)); no animation
-				// _skills.add(SkillTable.getInstance().getInfo(4055,8)); no animation
-				// _skills.add(SkillTable.getInstance().getInfo(4164,9)); no animation
-				// _skills.add(SkillTable.getInstance().getInfo(4165,9)); no animation
-				// _skills.add(SkillTable.getInstance().getInfo(4166,9)); no animation
-				// _skills.add(SkillTable.getInstance().getInfo(5115,4)); no animation
-				// _skills.add(SkillTable.getInstance().getInfo(5116,4)); no animation
-				// _skills.add(SkillTable.getInstance().getInfo(5579,4)); no need to add to the
-				// cubic skills list
+				_skills.add(SkillTable.getInstance().getInfo(4049, 8));
+				_skills.add(SkillTable.getInstance().getInfo(4052, 6));
 				break;
 			case SMART_CUBIC_EVATEMPLAR:
-				// _skills.add(SkillTable.getInstance().getInfo(4049,8)); no animation
-				// _skills.add(SkillTable.getInstance().getInfo(4050,7)); no animation
-				// _skills.add(SkillTable.getInstance().getInfo(4051,7)); no animation
-				// _skills.add(SkillTable.getInstance().getInfo(4052,6)); no animation
-				_skills.add(SkillTable.getInstance().getInfo(4053, 8)); // have animation
-				// _skills.add(SkillTable.getInstance().getInfo(4054,8)); no animation
-				// _skills.add(SkillTable.getInstance().getInfo(4055,8)); no animation
-				// _skills.add(SkillTable.getInstance().getInfo(4164,9)); no animation
-				_skills.add(SkillTable.getInstance().getInfo(4165, 9)); // have animation
-				// _skills.add(SkillTable.getInstance().getInfo(4166,9)); no animation
-				// _skills.add(SkillTable.getInstance().getInfo(5115,4)); no animation
-				// _skills.add(SkillTable.getInstance().getInfo(5116,4)); no animation
-				// _skills.add(SkillTable.getInstance().getInfo(5579,4)); no need to add to the
-				// cubic skills list
+				_skills.add(SkillTable.getInstance().getInfo(4053, 8));
+				_skills.add(SkillTable.getInstance().getInfo(4165, 9));
 				break;
 			case SMART_CUBIC_SHILLIENTEMPLAR:
-				_skills.add(SkillTable.getInstance().getInfo(4049, 8)); // have animation
-				// _skills.add(SkillTable.getInstance().getInfo(4050,7)); no animation
-				// _skills.add(SkillTable.getInstance().getInfo(4051,7)); no animation
-				// _skills.add(SkillTable.getInstance().getInfo(4052,6)); no animation
-				// _skills.add(SkillTable.getInstance().getInfo(4053,8)); no animation
-				// _skills.add(SkillTable.getInstance().getInfo(4054,8)); no animation
-				// _skills.add(SkillTable.getInstance().getInfo(4055,8)); no animation
-				// _skills.add(SkillTable.getInstance().getInfo(4164,9)); no animation
-				// _skills.add(SkillTable.getInstance().getInfo(4165,9)); no animation
-				// _skills.add(SkillTable.getInstance().getInfo(4166,9)); no animation
-				_skills.add(SkillTable.getInstance().getInfo(5115, 4)); // have animation
-				// _skills.add(SkillTable.getInstance().getInfo(5116,4)); no animation
-				// _skills.add(SkillTable.getInstance().getInfo(5579,4)); no need to add to the
-				// cubic skills list
+				_skills.add(SkillTable.getInstance().getInfo(4049, 8));
+				_skills.add(SkillTable.getInstance().getInfo(5115, 4));
 				break;
 		}
 		_disappearTask = ThreadPoolManager.getInstance().scheduleGeneral(new Disappear(), _cubicDuration); // disappear
@@ -268,12 +208,6 @@ public final class L2CubicInstance
 		return _owner;
 	}
 	
-	public final int getMCriticalHit(L2Character target, L2Skill skill)
-	{
-		// Magical Critical Rate for cubics is the base Magical Critical Rate of its owner
-		return (int) (BaseStats.WIT.calcBonus(_owner) * 10);
-	}
-	
 	public int getCubicPower()
 	{
 		return _cubicPower;
@@ -628,37 +562,38 @@ public final class L2CubicInstance
 								}
 								useCubicDisabler(type, L2CubicInstance.this, skill, targets);
 							}
-							else if (type == L2SkillType.MDAM)
+							else if ((type == L2SkillType.POISON) || (type == L2SkillType.DEBUFF) || (type == L2SkillType.DOT))
 							{
 								if (Config.DEBUG)
 								{
 									_log.info("L2CubicInstance: Action.run() handler " + type);
 								}
-								useCubicMdam(L2CubicInstance.this, skill, targets);
+								useCubicContinuous(L2CubicInstance.this, skill, targets);
 							}
-							else if ((type == L2SkillType.POISON) || (type == L2SkillType.DEBUFF) || (type == L2SkillType.DOT))
+							else
 							{
+								handler.useSkill(_owner, skill, targets);
 								if (Config.DEBUG)
 								{
-									_log.info("L2CubicInstance: Action.run() handler " + type);
+									_log.info("L2CubicInstance: Action.run(); other handler");
 								}
-								useCubicContinuous(L2CubicInstance.this, skill, targets);
 							}
-							else if (type == L2SkillType.DRAIN)
+							
+							if (skill.hasEffectType(L2EffectType.MAGICAL_ATTACK))
 							{
 								if (Config.DEBUG)
 								{
-									_log.info("L2CubicInstance: Action.run() skill " + type);
+									_log.info("L2CubicInstance: Action.run() handler " + type);
 								}
-								((L2SkillDrain) skill).useCubicSkill(L2CubicInstance.this, targets);
+								useCubicMdam(L2CubicInstance.this, skill, targets);
 							}
-							else
+							else if (skill.hasEffectType(L2EffectType.HP_DRAIN))
 							{
-								handler.useSkill(_owner, skill, targets);
 								if (Config.DEBUG)
 								{
-									_log.info("L2CubicInstance: Action.run(); other handler");
+									_log.info("L2CubicInstance: Action.run() skill " + type);
 								}
+								useCubicDrain(L2CubicInstance.this, skill, targets);
 							}
 							
 							// The cubic has done an action, increase the currentcount
@@ -698,14 +633,14 @@ public final class L2CubicInstance
 			// if this is a debuff let the duel manager know about it
 			// so the debuff can be removed after the duel
 			// (player & target must be in the same duel)
-			if ((target instanceof L2PcInstance) && ((L2PcInstance) target).isInDuel() && (skill.getSkillType() == L2SkillType.DEBUFF) && (activeCubic.getOwner().getDuelId() == ((L2PcInstance) target).getDuelId()))
+			if ((target.isPlayer()) && target.getActingPlayer().isInDuel() && (skill.getSkillType() == L2SkillType.DEBUFF) && (activeCubic.getOwner().getDuelId() == target.getActingPlayer().getDuelId()))
 			{
 				DuelManager dm = DuelManager.getInstance();
 				for (L2Effect debuff : skill.getEffects(activeCubic.getOwner(), target))
 				{
 					if (debuff != null)
 					{
-						dm.onBuff(((L2PcInstance) target), debuff);
+						dm.onBuff(target.getActingPlayer(), debuff);
 					}
 				}
 			}
@@ -727,7 +662,7 @@ public final class L2CubicInstance
 			
 			if (target.isAlikeDead())
 			{
-				if (target instanceof L2PcInstance)
+				if (target.isPlayer())
 				{
 					target.stopFakeDeath(true);
 				}
@@ -737,18 +672,10 @@ public final class L2CubicInstance
 				}
 			}
 			
-			boolean mcrit = Formulas.calcMCrit(activeCubic.getMCriticalHit(target, skill));
+			boolean mcrit = Formulas.calcMCrit(activeCubic.getOwner().getMCriticalHit(target, skill));
 			byte shld = Formulas.calcShldUse(activeCubic.getOwner(), target, skill);
 			int damage = (int) Formulas.calcMagicDam(activeCubic, target, skill, mcrit, shld);
 			
-			/*
-			 * If target is reflecting the skill then no damage is done Ignoring vengance-like reflections
-			 */
-			if ((Formulas.calcSkillReflect(target, skill) & Formulas.SKILL_REFLECT_SUCCEED) > 0)
-			{
-				damage = 0;
-			}
-			
 			if (Config.DEBUG)
 			{
 				_log.info("L2SkillMdam: useCubicSkill() -> damage = " + damage);
@@ -763,23 +690,62 @@ public final class L2CubicInstance
 					target.breakCast();
 				}
 				
-				activeCubic.getOwner().sendDamageMessage(target, damage, mcrit, false, false);
-				
-				if (skill.hasEffects())
+				// Shield Deflect Magic: If target is reflecting the skill then no damage is done.
+				if (target.getStat().calcStat(Stats.VENGEANCE_SKILL_MAGIC_DAMAGE, 0, target, skill) > Rnd.get(100))
 				{
-					// activate attacked effects, if any
-					target.stopSkillEffects(skill.getId());
-					if (target.getFirstEffect(skill) != null)
-					{
-						target.getEffectList().remove(target.getFirstEffect(skill));
-					}
-					if (Formulas.calcCubicSkillSuccess(activeCubic, target, skill, shld))
-					{
-						skill.getEffects(activeCubic, target, null);
-					}
+					damage = 0;
 				}
-				
+				else
+				{
+					activeCubic.getOwner().sendDamageMessage(target, damage, mcrit, false, false);
+					target.reduceCurrentHp(damage, activeCubic.getOwner(), skill);
+				}
+			}
+		}
+	}
+	
+	public void useCubicDrain(L2CubicInstance activeCubic, L2Skill skill, L2Object[] targets)
+	{
+		if (Config.DEBUG)
+		{
+			_log.info("L2SkillDrain: useCubicSkill()");
+		}
+		
+		for (L2Character target : (L2Character[]) targets)
+		{
+			if (target.isAlikeDead())
+			{
+				continue;
+			}
+			
+			boolean mcrit = Formulas.calcMCrit(activeCubic.getOwner().getMCriticalHit(target, skill));
+			byte shld = Formulas.calcShldUse(activeCubic.getOwner(), target, skill);
+			
+			int damage = (int) Formulas.calcMagicDam(activeCubic, target, skill, mcrit, shld);
+			if (Config.DEBUG)
+			{
+				_log.info("L2SkillDrain: useCubicSkill() -> damage = " + damage);
+			}
+			
+			// TODO: Unhardcode fixed value
+			double hpAdd = (0.4 * damage);
+			L2PcInstance owner = activeCubic.getOwner();
+			double hp = ((owner.getCurrentHp() + hpAdd) > owner.getMaxHp() ? owner.getMaxHp() : (owner.getCurrentHp() + hpAdd));
+			
+			owner.setCurrentHp(hp);
+			
+			// Check to see if we should damage the target
+			if ((damage > 0) && !target.isDead())
+			{
 				target.reduceCurrentHp(damage, activeCubic.getOwner(), skill);
+				
+				// Manage attack or cast break of the target (calculating rate, sending message...)
+				if (!target.isRaid() && Formulas.calcAtkBreak(target, damage))
+				{
+					target.breakAttack();
+					target.breakCast();
+				}
+				owner.sendDamageMessage(target, damage, mcrit, false, false);
 			}
 		}
 	}

+ 7 - 111
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/instance/L2PcInstance.java

@@ -7273,23 +7273,6 @@ public final class L2PcInstance extends L2Playable
 		return false;
 	}
 	
-	@Override
-	public boolean isUsingDualWeapon()
-	{
-		final L2Weapon weaponItem = getActiveWeaponItem();
-		if (weaponItem != null)
-		{
-			switch (weaponItem.getItemType())
-			{
-				case DUAL:
-				case DUALFIST:
-				case DUALDAGGER:
-					return true;
-			}
-		}
-		return false;
-	}
-	
 	public void setUptime(long time)
 	{
 		_uptime = time;
@@ -9673,7 +9656,7 @@ public final class L2PcInstance extends L2Playable
 		}
 		
 		// TODO: Unhardcode skillId 844 which is the outpost construct skill
-		if (((sklTargetType == L2TargetType.HOLY) && !checkIfOkToCastSealOfRule(CastleManager.getInstance().getCastle(this), false, skill, target)) || ((sklTargetType == L2TargetType.FLAGPOLE) && !checkIfOkToCastFlagDisplay(FortManager.getInstance().getFort(this), false, skill, target)) || ((sklType == L2SkillType.SIEGEFLAG) && !L2SkillSiegeFlag.checkIfOkToPlaceFlag(this, false, skill.getId() == 844)) || ((sklType == L2SkillType.STRSIEGEASSAULT) && !checkIfOkToUseStriderSiegeAssault()) || ((sklType == L2SkillType.SUMMON_FRIEND) && !(checkSummonerStatus(this) && checkSummonTargetStatus(target, this))))
+		if (((sklTargetType == L2TargetType.HOLY) && !checkIfOkToCastSealOfRule(CastleManager.getInstance().getCastle(this), false, skill, target)) || ((sklTargetType == L2TargetType.FLAGPOLE) && !checkIfOkToCastFlagDisplay(FortManager.getInstance().getFort(this), false, skill, target)) || ((sklType == L2SkillType.SIEGEFLAG) && !L2SkillSiegeFlag.checkIfOkToPlaceFlag(this, false, skill.getId() == 844)) || ((sklType == L2SkillType.SUMMON_FRIEND) && !(checkSummonerStatus(this) && checkSummonTargetStatus(target, this))))
 		{
 			sendPacket(ActionFailed.STATIC_PACKET);
 			abortCast();
@@ -9703,83 +9686,6 @@ public final class L2PcInstance extends L2Playable
 		return true;
 	}
 	
-	public boolean checkIfOkToUseStriderSiegeAssault()
-	{
-		Castle castle = CastleManager.getInstance().getCastle(this);
-		Fort fort = FortManager.getInstance().getFort(this);
-		
-		if ((castle == null) && (fort == null))
-		{
-			return false;
-		}
-		
-		if (castle != null)
-		{
-			return checkIfOkToUseStriderSiegeAssault(castle);
-		}
-		return checkIfOkToUseStriderSiegeAssault(fort);
-	}
-	
-	public boolean checkIfOkToUseStriderSiegeAssault(Castle castle)
-	{
-		String text = "";
-		
-		if ((castle == null) || (castle.getCastleId() <= 0))
-		{
-			text = "You must be on castle ground to use strider siege assault";
-		}
-		else if (!castle.getSiege().getIsInProgress())
-		{
-			text = "You can only use strider siege assault during a siege.";
-		}
-		else if (!(getTarget() instanceof L2DoorInstance))
-		{
-			text = "You can only use strider siege assault on doors and walls.";
-		}
-		else if (!isRidingStrider())
-		{
-			text = "You can only use strider siege assault when on strider.";
-		}
-		else
-		{
-			return true;
-		}
-		
-		sendMessage(text);
-		
-		return false;
-	}
-	
-	public boolean checkIfOkToUseStriderSiegeAssault(Fort fort)
-	{
-		String text = "";
-		
-		if ((fort == null) || (fort.getFortId() <= 0))
-		{
-			text = "You must be on fort ground to use strider siege assault";
-		}
-		else if (!fort.getSiege().getIsInProgress())
-		{
-			text = "You can only use strider siege assault during a siege.";
-		}
-		else if (!(getTarget() instanceof L2DoorInstance))
-		{
-			text = "You can only use strider siege assault on doors and walls.";
-		}
-		else if (!isRidingStrider())
-		{
-			text = "You can only use strider siege assault when on strider.";
-		}
-		else
-		{
-			return true;
-		}
-		
-		sendMessage(text);
-		
-		return false;
-	}
-	
 	public boolean checkIfOkToCastSealOfRule(Castle castle, boolean isCheckOnly, L2Skill skill, L2Object target)
 	{
 		SystemMessage sm;
@@ -13708,7 +13614,6 @@ public final class L2PcInstance extends L2Playable
 	public void increaseSouls(int count)
 	{
 		_souls += count;
-		// TODO: Fix double message if skill have a self effect.
 		SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOUR_SOUL_HAS_INCREASED_BY_S1_SO_IT_IS_NOW_AT_S2);
 		sm.addNumber(count);
 		sm.addNumber(_souls);
@@ -14006,10 +13911,10 @@ public final class L2PcInstance extends L2Playable
 		// Check if hit is missed
 		if (miss)
 		{
-			if (target instanceof L2PcInstance)
+			if (target.isPlayer())
 			{
 				SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.C1_EVADED_C2_ATTACK);
-				sm.addPcName((L2PcInstance) target);
+				sm.addPcName(target.getActingPlayer());
 				sm.addCharName(this);
 				target.sendPacket(sm);
 			}
@@ -14025,44 +13930,35 @@ public final class L2PcInstance extends L2Playable
 			SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.C1_HAD_CRITICAL_HIT);
 			sm.addPcName(this);
 			sendPacket(sm);
-			if ((target instanceof L2Npc) && (getSkillLevel(467) > 0))
-			{
-				L2Skill skill = SkillTable.getInstance().getInfo(467, getSkillLevel(467));
-				if (Rnd.get(100) < skill.getCritChance())
-				{
-					absorbSoul(skill, ((L2Npc) target));
-				}
-			}
 		}
 		if (mcrit)
 		{
 			sendPacket(SystemMessageId.CRITICAL_HIT_MAGIC);
 		}
 		
-		if (isInOlympiadMode() && (target instanceof L2PcInstance) && ((L2PcInstance) target).isInOlympiadMode() && (((L2PcInstance) target).getOlympiadGameId() == getOlympiadGameId()))
+		if (isInOlympiadMode() && target.isPlayer() && target.getActingPlayer().isInOlympiadMode() && (target.getActingPlayer().getOlympiadGameId() == getOlympiadGameId()))
 		{
 			OlympiadGameManager.getInstance().notifyCompetitorDamage(this, damage);
 		}
 		
 		final SystemMessage sm;
 		
-		if (target.isInvul() && !(target instanceof L2Npc))
+		if (target.isInvul() && !target.isNpc())
 		{
 			sm = SystemMessage.getSystemMessage(SystemMessageId.ATTACK_WAS_BLOCKED);
 		}
-		else if ((target instanceof L2DoorInstance) || (target instanceof L2ControlTowerInstance))
+		else if (target.isDoor() || (target instanceof L2ControlTowerInstance))
 		{
 			sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_DID_S1_DMG);
 			sm.addNumber(damage);
 		}
 		else
 		{
-			sm = SystemMessage.getSystemMessage(SystemMessageId.C1_GAVE_C2_DAMAGE_OF_S3);
+			sm = SystemMessage.getSystemMessage(SystemMessageId.C1_DONE_S3_DAMAGE_TO_C2);
 			sm.addPcName(this);
 			sm.addCharName(target);
 			sm.addNumber(damage);
 		}
-		
 		sendPacket(sm);
 	}
 	

+ 1 - 1
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/instance/L2TrapInstance.java

@@ -158,7 +158,7 @@ public class L2TrapInstance extends L2Trap
 		}
 		else
 		{
-			sm = SystemMessage.getSystemMessage(SystemMessageId.C1_GAVE_C2_DAMAGE_OF_S3);
+			sm = SystemMessage.getSystemMessage(SystemMessageId.C1_DONE_S3_DAMAGE_TO_C2);
 			sm.addCharName(this);
 			sm.addCharName(target);
 			sm.addNumber(damage);

+ 7 - 14
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/templates/L2NpcTemplate.java

@@ -458,19 +458,6 @@ public final class L2NpcTemplate extends L2CharTemplate
 						addImmobiliseSkill(skill);
 						addRangeSkill(skill);
 						break;
-					case PDAM:
-					case MDAM:
-					case BLOW:
-					case DRAIN:
-					case CHARGEDAM:
-					case FATAL:
-					case DEATHLINK:
-					case MANADAM:
-					case CPDAMPERCENT:
-						addAtkSkill(skill);
-						addUniversalSkill(skill);
-						addRangeSkill(skill);
-						break;
 					case POISON:
 					case DOT:
 					case MDOT:
@@ -483,7 +470,7 @@ public final class L2NpcTemplate extends L2CharTemplate
 						addCOTSkill(skill);
 						addRangeSkill(skill);
 						break;
-					default:
+					case DUMMY:
 						if (skill.hasEffectType(L2EffectType.CANCEL, L2EffectType.CANCEL_ALL, L2EffectType.NEGATE))
 						{
 							addNegativeSkill(skill);
@@ -493,6 +480,12 @@ public final class L2NpcTemplate extends L2CharTemplate
 						{
 							addHealSkill(skill);
 						}
+						else if (skill.hasEffectType(L2EffectType.PHYSICAL_ATTACK, L2EffectType.PHYSICAL_ATTACK_HP_LINK, L2EffectType.FATAL_BLOW, L2EffectType.ENERGY_ATTACK, L2EffectType.MAGICAL_ATTACK_MP, L2EffectType.MAGICAL_ATTACK, L2EffectType.DEATH_LINK, L2EffectType.HP_DRAIN))
+						{
+							addAtkSkill(skill);
+							addUniversalSkill(skill);
+							addRangeSkill(skill);
+						}
 						else
 						{
 							addUniversalSkill(skill);

+ 12 - 1
L2J_Server_BETA/java/com/l2jserver/gameserver/model/effects/L2EffectType.java

@@ -43,9 +43,14 @@ public enum L2EffectType
 	DISARM,
 	DMG_OVER_TIME,
 	DMG_OVER_TIME_PERCENT,
+	DEATH_LINK,
+	ENERGY_ATTACK,
 	ENLARGE_ABNORMAL_SLOT,
 	FAKE_DEATH,
+	FATAL_BLOW,
 	FEAR,
+	FOCUS_ENERGY,
+	FOCUS_MAX_ENERGY,
 	FOCUS_SOULS,
 	FUSION,
 	GIVE_SP,
@@ -54,9 +59,12 @@ public enum L2EffectType
 	HEAL_OVER_TIME,
 	HEAL_PERCENT,
 	HIDE,
-	INCREASE_CHARGES,
+	HP_DRAIN,
 	INVINCIBLE,
+	LETHAL,
 	LUCKY,
+	MAGICAL_ATTACK,
+	MAGICAL_ATTACK_MP,
 	MANA_DMG_OVER_TIME,
 	MANA_HEAL_OVER_TIME,
 	MANAHEAL,
@@ -70,6 +78,8 @@ public enum L2EffectType
 	PARALYZE,
 	PETRIFICATION,
 	PHOENIX_BLESSING,
+	PHYSICAL_ATTACK,
+	PHYSICAL_ATTACK_HP_LINK,
 	PHYSICAL_ATTACK_MUTE,
 	PHYSICAL_MUTE,
 	PROTECTION_BLESSING,
@@ -83,6 +93,7 @@ public enum L2EffectType
 	SILENT_MOVE,
 	SLEEP,
 	SPOIL,
+	STATIC_DAMAGE,
 	STUN,
 	SUMMON_AGATHION,
 	SUMMON_PET,

+ 13 - 56
L2J_Server_BETA/java/com/l2jserver/gameserver/model/skills/L2Skill.java

@@ -113,15 +113,12 @@ public abstract class L2Skill implements IChanceSkillTrigger
 	private final int _magic;
 	private final L2TraitType _traitType;
 	private final boolean _staticReuse;
-	private final boolean _staticDamage; // Damage dealing skills do static damage based on the power value.
 	/** MP consumption. */
 	private final int _mpConsume;
 	/** Initial MP consumption. */
 	private final int _mpInitialConsume;
 	/** HP consumption. */
 	private final int _hpConsume;
-	/** CP consumption. */
-	private final int _cpConsume;
 	/** Amount of items consumed by this skill from target. */
 	private final int _targetConsumeCount;
 	/** Id of item consumed by this skill from target. */
@@ -209,7 +206,6 @@ public abstract class L2Skill implements IChanceSkillTrigger
 	private final int _soulMaxConsume;
 	private final int _numSouls;
 	private final int _expNeeded;
-	private final int _critChance;
 	private final boolean _dependOnTargetBuff;
 	
 	private final int _afterEffectId;
@@ -249,7 +245,6 @@ public abstract class L2Skill implements IChanceSkillTrigger
 	private final boolean _ignoreShield;
 	
 	private final boolean _isSuicideAttack;
-	private final boolean _canBeReflected;
 	private final boolean _canBeDispeled;
 	
 	private final boolean _isClanSkill;
@@ -274,11 +269,9 @@ public abstract class L2Skill implements IChanceSkillTrigger
 		_magic = set.getInteger("isMagic", 0);
 		_traitType = set.getEnum("trait", L2TraitType.class, L2TraitType.NONE);
 		_staticReuse = set.getBool("staticReuse", false);
-		_staticDamage = set.getBool("staticDamage", false);
 		_mpConsume = set.getInteger("mpConsume", 0);
 		_mpInitialConsume = set.getInteger("mpInitialConsume", 0);
 		_hpConsume = set.getInteger("hpConsume", 0);
-		_cpConsume = set.getInteger("cpConsume", 0);
 		_targetConsumeCount = set.getInteger("targetConsumeCount", 0);
 		_targetConsumeId = set.getInteger("targetConsumeId", 0);
 		_itemConsumeCount = set.getInteger("itemConsumeCount", 0);
@@ -462,14 +455,13 @@ public abstract class L2Skill implements IChanceSkillTrigger
 		_soulMaxConsume = set.getInteger("soulMaxConsumeCount", 0);
 		_blowChance = set.getInteger("blowChance", 0);
 		_expNeeded = set.getInteger("expNeeded", 0);
-		_critChance = set.getInteger("critChance", 0);
 		
 		_isHeroSkill = SkillTreesData.getInstance().isHeroSkill(_id, _level);
 		_isGMSkill = SkillTreesData.getInstance().isGMSkill(_id, _level);
 		_isSevenSigns = (_id > 4360) && (_id < 4367);
 		_isClanSkill = SkillTreesData.getInstance().isClanSkill(_id, _level);
 		
-		_baseCritRate = set.getInteger("baseCritRate", ((_skillType == L2SkillType.PDAM) || (_skillType == L2SkillType.BLOW)) ? 0 : -1);
+		_baseCritRate = set.getInteger("baseCritRate", 0);
 		_halfKillRate = set.getInteger("halfKillRate", 0);
 		_lethalStrikeRate = set.getInteger("lethalStrikeRate", 0);
 		
@@ -481,7 +473,6 @@ public abstract class L2Skill implements IChanceSkillTrigger
 		_flyType = set.getString("flyType", null);
 		_flyRadius = set.getInteger("flyRadius", 0);
 		_flyCourse = set.getFloat("flyCourse", 0);
-		_canBeReflected = set.getBool("canBeReflected", true);
 		
 		_canBeDispeled = set.getBool("canBeDispeled", true);
 		
@@ -578,21 +569,16 @@ public abstract class L2Skill implements IChanceSkillTrigger
 			return getPower(isPvP, isPvE);
 		}
 		
-		switch (_skillType)
+		if (hasEffectType(L2EffectType.DEATH_LINK))
 		{
-			case DEATHLINK:
-			{
-				return getPower(isPvP, isPvE) * (-((activeChar.getCurrentHp() * 2) / activeChar.getMaxHp()) + 2);
-			}
-			case FATAL:
-			{
-				return getPower(isPvP, isPvE) * (-((target.getCurrentHp() * 2) / target.getMaxHp()) + 2);
-			}
-			default:
-			{
-				return getPower(isPvP, isPvE);
-			}
+			return getPower(isPvP, isPvE) * (-((activeChar.getCurrentHp() * 2) / activeChar.getMaxHp()) + 2);
 		}
+		
+		if (hasEffectType(L2EffectType.PHYSICAL_ATTACK_HP_LINK))
+		{
+			return getPower(isPvP, isPvE) * (-((target.getCurrentHp() * 2) / target.getMaxHp()) + 2);
+		}
+		return getPower(isPvP, isPvE);
 	}
 	
 	public final double getPower()
@@ -715,14 +701,6 @@ public abstract class L2Skill implements IChanceSkillTrigger
 		return _castRange;
 	}
 	
-	/**
-	 * @return Returns the cpConsume;
-	 */
-	public final int getCpConsume()
-	{
-		return _cpConsume;
-	}
-	
 	/**
 	 * @return Returns the effectRange.
 	 */
@@ -853,6 +831,9 @@ public abstract class L2Skill implements IChanceSkillTrigger
 		return _magic == 2;
 	}
 	
+	/**
+	 * @return Returns true to set dance skills.
+	 */
 	public final boolean isDance()
 	{
 		return _magic == 3;
@@ -866,11 +847,6 @@ public abstract class L2Skill implements IChanceSkillTrigger
 		return _staticReuse;
 	}
 	
-	public final boolean isStaticDamage()
-	{
-		return _staticDamage;
-	}
-	
 	/**
 	 * @return Returns the mpConsume.
 	 */
@@ -978,15 +954,7 @@ public abstract class L2Skill implements IChanceSkillTrigger
 	
 	public final boolean useSoulShot()
 	{
-		switch (getSkillType())
-		{
-			case PDAM:
-			case CHARGEDAM:
-			case BLOW:
-				return true;
-			default:
-				return false;
-		}
+		return (hasEffectType(L2EffectType.PHYSICAL_ATTACK, L2EffectType.PHYSICAL_ATTACK_HP_LINK, L2EffectType.FATAL_BLOW, L2EffectType.ENERGY_ATTACK));
 	}
 	
 	public final boolean useSpiritShot()
@@ -1049,11 +1017,6 @@ public abstract class L2Skill implements IChanceSkillTrigger
 		return _expNeeded;
 	}
 	
-	public final int getCritChance()
-	{
-		return _critChance;
-	}
-	
 	public final int getBaseCritRate()
 	{
 		return _baseCritRate;
@@ -1589,7 +1552,6 @@ public abstract class L2Skill implements IChanceSkillTrigger
 				effects.add(e);
 			}
 		}
-		
 		final L2Effect[] list = effects.toArray(new L2Effect[effects.size()]);
 		effector.getEffectList().add(list);
 		return effects.isEmpty() ? EMPTY_EFFECT_SET : list;
@@ -1750,11 +1712,6 @@ public abstract class L2Skill implements IChanceSkillTrigger
 		return _ignoreShield;
 	}
 	
-	public boolean canBeReflected()
-	{
-		return _canBeReflected;
-	}
-	
 	public boolean canBeDispeled()
 	{
 		return _canBeDispeled;

+ 0 - 12
L2J_Server_BETA/java/com/l2jserver/gameserver/model/skills/L2SkillType.java

@@ -21,11 +21,9 @@ package com.l2jserver.gameserver.model.skills;
 import java.lang.reflect.Constructor;
 
 import com.l2jserver.gameserver.model.StatsSet;
-import com.l2jserver.gameserver.model.skills.l2skills.L2SkillChargeDmg;
 import com.l2jserver.gameserver.model.skills.l2skills.L2SkillCreateItem;
 import com.l2jserver.gameserver.model.skills.l2skills.L2SkillDecoy;
 import com.l2jserver.gameserver.model.skills.l2skills.L2SkillDefault;
-import com.l2jserver.gameserver.model.skills.l2skills.L2SkillDrain;
 import com.l2jserver.gameserver.model.skills.l2skills.L2SkillLearnSkill;
 import com.l2jserver.gameserver.model.skills.l2skills.L2SkillSiegeFlag;
 import com.l2jserver.gameserver.model.skills.l2skills.L2SkillSignet;
@@ -41,16 +39,8 @@ import com.l2jserver.gameserver.model.skills.l2skills.L2SkillTrap;
 public enum L2SkillType
 {
 	// Damage
-	PDAM,
-	MDAM,
-	MANADAM,
-	CPDAMPERCENT,
 	DOT,
 	MDOT,
-	DRAIN(L2SkillDrain.class),
-	DEATHLINK,
-	FATAL,
-	BLOW,
 	SIGNET(L2SkillSignet.class),
 	SIGNET_CASTTIME(L2SkillSignetCasttime.class),
 	// Disablers
@@ -104,7 +94,6 @@ public enum L2SkillType
 	// Summons
 	SUMMON(L2SkillSummon.class),
 	FEED_PET,
-	STRSIEGEASSAULT,
 	ERASE,
 	BETRAY,
 	DECOY(L2SkillDecoy.class),
@@ -116,7 +105,6 @@ public enum L2SkillType
 	FUSION,
 	
 	RESURRECT,
-	CHARGEDAM(L2SkillChargeDmg.class),
 	RECALL(L2SkillTeleport.class),
 	TELEPORT(L2SkillTeleport.class),
 	SUMMON_FRIEND,

+ 0 - 209
L2J_Server_BETA/java/com/l2jserver/gameserver/model/skills/l2skills/L2SkillChargeDmg.java

@@ -1,209 +0,0 @@
-/*
- * 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.skills.l2skills;
-
-import java.util.logging.Level;
-import java.util.logging.LogRecord;
-import java.util.logging.Logger;
-
-import com.l2jserver.Config;
-import com.l2jserver.gameserver.model.L2Object;
-import com.l2jserver.gameserver.model.ShotType;
-import com.l2jserver.gameserver.model.StatsSet;
-import com.l2jserver.gameserver.model.actor.L2Character;
-import com.l2jserver.gameserver.model.effects.L2Effect;
-import com.l2jserver.gameserver.model.skills.L2Skill;
-import com.l2jserver.gameserver.model.stats.BaseStats;
-import com.l2jserver.gameserver.model.stats.Env;
-import com.l2jserver.gameserver.model.stats.Formulas;
-import com.l2jserver.gameserver.network.SystemMessageId;
-import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
-
-public class L2SkillChargeDmg extends L2Skill
-{
-	private static final Logger _logDamage = Logger.getLogger("damage");
-	
-	public L2SkillChargeDmg(StatsSet set)
-	{
-		super(set);
-	}
-	
-	@Override
-	public void useSkill(L2Character caster, L2Object[] targets)
-	{
-		if (caster.isAlikeDead())
-		{
-			return;
-		}
-		
-		double modifier = 0;
-		if (caster.isPlayer())
-		{
-			// Charges Formula (each charge increase +25%)
-			modifier = ((caster.getActingPlayer().getCharges() * 0.25) + 1);
-		}
-		boolean ss = useSoulShot() && caster.isChargedShot(ShotType.SOULSHOTS);
-		
-		for (L2Character target : (L2Character[]) targets)
-		{
-			if (target.isAlikeDead())
-			{
-				continue;
-			}
-			
-			// Calculate skill evasion
-			boolean skillIsEvaded = Formulas.calcPhysicalSkillEvasion(target, this);
-			if (skillIsEvaded)
-			{
-				if (caster.isPlayer())
-				{
-					SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.C1_DODGES_ATTACK);
-					sm.addString(target.getName());
-					caster.getActingPlayer().sendPacket(sm);
-				}
-				if (target.isPlayer())
-				{
-					SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.AVOIDED_C1_ATTACK2);
-					sm.addString(caster.getName());
-					target.getActingPlayer().sendPacket(sm);
-				}
-				
-				// no futher calculations needed.
-				continue;
-			}
-			
-			// TODO: should we use dual or not?
-			// because if so, damage are lowered but we don't do anything special with dual then
-			// like in doAttackHitByDual which in fact does the calcPhysDam call twice
-			// boolean dual = caster.isUsingDualWeapon();
-			byte shld = Formulas.calcShldUse(caster, target, this);
-			boolean crit = false;
-			if ((getBaseCritRate() > 0) && !isStaticDamage())
-			{
-				crit = Formulas.calcCrit(getBaseCritRate() * 10 * BaseStats.STR.calcBonus(caster), true, target);
-			}
-			// damage calculation, crit is static 2x
-			double damage = isStaticDamage() ? getPower() : Formulas.calcPhysDam(caster, target, this, shld, false, false, ss);
-			if (crit)
-			{
-				damage *= 2;
-			}
-			
-			if (damage > 0)
-			{
-				byte reflect = Formulas.calcSkillReflect(target, this);
-				if (hasEffects())
-				{
-					if ((reflect & Formulas.SKILL_REFLECT_SUCCEED) != 0)
-					{
-						caster.stopSkillEffects(getId());
-						getEffects(target, caster);
-						SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_FEEL_S1_EFFECT);
-						sm.addSkillName(this);
-						caster.sendPacket(sm);
-					}
-					else
-					{
-						// activate attacked effects, if any
-						target.stopSkillEffects(getId());
-						if (Formulas.calcSkillSuccess(caster, target, this, shld, false, false, true))
-						{
-							getEffects(caster, target, new Env(shld, false, false, false));
-							
-							SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_FEEL_S1_EFFECT);
-							sm.addSkillName(this);
-							target.sendPacket(sm);
-						}
-						else
-						{
-							SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.C1_RESISTED_YOUR_S2);
-							sm.addCharName(target);
-							sm.addSkillName(this);
-							caster.sendPacket(sm);
-						}
-					}
-				}
-				
-				double finalDamage = isStaticDamage() ? damage : damage * modifier;
-				
-				if (Config.LOG_GAME_DAMAGE && caster.isPlayable() && (damage > Config.LOG_GAME_DAMAGE_THRESHOLD))
-				{
-					LogRecord record = new LogRecord(Level.INFO, "");
-					record.setParameters(new Object[]
-					{
-						caster,
-						" did damage ",
-						(int) damage,
-						this,
-						" to ",
-						target
-					});
-					record.setLoggerName("pdam");
-					_logDamage.log(record);
-				}
-				
-				target.reduceCurrentHp(finalDamage, caster, this);
-				
-				// vengeance reflected damage
-				if ((reflect & Formulas.SKILL_REFLECT_VENGEANCE) != 0)
-				{
-					if (target.isPlayer())
-					{
-						SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.COUNTERED_C1_ATTACK);
-						sm.addCharName(caster);
-						target.sendPacket(sm);
-					}
-					if (caster.isPlayer())
-					{
-						SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.C1_PERFORMING_COUNTERATTACK);
-						sm.addCharName(target);
-						caster.sendPacket(sm);
-					}
-					// Formula from Diego Vargas post: http://www.l2guru.com/forum/showthread.php?p=3122630
-					// 1189 x Your PATK / PDEF of target
-					double vegdamage = ((1189 * target.getPAtk(caster)) / (double) caster.getPDef(target));
-					caster.reduceCurrentHp(vegdamage, target, this);
-				}
-				
-				caster.sendDamageMessage(target, (int) finalDamage, false, crit, false);
-				
-			}
-			else
-			{
-				caster.sendDamageMessage(target, 0, false, false, true);
-			}
-		}
-		
-		// effect self :]
-		if (hasSelfEffects())
-		{
-			L2Effect effect = caster.getFirstEffect(getId());
-			if ((effect != null) && effect.isSelfEffect())
-			{
-				// Replace old effect with new one.
-				effect.exit();
-			}
-			// cast self effect if any
-			getEffectsSelf(caster);
-		}
-		
-		// Consume shot
-		caster.setChargedShot(ShotType.SOULSHOTS, false);
-	}
-}

+ 0 - 245
L2J_Server_BETA/java/com/l2jserver/gameserver/model/skills/l2skills/L2SkillDrain.java

@@ -1,245 +0,0 @@
-/*
- * 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.skills.l2skills;
-
-import java.util.logging.Level;
-import java.util.logging.LogRecord;
-import java.util.logging.Logger;
-
-import com.l2jserver.Config;
-import com.l2jserver.gameserver.model.L2Object;
-import com.l2jserver.gameserver.model.ShotType;
-import com.l2jserver.gameserver.model.StatsSet;
-import com.l2jserver.gameserver.model.actor.L2Character;
-import com.l2jserver.gameserver.model.actor.L2Npc;
-import com.l2jserver.gameserver.model.actor.instance.L2CubicInstance;
-import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
-import com.l2jserver.gameserver.model.effects.L2Effect;
-import com.l2jserver.gameserver.model.skills.L2Skill;
-import com.l2jserver.gameserver.model.skills.targets.L2TargetType;
-import com.l2jserver.gameserver.model.stats.Formulas;
-import com.l2jserver.gameserver.network.SystemMessageId;
-import com.l2jserver.gameserver.network.serverpackets.StatusUpdate;
-import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
-
-public class L2SkillDrain extends L2Skill
-{
-	private static final Logger _logDamage = Logger.getLogger("damage");
-	
-	private final float _absorbPart;
-	private final int _absorbAbs;
-	
-	public L2SkillDrain(StatsSet set)
-	{
-		super(set);
-		
-		_absorbPart = set.getFloat("absorbPart", 0.f);
-		_absorbAbs = set.getInteger("absorbAbs", 0);
-	}
-	
-	@Override
-	public void useSkill(L2Character activeChar, L2Object[] targets)
-	{
-		if (activeChar.isAlikeDead())
-		{
-			return;
-		}
-		
-		boolean ss = useSoulShot() && activeChar.isChargedShot(ShotType.SOULSHOTS);
-		boolean sps = useSpiritShot() && activeChar.isChargedShot(ShotType.SPIRITSHOTS);
-		boolean bss = useSpiritShot() && activeChar.isChargedShot(ShotType.BLESSED_SPIRITSHOTS);
-		
-		for (L2Character target : (L2Character[]) targets)
-		{
-			if (target.isAlikeDead() && (getTargetType() != L2TargetType.CORPSE_MOB))
-			{
-				continue;
-			}
-			
-			if ((activeChar != target) && target.isInvul())
-			{
-				continue; // No effect on invulnerable chars unless they cast it themselves.
-			}
-			
-			boolean mcrit = Formulas.calcMCrit(activeChar.getMCriticalHit(target, this));
-			byte shld = Formulas.calcShldUse(activeChar, target, this);
-			int damage = isStaticDamage() ? (int) getPower() : (int) Formulas.calcMagicDam(activeChar, target, this, shld, sps, bss, mcrit);
-			
-			int _drain = 0;
-			int _cp = (int) target.getCurrentCp();
-			int _hp = (int) target.getCurrentHp();
-			
-			if (_cp > 0)
-			{
-				if (damage < _cp)
-				{
-					_drain = 0;
-				}
-				else
-				{
-					_drain = damage - _cp;
-				}
-			}
-			else if (damage > _hp)
-			{
-				_drain = _hp;
-			}
-			else
-			{
-				_drain = damage;
-			}
-			
-			double hpAdd = _absorbAbs + (_absorbPart * _drain);
-			double hp = ((activeChar.getCurrentHp() + hpAdd) > activeChar.getMaxHp() ? activeChar.getMaxHp() : (activeChar.getCurrentHp() + hpAdd));
-			
-			activeChar.setCurrentHp(hp);
-			
-			StatusUpdate suhp = new StatusUpdate(activeChar);
-			suhp.addAttribute(StatusUpdate.CUR_HP, (int) hp);
-			activeChar.sendPacket(suhp);
-			
-			// Check to see if we should damage the target
-			if ((damage > 0) && (!target.isDead() || (getTargetType() != L2TargetType.CORPSE_MOB)))
-			{
-				// Manage attack or cast break of the target (calculating rate, sending message...)
-				if (!target.isRaid() && Formulas.calcAtkBreak(target, damage))
-				{
-					target.breakAttack();
-					target.breakCast();
-				}
-				
-				activeChar.sendDamageMessage(target, damage, mcrit, false, false);
-				
-				if (Config.LOG_GAME_DAMAGE && activeChar.isPlayable() && (damage > Config.LOG_GAME_DAMAGE_THRESHOLD))
-				{
-					LogRecord record = new LogRecord(Level.INFO, "");
-					record.setParameters(new Object[]
-					{
-						activeChar,
-						" did damage ",
-						damage,
-						this,
-						" to ",
-						target
-					});
-					record.setLoggerName("mdam");
-					_logDamage.log(record);
-				}
-				
-				if (hasEffects() && (getTargetType() != L2TargetType.CORPSE_MOB))
-				{
-					// ignoring vengance-like reflections
-					if ((Formulas.calcSkillReflect(target, this) & Formulas.SKILL_REFLECT_SUCCEED) > 0)
-					{
-						activeChar.stopSkillEffects(getId());
-						getEffects(target, activeChar);
-						SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_FEEL_S1_EFFECT);
-						sm.addSkillName(getId());
-						activeChar.sendPacket(sm);
-					}
-					else
-					{
-						// activate attacked effects, if any
-						target.stopSkillEffects(getId());
-						if (Formulas.calcSkillSuccess(activeChar, target, this, shld, ss, sps, bss))
-						{
-							getEffects(activeChar, target);
-						}
-						else
-						{
-							SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.C1_RESISTED_YOUR_S2);
-							sm.addCharName(target);
-							sm.addSkillName(this);
-							activeChar.sendPacket(sm);
-						}
-					}
-				}
-				
-				target.reduceCurrentHp(damage, activeChar, this);
-			}
-			
-			// Check to see if we should do the decay right after the cast
-			if (target.isDead() && (getTargetType() == L2TargetType.CORPSE_MOB) && target.isNpc())
-			{
-				((L2Npc) target).endDecayTask();
-			}
-		}
-		// effect self :]
-		L2Effect effect = activeChar.getFirstEffect(getId());
-		if ((effect != null) && effect.isSelfEffect())
-		{
-			// Replace old effect with new one.
-			effect.exit();
-		}
-		// cast self effect if any
-		getEffectsSelf(activeChar);
-		// Consume shot
-		activeChar.setChargedShot(bss ? ShotType.BLESSED_SPIRITSHOTS : ShotType.SPIRITSHOTS, false);
-	}
-	
-	public void useCubicSkill(L2CubicInstance activeCubic, L2Object[] targets)
-	{
-		if (Config.DEBUG)
-		{
-			_log.info("L2SkillDrain: useCubicSkill()");
-		}
-		
-		for (L2Character target : (L2Character[]) targets)
-		{
-			if (target.isAlikeDead() && (getTargetType() != L2TargetType.CORPSE_MOB))
-			{
-				continue;
-			}
-			
-			boolean mcrit = Formulas.calcMCrit(activeCubic.getMCriticalHit(target, this));
-			byte shld = Formulas.calcShldUse(activeCubic.getOwner(), target, this);
-			
-			int damage = (int) Formulas.calcMagicDam(activeCubic, target, this, mcrit, shld);
-			if (Config.DEBUG)
-			{
-				_log.info("L2SkillDrain: useCubicSkill() -> damage = " + damage);
-			}
-			
-			double hpAdd = _absorbAbs + (_absorbPart * damage);
-			L2PcInstance owner = activeCubic.getOwner();
-			double hp = ((owner.getCurrentHp() + hpAdd) > owner.getMaxHp() ? owner.getMaxHp() : (owner.getCurrentHp() + hpAdd));
-			
-			owner.setCurrentHp(hp);
-			
-			StatusUpdate suhp = new StatusUpdate(owner);
-			suhp.addAttribute(StatusUpdate.CUR_HP, (int) hp);
-			owner.sendPacket(suhp);
-			
-			// Check to see if we should damage the target
-			if ((damage > 0) && (!target.isDead() || (getTargetType() != L2TargetType.CORPSE_MOB)))
-			{
-				target.reduceCurrentHp(damage, activeCubic.getOwner(), this);
-				
-				// Manage attack or cast break of the target (calculating rate, sending message...)
-				if (!target.isRaid() && Formulas.calcAtkBreak(target, damage))
-				{
-					target.breakAttack();
-					target.breakCast();
-				}
-				owner.sendDamageMessage(target, damage, mcrit, false, false);
-			}
-		}
-	}
-	
-}

+ 123 - 206
L2J_Server_BETA/java/com/l2jserver/gameserver/model/stats/Formulas.java

@@ -103,10 +103,6 @@ public final class Formulas
 	public static final byte SHIELD_DEFENSE_SUCCEED = 1; // normal shield defense
 	public static final byte SHIELD_DEFENSE_PERFECT_BLOCK = 2; // perfect block
 	
-	public static final byte SKILL_REFLECT_FAILED = 0; // no reflect
-	public static final byte SKILL_REFLECT_SUCCEED = 1; // normal reflect, some damage reflected some other not
-	public static final byte SKILL_REFLECT_VENGEANCE = 2; // 100% of the damage affect both
-	
 	private static final byte MELEE_ATTACK_RANGE = 40;
 	
 	/**
@@ -637,11 +633,10 @@ public final class Formulas
 			defence *= target.calcStat(Stats.PVP_PHYS_SKILL_DEF, 1, null, null);
 		}
 		
-		// Behind: 20% - Front: 10% (TODO: values are unconfirmed, possibly custom, remove or update when confirmed)
-		proximityBonus = attacker.isBehindTarget() ? 1.2 : attacker.isInFrontOfTarget() ? 1.1 : 1;
+		// Hitting from the side or the back gives a generic bonus since Gracia Part 1 ~> Side = +10% , Back = +20%
+		proximityBonus = attacker.isBehindTarget() ? 1.2 : attacker.isInFrontOfTarget() ? 1 : 1.1;
 		
 		damage *= calcValakasTrait(attacker, target, skill);
-		
 		double element = calcElemental(attacker, target, skill);
 		
 		// SSBoost > 0 have different calculation
@@ -681,17 +676,16 @@ public final class Formulas
 	}
 	
 	/**
-	 * Calculated damage caused by ATTACK of attacker on target, called separately for each weapon, if dual-weapon is used.
+	 * Calculated damage caused by ATTACK of attacker on target.
 	 * @param attacker player or NPC that makes ATTACK
 	 * @param target player or NPC, target of ATTACK
 	 * @param skill
 	 * @param shld
 	 * @param crit if the ATTACK have critical success
-	 * @param dual if dual weapon is used
 	 * @param ss if weapon item was charged by soulshot
 	 * @return
 	 */
-	public static final double calcPhysDam(L2Character attacker, L2Character target, L2Skill skill, byte shld, boolean crit, boolean dual, boolean ss)
+	public static final double calcPhysDam(L2Character attacker, L2Character target, L2Skill skill, byte shld, boolean crit, boolean ss)
 	{
 		final boolean isPvP = attacker.isPlayable() && target.isPlayable();
 		final boolean isPvE = attacker.isPlayable() && target.isL2Attackable();
@@ -702,26 +696,23 @@ public final class Formulas
 		// Def bonuses in PvP fight
 		if (isPvP)
 		{
-			if (skill == null)
-			{
-				defence *= target.calcStat(Stats.PVP_PHYSICAL_DEF, 1, null, null);
-			}
-			else
-			{
-				defence *= target.calcStat(Stats.PVP_PHYS_SKILL_DEF, 1, null, null);
-			}
+			defence *= (skill == null) ? target.calcStat(Stats.PVP_PHYSICAL_DEF, 1, null, null) : target.calcStat(Stats.PVP_PHYS_SKILL_DEF, 1, null, null);
 		}
 		
 		switch (shld)
 		{
 			case SHIELD_DEFENSE_SUCCEED:
+			{
 				if (!Config.ALT_GAME_SHIELD_BLOCKS)
 				{
 					defence += target.getShldDef();
 				}
 				break;
+			}
 			case SHIELD_DEFENSE_PERFECT_BLOCK: // perfect block
+			{
 				return 1.;
+			}
 		}
 		
 		if (ss)
@@ -958,11 +949,10 @@ public final class Formulas
 				}
 			}
 		}
-		
 		return damage;
 	}
 	
-	public static final double calcMagicDam(L2Character attacker, L2Character target, L2Skill skill, byte shld, boolean ss, boolean bss, boolean mcrit)
+	public static final double calcMagicDam(L2Character attacker, L2Character target, L2Skill skill, byte shld, boolean sps, boolean bss, boolean mcrit)
 	{
 		int mAtk = attacker.getMAtk(target, skill);
 		int mDef = target.getMDef(attacker, skill);
@@ -984,20 +974,14 @@ public final class Formulas
 		switch (shld)
 		{
 			case SHIELD_DEFENSE_SUCCEED:
-				mDef += target.getShldDef(); // kamael
+				mDef += target.getShldDef();
 				break;
-			case SHIELD_DEFENSE_PERFECT_BLOCK: // perfect block
+			case SHIELD_DEFENSE_PERFECT_BLOCK:
 				return 1;
 		}
 		
-		if (bss)
-		{
-			mAtk *= 4;
-		}
-		else if (ss)
-		{
-			mAtk *= 2;
-		}
+		// Bonus Spiritshot
+		mAtk *= bss ? 4 : sps ? 2 : 1;
 		// MDAM Formula.
 		double damage = ((91 * Math.sqrt(mAtk)) / mDef) * skill.getPower(attacker, target, isPvP, isPvE);
 		
@@ -1008,7 +992,7 @@ public final class Formulas
 			{
 				if (calcMagicSuccess(attacker, target, skill) && ((target.getLevel() - attacker.getLevel()) <= 9))
 				{
-					if (skill.getSkillType() == L2SkillType.DRAIN)
+					if (skill.hasEffectType(L2EffectType.HP_DRAIN))
 					{
 						attacker.sendPacket(SystemMessageId.DRAIN_HALF_SUCCESFUL);
 					}
@@ -1016,7 +1000,6 @@ public final class Formulas
 					{
 						attacker.sendPacket(SystemMessageId.ATTACK_FAILED);
 					}
-					
 					damage /= 2;
 				}
 				else
@@ -1025,50 +1008,33 @@ public final class Formulas
 					sm.addCharName(target);
 					sm.addSkillName(skill);
 					attacker.sendPacket(sm);
-					
 					damage = 1;
 				}
 			}
 			
 			if (target.isPlayer())
 			{
-				final SystemMessage sm = (skill.getSkillType() == L2SkillType.DRAIN) ? SystemMessage.getSystemMessage(SystemMessageId.RESISTED_C1_DRAIN) : SystemMessage.getSystemMessage(SystemMessageId.RESISTED_C1_MAGIC);
+				final SystemMessage sm = (skill.hasEffectType(L2EffectType.HP_DRAIN)) ? SystemMessage.getSystemMessage(SystemMessageId.RESISTED_C1_DRAIN) : SystemMessage.getSystemMessage(SystemMessageId.RESISTED_C1_MAGIC);
 				sm.addCharName(attacker);
 				target.sendPacket(sm);
 			}
 		}
 		else if (mcrit)
 		{
-			if (attacker.isPlayer() && target.isPlayer())
-			{
-				damage *= 2.5;
-			}
-			else
-			{
-				damage *= 3;
-			}
-			
+			damage *= attacker.isPlayer() && target.isPlayer() ? 2.5 : 3;
 			damage *= attacker.calcStat(Stats.MAGIC_CRIT_DMG, 1, null, null);
 		}
 		
 		// Weapon random damage
 		damage *= attacker.getRandomDamageMultiplier();
-		
 		// Pvp bonuses for dmg
 		if (isPvP)
 		{
-			if (skill.isMagic())
-			{
-				damage *= attacker.calcStat(Stats.PVP_MAGICAL_DMG, 1, null, null);
-			}
-			else
-			{
-				damage *= attacker.calcStat(Stats.PVP_PHYS_SKILL_DMG, 1, null, null);
-			}
+			Stats stat = skill.isMagic() ? Stats.PVP_MAGICAL_DMG : Stats.PVP_PHYS_SKILL_DMG;
+			damage *= attacker.calcStat(stat, 1, null, null);
 		}
 		// CT2.3 general magic vuln
 		damage *= target.calcStat(Stats.MAGIC_DAMAGE_VULN, 1, null, null);
-		
 		damage *= calcElemental(attacker, target, skill);
 		
 		if (target.isL2Attackable())
@@ -1087,7 +1053,6 @@ public final class Formulas
 				}
 			}
 		}
-		
 		return damage;
 	}
 	
@@ -1115,7 +1080,7 @@ public final class Formulas
 		{
 			if (calcMagicSuccess(owner, target, skill) && ((target.getLevel() - skill.getMagicLevel()) <= 9))
 			{
-				if (skill.getSkillType() == L2SkillType.DRAIN)
+				if (skill.hasEffectType(L2EffectType.HP_DRAIN))
 				{
 					owner.sendPacket(SystemMessageId.DRAIN_HALF_SUCCESFUL);
 				}
@@ -1123,7 +1088,6 @@ public final class Formulas
 				{
 					owner.sendPacket(SystemMessageId.ATTACK_FAILED);
 				}
-				
 				damage /= 2;
 			}
 			else
@@ -1132,13 +1096,12 @@ public final class Formulas
 				sm.addCharName(target);
 				sm.addSkillName(skill);
 				owner.sendPacket(sm);
-				
 				damage = 1;
 			}
 			
 			if (target.isPlayer())
 			{
-				if (skill.getSkillType() == L2SkillType.DRAIN)
+				if (skill.hasEffectType(L2EffectType.HP_DRAIN))
 				{
 					SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.RESISTED_C1_DRAIN);
 					sm.addCharName(owner);
@@ -1159,7 +1122,6 @@ public final class Formulas
 		
 		// CT2.3 general magic vuln
 		damage *= target.calcStat(Stats.MAGIC_DAMAGE_VULN, 1, null, null);
-		
 		damage *= calcElemental(owner, target, skill);
 		
 		if (target.isL2Attackable())
@@ -1178,7 +1140,6 @@ public final class Formulas
 				}
 			}
 		}
-		
 		return damage;
 	}
 	
@@ -1212,60 +1173,6 @@ public final class Formulas
 		return success;
 	}
 	
-	public static final boolean calcLethalHit(L2Character activeChar, L2Character target, L2Skill skill)
-	{
-		if ((activeChar.isPlayer() && !activeChar.getAccessLevel().canGiveDamage()) || (((skill.getCondition() & L2Skill.COND_BEHIND) != 0) && !activeChar.isBehindTarget()))
-		{
-			return false;
-		}
-		if (target.isLethalable() && !target.isInvul())
-		{
-			// Lvl Bonus Modifier.
-			double lethalStrikeRate = skill.getLethalStrikeRate() * calcLvlBonusMod(activeChar, target, skill);
-			double halfKillRate = skill.getHalfKillRate() * calcLvlBonusMod(activeChar, target, skill);
-			
-			// Lethal Strike
-			if (Rnd.get(100) < activeChar.calcStat(Stats.LETHAL_RATE, lethalStrikeRate, target, null))
-			{
-				// for Players CP and HP is set to 1.
-				if (target.isPlayer())
-				{
-					target.setCurrentCp(1);
-					target.setCurrentHp(1);
-					target.sendPacket(SystemMessageId.LETHAL_STRIKE);
-				}
-				// for Monsters HP is set to 1.
-				else if (target.isMonster() || target.isSummon())
-				{
-					target.setCurrentHp(1);
-				}
-				activeChar.sendPacket(SystemMessageId.LETHAL_STRIKE_SUCCESSFUL);
-			}
-			// Half-Kill
-			else if (Rnd.get(100) < activeChar.calcStat(Stats.LETHAL_RATE, halfKillRate, target, null))
-			{
-				// for Players CP is set to 1.
-				if (target.isPlayer())
-				{
-					target.setCurrentCp(1);
-					target.sendPacket(SystemMessageId.HALF_KILL);
-					target.sendPacket(SystemMessageId.CP_DISAPPEARS_WHEN_HIT_WITH_A_HALF_KILL_SKILL);
-				}
-				// for Monsters HP is set to 50%.
-				else if (target.isMonster() || target.isSummon())
-				{
-					target.setCurrentHp(target.getCurrentHp() * 0.5);
-				}
-				activeChar.sendPacket(SystemMessageId.HALF_KILL);
-			}
-		}
-		else
-		{
-			return false;
-		}
-		return true;
-	}
-	
 	public static final boolean calcMCrit(double mRate)
 	{
 		return mRate > Rnd.get(1000);
@@ -1313,14 +1220,7 @@ public final class Formulas
 		double rate = target.calcStat(Stats.ATTACK_CANCEL, init, null, null);
 		
 		// Adjust the rate to be between 1 and 99
-		if (rate > 99)
-		{
-			rate = 99;
-		}
-		else if (rate < 1)
-		{
-			rate = 1;
-		}
+		rate = Math.max(Math.min(rate, 99), 1);
 		
 		return Rnd.get(100) < rate;
 	}
@@ -1835,7 +1735,7 @@ public final class Formulas
 		}
 		
 		// if target reflect this skill then the effect will fail
-		if (calcSkillReflect(target, skill) != SKILL_REFLECT_FAILED)
+		if (!calcBuffDebuffReflection(target, skill))
 		{
 			return false;
 		}
@@ -1911,16 +1811,6 @@ public final class Formulas
 		final double failureModifier = attacker.calcStat(Stats.MAGIC_FAILURE_RATE, 1, target, skill);
 		int rate = 100 - Math.round((float) (lvlModifier * targetModifier * resModifier * failureModifier));
 		
-		// FIXME: This have nothing to do with Magic Nukes.
-		if (rate > skill.getMaxChance())
-		{
-			rate = skill.getMaxChance();
-		}
-		else if (rate < skill.getMinChance())
-		{
-			rate = skill.getMinChance();
-		}
-		
 		if (attacker.isDebug() || Config.DEVELOPER)
 		{
 			final StringBuilder stat = new StringBuilder(100);
@@ -1938,25 +1828,30 @@ public final class Formulas
 		return (Rnd.get(100) < rate);
 	}
 	
-	public static double calcManaDam(L2Character attacker, L2Character target, L2Skill skill, boolean ss, boolean bss)
+	public static double calcManaDam(L2Character attacker, L2Character target, L2Skill skill, byte shld, boolean sps, boolean bss, boolean mcrit)
 	{
-		// Mana Burn = (SQR(M.Atk)*Power*(Target Max MP/97))/M.Def
+		// Formula: (SQR(M.Atk)*Power*(Target Max MP/97))/M.Def
 		double mAtk = attacker.getMAtk(target, skill);
 		double mDef = target.getMDef(attacker, skill);
 		final boolean isPvP = attacker.isPlayable() && target.isPlayable();
 		final boolean isPvE = attacker.isPlayable() && target.isL2Attackable();
 		double mp = target.getMaxMp();
-		if (bss)
-		{
-			mAtk *= 4;
-		}
-		else if (ss)
+		
+		switch (shld)
 		{
-			mAtk *= 2;
+			case SHIELD_DEFENSE_SUCCEED:
+				mDef += target.getShldDef();
+				break;
+			case SHIELD_DEFENSE_PERFECT_BLOCK: // perfect block
+				return 1;
 		}
 		
+		// Bonus Spiritshot
+		mAtk *= bss ? 4 : sps ? 2 : 1;
+		
 		double damage = (Math.sqrt(mAtk) * skill.getPower(attacker, target, isPvP, isPvE) * (mp / 97)) / mDef;
 		damage *= (1 + (calcSkillVulnerability(attacker, target, skill) / 100));
+		
 		if (target.isL2Attackable())
 		{
 			damage *= attacker.calcStat(Stats.PVE_MAGICAL_DMG, 1, null, null);
@@ -1974,6 +1869,31 @@ public final class Formulas
 			}
 		}
 		
+		// Failure calculation
+		if (Config.ALT_GAME_MAGICFAILURES && !calcMagicSuccess(attacker, target, skill))
+		{
+			if (attacker.isPlayer())
+			{
+				SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.C1_RESISTED_YOUR_S2);
+				sm.addCharName(target);
+				sm.addSkillName(skill);
+				attacker.sendPacket(sm);
+				damage /= 2;
+			}
+			
+			if (target.isPlayer())
+			{
+				SystemMessage sm2 = SystemMessage.getSystemMessage(SystemMessageId.RESISTED_C1_MAGIC);
+				sm2.addCharName(attacker);
+				target.sendPacket(sm2);
+			}
+		}
+		
+		if (mcrit)
+		{
+			damage *= 3;
+			attacker.sendPacket(SystemMessageId.CRITICAL_HIT_MAGIC);
+		}
 		return damage;
 	}
 	
@@ -1996,14 +1916,29 @@ public final class Formulas
 		return restorePercent;
 	}
 	
-	public static boolean calcPhysicalSkillEvasion(L2Character target, L2Skill skill)
+	public static boolean calcPhysicalSkillEvasion(L2Character activeChar, L2Character target, L2Skill skill)
 	{
-		if ((skill.isMagic() && (skill.getSkillType() != L2SkillType.BLOW)) || skill.isDebuff())
+		if (skill.isMagic() || skill.isDebuff())
 		{
 			return false;
 		}
-		
-		return Rnd.get(100) < target.calcStat(Stats.P_SKILL_EVASION, 0, null, skill);
+		if (Rnd.get(100) < target.calcStat(Stats.P_SKILL_EVASION, 0, null, skill))
+		{
+			if (activeChar.isPlayer())
+			{
+				SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.C1_DODGES_ATTACK);
+				sm.addString(target.getName());
+				activeChar.getActingPlayer().sendPacket(sm);
+			}
+			if (target.isPlayer())
+			{
+				SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.AVOIDED_C1_ATTACK2);
+				sm.addString(activeChar.getName());
+				target.getActingPlayer().sendPacket(sm);
+			}
+			return true;
+		}
+		return false;
 	}
 	
 	public static boolean calcSkillMastery(L2Character actor, L2Skill sk)
@@ -2134,61 +2069,60 @@ public final class Formulas
 		return result;
 	}
 	
-	/**
-	 * Calculate skill reflection according these three possibilities:<br>
-	 * <ul>
-	 * <li>Reflect failed</li>
-	 * <li>Normal reflect (just effects). <U>Only possible for skilltypes: BUFF, REFLECT, HEAL_PERCENT, MANAHEAL_PERCENT, HOT, CPHOT, MPHOT</U></li>
-	 * <li>vengEance reflect (100% damage reflected but damage is also dealt to actor). <U>This is only possible for skills with skilltype PDAM, BLOW, CHARGEDAM, MDAM or DEATHLINK</U></li>
-	 * </ul>
-	 * @param target
-	 * @param skill
-	 * @return SKILL_REFLECTED_FAILED, SKILL_REFLECT_SUCCEED or SKILL_REFLECT_VENGEANCE
-	 */
-	public static byte calcSkillReflect(L2Character target, L2Skill skill)
+	public static void isDamageReflected(L2Character activeChar, L2Character target, L2Skill skill)
 	{
-		// Neither some special skills (like hero debuffs...) or those skills ignoring resistances can be reflected
-		if (!skill.canBeReflected() || (skill.getPower() == -1))
-		{
-			return SKILL_REFLECT_FAILED;
-		}
-		
-		// Only magic and melee skills can be reflected
-		if (!skill.isMagic() && ((skill.getCastRange() == -1) || (skill.getCastRange() > MELEE_ATTACK_RANGE)))
+		boolean reflect = true;
+		// Only melee skills can be reflected
+		if ((skill.getCastRange() == -1) || (skill.getCastRange() > MELEE_ATTACK_RANGE))
 		{
-			return SKILL_REFLECT_FAILED;
+			reflect = false;
 		}
 		
-		byte reflect = SKILL_REFLECT_FAILED;
-		// Check for non-reflected skilltypes, need additional retail check
-		switch (skill.getSkillType())
+		if (reflect)
 		{
-			case PDAM:
-			case MDAM:
-			case BLOW:
-			case DRAIN:
-			case CHARGEDAM:
-			case FATAL:
-			case DEATHLINK:
-			case MANADAM:
-			case CPDAMPERCENT:
-				final Stats stat = skill.isMagic() ? Stats.VENGEANCE_SKILL_MAGIC_DAMAGE : Stats.VENGEANCE_SKILL_PHYSICAL_DAMAGE;
-				final double venganceChance = target.getStat().calcStat(stat, 0, target, skill);
-				if (venganceChance > Rnd.get(100))
+			final double vengeanceChance = target.getStat().calcStat(Stats.VENGEANCE_SKILL_PHYSICAL_DAMAGE, 0, target, skill);
+			if (vengeanceChance > Rnd.get(100))
+			{
+				if (target.isPlayer())
 				{
-					reflect |= SKILL_REFLECT_VENGEANCE;
+					SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.COUNTERED_C1_ATTACK);
+					sm.addCharName(activeChar);
+					target.sendPacket(sm);
 				}
-				break;
-			default:
-				return SKILL_REFLECT_FAILED;
+				if (activeChar.isPlayer())
+				{
+					SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.C1_PERFORMING_COUNTERATTACK);
+					sm.addCharName(target);
+					activeChar.sendPacket(sm);
+				}
+				// Formula from Diego Vargas post: http://www.l2guru.com/forum/showthread.php?p=3122630
+				// 1189 x Your PATK / PDEF of target
+				double vegdamage = ((1189 * target.getPAtk(activeChar)) / activeChar.getPDef(target));
+				activeChar.reduceCurrentHp(vegdamage, target, skill);
+			}
+		}
+	}
+	
+	/**
+	 * Calculate buff/debuff reflection.
+	 * @param target
+	 * @param skill
+	 * @return {@code true} if reflect, {@code false} otherwise.
+	 */
+	public static boolean calcBuffDebuffReflection(L2Character target, L2Skill skill)
+	{
+		boolean reflect = false;
+		// Neither some special skills (like hero debuffs...) or those skills ignoring resistances can't be reflected
+		if ((skill.getPower() == -1) || (skill.isHeroSkill() && skill.isDebuff()))
+		{
+			return reflect;
 		}
 		
 		final double reflectChance = target.calcStat(skill.isMagic() ? Stats.REFLECT_SKILL_MAGIC : Stats.REFLECT_SKILL_PHYSIC, 0, null, skill);
 		if (Rnd.get(100) < reflectChance)
 		{
-			reflect |= SKILL_REFLECT_SUCCEED;
+			reflect = true;
 		}
-		
 		return reflect;
 	}
 	
@@ -2217,21 +2151,8 @@ public final class Formulas
 		
 		// Apply DEX Mod.
 		double blowChance = skill.getBlowChance() * BaseStats.DEX.calcBonus(activeChar);
-		
 		// Apply Position Bonus (TODO: values are unconfirmed, possibly custom, remove or update when confirmed).
-		if (activeChar.isInFrontOfTarget())
-		{
-			blowChance *= 1;
-		}
-		else if (activeChar.isBehindTarget())
-		{
-			blowChance *= 2;
-		}
-		else
-		{
-			blowChance *= 1.5;
-		}
-		
+		blowChance *= (activeChar.isInFrontOfTarget()) ? 1 : (activeChar.isBehindTarget()) ? 2 : 1.5;
 		return Rnd.get(100) < activeChar.calcStat(Stats.BLOW_RATE, blowChance, target, null);
 	}
 	
@@ -2372,11 +2293,7 @@ public final class Formulas
 	{
 		// Lvl Bonus Modifier.
 		rate *= (eff.getSkill().getMagicLevel() > 0) ? (cancelMagicLvl / eff.getSkill().getMagicLevel()) : 1;
-		
-		// Check the Rate Limits.
-		rate = Math.min(Math.max(rate, skill.getMinChance()), skill.getMaxChance());
-		
-		return Rnd.get(100) < rate;
+		return Rnd.get(100) < Math.min(Math.max(rate, skill.getMinChance()), skill.getMaxChance());
 	}
 	
 	/**

+ 0 - 6
L2J_Server_BETA/java/com/l2jserver/gameserver/model/stats/Stats.java

@@ -79,7 +79,6 @@ public enum Stats
 	SHIELD_RATE("rShld"),
 	CRITICAL_RATE("rCrit"),
 	BLOW_RATE("blowRate"),
-	LETHAL_RATE("lethalRate"),
 	MCRITICAL_RATE("mCritRate"),
 	EXPSP_RATE("rExp"),
 	BONUS_EXP("bonusExp"),
@@ -113,7 +112,6 @@ public enum Stats
 	AGGRESSION("aggression"), // locks a mob on tank caster
 	
 	// VULNERABILITIES
-	AGGRESSION_VULN("aggressionVuln"),
 	BLEED_VULN("bleedVuln"),
 	POISON_VULN("poisonVuln"),
 	STUN_VULN("stunVuln"),
@@ -154,7 +152,6 @@ public enum Stats
 	DARK_POWER("darkPower"),
 	
 	// PROFICIENCY
-	AGGRESSION_PROF("aggressionProf"),
 	BLEED_PROF("bleedProf"),
 	POISON_PROF("poisonProf"),
 	STUN_PROF("stunProf"),
@@ -165,11 +162,9 @@ public enum Stats
 	CANCEL_PROF("cancelProf"),
 	DERANGEMENT_PROF("derangementProf"),
 	DEBUFF_PROF("debuffProf"),
-	CRIT_PROF("critProf"),
 	VALAKAS_PROF("valakasProf"),
 	
 	// WEAPONS VULNERABILITIES
-	NONE_WPN_VULN("noneWpnVuln"), // Shields!!!
 	SWORD_WPN_VULN("swordWpnVuln"),
 	BLUNT_WPN_VULN("bluntWpnVuln"),
 	DAGGER_WPN_VULN("daggerWpnVuln"),
@@ -234,7 +229,6 @@ public enum Stats
 	MP_CONSUME("MpConsume"),
 	
 	// T1 stats
-	transformId("transformId"),
 	TALISMAN_SLOTS("talisman"),
 	CLOAK_SLOT("cloak"),
 	

+ 31 - 3
L2J_Server_BETA/java/com/l2jserver/gameserver/network/SystemMessageId.java

@@ -13304,9 +13304,9 @@ public final class SystemMessageId
 	
 	/**
 	 * ID: 2261<br>
-	 * Message: $c1 has given $c2 damage of $s3.
+	 * Message: $c1 has done $s3 points of damage to $c2.
 	 */
-	public static final SystemMessageId C1_GAVE_C2_DAMAGE_OF_S3;
+	public static final SystemMessageId C1_DONE_S3_DAMAGE_TO_C2;
 	
 	/**
 	 * ID: 2262<br>
@@ -14544,6 +14544,12 @@ public final class SystemMessageId
 	 */
 	public static final SystemMessageId YOU_CANT_CANCEL_RECEIVED_MAIL;
 	
+	/**
+	 * ID: 3031<br>
+	 * Message: By using the skill of Einhasad's holy sword, defeat the evil Lilims!
+	 */
+	public static final SystemMessageId USING_EINHASAD_HOLY_SWORD_DEFEAT_LILIMS;
+	
 	/**
 	 * ID: 3033<br>
 	 * Message: By using the invisible skill, sneak into the Dawn's document storage!
@@ -14562,12 +14568,30 @@ public final class SystemMessageId
 	 */
 	public static final SystemMessageId FEMALE_GUARDS_NOTICE_BETTER_THAN_MALE;
 	
+	/**
+	 * ID: 3039<br>
+	 * Message: By using the holy water of Einhasad, open the door possessed by the curse of flames.
+	 */
+	public static final SystemMessageId USING_EINHASAD_HOLY_WATER_TO_OPEN_DOOR;
+	
+	/**
+	 * ID: 3040<br>
+	 * Message: By using the Court Magician's Magic Staff, open the door on which the magician's barrier is placed.
+	 */
+	public static final SystemMessageId USING_COURT_MAGICIANS_STAFF_TO_OPEN_DOOR;
+	
 	/**
 	 * ID: 3059<br>
 	 * Message: $s1 did not receive it during the waiting time, so it was returned automatically.
 	 */
 	public static final SystemMessageId S1_NOT_RECEIVE_DURING_WAITING_TIME_MAIL_RETURNED;
 	
+	/**
+	 * ID: 3060<br>
+	 * Message: The sealing device glitters and moves. Activation complete normally!
+	 */
+	public static final SystemMessageId THE_SEALING_DEVICE_ACTIVATION_COMPLETE;
+	
 	/**
 	 * ID: 3062<br>
 	 * Message: Do you want to pay $s1 Adena ?
@@ -17205,7 +17229,7 @@ public final class SystemMessageId
 		YOU_HAVE_ALREADY_BOARDED_ANOTHER_AIRSHIP = new SystemMessageId(2258);
 		LOC_FANTASY_ISLAND_S1_S2_S3 = new SystemMessageId(2259);
 		PET_CAN_RUN_AWAY_WHEN_HUNGER_BELOW_10_PERCENT = new SystemMessageId(2260);
-		C1_GAVE_C2_DAMAGE_OF_S3 = new SystemMessageId(2261);
+		C1_DONE_S3_DAMAGE_TO_C2 = new SystemMessageId(2261);
 		C1_RECEIVED_DAMAGE_OF_S3_FROM_C2 = new SystemMessageId(2262);
 		C1_RECEIVED_DAMAGE_OF_S3_THROUGH_C2 = new SystemMessageId(2263);
 		C1_EVADED_C2_ATTACK = new SystemMessageId(2264);
@@ -17406,10 +17430,14 @@ public final class SystemMessageId
 		YOU_CANNOT_USE_SKILL_ENCHANT_ATTACKING_TRANSFORMED_BOAT = new SystemMessageId(3028);
 		S1_RETURNED_MAIL = new SystemMessageId(3029);
 		YOU_CANT_CANCEL_RECEIVED_MAIL = new SystemMessageId(3030);
+		USING_EINHASAD_HOLY_SWORD_DEFEAT_LILIMS = new SystemMessageId(3031);
 		SNEAK_INTO_DAWNS_DOCUMENT_STORAGE = new SystemMessageId(3033);
 		MALE_GUARDS_CAN_DETECT_FEMALES_DONT = new SystemMessageId(3037);
 		FEMALE_GUARDS_NOTICE_BETTER_THAN_MALE = new SystemMessageId(3038);
+		USING_EINHASAD_HOLY_WATER_TO_OPEN_DOOR = new SystemMessageId(3039);
+		USING_COURT_MAGICIANS_STAFF_TO_OPEN_DOOR = new SystemMessageId(3040);
 		S1_NOT_RECEIVE_DURING_WAITING_TIME_MAIL_RETURNED = new SystemMessageId(3059);
+		THE_SEALING_DEVICE_ACTIVATION_COMPLETE = new SystemMessageId(3060);
 		DO_YOU_WANT_TO_PAY_S1_ADENA = new SystemMessageId(3062);
 		DO_YOU_WANT_TO_FORWARD = new SystemMessageId(3063);
 		UNREAD_MAIL = new SystemMessageId(3064);