2 changed files with 275 additions and 3 deletions
@ -1,9 +1,281 @@ |
|||||||
package engine.mobileAI.MobHandlers; |
package engine.mobileAI.MobHandlers; |
||||||
|
|
||||||
import engine.objects.Mob; |
import engine.gameManager.PowersManager; |
||||||
|
import engine.mobileAI.Threads.MobAIThread; |
||||||
|
import engine.mobileAI.utilities.CombatUtilities; |
||||||
|
import engine.mobileAI.utilities.MovementUtilities; |
||||||
|
import engine.net.client.msg.PerformActionMsg; |
||||||
|
import engine.objects.*; |
||||||
|
import engine.powers.ActionsBase; |
||||||
|
import engine.powers.PowersBase; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.concurrent.ThreadLocalRandom; |
||||||
|
|
||||||
public class PlayerGuardHandler { |
public class PlayerGuardHandler { |
||||||
public static void run(Mob guard){ |
public static void run(Mob guard) { |
||||||
|
try { |
||||||
|
if (guard.combatTarget != null) { |
||||||
|
checkToDropGuardAggro(guard); |
||||||
|
} |
||||||
|
|
||||||
|
if (guard.combatTarget == null) |
||||||
|
CheckForPlayerGuardAggro(guard); |
||||||
|
|
||||||
|
CheckGuardMovement(guard); |
||||||
|
|
||||||
|
if (guard.combatTarget != null && CombatUtilities.inRangeToAttack(guard, guard.combatTarget)) |
||||||
|
CheckToAttack(guard); |
||||||
|
|
||||||
|
} catch (Exception ignored) { |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static void checkToDropGuardAggro(Mob guard){ |
||||||
|
if(guard.combatTarget.loc.distanceSquared(guard.loc) > (128f * 128f)) |
||||||
|
guard.setCombatTarget(null); |
||||||
|
} |
||||||
|
|
||||||
|
public static void CheckForPlayerGuardAggro(Mob guard){ |
||||||
|
PlayerCharacter tar = null; |
||||||
|
for(int id : guard.playerAgroMap.keySet()){ |
||||||
|
PlayerCharacter target = PlayerCharacter.getFromCache(id); |
||||||
|
|
||||||
|
if(target.loc.distanceSquared(guard.loc) > guard.getAggroRange() * guard.getAggroRange()) |
||||||
|
continue; |
||||||
|
|
||||||
|
if(tar == null || guard.loc.distanceSquared(tar.loc) < guard.loc.distanceSquared(target.loc)) |
||||||
|
if(MobCanAggro(guard,target)) |
||||||
|
tar = target; |
||||||
|
} |
||||||
|
if(tar != null) |
||||||
|
guard.setCombatTarget(tar); |
||||||
|
} |
||||||
|
|
||||||
|
public static Boolean MobCanAggro(Mob mob, PlayerCharacter loadedPlayer){ |
||||||
|
if (loadedPlayer == null) |
||||||
|
return false; |
||||||
|
|
||||||
|
//Player is Dead, Mob no longer needs to attempt to aggro. Remove them from aggro map.
|
||||||
|
if (!loadedPlayer.isAlive()) |
||||||
|
return false; |
||||||
|
|
||||||
|
//Can't see target, skip aggro.
|
||||||
|
if (!mob.canSee(loadedPlayer)) |
||||||
|
return false; |
||||||
|
|
||||||
|
if(mob.guardedCity != null && mob.guardedCity.cityOutlaws.contains(loadedPlayer.getObjectUUID())) |
||||||
|
return true; |
||||||
|
|
||||||
|
if(loadedPlayer.guild.getNation().equals(mob.guardedCity.getGuild().getNation())) |
||||||
|
return false; |
||||||
|
|
||||||
|
if(mob.guardedCity.isOpen()) |
||||||
|
return false; |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
public static boolean GuardCast(Mob mob) { |
||||||
|
|
||||||
|
try { |
||||||
|
// Method picks a random spell from a mobile's list of powers
|
||||||
|
// and casts it on the current target (or itself). Validation
|
||||||
|
// (including empty lists) is done previously within canCast();
|
||||||
|
|
||||||
|
ArrayList<Integer> powerTokens; |
||||||
|
ArrayList<Integer> purgeTokens; |
||||||
|
AbstractCharacter target = (AbstractCharacter) mob.getCombatTarget(); |
||||||
|
|
||||||
|
// Generate a list of tokens from the mob powers for this mobile.
|
||||||
|
|
||||||
|
powerTokens = new ArrayList<>(mob.mobPowers.keySet()); |
||||||
|
purgeTokens = new ArrayList<>(); |
||||||
|
|
||||||
|
// If player has this effect on them currently then remove
|
||||||
|
// this token from our list.
|
||||||
|
|
||||||
|
for (int powerToken : powerTokens) { |
||||||
|
|
||||||
|
PowersBase powerBase = PowersManager.getPowerByToken(powerToken); |
||||||
|
|
||||||
|
for (ActionsBase actionBase : powerBase.getActions()) { |
||||||
|
|
||||||
|
String stackType = actionBase.stackType; |
||||||
|
|
||||||
|
if (target.getEffects() != null && target.getEffects().containsKey(stackType)) |
||||||
|
purgeTokens.add(powerToken); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
powerTokens.removeAll(purgeTokens); |
||||||
|
|
||||||
|
// Sanity check
|
||||||
|
|
||||||
|
if (powerTokens.isEmpty()) |
||||||
|
return false; |
||||||
|
|
||||||
|
int powerToken = 0; |
||||||
|
int nukeRoll = ThreadLocalRandom.current().nextInt(1,100); |
||||||
|
|
||||||
|
if (nukeRoll < 55) { |
||||||
|
|
||||||
|
//use direct damage spell
|
||||||
|
powerToken = powerTokens.get(powerTokens.size() - 1); |
||||||
|
|
||||||
|
} else { |
||||||
|
//use random spell
|
||||||
|
powerToken = powerTokens.get(ThreadLocalRandom.current().nextInt(powerTokens.size())); |
||||||
|
} |
||||||
|
|
||||||
|
int powerRank = 1; |
||||||
|
|
||||||
|
switch(mob.getRank()){ |
||||||
|
case 1: |
||||||
|
powerRank = 10; |
||||||
|
break; |
||||||
|
case 2: |
||||||
|
powerRank = 15; |
||||||
|
break; |
||||||
|
case 3: |
||||||
|
powerRank = 20; |
||||||
|
break; |
||||||
|
case 4: |
||||||
|
powerRank = 25; |
||||||
|
break; |
||||||
|
case 5: |
||||||
|
powerRank = 30; |
||||||
|
break; |
||||||
|
case 6: |
||||||
|
powerRank = 35; |
||||||
|
break; |
||||||
|
case 7: |
||||||
|
powerRank = 40; |
||||||
|
break; |
||||||
|
} |
||||||
|
|
||||||
|
PowersBase mobPower = PowersManager.getPowerByToken(powerToken); |
||||||
|
|
||||||
|
//check for hit-roll
|
||||||
|
|
||||||
|
if (mobPower.requiresHitRoll) |
||||||
|
if (CombatUtilities.triggerDefense(mob, mob.getCombatTarget())) |
||||||
|
return false; |
||||||
|
|
||||||
|
// Cast the spell
|
||||||
|
|
||||||
|
if (CombatUtilities.inRange2D(mob, mob.getCombatTarget(), mobPower.getRange())) { |
||||||
|
|
||||||
|
PerformActionMsg msg; |
||||||
|
|
||||||
|
if (!mobPower.isHarmful() || mobPower.targetSelf) { |
||||||
|
|
||||||
|
if (mobPower.category.equals("DISPEL")) { |
||||||
|
PowersManager.useMobPower(mob, target, mobPower, powerRank); |
||||||
|
msg = PowersManager.createPowerMsg(mobPower, powerRank, mob, target); |
||||||
|
} else { |
||||||
|
PowersManager.useMobPower(mob, mob, mobPower, powerRank); |
||||||
|
msg = PowersManager.createPowerMsg(mobPower, powerRank, mob, mob); |
||||||
|
} |
||||||
|
} else { |
||||||
|
PowersManager.useMobPower(mob, target, mobPower, powerRank); |
||||||
|
msg = PowersManager.createPowerMsg(mobPower, powerRank, mob, target); |
||||||
|
} |
||||||
|
|
||||||
|
msg.setUnknown04(2); |
||||||
|
|
||||||
|
PowersManager.finishUseMobPower(msg, mob, 0, 0); |
||||||
|
return true; |
||||||
|
} |
||||||
|
} catch (Exception e) { |
||||||
|
////(mob.getObjectUUID() + " " + mob.getName() + " Failed At: MobCast" + " " + e.getMessage());
|
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
public static void CheckToAttack(Mob mob){ |
||||||
|
try { |
||||||
|
|
||||||
|
if(mob.getLastAttackTime() > System.currentTimeMillis()) |
||||||
|
return; |
||||||
|
|
||||||
|
PlayerCharacter target = (PlayerCharacter) mob.combatTarget; |
||||||
|
|
||||||
|
if (!mob.canSee(target)) { |
||||||
|
mob.setCombatTarget(null); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
if (mob.isMoving() && mob.getRange() > 20) |
||||||
|
return; |
||||||
|
|
||||||
|
if(target.combatStats == null) |
||||||
|
target.combatStats = new PlayerCombatStats(target); |
||||||
|
|
||||||
|
ItemBase mainHand = mob.getWeaponItemBase(true); |
||||||
|
ItemBase offHand = mob.getWeaponItemBase(false); |
||||||
|
|
||||||
|
if (mainHand == null && offHand == null) { |
||||||
|
CombatUtilities.combatCycle(mob, target, true, null); |
||||||
|
int delay = 3000; |
||||||
|
mob.setLastAttackTime(System.currentTimeMillis() + delay); |
||||||
|
} else if (mob.getWeaponItemBase(true) != null) { |
||||||
|
int delay = 3000; |
||||||
|
CombatUtilities.combatCycle(mob, target, true, mob.getWeaponItemBase(true)); |
||||||
|
mob.setLastAttackTime(System.currentTimeMillis() + delay); |
||||||
|
} else if (mob.getWeaponItemBase(false) != null) { |
||||||
|
int attackDelay = 3000; |
||||||
|
CombatUtilities.combatCycle(mob, target, false, mob.getWeaponItemBase(false)); |
||||||
|
mob.setLastAttackTime(System.currentTimeMillis() + attackDelay); |
||||||
|
} |
||||||
|
|
||||||
|
if (target.getPet() != null) |
||||||
|
if (target.getPet().getCombatTarget() == null && target.getPet().assist) |
||||||
|
target.getPet().setCombatTarget(mob); |
||||||
|
|
||||||
|
} catch (Exception e) { |
||||||
|
////(mob.getObjectUUID() + " " + mob.getName() + " Failed At: AttackPlayer" + " " + e.getMessage());
|
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static void CheckGuardMovement(Mob mob){ |
||||||
|
if (mob.getCombatTarget() == null) { |
||||||
|
if (!mob.isMoving()) |
||||||
|
Patrol(mob); |
||||||
|
else { |
||||||
|
mob.stopPatrolTime = System.currentTimeMillis(); |
||||||
|
} |
||||||
|
} else { |
||||||
|
MovementUtilities.moveToLocation(mob, mob.combatTarget.loc, mob.getRange()); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private static void Patrol(Mob mob) { |
||||||
|
|
||||||
|
try { |
||||||
|
|
||||||
|
if(mob.isMoving()) |
||||||
|
return; |
||||||
|
//make sure mob is out of combat stance
|
||||||
|
|
||||||
|
int patrolDelay = ThreadLocalRandom.current().nextInt((int) (MobAIThread.AI_PATROL_DIVISOR * 0.5f), MobAIThread.AI_PATROL_DIVISOR) + MobAIThread.AI_PATROL_DIVISOR; |
||||||
|
|
||||||
|
//early exit while waiting to patrol again
|
||||||
|
|
||||||
|
if (mob.stopPatrolTime + (patrolDelay * 1000) > System.currentTimeMillis()) |
||||||
|
return; |
||||||
|
|
||||||
|
if (mob.lastPatrolPointIndex > mob.patrolPoints.size() - 1) |
||||||
|
mob.lastPatrolPointIndex = 0; |
||||||
|
|
||||||
|
mob.destination = mob.patrolPoints.get(mob.lastPatrolPointIndex); |
||||||
|
mob.lastPatrolPointIndex += 1; |
||||||
|
|
||||||
|
MovementUtilities.aiMove(mob, mob.destination, true); |
||||||
|
|
||||||
|
} catch (Exception e) { |
||||||
|
////(mob.getObjectUUID() + " " + mob.getName() + " Failed At: AttackTarget" + " " + e.getMessage());
|
||||||
|
} |
||||||
} |
} |
||||||
} |
} |
||||||
|
Loading…
Reference in new issue