forked from MagicBane/Server
				
			
				 5 changed files with 384 additions and 0 deletions
			
			
		@ -0,0 +1,259 @@
				@@ -0,0 +1,259 @@
					 | 
				
			||||
package engine.mobileAI.behaviours; | 
				
			||||
 | 
				
			||||
import engine.Enum; | 
				
			||||
import engine.gameManager.MovementManager; | 
				
			||||
import engine.gameManager.PowersManager; | 
				
			||||
import engine.gameManager.ZoneManager; | 
				
			||||
import engine.math.Vector3f; | 
				
			||||
import engine.math.Vector3fImmutable; | 
				
			||||
import engine.mobileAI.utilities.CombatUtilities; | 
				
			||||
import engine.mobileAI.utilities.MovementUtilities; | 
				
			||||
import engine.objects.*; | 
				
			||||
import engine.powers.MobPowerEntry; | 
				
			||||
import engine.powers.PowersBase; | 
				
			||||
import org.pmw.tinylog.Logger; | 
				
			||||
 | 
				
			||||
import java.util.HashMap; | 
				
			||||
import java.util.Map; | 
				
			||||
import java.util.concurrent.ConcurrentHashMap; | 
				
			||||
import java.util.concurrent.ThreadLocalRandom; | 
				
			||||
 | 
				
			||||
public class GuardAI { | 
				
			||||
 | 
				
			||||
    public static HashMap<Mob,PowersBase> quedPowerCasts = new HashMap<>(); | 
				
			||||
 | 
				
			||||
    public static void run(Mob guard){ | 
				
			||||
 | 
				
			||||
        //1. check for players nearby to aggro to
 | 
				
			||||
        if(guard.combatTarget == null) | 
				
			||||
            CheckForPlayerGuardAggro(guard); | 
				
			||||
 | 
				
			||||
        //2. patrol if no target acquired
 | 
				
			||||
        if(guard.combatTarget == null) { | 
				
			||||
            patrol(guard); | 
				
			||||
            return; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        //3. attack based on whether spellcaster, archer or mele
 | 
				
			||||
        if(guard.mobPowers.isEmpty()){ | 
				
			||||
            if(guard.getEquip().get(2) != null && guard.getEquip().get(2).getItemBase().getRange() > 20) { | 
				
			||||
                runArcher(guard); | 
				
			||||
            }else { | 
				
			||||
                runMele(guard); | 
				
			||||
            } | 
				
			||||
        }else{ | 
				
			||||
            runCaster(guard); | 
				
			||||
        } | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public static void runCaster(Mob guard){ | 
				
			||||
 | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public static void runMele(Mob guard){ | 
				
			||||
 | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public static void runArcher(Mob guard){ | 
				
			||||
 | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public static void CheckForPlayerGuardAggro(Mob mob) { | 
				
			||||
 | 
				
			||||
        try { | 
				
			||||
 | 
				
			||||
            //looks for and sets mobs combatTarget
 | 
				
			||||
 | 
				
			||||
            if (!mob.isAlive()) | 
				
			||||
                return; | 
				
			||||
 | 
				
			||||
            ConcurrentHashMap<Integer, Boolean> loadedPlayers = mob.playerAgroMap; | 
				
			||||
 | 
				
			||||
            for (Map.Entry playerEntry : loadedPlayers.entrySet()) { | 
				
			||||
 | 
				
			||||
                int playerID = (int) playerEntry.getKey(); | 
				
			||||
                PlayerCharacter loadedPlayer = PlayerCharacter.getFromCache(playerID); | 
				
			||||
 | 
				
			||||
                //Player is null, let's remove them from the list.
 | 
				
			||||
 | 
				
			||||
                if (loadedPlayer == null) { | 
				
			||||
                    loadedPlayers.remove(playerID); | 
				
			||||
                    continue; | 
				
			||||
                } | 
				
			||||
 | 
				
			||||
                //Player is Dead, Mob no longer needs to attempt to aggro. Remove them from aggro map.
 | 
				
			||||
 | 
				
			||||
                if (!loadedPlayer.isAlive()) { | 
				
			||||
                    loadedPlayers.remove(playerID); | 
				
			||||
                    continue; | 
				
			||||
                } | 
				
			||||
 | 
				
			||||
                //Can't see target, skip aggro.
 | 
				
			||||
 | 
				
			||||
                if (!mob.canSee(loadedPlayer)) | 
				
			||||
                    continue; | 
				
			||||
 | 
				
			||||
                // No aggro for this player
 | 
				
			||||
 | 
				
			||||
                if (GuardCanAggro(mob, loadedPlayer) == false) | 
				
			||||
                    continue; | 
				
			||||
 | 
				
			||||
                if (MovementUtilities.inRangeToAggro(mob, loadedPlayer) && mob.getCombatTarget() == null) { | 
				
			||||
                    mob.setCombatTarget(loadedPlayer); | 
				
			||||
                    return; | 
				
			||||
                } | 
				
			||||
            } | 
				
			||||
        } catch (Exception e) { | 
				
			||||
            Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: CheckForPlayerGuardAggro" + e.getMessage()); | 
				
			||||
        } | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public static Boolean GuardCanAggro(Mob mob, PlayerCharacter target) { | 
				
			||||
 | 
				
			||||
        try { | 
				
			||||
 | 
				
			||||
            if (mob.getGuild().getNation().equals(target.getGuild().getNation())) | 
				
			||||
                return false; | 
				
			||||
 | 
				
			||||
            if (mob.BehaviourType.ordinal() == Enum.MobBehaviourType.GuardMinion.ordinal()) { | 
				
			||||
                if (((Mob) mob.npcOwner).building.getCity().cityOutlaws.contains(target.getObjectUUID()) == true) { | 
				
			||||
                    return true; | 
				
			||||
                } | 
				
			||||
            } else if (mob.building.getCity().cityOutlaws.contains(target.getObjectUUID()) == true) { | 
				
			||||
                return true; | 
				
			||||
            } | 
				
			||||
 | 
				
			||||
            //first check condemn list for aggro allowed (allies button is checked)
 | 
				
			||||
 | 
				
			||||
            if (ZoneManager.getCityAtLocation(mob.getLoc()).getTOL().reverseKOS) { | 
				
			||||
                for (Map.Entry<Integer, Condemned> entry : ZoneManager.getCityAtLocation(mob.getLoc()).getTOL().getCondemned().entrySet()) { | 
				
			||||
 | 
				
			||||
                    //target is listed individually
 | 
				
			||||
 | 
				
			||||
                    if (entry.getValue().getPlayerUID() == target.getObjectUUID() && entry.getValue().isActive()) | 
				
			||||
                        return false; | 
				
			||||
 | 
				
			||||
                    //target's guild is listed
 | 
				
			||||
 | 
				
			||||
                    if (Guild.getGuild(entry.getValue().getGuildUID()) == target.getGuild()) | 
				
			||||
                        return false; | 
				
			||||
 | 
				
			||||
                    //target's nation is listed
 | 
				
			||||
 | 
				
			||||
                    if (Guild.getGuild(entry.getValue().getGuildUID()) == target.getGuild().getNation()) | 
				
			||||
                        return false; | 
				
			||||
                } | 
				
			||||
                return true; | 
				
			||||
            } else { | 
				
			||||
 | 
				
			||||
                //allies button is not checked
 | 
				
			||||
 | 
				
			||||
                for (Map.Entry<Integer, Condemned> entry : ZoneManager.getCityAtLocation(mob.getLoc()).getTOL().getCondemned().entrySet()) { | 
				
			||||
 | 
				
			||||
                    //target is listed individually
 | 
				
			||||
 | 
				
			||||
                    if (entry.getValue().getPlayerUID() == target.getObjectUUID() && entry.getValue().isActive()) | 
				
			||||
                        return true; | 
				
			||||
 | 
				
			||||
                    //target's guild is listed
 | 
				
			||||
 | 
				
			||||
                    if (Guild.getGuild(entry.getValue().getGuildUID()) == target.getGuild()) | 
				
			||||
                        return true; | 
				
			||||
 | 
				
			||||
                    //target's nation is listed
 | 
				
			||||
 | 
				
			||||
                    if (Guild.getGuild(entry.getValue().getGuildUID()) == target.getGuild().getNation()) | 
				
			||||
                        return true; | 
				
			||||
                } | 
				
			||||
            } | 
				
			||||
        } catch (Exception e) { | 
				
			||||
            Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: GuardCanAggro" + " " + e.getMessage()); | 
				
			||||
        } | 
				
			||||
        return false; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public static void randomGuardPatrolPoint(Mob mob) { | 
				
			||||
 | 
				
			||||
        try { | 
				
			||||
 | 
				
			||||
            //early exit for a mob who is already moving to a patrol point
 | 
				
			||||
            //while mob moving, update lastPatrolTime so that when they stop moving the 10 second timer can begin
 | 
				
			||||
 | 
				
			||||
            if (mob.isMoving() == true) { | 
				
			||||
                mob.stopPatrolTime = System.currentTimeMillis(); | 
				
			||||
                return; | 
				
			||||
            } | 
				
			||||
 | 
				
			||||
            //wait between 10 and 15 seconds after reaching patrol point before moving
 | 
				
			||||
 | 
				
			||||
            int patrolDelay = ThreadLocalRandom.current().nextInt(10000) + 5000; | 
				
			||||
 | 
				
			||||
            //early exit while waiting to patrol again
 | 
				
			||||
 | 
				
			||||
            if (mob.stopPatrolTime + patrolDelay > System.currentTimeMillis()) | 
				
			||||
                return; | 
				
			||||
 | 
				
			||||
            float xPoint = ThreadLocalRandom.current().nextInt(400) - 200; | 
				
			||||
            float zPoint = ThreadLocalRandom.current().nextInt(400) - 200; | 
				
			||||
            Vector3fImmutable TreePos = mob.getGuild().getOwnedCity().getLoc(); | 
				
			||||
            mob.destination = new Vector3fImmutable(TreePos.x + xPoint, TreePos.y, TreePos.z + zPoint); | 
				
			||||
 | 
				
			||||
            MovementUtilities.aiMove(mob, mob.destination, true); | 
				
			||||
 | 
				
			||||
            if (mob.BehaviourType.ordinal() == Enum.MobBehaviourType.GuardCaptain.ordinal()) { | 
				
			||||
                for (Map.Entry<Mob, Integer> minion : mob.siegeMinionMap.entrySet()) { | 
				
			||||
 | 
				
			||||
                    //make sure mob is out of combat stance
 | 
				
			||||
 | 
				
			||||
                    if (minion.getKey().despawned == false) { | 
				
			||||
                        if (MovementUtilities.canMove(minion.getKey())) { | 
				
			||||
                            Vector3f minionOffset = Formation.getOffset(2, minion.getValue() + 3); | 
				
			||||
                            minion.getKey().updateLocation(); | 
				
			||||
                            Vector3fImmutable formationPatrolPoint = new Vector3fImmutable(mob.destination.x + minionOffset.x, mob.destination.y, mob.destination.z + minionOffset.z); | 
				
			||||
                            MovementUtilities.aiMove(minion.getKey(), formationPatrolPoint, true); | 
				
			||||
                        } | 
				
			||||
                    } | 
				
			||||
                } | 
				
			||||
            } | 
				
			||||
        } catch (Exception e) { | 
				
			||||
            Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: randomGuardPatrolPoints" + " " + e.getMessage()); | 
				
			||||
        } | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public static void patrol(Mob guard){ | 
				
			||||
        if (!guard.BehaviourType.equals(Enum.MobBehaviourType.GuardCaptain) && guard.npcOwner.isAlive()) | 
				
			||||
            return; | 
				
			||||
 | 
				
			||||
        //patrol
 | 
				
			||||
        Building barracks = guard.building; | 
				
			||||
 | 
				
			||||
        if (barracks != null && barracks.patrolPoints != null && !barracks.getPatrolPoints().isEmpty()) { | 
				
			||||
            guard.patrolPoints = barracks.patrolPoints; | 
				
			||||
        } else { | 
				
			||||
            randomGuardPatrolPoint(guard); | 
				
			||||
            return; | 
				
			||||
        } | 
				
			||||
        if (guard.lastPatrolPointIndex > guard.patrolPoints.size() - 1) | 
				
			||||
            guard.lastPatrolPointIndex = 0; | 
				
			||||
 | 
				
			||||
        guard.destination = guard.patrolPoints.get(guard.lastPatrolPointIndex); | 
				
			||||
        guard.lastPatrolPointIndex += 1; | 
				
			||||
 | 
				
			||||
        MovementUtilities.aiMove(guard, guard.destination, true); | 
				
			||||
 | 
				
			||||
        if (guard.BehaviourType.equals(Enum.MobBehaviourType.GuardCaptain)) { | 
				
			||||
            for (Map.Entry<Mob, Integer> minion : guard.siegeMinionMap.entrySet()) | 
				
			||||
 | 
				
			||||
                //make sure mob is out of combat stance
 | 
				
			||||
 | 
				
			||||
                if (!minion.getKey().despawned) { | 
				
			||||
                    if (MovementUtilities.canMove(minion.getKey())) { | 
				
			||||
                        Vector3f minionOffset = Formation.getOffset(2, minion.getValue() + 3); | 
				
			||||
                        minion.getKey().updateLocation(); | 
				
			||||
                        Vector3fImmutable formationPatrolPoint = new Vector3fImmutable(guard.destination.x + minionOffset.x, guard.destination.y, guard.destination.z + minionOffset.z); | 
				
			||||
                        MovementUtilities.aiMove(minion.getKey(), formationPatrolPoint, true); | 
				
			||||
                    } | 
				
			||||
                } | 
				
			||||
        } | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
@ -0,0 +1,17 @@
				@@ -0,0 +1,17 @@
					 | 
				
			||||
package engine.mobileAI.behaviours; | 
				
			||||
 | 
				
			||||
import engine.objects.Mob; | 
				
			||||
 | 
				
			||||
public class PetAI { | 
				
			||||
 | 
				
			||||
    public static void run(Mob pet){ | 
				
			||||
 | 
				
			||||
        //1. check for combat
 | 
				
			||||
 | 
				
			||||
        //2. check for distance from player
 | 
				
			||||
 | 
				
			||||
        //3. follow player
 | 
				
			||||
 | 
				
			||||
        //4. chase combat target
 | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
@ -0,0 +1,89 @@
				@@ -0,0 +1,89 @@
					 | 
				
			||||
package engine.mobileAI.behaviours; | 
				
			||||
 | 
				
			||||
import engine.Enum; | 
				
			||||
import engine.gameManager.BuildingManager; | 
				
			||||
import engine.gameManager.CombatManager; | 
				
			||||
import engine.gameManager.MovementManager; | 
				
			||||
import engine.gameManager.ZoneManager; | 
				
			||||
import engine.mobileAI.utilities.CombatUtilities; | 
				
			||||
import engine.objects.Building; | 
				
			||||
import engine.objects.City; | 
				
			||||
import engine.objects.Mob; | 
				
			||||
import engine.server.MBServerStatics; | 
				
			||||
import org.pmw.tinylog.Logger; | 
				
			||||
 | 
				
			||||
public class SiegeEngineAI { | 
				
			||||
 | 
				
			||||
    public static void run(Mob engine) { | 
				
			||||
 | 
				
			||||
        //1. check to respawn if engine is dead or initially spawning
 | 
				
			||||
        if (!engine.isAlive() || engine.despawned) { | 
				
			||||
            if (System.currentTimeMillis() - engine.deathTime > MBServerStatics.FIFTEEN_MINUTES) { | 
				
			||||
                engine.respawn(); | 
				
			||||
                return; | 
				
			||||
            } | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        //2. early exit if owner is null, siege engines cannot act with player intervention
 | 
				
			||||
        if (engine.getOwner() == null) | 
				
			||||
            return; | 
				
			||||
 | 
				
			||||
        //3. early exit if target is null, siege engines have no purpose without a target
 | 
				
			||||
        if (engine.combatTarget == null) | 
				
			||||
            return; | 
				
			||||
 | 
				
			||||
        //4. early exit if target is not a building, siege engines can only attack buildings
 | 
				
			||||
        if (!engine.combatTarget.getObjectType().equals(Enum.GameObjectType.Building)) { | 
				
			||||
            engine.setCombatTarget(null); | 
				
			||||
            return; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        //5. early exit if target is out of range, engines don't move and neither do buildings, avoid infinite loop
 | 
				
			||||
        if(CombatManager.NotInRange(engine,engine.combatTarget,engine.getRange())) { | 
				
			||||
            engine.setCombatTarget(null); | 
				
			||||
            return; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        //6. attack target, sanity checks passed, attack target
 | 
				
			||||
        AttackBuilding(engine,(Building) engine.combatTarget); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public static void AttackBuilding(Mob engine, Building target) { | 
				
			||||
 | 
				
			||||
        try { | 
				
			||||
 | 
				
			||||
            if (engine == null || target == null) | 
				
			||||
                return; | 
				
			||||
 | 
				
			||||
            if (target.getRank() == -1 || !target.isVulnerable() || BuildingManager.getBuildingFromCache(target.getObjectUUID()) == null) { | 
				
			||||
                engine.setCombatTarget(null); | 
				
			||||
                return; | 
				
			||||
            } | 
				
			||||
 | 
				
			||||
            City playercity = ZoneManager.getCityAtLocation(engine.getLoc()); | 
				
			||||
 | 
				
			||||
            if (playercity != null) | 
				
			||||
                for (Mob guard : playercity.getParent().zoneMobSet) | 
				
			||||
                    if (guard.BehaviourType != null && guard.BehaviourType.equals(Enum.MobBehaviourType.GuardCaptain)) | 
				
			||||
                        if (guard.getCombatTarget() == null && guard.getGuild() != null && engine.getGuild() != null && !guard.getGuild().equals(engine.getGuild())) | 
				
			||||
                            guard.setCombatTarget(engine); | 
				
			||||
 | 
				
			||||
 | 
				
			||||
            MovementManager.sendRWSSMsg(engine); | 
				
			||||
 | 
				
			||||
            CombatUtilities.combatCycle(engine, target, true, null); | 
				
			||||
            int delay = 15000; | 
				
			||||
            engine.setLastAttackTime(System.currentTimeMillis() + delay); | 
				
			||||
 | 
				
			||||
 | 
				
			||||
            //if (mob.isSiege()) {
 | 
				
			||||
            //    PowerProjectileMsg ppm = new PowerProjectileMsg(mob, target);
 | 
				
			||||
            //    ppm.setRange(50);
 | 
				
			||||
            //    DispatchMessage.dispatchMsgToInterestArea(mob, ppm, DispatchChannel.SECONDARY, MBServerStatics.CHARACTER_LOAD_RANGE, false, false);
 | 
				
			||||
            //}
 | 
				
			||||
 | 
				
			||||
        } catch (Exception e) { | 
				
			||||
            Logger.info(engine.getObjectUUID() + " " + engine.getName() + " Failed At: AttackBuilding" + " " + e.getMessage()); | 
				
			||||
        } | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
					Loading…
					
					
				
		Reference in new issue