Files
BattleBane/src/engine/mobileAI/MobHandlers/PlayerGuardHandler.java
T

280 lines
9.6 KiB
Java
Raw Normal View History

2025-03-25 20:16:50 -05:00
package engine.mobileAI.MobHandlers;
2025-03-28 06:59:44 -05:00
import engine.gameManager.PowersManager;
2025-03-28 07:03:12 -05:00
import engine.math.Vector3fImmutable;
2025-03-28 06:59:44 -05:00
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;
2025-03-25 20:16:50 -05:00
public class PlayerGuardHandler {
2025-03-28 06:59:44 -05:00
public static void run(Mob guard) {
try {
2025-03-28 07:05:45 -05:00
if (guard.combatTarget != null)
2025-03-28 06:59:44 -05:00
checkToDropGuardAggro(guard);
if (guard.combatTarget == null)
CheckForPlayerGuardAggro(guard);
2025-03-28 07:05:45 -05:00
if(MovementUtilities.canMove(guard))
CheckGuardMovement(guard);
2025-03-28 06:59:44 -05:00
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))
2025-03-28 07:05:45 -05:00
if(GuardCanAggro(guard,target))
2025-03-28 06:59:44 -05:00
tar = target;
}
if(tar != null)
guard.setCombatTarget(tar);
}
2025-03-28 07:05:45 -05:00
public static Boolean GuardCanAggro(Mob guard, PlayerCharacter loadedPlayer){
2025-03-28 06:59:44 -05:00
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.
2025-03-28 07:05:45 -05:00
if (!guard.canSee(loadedPlayer))
2025-03-28 06:59:44 -05:00
return false;
2025-03-28 07:05:45 -05:00
if(guard.guardedCity != null && guard.guardedCity.cityOutlaws.contains(loadedPlayer.getObjectUUID()))
2025-03-28 06:59:44 -05:00
return true;
2025-03-28 07:05:45 -05:00
if(loadedPlayer.guild.getNation().equals(guard.guardedCity.getGuild().getNation()))
2025-03-28 06:59:44 -05:00
return false;
2025-03-28 07:05:45 -05:00
return !guard.guardedCity.isOpen();
2025-03-28 06:59:44 -05:00
}
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;
2025-03-28 07:03:12 -05:00
int powerToken;
2025-03-28 06:59:44 -05:00
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;
}
2025-03-28 07:05:45 -05:00
public static void CheckToAttack(Mob guard){
2025-03-28 06:59:44 -05:00
try {
2025-03-28 07:05:45 -05:00
if(guard.getLastAttackTime() > System.currentTimeMillis())
2025-03-28 06:59:44 -05:00
return;
2025-03-28 07:05:45 -05:00
PlayerCharacter target = (PlayerCharacter) guard.combatTarget;
2025-03-28 06:59:44 -05:00
2025-03-28 07:05:45 -05:00
if (!guard.canSee(target)) {
guard.setCombatTarget(null);
2025-03-28 06:59:44 -05:00
return;
}
2025-03-28 07:05:45 -05:00
if (guard.isMoving() && guard.getRange() > 20)
2025-03-28 06:59:44 -05:00
return;
if(target.combatStats == null)
target.combatStats = new PlayerCombatStats(target);
2025-03-28 07:05:45 -05:00
ItemBase mainHand = guard.getWeaponItemBase(true);
ItemBase offHand = guard.getWeaponItemBase(false);
2025-03-28 06:59:44 -05:00
if (mainHand == null && offHand == null) {
2025-03-28 07:05:45 -05:00
CombatUtilities.combatCycle(guard, target, true, null);
2025-03-28 06:59:44 -05:00
int delay = 3000;
2025-03-28 07:05:45 -05:00
guard.setLastAttackTime(System.currentTimeMillis() + delay);
} else if (guard.getWeaponItemBase(true) != null) {
2025-03-28 06:59:44 -05:00
int delay = 3000;
2025-03-28 07:05:45 -05:00
CombatUtilities.combatCycle(guard, target, true, guard.getWeaponItemBase(true));
guard.setLastAttackTime(System.currentTimeMillis() + delay);
} else if (guard.getWeaponItemBase(false) != null) {
2025-03-28 06:59:44 -05:00
int attackDelay = 3000;
2025-03-28 07:05:45 -05:00
CombatUtilities.combatCycle(guard, target, false, guard.getWeaponItemBase(false));
guard.setLastAttackTime(System.currentTimeMillis() + attackDelay);
2025-03-28 06:59:44 -05:00
}
if (target.getPet() != null)
if (target.getPet().getCombatTarget() == null && target.getPet().assist)
2025-03-28 07:05:45 -05:00
target.getPet().setCombatTarget(guard);
2025-03-28 06:59:44 -05:00
} catch (Exception e) {
2025-03-28 07:05:45 -05:00
////(guard.getObjectUUID() + " " + guard.getName() + " Failed At: AttackPlayer" + " " + e.getMessage());
2025-03-28 06:59:44 -05:00
}
}
2025-03-28 07:05:45 -05:00
public static void CheckGuardMovement(Mob guard){
if (guard.getCombatTarget() == null) {
if (!guard.isMoving())
Patrol(guard);
2025-03-28 06:59:44 -05:00
else {
2025-03-28 07:05:45 -05:00
guard.stopPatrolTime = System.currentTimeMillis();
2025-03-28 06:59:44 -05:00
}
} else {
2025-03-28 07:05:45 -05:00
MovementUtilities.moveToLocation(guard, guard.combatTarget.loc, guard.getRange());
2025-03-28 06:59:44 -05:00
}
}
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
2025-03-28 07:03:12 -05:00
if (mob.stopPatrolTime + (patrolDelay * 1000L) > System.currentTimeMillis())
2025-03-28 06:59:44 -05:00
return;
if (mob.lastPatrolPointIndex > mob.patrolPoints.size() - 1)
mob.lastPatrolPointIndex = 0;
2025-03-28 07:03:12 -05:00
mob.destination = Vector3fImmutable.getRandomPointOnCircle(mob.patrolPoints.get(mob.lastPatrolPointIndex),16f);
2025-03-28 06:59:44 -05:00
mob.lastPatrolPointIndex += 1;
MovementUtilities.aiMove(mob, mob.destination, true);
2025-03-25 20:16:50 -05:00
2025-03-28 06:59:44 -05:00
} catch (Exception e) {
////(mob.getObjectUUID() + " " + mob.getName() + " Failed At: AttackTarget" + " " + e.getMessage());
}
2025-03-25 20:16:50 -05:00
}
}