|
|
|
@ -12,7 +12,6 @@ import engine.job.JobContainer;
@@ -12,7 +12,6 @@ import engine.job.JobContainer;
|
|
|
|
|
import engine.job.JobScheduler; |
|
|
|
|
import engine.jobs.AttackJob; |
|
|
|
|
import engine.jobs.DeferredPowerJob; |
|
|
|
|
import engine.math.Vector3f; |
|
|
|
|
import engine.mbEnums; |
|
|
|
|
import engine.net.client.ClientConnection; |
|
|
|
|
import engine.net.client.msg.TargetedActionMsg; |
|
|
|
@ -119,24 +118,18 @@ public enum CombatManager {
@@ -119,24 +118,18 @@ public enum CombatManager {
|
|
|
|
|
|
|
|
|
|
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; |
|
|
|
|
|
|
|
|
|
if (attacker.getObjectType().equals(mbEnums.GameObjectType.PlayerCharacter)) { |
|
|
|
|
if (!attacker.isCombat()) |
|
|
|
|
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
|
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
PlayerBonuses bonus = attacker.getBonuses(); |
|
|
|
|
|
|
|
|
|
float rangeMod = 1.0f; |
|
|
|
@ -159,12 +152,12 @@ public enum CombatManager {
@@ -159,12 +152,12 @@ public enum CombatManager {
|
|
|
|
|
|
|
|
|
|
boolean inRange = false; |
|
|
|
|
if (AbstractCharacter.IsAbstractCharacter(target)) { |
|
|
|
|
attackRange += ((AbstractCharacter)target).calcHitBox(); |
|
|
|
|
attackRange += ((AbstractCharacter) target).calcHitBox(); |
|
|
|
|
} else { |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if(attackRange > 15 && attacker.isMoving()){ |
|
|
|
|
if (attackRange > 15 && attacker.isMoving()) { |
|
|
|
|
//cannot shoot bow while moving;
|
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
@ -181,14 +174,14 @@ public enum CombatManager {
@@ -181,14 +174,14 @@ public enum CombatManager {
|
|
|
|
|
inRange = true; |
|
|
|
|
break; |
|
|
|
|
case Building: |
|
|
|
|
if(attackRange > 15){ |
|
|
|
|
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) { |
|
|
|
|
if (distanceSquared < rangeSquared) { |
|
|
|
|
inRange = true; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
}else { |
|
|
|
|
} 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; |
|
|
|
@ -312,7 +305,7 @@ public enum CombatManager {
@@ -312,7 +305,7 @@ public enum CombatManager {
|
|
|
|
|
DispatchManager.sendToAllInRange(attacker, msg); |
|
|
|
|
|
|
|
|
|
//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); |
|
|
|
|
|
|
|
|
|
//set auto attack job
|
|
|
|
@ -352,7 +345,7 @@ public enum CombatManager {
@@ -352,7 +345,7 @@ public enum CombatManager {
|
|
|
|
|
DispatchManager.dispatchMsgToInterestArea(target, msg, mbEnums.DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false); |
|
|
|
|
|
|
|
|
|
//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); |
|
|
|
|
//set auto attack job
|
|
|
|
|
setAutoAttackJob(attacker, slot, delay); |
|
|
|
@ -367,7 +360,7 @@ public enum CombatManager {
@@ -367,7 +360,7 @@ public enum CombatManager {
|
|
|
|
|
setAutoAttackJob(attacker, slot, delay); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
if(attacker.getObjectType().equals(mbEnums.GameObjectType.Mob) && ((Mob)attacker).isPet()) |
|
|
|
|
if (attacker.getObjectType().equals(mbEnums.GameObjectType.Mob) && ((Mob) attacker).isPet()) |
|
|
|
|
calculatePetDamage(attacker); |
|
|
|
|
|
|
|
|
|
//get the damage type
|
|
|
|
@ -437,7 +430,7 @@ public enum CombatManager {
@@ -437,7 +430,7 @@ public enum CombatManager {
|
|
|
|
|
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)); |
|
|
|
|
TargetedActionMsg cmm = new TargetedActionMsg(attacker, target, (float) 0, getSwingAnimation(weapon.template, null, slot)); |
|
|
|
|
DispatchManager.sendToAllInRange(target, cmm); |
|
|
|
|
setAutoAttackJob(attacker, slot, delay); |
|
|
|
|
return; |
|
|
|
@ -473,7 +466,12 @@ public enum CombatManager {
@@ -473,7 +466,12 @@ public enum CombatManager {
|
|
|
|
|
|
|
|
|
|
//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) { |
|
|
|
@ -624,7 +622,20 @@ public enum CombatManager {
@@ -624,7 +622,20 @@ public enum CombatManager {
|
|
|
|
|
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
|
|
|
|
|
float range; |
|
|
|
|
float damage; |
|
|
|
@ -636,7 +647,6 @@ public enum CombatManager {
@@ -636,7 +647,6 @@ public enum CombatManager {
|
|
|
|
|
dmgMultiplier += agent.getLevel() * 0.1f; |
|
|
|
|
range = (float) (maxDmg - minDmg); |
|
|
|
|
damage = min + ((ThreadLocalRandom.current().nextFloat() * range) + (ThreadLocalRandom.current().nextFloat() * range)) / 2; |
|
|
|
|
return (int) (damage * dmgMultiplier); |
|
|
|
|
} |
|
|
|
|
public static double getMinDmg(double min, AbstractCharacter agent) { |
|
|
|
|
int primary = agent.getStatStrCurrent(); |
|
|
|
|