Browse Source

simplified mob aI

lakebane
FatBoy-DOTC 4 weeks ago
parent
commit
1c5d78d566
  1. 98
      src/engine/mobileAI/Behaviours/StandardMob.java
  2. 2
      src/engine/mobileAI/utilities/CombatUtilities.java
  3. 2
      src/engine/mobileAI/utilities/MovementUtilities.java

98
src/engine/mobileAI/Behaviours/StandardMob.java

@ -7,6 +7,9 @@ import engine.mobileAI.utilities.CombatUtilities; @@ -7,6 +7,9 @@ import engine.mobileAI.utilities.CombatUtilities;
import engine.mobileAI.utilities.MovementUtilities;
import engine.objects.*;
import engine.server.MBServerStatics;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
public class StandardMob {
@ -17,19 +20,22 @@ public class StandardMob { @@ -17,19 +20,22 @@ public class StandardMob {
return;
}
mob.updateLocation();
if (mob.isMoving()) {
mob.setLoc(mob.getMovementLoc());
mob.updateLocation();
}
if(mob.combatTarget == null) {
HashSet<AbstractWorldObject> inRange = WorldGrid.getObjectsInRangePartial(mob.loc, MBServerStatics.CHARACTER_LOAD_RANGE, MBServerStatics.MASK_PLAYER);
if (!inRange.isEmpty()) {
CheckForAggro(mob, inRange);
CheckForAggro(mob);
return;
}
}else{
CheckToDropCombatTarget(mob);
if(mob.combatTarget == null){
HashSet<AbstractWorldObject> inRange = WorldGrid.getObjectsInRangePartial(mob.loc, MBServerStatics.CHARACTER_LOAD_RANGE, MBServerStatics.MASK_PLAYER);
CheckForAggro(mob, inRange);
CheckForAggro(mob);
return;
}
}
@ -37,7 +43,7 @@ public class StandardMob { @@ -37,7 +43,7 @@ public class StandardMob {
if(MovementUtilities.canMove(mob))
CheckForMovement(mob);
if(mob.combatTarget != null)
if(mob.combatTarget != null && !mob.isMoving())
CheckForAttack(mob);
}
@ -103,20 +109,76 @@ public class StandardMob { @@ -103,20 +109,76 @@ public class StandardMob {
}
}
public static void CheckForAggro(Mob mob, HashSet<AbstractWorldObject> inRange){
public static void CheckForAggro(Mob mob){
if(mob == null || !mob.isAlive() || mob.playerAgroMap.isEmpty()){
return;
}
if(mob.BehaviourType.equals(Enum.MobBehaviourType.HamletGuard)){
return;
}
if(mob.hate_values == null)
mob.hate_values = new HashMap<>();
if(mob.combatTarget != null)
return;
HashSet<AbstractWorldObject> inRange = WorldGrid.getObjectsInRangePartial(mob.loc, 60f, MBServerStatics.MASK_PLAYER);
if(inRange.isEmpty()){
mob.setCombatTarget(null);
return;
}
//clear out any players who are not in hated range anymore
ArrayList<PlayerCharacter> toRemove = new ArrayList<>();
for(PlayerCharacter pc : mob.hate_values.keySet()){
if(!inRange.contains(pc))
toRemove.add(pc);
}
for(PlayerCharacter pc : toRemove){
mob.hate_values.remove(pc);
}
//find most hated target
PlayerCharacter mostHated = (PlayerCharacter)inRange.iterator().next();
for(AbstractWorldObject awo : inRange){
PlayerCharacter loadedPlayer = (PlayerCharacter)awo;
if (loadedPlayer == null)
continue;
//Player is Dead, Mob no longer needs to attempt to aggro. Remove them from aggro map.
if (!loadedPlayer.isAlive())
continue;
//Can't see target, skip aggro.
if (!mob.canSee(loadedPlayer))
continue;
// No aggro for this race type
if (mob.notEnemy != null && mob.notEnemy.size() > 0 && mob.notEnemy.contains(loadedPlayer.getRace().getRaceType().getMonsterType()))
continue;
//mob has enemies and this player race is not it
if (mob.enemy != null && mob.enemy.size() > 0 && !mob.enemy.contains(loadedPlayer.getRace().getRaceType().getMonsterType()))
continue;
if(mob.hate_values.containsKey(loadedPlayer))
if(mob.hate_values.get(loadedPlayer) > mob.hate_values.get(mostHated))
mostHated = loadedPlayer;
}
if(mostHated != null)
mob.setCombatTarget(mostHated);
}
public static void CheckForMovement(Mob mob){
if(mob.combatTarget != null){
//chase player
float rangeSquared = mob.getRange() * mob.getRange();
Vector3fImmutable loc2D = mob.loc;
loc2D.setY(0);
Vector3fImmutable tarLoc2D = mob.combatTarget.loc;
tarLoc2D.setY(0);
if(loc2D.distanceSquared(tarLoc2D) > rangeSquared)
if(!CombatUtilities.inRange2D(mob,mob.combatTarget,mob.getRange()))
MovementUtilities.aiMove(mob,mob.combatTarget.loc,false);
}else{
@ -130,20 +192,20 @@ public class StandardMob { @@ -130,20 +192,20 @@ public class StandardMob {
}
public static void CheckForAttack(Mob mob){
float rangeSquared = mob.getRange() * mob.getRange();
Vector3fImmutable loc2D = mob.loc;
loc2D.setY(0);
Vector3fImmutable tarLoc2D = mob.combatTarget.loc;
tarLoc2D.setY(0);
if(loc2D.distanceSquared(tarLoc2D) > rangeSquared)
if(mob.isMoving())
return;
if (mob.BehaviourType.callsForHelp)
MobCallForHelp(mob);
ItemBase mainHand = mob.getWeaponItemBase(true);
ItemBase offHand = mob.getWeaponItemBase(false);
if(!CombatUtilities.inRange2D(mob,mob.combatTarget,mob.getRange()))
return;
if (mainHand == null && offHand == null) {
CombatUtilities.combatCycle(mob, mob.combatTarget, true, null);
int delay = 3000;
@ -159,7 +221,7 @@ public class StandardMob { @@ -159,7 +221,7 @@ public class StandardMob {
}
}
public static void MobCallForHelp(Mob mob){
HashSet<AbstractWorldObject> mobs = WorldGrid.getObjectsInRangePartial(mob.loc,60f, MBServerStatics.MASK_MOB);
HashSet<AbstractWorldObject> mobs = WorldGrid.getObjectsInRangePartial(mob.loc,20f, MBServerStatics.MASK_MOB);
for(AbstractWorldObject awo : mobs){
Mob responder = (Mob)awo;
if(responder.combatTarget == null)

2
src/engine/mobileAI/utilities/CombatUtilities.java

@ -132,6 +132,8 @@ public class CombatUtilities { @@ -132,6 +132,8 @@ public class CombatUtilities {
}
public static boolean canSwing(Mob agent) {
if(!CombatUtilities.inRange2D(agent,agent.combatTarget,agent.getRange()))
return false;
return (agent.isAlive() && !agent.getBonuses().getBool(ModType.Stunned, SourceType.None));
}

2
src/engine/mobileAI/utilities/MovementUtilities.java

@ -194,7 +194,7 @@ public class MovementUtilities { @@ -194,7 +194,7 @@ public class MovementUtilities {
public static void aiMove(Mob agent, Vector3fImmutable vect, boolean isWalking) {
InterestManager.forceLoad(agent);
//InterestManager.forceLoad(agent);
//update our walk/run state.
if (isWalking && !agent.isWalk()) {
agent.setWalkMode(true);

Loading…
Cancel
Save