Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 84446eb726 | |||
| 99f5a9c606 | |||
| 235b5e7375 | |||
| 7289f9e006 | |||
| 9c1afd9441 | |||
| 56226c71eb | |||
| c1eb6796f5 |
@@ -0,0 +1,10 @@
|
||||
package engine.mobileAI.BehaviourFiles;
|
||||
|
||||
import engine.objects.Mob;
|
||||
|
||||
public class PlayerGuard {
|
||||
|
||||
public static void process(Mob guard){
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
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.isNecroPet()){
|
||||
pet.killCharacter("no owner");
|
||||
return;
|
||||
}
|
||||
|
||||
if(!WorldGrid.getObjectsInRangePartial(pet.loc, MBServerStatics.CHARACTER_LOAD_RANGE,1).contains(pet.getOwner())){
|
||||
pet.teleport(pet.getOwner().loc);
|
||||
return;
|
||||
}
|
||||
|
||||
switch(enumMobState.getState(pet)){
|
||||
case dead:
|
||||
pet.despawn();
|
||||
return;
|
||||
case patrolling:
|
||||
if(pet.loc.distanceSquared(pet.getOwner().loc) > 90 && !pet.isMoving()){
|
||||
MovementUtilities.aiMove(pet,pet.getOwner().loc,false);
|
||||
}
|
||||
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.updateLocation();
|
||||
|
||||
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_MOB)) {
|
||||
Mob potentialTarget = (Mob) awo;
|
||||
if (!potentialTarget.isAlive())
|
||||
continue;
|
||||
if (MovementUtilities.inRangeToAggro(mob, potentialTarget)) {
|
||||
mob.setCombatTarget(potentialTarget);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
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(!mob.isMoving() && !CombatUtilities.inRangeToAttack(mob,mob.combatTarget)){
|
||||
if (!MovementUtilities.canMove(mob))
|
||||
return;
|
||||
MovementUtilities.aiMove(mob,mob.combatTarget.loc,false);
|
||||
return;
|
||||
}
|
||||
|
||||
mob.updateLocation();
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
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 {
|
||||
|
||||
//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 {
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
mob.setCombatTarget(null);
|
||||
return;
|
||||
}
|
||||
if (System.currentTimeMillis() > mob.getLastAttackTime())
|
||||
if (System.currentTimeMillis() > mob.getNextAttackTime())
|
||||
AttackTarget(mob, mob.getCombatTarget());
|
||||
|
||||
} catch (Exception e) {
|
||||
|
||||
@@ -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{
|
||||
|
||||
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();
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
@@ -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 {
|
||||
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));
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
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) {
|
||||
|
||||
Reference in New Issue
Block a user