|
|
|
@ -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) |
|
|
|
|