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