diff --git a/src/engine/gameManager/CombatManager.java b/src/engine/gameManager/CombatManager.java
index 7c422c06..529bb476 100644
--- a/src/engine/gameManager/CombatManager.java
+++ b/src/engine/gameManager/CombatManager.java
@@ -47,7 +47,7 @@ public enum CombatManager {
     public static final int COMBAT_PARRY_ANIMATION = 299;
     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
 
@@ -78,45 +78,45 @@ public enum CombatManager {
 
         if (mainWeapon == null && offWeapon == null) {
             //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))
-                processAttack(attacker, target, mbEnums.EquipSlotType.LHELD);
+                processAttack(attacker, target, mbEnums.EquipSlotType.LHELD,addedDelay);
             return;
         }
 
         if (mainWeapon != null && offWeapon == null) {
             //swing right hand only
-            processAttack(attacker, target, mbEnums.EquipSlotType.RHELD);
+            processAttack(attacker, target, mbEnums.EquipSlotType.RHELD,addedDelay);
             return;
         }
 
         if (mainWeapon == null && offWeapon != null && !offWeapon.template.item_skill_used.equals("Block")) {
             //swing left hand only
-            processAttack(attacker, target, mbEnums.EquipSlotType.LHELD);
+            processAttack(attacker, target, mbEnums.EquipSlotType.LHELD,addedDelay);
             return;
         }
 
         if (mainWeapon == null && offWeapon != null && offWeapon.template.item_skill_used.equals("Block")) {
             //no weapon equipped with a shield, punch with one hand
-            processAttack(attacker, target, mbEnums.EquipSlotType.RHELD);
+            processAttack(attacker, target, mbEnums.EquipSlotType.RHELD,addedDelay);
             return;
         }
 
         if (mainWeapon != null && offWeapon != null && offWeapon.template.item_skill_used.equals("Block")) {
             //one weapon equipped with a shield, swing with one hand
-            processAttack(attacker, target, mbEnums.EquipSlotType.RHELD);
+            processAttack(attacker, target, mbEnums.EquipSlotType.RHELD,addedDelay);
             return;
         }
 
         if (mainWeapon != null && offWeapon != null && !offWeapon.template.item_skill_used.equals("Block")) {
             //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))
-                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)
             return;
@@ -126,24 +126,6 @@ public enum CombatManager {
                 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();
 
         // check if character is in range to attack target
@@ -212,7 +194,7 @@ public enum CombatManager {
             }
 
             //get delay for the auto attack job
-            delay = 5000;
+            long delay = 5000;
 
             //if (weapon != null) {
 
@@ -248,7 +230,7 @@ public enum CombatManager {
                     if (((AbstractCharacter) target).combatTarget == null || !((AbstractCharacter) target).combatTarget.isAlive()) {
                         ((AbstractCharacter) target).combatTarget = attacker;
                         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();
 
         if (timers != null) {
-            AttackJob aj = new AttackJob(attacker, slot.ordinal(), true);
+            AttackJob aj = new AttackJob(attacker, slot.ordinal(), true, attacker.getCombatTarget());
             JobContainer job;
             job = JobScheduler.getInstance().scheduleJob(aj, (System.currentTimeMillis() + delay)); // offset 1 millisecond so no overlap issue
             timers.put("Attack" + slot.name(), job);
diff --git a/src/engine/jobs/AttackJob.java b/src/engine/jobs/AttackJob.java
index f2bb394b..01d30e8c 100644
--- a/src/engine/jobs/AttackJob.java
+++ b/src/engine/jobs/AttackJob.java
@@ -12,6 +12,7 @@ package engine.jobs;
 import engine.gameManager.CombatManager;
 import engine.job.AbstractJob;
 import engine.objects.AbstractCharacter;
+import engine.objects.AbstractWorldObject;
 
 public class AttackJob extends AbstractJob {
 
@@ -19,16 +20,20 @@ public class AttackJob extends AbstractJob {
     private final int slot;
     private final boolean success;
 
-    public AttackJob(AbstractCharacter source, int slot, boolean success) {
+    public final AbstractWorldObject target;
+
+    public AttackJob(AbstractCharacter source, int slot, boolean success, AbstractWorldObject target) {
         super();
         this.source = source;
         this.slot = slot;
         this.success = success;
+        this.target = target;
     }
 
     @Override
     protected void doJob() {
-        CombatManager.combatCycle(this.source, this.source.combatTarget);
+
+        CombatManager.combatCycle(this.source,target,0);
     }
 
     public boolean success() {
diff --git a/src/engine/mobileAI/MobAI.java b/src/engine/mobileAI/MobAI.java
index e19ece34..eb74c86e 100644
--- a/src/engine/mobileAI/MobAI.java
+++ b/src/engine/mobileAI/MobAI.java
@@ -125,7 +125,7 @@ public class MobAI {
                 if (mob.isMoving() && mob.getRange() > 20)
                     return;
 
-                CombatManager.combatCycle(mob, target);
+                CombatManager.combatCycle(mob, target,0);
             }
 
             if (target.getPet() != null)
@@ -159,7 +159,7 @@ public class MobAI {
                 MovementManager.sendRWSSMsg(mob);
 
 
-            CombatManager.combatCycle(mob, target);
+            CombatManager.combatCycle(mob, target,0);
 
             if (mob.isSiege()) {
                 PowerProjectileMsg ppm = new PowerProjectileMsg(mob, target);
@@ -183,7 +183,7 @@ public class MobAI {
 
             //no weapons, default mob attack speed 3 seconds.
 
-            CombatManager.combatCycle(mob, target);
+            CombatManager.combatCycle(mob, target,0);
 
         } catch (Exception e) {
             Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: AttackMob" + " " + e.getMessage());
diff --git a/src/engine/net/client/handlers/AttackCmdMsgHandler.java b/src/engine/net/client/handlers/AttackCmdMsgHandler.java
index 154804d8..27f25538 100644
--- a/src/engine/net/client/handlers/AttackCmdMsgHandler.java
+++ b/src/engine/net/client/handlers/AttackCmdMsgHandler.java
@@ -2,6 +2,7 @@ package engine.net.client.handlers;
 
 import engine.gameManager.BuildingManager;
 import engine.gameManager.CombatManager;
+import engine.jobs.AttackJob;
 import engine.mbEnums;
 import engine.net.client.ClientConnection;
 import engine.net.client.msg.AttackCmdMsg;
@@ -82,7 +83,25 @@ public class AttackCmdMsgHandler extends AbstractClientMsgHandler {
         if (playerCharacter.isSit())
             CombatManager.toggleSit(false, origin);
 
-        CombatManager.combatCycle(playerCharacter, target);
+        long addedDelay = 0;
+        //check if we are changing targets, cancel outstanding jobs if so
+        if (playerCharacter.getTimers().containsKey("Attack" + mbEnums.EquipSlotType.RHELD)) {
+            AttackJob ajR = ((AttackJob)playerCharacter.getTimers().get("Attack" + mbEnums.EquipSlotType.RHELD).getJob());
+            if(!ajR.target.equals(target)){
+                playerCharacter.getTimers().get("Attack" + mbEnums.EquipSlotType.RHELD).cancelJob();
+                addedDelay = ajR.getStopTime() - System.currentTimeMillis();
+            }
+        }
+
+        if (playerCharacter.getTimers().containsKey("Attack" + mbEnums.EquipSlotType.LHELD)) {
+            AttackJob ajL = ((AttackJob)playerCharacter.getTimers().get("Attack" + mbEnums.EquipSlotType.LHELD).getJob());
+            if(!ajL.target.equals(target)){
+                playerCharacter.getTimers().get("Attack" + mbEnums.EquipSlotType.LHELD).cancelJob();
+                addedDelay = ajL.getStopTime() - System.currentTimeMillis();
+            }
+        }
+
+        CombatManager.combatCycle(playerCharacter, target, addedDelay);
 
         return true;
     }