forked from MagicBane/Server
Merge branch 'bugfix-mob-casting' into feature-fatePeddler
This commit is contained in:
@@ -2679,6 +2679,9 @@ public class Enum {
|
||||
return race;
|
||||
}
|
||||
|
||||
public Boolean isMage(){
|
||||
return this.minionClass.ordinal() == MinionClass.MAGE.ordinal();
|
||||
}
|
||||
}
|
||||
|
||||
public enum GridObjectType {
|
||||
|
||||
@@ -191,7 +191,7 @@ public class dbLootHandler extends dbHandlerBase {
|
||||
int recordsRead = 0;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM static_npc_bootySet")) {
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM static_loot_bootySet")) {
|
||||
|
||||
ResultSet rs = preparedStatement.executeQuery();
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@ import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class dbMobBaseHandler extends dbHandlerBase {
|
||||
|
||||
@@ -71,24 +70,6 @@ public class dbMobBaseHandler extends dbHandlerBase {
|
||||
}
|
||||
return mobbaseList;
|
||||
}
|
||||
public HashMap<Integer, Integer> LOAD_STATIC_POWERS(int mobBaseUUID) {
|
||||
|
||||
HashMap<Integer, Integer> powersList = new HashMap<>();
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_npc_mobbase_powers` WHERE `mobbaseUUID`=?")) {
|
||||
|
||||
preparedStatement.setInt(1, mobBaseUUID);
|
||||
ResultSet rs = preparedStatement.executeQuery();
|
||||
|
||||
while (rs.next())
|
||||
powersList.put(rs.getInt("token"), rs.getInt("rank"));
|
||||
|
||||
} catch (SQLException e) {
|
||||
Logger.error(e);
|
||||
}
|
||||
return powersList;
|
||||
}
|
||||
|
||||
public ArrayList<MobBaseEffects> GET_RUNEBASE_EFFECTS(int runeID) {
|
||||
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.db.handlers;
|
||||
|
||||
import engine.Enum;
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.gameManager.PowersManager;
|
||||
import engine.objects.Mob;
|
||||
import engine.objects.PreparedStatementShared;
|
||||
import engine.powers.EffectsBase;
|
||||
import engine.powers.MobPowerEntry;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
|
||||
public class dbPowerHandler extends dbHandlerBase {
|
||||
|
||||
public dbPowerHandler() {
|
||||
this.localClass = Mob.class;
|
||||
this.localObjectType = engine.Enum.GameObjectType.valueOf(this.localClass.getSimpleName());
|
||||
}
|
||||
|
||||
public static void addAllSourceTypes() {
|
||||
PreparedStatementShared ps = null;
|
||||
try {
|
||||
ps = new PreparedStatementShared("SELECT * FROM static_power_sourcetype");
|
||||
ResultSet rs = ps.executeQuery();
|
||||
String IDString, source;
|
||||
while (rs.next()) {
|
||||
IDString = rs.getString("IDString");
|
||||
int token = DbManager.hasher.SBStringHash(IDString);
|
||||
|
||||
|
||||
source = rs.getString("source").replace("-", "").trim();
|
||||
Enum.EffectSourceType effectSourceType = Enum.EffectSourceType.GetEffectSourceType(source);
|
||||
|
||||
if (EffectsBase.effectSourceTypeMap.containsKey(token) == false)
|
||||
EffectsBase.effectSourceTypeMap.put(token, new HashSet<>());
|
||||
|
||||
EffectsBase.effectSourceTypeMap.get(token).add(effectSourceType);
|
||||
}
|
||||
rs.close();
|
||||
} catch (Exception e) {
|
||||
Logger.error(e);
|
||||
} finally {
|
||||
ps.release();
|
||||
}
|
||||
}
|
||||
|
||||
public static void addAllAnimationOverrides() {
|
||||
PreparedStatementShared ps = null;
|
||||
try {
|
||||
ps = new PreparedStatementShared("SELECT * FROM static_power_animation_override");
|
||||
ResultSet rs = ps.executeQuery();
|
||||
String IDString;
|
||||
int animation;
|
||||
while (rs.next()) {
|
||||
IDString = rs.getString("IDString");
|
||||
|
||||
EffectsBase eb = PowersManager.getEffectByIDString(IDString);
|
||||
if (eb != null)
|
||||
IDString = eb.getIDString();
|
||||
|
||||
animation = rs.getInt("animation");
|
||||
PowersManager.AnimationOverrides.put(IDString, animation);
|
||||
|
||||
}
|
||||
rs.close();
|
||||
} catch (Exception e) {
|
||||
Logger.error(e);
|
||||
} finally {
|
||||
ps.release();
|
||||
}
|
||||
}
|
||||
|
||||
public static HashMap<Integer, ArrayList<MobPowerEntry>> LOAD_MOB_POWERS() {
|
||||
|
||||
HashMap<Integer, ArrayList<MobPowerEntry>> mobPowers = new HashMap<>();
|
||||
MobPowerEntry mobPowerEntry;
|
||||
|
||||
int mobbaseID;
|
||||
int recordsRead = 0;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM static_npc_mobbase_powers ORDER BY `id` ASC;")) {
|
||||
|
||||
ResultSet rs = preparedStatement.executeQuery();
|
||||
|
||||
while (rs.next()) {
|
||||
|
||||
recordsRead++;
|
||||
|
||||
mobbaseID = rs.getInt("mobbaseUUID");
|
||||
mobPowerEntry = new MobPowerEntry(rs);
|
||||
|
||||
if (mobPowers.get(mobbaseID) == null) {
|
||||
ArrayList<MobPowerEntry> powerList = new ArrayList<>();
|
||||
powerList.add(mobPowerEntry);
|
||||
mobPowers.put(mobbaseID, powerList);
|
||||
} else {
|
||||
ArrayList<MobPowerEntry> powerList = mobPowers.get(mobbaseID);
|
||||
powerList.add(mobPowerEntry);
|
||||
mobPowers.put(mobbaseID, powerList);
|
||||
}
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
Logger.error(e);
|
||||
return mobPowers;
|
||||
}
|
||||
|
||||
Logger.info("read: " + recordsRead + " cached: " + mobPowers.size());
|
||||
return mobPowers;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,7 +2,6 @@ package engine.devcmd.cmds;
|
||||
|
||||
import engine.devcmd.AbstractDevCmd;
|
||||
import engine.gameManager.LootManager;
|
||||
import engine.gameManager.NPCManager;
|
||||
import engine.gameManager.ZoneManager;
|
||||
import engine.loot.BootySetEntry;
|
||||
import engine.objects.*;
|
||||
@@ -33,7 +32,7 @@ public class SimulateBootyCmd extends AbstractDevCmd {
|
||||
output += "Special Loot:" + newline;
|
||||
|
||||
if (mob.bootySet != 0) {
|
||||
for (BootySetEntry entry : NPCManager._bootySetMap.get(mob.bootySet)) {
|
||||
for (BootySetEntry entry : LootManager._bootySetMap.get(mob.bootySet)) {
|
||||
ItemBase item = ItemBase.getItemBase(entry.itemBase);
|
||||
if (item != null) {
|
||||
output += "[" + entry.bootyType + "] " + item.getName() + " [Chance] " + entry.dropChance + newline;
|
||||
@@ -118,7 +117,7 @@ public class SimulateBootyCmd extends AbstractDevCmd {
|
||||
else
|
||||
dropRate = LootManager.NORMAL_DROP_RATE;
|
||||
|
||||
for (BootySetEntry entry : NPCManager._bootySetMap.get(mob.getMobBase().bootySet)) {
|
||||
for (BootySetEntry entry : LootManager._bootySetMap.get(mob.getMobBase().bootySet)) {
|
||||
|
||||
if (entry.bootyType.equals("GOLD"))
|
||||
output += "NORMAL TABLE [" + entry.bootyType + "] " + entry.genTable + ": " + entry.dropChance + newline;
|
||||
|
||||
@@ -11,9 +11,7 @@ package engine.devcmd.cmds;
|
||||
|
||||
import engine.Enum.GameObjectType;
|
||||
import engine.devcmd.AbstractDevCmd;
|
||||
import engine.gameManager.BuildingManager;
|
||||
import engine.objects.AbstractGameObject;
|
||||
import engine.objects.Building;
|
||||
import engine.objects.Mob;
|
||||
import engine.objects.PlayerCharacter;
|
||||
|
||||
@@ -30,55 +28,40 @@ public class aiInfoCmd extends AbstractDevCmd {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void _doCmd(PlayerCharacter pc, String[] words,
|
||||
protected void _doCmd(PlayerCharacter playerCharacter, String[] words,
|
||||
AbstractGameObject target) {
|
||||
|
||||
// Arg Count Check
|
||||
|
||||
if (words.length != 1) {
|
||||
this.sendUsage(pc);
|
||||
this.sendUsage(playerCharacter);
|
||||
return;
|
||||
}
|
||||
if (pc == null) {
|
||||
|
||||
if (playerCharacter == null)
|
||||
return;
|
||||
}
|
||||
|
||||
String newline = "\r\n ";
|
||||
|
||||
try {
|
||||
int targetID = Integer.parseInt(words[0]);
|
||||
Building b = BuildingManager.getBuilding(targetID);
|
||||
if (b == null)
|
||||
throwbackError(pc, "Building with ID " + targetID
|
||||
+ " not found");
|
||||
else
|
||||
target = b;
|
||||
} catch (Exception e) {
|
||||
}
|
||||
|
||||
if (target == null) {
|
||||
throwbackError(pc, "Target is unknown or of an invalid type."
|
||||
+ newline + "Type ID: 0x"
|
||||
+ pc.getLastTargetType().toString()
|
||||
+ " Table ID: " + pc.getLastTargetID());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
GameObjectType objType = target.getObjectType();
|
||||
int objectUUID = target.getObjectUUID();
|
||||
String output;
|
||||
|
||||
if (objType != GameObjectType.Mob) {
|
||||
output = "Please Select A Mob For AI Info" + newline;
|
||||
} else {
|
||||
Mob mob = (Mob) target;
|
||||
output = "Mob AI Information:" + newline;
|
||||
output += mob.getName() + newline;
|
||||
if (mob.BehaviourType != null) {
|
||||
output += "BehaviourType: " + mob.BehaviourType.toString() + newline;
|
||||
if (mob.BehaviourType.BehaviourHelperType != null) {
|
||||
output += "Behaviour Helper Type: " + mob.BehaviourType.BehaviourHelperType.toString() + newline;
|
||||
} else {
|
||||
output += "Behaviour Helper Type: NULL" + newline;
|
||||
throwbackInfo(playerCharacter, output);
|
||||
return;
|
||||
}
|
||||
|
||||
Mob mob = (Mob) target;
|
||||
output = "Mob AI Information:" + newline;
|
||||
output += mob.getName() + newline;
|
||||
if (mob.BehaviourType != null) {
|
||||
output += "BehaviourType: " + mob.BehaviourType.toString() + newline;
|
||||
if (mob.BehaviourType.BehaviourHelperType != null) {
|
||||
output += "Behaviour Helper Type: " + mob.BehaviourType.BehaviourHelperType.toString() + newline;
|
||||
} else {
|
||||
output += "Behaviour Helper Type: NULL" + newline;
|
||||
}
|
||||
output += "Wimpy: " + mob.BehaviourType.isWimpy + newline;
|
||||
output += "Agressive: " + mob.BehaviourType.isAgressive + newline;
|
||||
@@ -90,18 +73,21 @@ public class aiInfoCmd extends AbstractDevCmd {
|
||||
}
|
||||
output += "Aggro Range: " + mob.getAggroRange() + newline;
|
||||
output += "Player Aggro Map Size: " + mob.playerAgroMap.size() + newline;
|
||||
if (mob.playerAgroMap.size() > 0) {
|
||||
output += "Players Loaded:" + newline;
|
||||
}
|
||||
for (Map.Entry<Integer, Boolean> entry : mob.playerAgroMap.entrySet()) {
|
||||
output += "Player ID: " + entry.getKey() + " Is Safemode: " + entry.getValue() + newline;
|
||||
}
|
||||
if (mob.getCombatTarget() != null)
|
||||
output += "Current Target: " + mob.getCombatTarget().getName() + newline;
|
||||
else
|
||||
output += "Current Target: NULL" + newline;
|
||||
if (mob.playerAgroMap.size() > 0) {
|
||||
output += "Players Loaded:" + newline;
|
||||
}
|
||||
throwbackInfo(pc, output);
|
||||
for (Map.Entry<Integer, Boolean> entry : mob.playerAgroMap.entrySet()) {
|
||||
output += "Player ID: " + entry.getKey() + " Hate Value: " + (PlayerCharacter.getPlayerCharacter(entry.getKey())).getHateValue() + newline;
|
||||
}
|
||||
if (mob.getCombatTarget() != null)
|
||||
output += "Current Target: " + mob.getCombatTarget().getName() + newline;
|
||||
else
|
||||
output += "Current Target: NULL" + newline;
|
||||
|
||||
for (int token : mob.mobPowers.keySet())
|
||||
output += token + newline;
|
||||
|
||||
throwbackInfo(playerCharacter, output);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -72,6 +72,8 @@ public enum DbManager {
|
||||
public static final dbShrineHandler ShrineQueries = new dbShrineHandler();
|
||||
public static final dbHeightMapHandler HeightMapQueries = new dbHeightMapHandler();
|
||||
public static final dbRunegateHandler RunegateQueries = new dbRunegateHandler();
|
||||
|
||||
public static final dbPowerHandler PowerQueries = new dbPowerHandler();
|
||||
private static final EnumMap<GameObjectType, ConcurrentHashMap<Integer, AbstractGameObject>> objectCache = new EnumMap<>(GameObjectType.class);
|
||||
public static Hasher hasher;
|
||||
private static HikariDataSource connectionPool = null;
|
||||
|
||||
@@ -42,6 +42,7 @@ public enum LootManager {
|
||||
public static float HOTZONE_DROP_RATE;
|
||||
public static float HOTZONE_EXP_RATE;
|
||||
public static float HOTZONE_GOLD_RATE;
|
||||
public static HashMap<Integer, ArrayList<BootySetEntry>> _bootySetMap = new HashMap<>();
|
||||
|
||||
// Bootstrap routine to initialize the Loot Manager
|
||||
|
||||
@@ -73,11 +74,11 @@ public enum LootManager {
|
||||
|
||||
//iterate the booty sets
|
||||
|
||||
if (mob.getMobBase().bootySet != 0 && NPCManager._bootySetMap.containsKey(mob.getMobBase().bootySet) == true)
|
||||
RunBootySet(NPCManager._bootySetMap.get(mob.getMobBase().bootySet), mob, inHotzone, fromDeath);
|
||||
if (mob.getMobBase().bootySet != 0 && _bootySetMap.containsKey(mob.getMobBase().bootySet) == true)
|
||||
RunBootySet(_bootySetMap.get(mob.getMobBase().bootySet), mob, inHotzone, fromDeath);
|
||||
|
||||
if (mob.bootySet != 0 && NPCManager._bootySetMap.containsKey(mob.bootySet) == true)
|
||||
RunBootySet(NPCManager._bootySetMap.get(mob.bootySet), mob, inHotzone, fromDeath);
|
||||
if (mob.bootySet != 0 && _bootySetMap.containsKey(mob.bootySet) == true)
|
||||
RunBootySet(_bootySetMap.get(mob.bootySet), mob, inHotzone, fromDeath);
|
||||
|
||||
//lastly, check mobs inventory for godly or disc runes to send a server announcement
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ package engine.gameManager;
|
||||
|
||||
import engine.Enum;
|
||||
import engine.InterestManagement.WorldGrid;
|
||||
import engine.loot.BootySetEntry;
|
||||
import engine.net.Dispatch;
|
||||
import engine.net.DispatchMessage;
|
||||
import engine.net.client.msg.PetMsg;
|
||||
@@ -18,14 +17,13 @@ public enum NPCManager {
|
||||
|
||||
NPC_MANAGER;
|
||||
public static HashMap<Integer, ArrayList<Integer>> _runeSetMap = new HashMap<>();
|
||||
public static HashMap<Integer, ArrayList<BootySetEntry>> _bootySetMap = new HashMap<>();
|
||||
|
||||
public static void LoadAllRuneSets() {
|
||||
_runeSetMap = DbManager.ItemBaseQueries.LOAD_RUNES_FOR_NPC_AND_MOBS();
|
||||
}
|
||||
|
||||
public static void LoadAllBootySets() {
|
||||
_bootySetMap = DbManager.LootQueries.LOAD_BOOTY_TABLES();
|
||||
LootManager._bootySetMap = DbManager.LootQueries.LOAD_BOOTY_TABLES();
|
||||
}
|
||||
|
||||
public static void applyRuneSetEffects(Mob mob) {
|
||||
@@ -108,7 +106,7 @@ public enum NPCManager {
|
||||
|
||||
public static void dismissNecroPet(Mob necroPet, boolean updateOwner) {
|
||||
|
||||
necroPet.combatTarget = null;
|
||||
necroPet.setCombatTarget(null);
|
||||
necroPet.hasLoot = false;
|
||||
|
||||
if (necroPet.parentZone != null)
|
||||
|
||||
@@ -12,6 +12,7 @@ import engine.Enum.*;
|
||||
import engine.InterestManagement.HeightMap;
|
||||
import engine.InterestManagement.WorldGrid;
|
||||
import engine.db.handlers.dbEffectsBaseHandler;
|
||||
import engine.db.handlers.dbPowerHandler;
|
||||
import engine.db.handlers.dbSkillReqHandler;
|
||||
import engine.job.AbstractJob;
|
||||
import engine.job.AbstractScheduleJob;
|
||||
@@ -26,13 +27,11 @@ import engine.net.client.ClientConnection;
|
||||
import engine.net.client.msg.*;
|
||||
import engine.objects.*;
|
||||
import engine.powers.*;
|
||||
import engine.powers.effectmodifiers.AbstractEffectModifier;
|
||||
import engine.powers.poweractions.AbstractPowerAction;
|
||||
import engine.powers.poweractions.TrackPowerAction;
|
||||
import engine.server.MBServerStatics;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
@@ -53,9 +52,8 @@ public enum PowersManager {
|
||||
public static HashMap<String, AbstractPowerAction> powerActionsByIDString = new HashMap<>();
|
||||
public static HashMap<Integer, AbstractPowerAction> powerActionsByID = new HashMap<>();
|
||||
public static HashMap<String, Integer> ActionTokenByIDString = new HashMap<>();
|
||||
public static HashMap<Integer, AbstractEffectModifier> modifiersByToken = new HashMap<>();
|
||||
public static HashMap<String, Integer> AnimationOverrides = new HashMap<>();
|
||||
public static HashMap<Integer, HashMap<Integer, Integer>> AllMobPowers = new HashMap<>();
|
||||
public static HashMap<Integer, ArrayList<MobPowerEntry>> AllMobPowers;
|
||||
private static JobScheduler js;
|
||||
|
||||
private PowersManager() {
|
||||
@@ -85,10 +83,6 @@ public enum PowersManager {
|
||||
return PowersManager.effectsBaseByIDString.get(IDString);
|
||||
}
|
||||
|
||||
public static AbstractPowerAction getPowerActionByID(Integer id) {
|
||||
return PowersManager.powerActionsByID.get(id);
|
||||
}
|
||||
|
||||
public static AbstractPowerAction getPowerActionByIDString(String IDString) {
|
||||
return PowersManager.powerActionsByIDString.get(IDString);
|
||||
}
|
||||
@@ -128,8 +122,8 @@ public enum PowersManager {
|
||||
dbEffectsBaseHandler.cacheAllEffectModifiers();
|
||||
|
||||
// Add Source Types to Effects
|
||||
PowersManager.addAllSourceTypes();
|
||||
PowersManager.addAllAnimationOverrides();
|
||||
dbPowerHandler.addAllSourceTypes();
|
||||
dbPowerHandler.addAllAnimationOverrides();
|
||||
|
||||
// Add PowerActions
|
||||
AbstractPowerAction.getAllPowerActions(PowersManager.powerActionsByIDString, PowersManager.powerActionsByID, PowersManager.effectsBaseByIDString);
|
||||
@@ -156,59 +150,6 @@ public enum PowersManager {
|
||||
|
||||
}
|
||||
|
||||
private static void addAllSourceTypes() {
|
||||
PreparedStatementShared ps = null;
|
||||
try {
|
||||
ps = new PreparedStatementShared("SELECT * FROM static_power_sourcetype");
|
||||
ResultSet rs = ps.executeQuery();
|
||||
String IDString, source;
|
||||
while (rs.next()) {
|
||||
IDString = rs.getString("IDString");
|
||||
int token = DbManager.hasher.SBStringHash(IDString);
|
||||
|
||||
|
||||
source = rs.getString("source").replace("-", "").trim();
|
||||
EffectSourceType effectSourceType = EffectSourceType.GetEffectSourceType(source);
|
||||
|
||||
if (EffectsBase.effectSourceTypeMap.containsKey(token) == false)
|
||||
EffectsBase.effectSourceTypeMap.put(token, new HashSet<>());
|
||||
|
||||
EffectsBase.effectSourceTypeMap.get(token).add(effectSourceType);
|
||||
}
|
||||
rs.close();
|
||||
} catch (Exception e) {
|
||||
Logger.error(e);
|
||||
} finally {
|
||||
ps.release();
|
||||
}
|
||||
}
|
||||
|
||||
private static void addAllAnimationOverrides() {
|
||||
PreparedStatementShared ps = null;
|
||||
try {
|
||||
ps = new PreparedStatementShared("SELECT * FROM static_power_animation_override");
|
||||
ResultSet rs = ps.executeQuery();
|
||||
String IDString;
|
||||
int animation;
|
||||
while (rs.next()) {
|
||||
IDString = rs.getString("IDString");
|
||||
|
||||
EffectsBase eb = PowersManager.getEffectByIDString(IDString);
|
||||
if (eb != null)
|
||||
IDString = eb.getIDString();
|
||||
|
||||
animation = rs.getInt("animation");
|
||||
PowersManager.AnimationOverrides.put(IDString, animation);
|
||||
|
||||
}
|
||||
rs.close();
|
||||
} catch (Exception e) {
|
||||
Logger.error(e);
|
||||
} finally {
|
||||
ps.release();
|
||||
}
|
||||
}
|
||||
|
||||
public static EffectsBase setEffectToken(int ID, int token) {
|
||||
for (EffectsBase eb : PowersManager.effectsBaseByIDString.values()) {
|
||||
if (eb.getUUID() == ID) {
|
||||
@@ -2778,26 +2719,6 @@ public enum PowersManager {
|
||||
}
|
||||
}
|
||||
|
||||
public static void LoadAllMobPowers() {
|
||||
|
||||
int count = 0;
|
||||
|
||||
for (AbstractGameObject mobBaseAgo : DbManager.getList(GameObjectType.MobBase)) {
|
||||
|
||||
int mobBaseID = ((MobBase) mobBaseAgo).getLoadID();
|
||||
|
||||
HashMap powersList = DbManager.MobBaseQueries.LOAD_STATIC_POWERS(mobBaseID);
|
||||
|
||||
if (powersList.isEmpty())
|
||||
continue;
|
||||
;
|
||||
|
||||
AllMobPowers.put(mobBaseID, powersList);
|
||||
count++;
|
||||
}
|
||||
|
||||
Logger.info("Powers loaded for " + count + " Mobbases/");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
+208
-96
@@ -20,7 +20,6 @@ import engine.mobileAI.utilities.MovementUtilities;
|
||||
import engine.net.DispatchMessage;
|
||||
import engine.net.client.msg.PerformActionMsg;
|
||||
import engine.net.client.msg.PowerProjectileMsg;
|
||||
import engine.net.client.msg.UpdateStateMsg;
|
||||
import engine.objects.*;
|
||||
import engine.powers.ActionsBase;
|
||||
import engine.powers.PowersBase;
|
||||
@@ -50,12 +49,16 @@ public class MobAI {
|
||||
return;
|
||||
}
|
||||
|
||||
if (target.getObjectType() == Enum.GameObjectType.PlayerCharacter && canCast(mob))
|
||||
if (MobCast(mob)) {
|
||||
if (target.getObjectType() == Enum.GameObjectType.PlayerCharacter && canCast(mob)) {
|
||||
if (mob.isPlayerGuard() == false && MobCast(mob)) {
|
||||
mob.updateLocation();
|
||||
return;
|
||||
}
|
||||
|
||||
if (mob.isPlayerGuard() == true && GuardCast(mob)) {
|
||||
mob.updateLocation();
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!CombatUtilities.inRangeToAttack(mob, target))
|
||||
return;
|
||||
|
||||
@@ -230,8 +233,8 @@ public class MobAI {
|
||||
attackDelay = 11000;
|
||||
CombatUtilities.combatCycle(mob, target, false, mob.getWeaponItemBase(false));
|
||||
mob.setLastAttackTime(System.currentTimeMillis() + attackDelay);
|
||||
if (target.combatTarget == null) {
|
||||
target.combatTarget = mob;
|
||||
if (target.getCombatTarget() == null) {
|
||||
target.setCombatTarget(mob);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
@@ -245,13 +248,6 @@ public class MobAI {
|
||||
|
||||
//make sure mob is out of combat stance
|
||||
|
||||
if (mob.isCombat() && mob.getCombatTarget() == null) {
|
||||
mob.setCombat(false);
|
||||
UpdateStateMsg rwss = new UpdateStateMsg();
|
||||
rwss.setPlayer(mob);
|
||||
DispatchMessage.sendToAllInRange(mob, rwss);
|
||||
}
|
||||
|
||||
int patrolDelay = ThreadLocalRandom.current().nextInt((int) (MobAIThread.AI_PATROL_DIVISOR * 0.5f), MobAIThread.AI_PATROL_DIVISOR) + MobAIThread.AI_PATROL_DIVISOR;
|
||||
|
||||
//early exit while waiting to patrol again
|
||||
@@ -279,19 +275,12 @@ public class MobAI {
|
||||
|
||||
MovementUtilities.aiMove(mob, mob.destination, true);
|
||||
|
||||
if (mob.BehaviourType.ordinal() == Enum.MobBehaviourType.GuardCaptain.ordinal()) {
|
||||
if (mob.BehaviourType.equals(Enum.MobBehaviourType.GuardCaptain)) {
|
||||
for (Entry<Mob, Integer> minion : mob.siegeMinionMap.entrySet()) {
|
||||
|
||||
//make sure mob is out of combat stance
|
||||
|
||||
if (minion.getKey().despawned == false) {
|
||||
if (minion.getKey().isCombat() && minion.getKey().getCombatTarget() == null) {
|
||||
minion.getKey().setCombat(false);
|
||||
UpdateStateMsg rwss = new UpdateStateMsg();
|
||||
rwss.setPlayer(minion.getKey());
|
||||
DispatchMessage.sendToAllInRange(minion.getKey(), rwss);
|
||||
}
|
||||
|
||||
if (MovementUtilities.canMove(minion.getKey())) {
|
||||
Vector3f minionOffset = Formation.getOffset(2, minion.getValue() + 3);
|
||||
minion.getKey().updateLocation();
|
||||
@@ -316,6 +305,16 @@ public class MobAI {
|
||||
if (mob == null)
|
||||
return false;
|
||||
|
||||
if(mob.isPlayerGuard == true){
|
||||
int contractID;
|
||||
if(mob.BehaviourType.equals(Enum.MobBehaviourType.GuardMinion))
|
||||
contractID = mob.npcOwner.contract.getContractID();
|
||||
else
|
||||
contractID = mob.contract.getContractID();
|
||||
if(Enum.MinionType.ContractToMinionMap.get(contractID).isMage() == false)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mob.mobPowers.isEmpty())
|
||||
return false;
|
||||
|
||||
@@ -323,12 +322,6 @@ public class MobAI {
|
||||
mob.setCombatTarget(null);
|
||||
return false;
|
||||
}
|
||||
|
||||
int castRoll = ThreadLocalRandom.current().nextInt(101);
|
||||
|
||||
if (castRoll <= MobAIThread.AI_POWER_DIVISOR)
|
||||
return false;
|
||||
|
||||
if (mob.nextCastTime == 0)
|
||||
mob.nextCastTime = System.currentTimeMillis();
|
||||
|
||||
@@ -349,7 +342,7 @@ public class MobAI {
|
||||
|
||||
ArrayList<Integer> powerTokens;
|
||||
ArrayList<Integer> purgeTokens;
|
||||
PlayerCharacter target = (PlayerCharacter) mob.getCombatTarget();
|
||||
AbstractCharacter target = (AbstractCharacter) mob.getCombatTarget();
|
||||
|
||||
if (mob.BehaviourType.callsForHelp)
|
||||
MobCallForHelp(mob);
|
||||
@@ -395,37 +388,152 @@ public class MobAI {
|
||||
|
||||
if (CombatUtilities.triggerDefense(mob, mob.getCombatTarget()))
|
||||
return false;
|
||||
|
||||
if (CombatUtilities.triggerDodge(mob, mob.getCombatTarget()))
|
||||
return false;
|
||||
|
||||
if (CombatUtilities.triggerBlock(mob, mob.getCombatTarget()))
|
||||
return false;
|
||||
|
||||
if (CombatUtilities.triggerParry(mob, mob.getCombatTarget()))
|
||||
return false;
|
||||
}
|
||||
|
||||
// Cast the spell
|
||||
|
||||
if (CombatUtilities.inRange2D(mob, mob.getCombatTarget(), mobPower.getRange())) {
|
||||
|
||||
PowersManager.useMobPower(mob, (AbstractCharacter) mob.getCombatTarget(), mobPower, powerRank);
|
||||
|
||||
PerformActionMsg msg;
|
||||
|
||||
if (!mobPower.isHarmful() || mobPower.targetSelf)
|
||||
if (!mobPower.isHarmful() || mobPower.targetSelf) {
|
||||
PowersManager.useMobPower(mob, mob, mobPower, powerRank);
|
||||
msg = PowersManager.createPowerMsg(mobPower, powerRank, mob, mob);
|
||||
else
|
||||
}
|
||||
else {
|
||||
PowersManager.useMobPower(mob, target, mobPower, powerRank);
|
||||
msg = PowersManager.createPowerMsg(mobPower, powerRank, mob, target);
|
||||
}
|
||||
|
||||
msg.setUnknown04(2);
|
||||
|
||||
PowersManager.finishUseMobPower(msg, mob, 0, 0);
|
||||
long randomCooldown = (long)((ThreadLocalRandom.current().nextInt(10,15) * 1000) * MobAIThread.AI_CAST_FREQUENCY);
|
||||
mob.nextCastTime = System.currentTimeMillis() + randomCooldown;
|
||||
return true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: MobCast" + " " + e.getMessage());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean GuardCast(Mob mob) {
|
||||
|
||||
try {
|
||||
// Method picks a random spell from a mobile's list of powers
|
||||
// and casts it on the current target (or itself). Validation
|
||||
// (including empty lists) is done previously within canCast();
|
||||
|
||||
ArrayList<Integer> powerTokens;
|
||||
ArrayList<Integer> purgeTokens;
|
||||
AbstractCharacter target = (AbstractCharacter) mob.getCombatTarget();
|
||||
|
||||
if (mob.BehaviourType.callsForHelp)
|
||||
MobCallForHelp(mob);
|
||||
|
||||
// Generate a list of tokens from the mob powers for this mobile.
|
||||
|
||||
powerTokens = new ArrayList<>(mob.mobPowers.keySet());
|
||||
purgeTokens = new ArrayList<>();
|
||||
|
||||
// If player has this effect on them currently then remove
|
||||
// this token from our list.
|
||||
|
||||
for (int powerToken : powerTokens) {
|
||||
|
||||
PowersBase powerBase = PowersManager.getPowerByToken(powerToken);
|
||||
|
||||
for (ActionsBase actionBase : powerBase.getActions()) {
|
||||
|
||||
String stackType = actionBase.stackType;
|
||||
|
||||
if (target.getEffects() != null && target.getEffects().containsKey(stackType))
|
||||
purgeTokens.add(powerToken);
|
||||
}
|
||||
}
|
||||
|
||||
powerTokens.removeAll(purgeTokens);
|
||||
|
||||
// Sanity check
|
||||
|
||||
if (powerTokens.isEmpty())
|
||||
return false;
|
||||
|
||||
int powerToken = 0;
|
||||
int nukeRoll = ThreadLocalRandom.current().nextInt(1,100);
|
||||
|
||||
if (nukeRoll < 55) {
|
||||
|
||||
//use direct damage spell
|
||||
powerToken = powerTokens.get(powerTokens.size() - 1);
|
||||
|
||||
} else {
|
||||
//use random spell
|
||||
powerToken = powerTokens.get(ThreadLocalRandom.current().nextInt(powerTokens.size()));
|
||||
}
|
||||
|
||||
int powerRank = 1;
|
||||
|
||||
switch(mob.getRank()){
|
||||
case 1:
|
||||
powerRank = 10;
|
||||
break;
|
||||
case 2:
|
||||
powerRank = 15;
|
||||
break;
|
||||
case 3:
|
||||
powerRank = 20;
|
||||
break;
|
||||
case 4:
|
||||
powerRank = 25;
|
||||
break;
|
||||
case 5:
|
||||
powerRank = 30;
|
||||
break;
|
||||
case 6:
|
||||
powerRank = 35;
|
||||
break;
|
||||
case 7:
|
||||
powerRank = 40;
|
||||
break;
|
||||
}
|
||||
|
||||
PowersBase mobPower = PowersManager.getPowerByToken(powerToken);
|
||||
|
||||
//check for hit-roll
|
||||
|
||||
if (mobPower.requiresHitRoll)
|
||||
if (CombatUtilities.triggerDefense(mob, mob.getCombatTarget()))
|
||||
return false;
|
||||
|
||||
// Cast the spell
|
||||
|
||||
if (CombatUtilities.inRange2D(mob, mob.getCombatTarget(), mobPower.getRange())) {
|
||||
|
||||
PerformActionMsg msg;
|
||||
|
||||
if (!mobPower.isHarmful() || mobPower.targetSelf) {
|
||||
|
||||
if (mobPower.category.equals("DISPEL")) {
|
||||
PowersManager.useMobPower(mob, target, mobPower, powerRank);
|
||||
msg = PowersManager.createPowerMsg(mobPower, powerRank, mob, target);
|
||||
} else {
|
||||
PowersManager.useMobPower(mob, mob, mobPower, powerRank);
|
||||
msg = PowersManager.createPowerMsg(mobPower, powerRank, mob, mob);
|
||||
}
|
||||
} else {
|
||||
PowersManager.useMobPower(mob, target, mobPower, powerRank);
|
||||
msg = PowersManager.createPowerMsg(mobPower, powerRank, mob, target);
|
||||
}
|
||||
|
||||
msg.setUnknown04(2);
|
||||
|
||||
PowersManager.finishUseMobPower(msg, mob, 0, 0);
|
||||
|
||||
// Default minimum seconds between cast = 10
|
||||
|
||||
float randomCooldown = (ThreadLocalRandom.current().nextInt(150) + 100) * 0.01f;
|
||||
mob.nextCastTime = System.currentTimeMillis() + (long) ((mobPower.getCooldown() + (MobAIThread.AI_POWER_DIVISOR * 1000)) * randomCooldown);
|
||||
long randomCooldown = (long)((ThreadLocalRandom.current().nextInt(10,15) * 1000) * MobAIThread.AI_CAST_FREQUENCY);
|
||||
mob.nextCastTime = System.currentTimeMillis() + randomCooldown;
|
||||
return true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
@@ -529,22 +637,15 @@ public class MobAI {
|
||||
|
||||
//no players loaded, no need to proceed
|
||||
|
||||
if (mob.playerAgroMap.isEmpty() && mob.isPlayerGuard == false && mob.BehaviourType.ordinal() != Enum.MobBehaviourType.Pet1.ordinal()) {
|
||||
mob.setCombatTarget(null);
|
||||
if (mob.playerAgroMap.isEmpty()) {
|
||||
if(mob.getCombatTarget() != null)
|
||||
mob.setCombatTarget(null);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mob.isCombat() && mob.getCombatTarget() == null) {
|
||||
mob.setCombat(false);
|
||||
UpdateStateMsg rwss = new UpdateStateMsg();
|
||||
rwss.setPlayer(mob);
|
||||
DispatchMessage.sendToAllInRange(mob, rwss);
|
||||
}
|
||||
|
||||
if (mob.BehaviourType.ordinal() != Enum.MobBehaviourType.Pet1.ordinal())
|
||||
CheckToSendMobHome(mob);
|
||||
|
||||
if (mob.combatTarget != null) {
|
||||
if (mob.getCombatTarget() != null) {
|
||||
if (mob.getCombatTarget().isAlive() == false) {
|
||||
mob.setCombatTarget(null);
|
||||
return;
|
||||
@@ -552,7 +653,7 @@ public class MobAI {
|
||||
|
||||
if (mob.getCombatTarget().getObjectTypeMask() == MBServerStatics.MASK_PLAYER) {
|
||||
|
||||
PlayerCharacter target = (PlayerCharacter) mob.combatTarget;
|
||||
PlayerCharacter target = (PlayerCharacter) mob.getCombatTarget();
|
||||
|
||||
if (mob.playerAgroMap.containsKey(target.getObjectUUID()) == false) {
|
||||
mob.setCombatTarget(null);
|
||||
@@ -644,7 +745,7 @@ public class MobAI {
|
||||
|
||||
}
|
||||
|
||||
if (aiAgent.combatTarget == null) {
|
||||
if (aiAgent.getCombatTarget() == null) {
|
||||
|
||||
//look for pets to aggro if no players found to aggro
|
||||
|
||||
@@ -790,23 +891,8 @@ public class MobAI {
|
||||
if (mob.getCombatTarget().getObjectType().equals(Enum.GameObjectType.PlayerCharacter) && MovementUtilities.inRangeDropAggro(mob, (PlayerCharacter) mob.getCombatTarget()) == false && mob.BehaviourType.ordinal() != Enum.MobBehaviourType.Pet1.ordinal()) {
|
||||
|
||||
mob.setCombatTarget(null);
|
||||
|
||||
if (mob.isCombat()) {
|
||||
mob.setCombat(false);
|
||||
UpdateStateMsg rwss = new UpdateStateMsg();
|
||||
rwss.setPlayer(mob);
|
||||
DispatchMessage.sendToAllInRange(mob, rwss);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mob.isCombat()) {
|
||||
mob.setCombat(true);
|
||||
UpdateStateMsg rwss = new UpdateStateMsg();
|
||||
rwss.setPlayer(mob);
|
||||
DispatchMessage.sendToAllInRange(mob, rwss);
|
||||
}
|
||||
|
||||
if (System.currentTimeMillis() > mob.getLastAttackTime())
|
||||
AttackTarget(mob, mob.getCombatTarget());
|
||||
|
||||
@@ -869,10 +955,12 @@ public class MobAI {
|
||||
|
||||
try {
|
||||
|
||||
mob.updateMovementState();
|
||||
mob.updateLocation();
|
||||
|
||||
if (CombatUtilities.inRange2D(mob, mob.getCombatTarget(), mob.getRange()) == false) {
|
||||
float rangeSquared = mob.getRange() * mob.getRange();
|
||||
float distanceSquared = mob.getLoc().distanceSquared2D(mob.getCombatTarget().getLoc());
|
||||
if(mob.isMoving() == true && distanceSquared < rangeSquared - 50) {
|
||||
mob.destination = mob.getLoc();
|
||||
MovementUtilities.moveToLocation(mob, mob.destination, 0);
|
||||
} else if (CombatUtilities.inRange2D(mob, mob.getCombatTarget(), mob.getRange()) == false) {
|
||||
if (mob.getRange() > 15) {
|
||||
mob.destination = mob.getCombatTarget().getLoc();
|
||||
MovementUtilities.moveToLocation(mob, mob.destination, 0);
|
||||
@@ -891,11 +979,10 @@ public class MobAI {
|
||||
MovementUtilities.moveToLocation(mob, mob.getCombatTarget().getLoc(), 0);
|
||||
break;
|
||||
}
|
||||
if (CombatUtilities.inRange2D(mob, mob.getCombatTarget(), mob.getRange()) == true) {
|
||||
mob.stopMovement(mob.getLoc());
|
||||
}
|
||||
}
|
||||
}
|
||||
mob.updateMovementState();
|
||||
mob.updateLocation();
|
||||
} catch (Exception e) {
|
||||
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: chaseTarget" + " " + e.getMessage());
|
||||
}
|
||||
@@ -919,7 +1006,8 @@ public class MobAI {
|
||||
|
||||
if (aggroMob.isGuard())
|
||||
continue;
|
||||
|
||||
if(aggroMob.BehaviourType.equals(Enum.MobBehaviourType.Pet1))
|
||||
continue;
|
||||
if (mob.getLoc().distanceSquared2D(aggroMob.getLoc()) > sqr(50))
|
||||
continue;
|
||||
|
||||
@@ -936,6 +1024,18 @@ public class MobAI {
|
||||
if (mob.getCombatTarget() == null)
|
||||
CheckForPlayerGuardAggro(mob);
|
||||
|
||||
AbstractWorldObject newTarget = ChangeTargetFromHateValue(mob);
|
||||
|
||||
if (newTarget != null) {
|
||||
|
||||
if (newTarget.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) {
|
||||
if (GuardCanAggro(mob, (PlayerCharacter) newTarget))
|
||||
mob.setCombatTarget(newTarget);
|
||||
} else
|
||||
mob.setCombatTarget(newTarget);
|
||||
|
||||
}
|
||||
|
||||
CheckMobMovement(mob);
|
||||
CheckForAttack(mob);
|
||||
} catch (Exception e) {
|
||||
@@ -946,14 +1046,33 @@ public class MobAI {
|
||||
public static void GuardMinionLogic(Mob mob) {
|
||||
|
||||
try {
|
||||
if (!mob.npcOwner.isAlive() && mob.getCombatTarget() == null)
|
||||
CheckForPlayerGuardAggro(mob);
|
||||
if (!mob.npcOwner.isAlive()) {
|
||||
|
||||
if (mob.npcOwner.getCombatTarget() != null)
|
||||
mob.setCombatTarget(mob.npcOwner.getCombatTarget());
|
||||
else
|
||||
mob.setCombatTarget(null);
|
||||
if(mob.getCombatTarget() == null) {
|
||||
CheckForPlayerGuardAggro(mob);
|
||||
}else {
|
||||
|
||||
AbstractWorldObject newTarget = ChangeTargetFromHateValue(mob);
|
||||
|
||||
if (newTarget != null) {
|
||||
|
||||
if (newTarget.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) {
|
||||
if (GuardCanAggro(mob, (PlayerCharacter) newTarget))
|
||||
mob.setCombatTarget(newTarget);
|
||||
} else
|
||||
mob.setCombatTarget(newTarget);
|
||||
|
||||
}
|
||||
}
|
||||
}else {
|
||||
if (mob.npcOwner.getCombatTarget() != null)
|
||||
if(mob.getCombatTarget() != null && mob.getCombatTarget().equals(mob.npcOwner.getCombatTarget()) == false)
|
||||
mob.setCombatTarget(mob.npcOwner.getCombatTarget());
|
||||
else
|
||||
if(mob.getCombatTarget() != null) {
|
||||
mob.setCombatTarget(null);
|
||||
}
|
||||
}
|
||||
CheckMobMovement(mob);
|
||||
CheckForAttack(mob);
|
||||
} catch (Exception e) {
|
||||
@@ -1014,7 +1133,7 @@ public class MobAI {
|
||||
|
||||
if (mob.getCombatTarget() == null)
|
||||
SafeGuardAggro(mob);
|
||||
else if (mob.combatTarget.isAlive() == false)
|
||||
else if (mob.getCombatTarget().isAlive() == false)
|
||||
SafeGuardAggro(mob);
|
||||
|
||||
CheckForAttack(mob);
|
||||
@@ -1055,7 +1174,7 @@ public class MobAI {
|
||||
|
||||
//check if mob can attack if it isn't wimpy
|
||||
|
||||
if (!mob.BehaviourType.isWimpy && mob.combatTarget != null)
|
||||
if (!mob.BehaviourType.isWimpy && mob.getCombatTarget() != null)
|
||||
CheckForAttack(mob);
|
||||
|
||||
} catch (Exception e) {
|
||||
@@ -1103,7 +1222,7 @@ public class MobAI {
|
||||
if (GuardCanAggro(mob, loadedPlayer) == false)
|
||||
continue;
|
||||
|
||||
if (MovementUtilities.inRangeToAggro(mob, loadedPlayer)) {
|
||||
if (MovementUtilities.inRangeToAggro(mob, loadedPlayer) && mob.getCombatTarget() == null) {
|
||||
mob.setCombatTarget(loadedPlayer);
|
||||
return;
|
||||
}
|
||||
@@ -1211,13 +1330,6 @@ public class MobAI {
|
||||
//make sure mob is out of combat stance
|
||||
|
||||
if (minion.getKey().despawned == false) {
|
||||
if (minion.getKey().isCombat() && minion.getKey().getCombatTarget() == null) {
|
||||
minion.getKey().setCombat(false);
|
||||
UpdateStateMsg rwss = new UpdateStateMsg();
|
||||
rwss.setPlayer(minion.getKey());
|
||||
DispatchMessage.sendToAllInRange(minion.getKey(), rwss);
|
||||
}
|
||||
|
||||
if (MovementUtilities.canMove(minion.getKey())) {
|
||||
Vector3f minionOffset = Formation.getOffset(2, minion.getValue() + 3);
|
||||
minion.getKey().updateLocation();
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package engine.mobileAI.Threads;
|
||||
|
||||
import engine.gameManager.ConfigManager;
|
||||
import engine.mobileAI.MobAI;
|
||||
import engine.gameManager.ZoneManager;
|
||||
import engine.objects.Mob;
|
||||
import engine.objects.Zone;
|
||||
import engine.server.MBServerStatics;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
public class MobAIThread implements Runnable{
|
||||
@@ -11,7 +13,7 @@ public class MobAIThread implements Runnable{
|
||||
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;
|
||||
public static float AI_CAST_FREQUENCY;
|
||||
// Thread constructor
|
||||
|
||||
public MobAIThread() {
|
||||
@@ -21,6 +23,9 @@ public class MobAIThread implements Runnable{
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
//cache config value for mobile casting delay
|
||||
AI_CAST_FREQUENCY = Float.parseFloat(ConfigManager.MB_AI_CAST_FREQUENCY.getValue());
|
||||
AI_BASE_AGGRO_RANGE = (int)(60 * Float.parseFloat(ConfigManager.MB_AI_AGGRO_RANGE.getValue()));
|
||||
while (true) {
|
||||
for (Zone zone : ZoneManager.getAllZones()) {
|
||||
|
||||
|
||||
@@ -28,6 +28,8 @@ import engine.math.AtomicFloat;
|
||||
import engine.math.Bounds;
|
||||
import engine.math.Vector3fImmutable;
|
||||
import engine.net.ByteBufferWriter;
|
||||
import engine.net.DispatchMessage;
|
||||
import engine.net.client.msg.UpdateStateMsg;
|
||||
import engine.powers.EffectsBase;
|
||||
import engine.server.MBServerStatics;
|
||||
import org.pmw.tinylog.Logger;
|
||||
@@ -1160,6 +1162,23 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
|
||||
}
|
||||
|
||||
public final void setCombatTarget(final AbstractWorldObject value) {
|
||||
if(this.getObjectTypeMask() == 2050) {//MOB?
|
||||
if (value == null) {
|
||||
if (this.isCombat()) {
|
||||
this.setCombat(false);
|
||||
UpdateStateMsg rwss = new UpdateStateMsg();
|
||||
rwss.setPlayer(this);
|
||||
DispatchMessage.sendToAllInRange(this, rwss);
|
||||
}
|
||||
}else {
|
||||
if (!this.isCombat()) {
|
||||
this.setCombat(true);
|
||||
UpdateStateMsg rwss = new UpdateStateMsg();
|
||||
rwss.setPlayer(this);
|
||||
DispatchMessage.sendToAllInRange(this, rwss);
|
||||
}
|
||||
}
|
||||
}
|
||||
this.combatTarget = value;
|
||||
}
|
||||
|
||||
|
||||
+26
-13
@@ -29,6 +29,7 @@ import engine.net.DispatchMessage;
|
||||
import engine.net.client.msg.PetMsg;
|
||||
import engine.net.client.msg.PlaceAssetMsg;
|
||||
import engine.powers.EffectsBase;
|
||||
import engine.powers.MobPowerEntry;
|
||||
import engine.server.MBServerStatics;
|
||||
import org.joda.time.DateTime;
|
||||
import org.pmw.tinylog.Logger;
|
||||
@@ -38,6 +39,7 @@ import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
|
||||
@@ -60,7 +62,7 @@ public class Mob extends AbstractIntelligenceAgent {
|
||||
public boolean despawned = false;
|
||||
public Vector3fImmutable destination = Vector3fImmutable.ZERO;
|
||||
public Vector3fImmutable localLoc = Vector3fImmutable.ZERO;
|
||||
public HashMap<Integer, Integer> mobPowers;
|
||||
public LinkedHashMap<Integer, Integer> mobPowers = new LinkedHashMap<>();
|
||||
public MobBase mobBase;
|
||||
public int spawnTime;
|
||||
public Zone parentZone;
|
||||
@@ -1303,7 +1305,7 @@ public class Mob extends AbstractIntelligenceAgent {
|
||||
} catch (Exception e) {
|
||||
Logger.error(e.getMessage());
|
||||
}
|
||||
this.combatTarget = null;
|
||||
this.setCombatTarget(null);
|
||||
this.hasLoot = false;
|
||||
this.playerAgroMap.clear();
|
||||
|
||||
@@ -1327,7 +1329,7 @@ public class Mob extends AbstractIntelligenceAgent {
|
||||
} else if (this.isPet() || this.isNecroPet()) {
|
||||
//this.state = STATE.Disabled;
|
||||
|
||||
this.combatTarget = null;
|
||||
this.setCombatTarget(null);
|
||||
this.hasLoot = false;
|
||||
|
||||
//if (this.parentZone != null)
|
||||
@@ -1370,7 +1372,7 @@ public class Mob extends AbstractIntelligenceAgent {
|
||||
|
||||
this.combat = false;
|
||||
this.walkMode = true;
|
||||
this.combatTarget = null;
|
||||
this.setCombatTarget(null);
|
||||
|
||||
this.hasLoot = this.charItemManager.getInventoryCount() > 0;
|
||||
} catch (Exception e) {
|
||||
@@ -1389,7 +1391,7 @@ public class Mob extends AbstractIntelligenceAgent {
|
||||
this.mana.set(this.manaMax);
|
||||
this.combat = false;
|
||||
this.walkMode = true;
|
||||
this.combatTarget = null;
|
||||
this.setCombatTarget(null);
|
||||
this.isAlive.set(true);
|
||||
this.deathTime = 0;
|
||||
this.lastBindLoc = this.bindLoc;
|
||||
@@ -1945,24 +1947,35 @@ public class Mob extends AbstractIntelligenceAgent {
|
||||
} catch (Exception e) {
|
||||
Logger.error(e.getMessage());
|
||||
}
|
||||
mobPowers = new HashMap<>();
|
||||
|
||||
// Powers from mobbase
|
||||
|
||||
if (PowersManager.AllMobPowers.containsKey(this.getMobBaseID()))
|
||||
mobPowers = PowersManager.AllMobPowers.get(this.getMobBaseID());
|
||||
for (MobPowerEntry mobPowerEntry : PowersManager.AllMobPowers.get(this.getMobBaseID()))
|
||||
mobPowers.put(mobPowerEntry.token, mobPowerEntry.rank);
|
||||
|
||||
// Powers from contract
|
||||
|
||||
if (this.contract != null && PowersManager.AllMobPowers.containsKey(this.contract.getContractID()))
|
||||
for (MobPowerEntry mobPowerEntry : PowersManager.AllMobPowers.get(this.contract.getContractID()))
|
||||
mobPowers.put(mobPowerEntry.token, mobPowerEntry.rank);
|
||||
|
||||
if (this.equip == null) {
|
||||
Logger.error("Null equipset returned for uuid " + currentID);
|
||||
this.equip = new HashMap<>(0);
|
||||
}
|
||||
|
||||
// Combine mobbase and mob aggro arrays into one bitvector
|
||||
//skip for pets
|
||||
if(this.isPet() == false && this.isSummonedPet() == false && this.isNecroPet() == false) {
|
||||
|
||||
if (this.isPet() == false && this.isSummonedPet() == false && this.isNecroPet() == false) {
|
||||
if (this.getMobBase().notEnemy.size() > 0)
|
||||
this.notEnemy.addAll(this.getMobBase().notEnemy);
|
||||
|
||||
if (this.getMobBase().enemy.size() > 0)
|
||||
this.enemy.addAll(this.getMobBase().enemy);
|
||||
}
|
||||
|
||||
try {
|
||||
NPCManager.applyRuneSetEffects(this);
|
||||
recalculateStats();
|
||||
@@ -1973,6 +1986,7 @@ public class Mob extends AbstractIntelligenceAgent {
|
||||
Bounds mobBounds = Bounds.borrow();
|
||||
mobBounds.setBounds(this.getLoc());
|
||||
this.setBounds(mobBounds);
|
||||
|
||||
if (this.contract != null && this.contract.getContractID() == 910) {
|
||||
this.isPlayerGuard = true;
|
||||
this.BehaviourType = MobBehaviourType.GuardCaptain;
|
||||
@@ -1983,6 +1997,7 @@ public class Mob extends AbstractIntelligenceAgent {
|
||||
|
||||
if (!this.isGuard() && !this.isPlayerGuard() && !this.isPet() && !this.isNecroPet() && !this.isSummonedPet() && !this.isCharmedPet()) {
|
||||
this.patrolPoints = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
float patrolRadius = this.getSpawnRadius();
|
||||
|
||||
@@ -1994,10 +2009,12 @@ public class Mob extends AbstractIntelligenceAgent {
|
||||
|
||||
Vector3fImmutable newPatrolPoint = Vector3fImmutable.getRandomPointInCircle(this.getBindLoc(), patrolRadius);
|
||||
this.patrolPoints.add(newPatrolPoint);
|
||||
|
||||
if (i == 1)
|
||||
MovementManager.translocate(this, newPatrolPoint, null);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.BehaviourType == null)
|
||||
this.BehaviourType = this.getMobBase().fsm;
|
||||
|
||||
@@ -2042,10 +2059,6 @@ public class Mob extends AbstractIntelligenceAgent {
|
||||
this.isSiege = isSiege;
|
||||
}
|
||||
|
||||
public long getTimeToSpawnSiege() {
|
||||
return timeToSpawnSiege;
|
||||
}
|
||||
|
||||
public void setTimeToSpawnSiege(long timeToSpawnSiege) {
|
||||
this.timeToSpawnSiege = timeToSpawnSiege;
|
||||
}
|
||||
@@ -2066,7 +2079,7 @@ public class Mob extends AbstractIntelligenceAgent {
|
||||
PlayerCharacter player = (PlayerCharacter) ac;
|
||||
|
||||
if (this.getCombatTarget() == null) {
|
||||
this.combatTarget = ac;
|
||||
this.setCombatTarget(ac);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ package engine.objects;
|
||||
import ch.claude_martin.enumbitset.EnumBitSet;
|
||||
import engine.Enum;
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.gameManager.NPCManager;
|
||||
import engine.gameManager.LootManager;
|
||||
import engine.loot.BootySetEntry;
|
||||
import engine.server.MBServerStatics;
|
||||
|
||||
@@ -119,7 +119,7 @@ public class MobBase extends AbstractGameObject {
|
||||
if (equipmentSetID == 0)
|
||||
return equip;
|
||||
|
||||
equipList = NPCManager._bootySetMap.get(equipmentSetID);
|
||||
equipList = LootManager._bootySetMap.get(equipmentSetID);
|
||||
|
||||
if (equipList == null)
|
||||
return equip;
|
||||
|
||||
@@ -617,7 +617,7 @@ public class NPC extends AbstractCharacter {
|
||||
|
||||
public static boolean UpdateEquipSetID(NPC npc, int equipSetID) {
|
||||
|
||||
if (!NPCManager._bootySetMap.containsKey(equipSetID))
|
||||
if (!LootManager._bootySetMap.containsKey(equipSetID))
|
||||
return false;
|
||||
|
||||
if (!DbManager.NPCQueries.UPDATE_EQUIPSET(npc, equipSetID))
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package engine.powers;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
public class MobPowerEntry {
|
||||
|
||||
public int token;
|
||||
public int rank;
|
||||
|
||||
|
||||
public MobPowerEntry(ResultSet rs) throws SQLException {
|
||||
this.token = rs.getInt("token");
|
||||
this.rank = rs.getInt("rank");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -333,8 +333,8 @@ public class WorldServer {
|
||||
Logger.info("Loading NPC and Mob Rune Sets");
|
||||
NPCManager.LoadAllRuneSets();
|
||||
|
||||
Logger.info("Loading Mobile Booty Sets");
|
||||
NPCManager.LoadAllBootySets();
|
||||
Logger.info("Loading Booty Sets");
|
||||
LootManager._bootySetMap = DbManager.LootQueries.LOAD_BOOTY_TABLES();
|
||||
|
||||
// Load new loot system
|
||||
Logger.info("Initializing Loot Manager");
|
||||
@@ -348,8 +348,8 @@ public class WorldServer {
|
||||
Logger.info("Loading MobBases.");
|
||||
DbManager.MobBaseQueries.GET_ALL_MOBBASES();
|
||||
|
||||
Logger.info("Loading Mob Powers for MobBases");
|
||||
PowersManager.LoadAllMobPowers();
|
||||
Logger.info("Loading Mob Powers");
|
||||
PowersManager.AllMobPowers = DbManager.PowerQueries.LOAD_MOB_POWERS();
|
||||
|
||||
Logger.info("Loading item enchants");
|
||||
DbManager.LootQueries.LOAD_ENCHANT_VALUES();
|
||||
|
||||
Reference in New Issue
Block a user