diff --git a/src/engine/ai/MobileFSM.java b/src/engine/ai/MobileFSM.java index ca05ba8b..c742e79c 100644 --- a/src/engine/ai/MobileFSM.java +++ b/src/engine/ai/MobileFSM.java @@ -60,7 +60,9 @@ public class MobileFSM { Simple(null, false, false, true, false, false), Helpee(null, false, true, true, false, true), HelpeeWimpy(null, true, false, true, false, false), - None(null, false, false, false, false, false); + None(null, false, false, false, false, false), + GuardCaptain(null,false,true,true,true,false), + GuardMinion(GuardCaptain,false,true,true,false,true); private static HashMap _behaviourTypes = new HashMap<>(); public MobBehaviourType BehaviourHelperType; @@ -372,6 +374,41 @@ public class MobileFSM { if (!MovementUtilities.updateMovementToCharacter(aiAgent, mob)) return; } + private static void patrol(Mob mob){ + if(mob.isMoving() == true){ + //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 + mob.stopPatrolTime = System.currentTimeMillis(); + return; + } + //wait 10 seconds after reaching patrol point before moving again + if(mob.stopPatrolTime + 10000 > System.currentTimeMillis()){ + //early exit while waiting to patrol again + return; + } + //make sure mob is out of combat stance + if (mob.isCombat() && mob.getCombatTarget() == null) { + mob.setCombat(false); + UpdateStateMsg rwss = new UpdateStateMsg(); + rwss.setPlayer(mob); + DispatchMessage.sendToAllInRange(mob, rwss); + } + //guard captains inherit barracks patrol points dynamically + if(mob.isPlayerGuard() && mob.getContract() != null){ + Building barracks = mob.building; + if(barracks != null && barracks.patrolPoints != null && barracks.getPatrolPoints().isEmpty() == false) { + mob.patrolPoints = barracks.patrolPoints; + } + } + if (MovementUtilities.canMove(mob)) { + //get the next index of the patrol point from the patrolPoints list + if (mob.lastPatrolPointIndex > mob.patrolPoints.size()) { + mob.lastPatrolPointIndex = 0; + } + MovementUtilities.aiMove(mob, mob.patrolPoints.get(mob.lastPatrolPointIndex), true); + mob.lastPatrolPointIndex += 1; + } + } private static void guardPatrol(Mob aiAgent) { if (aiAgent.isCombat() && aiAgent.getCombatTarget() == null) { aiAgent.setCombat(false); @@ -573,6 +610,9 @@ public class MobileFSM { if (mob.BehaviourType != null && mob.BehaviourType == MobBehaviourType.None) { return; } + if(mob.BehaviourType == null || mob.BehaviourType.ordinal() == MobBehaviourType.None.ordinal()){ + mob.BehaviourType = MobBehaviourType.Simple; + } if (mob.isAlive() == false) { //no need to continue if mob is dead, check for respawn and move on CheckForRespawn(mob); @@ -674,9 +714,13 @@ public class MobileFSM { } } else{ //pet logic + if(mob.playerAgroMap.containsKey(mob.getOwner().getObjectUUID()) == false){ + //mob no longer has its owner loaded, translocate pet to owner + MovementManager.translocate(mob,mob.getOwner().getLoc(),null); + } if (mob.getCombatTarget() == null || mob.combatTarget.isAlive() == false) { //move back to owner - if (CombatUtilities.inRange2D(mob, mob.getOwner(), 5) == false) { + if (CombatUtilities.inRange2D(mob, mob.getOwner(), 10) == false) { mob.destination = mob.getOwner().getLoc(); MovementUtilities.moveToLocation(mob, mob.destination, 5); } diff --git a/src/engine/devcmd/cmds/aiInfoCmd.java b/src/engine/devcmd/cmds/aiInfoCmd.java index 5e5483f3..ed89f486 100644 --- a/src/engine/devcmd/cmds/aiInfoCmd.java +++ b/src/engine/devcmd/cmds/aiInfoCmd.java @@ -81,7 +81,11 @@ public class aiInfoCmd extends AbstractDevCmd { output += mob.getName() + newline; if(mob.BehaviourType != null) { output += "BehaviourType: " + mob.BehaviourType.toString() + newline; - output += "Behaviour Helper Type: " + mob.BehaviourType.BehaviourHelperType.toString() + newline; + if(mob.BehaviourType.BehaviourHelperType != null) { + output += "Behaviour Helper Type: " + mob.BehaviourType.BehaviourHelperType.toString() + newline; + } else{ + output += "Behaviour Helper Type: NULL" + newline; + } output += "Wimpy: " + mob.BehaviourType.isWimpy + newline; output += "Agressive: " + mob.BehaviourType.isAgressive + newline; output += "Can Roam: " + mob.BehaviourType.canRoam + newline; diff --git a/src/engine/loot/LootManager.java b/src/engine/loot/LootManager.java index 0b352b8e..7811c131 100644 --- a/src/engine/loot/LootManager.java +++ b/src/engine/loot/LootManager.java @@ -106,7 +106,7 @@ public class LootManager { break; case "ITEM": MobLoot disc = new MobLoot(mob, ItemBase.getItemBase(bse.itemBase), true); - if (disc != null || fromDeath) + if (disc != null && !fromDeath) mob.getCharItemManager().addItemToInventory(disc); break; diff --git a/src/engine/objects/Mob.java b/src/engine/objects/Mob.java index 02df689b..1f480526 100644 --- a/src/engine/objects/Mob.java +++ b/src/engine/objects/Mob.java @@ -13,6 +13,7 @@ import engine.Enum; import engine.Enum.*; import engine.InterestManagement.WorldGrid; import engine.ai.MobileFSM; +import engine.ai.utilities.MovementUtilities; import engine.exception.SerializationException; import engine.gameManager.*; import engine.job.JobContainer; @@ -106,6 +107,9 @@ public class Mob extends AbstractIntelligenceAgent { public EnumBitSet notEnemy; public EnumBitSet enemy; public MobileFSM.MobBehaviourType BehaviourType; + public ArrayList patrolPoints; + public int lastPatrolPointIndex = 0; + public long stopPatrolTime = 0; /** * No Id Constructor */ @@ -1972,7 +1976,21 @@ public class Mob extends AbstractIntelligenceAgent { Bounds mobBounds = Bounds.borrow(); mobBounds.setBounds(this.getLoc()); this.setBounds(mobBounds); + //assign 5 random patrol points for regular mobs + if(!this.isGuard() && !this.isPlayerGuard() && !this.isPet() && !this.isNecroPet() && !this.isSummonedPet() && !this.isCharmedPet()){ + for(int i = 0; i < 5; ++i){ + float patrolRadius = this.getSpawnRadius(); + if (patrolRadius > 256) + patrolRadius = 256; + + if (patrolRadius < 60) + patrolRadius = 60; + + Vector3fImmutable newPatrolPoint = Vector3fImmutable.getRandomPointInCircle(this.getBindLoc(), patrolRadius); + patrolPoints.add(newPatrolPoint); + } + } } catch (Exception e) { Logger.error(e.getMessage()); }