|
|
|
@ -518,7 +518,7 @@ public enum CombatManager {
@@ -518,7 +518,7 @@ public enum CombatManager {
|
|
|
|
|
/** |
|
|
|
|
* Attempt to attack target |
|
|
|
|
*/ |
|
|
|
|
private static void attack(AbstractCharacter ac, AbstractWorldObject target, Item weapon, ItemBase wb, boolean mainHand) { |
|
|
|
|
private static void attack(AbstractCharacter attacker, AbstractWorldObject target, Item weapon, ItemBase wb, boolean mainHand) { |
|
|
|
|
|
|
|
|
|
float atr; |
|
|
|
|
int minDamage, maxDamage; |
|
|
|
@ -526,20 +526,20 @@ public enum CombatManager {
@@ -526,20 +526,20 @@ public enum CombatManager {
|
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
|
|
|
|
|
if (ac == null) |
|
|
|
|
if (attacker == null) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
if (target == null) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
if (mainHand) { |
|
|
|
|
atr = ac.getAtrHandOne(); |
|
|
|
|
minDamage = ac.getMinDamageHandOne(); |
|
|
|
|
maxDamage = ac.getMaxDamageHandOne(); |
|
|
|
|
atr = attacker.getAtrHandOne(); |
|
|
|
|
minDamage = attacker.getMinDamageHandOne(); |
|
|
|
|
maxDamage = attacker.getMaxDamageHandOne(); |
|
|
|
|
} else { |
|
|
|
|
atr = ac.getAtrHandTwo(); |
|
|
|
|
minDamage = ac.getMinDamageHandTwo(); |
|
|
|
|
maxDamage = ac.getMaxDamageHandTwo(); |
|
|
|
|
atr = attacker.getAtrHandTwo(); |
|
|
|
|
minDamage = attacker.getMinDamageHandTwo(); |
|
|
|
|
maxDamage = attacker.getMaxDamageHandTwo(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
boolean tarIsRat = false; |
|
|
|
@ -558,9 +558,9 @@ public enum CombatManager {
@@ -558,9 +558,9 @@ public enum CombatManager {
|
|
|
|
|
//Dont think we need to do this anymore.
|
|
|
|
|
|
|
|
|
|
if (tarIsRat) |
|
|
|
|
if (ac.getBonuses().getFloatPercentAll(ModType.Slay, SourceType.Rat) != 0) { //strip away current % dmg buffs then add with rat %
|
|
|
|
|
if (attacker.getBonuses().getFloatPercentAll(ModType.Slay, SourceType.Rat) != 0) { //strip away current % dmg buffs then add with rat %
|
|
|
|
|
|
|
|
|
|
float percent = 1 + ac.getBonuses().getFloatPercentAll(ModType.Slay, SourceType.Rat); |
|
|
|
|
float percent = 1 + attacker.getBonuses().getFloatPercentAll(ModType.Slay, SourceType.Rat); |
|
|
|
|
|
|
|
|
|
minDamage *= percent; |
|
|
|
|
maxDamage *= percent; |
|
|
|
@ -571,24 +571,24 @@ public enum CombatManager {
@@ -571,24 +571,24 @@ public enum CombatManager {
|
|
|
|
|
//subtract stamina
|
|
|
|
|
|
|
|
|
|
if (wb == null) |
|
|
|
|
ac.modifyStamina(-0.5f, ac, true); |
|
|
|
|
attacker.modifyStamina(-0.5f, attacker, true); |
|
|
|
|
else { |
|
|
|
|
float stam = wb.getWeight() / 3; |
|
|
|
|
stam = (stam < 1) ? 1 : stam; |
|
|
|
|
ac.modifyStamina(-(stam), ac, true); |
|
|
|
|
attacker.modifyStamina(-(stam), attacker, true); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
ac.cancelOnAttackSwing(); |
|
|
|
|
attacker.cancelOnAttackSwing(); |
|
|
|
|
|
|
|
|
|
errorTrack = 2; |
|
|
|
|
|
|
|
|
|
//set last time this player has attacked something.
|
|
|
|
|
|
|
|
|
|
if (target.getObjectType().equals(GameObjectType.PlayerCharacter) && target.getObjectUUID() != ac.getObjectUUID() && ac.getObjectType() == GameObjectType.PlayerCharacter) { |
|
|
|
|
ac.setTimeStamp("LastCombatPlayer", System.currentTimeMillis()); |
|
|
|
|
if (target.getObjectType().equals(GameObjectType.PlayerCharacter) && target.getObjectUUID() != attacker.getObjectUUID() && attacker.getObjectType() == GameObjectType.PlayerCharacter) { |
|
|
|
|
attacker.setTimeStamp("LastCombatPlayer", System.currentTimeMillis()); |
|
|
|
|
((PlayerCharacter) target).setTimeStamp("LastCombatPlayer", System.currentTimeMillis()); |
|
|
|
|
} else |
|
|
|
|
ac.setTimeStamp("LastCombatMob", System.currentTimeMillis()); |
|
|
|
|
attacker.setTimeStamp("LastCombatMob", System.currentTimeMillis()); |
|
|
|
|
|
|
|
|
|
errorTrack = 3; |
|
|
|
|
|
|
|
|
@ -599,7 +599,7 @@ public enum CombatManager {
@@ -599,7 +599,7 @@ public enum CombatManager {
|
|
|
|
|
if (target.getObjectType().equals(GameObjectType.Building)) { |
|
|
|
|
|
|
|
|
|
if (BuildingManager.getBuildingFromCache(target.getObjectUUID()) == null) { |
|
|
|
|
ac.setCombatTarget(null); |
|
|
|
|
attacker.setCombatTarget(null); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -607,34 +607,15 @@ public enum CombatManager {
@@ -607,34 +607,15 @@ public enum CombatManager {
|
|
|
|
|
|
|
|
|
|
Building building = (Building) target; |
|
|
|
|
|
|
|
|
|
if (building.getParentZone() != null && building.getParentZone().isPlayerCity()) { |
|
|
|
|
|
|
|
|
|
if (System.currentTimeMillis() > building.getTimeStamp("CallForHelp")) { |
|
|
|
|
|
|
|
|
|
building.getTimestamps().put("CallForHelp", System.currentTimeMillis() + 15000); |
|
|
|
|
|
|
|
|
|
for (Mob mob : building.getParentZone().zoneMobSet) { |
|
|
|
|
if (!mob.isPlayerGuard()) |
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
if (mob.getCombatTarget() != null) |
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
if (mob.getGuild() != null && building.getGuild() != null) |
|
|
|
|
if (!Guild.sameGuild(mob.getGuild().getNation(), building.getGuild().getNation())) |
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
if (mob.getLoc().distanceSquared2D(building.getLoc()) > sqr(300)) |
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
mob.setCombatTarget(ac); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
City playerCity = ZoneManager.getCityAtLocation(building.getLoc()); |
|
|
|
|
if(playerCity != null){ |
|
|
|
|
if(!playerCity.cityOutlaws.contains(attacker.getObjectUUID())) |
|
|
|
|
playerCity.cityOutlaws.add(attacker.getObjectUUID()); |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
AbstractCharacter tar = (AbstractCharacter) target; |
|
|
|
|
defense = tar.getDefenseRating(); |
|
|
|
|
handleRetaliate(tar, ac); //Handle target attacking back if in combat and has no other target
|
|
|
|
|
handleRetaliate(tar, attacker); //Handle target attacking back if in combat and has no other target
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
errorTrack = 4; |
|
|
|
@ -660,11 +641,11 @@ public enum CombatManager {
@@ -660,11 +641,11 @@ public enum CombatManager {
|
|
|
|
|
|
|
|
|
|
if (roll < chance) { |
|
|
|
|
|
|
|
|
|
if (ac.getObjectType().equals(GameObjectType.PlayerCharacter)) |
|
|
|
|
updateAttackTimers((PlayerCharacter) ac, target, true); |
|
|
|
|
if (attacker.getObjectType().equals(GameObjectType.PlayerCharacter)) |
|
|
|
|
updateAttackTimers((PlayerCharacter) attacker, target, true); |
|
|
|
|
|
|
|
|
|
boolean skipPassives = false; |
|
|
|
|
PlayerBonuses bonuses = ac.getBonuses(); |
|
|
|
|
PlayerBonuses bonuses = attacker.getBonuses(); |
|
|
|
|
|
|
|
|
|
if (bonuses != null && bonuses.getBool(ModType.IgnorePassiveDefense, SourceType.None)) |
|
|
|
|
skipPassives = true; |
|
|
|
@ -679,26 +660,26 @@ public enum CombatManager {
@@ -679,26 +660,26 @@ public enum CombatManager {
|
|
|
|
|
// Apply Weapon power effect if any. don't try to apply twice if
|
|
|
|
|
// dual wielding. Perform after passive test for sync purposes.
|
|
|
|
|
|
|
|
|
|
if (ac.getObjectType().equals(GameObjectType.PlayerCharacter) && (mainHand || wb.isTwoHanded())) { |
|
|
|
|
if (attacker.getObjectType().equals(GameObjectType.PlayerCharacter) && (mainHand || wb.isTwoHanded())) { |
|
|
|
|
|
|
|
|
|
dpj = ((PlayerCharacter) ac).getWeaponPower(); |
|
|
|
|
dpj = ((PlayerCharacter) attacker).getWeaponPower(); |
|
|
|
|
|
|
|
|
|
if (dpj != null) { |
|
|
|
|
|
|
|
|
|
PlayerBonuses bonus = ac.getBonuses(); |
|
|
|
|
PlayerBonuses bonus = attacker.getBonuses(); |
|
|
|
|
float attackRange = getWeaponRange(wb, bonus); |
|
|
|
|
dpj.attack(target, attackRange); |
|
|
|
|
|
|
|
|
|
if (dpj.getPower() != null && (dpj.getPowerToken() == -1851459567 || dpj.getPowerToken() == -1851489518)) |
|
|
|
|
((PlayerCharacter) ac).setWeaponPower(dpj); |
|
|
|
|
((PlayerCharacter) attacker).setWeaponPower(dpj); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//check to apply second backstab.
|
|
|
|
|
|
|
|
|
|
if (ac.getObjectType().equals(GameObjectType.PlayerCharacter) && !mainHand) { |
|
|
|
|
if (attacker.getObjectType().equals(GameObjectType.PlayerCharacter) && !mainHand) { |
|
|
|
|
|
|
|
|
|
dpj = ((PlayerCharacter) ac).getWeaponPower(); |
|
|
|
|
dpj = ((PlayerCharacter) attacker).getWeaponPower(); |
|
|
|
|
|
|
|
|
|
if (dpj != null && dpj.getPower() != null && (dpj.getPowerToken() == -1851459567 || dpj.getPowerToken() == -1851489518)) { |
|
|
|
|
float attackRange = getWeaponRange(wb, bonuses); |
|
|
|
@ -718,24 +699,24 @@ public enum CombatManager {
@@ -718,24 +699,24 @@ public enum CombatManager {
|
|
|
|
|
|
|
|
|
|
//Handle Block passive
|
|
|
|
|
|
|
|
|
|
if (testPassive(ac, tarAc, "Block") && canTestBlock(ac, target)) { |
|
|
|
|
if (testPassive(attacker, tarAc, "Block") && canTestBlock(attacker, target)) { |
|
|
|
|
|
|
|
|
|
if (!target.isAlive()) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
sendPassiveDefenseMessage(ac, wb, target, MBServerStatics.COMBAT_SEND_BLOCK, dpj, mainHand); |
|
|
|
|
sendPassiveDefenseMessage(attacker, wb, target, MBServerStatics.COMBAT_SEND_BLOCK, dpj, mainHand); |
|
|
|
|
passiveFired = true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//Handle Parry passive
|
|
|
|
|
|
|
|
|
|
if (!passiveFired) |
|
|
|
|
if (canTestParry(ac, target) && testPassive(ac, tarAc, "Parry")) { |
|
|
|
|
if (canTestParry(attacker, target) && testPassive(attacker, tarAc, "Parry")) { |
|
|
|
|
|
|
|
|
|
if (!target.isAlive()) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
sendPassiveDefenseMessage(ac, wb, target, MBServerStatics.COMBAT_SEND_PARRY, dpj, mainHand); |
|
|
|
|
sendPassiveDefenseMessage(attacker, wb, target, MBServerStatics.COMBAT_SEND_PARRY, dpj, mainHand); |
|
|
|
|
passiveFired = true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -746,12 +727,12 @@ public enum CombatManager {
@@ -746,12 +727,12 @@ public enum CombatManager {
|
|
|
|
|
//Handle Dodge passive
|
|
|
|
|
|
|
|
|
|
if (!passiveFired) |
|
|
|
|
if (testPassive(ac, tarAc, "Dodge")) { |
|
|
|
|
if (testPassive(attacker, tarAc, "Dodge")) { |
|
|
|
|
|
|
|
|
|
if (!target.isAlive()) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
sendPassiveDefenseMessage(ac, wb, target, MBServerStatics.COMBAT_SEND_DODGE, dpj, mainHand); |
|
|
|
|
sendPassiveDefenseMessage(attacker, wb, target, MBServerStatics.COMBAT_SEND_DODGE, dpj, mainHand); |
|
|
|
|
passiveFired = true; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -767,7 +748,7 @@ public enum CombatManager {
@@ -767,7 +748,7 @@ public enum CombatManager {
|
|
|
|
|
//if target is player, set last attack timestamp
|
|
|
|
|
|
|
|
|
|
if (target.getObjectType().equals(GameObjectType.PlayerCharacter)) |
|
|
|
|
updateAttackTimers((PlayerCharacter) target, ac, false); |
|
|
|
|
updateAttackTimers((PlayerCharacter) target, attacker, false); |
|
|
|
|
|
|
|
|
|
//Get damage Type
|
|
|
|
|
|
|
|
|
@ -775,7 +756,7 @@ public enum CombatManager {
@@ -775,7 +756,7 @@ public enum CombatManager {
|
|
|
|
|
|
|
|
|
|
if (wb != null) |
|
|
|
|
damageType = wb.getDamageType(); |
|
|
|
|
else if (ac.getObjectType().equals(GameObjectType.Mob) && ((Mob) ac).isSiege()) |
|
|
|
|
else if (attacker.getObjectType().equals(GameObjectType.Mob) && ((Mob) attacker).isSiege()) |
|
|
|
|
damageType = DamageType.Siege; |
|
|
|
|
else |
|
|
|
|
damageType = DamageType.Crush; |
|
|
|
@ -794,7 +775,7 @@ public enum CombatManager {
@@ -794,7 +775,7 @@ public enum CombatManager {
|
|
|
|
|
//make sure target is not immune to damage type;
|
|
|
|
|
|
|
|
|
|
if (resists != null && resists.immuneTo(damageType)) { |
|
|
|
|
sendCombatMessage(ac, target, 0f, wb, dpj, mainHand); |
|
|
|
|
sendCombatMessage(attacker, target, 0f, wb, dpj, mainHand); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -805,9 +786,9 @@ public enum CombatManager {
@@ -805,9 +786,9 @@ public enum CombatManager {
|
|
|
|
|
float damage; |
|
|
|
|
|
|
|
|
|
if (wb != null) |
|
|
|
|
damage = calculateDamage(ac, tarAc, minDamage, maxDamage, damageType, resists); |
|
|
|
|
damage = calculateDamage(attacker, tarAc, minDamage, maxDamage, damageType, resists); |
|
|
|
|
else |
|
|
|
|
damage = calculateDamage(ac, tarAc, minDamage, maxDamage, damageType, resists); |
|
|
|
|
damage = calculateDamage(attacker, tarAc, minDamage, maxDamage, damageType, resists); |
|
|
|
|
|
|
|
|
|
float d = 0f; |
|
|
|
|
|
|
|
|
@ -821,34 +802,34 @@ public enum CombatManager {
@@ -821,34 +802,34 @@ public enum CombatManager {
|
|
|
|
|
damage *= 2.5f; //increase damage if sitting
|
|
|
|
|
|
|
|
|
|
if (tarAc.getHealth() > 0) |
|
|
|
|
d = tarAc.modifyHealth(-damage, ac, false); |
|
|
|
|
d = tarAc.modifyHealth(-damage, attacker, false); |
|
|
|
|
|
|
|
|
|
} else if (target.getObjectType().equals(GameObjectType.Building)) { |
|
|
|
|
|
|
|
|
|
if (BuildingManager.getBuildingFromCache(target.getObjectUUID()) == null) { |
|
|
|
|
ac.setCombatTarget(null); |
|
|
|
|
attacker.setCombatTarget(null); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (target.getHealth() > 0) |
|
|
|
|
d = ((Building) target).modifyHealth(-damage, ac); |
|
|
|
|
d = ((Building) target).modifyHealth(-damage, attacker); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
errorTrack = 13; |
|
|
|
|
|
|
|
|
|
//Test to see if any damage needs done to weapon or armor
|
|
|
|
|
|
|
|
|
|
testItemDamage(ac, target, weapon, wb); |
|
|
|
|
testItemDamage(attacker, target, weapon, wb); |
|
|
|
|
|
|
|
|
|
// if target is dead, we got the killing blow, remove attack timers on our weapons
|
|
|
|
|
|
|
|
|
|
if (tarAc != null && !tarAc.isAlive()) |
|
|
|
|
removeAttackTimers(ac); |
|
|
|
|
removeAttackTimers(attacker); |
|
|
|
|
|
|
|
|
|
//test double death fix
|
|
|
|
|
|
|
|
|
|
if (d != 0) |
|
|
|
|
sendCombatMessage(ac, target, damage, wb, dpj, mainHand); //send damage message
|
|
|
|
|
sendCombatMessage(attacker, target, damage, wb, dpj, mainHand); //send damage message
|
|
|
|
|
|
|
|
|
|
errorTrack = 14; |
|
|
|
|
|
|
|
|
@ -875,7 +856,7 @@ public enum CombatManager {
@@ -875,7 +856,7 @@ public enum CombatManager {
|
|
|
|
|
int procChance = ThreadLocalRandom.current().nextInt(100); |
|
|
|
|
|
|
|
|
|
if (procChance < MBServerStatics.PROC_CHANCE) |
|
|
|
|
((WeaponProcEffectModifier) aem).applyProc(ac, target); |
|
|
|
|
((WeaponProcEffectModifier) aem).applyProc(attacker, target); |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -887,52 +868,52 @@ public enum CombatManager {
@@ -887,52 +868,52 @@ public enum CombatManager {
|
|
|
|
|
|
|
|
|
|
//handle damage shields
|
|
|
|
|
|
|
|
|
|
if (ac.isAlive() && tarAc != null && tarAc.isAlive()) |
|
|
|
|
handleDamageShields(ac, tarAc, damage); |
|
|
|
|
if (attacker.isAlive() && tarAc != null && tarAc.isAlive()) |
|
|
|
|
handleDamageShields(attacker, tarAc, damage); |
|
|
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
|
|
// Apply Weapon power effect if any.
|
|
|
|
|
// don't try to apply twice if dual wielding.
|
|
|
|
|
|
|
|
|
|
if (ac.getObjectType().equals(GameObjectType.PlayerCharacter) && (mainHand || wb.isTwoHanded())) { |
|
|
|
|
dpj = ((PlayerCharacter) ac).getWeaponPower(); |
|
|
|
|
if (attacker.getObjectType().equals(GameObjectType.PlayerCharacter) && (mainHand || wb.isTwoHanded())) { |
|
|
|
|
dpj = ((PlayerCharacter) attacker).getWeaponPower(); |
|
|
|
|
|
|
|
|
|
if (dpj != null) { |
|
|
|
|
|
|
|
|
|
PowersBase wp = dpj.getPower(); |
|
|
|
|
|
|
|
|
|
if (wp.requiresHitRoll() == false) { |
|
|
|
|
PlayerBonuses bonus = ac.getBonuses(); |
|
|
|
|
PlayerBonuses bonus = attacker.getBonuses(); |
|
|
|
|
float attackRange = getWeaponRange(wb, bonus); |
|
|
|
|
dpj.attack(target, attackRange); |
|
|
|
|
} else |
|
|
|
|
((PlayerCharacter) ac).setWeaponPower(null); |
|
|
|
|
((PlayerCharacter) attacker).setWeaponPower(null); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (target.getObjectType() == GameObjectType.Mob) |
|
|
|
|
((Mob) target).handleDirectAggro(ac); |
|
|
|
|
((Mob) target).handleDirectAggro(attacker); |
|
|
|
|
|
|
|
|
|
errorTrack = 17; |
|
|
|
|
|
|
|
|
|
//miss, Send miss message
|
|
|
|
|
|
|
|
|
|
sendCombatMessage(ac, target, 0f, wb, dpj, mainHand); |
|
|
|
|
sendCombatMessage(attacker, target, 0f, wb, dpj, mainHand); |
|
|
|
|
|
|
|
|
|
//if attacker is player, set last attack timestamp
|
|
|
|
|
|
|
|
|
|
if (ac.getObjectType().equals(GameObjectType.PlayerCharacter)) |
|
|
|
|
updateAttackTimers((PlayerCharacter) ac, target, true); |
|
|
|
|
if (attacker.getObjectType().equals(GameObjectType.PlayerCharacter)) |
|
|
|
|
updateAttackTimers((PlayerCharacter) attacker, target, true); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
errorTrack = 18; |
|
|
|
|
|
|
|
|
|
//cancel effects that break on attack or attackSwing
|
|
|
|
|
ac.cancelOnAttack(); |
|
|
|
|
attacker.cancelOnAttack(); |
|
|
|
|
|
|
|
|
|
} catch (Exception e) { |
|
|
|
|
Logger.error(ac.getName() + ' ' + errorTrack + ' ' + e); |
|
|
|
|
Logger.error(attacker.getName() + ' ' + errorTrack + ' ' + e); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|