forked from MagicBane/Server
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
158 lines
5.1 KiB
158 lines
5.1 KiB
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ . |
|
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌· |
|
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀ |
|
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌ |
|
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀ |
|
// Magicbane Emulator Project © 2013 - 2022 |
|
// www.magicbane.com |
|
|
|
|
|
package engine.ai; |
|
|
|
import engine.gameManager.ConfigManager; |
|
import engine.gameManager.ZoneManager; |
|
import engine.objects.Mob; |
|
import engine.objects.Zone; |
|
import engine.util.ThreadUtils; |
|
import org.joda.time.DateTime; |
|
import org.pmw.tinylog.Logger; |
|
|
|
import java.time.Duration; |
|
import java.time.Instant; |
|
|
|
|
|
public class MobileFSMManager { |
|
|
|
private static final MobileFSMManager INSTANCE = new MobileFSMManager(); |
|
public static Duration executionTime = Duration.ofNanos(1); |
|
public static Duration executionMax = Duration.ofNanos(1); |
|
//AI variables moved form mb_server_statics |
|
public static int AI_BASE_AGGRO_RANGE = 60; |
|
public static int AI_DROP_AGGRO_RANGE = 60; |
|
public static int AI_PULSE_MOB_THRESHOLD = 200; |
|
public static int AI_PATROL_DIVISOR = 15; |
|
public static int AI_POWER_DIVISOR = 20; |
|
private volatile boolean alive; |
|
private long timeOfKill = -1; |
|
public fsmState currentState; |
|
public Mob currentMob; |
|
public enum fsmState { |
|
ATTACKTARGET, |
|
ATTACKPLAYER, |
|
ATTACKBUILDING, |
|
ATTACKMOB, |
|
PATROL, |
|
CANCAST, |
|
MOBCAST, |
|
MOBCALLFORHELP, |
|
DETERMINEACTION, |
|
CHECKFORAGRO, |
|
CHECKMOBMOVEMENT, |
|
CHECKFORRESPAWN, |
|
CHECKFORATTACK, |
|
CHECKTOSENDMOBHOME, |
|
CHASETARGET, |
|
SAFEGUARDAGRO, |
|
GUARDCAPTAINLOGIC, |
|
GUARDMINIONLOGIC, |
|
GUARDWALLARCHERLOGIC, |
|
PETLOGIC, |
|
HAMLETGUARDLOGIC, |
|
DEFAULTLOGIC, |
|
CHECKFORPLAYERGUARDAGRO, |
|
GUARDCANAGRO, |
|
RANDOMGUARDPATROLPOINTS, |
|
CHANGETARGETFROMHATEVALUE |
|
} |
|
public String getFSMState(){ |
|
return "Executing: " + this.currentState + " on Mobile UUID: " + this.currentMob.getObjectUUID() + " " + this.currentMob.getName(); |
|
} |
|
private MobileFSMManager() { |
|
|
|
Runnable worker = new Runnable() { |
|
@Override |
|
public void run() { |
|
execution(); |
|
} |
|
}; |
|
|
|
alive = true; |
|
|
|
//assign the AI varibales base don difficulty scaling from config file: |
|
|
|
float difficulty = Float.parseFloat(ConfigManager.MB_AI_AGGRO_RANGE.getValue()); |
|
AI_BASE_AGGRO_RANGE = (int) (100 * difficulty); // range at which aggressive mobs will attack you |
|
|
|
difficulty = Float.parseFloat(ConfigManager.MB_AI_CAST_FREQUENCY.getValue()); |
|
AI_POWER_DIVISOR = (int) (20 * (1.5f - difficulty)); //duration between mob casts |
|
|
|
Thread t = new Thread(worker, "MobileFSMManager"); |
|
t.start(); |
|
} |
|
|
|
public static MobileFSMManager getInstance() { |
|
return INSTANCE; |
|
} |
|
|
|
/** |
|
* Stops the MobileFSMManager |
|
*/ |
|
public void shutdown() { |
|
if (alive) { |
|
alive = false; |
|
timeOfKill = System.currentTimeMillis(); |
|
} |
|
} |
|
|
|
|
|
public boolean isAlive() { |
|
return this.alive; |
|
} |
|
|
|
|
|
private void execution() { |
|
|
|
//Load zone threshold once. |
|
|
|
long mobPulse = System.currentTimeMillis() + AI_PULSE_MOB_THRESHOLD; |
|
Instant startTime; |
|
|
|
while (alive) { |
|
|
|
ThreadUtils.sleep(1); |
|
|
|
if (System.currentTimeMillis() > mobPulse) { |
|
|
|
startTime = Instant.now(); |
|
|
|
for (Zone zone : ZoneManager.getAllZones()) { |
|
|
|
if(zone.respawnQue.size() > 0 && zone.lastRespawn + 100 < System.currentTimeMillis()){ |
|
zone.respawnQue.get(0).respawn(); |
|
zone.respawnQue.remove(0); |
|
zone.lastRespawn = System.currentTimeMillis(); |
|
} |
|
for (Mob mob : zone.zoneMobSet) { |
|
|
|
try { |
|
if (mob != null) |
|
MobileFSM.DetermineAction(mob); |
|
} catch (Exception e) { |
|
Logger.error("Mob: " + mob.getName() + " UUID: " + mob.getObjectUUID() + " ERROR: " + e); |
|
e.printStackTrace(); |
|
} |
|
} |
|
} |
|
|
|
executionTime = Duration.between(startTime, Instant.now()); |
|
|
|
if (executionTime.compareTo(executionMax) > 0) |
|
executionMax = executionTime; |
|
|
|
mobPulse = System.currentTimeMillis() + AI_PULSE_MOB_THRESHOLD; |
|
Logger.error("MobileFSM cycle completed: " + DateTime.now()); |
|
} |
|
} |
|
} |
|
|
|
}
|
|
|