Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ef9c431d5e | |||
| cf6db2444c | |||
| d074aa8f1c | |||
| 4ea4609b1b | |||
| 58e84bfc21 | |||
| 0a82a69a95 | |||
| b33af64f60 | |||
| 6311f8b2f8 | |||
| e4ac2bc489 | |||
| 5b6896e537 | |||
| 46b9da0612 | |||
| 898f6dfa69 | |||
| 67628a21b3 | |||
| 9f09a0e8b0 |
@@ -89,7 +89,7 @@ public class Dungeon {
|
|||||||
writer.putInt(rulingGuild.getCharter());
|
writer.putInt(rulingGuild.getCharter());
|
||||||
writer.putInt(0); // always 00000000
|
writer.putInt(0); // always 00000000
|
||||||
|
|
||||||
writer.put((byte)1);//set safehold
|
writer.put((byte)0);
|
||||||
|
|
||||||
writer.put((byte) 1);
|
writer.put((byte) 1);
|
||||||
writer.put((byte) 1); // *** Refactor: What are these flags?
|
writer.put((byte) 1); // *** Refactor: What are these flags?
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
package engine.gameManager;
|
package engine.gameManager;
|
||||||
|
|
||||||
|
import engine.Enum;
|
||||||
import engine.Enum.*;
|
import engine.Enum.*;
|
||||||
import engine.exception.MsgSendException;
|
import engine.exception.MsgSendException;
|
||||||
import engine.job.JobContainer;
|
import engine.job.JobContainer;
|
||||||
@@ -924,7 +925,6 @@ public enum CombatManager {
|
|||||||
damage *= 1 + (armorPierce * 0.01f);
|
damage *= 1 + (armorPierce * 0.01f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Resists.handleFortitude(tarAc,damageType,damage);
|
//Resists.handleFortitude(tarAc,damageType,damage);
|
||||||
|
|
||||||
float d = 0f;
|
float d = 0f;
|
||||||
@@ -978,26 +978,7 @@ public enum CombatManager {
|
|||||||
errorTrack = 14;
|
errorTrack = 14;
|
||||||
|
|
||||||
//handle procs
|
//handle procs
|
||||||
|
procChanceHandler(weapon,ac,tarAc);
|
||||||
if (weapon != null && tarAc != null && tarAc.isAlive()) {
|
|
||||||
|
|
||||||
if(weapon.effects != null){
|
|
||||||
for (Effect eff : weapon.effects.values()){
|
|
||||||
for(AbstractEffectModifier mod : eff.getEffectModifiers()){
|
|
||||||
if(mod.modType.equals(ModType.WeaponProc)){
|
|
||||||
int procChance = ThreadLocalRandom.current().nextInt(100);
|
|
||||||
if (procChance < MBServerStatics.PROC_CHANCE) {
|
|
||||||
try {
|
|
||||||
((WeaponProcEffectModifier) mod).applyProc(ac, target);
|
|
||||||
}catch(Exception e){
|
|
||||||
Logger.error(eff.getName() + " Failed To Cast Proc");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
errorTrack = 15;
|
errorTrack = 15;
|
||||||
|
|
||||||
@@ -1081,6 +1062,41 @@ public enum CombatManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void procChanceHandler(Item weapon, AbstractCharacter ac, AbstractCharacter tarAc) {
|
||||||
|
|
||||||
|
//no weapon means no proc
|
||||||
|
if(weapon == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
//caster is dead of null, no proc
|
||||||
|
if(ac == null || !ac.isAlive())
|
||||||
|
return;
|
||||||
|
|
||||||
|
//target is dead or null, no proc
|
||||||
|
if(tarAc == null || !tarAc.isAlive())
|
||||||
|
return;
|
||||||
|
|
||||||
|
//no effects on weapon, skip proc
|
||||||
|
if(weapon.effects == null || weapon.effects.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (Effect eff : weapon.effects.values()){
|
||||||
|
for(AbstractEffectModifier mod : eff.getEffectModifiers()) {
|
||||||
|
if (mod.modType.equals(ModType.WeaponProc)) {
|
||||||
|
int procChance = ThreadLocalRandom.current().nextInt(100);
|
||||||
|
if (procChance < MBServerStatics.PROC_CHANCE) {
|
||||||
|
try {
|
||||||
|
((WeaponProcEffectModifier) mod).applyProc(ac, tarAc);
|
||||||
|
break;
|
||||||
|
} catch (Exception e) {
|
||||||
|
Logger.error(eff.getName() + " Failed To Cast Proc");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean canTestParry(AbstractCharacter ac, AbstractWorldObject target) {
|
public static boolean canTestParry(AbstractCharacter ac, AbstractWorldObject target) {
|
||||||
|
|
||||||
if (ac == null || target == null || !AbstractWorldObject.IsAbstractCharacter(target))
|
if (ac == null || target == null || !AbstractWorldObject.IsAbstractCharacter(target))
|
||||||
|
|||||||
@@ -1,430 +0,0 @@
|
|||||||
package engine.gameManager;
|
|
||||||
|
|
||||||
import engine.Enum;
|
|
||||||
import engine.exception.MsgSendException;
|
|
||||||
import engine.job.JobContainer;
|
|
||||||
import engine.job.JobScheduler;
|
|
||||||
import engine.jobs.AttackJob;
|
|
||||||
import engine.jobs.DeferredPowerJob;
|
|
||||||
import engine.net.DispatchMessage;
|
|
||||||
import engine.net.client.ClientConnection;
|
|
||||||
import engine.net.client.msg.AttackCmdMsg;
|
|
||||||
import engine.net.client.msg.TargetedActionMsg;
|
|
||||||
import engine.objects.*;
|
|
||||||
import engine.powers.DamageShield;
|
|
||||||
import engine.powers.effectmodifiers.AbstractEffectModifier;
|
|
||||||
import engine.powers.effectmodifiers.WeaponProcEffectModifier;
|
|
||||||
import engine.server.MBServerStatics;
|
|
||||||
import org.pmw.tinylog.Logger;
|
|
||||||
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
import java.util.concurrent.ThreadLocalRandom;
|
|
||||||
|
|
||||||
public class CombatSystem {
|
|
||||||
|
|
||||||
public static void attemptCombat(AbstractCharacter source, AbstractWorldObject target, boolean mainhand){
|
|
||||||
|
|
||||||
//1. source or target doesn't exist, early exit
|
|
||||||
if(source == null || target == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
//2. source or target is dead, early exit
|
|
||||||
if(!source.isAlive() || !target.isAlive())
|
|
||||||
return;
|
|
||||||
|
|
||||||
//3. make sure if target is a building to ensure that it is damageable
|
|
||||||
if(target.getObjectType().equals(Enum.GameObjectType.Building)){
|
|
||||||
Building building = (Building)target;
|
|
||||||
if(building.assetIsProtected() || building.getProtectionState().equals(Enum.ProtectionState.NPC))
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//after thought: make sure target is in range of source
|
|
||||||
if(!inRange(source,target,mainhand))
|
|
||||||
return;
|
|
||||||
|
|
||||||
//4. apply any weapon powers and then clear the weapon power memory for the player
|
|
||||||
if (source.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) {
|
|
||||||
PlayerCharacter pc = (PlayerCharacter)source;
|
|
||||||
if(pc.getWeaponPower() != null){
|
|
||||||
pc.getWeaponPower().attack(target,pc.getRange());
|
|
||||||
pc.setWeaponPower(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//5. make sure if target is AbstractCharacter to check for defense trigger and passive trigger
|
|
||||||
if(AbstractCharacter.IsAbstractCharacter(target)) {
|
|
||||||
int atr;
|
|
||||||
int def;
|
|
||||||
if (source.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) {
|
|
||||||
PlayerCharacter pc = (PlayerCharacter)source;
|
|
||||||
if(pc.combatStats == null)
|
|
||||||
pc.combatStats = new PlayerCombatStats(pc);
|
|
||||||
atr = (int) pc.combatStats.atrHandOne;
|
|
||||||
if(!mainhand)
|
|
||||||
atr =(int) pc.combatStats.atrHandTwo;
|
|
||||||
|
|
||||||
def = pc.combatStats.defense;
|
|
||||||
} else {
|
|
||||||
atr = (int) ((source.getAtrHandOne() + source.getAtrHandTwo()) * 0.5f);
|
|
||||||
def = source.defenseRating;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!LandHit(atr,def)) {
|
|
||||||
createTimer(source,mainhand);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(source.getBonuses() != null)
|
|
||||||
if(!source.getBonuses().getBool(Enum.ModType.IgnorePassiveDefense, Enum.SourceType.None))
|
|
||||||
if(triggerPassive(source,target)) {
|
|
||||||
createTimer(source,mainhand);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//commence actual combat management
|
|
||||||
|
|
||||||
//6. check for any procs
|
|
||||||
if (source.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) {
|
|
||||||
PlayerCharacter pc = (PlayerCharacter)source;
|
|
||||||
if(pc.getCharItemManager() != null && pc.getCharItemManager().getEquipped() != null){
|
|
||||||
Item weapon = pc.getCharItemManager().getEquipped(1);
|
|
||||||
if(!mainhand)
|
|
||||||
weapon = pc.getCharItemManager().getEquipped(2);
|
|
||||||
if(weapon != null){
|
|
||||||
if(weapon.effects != null){
|
|
||||||
for (Effect eff : weapon.effects.values()){
|
|
||||||
for(AbstractEffectModifier mod : eff.getEffectModifiers()){
|
|
||||||
if(mod.modType.equals(Enum.ModType.WeaponProc)){
|
|
||||||
int procChance = ThreadLocalRandom.current().nextInt(0,101);
|
|
||||||
if (procChance <= MBServerStatics.PROC_CHANCE) {
|
|
||||||
try {
|
|
||||||
((WeaponProcEffectModifier) mod).applyProc(source, target);
|
|
||||||
}catch(Exception e){
|
|
||||||
Logger.error(eff.getName() + " Failed To Cast Proc");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//7. configure damage amounts and type
|
|
||||||
Enum.DamageType damageType = Enum.DamageType.Crush;
|
|
||||||
int min = 0;
|
|
||||||
int max = 0;
|
|
||||||
if (source.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) {
|
|
||||||
PlayerCharacter pc = (PlayerCharacter) source;
|
|
||||||
if(mainhand){
|
|
||||||
min = pc.combatStats.minDamageHandOne;
|
|
||||||
max = pc.combatStats.maxDamageHandOne;
|
|
||||||
}else{
|
|
||||||
min = pc.combatStats.minDamageHandTwo;
|
|
||||||
max = pc.combatStats.maxDamageHandTwo;
|
|
||||||
}
|
|
||||||
}else if (source.getObjectType().equals(Enum.GameObjectType.Mob)) {
|
|
||||||
Mob mob = (Mob) source;
|
|
||||||
min = (int) mob.mobBase.getDamageMin();
|
|
||||||
max = (int) mob.mobBase.getDamageMax();
|
|
||||||
}
|
|
||||||
|
|
||||||
int damage = ThreadLocalRandom.current().nextInt(min,max + 1);
|
|
||||||
|
|
||||||
if(source.getBonuses() != null){
|
|
||||||
damage *= 1 + source.getBonuses().getFloatPercentAll(Enum.ModType.MeleeDamageModifier, Enum.SourceType.None);
|
|
||||||
}
|
|
||||||
if (source.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) {
|
|
||||||
PlayerCharacter pc = (PlayerCharacter) source;
|
|
||||||
damage *= pc.ZergMultiplier;
|
|
||||||
}
|
|
||||||
|
|
||||||
//8. configure the attack message to be sent to the clients
|
|
||||||
int animation = 0;
|
|
||||||
ItemBase wb = null;
|
|
||||||
if(source.getCharItemManager() != null && source.getCharItemManager().getEquipped() != null) {
|
|
||||||
Item weapon = source.getCharItemManager().getEquipped(1);
|
|
||||||
if (!mainhand)
|
|
||||||
weapon = source.getCharItemManager().getEquipped(2);
|
|
||||||
|
|
||||||
if(weapon != null && weapon.getItemBase().getAnimations() != null && !weapon.getItemBase().getAnimations().isEmpty()){
|
|
||||||
animation = weapon.getItemBase().getAnimations().get(0);
|
|
||||||
wb = weapon.getItemBase();
|
|
||||||
damageType = wb.getDamageType();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//9. reduce damage from resists and apply damage shields
|
|
||||||
if(AbstractCharacter.IsAbstractCharacter(target)){
|
|
||||||
AbstractCharacter abs = (AbstractCharacter) target;
|
|
||||||
damage = (int) abs.getResists().getResistedDamage(source, abs,damageType,damage,1);
|
|
||||||
handleDamageShields(source,abs,damage);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
sendCombatMessage(source, target, 0f, wb, null, mainhand, animation);
|
|
||||||
|
|
||||||
//if attacker is player, set last attack timestamp
|
|
||||||
if (source.getObjectType().equals(Enum.GameObjectType.PlayerCharacter))
|
|
||||||
updateAttackTimers((PlayerCharacter) source, target);
|
|
||||||
|
|
||||||
//10. cancel all effects that cancel on attack
|
|
||||||
source.cancelOnAttack();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean LandHit(int ATR, int DEF){
|
|
||||||
|
|
||||||
int roll = ThreadLocalRandom.current().nextInt(101);
|
|
||||||
|
|
||||||
float chance = PlayerCombatStats.getHitChance(ATR,DEF);
|
|
||||||
return chance >= roll;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void sendCombatMessage(AbstractCharacter source, AbstractWorldObject target, float damage, ItemBase wb, DeferredPowerJob dpj, boolean mainHand, int swingAnimation) {
|
|
||||||
|
|
||||||
if (dpj != null)
|
|
||||||
if (PowersManager.AnimationOverrides.containsKey(dpj.getAction().getEffectID()))
|
|
||||||
swingAnimation = PowersManager.AnimationOverrides.get(dpj.getAction().getEffectID());
|
|
||||||
|
|
||||||
if (source.getObjectType() == Enum.GameObjectType.PlayerCharacter)
|
|
||||||
for (Effect eff : source.getEffects().values())
|
|
||||||
if (eff.getPower() != null && (eff.getPower().getToken() == 429506943 || eff.getPower().getToken() == 429408639 || eff.getPower().getToken() == 429513599 || eff.getPower().getToken() == 429415295))
|
|
||||||
swingAnimation = 0;
|
|
||||||
|
|
||||||
TargetedActionMsg cmm = new TargetedActionMsg(source, target, damage, swingAnimation);
|
|
||||||
DispatchMessage.sendToAllInRange(target, cmm);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void updateAttackTimers(PlayerCharacter pc, AbstractWorldObject target) {
|
|
||||||
|
|
||||||
//Set Attack Timers
|
|
||||||
|
|
||||||
if (target.getObjectType().equals(Enum.GameObjectType.PlayerCharacter))
|
|
||||||
pc.setLastPlayerAttackTime();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void handleDamageShields(AbstractCharacter ac, AbstractCharacter target, float damage) {
|
|
||||||
|
|
||||||
if (ac == null || target == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
PlayerBonuses bonuses = target.getBonuses();
|
|
||||||
|
|
||||||
if (bonuses != null) {
|
|
||||||
|
|
||||||
ConcurrentHashMap<AbstractEffectModifier, DamageShield> damageShields = bonuses.getDamageShields();
|
|
||||||
float total = 0;
|
|
||||||
|
|
||||||
for (DamageShield ds : damageShields.values()) {
|
|
||||||
|
|
||||||
//get amount to damage back
|
|
||||||
|
|
||||||
float amount;
|
|
||||||
|
|
||||||
if (ds.usePercent())
|
|
||||||
amount = damage * ds.getAmount() / 100;
|
|
||||||
else
|
|
||||||
amount = ds.getAmount();
|
|
||||||
|
|
||||||
//get resisted damage for damagetype
|
|
||||||
|
|
||||||
Resists resists = ac.getResists();
|
|
||||||
|
|
||||||
if (resists != null) {
|
|
||||||
amount = resists.getResistedDamage(target, ac, ds.getDamageType(), amount, 0);
|
|
||||||
}
|
|
||||||
total += amount;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (total > 0) {
|
|
||||||
|
|
||||||
//apply Damage back
|
|
||||||
|
|
||||||
ac.modifyHealth(-total, target, true);
|
|
||||||
|
|
||||||
TargetedActionMsg cmm = new TargetedActionMsg(ac, ac, total, 0);
|
|
||||||
DispatchMessage.sendToAllInRange(target, cmm);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean inRange(AbstractCharacter source, AbstractWorldObject target, boolean mainhand){
|
|
||||||
|
|
||||||
if(source == null || target == null)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
float distanceSquared = source.loc.distanceSquared(target.loc);
|
|
||||||
|
|
||||||
float rangeSquared = 16.0f;
|
|
||||||
|
|
||||||
if(source.getCharItemManager() != null && source.getCharItemManager().getEquipped() != null){
|
|
||||||
Item weapon = source.getCharItemManager().getEquipped(1);
|
|
||||||
if(!mainhand)
|
|
||||||
weapon = source.getCharItemManager().getEquipped(2);
|
|
||||||
if(weapon != null)
|
|
||||||
rangeSquared = weapon.getItemBase().getRange() * weapon.getItemBase().getRange();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(source.getBonuses() != null){
|
|
||||||
rangeSquared *= 1 + source.getBonuses().getFloatPercentAll(Enum.ModType.WeaponRange, Enum.SourceType.None);
|
|
||||||
}
|
|
||||||
|
|
||||||
return distanceSquared <= rangeSquared;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean triggerPassive(AbstractCharacter source, AbstractWorldObject target) {
|
|
||||||
boolean passiveFired = false;
|
|
||||||
|
|
||||||
if (!AbstractCharacter.IsAbstractCharacter(target))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
AbstractCharacter tarAc = (AbstractCharacter) target;
|
|
||||||
//Handle Block passive
|
|
||||||
if (testPassive(source, tarAc, "Block")) {
|
|
||||||
sendPassiveDefenseMessage(source, null, target, MBServerStatics.COMBAT_SEND_DODGE, null, true);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Handle Parry passive
|
|
||||||
if (testPassive(source, tarAc, "Parry")) {
|
|
||||||
sendPassiveDefenseMessage(source, null, target, MBServerStatics.COMBAT_SEND_DODGE, null, true);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Handle Dodge passive
|
|
||||||
if (testPassive(source, tarAc, "Dodge")) {
|
|
||||||
sendPassiveDefenseMessage(source, null, target, MBServerStatics.COMBAT_SEND_DODGE, null, true);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void sendPassiveDefenseMessage(AbstractCharacter source, ItemBase wb, AbstractWorldObject target, int passiveType, DeferredPowerJob dpj, boolean mainHand) {
|
|
||||||
|
|
||||||
int swingAnimation = 75;
|
|
||||||
|
|
||||||
if (dpj != null)
|
|
||||||
if (PowersManager.AnimationOverrides.containsKey(dpj.getAction().getEffectID()))
|
|
||||||
swingAnimation = PowersManager.AnimationOverrides.get(dpj.getAction().getEffectID());
|
|
||||||
|
|
||||||
TargetedActionMsg cmm = new TargetedActionMsg(source, swingAnimation, target, passiveType);
|
|
||||||
DispatchMessage.sendToAllInRange(target, cmm);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean testPassive(AbstractCharacter source, AbstractCharacter target, String type) {
|
|
||||||
|
|
||||||
if(target.getBonuses() != null)
|
|
||||||
if(target.getBonuses().getBool(Enum.ModType.Stunned, Enum.SourceType.None))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
float chance = target.getPassiveChance(type, source.getLevel(), true);
|
|
||||||
|
|
||||||
if (chance == 0f)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
//max 75% chance of passive to fire
|
|
||||||
|
|
||||||
if (chance > 75f)
|
|
||||||
chance = 75f;
|
|
||||||
|
|
||||||
int roll = ThreadLocalRandom.current().nextInt(1,100);
|
|
||||||
|
|
||||||
return roll < chance;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void createTimer(AbstractCharacter source, boolean mainhand) {
|
|
||||||
|
|
||||||
ConcurrentHashMap<String, JobContainer> timers = source.getTimers();
|
|
||||||
int slot = 1;
|
|
||||||
if(!mainhand)
|
|
||||||
slot = 2;
|
|
||||||
|
|
||||||
int time = 3000;
|
|
||||||
if(source.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)){
|
|
||||||
PlayerCharacter pc = (PlayerCharacter)source;
|
|
||||||
if(mainhand){
|
|
||||||
time = (int) pc.combatStats.attackSpeedHandOne;
|
|
||||||
}else{
|
|
||||||
time = (int) pc.combatStats.attackSpeedHandTwo;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (timers != null) {
|
|
||||||
AttackJob aj = new AttackJob(source, slot, true);
|
|
||||||
JobContainer job;
|
|
||||||
job = JobScheduler.getInstance().scheduleJob(aj, (time * 100));
|
|
||||||
timers.put("Attack" + slot, job);
|
|
||||||
} else {
|
|
||||||
Logger.error("Unable to find Timers for Character " + source.getObjectUUID());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void setAttackTarget(AttackCmdMsg msg, ClientConnection origin) throws MsgSendException {
|
|
||||||
|
|
||||||
PlayerCharacter player;
|
|
||||||
int targetType;
|
|
||||||
AbstractWorldObject target;
|
|
||||||
|
|
||||||
if (TargetedActionMsg.un2cnt == 60 || TargetedActionMsg.un2cnt == 70)
|
|
||||||
return;
|
|
||||||
|
|
||||||
player = SessionManager.getPlayerCharacter(origin);
|
|
||||||
|
|
||||||
if (player == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
//source must match player this account belongs to
|
|
||||||
|
|
||||||
if (player.getObjectUUID() != msg.getSourceID() || player.getObjectType().ordinal() != msg.getSourceType()) {
|
|
||||||
Logger.error("Msg Source ID " + msg.getSourceID() + " Does not Match Player ID " + player.getObjectUUID());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
targetType = msg.getTargetType();
|
|
||||||
|
|
||||||
if (targetType == Enum.GameObjectType.PlayerCharacter.ordinal()) {
|
|
||||||
target = PlayerCharacter.getFromCache(msg.getTargetID());
|
|
||||||
} else if (targetType == Enum.GameObjectType.Building.ordinal()) {
|
|
||||||
target = BuildingManager.getBuildingFromCache(msg.getTargetID());
|
|
||||||
} else if (targetType == Enum.GameObjectType.Mob.ordinal()) {
|
|
||||||
target = Mob.getFromCache(msg.getTargetID());
|
|
||||||
} else {
|
|
||||||
player.setCombatTarget(null);
|
|
||||||
return; //not valid type to attack
|
|
||||||
}
|
|
||||||
|
|
||||||
// quit of the combat target is already the current combat target
|
|
||||||
// or there is no combat target
|
|
||||||
|
|
||||||
if (target == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
//set sources target
|
|
||||||
|
|
||||||
player.setCombatTarget(target);
|
|
||||||
|
|
||||||
boolean hasMain = false;
|
|
||||||
boolean hasOff = false;
|
|
||||||
if(player.getCharItemManager() != null && player.getCharItemManager().getEquipped() != null){
|
|
||||||
if(player.getCharItemManager().getEquipped(1) != null)
|
|
||||||
hasMain = true;
|
|
||||||
if(player.getCharItemManager().getEquipped(2) != null && !player.getCharItemManager().getEquipped(2).getItemBase().isShield())
|
|
||||||
hasOff = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(hasMain){
|
|
||||||
createTimer(player,true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(hasOff){
|
|
||||||
createTimer(player,false);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -28,6 +28,7 @@ import engine.net.client.ClientConnection;
|
|||||||
import engine.net.client.msg.*;
|
import engine.net.client.msg.*;
|
||||||
import engine.objects.*;
|
import engine.objects.*;
|
||||||
import engine.powers.*;
|
import engine.powers.*;
|
||||||
|
import engine.powers.effectmodifiers.AbstractEffectModifier;
|
||||||
import engine.powers.poweractions.AbstractPowerAction;
|
import engine.powers.poweractions.AbstractPowerAction;
|
||||||
import engine.powers.poweractions.TrackPowerAction;
|
import engine.powers.poweractions.TrackPowerAction;
|
||||||
import engine.server.MBServerStatics;
|
import engine.server.MBServerStatics;
|
||||||
@@ -198,6 +199,10 @@ public enum PowersManager {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(msg.getPowerUsedID() == -1851459567){//backstab
|
||||||
|
applyPower(pc,pc,pc.loc,-1851459567,msg.getNumTrains(),false);
|
||||||
|
}
|
||||||
|
|
||||||
if (usePowerA(msg, origin, sendCastToSelf)) {
|
if (usePowerA(msg, origin, sendCastToSelf)) {
|
||||||
// Cast failed for some reason, reset timer
|
// Cast failed for some reason, reset timer
|
||||||
|
|
||||||
@@ -1968,9 +1973,7 @@ public enum PowersManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void runPowerAction(AbstractCharacter source,
|
public static void runPowerAction(AbstractCharacter source, AbstractWorldObject awo, Vector3fImmutable targetLoc, ActionsBase ab, int trains, PowersBase pb) {
|
||||||
AbstractWorldObject awo, Vector3fImmutable targetLoc,
|
|
||||||
ActionsBase ab, int trains, PowersBase pb) {
|
|
||||||
AbstractPowerAction pa = ab.getPowerAction();
|
AbstractPowerAction pa = ab.getPowerAction();
|
||||||
if (pa == null) {
|
if (pa == null) {
|
||||||
Logger.error(
|
Logger.error(
|
||||||
@@ -1978,6 +1981,26 @@ public enum PowersManager {
|
|||||||
+ ab.getEffectID());
|
+ ab.getEffectID());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(AbstractCharacter.IsAbstractCharacter(awo)) {
|
||||||
|
try {
|
||||||
|
boolean immune = false;
|
||||||
|
AbstractCharacter absChar = (AbstractCharacter) awo;
|
||||||
|
for (AbstractEffectModifier mod : ab.getPowerAction().getEffectsBase().getModifiers()) {
|
||||||
|
if (absChar.getBonuses() != null) {
|
||||||
|
if (absChar.getBonuses().getBool(ModType.ImmuneTo, mod.sourceType) || absChar.getBonuses().getBool(ModType.NoMod, mod.sourceType))
|
||||||
|
immune = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (immune)
|
||||||
|
return;
|
||||||
|
}catch(Exception e){
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
pa.startAction(source, awo, targetLoc, trains, ab, pb);
|
pa.startAction(source, awo, targetLoc, trains, ab, pb);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2514,10 +2537,12 @@ public enum PowersManager {
|
|||||||
return true;
|
return true;
|
||||||
} else if (testPassive(pc, tarAc, "Block")) {
|
} else if (testPassive(pc, tarAc, "Block")) {
|
||||||
// Dodge fired, send dodge message
|
// Dodge fired, send dodge message
|
||||||
PerformActionMsg dodgeMsg = new PerformActionMsg(msg);
|
//PerformActionMsg dodgeMsg = new PerformActionMsg(msg);
|
||||||
dodgeMsg.setTargetType(awo.getObjectType().ordinal());
|
//dodgeMsg.setTargetType(awo.getObjectType().ordinal());
|
||||||
dodgeMsg.setTargetID(awo.getObjectUUID());
|
//dodgeMsg.setTargetID(awo.getObjectUUID());
|
||||||
sendPowerMsg(pc, 4, dodgeMsg);
|
//sendPowerMsg(pc, 4, dodgeMsg);
|
||||||
|
TargetedActionMsg cmm = new TargetedActionMsg(pc, 75, tarAc, MBServerStatics.COMBAT_SEND_BLOCK);
|
||||||
|
DispatchMessage.sendToAllInRange(tarAc, cmm);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,9 +21,9 @@ public class ZergManager {
|
|||||||
return 0.0f;
|
return 0.0f;
|
||||||
|
|
||||||
switch(count){
|
switch(count){
|
||||||
case 4: return 0.63f;
|
case 4: return 0.50f;
|
||||||
case 5: return 0.40f;
|
case 5: return 0.0f;
|
||||||
case 6: return 0.25f;
|
case 6: return 0.0f;
|
||||||
default: return 1.0f;
|
default: return 1.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ public class RequestEnterWorldHandler extends AbstractClientMsgHandler {
|
|||||||
|
|
||||||
PlayerCharacter player = origin.getPlayerCharacter();
|
PlayerCharacter player = origin.getPlayerCharacter();
|
||||||
|
|
||||||
WorldGrid.RemoveWorldObject(player);
|
|
||||||
Dispatch dispatch;
|
Dispatch dispatch;
|
||||||
|
|
||||||
if (player == null) {
|
if (player == null) {
|
||||||
@@ -57,6 +57,11 @@ public class RequestEnterWorldHandler extends AbstractClientMsgHandler {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//if(player.isEnteredWorld()){
|
||||||
|
// if(player != null) {
|
||||||
|
// WorldGrid.RemoveWorldObject(player);
|
||||||
|
// }
|
||||||
|
//}
|
||||||
player.setEnteredWorld(false);
|
player.setEnteredWorld(false);
|
||||||
|
|
||||||
Account acc = SessionManager.getAccount(origin);
|
Account acc = SessionManager.getAccount(origin);
|
||||||
@@ -106,9 +111,14 @@ public class RequestEnterWorldHandler extends AbstractClientMsgHandler {
|
|||||||
|
|
||||||
player.getTimestamps().put("EnterWorld", System.currentTimeMillis());
|
player.getTimestamps().put("EnterWorld", System.currentTimeMillis());
|
||||||
|
|
||||||
if (player.getLoc().equals(Vector3fImmutable.ZERO) || System.currentTimeMillis() > player.getTimeStamp("logout") + (15 * 60 * 1000)) {
|
Long logout = player.getTimeStamp("logout");
|
||||||
|
if (player.getLoc().equals(Vector3fImmutable.ZERO) || System.currentTimeMillis() > logout + (15 * 60 * 1000)) {
|
||||||
player.stopMovement(player.getBindLoc());
|
player.stopMovement(player.getBindLoc());
|
||||||
player.setSafeMode();
|
try {
|
||||||
|
player.setSafeMode();
|
||||||
|
}catch(Exception e){
|
||||||
|
Logger.error(e);
|
||||||
|
}
|
||||||
player.updateLocation();
|
player.updateLocation();
|
||||||
player.setRegion(AbstractWorldObject.GetRegionByWorldObject(player));
|
player.setRegion(AbstractWorldObject.GetRegionByWorldObject(player));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ public class TeleportRepledgeListMsg extends ClientNetMsg {
|
|||||||
for (int i = 0; i < 3; i++)
|
for (int i = 0; i < 3; i++)
|
||||||
writer.putInt(0);
|
writer.putInt(0);
|
||||||
|
|
||||||
writer.putInt(cities.size() + mines.size() + 1);
|
writer.putInt(cities.size() + mines.size());// + 1);
|
||||||
|
|
||||||
for (City city : cities)
|
for (City city : cities)
|
||||||
City.serializeForClientMsg(city, writer);
|
City.serializeForClientMsg(city, writer);
|
||||||
@@ -117,7 +117,7 @@ public class TeleportRepledgeListMsg extends ClientNetMsg {
|
|||||||
for(Mine mine : mines)
|
for(Mine mine : mines)
|
||||||
Mine.serializeForClientMsgTeleport(mine, writer);
|
Mine.serializeForClientMsgTeleport(mine, writer);
|
||||||
|
|
||||||
Dungeon.serializeForClientMsgTeleport(writer);
|
//Dungeon.serializeForClientMsgTeleport(writer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PlayerCharacter getPlayer() {
|
public PlayerCharacter getPlayer() {
|
||||||
|
|||||||
@@ -1058,6 +1058,7 @@ public class CharacterItemManager {
|
|||||||
i.addToCache();
|
i.addToCache();
|
||||||
try {
|
try {
|
||||||
i.stripCastableEnchants();
|
i.stripCastableEnchants();
|
||||||
|
this.updateInventory();
|
||||||
}catch(Exception ignored){
|
}catch(Exception ignored){
|
||||||
Logger.error("FAILED TO STRIP CASTABLE ENCHANTS: Move Item To Bank");
|
Logger.error("FAILED TO STRIP CASTABLE ENCHANTS: Move Item To Bank");
|
||||||
}
|
}
|
||||||
@@ -1203,6 +1204,7 @@ public class CharacterItemManager {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
i.stripCastableEnchants();
|
i.stripCastableEnchants();
|
||||||
|
this.updateInventory();
|
||||||
}catch(Exception ignored){
|
}catch(Exception ignored){
|
||||||
Logger.error("FAILED TO STRIP CASTABLE ENCHANTS: Move Item To Vault");
|
Logger.error("FAILED TO STRIP CASTABLE ENCHANTS: Move Item To Vault");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -819,15 +819,61 @@ public class Item extends AbstractWorldObject {
|
|||||||
|
|
||||||
public void stripCastableEnchants(){
|
public void stripCastableEnchants(){
|
||||||
try {
|
try {
|
||||||
ArrayList<Effect> ToRemove = new ArrayList<>();
|
//strip EnchantWeapon
|
||||||
for (Effect eff : this.effects.values()) {
|
if(this.effects.get("EnchantWeapon") != null){
|
||||||
if (eff.getJobContainer() != null && !eff.getJobContainer().noTimer()) {
|
this.effects.remove("EnchantWeapon");
|
||||||
eff.endEffectNoPower();
|
Effect eff = this.effects.get("EnchantWeapon");
|
||||||
eff.getJobContainer().cancelJob();
|
eff.endEffectNoPower();
|
||||||
ToRemove.add(eff);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
this.effects.values().removeAll(ToRemove);
|
|
||||||
|
//strip FGM-003
|
||||||
|
if(this.effects.get("1000") != null){
|
||||||
|
this.effects.remove("1000");
|
||||||
|
Effect eff = this.effects.get("1000");
|
||||||
|
eff.endEffectNoPower();
|
||||||
|
}
|
||||||
|
|
||||||
|
//strip FGM-001
|
||||||
|
if(this.effects.get("996") != null){
|
||||||
|
this.effects.remove("996");
|
||||||
|
Effect eff = this.effects.get("996");
|
||||||
|
eff.endEffectNoPower();
|
||||||
|
}
|
||||||
|
|
||||||
|
//strip ENC-001
|
||||||
|
if(this.effects.get("957") != null){
|
||||||
|
this.effects.remove("957");
|
||||||
|
Effect eff = this.effects.get("957");
|
||||||
|
eff.endEffectNoPower();
|
||||||
|
}
|
||||||
|
if(this.effects.get("958") != null){
|
||||||
|
this.effects.remove("958");
|
||||||
|
Effect eff = this.effects.get("958");
|
||||||
|
eff.endEffectNoPower();
|
||||||
|
}
|
||||||
|
if(this.effects.get("959") != null){
|
||||||
|
this.effects.remove("959");
|
||||||
|
Effect eff = this.effects.get("959");
|
||||||
|
eff.endEffectNoPower();
|
||||||
|
}
|
||||||
|
if(this.effects.get("960") != null){
|
||||||
|
this.effects.remove("960");
|
||||||
|
Effect eff = this.effects.get("960");
|
||||||
|
eff.endEffectNoPower();
|
||||||
|
}
|
||||||
|
if(this.effects.get("961") != null){
|
||||||
|
this.effects.remove("961");
|
||||||
|
Effect eff = this.effects.get("961");
|
||||||
|
eff.endEffectNoPower();
|
||||||
|
}
|
||||||
|
if(this.effects.get("962") != null){
|
||||||
|
this.effects.remove("962");
|
||||||
|
Effect eff = this.effects.get("962");
|
||||||
|
eff.endEffectNoPower();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.applyAllBonuses();
|
||||||
|
//this.effects.values().removeAll(ToRemove);
|
||||||
}catch(Exception ignored){
|
}catch(Exception ignored){
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5145,7 +5145,9 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
@Override
|
@Override
|
||||||
public void update(Boolean newSystem) {
|
public void update(Boolean newSystem) {
|
||||||
|
|
||||||
this.updateLocation();
|
if(!newSystem)
|
||||||
|
this.updateLocation();
|
||||||
|
|
||||||
this.updateMovementState();
|
this.updateMovementState();
|
||||||
|
|
||||||
if(!newSystem)
|
if(!newSystem)
|
||||||
@@ -5221,11 +5223,6 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
try {
|
|
||||||
this.clearClientEffects();
|
|
||||||
}catch(Exception ignored){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Logger.error(e);
|
Logger.error(e);
|
||||||
@@ -5237,17 +5234,6 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
Logger.error("UPDATE ISSUE: " + e);
|
Logger.error("UPDATE ISSUE: " + e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clearClientEffects(){
|
|
||||||
if(this.bonuses != null) {
|
|
||||||
if (!bonuses.getBool(ModType.Stunned, SourceType.None)) {
|
|
||||||
this.removeEffectBySource(EffectSourceType.Stun, 40, true);
|
|
||||||
}
|
|
||||||
if(!this.bonuses.getBool(Enum.ModType.CannotMove,Enum.SourceType.None)){
|
|
||||||
this.removeEffectBySource(EffectSourceType.Root,40,true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public static void unboxPlayer(PlayerCharacter player){
|
public static void unboxPlayer(PlayerCharacter player){
|
||||||
String machineID = player.getClientConnection().machineID;
|
String machineID = player.getClientConnection().machineID;
|
||||||
ArrayList<PlayerCharacter> sameMachine = new ArrayList<>();
|
ArrayList<PlayerCharacter> sameMachine = new ArrayList<>();
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package engine.objects;
|
package engine.objects;
|
||||||
|
|
||||||
import engine.Enum;
|
import engine.Enum;
|
||||||
|
import engine.jobs.DeferredPowerJob;
|
||||||
import engine.powers.EffectsBase;
|
import engine.powers.EffectsBase;
|
||||||
import engine.powers.PowersBase;
|
import engine.powers.PowersBase;
|
||||||
import engine.powers.effectmodifiers.AbstractEffectModifier;
|
import engine.powers.effectmodifiers.AbstractEffectModifier;
|
||||||
@@ -433,7 +434,7 @@ public class PlayerCombatStats {
|
|||||||
|
|
||||||
atr *= 1.0f + stanceValue;
|
atr *= 1.0f + stanceValue;
|
||||||
if(this.owner.bonuses != null) {
|
if(this.owner.bonuses != null) {
|
||||||
float positivePercentBonuses = this.owner.bonuses.getFloatPercentPositive(Enum.ModType.OCV, Enum.SourceType.None);
|
float positivePercentBonuses = this.owner.bonuses.getFloatPercentPositive(Enum.ModType.OCV, Enum.SourceType.None) - stanceValue;
|
||||||
float negativePercentBonuses = this.owner.bonuses.getFloatPercentNegative(Enum.ModType.OCV, Enum.SourceType.None);
|
float negativePercentBonuses = this.owner.bonuses.getFloatPercentNegative(Enum.ModType.OCV, Enum.SourceType.None);
|
||||||
float modifier = 1 + (positivePercentBonuses + negativePercentBonuses);
|
float modifier = 1 + (positivePercentBonuses + negativePercentBonuses);
|
||||||
if(preciseRune > 1.0f)
|
if(preciseRune > 1.0f)
|
||||||
@@ -516,6 +517,7 @@ public class PlayerCombatStats {
|
|||||||
);
|
);
|
||||||
if(this.owner.bonuses != null){
|
if(this.owner.bonuses != null){
|
||||||
minDMG += this.owner.bonuses.getFloat(Enum.ModType.MinDamage, Enum.SourceType.None);
|
minDMG += this.owner.bonuses.getFloat(Enum.ModType.MinDamage, Enum.SourceType.None);
|
||||||
|
minDMG += this.owner.bonuses.getFloat(Enum.ModType.MeleeDamageModifier, Enum.SourceType.None);
|
||||||
minDMG *= 1 + this.owner.bonuses.getFloatPercentAll(Enum.ModType.MeleeDamageModifier, Enum.SourceType.None);
|
minDMG *= 1 + this.owner.bonuses.getFloatPercentAll(Enum.ModType.MeleeDamageModifier, Enum.SourceType.None);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -596,6 +598,7 @@ public class PlayerCombatStats {
|
|||||||
|
|
||||||
if(this.owner.bonuses != null){
|
if(this.owner.bonuses != null){
|
||||||
maxDMG += this.owner.bonuses.getFloat(Enum.ModType.MaxDamage, Enum.SourceType.None);
|
maxDMG += this.owner.bonuses.getFloat(Enum.ModType.MaxDamage, Enum.SourceType.None);
|
||||||
|
maxDMG += this.owner.bonuses.getFloat(Enum.ModType.MeleeDamageModifier, Enum.SourceType.None);
|
||||||
maxDMG *= 1 + this.owner.bonuses.getFloatPercentAll(Enum.ModType.MeleeDamageModifier, Enum.SourceType.None);
|
maxDMG *= 1 + this.owner.bonuses.getFloatPercentAll(Enum.ModType.MeleeDamageModifier, Enum.SourceType.None);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1053,8 +1056,14 @@ public class PlayerCombatStats {
|
|||||||
atr += (modifiedDexterity * 0.5f) + weaponATR1 + weaponATR2;
|
atr += (modifiedDexterity * 0.5f) + weaponATR1 + weaponATR2;
|
||||||
atr *= precise;
|
atr *= precise;
|
||||||
atr += atrBuffs;
|
atr += atrBuffs;
|
||||||
|
if(pc.getWeaponPower() != null){
|
||||||
|
DeferredPowerJob dpj = pc.getWeaponPower();
|
||||||
|
dpj.endEffect();
|
||||||
|
}
|
||||||
|
|
||||||
if(pc.bonuses != null)
|
if(pc.bonuses != null)
|
||||||
atr *= 1 + (pc.bonuses.getFloatPercentAll(Enum.ModType.OCV, Enum.SourceType.None) - (stanceMod - 1) - (precise - 1) - healerDefStance);
|
atr *= 1 + (pc.bonuses.getFloatPercentAll(Enum.ModType.OCV, Enum.SourceType.None) - (stanceMod - 1) - (precise - 1) - healerDefStance);
|
||||||
|
|
||||||
atr *= stanceMod;
|
atr *= stanceMod;
|
||||||
return atr;
|
return atr;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user