|  |  | @ -12,7 +12,6 @@ import engine.job.JobContainer; | 
			
		
	
		
		
			
				
					
					|  |  |  | import engine.job.JobScheduler; |  |  |  | import engine.job.JobScheduler; | 
			
		
	
		
		
			
				
					
					|  |  |  | import engine.jobs.AttackJob; |  |  |  | import engine.jobs.AttackJob; | 
			
		
	
		
		
			
				
					
					|  |  |  | import engine.jobs.DeferredPowerJob; |  |  |  | import engine.jobs.DeferredPowerJob; | 
			
		
	
		
		
			
				
					
					|  |  |  | import engine.math.Vector3f; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | import engine.mbEnums; |  |  |  | import engine.mbEnums; | 
			
		
	
		
		
			
				
					
					|  |  |  | import engine.net.client.ClientConnection; |  |  |  | import engine.net.client.ClientConnection; | 
			
		
	
		
		
			
				
					
					|  |  |  | import engine.net.client.msg.TargetedActionMsg; |  |  |  | import engine.net.client.msg.TargetedActionMsg; | 
			
		
	
	
		
		
			
				
					|  |  | @ -119,361 +118,360 @@ public enum CombatManager { | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     public static void processAttack(AbstractCharacter attacker, AbstractWorldObject target, mbEnums.EquipSlotType slot) { |  |  |  |     public static void processAttack(AbstractCharacter attacker, AbstractWorldObject target, mbEnums.EquipSlotType slot) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         if(slot == null || target == null || attacker == null) |  |  |  |         if (slot == null || target == null || attacker == null) | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |             return; |  |  |  |             return; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (attacker.getObjectType().equals(mbEnums.GameObjectType.PlayerCharacter)) { |  |  |  |         if (attacker.getObjectType().equals(mbEnums.GameObjectType.PlayerCharacter)) { | 
			
		
	
		
		
			
				
					
					|  |  |  |             if (!attacker.isCombat()) |  |  |  |             if (!attacker.isCombat()) | 
			
		
	
		
		
			
				
					
					|  |  |  |                 return; |  |  |  |                 return; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             //check if this slot is on attack timer, if timer has passed clear it, else early exit
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             if(attacker.getTimers() != null && attacker.getTimers().containsKey("Attack"+slot.name())) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 if(attacker.getTimers().get("Attack"+slot.name()).timeToExecutionLeft() <= 0) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     attacker.getTimers().remove("Attack"+slot.name()); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 else |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     return; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         target.combatLock.writeLock().lock(); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         // check if character is in range to attack target
 |  |  |  |         // check if character is in range to attack target
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         try { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             PlayerBonuses bonus = attacker.getBonuses(); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         PlayerBonuses bonus = attacker.getBonuses(); |  |  |  |             float rangeMod = 1.0f; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |             float attackRange = MBServerStatics.NO_WEAPON_RANGE; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         float rangeMod = 1.0f; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         float attackRange = MBServerStatics.NO_WEAPON_RANGE; |  |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         Item weapon = attacker.charItemManager.getEquipped(slot); |  |  |  |             Item weapon = attacker.charItemManager.getEquipped(slot); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (weapon != null) { |  |  |  |             if (weapon != null) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |             if (bonus != null) |  |  |  |                 if (bonus != null) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 rangeMod += bonus.getFloatPercentAll(mbEnums.ModType.WeaponRange, mbEnums.SourceType.None); |  |  |  |                     rangeMod += bonus.getFloatPercentAll(mbEnums.ModType.WeaponRange, mbEnums.SourceType.None); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             attackRange += weapon.template.item_weapon_max_range * rangeMod; |  |  |  |                 attackRange += weapon.template.item_weapon_max_range * rangeMod; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |             } | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (attacker.getObjectType().equals(mbEnums.GameObjectType.Mob)) |  |  |  |             if (attacker.getObjectType().equals(mbEnums.GameObjectType.Mob)) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |             if (((Mob) attacker).isSiege()) |  |  |  |                 if (((Mob) attacker).isSiege()) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 attackRange = 300; |  |  |  |                     attackRange = 300; | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         float distanceSquared = attacker.loc.distanceSquared(target.loc); |  |  |  |             float distanceSquared = attacker.loc.distanceSquared(target.loc); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         boolean inRange = false; |  |  |  |             boolean inRange = false; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         if (AbstractCharacter.IsAbstractCharacter(target)) { |  |  |  |             if (AbstractCharacter.IsAbstractCharacter(target)) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |             attackRange += ((AbstractCharacter)target).calcHitBox(); |  |  |  |                 attackRange += ((AbstractCharacter) target).calcHitBox(); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         } else { |  |  |  |             } else { | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |             } | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         if(attackRange > 15 && attacker.isMoving()){ |  |  |  |             if (attackRange > 15 && attacker.isMoving()) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |             //cannot shoot bow while moving;
 |  |  |  |                 //cannot shoot bow while moving;
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |             return; |  |  |  |                 return; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |             } | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         switch (target.getObjectType()) { |  |  |  |             switch (target.getObjectType()) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |             case PlayerCharacter: |  |  |  |                 case PlayerCharacter: | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 attackRange += ((PlayerCharacter) target).getCharacterHeight() * 0.5f; |  |  |  |                     attackRange += ((PlayerCharacter) target).getCharacterHeight() * 0.5f; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 if (distanceSquared < attackRange * attackRange) |  |  |  |                     if (distanceSquared < attackRange * attackRange) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                     inRange = true; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 break; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             case Mob: |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 attackRange += ((AbstractCharacter) target).calcHitBox(); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 if (distanceSquared < attackRange * attackRange) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     inRange = true; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 break; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             case Building: |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 if(attackRange > 15){ |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     float rangeSquared = (attackRange + target.getBounds().getHalfExtents().x) * (attackRange + target.getBounds().getHalfExtents().x); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     //float distanceSquared = attacker.loc.distanceSquared(target.loc);
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     if(distanceSquared < rangeSquared) { |  |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |                         inRange = true; |  |  |  |                         inRange = true; | 
			
		
	
		
		
			
				
					
					|  |  |  |                         break; |  |  |  |                     break; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                     } |  |  |  |                 case Mob: | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 }else { |  |  |  |                     attackRange += ((AbstractCharacter) target).calcHitBox(); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                     float locX = target.loc.x - target.getBounds().getHalfExtents().x; |  |  |  |                     if (distanceSquared < attackRange * attackRange) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                     float locZ = target.loc.z - target.getBounds().getHalfExtents().y; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     float sizeX = (target.getBounds().getHalfExtents().x + attackRange) * 2; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     float sizeZ = (target.getBounds().getHalfExtents().y + attackRange) * 2; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     Rectangle2D.Float rect = new Rectangle2D.Float(locX, locZ, sizeX, sizeZ); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     if (rect.contains(new Point2D.Float(attacker.loc.x, attacker.loc.z))) |  |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |                         inRange = true; |  |  |  |                         inRange = true; | 
			
		
	
		
		
			
				
					
					|  |  |  |                     break; |  |  |  |                     break; | 
			
		
	
		
		
			
				
					
					|  |  |  |                 } |  |  |  |                 case Building: | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |                     if (attackRange > 15) { | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                         float rangeSquared = (attackRange + target.getBounds().getHalfExtents().x) * (attackRange + target.getBounds().getHalfExtents().x); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                         //float distanceSquared = attacker.loc.distanceSquared(target.loc);
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                         if (distanceSquared < rangeSquared) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                             inRange = true; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                             break; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                         } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     } else { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                         float locX = target.loc.x - target.getBounds().getHalfExtents().x; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                         float locZ = target.loc.z - target.getBounds().getHalfExtents().y; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                         float sizeX = (target.getBounds().getHalfExtents().x + attackRange) * 2; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                         float sizeZ = (target.getBounds().getHalfExtents().y + attackRange) * 2; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                         Rectangle2D.Float rect = new Rectangle2D.Float(locX, locZ, sizeX, sizeZ); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                         if (rect.contains(new Point2D.Float(attacker.loc.x, attacker.loc.z))) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                             inRange = true; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                         break; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         //get delay for the auto attack job
 |  |  |  |             //get delay for the auto attack job
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         long delay = 5000; |  |  |  |             long delay = 5000; | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (weapon != null) { |  |  |  |             if (weapon != null) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             int wepSpeed = (int) (weapon.template.item_weapon_wepspeed); |  |  |  |                 int wepSpeed = (int) (weapon.template.item_weapon_wepspeed); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             if (weapon.getBonusPercent(mbEnums.ModType.WeaponSpeed, mbEnums.SourceType.None) != 0f) //add weapon speed bonus
 |  |  |  |                 if (weapon.getBonusPercent(mbEnums.ModType.WeaponSpeed, mbEnums.SourceType.None) != 0f) //add weapon speed bonus
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 wepSpeed *= (1 + weapon.getBonus(mbEnums.ModType.WeaponSpeed, mbEnums.SourceType.None)); |  |  |  |                     wepSpeed *= (1 + weapon.getBonus(mbEnums.ModType.WeaponSpeed, mbEnums.SourceType.None)); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             if (attacker.getBonuses() != null && attacker.getBonuses().getFloatPercentAll(mbEnums.ModType.AttackDelay, mbEnums.SourceType.None) != 0f) //add effects speed bonus
 |  |  |  |                 if (attacker.getBonuses() != null && attacker.getBonuses().getFloatPercentAll(mbEnums.ModType.AttackDelay, mbEnums.SourceType.None) != 0f) //add effects speed bonus
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 wepSpeed *= (1 + attacker.getBonuses().getFloatPercentAll(mbEnums.ModType.AttackDelay, mbEnums.SourceType.None)); |  |  |  |                     wepSpeed *= (1 + attacker.getBonuses().getFloatPercentAll(mbEnums.ModType.AttackDelay, mbEnums.SourceType.None)); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             if (wepSpeed < 10) |  |  |  |                 if (wepSpeed < 10) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 wepSpeed = 10; //Old was 10, but it can be reached lower with legit buffs,effects.
 |  |  |  |                     wepSpeed = 10; //Old was 10, but it can be reached lower with legit buffs,effects.
 | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             delay = wepSpeed * 100L; |  |  |  |                 delay = wepSpeed * 100L; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |             } | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (attacker.getObjectType().equals(mbEnums.GameObjectType.Mob)) |  |  |  |             if (attacker.getObjectType().equals(mbEnums.GameObjectType.Mob)) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |             ((Mob) attacker).nextAttackTime = System.currentTimeMillis() + delay; |  |  |  |                 ((Mob) attacker).nextAttackTime = System.currentTimeMillis() + delay; | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (inRange) { |  |  |  |             if (inRange) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             //handle retaliate
 |  |  |  |                 //handle retaliate
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |             if (AbstractCharacter.IsAbstractCharacter(target)) { |  |  |  |                 if (AbstractCharacter.IsAbstractCharacter(target)) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 if (((AbstractCharacter) target).combatTarget == null || !((AbstractCharacter) target).combatTarget.isAlive()) { |  |  |  |                     if (((AbstractCharacter) target).combatTarget == null || !((AbstractCharacter) target).combatTarget.isAlive()) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                     ((AbstractCharacter) target).combatTarget = attacker; |  |  |  |                         ((AbstractCharacter) target).combatTarget = attacker; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                     if (target.getObjectType().equals(mbEnums.GameObjectType.PlayerCharacter) && ((AbstractCharacter) target).isCombat()) |  |  |  |                         if (target.getObjectType().equals(mbEnums.GameObjectType.PlayerCharacter) && ((AbstractCharacter) target).isCombat()) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                         combatCycle((AbstractCharacter) target, attacker); |  |  |  |                             combatCycle((AbstractCharacter) target, attacker); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     } | 
			
		
	
		
		
			
				
					
					|  |  |  |                 } |  |  |  |                 } | 
			
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             // take stamina away from attacker if its not a mob
 |  |  |  |                 // take stamina away from attacker if its not a mob
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |             if (weapon != null && !attacker.getObjectType().equals(mbEnums.GameObjectType.Mob)) { |  |  |  |                 if (weapon != null && !attacker.getObjectType().equals(mbEnums.GameObjectType.Mob)) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 //check if Out of Stamina
 |  |  |  |                     //check if Out of Stamina
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 if (attacker.getObjectType().equals(mbEnums.GameObjectType.PlayerCharacter)) { |  |  |  |                     if (attacker.getObjectType().equals(mbEnums.GameObjectType.PlayerCharacter)) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                     if (attacker.getStamina() < (weapon.template.item_wt / 3f)) { |  |  |  |                         if (attacker.getStamina() < (weapon.template.item_wt / 3f)) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                         //set auto attack job
 |  |  |  |                             //set auto attack job
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                         setAutoAttackJob(attacker, slot, delay); |  |  |  |                             setAutoAttackJob(attacker, slot, delay); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                         return; |  |  |  |                             return; | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                         } | 
			
		
	
		
		
			
				
					
					|  |  |  |                     } |  |  |  |                     } | 
			
		
	
		
		
			
				
					
					|  |  |  |                 } |  |  |  |                     float stam = weapon.template.item_wt / 3f; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 float stam = weapon.template.item_wt / 3f; |  |  |  |                     stam = (stam < 1) ? 1 : stam; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 stam = (stam < 1) ? 1 : stam; |  |  |  |                     attacker.modifyStamina(-(stam), attacker, true); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 attacker.modifyStamina(-(stam), attacker, true); |  |  |  |                 } else | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |             } else |  |  |  |                     attacker.modifyStamina(1, attacker, true); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 attacker.modifyStamina(1, attacker, true); |  |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             //cancel things that are cancelled by an attack
 |  |  |  |                 //cancel things that are cancelled by an attack
 | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             attacker.cancelOnAttackSwing(); |  |  |  |                 attacker.cancelOnAttackSwing(); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             //declare relevant variables
 |  |  |  |                 //declare relevant variables
 | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             int min = attacker.minDamageHandOne; |  |  |  |                 int min = attacker.minDamageHandOne; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |             int max = attacker.maxDamageHandOne; |  |  |  |                 int max = attacker.maxDamageHandOne; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |             int atr = attacker.atrHandOne; |  |  |  |                 int atr = attacker.atrHandOne; | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             //get the proper stats based on which slot is attacking
 |  |  |  |                 //get the proper stats based on which slot is attacking
 | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             if (slot == mbEnums.EquipSlotType.LHELD) { |  |  |  |                 if (slot == mbEnums.EquipSlotType.LHELD) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 min = attacker.minDamageHandTwo; |  |  |  |                     min = attacker.minDamageHandTwo; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 max = attacker.maxDamageHandTwo; |  |  |  |                     max = attacker.maxDamageHandTwo; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 atr = attacker.atrHandTwo; |  |  |  |                     atr = attacker.atrHandTwo; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |                 } | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             //apply weapon powers before early exit for miss or passives
 |  |  |  |                 //apply weapon powers before early exit for miss or passives
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |             DeferredPowerJob dpj = null; |  |  |  |                 DeferredPowerJob dpj = null; | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             if (attacker.getObjectType().equals(mbEnums.GameObjectType.PlayerCharacter)) { |  |  |  |                 if (attacker.getObjectType().equals(mbEnums.GameObjectType.PlayerCharacter)) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                 dpj = ((PlayerCharacter) attacker).getWeaponPower(); |  |  |  |                     dpj = ((PlayerCharacter) attacker).getWeaponPower(); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                 if (dpj != null) { |  |  |  |                     if (dpj != null) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                     dpj.attack(target, attackRange); |  |  |  |                         dpj.attack(target, attackRange); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                     if (dpj.getPower() != null && (dpj.getPowerToken() == -1851459567 || dpj.getPowerToken() == -1851489518)) |  |  |  |                         if (dpj.getPower() != null && (dpj.getPowerToken() == -1851459567 || dpj.getPowerToken() == -1851489518)) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                         ((PlayerCharacter) attacker).setWeaponPower(dpj); |  |  |  |                             ((PlayerCharacter) attacker).setWeaponPower(dpj); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     } | 
			
		
	
		
		
			
				
					
					|  |  |  |                 } |  |  |  |                 } | 
			
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             int def = 0; |  |  |  |                 int def = 0; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             if (AbstractCharacter.IsAbstractCharacter(target)) |  |  |  |                 if (AbstractCharacter.IsAbstractCharacter(target)) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 def = ((AbstractCharacter) target).defenseRating; |  |  |  |                     def = ((AbstractCharacter) target).defenseRating; | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             //calculate hit chance based off ATR and DEF
 |  |  |  |                 //calculate hit chance based off ATR and DEF
 | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             int hitChance; |  |  |  |                 int hitChance; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |             if (def == 0) |  |  |  |                 if (def == 0) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 def = 1; |  |  |  |                     def = 1; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |             float dif = atr * 1f / def; |  |  |  |                 float dif = atr * 1f / def; | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             if (dif <= 0.8f) |  |  |  |                 if (dif <= 0.8f) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 hitChance = 4; |  |  |  |                     hitChance = 4; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |             else |  |  |  |                 else | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 hitChance = ((int) (450 * (dif - 0.8f)) + 4); |  |  |  |                     hitChance = ((int) (450 * (dif - 0.8f)) + 4); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             if (target.getObjectType() == mbEnums.GameObjectType.Building) |  |  |  |                 if (target.getObjectType() == mbEnums.GameObjectType.Building) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 hitChance = 100; |  |  |  |                     hitChance = 100; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |             int passiveAnim = getPassiveAnimation(mbEnums.PassiveType.None); // checking for a miss due to ATR vs Def
 |  |  |  |                 int passiveAnim = getPassiveAnimation(mbEnums.PassiveType.None); // checking for a miss due to ATR vs Def
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |             if (ThreadLocalRandom.current().nextInt(100) > hitChance) { |  |  |  |                 if (ThreadLocalRandom.current().nextInt(100) > hitChance) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 TargetedActionMsg msg = new TargetedActionMsg(attacker, target, 0f, passiveAnim); |  |  |  |                     TargetedActionMsg msg = new TargetedActionMsg(attacker, target, 0f, passiveAnim); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                 if (target.getObjectType() == mbEnums.GameObjectType.PlayerCharacter) |  |  |  |                     if (target.getObjectType() == mbEnums.GameObjectType.PlayerCharacter) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                     DispatchManager.dispatchMsgToInterestArea(target, msg, mbEnums.DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false); |  |  |  |                         DispatchManager.dispatchMsgToInterestArea(target, msg, mbEnums.DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 else |  |  |  |                     else | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                     DispatchManager.sendToAllInRange(attacker, msg); |  |  |  |                         DispatchManager.sendToAllInRange(attacker, msg); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                 //we need to send the animation even if the attacker misses
 |  |  |  |                     //we need to send the animation even if the attacker misses
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 TargetedActionMsg cmm = new TargetedActionMsg(attacker, target, (float) 0, getSwingAnimation(weapon.template,null,slot)); |  |  |  |                     TargetedActionMsg cmm = new TargetedActionMsg(attacker, target, (float) 0, getSwingAnimation(weapon.template, null, slot)); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 DispatchManager.sendToAllInRange(target, cmm); |  |  |  |                     DispatchManager.sendToAllInRange(target, cmm); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                 //set auto attack job
 |  |  |  |                     //set auto attack job
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 setAutoAttackJob(attacker, slot, delay); |  |  |  |                     setAutoAttackJob(attacker, slot, delay); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 return; |  |  |  |                     return; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |                 } | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             //calculate passive chances only if target is AbstractCharacter
 |  |  |  |                 //calculate passive chances only if target is AbstractCharacter
 | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             if (EnumSet.of(mbEnums.GameObjectType.PlayerCharacter, mbEnums.GameObjectType.NPC, mbEnums.GameObjectType.Mob).contains(target.getObjectType())) { |  |  |  |                 if (EnumSet.of(mbEnums.GameObjectType.PlayerCharacter, mbEnums.GameObjectType.NPC, mbEnums.GameObjectType.Mob).contains(target.getObjectType())) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 mbEnums.PassiveType passiveType = mbEnums.PassiveType.None; |  |  |  |                     mbEnums.PassiveType passiveType = mbEnums.PassiveType.None; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 int hitRoll = ThreadLocalRandom.current().nextInt(100); |  |  |  |                     int hitRoll = ThreadLocalRandom.current().nextInt(100); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                 float dodgeChance = ((AbstractCharacter) target).getPassiveChance("Dodge", attacker.getLevel(), true); |  |  |  |                     float dodgeChance = ((AbstractCharacter) target).getPassiveChance("Dodge", attacker.getLevel(), true); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 float blockChance = ((AbstractCharacter) target).getPassiveChance("Block", attacker.getLevel(), true); |  |  |  |                     float blockChance = ((AbstractCharacter) target).getPassiveChance("Block", attacker.getLevel(), true); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 float parryChance = ((AbstractCharacter) target).getPassiveChance("Parry", attacker.getLevel(), true); |  |  |  |                     float parryChance = ((AbstractCharacter) target).getPassiveChance("Parry", attacker.getLevel(), true); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                 // Passive chance clamped at 75
 |  |  |  |                     // Passive chance clamped at 75
 | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                 dodgeChance = Math.max(0, Math.min(75, dodgeChance)); |  |  |  |                     dodgeChance = Math.max(0, Math.min(75, dodgeChance)); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 blockChance = Math.max(0, Math.min(75, blockChance)); |  |  |  |                     blockChance = Math.max(0, Math.min(75, blockChance)); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 parryChance = Math.max(0, Math.min(75, parryChance)); |  |  |  |                     parryChance = Math.max(0, Math.min(75, parryChance)); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                 if (hitRoll < dodgeChance) |  |  |  |                     if (hitRoll < dodgeChance) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                     passiveType = mbEnums.PassiveType.Dodge; |  |  |  |                         passiveType = mbEnums.PassiveType.Dodge; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 else if (hitRoll < blockChance) |  |  |  |                     else if (hitRoll < blockChance) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                     passiveType = mbEnums.PassiveType.Block; |  |  |  |                         passiveType = mbEnums.PassiveType.Block; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 else if (hitRoll < parryChance) |  |  |  |                     else if (hitRoll < parryChance) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                     passiveType = mbEnums.PassiveType.Parry; |  |  |  |                         passiveType = mbEnums.PassiveType.Parry; | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                 if (!passiveType.equals(mbEnums.PassiveType.None)) { |  |  |  |                     if (!passiveType.equals(mbEnums.PassiveType.None)) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                     passiveAnim = getPassiveAnimation(passiveType); |  |  |  |                         passiveAnim = getPassiveAnimation(passiveType); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                     TargetedActionMsg msg = new TargetedActionMsg(attacker, passiveAnim, target, passiveType.value); |  |  |  |                         TargetedActionMsg msg = new TargetedActionMsg(attacker, passiveAnim, target, passiveType.value); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                     if (target.getObjectType() == mbEnums.GameObjectType.PlayerCharacter) |  |  |  |                         if (target.getObjectType() == mbEnums.GameObjectType.PlayerCharacter) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                         DispatchManager.dispatchMsgToInterestArea(target, msg, mbEnums.DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false); |  |  |  |                             DispatchManager.dispatchMsgToInterestArea(target, msg, mbEnums.DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                     //we need to send the animation even if the attacker misses
 |  |  |  |                         //we need to send the animation even if the attacker misses
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                     TargetedActionMsg cmm = new TargetedActionMsg(attacker, target, (float) 0, getSwingAnimation(weapon.template,null,slot)); |  |  |  |                         TargetedActionMsg cmm = new TargetedActionMsg(attacker, target, (float) 0, getSwingAnimation(weapon.template, null, slot)); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                     DispatchManager.sendToAllInRange(target, cmm); |  |  |  |                         DispatchManager.sendToAllInRange(target, cmm); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                         //set auto attack job
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                         setAutoAttackJob(attacker, slot, delay); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                         return; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 //calculate the base damage
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 int damage = ThreadLocalRandom.current().nextInt(min, max + 1); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 if (damage == 0) { | 
			
		
	
		
		
			
				
					
					|  |  |  |                     //set auto attack job
 |  |  |  |                     //set auto attack job
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                     setAutoAttackJob(attacker, slot, delay); |  |  |  |                     setAutoAttackJob(attacker, slot, delay); | 
			
		
	
		
		
			
				
					
					|  |  |  |                     return; |  |  |  |                     return; | 
			
		
	
		
		
			
				
					
					|  |  |  |                 } |  |  |  |                 } | 
			
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |                 if (attacker.getObjectType().equals(mbEnums.GameObjectType.Mob) && ((Mob) attacker).isPet()) | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     calculatePetDamage(attacker); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             //calculate the base damage
 |  |  |  |                 //get the damage type
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |             int damage = ThreadLocalRandom.current().nextInt(min, max + 1); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             if (damage == 0) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 //set auto attack job
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 setAutoAttackJob(attacker, slot, delay); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 return; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             if(attacker.getObjectType().equals(mbEnums.GameObjectType.Mob) && ((Mob)attacker).isPet()) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 calculatePetDamage(attacker); |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             //get the damage type
 |  |  |  |                 mbEnums.DamageType damageType; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             mbEnums.DamageType damageType; |  |  |  |                 if (attacker.charItemManager.getEquipped().get(slot) == null) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     damageType = mbEnums.DamageType.CRUSHING; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     if (attacker.getObjectType().equals(mbEnums.GameObjectType.Mob)) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                         if (((Mob) attacker).isSiege()) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                             damageType = mbEnums.DamageType.SIEGE; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 } else { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     damageType = (mbEnums.DamageType) attacker.charItemManager.getEquipped().get(slot).template.item_weapon_damage.keySet().toArray()[0]; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             if (attacker.charItemManager.getEquipped().get(slot) == null) { |  |  |  |                 //get resists
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 damageType = mbEnums.DamageType.CRUSHING; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 if (attacker.getObjectType().equals(mbEnums.GameObjectType.Mob)) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     if (((Mob) attacker).isSiege()) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                         damageType = mbEnums.DamageType.SIEGE; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             } else { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 damageType = (mbEnums.DamageType) attacker.charItemManager.getEquipped().get(slot).template.item_weapon_damage.keySet().toArray()[0]; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             //get resists
 |  |  |  |                 Resists resists; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             Resists resists; |  |  |  |                 if (!AbstractCharacter.IsAbstractCharacter(target)) | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     resists = ((Building) target).getResists();            //this is a building
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 else | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     resists = ((AbstractCharacter) target).getResists();   //this is a character
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             if (!AbstractCharacter.IsAbstractCharacter(target)) |  |  |  |                 if (AbstractCharacter.IsAbstractCharacter(target)) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 resists = ((Building) target).getResists();            //this is a building
 |  |  |  |                     AbstractCharacter absTarget = (AbstractCharacter) target; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |             else |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 resists = ((AbstractCharacter) target).getResists();   //this is a character
 |  |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             if (AbstractCharacter.IsAbstractCharacter(target)) { |  |  |  |                     //check damage shields
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 AbstractCharacter absTarget = (AbstractCharacter) target; |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                 //check damage shields
 |  |  |  |                     PlayerBonuses bonuses = absTarget.getBonuses(); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                 PlayerBonuses bonuses = absTarget.getBonuses(); |  |  |  |                     if (bonuses != null) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                 if (bonuses != null) { |  |  |  |                         ConcurrentHashMap<AbstractEffectModifier, DamageShield> damageShields = bonuses.getDamageShields(); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                         float total = 0; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                     ConcurrentHashMap<AbstractEffectModifier, DamageShield> damageShields = bonuses.getDamageShields(); |  |  |  |                         for (DamageShield ds : damageShields.values()) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                     float total = 0; |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                     for (DamageShield ds : damageShields.values()) { |  |  |  |                             //get amount to damage back
 | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                         //get amount to damage back
 |  |  |  |                             float amount; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                         float amount; |  |  |  |                             if (ds.usePercent()) | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                 amount = damage * ds.getAmount() / 100; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                             else | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                 amount = ds.getAmount(); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                         if (ds.usePercent()) |  |  |  |                             //get resisted damage for damagetype
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                             amount = damage * ds.getAmount() / 100; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                         else |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                             amount = ds.getAmount(); |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                         //get resisted damage for damagetype
 |  |  |  |                             if (resists != null) | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                 amount = resists.getResistedDamage(absTarget, attacker, ds.getDamageType(), amount, 0); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                             total += amount; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                         } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                         if (resists != null) |  |  |  |                         if (total > 0) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                             amount = resists.getResistedDamage(absTarget, attacker, ds.getDamageType(), amount, 0); |  |  |  |                             //apply Damage back
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                         total += amount; |  |  |  |                             attacker.modifyHealth(-total, absTarget, true); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                             TargetedActionMsg cmm = new TargetedActionMsg(attacker, attacker, total, 0); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                             DispatchManager.sendToAllInRange(target, cmm); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                         } | 
			
		
	
		
		
			
				
					
					|  |  |  |                     } |  |  |  |                     } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                     if (total > 0) { |  |  |  |                     if (resists != null) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                         //apply Damage back
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                         attacker.modifyHealth(-total, absTarget, true); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                         TargetedActionMsg cmm = new TargetedActionMsg(attacker, attacker, total, 0); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                         DispatchManager.sendToAllInRange(target, cmm); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 } |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                 if (resists != null) { |  |  |  |                         //check for damage type immunities
 | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                     //check for damage type immunities
 |  |  |  |                         if (resists.immuneTo(damageType)) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                             //set auto attack job
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                             //we need to send the animation even if the attacker misses
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                             TargetedActionMsg cmm = new TargetedActionMsg(attacker, target, (float) 0, getSwingAnimation(weapon.template, null, slot)); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                             DispatchManager.sendToAllInRange(target, cmm); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                             setAutoAttackJob(attacker, slot, delay); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                             return; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                         } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                         //calculate resisted damage including fortitude
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                     if (resists.immuneTo(damageType)) { |  |  |  |                         damage = (int) resists.getResistedDamage(attacker, (AbstractCharacter) target, damageType, damage, 0); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                         //set auto attack job
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                         //we need to send the animation even if the attacker misses
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                         TargetedActionMsg cmm = new TargetedActionMsg(attacker, target, (float) 0, getSwingAnimation(weapon.template,null,slot)); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                         DispatchManager.sendToAllInRange(target, cmm); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                         setAutoAttackJob(attacker, slot, delay); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                         return; |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |                     } |  |  |  |                     } | 
			
		
	
		
		
			
				
					
					|  |  |  |                     //calculate resisted damage including fortitude
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     damage = (int) resists.getResistedDamage(attacker, (AbstractCharacter) target, damageType, damage, 0); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 } |  |  |  |                 } | 
			
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             //remove damage from target health
 |  |  |  |                 //remove damage from target health
 | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             if (damage > 0) { |  |  |  |                 if (damage > 0) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                 if (AbstractCharacter.IsAbstractCharacter(target)) |  |  |  |                     if (AbstractCharacter.IsAbstractCharacter(target)) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                     ((AbstractCharacter) target).modifyHealth(-damage, attacker, true); |  |  |  |                         ((AbstractCharacter) target).modifyHealth(-damage, attacker, true); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 else |  |  |  |                     else | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                     ((Building) target).modifyHealth(-damage, attacker); |  |  |  |                         ((Building) target).modifyHealth(-damage, attacker); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                 int attackAnim = getSwingAnimation(null, null, slot); |  |  |  |                     int attackAnim = getSwingAnimation(null, null, slot); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 if (attacker.charItemManager.getEquipped().get(slot) != null) { |  |  |  |                     if (attacker.charItemManager.getEquipped().get(slot) != null) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                     if (attacker.getObjectType().equals(mbEnums.GameObjectType.PlayerCharacter)) { |  |  |  |                         if (attacker.getObjectType().equals(mbEnums.GameObjectType.PlayerCharacter)) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                         DeferredPowerJob weaponPower = ((PlayerCharacter) attacker).getWeaponPower(); |  |  |  |                             DeferredPowerJob weaponPower = ((PlayerCharacter) attacker).getWeaponPower(); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                         attackAnim = getSwingAnimation(weapon.template, weaponPower, slot); |  |  |  |                             attackAnim = getSwingAnimation(weapon.template, weaponPower, slot); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                     } else { |  |  |  |                         } else { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                         attackAnim = getSwingAnimation(weapon.template, null, slot); |  |  |  |                             attackAnim = getSwingAnimation(weapon.template, null, slot); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                         } | 
			
		
	
		
		
			
				
					
					|  |  |  |                     } |  |  |  |                     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     TargetedActionMsg cmm = new TargetedActionMsg(attacker, target, (float) damage, attackAnim); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     DispatchManager.sendToAllInRange(target, cmm); | 
			
		
	
		
		
			
				
					
					|  |  |  |                 } |  |  |  |                 } | 
			
		
	
		
		
			
				
					
					|  |  |  |                 TargetedActionMsg cmm = new TargetedActionMsg(attacker, target, (float) damage, attackAnim); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 DispatchManager.sendToAllInRange(target, cmm); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |             } | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         //set auto attack job
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         setAutoAttackJob(attacker, slot, delay); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             //set auto attack job
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             setAutoAttackJob(attacker, slot, delay); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         } catch (Exception ex) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             cancelAutoAttackJob(attacker,slot); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             //Logger.error("COMBAT CAUGHT ERROR: " + ex.getMessage());
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         } finally { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             target.combatLock.writeLock().unlock(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     public static void toggleCombat(boolean toggle, ClientConnection origin) { |  |  |  |     public static void toggleCombat(boolean toggle, ClientConnection origin) { | 
			
		
	
	
		
		
			
				
					|  |  | @ -624,7 +622,20 @@ public enum CombatManager { | 
			
		
	
		
		
			
				
					
					|  |  |  |             Logger.error("Unable to find Timers for Character " + attacker.getObjectUUID()); |  |  |  |             Logger.error("Unable to find Timers for Character " + attacker.getObjectUUID()); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |     public static int calculatePetDamage(AbstractCharacter agent) { |  |  |  |     public static void cancelAutoAttackJob(AbstractCharacter attacker, mbEnums.EquipSlotType slot) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         attacker.getTimestamps().put("Attack" + slot.name(), System.currentTimeMillis()); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         //handle auto attack job creation
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         ConcurrentHashMap<String, JobContainer> timers = attacker.getTimers(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         if (timers != null) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             timers.get("Attack" + slot.name()).cancelJob(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         } else | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             Logger.error("Unable to find Timers for Character " + attacker.getObjectUUID()); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     public static void calculatePetDamage(AbstractCharacter agent) { | 
			
		
	
		
		
			
				
					
					|  |  |  |         //damage calc for pet
 |  |  |  |         //damage calc for pet
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         float range; |  |  |  |         float range; | 
			
		
	
		
		
			
				
					
					|  |  |  |         float damage; |  |  |  |         float damage; | 
			
		
	
	
		
		
			
				
					|  |  | @ -636,7 +647,6 @@ public enum CombatManager { | 
			
		
	
		
		
			
				
					
					|  |  |  |         dmgMultiplier += agent.getLevel() * 0.1f; |  |  |  |         dmgMultiplier += agent.getLevel() * 0.1f; | 
			
		
	
		
		
			
				
					
					|  |  |  |         range = (float) (maxDmg - minDmg); |  |  |  |         range = (float) (maxDmg - minDmg); | 
			
		
	
		
		
			
				
					
					|  |  |  |         damage = min + ((ThreadLocalRandom.current().nextFloat() * range) + (ThreadLocalRandom.current().nextFloat() * range)) / 2; |  |  |  |         damage = min + ((ThreadLocalRandom.current().nextFloat() * range) + (ThreadLocalRandom.current().nextFloat() * range)) / 2; | 
			
		
	
		
		
			
				
					
					|  |  |  |         return (int) (damage * dmgMultiplier); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |     public static double getMinDmg(double min, AbstractCharacter agent) { |  |  |  |     public static double getMinDmg(double min, AbstractCharacter agent) { | 
			
		
	
		
		
			
				
					
					|  |  |  |         int primary = agent.getStatStrCurrent(); |  |  |  |         int primary = agent.getStatStrCurrent(); | 
			
		
	
	
		
		
			
				
					|  |  | 
 |