|  |  | @ -47,7 +47,7 @@ public enum CombatManager { | 
			
		
	
		
		
			
				
					
					|  |  |  |     public static final int COMBAT_PARRY_ANIMATION = 299; |  |  |  |     public static final int COMBAT_PARRY_ANIMATION = 299; | 
			
		
	
		
		
			
				
					
					|  |  |  |     public static final int COMBAT_DODGE_ANIMATION = 300; |  |  |  |     public static final int COMBAT_DODGE_ANIMATION = 300; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     public static void combatCycle(AbstractCharacter attacker, AbstractWorldObject target) { |  |  |  |     public static void combatCycle(AbstractCharacter attacker, AbstractWorldObject target, long addedDelay) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         //early exit checks
 |  |  |  |         //early exit checks
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -78,45 +78,45 @@ public enum CombatManager { | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (mainWeapon == null && offWeapon == null) { |  |  |  |         if (mainWeapon == null && offWeapon == null) { | 
			
		
	
		
		
			
				
					
					|  |  |  |             //no weapons equipped, punch with both fists
 |  |  |  |             //no weapons equipped, punch with both fists
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             processAttack(attacker, target, mbEnums.EquipSlotType.RHELD); |  |  |  |             processAttack(attacker, target, mbEnums.EquipSlotType.RHELD,addedDelay); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |             if (attacker.getObjectType().equals(mbEnums.GameObjectType.PlayerCharacter)) |  |  |  |             if (attacker.getObjectType().equals(mbEnums.GameObjectType.PlayerCharacter)) | 
			
		
	
		
		
			
				
					
					|  |  |  |                 processAttack(attacker, target, mbEnums.EquipSlotType.LHELD); |  |  |  |                 processAttack(attacker, target, mbEnums.EquipSlotType.LHELD,addedDelay); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |             return; |  |  |  |             return; | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (mainWeapon != null && offWeapon == null) { |  |  |  |         if (mainWeapon != null && offWeapon == null) { | 
			
		
	
		
		
			
				
					
					|  |  |  |             //swing right hand only
 |  |  |  |             //swing right hand only
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             processAttack(attacker, target, mbEnums.EquipSlotType.RHELD); |  |  |  |             processAttack(attacker, target, mbEnums.EquipSlotType.RHELD,addedDelay); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |             return; |  |  |  |             return; | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (mainWeapon == null && offWeapon != null && !offWeapon.template.item_skill_used.equals("Block")) { |  |  |  |         if (mainWeapon == null && offWeapon != null && !offWeapon.template.item_skill_used.equals("Block")) { | 
			
		
	
		
		
			
				
					
					|  |  |  |             //swing left hand only
 |  |  |  |             //swing left hand only
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             processAttack(attacker, target, mbEnums.EquipSlotType.LHELD); |  |  |  |             processAttack(attacker, target, mbEnums.EquipSlotType.LHELD,addedDelay); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |             return; |  |  |  |             return; | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (mainWeapon == null && offWeapon != null && offWeapon.template.item_skill_used.equals("Block")) { |  |  |  |         if (mainWeapon == null && offWeapon != null && offWeapon.template.item_skill_used.equals("Block")) { | 
			
		
	
		
		
			
				
					
					|  |  |  |             //no weapon equipped with a shield, punch with one hand
 |  |  |  |             //no weapon equipped with a shield, punch with one hand
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             processAttack(attacker, target, mbEnums.EquipSlotType.RHELD); |  |  |  |             processAttack(attacker, target, mbEnums.EquipSlotType.RHELD,addedDelay); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |             return; |  |  |  |             return; | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (mainWeapon != null && offWeapon != null && offWeapon.template.item_skill_used.equals("Block")) { |  |  |  |         if (mainWeapon != null && offWeapon != null && offWeapon.template.item_skill_used.equals("Block")) { | 
			
		
	
		
		
			
				
					
					|  |  |  |             //one weapon equipped with a shield, swing with one hand
 |  |  |  |             //one weapon equipped with a shield, swing with one hand
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             processAttack(attacker, target, mbEnums.EquipSlotType.RHELD); |  |  |  |             processAttack(attacker, target, mbEnums.EquipSlotType.RHELD,addedDelay); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |             return; |  |  |  |             return; | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (mainWeapon != null && offWeapon != null && !offWeapon.template.item_skill_used.equals("Block")) { |  |  |  |         if (mainWeapon != null && offWeapon != null && !offWeapon.template.item_skill_used.equals("Block")) { | 
			
		
	
		
		
			
				
					
					|  |  |  |             //two weapons equipped, swing both hands
 |  |  |  |             //two weapons equipped, swing both hands
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             processAttack(attacker, target, mbEnums.EquipSlotType.RHELD); |  |  |  |             processAttack(attacker, target, mbEnums.EquipSlotType.RHELD,addedDelay); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |             if (attacker.getObjectType().equals(mbEnums.GameObjectType.PlayerCharacter)) |  |  |  |             if (attacker.getObjectType().equals(mbEnums.GameObjectType.PlayerCharacter)) | 
			
		
	
		
		
			
				
					
					|  |  |  |                 processAttack(attacker, target, mbEnums.EquipSlotType.LHELD); |  |  |  |                 processAttack(attacker, target, mbEnums.EquipSlotType.LHELD,addedDelay); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     public static void processAttack(AbstractCharacter attacker, AbstractWorldObject target, mbEnums.EquipSlotType slot) { |  |  |  |     public static void processAttack(AbstractCharacter attacker, AbstractWorldObject target, mbEnums.EquipSlotType slot, long addedDelay) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (slot == null || target == null || attacker == null) |  |  |  |         if (slot == null || target == null || attacker == null) | 
			
		
	
		
		
			
				
					
					|  |  |  |             return; |  |  |  |             return; | 
			
		
	
	
		
		
			
				
					|  |  | @ -126,24 +126,6 @@ public enum CombatManager { | 
			
		
	
		
		
			
				
					
					|  |  |  |                 return; |  |  |  |                 return; | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         long delay = 0L; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         if(attacker.getTimestamps().containsKey("Attack" + slot)){ |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             if(attacker.getObjectType().equals(mbEnums.GameObjectType.PlayerCharacter)){ |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 if(slot.equals(mbEnums.EquipSlotType.RHELD)){ |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     delay = (long)(attacker.speedHandOne * 100L); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 }else{ |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     delay = (long)(attacker.speedHandTwo * 100L); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             if(System.currentTimeMillis() < attacker.getTimestamps().get("Attack" + slot)){ |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 return; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         attacker.getTimestamps().put("Attack" + slot, System.currentTimeMillis() + delay - 500L); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         target.combatLock.writeLock().lock(); |  |  |  |         target.combatLock.writeLock().lock(); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         // check if character is in range to attack target
 |  |  |  |         // check if character is in range to attack target
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -212,7 +194,7 @@ public enum CombatManager { | 
			
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |             } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             //get delay for the auto attack job
 |  |  |  |             //get delay for the auto attack job
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             delay = 5000; |  |  |  |             long delay = 5000; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             //if (weapon != null) {
 |  |  |  |             //if (weapon != null) {
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -248,7 +230,7 @@ public enum CombatManager { | 
			
		
	
		
		
			
				
					
					|  |  |  |                     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,0); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |                     } |  |  |  |                     } | 
			
		
	
		
		
			
				
					
					|  |  |  |                 } |  |  |  |                 } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -640,7 +622,7 @@ public enum CombatManager { | 
			
		
	
		
		
			
				
					
					|  |  |  |         ConcurrentHashMap<String, JobContainer> timers = attacker.getTimers(); |  |  |  |         ConcurrentHashMap<String, JobContainer> timers = attacker.getTimers(); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (timers != null) { |  |  |  |         if (timers != null) { | 
			
		
	
		
		
			
				
					
					|  |  |  |             AttackJob aj = new AttackJob(attacker, slot.ordinal(), true); |  |  |  |             AttackJob aj = new AttackJob(attacker, slot.ordinal(), true, attacker.getCombatTarget()); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |             JobContainer job; |  |  |  |             JobContainer job; | 
			
		
	
		
		
			
				
					
					|  |  |  |             job = JobScheduler.getInstance().scheduleJob(aj, (System.currentTimeMillis() + delay)); // offset 1 millisecond so no overlap issue
 |  |  |  |             job = JobScheduler.getInstance().scheduleJob(aj, (System.currentTimeMillis() + delay)); // offset 1 millisecond so no overlap issue
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             timers.put("Attack" + slot.name(), job); |  |  |  |             timers.put("Attack" + slot.name(), job); | 
			
		
	
	
		
		
			
				
					|  |  | 
 |