Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 84446eb726 | |||
| 99f5a9c606 | |||
| 235b5e7375 | |||
| 7289f9e006 | |||
| 9c1afd9441 | |||
| 56226c71eb | |||
| c1eb6796f5 | |||
| 88e16448a8 | |||
| 4cb428e993 | |||
| af9945f9db |
@@ -75,6 +75,12 @@ public enum LootManager {
|
||||
}
|
||||
|
||||
public static void GenerateMobLoot(Mob mob) {
|
||||
|
||||
//no loot for safezones
|
||||
if(mob == null || mob.getSafeZone()){
|
||||
return;
|
||||
}
|
||||
|
||||
//determine if mob is in hotzone
|
||||
boolean inHotzone = false;
|
||||
|
||||
|
||||
@@ -117,7 +117,7 @@ public abstract class AbstractEffectJob extends AbstractScheduleJob {
|
||||
}
|
||||
|
||||
public void endEffect() {
|
||||
if (this.eb == null)
|
||||
if (this.eb == null || this.power == null)
|
||||
return;
|
||||
this.eb.endEffect(this.source, this.target, this.trains, this.power, this);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -601,23 +598,6 @@ public class MobAI {
|
||||
|
||||
if (mob == null)
|
||||
return;
|
||||
|
||||
boolean continueExecution = false;
|
||||
switch(mob.BehaviourType){
|
||||
case GuardCaptain:
|
||||
case GuardMinion:
|
||||
case Pet1:
|
||||
case GuardWallArcher:
|
||||
case HamletGuard:
|
||||
case SimpleStandingGuard:
|
||||
continueExecution = true;
|
||||
break;
|
||||
}
|
||||
if(!continueExecution) {
|
||||
MobAi2.runAI(mob);
|
||||
return;
|
||||
}
|
||||
|
||||
if(mob.isAlive())
|
||||
if(!mob.getMovementLoc().equals(Vector3fImmutable.ZERO))
|
||||
mob.setLoc(mob.getMovementLoc());
|
||||
@@ -935,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,360 +0,0 @@
|
||||
package engine.mobileAI;
|
||||
|
||||
import engine.Enum;
|
||||
import engine.InterestManagement.WorldGrid;
|
||||
import engine.gameManager.*;
|
||||
import engine.mobileAI.Threads.MobAIThread;
|
||||
import engine.mobileAI.utilities.CombatUtilities;
|
||||
import engine.mobileAI.utilities.MovementUtilities;
|
||||
import engine.objects.*;
|
||||
import engine.server.MBServerStatics;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
public class MobAi2 {
|
||||
|
||||
public enum State
|
||||
{
|
||||
Idle,
|
||||
Patrolling,
|
||||
Attacking,
|
||||
Dead
|
||||
}
|
||||
|
||||
public static boolean Agressive(Mob mob){
|
||||
return mob.BehaviourType.name().contains("Aggro");
|
||||
}
|
||||
|
||||
public static boolean Caster(Mob mob){
|
||||
return mob.BehaviourType.name().contains("Power");
|
||||
}
|
||||
|
||||
public static boolean HelpResponder(Mob mob){
|
||||
return mob.BehaviourType.name().contains("Helpee");
|
||||
}
|
||||
|
||||
public static State getState(Mob mob){
|
||||
|
||||
if(!mob.isAlive())
|
||||
return State.Dead;
|
||||
|
||||
if(mob.playerAgroMap.isEmpty())
|
||||
return State.Idle;
|
||||
|
||||
if(mob.combatTarget != null)
|
||||
return State.Attacking;
|
||||
|
||||
return State.Patrolling;
|
||||
}
|
||||
|
||||
public static void runAI(Mob mob){
|
||||
|
||||
//these will be handled in special conditions later
|
||||
switch(mob.BehaviourType){
|
||||
case GuardCaptain:
|
||||
case GuardMinion:
|
||||
case Pet1:
|
||||
case GuardWallArcher:
|
||||
case HamletGuard:
|
||||
case SimpleStandingGuard:
|
||||
return;
|
||||
}
|
||||
switch(getState(mob)){
|
||||
case Idle:
|
||||
if(mob.isMoving())
|
||||
mob.stopMovement(mob.loc);
|
||||
if(mob.combatTarget != null) {
|
||||
mob.setCombatTarget(null);
|
||||
mob.setCombat(false);
|
||||
}
|
||||
return;
|
||||
case Dead:
|
||||
respawn(mob);
|
||||
break;
|
||||
case Patrolling:
|
||||
patrol(mob);
|
||||
break;
|
||||
case Attacking:
|
||||
attack(mob);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//handles respawning and de-spawning for mobs and their corpses
|
||||
public static void respawn(Mob mob){
|
||||
|
||||
//if mob doesn't have a death time somehow, set it to now
|
||||
if (mob.deathTime == 0)
|
||||
mob.setDeathTime(System.currentTimeMillis());
|
||||
|
||||
//only execute this logic is the mob hasn't de-spawned yet
|
||||
if (!mob.despawned) {
|
||||
|
||||
//if the inventory is empty, the mob can disappear
|
||||
if(mob.getInventory(true).isEmpty() && System.currentTimeMillis() > mob.deathTime + 10000L) {
|
||||
mob.despawn();
|
||||
mob.deathTime = System.currentTimeMillis();
|
||||
return;
|
||||
}
|
||||
|
||||
//if the mob has been dead for 10 seconds it can disappear
|
||||
if (System.currentTimeMillis() > mob.deathTime + 10000L) {
|
||||
mob.despawn();
|
||||
mob.deathTime = System.currentTimeMillis();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//disc dropper respawns are handled elsewhere
|
||||
if(Mob.discDroppers.contains(mob))
|
||||
return;
|
||||
|
||||
//if mob isn't queued for respawn, do so now
|
||||
if (!Zone.respawnQue.contains(mob)) {
|
||||
if (System.currentTimeMillis() > (mob.deathTime + (mob.spawnTime * 1000L))) {
|
||||
Zone.respawnQue.add(mob);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//handles patrolling and looking for potential combat targets
|
||||
public static void patrol(Mob mob){
|
||||
if(Agressive(mob) && mob.combatTarget == null) {
|
||||
HashSet<AbstractWorldObject> potentialTargets = WorldGrid.getObjectsInRangePartial(mob.loc, 50, MBServerStatics.MASK_PLAYER);
|
||||
for (AbstractWorldObject awo : potentialTargets) {
|
||||
PlayerCharacter target = (PlayerCharacter) awo;
|
||||
if (mob.canSee(target))
|
||||
mob.setCombatTarget(target);
|
||||
if (mob.combatTarget != null) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(mob.isMoving() || !mob.BehaviourType.canRoam)
|
||||
return;
|
||||
|
||||
int patrolDelay = ThreadLocalRandom.current().nextInt((int) (MobAIThread.AI_PATROL_DIVISOR * 0.5f), MobAIThread.AI_PATROL_DIVISOR) + MobAIThread.AI_PATROL_DIVISOR;
|
||||
|
||||
if (mob.stopPatrolTime + (patrolDelay * 1000L) > System.currentTimeMillis())
|
||||
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){
|
||||
AbstractWorldObject target = mob.combatTarget;
|
||||
|
||||
if (target == null || !target.isAlive()) {
|
||||
mob.setCombatTarget(null);
|
||||
return;
|
||||
}
|
||||
|
||||
if(!mob.isCombat())
|
||||
mob.setCombat(true);
|
||||
|
||||
if (!CombatUtilities.inRangeToAttack(mob, target) && mob.BehaviourType.canRoam) {
|
||||
if(mob.nextChaseUpdate < System.currentTimeMillis()) {
|
||||
mob.nextChaseUpdate = System.currentTimeMillis() + 2500L;
|
||||
MovementUtilities.aiMove(mob, target.loc, false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
switch (target.getObjectType()) {
|
||||
case PlayerCharacter:
|
||||
PlayerCharacter targetPlayer = (PlayerCharacter) target;
|
||||
AttackPlayer(mob, targetPlayer);
|
||||
break;
|
||||
case Building:
|
||||
Building targetBuilding = (Building) target;
|
||||
AttackBuilding(mob, targetBuilding);
|
||||
break;
|
||||
case Mob:
|
||||
Mob targetMob = (Mob) target;
|
||||
AttackMob(mob, targetMob);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public static void AttackPlayer(Mob mob, PlayerCharacter target) {
|
||||
|
||||
try {
|
||||
|
||||
if (!mob.canSee(target)) {
|
||||
mob.setCombatTarget(null);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mob.BehaviourType.callsForHelp)
|
||||
MobCallForHelp(mob);
|
||||
|
||||
if (!MovementUtilities.inRangeDropAggro(mob, target)) {
|
||||
mob.setCombatTarget(null);
|
||||
return;
|
||||
}
|
||||
|
||||
if (CombatUtilities.inRange2D(mob, target, mob.getRange())) {
|
||||
|
||||
//no weapons, default mob attack speed 3 seconds.
|
||||
|
||||
if (System.currentTimeMillis() < mob.getLastAttackTime())
|
||||
return;
|
||||
|
||||
// ranged mobs can't attack while running. skip until they finally stop.
|
||||
|
||||
if (mob.isMoving() && mob.getRange() > 20)
|
||||
return;
|
||||
|
||||
// add timer for last attack.
|
||||
|
||||
ItemBase mainHand = mob.getWeaponItemBase(true);
|
||||
ItemBase offHand = mob.getWeaponItemBase(false);
|
||||
|
||||
if (mainHand == null && offHand == null) {
|
||||
CombatUtilities.combatCycle(mob, target, true, null);
|
||||
int delay = 3000;
|
||||
if (mob.isSiege())
|
||||
delay = 11000;
|
||||
mob.setLastAttackTime(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);
|
||||
} 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);
|
||||
}
|
||||
}
|
||||
|
||||
if (target.getPet() != null)
|
||||
if (target.getPet().getCombatTarget() == null && target.getPet().assist)
|
||||
target.getPet().setCombatTarget(mob);
|
||||
|
||||
} catch (Exception e) {
|
||||
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: AttackPlayer" + " " + e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void AttackBuilding(Mob mob, Building target) {
|
||||
|
||||
try {
|
||||
|
||||
if(mob == null || target == null)
|
||||
return;
|
||||
|
||||
if (target.getRank() == -1 || !target.isVulnerable() || BuildingManager.getBuildingFromCache(target.getObjectUUID()) == null) {
|
||||
mob.setCombatTarget(null);
|
||||
return;
|
||||
}
|
||||
|
||||
City playerCity = ZoneManager.getCityAtLocation(mob.getLoc());
|
||||
|
||||
if (playerCity != null)
|
||||
for (Mob guard : playerCity.getParent().zoneMobSet)
|
||||
if (guard.BehaviourType != null && guard.BehaviourType.ordinal() == Enum.MobBehaviourType.GuardCaptain.ordinal())
|
||||
if (guard.getCombatTarget() == null && guard.getGuild() != null && mob.getGuild() != null && !guard.getGuild().equals(mob.getGuild()))
|
||||
guard.setCombatTarget(mob);
|
||||
|
||||
if (mob.isSiege())
|
||||
MovementManager.sendRWSSMsg(mob);
|
||||
|
||||
ItemBase mainHand = mob.getWeaponItemBase(true);
|
||||
ItemBase offHand = mob.getWeaponItemBase(false);
|
||||
|
||||
if (mainHand == null && offHand == null) {
|
||||
CombatUtilities.combatCycle(mob, target, true, null);
|
||||
int delay = 3000;
|
||||
if (mob.isSiege())
|
||||
delay = 15000;
|
||||
mob.setLastAttackTime(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);
|
||||
} 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);
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: AttackBuilding" + " " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public static void AttackMob(Mob mob, Mob target) {
|
||||
|
||||
try {
|
||||
|
||||
if (mob.getRange() >= 30 && mob.isMoving())
|
||||
return;
|
||||
|
||||
//no weapons, default mob attack speed 3 seconds.
|
||||
|
||||
ItemBase mainHand = mob.getWeaponItemBase(true);
|
||||
ItemBase offHand = mob.getWeaponItemBase(false);
|
||||
|
||||
if (mainHand == null && offHand == null) {
|
||||
CombatUtilities.combatCycle(mob, target, true, null);
|
||||
int delay = 3000;
|
||||
if (mob.isSiege())
|
||||
delay = 11000;
|
||||
mob.setLastAttackTime(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);
|
||||
} 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);
|
||||
if (target.getCombatTarget() == null) {
|
||||
target.setCombatTarget(mob);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: AttackMob" + " " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public static void MobCallForHelp(Mob mob) {
|
||||
|
||||
if (mob.nextCallForHelp == 0)
|
||||
mob.nextCallForHelp = System.currentTimeMillis();
|
||||
|
||||
if (mob.nextCallForHelp > System.currentTimeMillis())
|
||||
return;
|
||||
|
||||
Zone mobCamp = mob.getParentZone();
|
||||
|
||||
for (Mob helper : mobCamp.zoneMobSet) {
|
||||
if (HelpResponder(helper)) {
|
||||
helper.setCombatTarget(mob.getCombatTarget());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mob.nextCallForHelp = System.currentTimeMillis() + 30000L;
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
@@ -8,8 +8,6 @@
|
||||
|
||||
|
||||
package engine.mobileAI.Threads;
|
||||
import engine.InterestManagement.InterestManager;
|
||||
import engine.InterestManagement.WorldGrid;
|
||||
import engine.gameManager.ZoneManager;
|
||||
import engine.objects.Mob;
|
||||
import engine.objects.Zone;
|
||||
@@ -51,8 +49,6 @@ public class MobRespawnThread implements Runnable {
|
||||
respawner.respawn();
|
||||
zone.respawnQue.remove(respawner);
|
||||
zone.lastRespawn = System.currentTimeMillis();
|
||||
WorldGrid.updateObject(respawner);
|
||||
InterestManager.setObjectDirty(respawner);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
@@ -631,6 +631,11 @@ public class VendorDialogMsg extends ClientNetMsg {
|
||||
.getObjectUUID(), true);
|
||||
DispatchMessage.dispatchMsgToInterestArea(pc, arm, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false);
|
||||
|
||||
if(pc.getCharItemManager() != null && pc.getCharItemManager().getGoldInventory() != null && pc.getCharItemManager().getGoldInventory().getNumOfItems() < 1000) {
|
||||
pc.getCharItemManager().addGoldToInventory(1000, false);
|
||||
pc.getCharItemManager().addItemToInventory(new MobLoot(pc, ItemBase.getItemBase(980066), 1, false).promoteToItem(pc));
|
||||
pc.getCharItemManager().updateInventory();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,6 @@ import engine.math.Quaternion;
|
||||
import engine.math.Vector3f;
|
||||
import engine.math.Vector3fImmutable;
|
||||
import engine.mobileAI.Threads.MobAIThread;
|
||||
import engine.mobileAI.utilities.MovementUtilities;
|
||||
import engine.net.ByteBufferWriter;
|
||||
import engine.net.Dispatch;
|
||||
import engine.net.DispatchMessage;
|
||||
@@ -84,7 +83,6 @@ public class Mob extends AbstractIntelligenceAgent {
|
||||
public int lastPatrolPointIndex = 0;
|
||||
public long stopPatrolTime = 0;
|
||||
public City guardedCity;
|
||||
public long nextChaseUpdate = 0;
|
||||
protected int dbID; //the database ID
|
||||
protected int loadID;
|
||||
protected float spawnRadius;
|
||||
@@ -98,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;
|
||||
@@ -1444,23 +1442,12 @@ public class Mob extends AbstractIntelligenceAgent {
|
||||
loadInventory();
|
||||
|
||||
this.updateLocation();
|
||||
reloadAgroMap(this);
|
||||
}
|
||||
|
||||
private static void reloadAgroMap(Mob mob){
|
||||
mob.playerAgroMap.clear();
|
||||
for(AbstractWorldObject obj : WorldGrid.getObjectsInRangePartial(mob.loc,MBServerStatics.CHARACTER_LOAD_RANGE,1)){
|
||||
if(!mob.playerAgroMap.containsKey(obj.getObjectUUID())){
|
||||
mob.playerAgroMap.put(obj.getObjectUUID(),false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void despawn() {
|
||||
|
||||
this.despawned = true;
|
||||
|
||||
this.stopPatrolTime = System.currentTimeMillis();
|
||||
WorldGrid.RemoveWorldObject(this);
|
||||
this.charItemManager.clearInventory();
|
||||
|
||||
@@ -2160,9 +2147,8 @@ public class Mob extends AbstractIntelligenceAgent {
|
||||
Vector3fImmutable newPatrolPoint = Vector3fImmutable.getRandomPointInCircle(this.getBindLoc(), patrolRadius);
|
||||
this.patrolPoints.add(newPatrolPoint);
|
||||
|
||||
if (i == 1) {
|
||||
MovementUtilities.aiMove(this,newPatrolPoint,true);
|
||||
}
|
||||
if (i == 1)
|
||||
MovementManager.translocate(this, newPatrolPoint, null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2251,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) {
|
||||
|
||||
@@ -2925,6 +2925,9 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
}
|
||||
|
||||
public synchronized void grantXP(int xp) {
|
||||
int groupSize = 1;
|
||||
if(GroupManager.getGroup(this)!= null)
|
||||
groupSize = GroupManager.getGroup(this).members.size();
|
||||
if(this.promotionClass == null && this.level == 10){
|
||||
this.setOverFlowEXP(0);
|
||||
this.update(false);
|
||||
@@ -3075,6 +3078,14 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
SetObjectValueMsg upm = new SetObjectValueMsg(this, 9);
|
||||
DispatchMessage.dispatchMsgToInterestArea(this, upm, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, false, false);
|
||||
checkGuildStatus();
|
||||
|
||||
//give gold for level up if level is under or equal to 20 and over 10
|
||||
if(this.level >= 10 && this.level < 20) {
|
||||
int gold = (int) ((100000 * (this.level - 10) / 55.0) / groupSize);
|
||||
this.charItemManager.addGoldToInventory(gold, false);
|
||||
this.charItemManager.updateInventory();
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
this.exp += remainingXP;
|
||||
@@ -4640,7 +4651,7 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
|
||||
tmpLevel = targetLevel;
|
||||
|
||||
tmpLevel = (short) Math.min(tmpLevel, 75);
|
||||
tmpLevel = (short) Math.min(tmpLevel, MBServerStatics.LEVELCAP);
|
||||
|
||||
while (this.level < tmpLevel) {
|
||||
grantXP(Experience.getBaseExperience(tmpLevel) - this.exp);
|
||||
@@ -4886,11 +4897,11 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
while (this.level < 10) {
|
||||
grantXP(Experience.getBaseExperience(this.level + 1) - this.exp);
|
||||
}
|
||||
if(this.charItemManager != null && this.charItemManager.getGoldInventory() != null && this.charItemManager.getGoldInventory().getNumOfItems() < 1000) {
|
||||
this.getCharItemManager().addGoldToInventory(1000, false);
|
||||
this.getCharItemManager().addItemToInventory(new MobLoot(this, ItemBase.getItemBase(980066), 1, false).promoteToItem(this));
|
||||
this.getCharItemManager().updateInventory();
|
||||
}
|
||||
//if(this.charItemManager != null && this.charItemManager.getGoldInventory() != null && this.charItemManager.getGoldInventory().getNumOfItems() < 1000) {
|
||||
// this.getCharItemManager().addGoldToInventory(1000, false);
|
||||
// this.getCharItemManager().addItemToInventory(new MobLoot(this, ItemBase.getItemBase(980066), 1, false).promoteToItem(this));
|
||||
// this.getCharItemManager().updateInventory();
|
||||
//}
|
||||
}
|
||||
|
||||
if(this.isBoxed && !this.containsEffect(1672601862)) {
|
||||
|
||||
Reference in New Issue
Block a user