Browse Source

Easy AI first draft

lakebane-easy
FatBoy-DOTC 1 week ago
parent
commit
c1eb6796f5
  1. 10
      src/engine/mobileAI/BehaviourFiles/PlayerGuard.java
  2. 88
      src/engine/mobileAI/BehaviourFiles/PlayerPet.java
  3. 47
      src/engine/mobileAI/BehaviourFiles/SiegeMob.java
  4. 161
      src/engine/mobileAI/BehaviourFiles/StandardMob.java
  5. 32
      src/engine/mobileAI/EasyAI.java
  6. 25
      src/engine/mobileAI/MobAI.java
  7. 3
      src/engine/mobileAI/Threads/MobAIThread.java
  8. 27
      src/engine/mobileAI/enumMobState.java
  9. 5
      src/engine/mobileAI/utilities/MovementUtilities.java
  10. 10
      src/engine/objects/Mob.java

10
src/engine/mobileAI/BehaviourFiles/PlayerGuard.java

@ -0,0 +1,10 @@ @@ -0,0 +1,10 @@
package engine.mobileAI.BehaviourFiles;
import engine.objects.Mob;
public class PlayerGuard {
public static void process(Mob guard){
}
}

88
src/engine/mobileAI/BehaviourFiles/PlayerPet.java

@ -0,0 +1,88 @@ @@ -0,0 +1,88 @@
package engine.mobileAI.BehaviourFiles;
import engine.InterestManagement.WorldGrid;
import engine.gameManager.PowersManager;
import engine.mobileAI.enumMobState;
import engine.mobileAI.utilities.CombatUtilities;
import engine.mobileAI.utilities.MovementUtilities;
import engine.objects.AbstractWorldObject;
import engine.objects.ItemBase;
import engine.objects.Mob;
import engine.objects.PlayerCharacter;
import engine.powers.PowersBase;
import engine.server.MBServerStatics;
import java.util.Map;
public class PlayerPet {
public static void process(Mob pet){
if(pet.getOwner() == null){
pet.despawn();
return;
}
if(!pet.playerAgroMap.contains(pet.getOwner().getObjectUUID())){
pet.teleport(pet.getOwner().loc);
return;
}
switch(enumMobState.getState(pet)){
case dead:
pet.despawn();
return;
case patrolling:
if(pet.loc.distanceSquared(pet.getOwner().loc) > 25){
MovementUtilities.aiMove(pet,pet.getOwner().loc,false);
} else if (pet.isMoving()) {
pet.stopMovement(pet.getMovementLoc());
}
return;
case attacking:
attack(pet);
return;
}
}
public static void attack(Mob mob){
if (mob.combatTarget == null || !mob.combatTarget.isAlive()) {
mob.setCombatTarget(null);
aggro(mob);
return;
}
if(!CombatUtilities.inRangeToAttack(mob,mob.combatTarget)){
if (!MovementUtilities.canMove(mob))
return;
MovementUtilities.aiMove(mob,mob.combatTarget.loc,false);
return;
}
mob.stopMovement(mob.getMovementLoc());
ItemBase weapon = mob.getWeaponItemBase(true);
boolean mainHand = true;
if(weapon == null) {
weapon = mob.getWeaponItemBase(false);
mainHand = false;
}
if (System.currentTimeMillis() > mob.getNextAttackTime()) {
CombatUtilities.combatCycle(mob, mob.combatTarget, mainHand, weapon);
mob.setNextAttackTime(System.currentTimeMillis() + 3000L);
}
}
public static void aggro(Mob mob){
for(AbstractWorldObject awo : WorldGrid.getObjectsInRangePartial(mob.loc,30, MBServerStatics.MASK_PET)) {
Mob potentialTarget = (Mob) awo;
if (!potentialTarget.isAlive())
continue;
if (MovementUtilities.inRangeToAggro(mob, potentialTarget)) {
mob.setCombatTarget(potentialTarget);
return;
}
}
}
}

47
src/engine/mobileAI/BehaviourFiles/SiegeMob.java

@ -0,0 +1,47 @@ @@ -0,0 +1,47 @@
package engine.mobileAI.BehaviourFiles;
import engine.Enum;
import engine.mobileAI.utilities.CombatUtilities;
import engine.objects.Mob;
public class SiegeMob {
public static void process(Mob treb){
if(!treb.isAlive()){
if(!treb.despawned){
treb.despawn();
treb.deathTime = System.currentTimeMillis();
return;
}
if(treb.deathTime == 0) {
treb.deathTime = System.currentTimeMillis();
return;
}
if(treb.deathTime + 900000L > System.currentTimeMillis()) {
treb.respawn();
treb.setCombatTarget(null);
return;
}
}
if(treb.combatTarget == null)
return;
if(!treb.combatTarget.getObjectType().equals(Enum.GameObjectType.Building)) {
treb.setCombatTarget(null);
return;
}
if(!treb.combatTarget.isAlive()) {
treb.setCombatTarget(null);
return;
}
if(!CombatUtilities.inRangeToAttack(treb,treb.combatTarget))
treb.setCombatTarget(null);
if (System.currentTimeMillis() > treb.getNextAttackTime()) {
CombatUtilities.combatCycle(treb, treb.combatTarget, true, null);
treb.setNextAttackTime(System.currentTimeMillis() + 11000L);
}
}
}

161
src/engine/mobileAI/BehaviourFiles/StandardMob.java

@ -0,0 +1,161 @@ @@ -0,0 +1,161 @@
package engine.mobileAI.BehaviourFiles;
import engine.InterestManagement.WorldGrid;
import engine.gameManager.PowersManager;
import engine.mobileAI.enumMobState;
import engine.mobileAI.utilities.CombatUtilities;
import engine.mobileAI.utilities.MovementUtilities;
import engine.objects.*;
import engine.powers.PowersBase;
import engine.server.MBServerStatics;
import java.util.Map;
public class StandardMob {
public static void process(Mob mob){
switch(enumMobState.getState(mob)){
case idle:
return;
case dead:
respawn(mob);
return;
case patrolling:
if(mob.combatTarget == null)
aggro(mob);
if(mob.combatTarget == null)
patrol(mob);
return;
case attacking:
attack(mob);
return;
}
}
public static void respawn(Mob mob){
if (mob.deathTime == 0) {
mob.setDeathTime(System.currentTimeMillis());
return;
}
if (!mob.despawned) {
if (mob.getCharItemManager() != null && mob.getCharItemManager().getInventoryCount() > 0) {
if (System.currentTimeMillis() > mob.deathTime + MBServerStatics.DESPAWN_TIMER_WITH_LOOT) {
mob.despawn();
mob.deathTime = System.currentTimeMillis();
return;
}
//No items in inventory.
} else if (mob.isHasLoot()) {
if (System.currentTimeMillis() > mob.deathTime + MBServerStatics.DESPAWN_TIMER_ONCE_LOOTED) {
mob.despawn();
mob.deathTime = System.currentTimeMillis();
return;
}
//Mob never had Loot.
} else {
if (System.currentTimeMillis() > mob.deathTime + MBServerStatics.DESPAWN_TIMER) {
mob.despawn();
mob.deathTime = System.currentTimeMillis();
return;
}
}
}
if(Mob.discDroppers.contains(mob))
return;
if (System.currentTimeMillis() > (mob.deathTime + (mob.spawnTime * 1000L))) {
if (!Zone.respawnQue.contains(mob)) {
Zone.respawnQue.add(mob);
}
}
}
public static void aggro(Mob mob){
if(enumMobState.Agressive(mob)){
for(int id : mob.playerAgroMap.keySet()){
PlayerCharacter potentialTarget = PlayerCharacter.getFromCache(id);
if(!potentialTarget.isAlive() || mob.canSee(potentialTarget))
continue;
if (MovementUtilities.inRangeToAggro(mob, potentialTarget)) {
mob.setCombatTarget(potentialTarget);
return;
}
}
for(AbstractWorldObject awo : WorldGrid.getObjectsInRangePartial(mob.loc,60, MBServerStatics.MASK_PET)){
Mob potentialTarget = (Mob)awo;
if(!potentialTarget.isAlive())
continue;
if (MovementUtilities.inRangeToAggro(mob, potentialTarget)) {
mob.setCombatTarget(potentialTarget);
return;
}
}
}
}
public static void patrol(Mob mob){
if (!MovementUtilities.canMove(mob))
return;
if (mob.stopPatrolTime + 5000L > System.currentTimeMillis())
return;
if(mob.isMoving())
return;
if (mob.lastPatrolPointIndex > mob.patrolPoints.size() - 1)
mob.lastPatrolPointIndex = 0;
mob.destination = mob.patrolPoints.get(mob.lastPatrolPointIndex);
mob.lastPatrolPointIndex += 1;
MovementUtilities.aiMove(mob, mob.destination, true);
}
public static void attack(Mob mob){
if (!MovementUtilities.inRangeOfBindLocation(mob)) {
PowersBase recall = PowersManager.getPowerByToken(-1994153779);
PowersManager.useMobPower(mob, mob, recall, 40);
mob.setCombatTarget(null);
for (Map.Entry playerEntry : mob.playerAgroMap.entrySet())
PlayerCharacter.getFromCache((int) playerEntry.getKey()).setHateValue(0);
mob.setCombatTarget(null);
return;
}
if (mob.combatTarget == null || !mob.combatTarget.isAlive()) {
mob.setCombatTarget(null);
return;
}
if(MovementUtilities.inRangeDropAggro(mob, (PlayerCharacter) mob.getCombatTarget())){
mob.setCombatTarget(null);
MovementUtilities.aiMove(mob,mob.bindLoc,true);
return;
}
if(!CombatUtilities.inRangeToAttack(mob,mob.combatTarget)){
if (!MovementUtilities.canMove(mob))
return;
MovementUtilities.aiMove(mob,mob.combatTarget.loc,false);
return;
}
mob.stopMovement(mob.getMovementLoc());
ItemBase weapon = mob.getWeaponItemBase(true);
boolean mainHand = true;
if(weapon == null) {
weapon = mob.getWeaponItemBase(false);
mainHand = false;
}
if (System.currentTimeMillis() > mob.getNextAttackTime()) {
CombatUtilities.combatCycle(mob, mob.combatTarget, mainHand, weapon);
mob.setNextAttackTime(System.currentTimeMillis() + 3000L);
}
}
}

32
src/engine/mobileAI/EasyAI.java

@ -0,0 +1,32 @@ @@ -0,0 +1,32 @@
package engine.mobileAI;
import engine.mobileAI.BehaviourFiles.PlayerGuard;
import engine.mobileAI.BehaviourFiles.PlayerPet;
import engine.mobileAI.BehaviourFiles.SiegeMob;
import engine.mobileAI.BehaviourFiles.StandardMob;
import engine.objects.Mob;
public class EasyAI {
public static void aiRun(Mob mob) {
if (mob == null)
return;
if (mob.isPlayerGuard) {
PlayerGuard.process(mob);
return;
}
if(mob.isSiege()){
SiegeMob.process(mob);
return;
}
if (mob.isPet()) {
PlayerPet.process(mob);
return;
}
StandardMob.process(mob);
}
}

25
src/engine/mobileAI/MobAI.java

@ -9,7 +9,6 @@ @@ -9,7 +9,6 @@
package engine.mobileAI;
import engine.Enum;
import engine.Enum.DispatchChannel;
import engine.InterestManagement.WorldGrid;
import engine.gameManager.*;
import engine.math.Vector3f;
@ -17,9 +16,7 @@ import engine.math.Vector3fImmutable; @@ -17,9 +16,7 @@ import engine.math.Vector3fImmutable;
import engine.mobileAI.Threads.MobAIThread;
import engine.mobileAI.utilities.CombatUtilities;
import engine.mobileAI.utilities.MovementUtilities;
import engine.net.DispatchMessage;
import engine.net.client.msg.PerformActionMsg;
import engine.net.client.msg.PowerProjectileMsg;
import engine.objects.*;
import engine.powers.ActionsBase;
import engine.powers.PowersBase;
@ -118,7 +115,7 @@ public class MobAI { @@ -118,7 +115,7 @@ public class MobAI {
//no weapons, default mob attack speed 3 seconds.
if (System.currentTimeMillis() < mob.getLastAttackTime())
if (System.currentTimeMillis() < mob.getNextAttackTime())
return;
// ranged mobs cant attack while running. skip until they finally stop.
@ -136,19 +133,19 @@ public class MobAI { @@ -136,19 +133,19 @@ public class MobAI {
int delay = 3000;
if (mob.isSiege())
delay = 11000;
mob.setLastAttackTime(System.currentTimeMillis() + delay);
mob.setNextAttackTime(System.currentTimeMillis() + delay);
} else if (mob.getWeaponItemBase(true) != null) {
int delay = 3000;
if (mob.isSiege())
delay = 11000;
CombatUtilities.combatCycle(mob, target, true, mob.getWeaponItemBase(true));
mob.setLastAttackTime(System.currentTimeMillis() + delay);
mob.setNextAttackTime(System.currentTimeMillis() + delay);
} else if (mob.getWeaponItemBase(false) != null) {
int attackDelay = 3000;
if (mob.isSiege())
attackDelay = 11000;
CombatUtilities.combatCycle(mob, target, false, mob.getWeaponItemBase(false));
mob.setLastAttackTime(System.currentTimeMillis() + attackDelay);
mob.setNextAttackTime(System.currentTimeMillis() + attackDelay);
}
}
@ -193,19 +190,19 @@ public class MobAI { @@ -193,19 +190,19 @@ public class MobAI {
int delay = 3000;
if (mob.isSiege())
delay = 15000;
mob.setLastAttackTime(System.currentTimeMillis() + delay);
mob.setNextAttackTime(System.currentTimeMillis() + delay);
} else if (mob.getWeaponItemBase(true) != null) {
int attackDelay = 3000;
if (mob.isSiege())
attackDelay = 15000;
CombatUtilities.combatCycle(mob, target, true, mob.getWeaponItemBase(true));
mob.setLastAttackTime(System.currentTimeMillis() + attackDelay);
mob.setNextAttackTime(System.currentTimeMillis() + attackDelay);
} else if (mob.getWeaponItemBase(false) != null) {
int attackDelay = 3000;
if (mob.isSiege())
attackDelay = 15000;
CombatUtilities.combatCycle(mob, target, false, mob.getWeaponItemBase(false));
mob.setLastAttackTime(System.currentTimeMillis() + attackDelay);
mob.setNextAttackTime(System.currentTimeMillis() + attackDelay);
}
//if (mob.isSiege()) {
@ -236,19 +233,19 @@ public class MobAI { @@ -236,19 +233,19 @@ public class MobAI {
int delay = 3000;
if (mob.isSiege())
delay = 11000;
mob.setLastAttackTime(System.currentTimeMillis() + delay);
mob.setNextAttackTime(System.currentTimeMillis() + delay);
} else if (mob.getWeaponItemBase(true) != null) {
int attackDelay = 3000;
if (mob.isSiege())
attackDelay = 11000;
CombatUtilities.combatCycle(mob, target, true, mob.getWeaponItemBase(true));
mob.setLastAttackTime(System.currentTimeMillis() + attackDelay);
mob.setNextAttackTime(System.currentTimeMillis() + attackDelay);
} else if (mob.getWeaponItemBase(false) != null) {
int attackDelay = 3000;
if (mob.isSiege())
attackDelay = 11000;
CombatUtilities.combatCycle(mob, target, false, mob.getWeaponItemBase(false));
mob.setLastAttackTime(System.currentTimeMillis() + attackDelay);
mob.setNextAttackTime(System.currentTimeMillis() + attackDelay);
if (target.getCombatTarget() == null) {
target.setCombatTarget(mob);
}
@ -918,7 +915,7 @@ public class MobAI { @@ -918,7 +915,7 @@ public class MobAI {
mob.setCombatTarget(null);
return;
}
if (System.currentTimeMillis() > mob.getLastAttackTime())
if (System.currentTimeMillis() > mob.getNextAttackTime())
AttackTarget(mob, mob.getCombatTarget());
} catch (Exception e) {

3
src/engine/mobileAI/Threads/MobAIThread.java

@ -1,6 +1,7 @@ @@ -1,6 +1,7 @@
package engine.mobileAI.Threads;
import engine.gameManager.ConfigManager;
import engine.mobileAI.EasyAI;
import engine.mobileAI.MobAI;
import engine.gameManager.ZoneManager;
import engine.objects.Mob;
@ -33,7 +34,7 @@ public class MobAIThread implements Runnable{ @@ -33,7 +34,7 @@ public class MobAIThread implements Runnable{
try {
if (mob != null)
MobAI.DetermineAction(mob);
EasyAI.aiRun(mob);
} catch (Exception e) {
Logger.error("Mob: " + mob.getName() + " UUID: " + mob.getObjectUUID() + " ERROR: " + e);
e.printStackTrace();

27
src/engine/mobileAI/enumMobState.java

@ -0,0 +1,27 @@ @@ -0,0 +1,27 @@
package engine.mobileAI;
import engine.objects.Mob;
public enum enumMobState {
idle,
attacking,
patrolling,
dead;
public static enumMobState getState(Mob mob){
if(mob.playerAgroMap.isEmpty())
return enumMobState.idle;
if(!mob.isAlive())
return enumMobState.dead;
if(mob.combatTarget != null)
return enumMobState.attacking;
return enumMobState.patrolling;
}
public static boolean Agressive(Mob mob){
return mob.BehaviourType.name().contains("Aggro");
}
}

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

@ -83,7 +83,7 @@ public class MovementUtilities { @@ -83,7 +83,7 @@ public class MovementUtilities {
}
public static boolean inRangeToAggro(Mob agent, PlayerCharacter target) {
public static boolean inRangeToAggro(Mob agent, AbstractCharacter target) {
Vector3fImmutable sl = agent.getLoc();
Vector3fImmutable tl = target.getLoc();
@ -169,6 +169,9 @@ public class MovementUtilities { @@ -169,6 +169,9 @@ public class MovementUtilities {
if (agent.getMobBase() != null && Enum.MobFlagType.SENTINEL.elementOf(agent.getMobBase().getFlags()))
return false;
if(!agent.BehaviourType.canRoam)
return false;
return (agent.isAlive() && !agent.getBonuses().getBool(ModType.Stunned, SourceType.None) && !agent.getBonuses().getBool(ModType.CannotMove, SourceType.None));
}

10
src/engine/objects/Mob.java

@ -96,7 +96,7 @@ public class Mob extends AbstractIntelligenceAgent { @@ -96,7 +96,7 @@ public class Mob extends AbstractIntelligenceAgent {
private AbstractWorldObject fearedObject = null;
private int buildingID;
private boolean isSiege = false;
private long lastAttackTime = 0;
private long nextAttackTime = 0;
private int lastMobPowerToken = 0;
private HashMap<Integer, MobEquipment> equip = null;
private DeferredPowerJob weaponPower;
@ -2237,12 +2237,12 @@ public class Mob extends AbstractIntelligenceAgent { @@ -2237,12 +2237,12 @@ public class Mob extends AbstractIntelligenceAgent {
return this.upgradeDateTime != null;
}
public long getLastAttackTime() {
return lastAttackTime;
public long getNextAttackTime() {
return nextAttackTime;
}
public void setLastAttackTime(long lastAttackTime) {
this.lastAttackTime = lastAttackTime;
public void setNextAttackTime(long lastAttackTime) {
this.nextAttackTime = lastAttackTime;
}
public void setDeathTime(long deathTime) {

Loading…
Cancel
Save