Browse Source

rentrant lock on combat

combat-3
FatBoy-DOTC 7 months ago
parent
commit
cf58e7b984
  1. 54
      src/engine/gameManager/CombatManager.java
  2. 1
      src/engine/objects/AbstractWorldObject.java

54
src/engine/gameManager/CombatManager.java

@ -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,24 +118,18 @@ 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 rangeMod = 1.0f;
@ -159,12 +152,12 @@ public enum CombatManager {
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;
} }
@ -181,14 +174,14 @@ public enum CombatManager {
inRange = true; inRange = true;
break; break;
case Building: case Building:
if(attackRange > 15){ if (attackRange > 15) {
float rangeSquared = (attackRange + target.getBounds().getHalfExtents().x) * (attackRange + target.getBounds().getHalfExtents().x); float rangeSquared = (attackRange + target.getBounds().getHalfExtents().x) * (attackRange + target.getBounds().getHalfExtents().x);
//float distanceSquared = attacker.loc.distanceSquared(target.loc); //float distanceSquared = attacker.loc.distanceSquared(target.loc);
if(distanceSquared < rangeSquared) { if (distanceSquared < rangeSquared) {
inRange = true; inRange = true;
break; break;
} }
}else { } else {
float locX = target.loc.x - target.getBounds().getHalfExtents().x; float locX = target.loc.x - target.getBounds().getHalfExtents().x;
float locZ = target.loc.z - target.getBounds().getHalfExtents().y; float locZ = target.loc.z - target.getBounds().getHalfExtents().y;
float sizeX = (target.getBounds().getHalfExtents().x + attackRange) * 2; float sizeX = (target.getBounds().getHalfExtents().x + attackRange) * 2;
@ -312,7 +305,7 @@ public enum CombatManager {
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
@ -352,7 +345,7 @@ public enum CombatManager {
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 //set auto attack job
setAutoAttackJob(attacker, slot, delay); setAutoAttackJob(attacker, slot, delay);
@ -367,7 +360,7 @@ public enum CombatManager {
setAutoAttackJob(attacker, slot, delay); setAutoAttackJob(attacker, slot, delay);
return; return;
} }
if(attacker.getObjectType().equals(mbEnums.GameObjectType.Mob) && ((Mob)attacker).isPet()) if (attacker.getObjectType().equals(mbEnums.GameObjectType.Mob) && ((Mob) attacker).isPet())
calculatePetDamage(attacker); calculatePetDamage(attacker);
//get the damage type //get the damage type
@ -437,7 +430,7 @@ public enum CombatManager {
if (resists.immuneTo(damageType)) { if (resists.immuneTo(damageType)) {
//set auto attack job //set auto attack job
//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);
setAutoAttackJob(attacker, slot, delay); setAutoAttackJob(attacker, slot, delay);
return; return;
@ -473,7 +466,12 @@ public enum CombatManager {
//set auto attack job //set auto attack job
setAutoAttackJob(attacker, slot, delay); 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();

1
src/engine/objects/AbstractWorldObject.java

@ -59,6 +59,7 @@ public abstract class AbstractWorldObject extends AbstractGameObject {
private Vector3f rot = new Vector3f(0.0f, 0.0f, 0.0f); private Vector3f rot = new Vector3f(0.0f, 0.0f, 0.0f);
private int objectTypeMask = 0; private int objectTypeMask = 0;
private Bounds bounds; private Bounds bounds;
public ReentrantReadWriteLock combatLock = new ReentrantReadWriteLock();
/** /**
* No Id Constructor * No Id Constructor

Loading…
Cancel
Save