Compare commits

..

8 Commits

Author SHA1 Message Date
byronhb 221ae0a58b Fixes for /mob, /npc, and /equipset commands. 2025-11-10 21:14:28 -06:00
MagicBot 3649c629b7 Revert "DamageType defined as in JSON"
This reverts commit 1c31070fc8.
2024-04-01 12:04:12 -04:00
MagicBot 1c31070fc8 DamageType defined as in JSON 2024-04-01 12:01:59 -04:00
MagicBot bff41967db Revert "Out of combat mode when patrolling."
This reverts commit d3692d0fb7.
2023-09-08 13:07:15 -04:00
MagicBot d3692d0fb7 Out of combat mode when patrolling. 2023-09-08 13:04:29 -04:00
FatBoy 074a799d01 added health recovery to mobs 2023-08-22 20:58:52 -05:00
FatBoy 36ffd08a72 guard minions logic work 2023-08-22 20:52:45 -05:00
FatBoy 58f828b3cd items removed properly from inventory, NPCs nop longer stock base items 2023-08-22 20:52:26 -05:00
52 changed files with 2473 additions and 2073 deletions
+9 -11
View File
@@ -2822,6 +2822,7 @@ public class Enum {
public enum MobBehaviourType {
None(null, false, false, false, false, false),
//Power
Power(null, false, true, true, true, false),
PowerHelpee(Power, false, true, true, false, true),
PowerHelpeeWimpy(Power, true, false, true, false, false),
@@ -2846,7 +2847,6 @@ public class Enum {
//Independent Types
SimpleStandingGuard(null, false, false, false, false, false),
Pet1(null, false, false, true, false, false),
SiegeEngine(null, false, false, false, false, false),
Simple(null, false, false, true, false, false),
Helpee(null, false, true, true, false, true),
HelpeeWimpy(null, true, false, true, false, false),
@@ -2857,12 +2857,13 @@ public class Enum {
HamletGuard(null, false, true, false, false, false),
AggroWanderer(null, false, false, true, false, false);
public final MobBehaviourType BehaviourHelperType;
public final boolean isWimpy;
public final boolean isAgressive;
public final boolean canRoam;
public final boolean callsForHelp;
public final boolean respondsToCallForHelp;
private static HashMap<Integer, MobBehaviourType> _behaviourTypes = new HashMap<>();
public MobBehaviourType BehaviourHelperType;
public boolean isWimpy;
public boolean isAgressive;
public boolean canRoam;
public boolean callsForHelp;
public boolean respondsToCallForHelp;
MobBehaviourType(MobBehaviourType helpeebehaviourType, boolean wimpy, boolean agressive, boolean canroam, boolean callsforhelp, boolean respondstocallforhelp) {
this.BehaviourHelperType = helpeebehaviourType;
@@ -2877,11 +2878,8 @@ public class Enum {
public enum AIAgentType {
MOBILE,
GUARDCAPTAIN,
GUARDMINION,
GUARDWALLARCHER,
PET,
CHARMED,
SIEGEENGINE;
GUARD;
}
}
@@ -140,7 +140,7 @@ public enum InterestManager implements Runnable {
else {
if (pc != null)
if (pcc.getSeeInvis() < pc.hidden)
if (pcc.getSeeInvis() < pc.getHidden())
continue;
if (!cc.sendMsg(uom)) {
@@ -340,7 +340,7 @@ public enum InterestManager implements Runnable {
if (loadedPlayer.getObjectUUID() == player.getObjectUUID())
continue;
if (player.getSeeInvis() < loadedPlayer.hidden)
if (player.getSeeInvis() < loadedPlayer.getHidden())
continue;
if (loadedPlayer.safemodeInvis())
@@ -372,7 +372,7 @@ public enum InterestManager implements Runnable {
if (playerLoadedObject.getObjectType().equals(GameObjectType.PlayerCharacter)) {
PlayerCharacter loadedPlayer = (PlayerCharacter) playerLoadedObject;
if (player.getSeeInvis() < loadedPlayer.hidden)
if (player.getSeeInvis() < loadedPlayer.getHidden())
toRemove.add(playerLoadedObject);
else if (loadedPlayer.safemodeInvis())
toRemove.add(playerLoadedObject);
@@ -437,7 +437,7 @@ public enum InterestManager implements Runnable {
// dont load if invis
if (player.getSeeInvis() < awopc.hidden)
if (player.getSeeInvis() < awopc.getHidden())
continue;
lcm = new LoadCharacterMsg(awopc, PlayerCharacter.hideNonAscii());
@@ -467,7 +467,7 @@ public enum InterestManager implements Runnable {
if (awonpc.despawned == true)
continue;
awonpc.playerAgroMap.put(player.getObjectUUID(), 0f);
awonpc.playerAgroMap.put(player.getObjectUUID(), false);
((Mob) awonpc).setCombatTarget(null);
lcm = new LoadCharacterMsg(awonpc, PlayerCharacter.hideNonAscii());
@@ -480,7 +480,7 @@ public enum InterestManager implements Runnable {
if (!awonpc.isAlive())
continue;
awonpc.playerAgroMap.put(player.getObjectUUID(), 0f);
awonpc.playerAgroMap.put(player.getObjectUUID(), false);
if ((awonpc.agentType.equals(Enum.AIAgentType.MOBILE)))
((Mob) awonpc).setCombatTarget(null);
+32 -39
View File
@@ -28,27 +28,31 @@ public class dbMobHandler extends dbHandlerBase {
this.localObjectType = engine.Enum.GameObjectType.valueOf(this.localClass.getSimpleName());
}
public Mob PERSIST(Mob toAdd) {
public Mob ADD_MOB(Mob toAdd) {
Mob mobile = null;
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("CALL `mob_CREATE`(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);")) {
PreparedStatement preparedStatement = connection.prepareStatement("CALL `mob_CREATE`(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);")) {
preparedStatement.setLong(1, toAdd.parentZoneUUID);
preparedStatement.setInt(2, toAdd.loadID);
preparedStatement.setInt(3, toAdd.guildUUID);
preparedStatement.setFloat(4, toAdd.bindLoc.x);
preparedStatement.setFloat(5, toAdd.bindLoc.y);
preparedStatement.setFloat(6, toAdd.bindLoc.z);
preparedStatement.setLong(1, toAdd.getParentZoneID());
preparedStatement.setInt(2, toAdd.getMobBaseID());
preparedStatement.setInt(3, toAdd.getGuildUUID());
preparedStatement.setFloat(4, toAdd.getSpawnX());
preparedStatement.setFloat(5, toAdd.getSpawnY());
preparedStatement.setFloat(6, toAdd.getSpawnZ());
preparedStatement.setInt(7, 0);
preparedStatement.setFloat(8, toAdd.spawnRadius);
preparedStatement.setInt(9, toAdd.spawnTime);
preparedStatement.setInt(10, toAdd.contractUUID);
preparedStatement.setInt(11, toAdd.buildingUUID);
preparedStatement.setInt(12, toAdd.level);
preparedStatement.setString(13, toAdd.firstName);
preparedStatement.setString(14, toAdd.behaviourType.toString());
preparedStatement.setFloat(8, toAdd.getSpawnRadius());
preparedStatement.setInt(9, toAdd.getTrueSpawnTime());
if (toAdd.getContract() != null)
preparedStatement.setInt(10, toAdd.getContract().getContractID());
else
preparedStatement.setInt(10, 0);
preparedStatement.setInt(11, toAdd.getBuildingID());
preparedStatement.setInt(12, toAdd.getLevel());
preparedStatement.setString(13, toAdd.getFirstName());
ResultSet rs = preparedStatement.executeQuery();
@@ -102,17 +106,17 @@ public class dbMobHandler extends dbHandlerBase {
return row_count;
}
public void LOAD_GUARD_MINIONS(Mob guardCaptain) {
public void LOAD_PATROL_POINTS(Mob captain) {
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `dyn_guards` WHERE `captainUID` = ?")) {
preparedStatement.setInt(1, guardCaptain.getObjectUUID());
preparedStatement.setInt(1, captain.getObjectUUID());
ResultSet rs = preparedStatement.executeQuery();
while (rs.next()) {
String minionName = rs.getString("minionName");
Mob toCreate = Mob.createGuardMinion(guardCaptain, guardCaptain.getLevel(), minionName);
String name = rs.getString("name");
Mob toCreate = Mob.createGuardMob(captain, captain.getGuild(), captain.getParentZone(), captain.building.getLoc(), captain.getLevel(), name);
if (toCreate == null)
return;
@@ -127,13 +131,15 @@ public class dbMobHandler extends dbHandlerBase {
}
}
public boolean ADD_GUARD_MINION(final long captainUID, final String minionName) {
public boolean ADD_TO_GUARDS(final long captainUID, final int mobBaseID, final String name, final int slot) {
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("INSERT INTO `dyn_guards` (`captainUID`, `minionName`) VALUES (?,?)")) {
PreparedStatement preparedStatement = connection.prepareStatement("INSERT INTO `dyn_guards` (`captainUID`, `mobBaseID`,`name`, `slot`) VALUES (?,?,?,?)")) {
preparedStatement.setLong(1, captainUID);
preparedStatement.setString(2, minionName);
preparedStatement.setInt(2, mobBaseID);
preparedStatement.setString(3, name);
preparedStatement.setInt(4, slot);
return (preparedStatement.executeUpdate() > 0);
@@ -143,13 +149,14 @@ public class dbMobHandler extends dbHandlerBase {
}
}
public boolean REMOVE_GUARD_MINION(final long captainUID, final String minionName) {
public boolean REMOVE_FROM_GUARDS(final long captainUID, final int mobBaseID, final int slot) {
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("DELETE FROM `dyn_guards` WHERE `captainUID`=? AND `minionName`=? LIMIT 1;")) {
PreparedStatement preparedStatement = connection.prepareStatement("DELETE FROM `dyn_guards` WHERE `captainUID`=? AND `mobBaseID`=? AND `slot` =?")) {
preparedStatement.setLong(1, captainUID);
preparedStatement.setString(2, minionName);
preparedStatement.setInt(2, mobBaseID);
preparedStatement.setInt(3, slot);
return (preparedStatement.executeUpdate() > 0);
@@ -159,20 +166,6 @@ public class dbMobHandler extends dbHandlerBase {
}
}
public boolean REMOVE_ALL_MINIONS(final long captainUID) {
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("DELETE FROM `dyn_guards` WHERE `captainUID`=?;")) {
preparedStatement.setLong(1, captainUID);
return (preparedStatement.executeUpdate() > 0);
} catch (SQLException e) {
Logger.error(e);
return false;
}
}
public ArrayList<Mob> GET_ALL_MOBS_FOR_ZONE(Zone zone) {
+5 -1
View File
@@ -243,8 +243,12 @@ public class dbNPCHandler extends dbHandlerBase {
public boolean UPDATE_EQUIPSET(NPC npc, int equipSetID) {
// Column name must match what NPC/Mob loaders read ("equipmentSet").
// Using the wrong column here causes the update to fail silently and
// dev command to report "Unable to find Equipset" despite a valid ID.
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE `obj_npc` SET `equipsetID`=? WHERE `UID`=?")) {
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE `obj_npc` SET `equipmentSet`=? WHERE `UID`=?")) {
preparedStatement.setInt(1, equipSetID);
preparedStatement.setLong(2, npc.getObjectUUID());
@@ -15,9 +15,15 @@ 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 {
@@ -80,4 +86,43 @@ public class dbPowerHandler extends dbHandlerBase {
}
}
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;
}
}
@@ -11,8 +11,6 @@ package engine.db.handlers;
import engine.gameManager.DbManager;
import engine.objects.RuneBase;
import engine.powers.RunePowerEntry;
import engine.powers.RuneSkillAdjustEntry;
import org.pmw.tinylog.Logger;
import java.sql.Connection;
@@ -29,84 +27,6 @@ public class dbRuneBaseHandler extends dbHandlerBase {
this.localObjectType = engine.Enum.GameObjectType.valueOf(this.localClass.getSimpleName());
}
public static HashMap<Integer, ArrayList<RunePowerEntry>> LOAD_RUNE_POWERS() {
HashMap<Integer, ArrayList<RunePowerEntry>> mobPowers = new HashMap<>();
RunePowerEntry runePowerEntry;
int rune_id;
int recordsRead = 0;
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM static_rune_powers")) {
ResultSet rs = preparedStatement.executeQuery();
while (rs.next()) {
recordsRead++;
rune_id = rs.getInt("rune_id");
runePowerEntry = new RunePowerEntry(rs);
if (mobPowers.get(rune_id) == null) {
ArrayList<RunePowerEntry> runePowerList = new ArrayList<>();
runePowerList.add(runePowerEntry);
mobPowers.put(rune_id, runePowerList);
} else {
ArrayList<RunePowerEntry> powerList = mobPowers.get(rune_id);
powerList.add(runePowerEntry);
mobPowers.put(rune_id, powerList);
}
}
} catch (SQLException e) {
Logger.error(e);
return mobPowers;
}
Logger.info("read: " + recordsRead + " cached: " + mobPowers.size());
return mobPowers;
}
public static HashMap<Integer, ArrayList<RuneSkillAdjustEntry>> LOAD_RUNE_SKILL_ADJUSTS() {
HashMap<Integer, ArrayList<RuneSkillAdjustEntry>> runeSkillAdjusts = new HashMap<>();
RuneSkillAdjustEntry runeSkillAdjustEntry;
int rune_id;
int recordsRead = 0;
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM static_rune_skill_adjusts")) {
ResultSet rs = preparedStatement.executeQuery();
while (rs.next()) {
recordsRead++;
rune_id = rs.getInt("rune_id");
runeSkillAdjustEntry = new RuneSkillAdjustEntry(rs);
if (runeSkillAdjusts.get(rune_id) == null) {
ArrayList<RuneSkillAdjustEntry> skillAdjustList = new ArrayList<>();
skillAdjustList.add(runeSkillAdjustEntry);
runeSkillAdjusts.put(rune_id, skillAdjustList);
} else {
ArrayList<RuneSkillAdjustEntry> powerList = runeSkillAdjusts.get(rune_id);
powerList.add(runeSkillAdjustEntry);
runeSkillAdjusts.put(rune_id, powerList);
}
}
} catch (SQLException e) {
Logger.error(e);
return runeSkillAdjusts;
}
Logger.info("read: " + recordsRead + " cached: " + runeSkillAdjusts.size());
return runeSkillAdjusts;
}
public void GET_RUNE_REQS(final RuneBase rb) {
try (Connection connection = DbManager.getConnection();
+2 -3
View File
@@ -9,7 +9,6 @@
package engine.devcmd.cmds;
import engine.Enum;
import engine.Enum.GameObjectType;
import engine.devcmd.AbstractDevCmd;
import engine.gameManager.ChatManager;
@@ -44,7 +43,7 @@ public class AddMobCmd extends AbstractDevCmd {
MobBase mb = (MobBase) mobbaseAGO;
int loadID = mb.getObjectUUID();
Mob mob = Mob.createMob(loadID, Vector3fImmutable.getRandomPointInCircle(pc.getLoc(), 100),
null, zone, null, null, "", 1, Enum.AIAgentType.MOBILE);
null, true, zone, null, 0, "", 1);
if (mob != null) {
mob.updateDatabase();
this.setResult(String.valueOf(mob.getDBID()));
@@ -85,7 +84,7 @@ public class AddMobCmd extends AbstractDevCmd {
Mob mob = Mob.createMob(loadID, pc.getLoc(),
null, zone, null, null, "", 1, Enum.AIAgentType.MOBILE);
null, true, zone, null, 0, "", 1);
if (mob != null) {
mob.updateDatabase();
ChatManager.chatSayInfo(pc,
+1 -3
View File
@@ -440,9 +440,7 @@ public class InfoCmd extends AbstractDevCmd {
output += "isSummonedPet: true";
else
output += "isSummonedPet: false";
PlayerCharacter owner = (PlayerCharacter) targetMob.guardCaptain;
PlayerCharacter owner = targetMob.getOwner();
if (owner != null)
output += " owner: " + owner.getObjectUUID();
output += newline;
+9 -13
View File
@@ -103,19 +103,15 @@ public class PrintStatsCmd extends AbstractDevCmd {
main = getWeaponBase(1, equip);
ItemBase off = null;
if(equip != null){
if(equip.get(2) != null && !equip.get(2).getItemBase().isShield()){
//off hand weapon
out += "Attack Rating: " + tar.atrHandTwo + newline;
out += "Damage: " + tar.minDamageHandTwo + " - " + tar.maxDamageHandTwo + newline;
out += "Range: " + tar.rangeHandTwo + newline;
out += "Attack Speed: " + tar.speedHandTwo + newline;
} else{
out += "Attack Rating: " + tar.atrHandOne + newline;
out += "Damage: " + tar.minDamageHandOne + " - " + tar.maxDamageHandOne + newline;
out += "Range: " + tar.rangeHandOne + newline;
out += "Attack Speed: " + tar.speedHandOne + newline;
}
if (equip != null)
getWeaponBase(2, equip);
if (main == null && off == null) {
out += "Main Hand: atr: " + tar.getAtrHandOne() + ", damage: " + tar.getMinDamageHandOne() + " to " + tar.getMaxDamageHandOne() + ", speed: " + tar.getSpeedHandOne() + ", range: 6" + newline;
} else {
if (main != null)
out += "Main Hand: atr: " + tar.getAtrHandOne() + ", damage: " + tar.getMinDamageHandOne() + " to " + tar.getMaxDamageHandOne() + ", speed: " + tar.getSpeedHandOne() + ", range: " + main.getRange() + newline;
if (off != null)
out += "Main Hand: atr: " + tar.getAtrHandTwo() + ", damage: " + tar.getMinDamageHandTwo() + " to " + tar.getMaxDamageHandTwo() + ", speed: " + tar.getSpeedHandTwo() + ", range: " + off.getRange() + newline;
}
out += "isAlive: " + tar.isAlive() + ", Combat: " + tar.isCombat() + newline;
+8 -13
View File
@@ -59,25 +59,22 @@ public class PurgeObjectsCmd extends AbstractDevCmd {
if (npc != null) {
for (Integer minionUUID : npc.minions) {
Mob mob = Mob.getMob(minionUUID);
for (Mob mob : npc.getSiegeMinionMap().keySet()) {
WorldGrid.RemoveWorldObject(mob);
WorldGrid.removeObject(mob, pc);
//Mob.getRespawnMap().remove(mob);
if (mob.getParentZone() != null)
mob.getParentZone().zoneMobSet.remove(mob);
}
DbManager.NPCQueries.DELETE_NPC(npc);
DbManager.removeFromCache(GameObjectType.NPC,
npc.getObjectUUID());
WorldGrid.RemoveWorldObject(npc);
} else if (mobA != null) {
for (Integer minionUUID : mobA.minions) {
Mob mob = Mob.getMob(minionUUID);
for (Mob mob : mobA.getSiegeMinionMap().keySet()) {
WorldGrid.RemoveWorldObject(mob);
WorldGrid.removeObject(mob, pc);
//Mob.getRespawnMap().remove(mob);
if (mob.getParentZone() != null)
mob.getParentZone().zoneMobSet.remove(mob);
}
@@ -154,11 +151,10 @@ public class PurgeObjectsCmd extends AbstractDevCmd {
if (npc != null) {
for (Integer minionUUID : npc.minions) {
Mob mob = Mob.getMob(minionUUID);
for (Mob mob : npc.getSiegeMinionMap().keySet()) {
WorldGrid.RemoveWorldObject(mob);
WorldGrid.removeObject(mob, pc);
//Mob.getRespawnMap().remove(mob);
if (mob.getParentZone() != null)
mob.getParentZone().zoneMobSet.remove(mob);
}
@@ -167,11 +163,10 @@ public class PurgeObjectsCmd extends AbstractDevCmd {
npc.getObjectUUID());
WorldGrid.RemoveWorldObject(npc);
} else if (mobA != null) {
for (Integer minionUUID : mobA.minions) {
Mob mob = Mob.getMob(minionUUID);
for (Mob mob : mobA.getSiegeMinionMap().keySet()) {
WorldGrid.RemoveWorldObject(mob);
WorldGrid.removeObject(mob, pc);
//Mob.getRespawnMap().remove(mob);
if (mob.getParentZone() != null)
mob.getParentZone().zoneMobSet.remove(mob);
}
+42 -10
View File
@@ -11,6 +11,7 @@ package engine.devcmd.cmds;
import engine.Enum.BuildingGroup;
import engine.Enum.DbObjectType;
import engine.Enum.GameObjectType;
import engine.InterestManagement.WorldGrid;
import engine.devcmd.AbstractDevCmd;
import engine.gameManager.BuildingManager;
@@ -137,16 +138,49 @@ public class RemoveObjectCmd extends AbstractDevCmd {
Warehouse.warehouseByBuildingUUID.remove(building.getObjectUUID());
}
//remove cached shrines.
if ((building.getBlueprintUUID() != 0)
&& (building.getBlueprint().getBuildingGroup() == BuildingGroup.SHRINE))
Shrine.RemoveShrineFromCacheByBuilding(building);
// Remove hirelings for this building
for (AbstractCharacter ac : building.getHirelings().keySet()) {
NPC npc = null;
Mob mobA = null;
for (AbstractCharacter abstractCharacter : building.getHirelings().keySet())
BuildingManager.removeHireling(building, abstractCharacter);
if (ac.getObjectType() == GameObjectType.NPC)
npc = (NPC) ac;
else if (ac.getObjectType() == GameObjectType.Mob)
mobA = (Mob) ac;
if (npc != null) {
for (Mob mob : npc.getSiegeMinionMap().keySet()) {
WorldGrid.RemoveWorldObject(mob);
WorldGrid.removeObject(mob, pc);
//Mob.getRespawnMap().remove(mob);
if (mob.getParentZone() != null)
mob.getParentZone().zoneMobSet.remove(mob);
}
DbManager.NPCQueries.DELETE_NPC(npc);
DbManager.removeFromCache(npc);
WorldGrid.RemoveWorldObject(npc);
WorldGrid.removeObject(npc, pc);
} else if (mobA != null) {
for (Mob mob : mobA.getSiegeMinionMap().keySet()) {
WorldGrid.RemoveWorldObject(mob);
WorldGrid.removeObject(mob, pc);
//Mob.getRespawnMap().remove(mob);
if (mob.getParentZone() != null)
mob.getParentZone().zoneMobSet.remove(mob);
}
DbManager.MobQueries.DELETE_MOB(mobA);
DbManager.removeFromCache(mobA);
WorldGrid.RemoveWorldObject(mobA);
WorldGrid.removeObject(mobA, pc);
}
}
Zone zone = building.getParentZone();
DbManager.BuildingQueries.DELETE_FROM_DATABASE(building);
DbManager.removeFromCache(building);
@@ -175,13 +209,11 @@ public class RemoveObjectCmd extends AbstractDevCmd {
if (npc.building != null)
npc.building.getHirelings().remove(npc);
for (Integer minionUUID : npc.minions) {
Mob minionMob = Mob.getMob(minionUUID);
WorldGrid.RemoveWorldObject(minionMob);
WorldGrid.removeObject(minionMob, pc);
if (minionMob.getParentZone() != null)
minionMob.getParentZone().zoneMobSet.remove(minionMob);
for (Mob mob : npc.getSiegeMinionMap().keySet()) {
WorldGrid.RemoveWorldObject(mob);
WorldGrid.removeObject(mob, pc);
if (mob.getParentZone() != null)
mob.getParentZone().zoneMobSet.remove(mob);
}
DbManager.NPCQueries.DELETE_NPC(npc);
+1 -1
View File
@@ -159,7 +159,7 @@ public class SetSubRaceCmd extends AbstractDevCmd {
// pum.setEffectID(token);
// pum.setSourceType(pc.getObjectType().ordinal());
// pum.setSourceID(pc.getObjectUUID());
// pum.setStartLocType(pc.getObjectType().ordinal());
// pum.setTargetType(pc.getObjectType().ordinal());
// pum.setTargetID(pc.getObjectUUID());
// pum.setNumTrains(40);
// pum.setDuration(-1);
+1 -2
View File
@@ -1,6 +1,5 @@
package engine.devcmd.cmds;
import engine.Enum;
import engine.devcmd.AbstractDevCmd;
import engine.gameManager.ZoneManager;
import engine.math.Vector3fImmutable;
@@ -111,7 +110,7 @@ public class SplatMobCmd extends AbstractDevCmd {
mobile = Mob.createMob(_mobileUUID,
Vector3fImmutable.getRandomPointInCircle(_currentLocation, _targetRange),
null, serverZone, null, null, "", 1, Enum.AIAgentType.MOBILE);
null, true, serverZone, null, 0, "", 1);
if (mobile != null) {
mobile.updateDatabase();
+13 -77
View File
@@ -9,17 +9,12 @@
package engine.devcmd.cmds;
import engine.Enum;
import engine.Enum.GameObjectType;
import engine.devcmd.AbstractDevCmd;
import engine.gameManager.PowersManager;
import engine.mobileAI.MobAI;
import engine.objects.AbstractGameObject;
import engine.objects.Mob;
import engine.objects.PlayerCharacter;
import engine.powers.RunePowerEntry;
import java.util.ArrayList;
import java.util.Map;
@@ -61,39 +56,18 @@ public class aiInfoCmd extends AbstractDevCmd {
Mob mob = (Mob) target;
output = "Mob AI Information:" + newline;
output += mob.getName() + newline;
output += mob.agentType.toString() + newline;
int contractID = 0;
if (mob.isPlayerGuard() == true) {
if (mob.agentType.equals(Enum.AIAgentType.GUARDMINION))
contractID = mob.guardCaptain.contract.getContractID();
else
contractID = mob.contract.getContractID();
}
if (contractID != 0) {
if (mob.agentType.equals(Enum.AIAgentType.GUARDMINION)) {
output += "Captain Contract: " + contractID + newline;
output += "Captain UUID: " + mob.guardCaptain.getObjectUUID() + newline;
} else
output += "Contract: " + contractID + 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;
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;
output += "Can Roam: " + mob.behaviourType.canRoam + newline;
output += "Calls For Help: " + mob.behaviourType.callsForHelp + newline;
output += "Responds To Call For Help: " + mob.behaviourType.respondsToCallForHelp + newline;
output += "Wimpy: " + mob.BehaviourType.isWimpy + newline;
output += "Agressive: " + mob.BehaviourType.isAgressive + newline;
output += "Can Roam: " + mob.BehaviourType.canRoam + newline;
output += "Calls For Help: " + mob.BehaviourType.callsForHelp + newline;
output += "Responds To Call For Help: " + mob.BehaviourType.respondsToCallForHelp + newline;
} else {
output += "BehaviourType: NULL" + newline;
}
@@ -102,54 +76,16 @@ public class aiInfoCmd extends AbstractDevCmd {
if (mob.playerAgroMap.size() > 0) {
output += "Players Loaded:" + newline;
}
for (Map.Entry<Integer, Float> entry : mob.playerAgroMap.entrySet()) {
output += "Player ID: " + entry.getKey() + " Hate Value: " + entry.getValue() + newline;
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;
if (mob.guardedCity != null)
output += "Patrolling: " + mob.guardedCity.getCityName() + newline;
output += "See Invis Level: " + mob.mobBase.getSeeInvis() + newline;
output += "Can Cast: " + MobAI.canCast(mob) + newline;
output += "Powers:" + newline;
ArrayList<RunePowerEntry> powerEntries = new ArrayList<>(PowersManager.getPowersForRune(mob.getMobBaseID()));
// Additional powers may come from the contract ID. This is to support
// powers for player guards irrespective of the mobbase used.
if (mob.isPlayerGuard()) {
ArrayList<RunePowerEntry> contractEntries = new ArrayList<>();
if (mob.contract != null)
contractEntries = new ArrayList<>(PowersManager.getPowersForRune(mob.contractUUID));
if (mob.agentType.equals(Enum.AIAgentType.GUARDMINION))
contractEntries = new ArrayList<>(PowersManager.getPowersForRune(mob.guardCaptain.contractUUID));
powerEntries.addAll(contractEntries);
}
for (RunePowerEntry runePowerEntry : powerEntries)
output += PowersManager.getPowerByToken(runePowerEntry.token).getName() + newline;
// List outlaws defined for this player guard's city
if (mob.isPlayerGuard()) {
ArrayList<Integer> outlaws = new ArrayList(mob.guardedCity.cityOutlaws);
if (outlaws.isEmpty() == false)
output += "Outlaws: " + newline;
for (Integer outlawUUID : outlaws)
output += outlawUUID + newline;
}
for (int token : mob.mobPowers.keySet())
output += token + newline;
throwbackInfo(playerCharacter, output);
}
+38 -102
View File
@@ -308,72 +308,6 @@ public enum BuildingManager {
}
public static void removeHireling(Building building, AbstractCharacter hireling) {
if (hireling.getObjectType().equals(GameObjectType.Mob)) {
Mob guardCaptain = (Mob) hireling;
// Clear minions from database if a guard captain
if (guardCaptain.agentType.equals(Enum.AIAgentType.GUARDCAPTAIN))
DbManager.MobQueries.REMOVE_ALL_MINIONS(hireling.getObjectUUID());
}
// Clear minions from world
for (Integer minionUUID : hireling.minions) {
Mob minionMob = Mob.getMob(minionUUID);
DbManager.removeFromCache(minionMob);
WorldGrid.RemoveWorldObject(minionMob);
WorldGrid.unloadObject(minionMob);
if (minionMob.getParentZone() != null)
minionMob.getParentZone().zoneMobSet.remove(minionMob);
}
// Remove hireling from building
building.getHirelings().remove(hireling);
// Remove from zone mob set
if (hireling.getObjectType().equals(GameObjectType.Mob)) {
Mob hirelingMob = (Mob) hireling;
if (hirelingMob.getParentZone() != null)
if (hirelingMob.getParentZone().zoneMobSet.contains(hirelingMob))
hirelingMob.getParentZone().zoneMobSet.remove(hireling);
}
if (hireling.getObjectType().equals(GameObjectType.NPC)) {
NPC hirelingNPC = (NPC) hireling;
if (hirelingNPC.getParentZone() != null)
if (hirelingNPC.getParentZone().zoneNPCSet.contains(hirelingNPC))
hirelingNPC.getParentZone().zoneNPCSet.remove(hireling);
}
// Unload hireling from world
DbManager.removeFromCache(hireling);
WorldGrid.RemoveWorldObject(hireling);
WorldGrid.removeObject(hireling);
// Delete hireling from database
if (hireling.getObjectType().equals(GameObjectType.Mob))
DbManager.MobQueries.DELETE_MOB((Mob) hireling);
else
DbManager.NPCQueries.DELETE_NPC((NPC) hireling);
}
public static void cleanupHirelings(Building building) {
// Early exit: Cannot have hirelings in a building
@@ -386,18 +320,42 @@ public enum BuildingManager {
if (building.getRank() < 1) {
for (AbstractCharacter slottedNPC : building.getHirelings().keySet())
BuildingManager.removeHireling(building, slottedNPC);
for (AbstractCharacter slottedNPC : building.getHirelings().keySet()) {
if (slottedNPC.getObjectType() == Enum.GameObjectType.NPC)
((NPC) slottedNPC).remove();
else if (slottedNPC.getObjectType() == Enum.GameObjectType.Mob)
NPCManager.removeMobileFromBuilding(((Mob) slottedNPC), building);
}
return;
}
// Delete hireling if building has deranked.
for (AbstractCharacter hireling : building.getHirelings().keySet()) {
NPC npc = null;
Mob mob = null;
if (hireling.getObjectType() == Enum.GameObjectType.NPC)
npc = (NPC) hireling;
else if (hireling.getObjectType() == Enum.GameObjectType.Mob)
mob = (Mob) hireling;
if (building.getHirelings().get(hireling) > building.getBlueprint().getSlotsForRank(building.getRank()))
BuildingManager.removeHireling(building, hireling);
if (npc != null) {
if (!npc.remove())
Logger.error("Failed to remove npc " + npc.getObjectUUID()
+ "from Building " + building.getObjectUUID());
else
building.getHirelings().remove(npc);
} else if (mob != null) {
if (!NPCManager.removeMobileFromBuilding(mob, building))
Logger.error("Failed to remove npc " + npc.getObjectUUID()
+ "from Building " + building.getObjectUUID());
else
building.getHirelings().remove(npc);
}
}
@@ -572,63 +530,41 @@ public enum BuildingManager {
else
rank = 10;
Mob mobile;
Mob mob;
NPC npc;
if (NPC.ISWallArcher(contract)) {
mobile = Mob.createMob(contract.getMobbaseID(), Vector3fImmutable.ZERO, contractOwner.getGuild(), zone, building, contract, pirateName, rank, Enum.AIAgentType.GUARDWALLARCHER);
mob = Mob.createMob(contract.getMobbaseID(), Vector3fImmutable.ZERO, contractOwner.getGuild(), true, zone, building, contract.getContractID(), pirateName, rank);
if (mobile == null)
if (mob == null)
return false;
// Configure AI and write new mobile to disk
mobile.behaviourType = Enum.MobBehaviourType.GuardWallArcher;
mobile = DbManager.MobQueries.PERSIST(mobile);
// Spawn new mobile
mobile.setLoc(mobile.getLoc());
mob.setLoc(mob.getLoc());
return true;
}
if (NPC.ISGuardCaptain(contract.getContractID())) {
mobile = Mob.createMob(contract.getMobbaseID(), Vector3fImmutable.ZERO, contractOwner.getGuild(), zone, building, contract, pirateName, rank, Enum.AIAgentType.GUARDCAPTAIN);
mob = Mob.createMob(contract.getMobbaseID(), Vector3fImmutable.ZERO, contractOwner.getGuild(), true, zone, building, contract.getContractID(), pirateName, rank);
if (mobile == null)
if (mob == null)
return false;
// Configure AI and write new mobile to disk
mobile.behaviourType = Enum.MobBehaviourType.GuardCaptain;
mobile = DbManager.MobQueries.PERSIST(mobile);
// Spawn new mobile
mobile.setLoc(mobile.getLoc());
mob.setLoc(mob.getLoc());
return true;
}
if (contract.getContractID() == 910) {
//guard dog
mobile = Mob.createMob(contract.getMobbaseID(), Vector3fImmutable.ZERO, contractOwner.getGuild(), zone, building, contract, pirateName, rank, Enum.AIAgentType.GUARDCAPTAIN);
mob = Mob.createMob(contract.getMobbaseID(), Vector3fImmutable.ZERO, contractOwner.getGuild(), true, zone, building, contract.getContractID(), pirateName, rank);
if (mobile == null)
if (mob == null)
return false;
// Configure AI and write new mobile to disk
mobile.behaviourType = Enum.MobBehaviourType.GuardCaptain;
mobile = DbManager.MobQueries.PERSIST(mobile);
// Spawn new mobile
mobile.setLoc(mobile.getLoc());
mob.setLoc(mob.getLoc());
return true;
}
+1 -1
View File
@@ -788,7 +788,7 @@ public enum ChatManager {
it.remove();
else {
PlayerCharacter pcc = (PlayerCharacter) awo;
if (pcc.getSeeInvis() < pc.hidden)
if (pcc.getSeeInvis() < pc.getHidden())
it.remove();
}
}
+179 -92
View File
@@ -30,6 +30,8 @@ import java.util.HashSet;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ThreadLocalRandom;
import static engine.math.FastMath.sqr;
public enum CombatManager {
COMBATMANAGER;
@@ -39,6 +41,63 @@ public enum CombatManager {
/**
* Message sent by player to attack something.
*/
public static void setAttackTarget(AttackCmdMsg msg, ClientConnection origin) throws MsgSendException {
PlayerCharacter player;
int targetType;
AbstractWorldObject target;
if (TargetedActionMsg.un2cnt == 60 || TargetedActionMsg.un2cnt == 70)
return;
player = SessionManager.getPlayerCharacter(origin);
if (player == null)
return;
//source must match player this account belongs to
if (player.getObjectUUID() != msg.getSourceID() || player.getObjectType().ordinal() != msg.getSourceType()) {
Logger.error("Msg Source ID " + msg.getSourceID() + " Does not Match Player ID " + player.getObjectUUID());
return;
}
targetType = msg.getTargetType();
if (targetType == GameObjectType.PlayerCharacter.ordinal()) {
target = PlayerCharacter.getFromCache(msg.getTargetID());
} else if (targetType == GameObjectType.Building.ordinal()) {
target = BuildingManager.getBuildingFromCache(msg.getTargetID());
} else if (targetType == GameObjectType.Mob.ordinal()) {
target = Mob.getFromCache(msg.getTargetID());
} else {
player.setCombatTarget(null);
return; //not valid type to attack
}
// quit of the combat target is already the current combat target
// or there is no combat target
if (target == null)
return;
//set sources target
player.setCombatTarget(target);
//put in combat if not already
if (!player.isCombat())
toggleCombat(true, origin);
//make character stand if sitting
if (player.isSit())
toggleSit(false, origin);
AttackTarget(player, target);
}
public static void AttackTarget(PlayerCharacter playerCharacter, AbstractWorldObject target) {
@@ -82,6 +141,11 @@ public enum CombatManager {
if (off == null)
CombatManager.createTimer(playerCharacter, MBServerStatics.SLOT_OFFHAND, 1, true); // attack in 0.1 of a second
}
City playerCity = ZoneManager.getCityAtLocation(playerCharacter.getLoc());
if (playerCity != null && playerCity.getGuild().getNation().equals(playerCharacter.getGuild().getNation()) == false && playerCity.cityOutlaws.contains(playerCharacter.getObjectUUID()) == false)
playerCity.cityOutlaws.add(playerCharacter.getObjectUUID());
}
public static void setAttackTarget(PetAttackMsg msg, ClientConnection origin) throws MsgSendException {
@@ -459,7 +523,7 @@ public enum CombatManager {
/**
* Attempt to attack target
*/
private static void attack(AbstractCharacter attacker, AbstractWorldObject target, Item weapon, ItemBase wb, boolean mainHand) {
private static void attack(AbstractCharacter ac, AbstractWorldObject target, Item weapon, ItemBase wb, boolean mainHand) {
float atr;
int minDamage, maxDamage;
@@ -467,20 +531,20 @@ public enum CombatManager {
try {
if (attacker == null)
if (ac == null)
return;
if (target == null)
return;
if (mainHand) {
atr = attacker.getAtrHandOne();
minDamage = attacker.getMinDamageHandOne();
maxDamage = attacker.getMaxDamageHandOne();
atr = ac.getAtrHandOne();
minDamage = ac.getMinDamageHandOne();
maxDamage = ac.getMaxDamageHandOne();
} else {
atr = attacker.getAtrHandTwo();
minDamage = attacker.getMinDamageHandTwo();
maxDamage = attacker.getMaxDamageHandTwo();
atr = ac.getAtrHandTwo();
minDamage = ac.getMinDamageHandTwo();
maxDamage = ac.getMaxDamageHandTwo();
}
boolean tarIsRat = false;
@@ -499,9 +563,9 @@ public enum CombatManager {
//Dont think we need to do this anymore.
if (tarIsRat)
if (attacker.getBonuses().getFloatPercentAll(ModType.Slay, SourceType.Rat) != 0) { //strip away current % dmg buffs then add with rat %
if (ac.getBonuses().getFloatPercentAll(ModType.Slay, SourceType.Rat) != 0) { //strip away current % dmg buffs then add with rat %
float percent = 1 + attacker.getBonuses().getFloatPercentAll(ModType.Slay, SourceType.Rat);
float percent = 1 + ac.getBonuses().getFloatPercentAll(ModType.Slay, SourceType.Rat);
minDamage *= percent;
maxDamage *= percent;
@@ -512,24 +576,24 @@ public enum CombatManager {
//subtract stamina
if (wb == null)
attacker.modifyStamina(-0.5f, attacker, true);
ac.modifyStamina(-0.5f, ac, true);
else {
float stam = wb.getWeight() / 3;
stam = (stam < 1) ? 1 : stam;
attacker.modifyStamina(-(stam), attacker, true);
ac.modifyStamina(-(stam), ac, true);
}
attacker.cancelOnAttackSwing();
ac.cancelOnAttackSwing();
errorTrack = 2;
//set last time this player has attacked something.
if (target.getObjectType().equals(GameObjectType.PlayerCharacter) && target.getObjectUUID() != attacker.getObjectUUID() && attacker.getObjectType() == GameObjectType.PlayerCharacter) {
attacker.setTimeStamp("LastCombatPlayer", System.currentTimeMillis());
if (target.getObjectType().equals(GameObjectType.PlayerCharacter) && target.getObjectUUID() != ac.getObjectUUID() && ac.getObjectType() == GameObjectType.PlayerCharacter) {
ac.setTimeStamp("LastCombatPlayer", System.currentTimeMillis());
((PlayerCharacter) target).setTimeStamp("LastCombatPlayer", System.currentTimeMillis());
} else
attacker.setTimeStamp("LastCombatMob", System.currentTimeMillis());
ac.setTimeStamp("LastCombatMob", System.currentTimeMillis());
errorTrack = 3;
@@ -540,16 +604,42 @@ public enum CombatManager {
if (target.getObjectType().equals(GameObjectType.Building)) {
if (BuildingManager.getBuildingFromCache(target.getObjectUUID()) == null) {
attacker.setCombatTarget(null);
ac.setCombatTarget(null);
return;
}
defense = 0;
Building building = (Building) target;
if (building.getParentZone() != null && building.getParentZone().isPlayerCity()) {
if (System.currentTimeMillis() > building.getTimeStamp("CallForHelp")) {
building.getTimestamps().put("CallForHelp", System.currentTimeMillis() + 15000);
for (Mob mob : building.getParentZone().zoneMobSet) {
if (!mob.isPlayerGuard())
continue;
if (mob.getCombatTarget() != null)
continue;
if (mob.getGuild() != null && building.getGuild() != null)
if (!Guild.sameGuild(mob.getGuild().getNation(), building.getGuild().getNation()))
continue;
if (mob.getLoc().distanceSquared2D(building.getLoc()) > sqr(300))
continue;
mob.setCombatTarget(ac);
}
}
}
} else {
AbstractCharacter tar = (AbstractCharacter) target;
defense = tar.getDefenseRating();
handleRetaliate(tar, attacker); //Handle target attacking back if in combat and has no other target
handleRetaliate(tar, ac); //Handle target attacking back if in combat and has no other target
}
errorTrack = 4;
@@ -575,11 +665,11 @@ public enum CombatManager {
if (roll < chance) {
if (attacker.getObjectType().equals(GameObjectType.PlayerCharacter))
updateAttackTimers((PlayerCharacter) attacker, target, true);
if (ac.getObjectType().equals(GameObjectType.PlayerCharacter))
updateAttackTimers((PlayerCharacter) ac, target, true);
boolean skipPassives = false;
PlayerBonuses bonuses = attacker.getBonuses();
PlayerBonuses bonuses = ac.getBonuses();
if (bonuses != null && bonuses.getBool(ModType.IgnorePassiveDefense, SourceType.None))
skipPassives = true;
@@ -594,26 +684,26 @@ public enum CombatManager {
// Apply Weapon power effect if any. don't try to apply twice if
// dual wielding. Perform after passive test for sync purposes.
if (attacker.getObjectType().equals(GameObjectType.PlayerCharacter) && (mainHand || wb.isTwoHanded())) {
if (ac.getObjectType().equals(GameObjectType.PlayerCharacter) && (mainHand || wb.isTwoHanded())) {
dpj = ((PlayerCharacter) attacker).getWeaponPower();
dpj = ((PlayerCharacter) ac).getWeaponPower();
if (dpj != null) {
PlayerBonuses bonus = attacker.getBonuses();
PlayerBonuses bonus = ac.getBonuses();
float attackRange = getWeaponRange(wb, bonus);
dpj.attack(target, attackRange);
if (dpj.getPower() != null && (dpj.getPowerToken() == -1851459567 || dpj.getPowerToken() == -1851489518))
((PlayerCharacter) attacker).setWeaponPower(dpj);
((PlayerCharacter) ac).setWeaponPower(dpj);
}
}
//check to apply second backstab.
if (attacker.getObjectType().equals(GameObjectType.PlayerCharacter) && !mainHand) {
if (ac.getObjectType().equals(GameObjectType.PlayerCharacter) && !mainHand) {
dpj = ((PlayerCharacter) attacker).getWeaponPower();
dpj = ((PlayerCharacter) ac).getWeaponPower();
if (dpj != null && dpj.getPower() != null && (dpj.getPowerToken() == -1851459567 || dpj.getPowerToken() == -1851489518)) {
float attackRange = getWeaponRange(wb, bonuses);
@@ -633,24 +723,24 @@ public enum CombatManager {
//Handle Block passive
if (testPassive(attacker, tarAc, "Block") && canTestBlock(attacker, target)) {
if (testPassive(ac, tarAc, "Block") && canTestBlock(ac, target)) {
if (!target.isAlive())
return;
sendPassiveDefenseMessage(attacker, wb, target, MBServerStatics.COMBAT_SEND_BLOCK, dpj, mainHand);
sendPassiveDefenseMessage(ac, wb, target, MBServerStatics.COMBAT_SEND_BLOCK, dpj, mainHand);
passiveFired = true;
}
//Handle Parry passive
if (!passiveFired)
if (canTestParry(attacker, target) && testPassive(attacker, tarAc, "Parry")) {
if (canTestParry(ac, target) && testPassive(ac, tarAc, "Parry")) {
if (!target.isAlive())
return;
sendPassiveDefenseMessage(attacker, wb, target, MBServerStatics.COMBAT_SEND_PARRY, dpj, mainHand);
sendPassiveDefenseMessage(ac, wb, target, MBServerStatics.COMBAT_SEND_PARRY, dpj, mainHand);
passiveFired = true;
}
@@ -661,12 +751,12 @@ public enum CombatManager {
//Handle Dodge passive
if (!passiveFired)
if (testPassive(attacker, tarAc, "Dodge")) {
if (testPassive(ac, tarAc, "Dodge")) {
if (!target.isAlive())
return;
sendPassiveDefenseMessage(attacker, wb, target, MBServerStatics.COMBAT_SEND_DODGE, dpj, mainHand);
sendPassiveDefenseMessage(ac, wb, target, MBServerStatics.COMBAT_SEND_DODGE, dpj, mainHand);
passiveFired = true;
}
}
@@ -682,7 +772,7 @@ public enum CombatManager {
//if target is player, set last attack timestamp
if (target.getObjectType().equals(GameObjectType.PlayerCharacter))
updateAttackTimers((PlayerCharacter) target, attacker, false);
updateAttackTimers((PlayerCharacter) target, ac, false);
//Get damage Type
@@ -690,7 +780,7 @@ public enum CombatManager {
if (wb != null)
damageType = wb.getDamageType();
else if (attacker.getObjectType().equals(GameObjectType.Mob) && ((Mob) attacker).isSiege())
else if (ac.getObjectType().equals(GameObjectType.Mob) && ((Mob) ac).isSiege())
damageType = DamageType.Siege;
else
damageType = DamageType.Crush;
@@ -709,7 +799,7 @@ public enum CombatManager {
//make sure target is not immune to damage type;
if (resists != null && resists.immuneTo(damageType)) {
sendCombatMessage(attacker, target, 0f, wb, dpj, mainHand);
sendCombatMessage(ac, target, 0f, wb, dpj, mainHand);
return;
}
@@ -720,9 +810,9 @@ public enum CombatManager {
float damage;
if (wb != null)
damage = calculateDamage(attacker, tarAc, minDamage, maxDamage, damageType, resists);
damage = calculateDamage(ac, tarAc, minDamage, maxDamage, damageType, resists);
else
damage = calculateDamage(attacker, tarAc, minDamage, maxDamage, damageType, resists);
damage = calculateDamage(ac, tarAc, minDamage, maxDamage, damageType, resists);
float d = 0f;
@@ -735,35 +825,40 @@ public enum CombatManager {
if (tarAc.isSit())
damage *= 2.5f; //increase damage if sitting
if (tarAc.getObjectType() == GameObjectType.Mob) {
ac.setHateValue(damage * MBServerStatics.PLAYER_COMBAT_HATE_MODIFIER);
((Mob) tarAc).handleDirectAggro(ac);
}
if (tarAc.getHealth() > 0)
d = tarAc.modifyHealth(-damage, attacker, false);
d = tarAc.modifyHealth(-damage, ac, false);
} else if (target.getObjectType().equals(GameObjectType.Building)) {
if (BuildingManager.getBuildingFromCache(target.getObjectUUID()) == null) {
attacker.setCombatTarget(null);
ac.setCombatTarget(null);
return;
}
if (target.getHealth() > 0)
d = ((Building) target).modifyHealth(-damage, attacker);
d = ((Building) target).modifyHealth(-damage, ac);
}
errorTrack = 13;
//Test to see if any damage needs done to weapon or armor
testItemDamage(attacker, target, weapon, wb);
testItemDamage(ac, target, weapon, wb);
// if target is dead, we got the killing blow, remove attack timers on our weapons
if (tarAc != null && !tarAc.isAlive())
removeAttackTimers(attacker);
removeAttackTimers(ac);
//test double death fix
if (d != 0)
sendCombatMessage(attacker, target, damage, wb, dpj, mainHand); //send damage message
sendCombatMessage(ac, target, damage, wb, dpj, mainHand); //send damage message
errorTrack = 14;
@@ -790,7 +885,7 @@ public enum CombatManager {
int procChance = ThreadLocalRandom.current().nextInt(100);
if (procChance < MBServerStatics.PROC_CHANCE)
((WeaponProcEffectModifier) aem).applyProc(attacker, target);
((WeaponProcEffectModifier) aem).applyProc(ac, target);
}
}
@@ -802,52 +897,52 @@ public enum CombatManager {
//handle damage shields
if (attacker.isAlive() && tarAc != null && tarAc.isAlive())
handleDamageShields(attacker, tarAc, damage);
if (ac.isAlive() && tarAc != null && tarAc.isAlive())
handleDamageShields(ac, tarAc, damage);
} else {
// Apply Weapon power effect if any.
// don't try to apply twice if dual wielding.
if (attacker.getObjectType().equals(GameObjectType.PlayerCharacter) && (mainHand || wb.isTwoHanded())) {
dpj = ((PlayerCharacter) attacker).getWeaponPower();
if (ac.getObjectType().equals(GameObjectType.PlayerCharacter) && (mainHand || wb.isTwoHanded())) {
dpj = ((PlayerCharacter) ac).getWeaponPower();
if (dpj != null) {
PowersBase wp = dpj.getPower();
if (wp.requiresHitRoll() == false) {
PlayerBonuses bonus = attacker.getBonuses();
PlayerBonuses bonus = ac.getBonuses();
float attackRange = getWeaponRange(wb, bonus);
dpj.attack(target, attackRange);
} else
((PlayerCharacter) attacker).setWeaponPower(null);
((PlayerCharacter) ac).setWeaponPower(null);
}
}
if (target.getObjectType() == GameObjectType.Mob)
((Mob) target).handleDirectAggro(attacker);
((Mob) target).handleDirectAggro(ac);
errorTrack = 17;
//miss, Send miss message
sendCombatMessage(attacker, target, 0f, wb, dpj, mainHand);
sendCombatMessage(ac, target, 0f, wb, dpj, mainHand);
//if attacker is player, set last attack timestamp
if (attacker.getObjectType().equals(GameObjectType.PlayerCharacter))
updateAttackTimers((PlayerCharacter) attacker, target, true);
if (ac.getObjectType().equals(GameObjectType.PlayerCharacter))
updateAttackTimers((PlayerCharacter) ac, target, true);
}
errorTrack = 18;
//cancel effects that break on attack or attackSwing
attacker.cancelOnAttack();
ac.cancelOnAttack();
} catch (Exception e) {
Logger.error(attacker.getName() + ' ' + errorTrack + ' ' + e);
Logger.error(ac.getName() + ' ' + errorTrack + ' ' + e);
}
}
@@ -1125,7 +1220,7 @@ public enum CombatManager {
toggleCombat(msg.getToggle(), origin);
}
public static void toggleCombat(boolean toggle, ClientConnection origin) {
private static void toggleCombat(boolean toggle, ClientConnection origin) {
PlayerCharacter pc = SessionManager.getPlayerCharacter(origin);
@@ -1142,7 +1237,7 @@ public enum CombatManager {
DispatchMessage.dispatchMsgToInterestArea(pc, rwss, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, false, false);
}
public static void toggleSit(boolean toggle, ClientConnection origin) {
private static void toggleSit(boolean toggle, ClientConnection origin) {
PlayerCharacter pc = SessionManager.getPlayerCharacter(origin);
@@ -1172,69 +1267,61 @@ public enum CombatManager {
}
//Called when character takes damage.
public static void handleRetaliate(AbstractCharacter target, AbstractCharacter attacker) {
public static void handleRetaliate(AbstractCharacter tarAc, AbstractCharacter ac) {
if (attacker == null || target == null)
if (ac == null || tarAc == null)
return;
if (attacker.equals(target))
if (ac.equals(tarAc))
return;
if (target.isMoving() && target.getObjectType().equals(GameObjectType.PlayerCharacter))
if (tarAc.isMoving() && tarAc.getObjectType().equals(GameObjectType.PlayerCharacter))
return;
if (!target.isAlive() || !attacker.isAlive())
if (!tarAc.isAlive() || !ac.isAlive())
return;
boolean isCombat = target.isCombat();
boolean isCombat = tarAc.isCombat();
//If target in combat and has no target, then attack back
AbstractWorldObject awoCombTar = target.getCombatTarget();
AbstractWorldObject awoCombTar = tarAc.getCombatTarget();
if ((target.isCombat() && awoCombTar == null) || (isCombat && awoCombTar != null && (!awoCombTar.isAlive() || target.isCombat() && NotInRange(target, awoCombTar, target.getRange()))) || (target != null && target.getObjectType() == GameObjectType.Mob && ((Mob) target).isSiege()))
if (target.getObjectType().equals(GameObjectType.PlayerCharacter)) { // we are in combat with no valid target
if ((tarAc.isCombat() && awoCombTar == null) || (isCombat && awoCombTar != null && (!awoCombTar.isAlive() || tarAc.isCombat() && NotInRange(tarAc, awoCombTar, tarAc.getRange()))) || (tarAc != null && tarAc.getObjectType() == GameObjectType.Mob && ((Mob) tarAc).isSiege()))
if (tarAc.getObjectType().equals(GameObjectType.PlayerCharacter)) { // we are in combat with no valid target
PlayerCharacter pc = (PlayerCharacter) target;
target.setCombatTarget(attacker);
pc.setLastTarget(attacker.getObjectType(), attacker.getObjectUUID());
PlayerCharacter pc = (PlayerCharacter) tarAc;
tarAc.setCombatTarget(ac);
pc.setLastTarget(ac.getObjectType(), ac.getObjectUUID());
if (target.getTimers() != null)
if (!target.getTimers().containsKey("Attack" + MBServerStatics.SLOT_MAINHAND))
CombatManager.AttackTarget((PlayerCharacter) target, target.getCombatTarget());
if (tarAc.getTimers() != null)
if (!tarAc.getTimers().containsKey("Attack" + MBServerStatics.SLOT_MAINHAND))
CombatManager.AttackTarget((PlayerCharacter) tarAc, tarAc.getCombatTarget());
}
//Handle pet retaliate if assist is on and pet doesn't have a target.
if (target.getObjectType().equals(GameObjectType.PlayerCharacter)) {
if (tarAc.getObjectType().equals(GameObjectType.PlayerCharacter)) {
Mob pet = ((PlayerCharacter) target).getPet();
Mob pet = ((PlayerCharacter) tarAc).getPet();
if (pet != null && pet.assist && pet.getCombatTarget() == null)
pet.setCombatTarget(attacker);
pet.setCombatTarget(ac);
}
//Handle Mob Retaliate.
if (target.getObjectType() == GameObjectType.Mob) {
if (tarAc.getObjectType() == GameObjectType.Mob) {
Mob attackedMobile = (Mob) target;
Mob retaliater = (Mob) tarAc;
//handle minion informing his captain of an attack
if (attackedMobile.agentType.equals(AIAgentType.GUARDMINION) && attackedMobile.guardCaptain != null && attackedMobile.guardCaptain.isAlive()) {
if (attackedMobile.guardCaptain.combatTarget == null)
attackedMobile.guardCaptain.setCombatTarget(attacker);
}
// Mobile already has a target; don't switch.
if (attackedMobile.getCombatTarget() != null && !attackedMobile.isSiege())
if (retaliater.getCombatTarget() != null && !retaliater.isSiege())
return;
attackedMobile.setCombatTarget(attacker);
if (ac.getObjectType() == GameObjectType.Mob && retaliater.isSiege())
return;
retaliater.setCombatTarget(ac);
}
}
+10 -10
View File
@@ -116,8 +116,8 @@ public enum MovementManager {
// if inside a building, convert both locations from the building local reference frame to the world reference frame
if (msg.getInBuildingUUID() > 0) {
Building building = BuildingManager.getBuildingFromCache(msg.getInBuildingUUID());
if (msg.getTargetID() > 0) {
Building building = BuildingManager.getBuildingFromCache(msg.getTargetID());
if (building != null) {
Vector3fImmutable convertLocEnd = new Vector3fImmutable(ZoneManager.convertLocalToWorld(building, endLocation));
@@ -128,8 +128,8 @@ public enum MovementManager {
// }
// else {
toMove.setInBuilding(msg.getInBuilding());
toMove.setInFloorID(msg.getInBuildingFloor());
toMove.setInBuildingID(msg.getInBuildingUUID());
toMove.setInFloorID(msg.getUnknown01());
toMove.setInBuildingID(msg.getTargetID());
msg.setStartCoord(ZoneManager.convertWorldToLocal(building, toMove.getLoc()));
if (toMove.getObjectType() == GameObjectType.PlayerCharacter) {
@@ -174,9 +174,9 @@ public enum MovementManager {
msg.setStartCoord(ZoneManager.convertWorldToLocal(Regions.GetBuildingForRegion(toMove.region), toMove.getLoc()));
msg.setEndCoord(ZoneManager.convertWorldToLocal(regionBuilding, endLocation));
msg.setInBuilding(toMove.region.level);
msg.setInBuildingFloor(toMove.region.room);
msg.setStartLocType(GameObjectType.Building.ordinal());
msg.setInBuildingUUID(regionBuilding.getObjectUUID());
msg.setUnknown01(toMove.region.room);
msg.setTargetType(GameObjectType.Building.ordinal());
msg.setTargetID(regionBuilding.getObjectUUID());
}
} else {
@@ -185,8 +185,8 @@ public enum MovementManager {
toMove.setInBuilding(-1);
msg.setStartCoord(toMove.getLoc());
msg.setEndCoord(endLocation);
msg.setStartLocType(0);
msg.setInBuildingUUID(0);
msg.setTargetType(0);
msg.setTargetID(0);
}
//checks sync between character and server, if out of sync, teleport player to original position and return.
@@ -233,7 +233,7 @@ public enum MovementManager {
toMove.cancelOnMove();
//cancel any attacks for manual move.
if ((toMove.getObjectType() == GameObjectType.PlayerCharacter) && msg.getInitiatedFromAttack() == 0)
if ((toMove.getObjectType() == GameObjectType.PlayerCharacter) && msg.getUnknown02() == 0)
toMove.setCombatTarget(null);
+160 -248
View File
@@ -5,17 +5,13 @@ import engine.InterestManagement.WorldGrid;
import engine.math.Quaternion;
import engine.math.Vector3f;
import engine.math.Vector3fImmutable;
import engine.mobileAI.MobAI;
import engine.net.Dispatch;
import engine.net.DispatchMessage;
import engine.net.client.msg.PetMsg;
import engine.objects.*;
import engine.powers.EffectsBase;
import engine.powers.PowersBase;
import engine.powers.RuneSkillAdjustEntry;
import org.pmw.tinylog.Logger;
import javax.smartcardio.ATR;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.concurrent.ThreadLocalRandom;
@@ -27,6 +23,92 @@ public enum NPCManager {
NPC_MANAGER;
public static HashMap<Integer, ArrayList<Integer>> _runeSetMap = new HashMap<>();
public static void LoadAllRuneSets() {
_runeSetMap = DbManager.ItemBaseQueries.LOAD_RUNES_FOR_NPC_AND_MOBS();
}
public static void LoadAllBootySets() {
LootManager._bootySetMap = DbManager.LootQueries.LOAD_BOOTY_TABLES();
}
public static void applyRuneSetEffects(Mob mob) {
// Early exit
if (mob.runeSet == 0)
return;
//Apply all rune effects.
if (NPCManager._runeSetMap.get(mob.runeSet).contains(252623)) {
mob.isPlayerGuard = true;
}
// Only captains have contracts
if (mob.contract != null || mob.isPlayerGuard)
applyEffectsForRune(mob, 252621);
// Apply effects from RuneSet
if (mob.runeSet != 0)
for (int runeID : _runeSetMap.get(mob.runeSet))
applyEffectsForRune(mob, runeID);
// Not sure why but apply Warrior effects for some reason?
applyEffectsForRune(mob, 2518);
}
public static void applyEffectsForRune(AbstractCharacter character, int runeID) {
EffectsBase effectsBase;
RuneBase sourceRune = RuneBase.getRuneBase(runeID);
// Race runes are in the runeset but not in runebase for some reason
if (sourceRune == null)
return;
for (MobBaseEffects mbe : sourceRune.getEffectsList()) {
effectsBase = PowersManager.getEffectByToken(mbe.getToken());
if (effectsBase == null) {
Logger.info("Mob: " + character.getObjectUUID() + " EffectsBase Null for Token " + mbe.getToken());
continue;
}
//check to upgrade effects if needed.
if (character.effects.containsKey(Integer.toString(effectsBase.getUUID()))) {
if (mbe.getReqLvl() > (int) character.level)
continue;
Effect eff = character.effects.get(Integer.toString(effectsBase.getUUID()));
if (eff == null)
continue;
//Current effect is a higher rank, dont apply.
if (eff.getTrains() > mbe.getRank())
continue;
//new effect is of a higher rank. remove old effect and apply new one.
eff.cancelJob();
character.addEffectNoTimer(Integer.toString(effectsBase.getUUID()), effectsBase, mbe.getRank(), true);
} else {
if (mbe.getReqLvl() > (int) character.level)
continue;
character.addEffectNoTimer(Integer.toString(effectsBase.getUUID()), effectsBase, mbe.getRank(), true);
}
}
}
public static void dismissNecroPet(Mob necroPet, boolean updateOwner) {
necroPet.setCombatTarget(null);
@@ -45,12 +127,10 @@ public enum NPCManager {
DbManager.removeFromCache(necroPet);
PlayerCharacter petOwner = (PlayerCharacter) necroPet.guardCaptain;
PlayerCharacter petOwner = necroPet.getOwner();
if (petOwner != null) {
necroPet.guardCaptain = null;
necroPet.setOwner(null);
petOwner.setPet(null);
if (updateOwner == false)
@@ -122,6 +202,78 @@ public enum NPCManager {
playerCharacter.necroPets.clear();
}
public static void removeSiegeMinions(Mob mobile) {
for (Mob toRemove : mobile.siegeMinionMap.keySet()) {
if (mobile.isMoving()) {
mobile.stopMovement(mobile.getLoc());
if (toRemove.parentZone != null)
toRemove.parentZone.zoneMobSet.remove(toRemove);
}
try {
toRemove.clearEffects();
} catch (Exception e) {
Logger.error(e.getMessage());
}
if (toRemove.parentZone != null)
toRemove.parentZone.zoneMobSet.remove(toRemove);
WorldGrid.RemoveWorldObject(toRemove);
WorldGrid.removeObject(toRemove);
DbManager.removeFromCache(toRemove);
PlayerCharacter petOwner = toRemove.getOwner();
if (petOwner != null) {
petOwner.setPet(null);
toRemove.setOwner(null);
PetMsg petMsg = new PetMsg(5, null);
Dispatch dispatch = Dispatch.borrow(petOwner, petMsg);
DispatchMessage.dispatchMsgDispatch(dispatch, Enum.DispatchChannel.PRIMARY);
}
}
}
public static boolean removeMobileFromBuilding(Mob mobile, Building building) {
// Remove npc from it's building
try {
mobile.clearEffects();
} catch (Exception e) {
Logger.error(e.getMessage());
}
if (mobile.parentZone != null)
mobile.parentZone.zoneMobSet.remove(mobile);
if (building != null) {
building.getHirelings().remove(mobile);
removeSiegeMinions(mobile);
}
// Delete npc from database
if (DbManager.MobQueries.DELETE_MOB(mobile) == 0)
return false;
// Remove npc from the simulation
mobile.removeFromCache();
DbManager.removeFromCache(mobile);
WorldGrid.RemoveWorldObject(mobile);
WorldGrid.removeObject(mobile);
return true;
}
public static void loadAllPirateNames() {
DbManager.NPCQueries.LOAD_PIRATE_NAMES();
@@ -188,18 +340,9 @@ public enum NPCManager {
else
buildingSlot = BuildingManager.getAvailableSlot(abstractCharacter.building);
// Override slot for siege engines
if (abstractCharacter.getObjectType().equals(Enum.GameObjectType.Mob) && ((Mob) abstractCharacter).behaviourType.equals(Enum.MobBehaviourType.SiegeEngine)) {
Mob siegeMobile = (Mob) abstractCharacter;
buildingSlot = siegeMobile.guardCaptain.minions.size() + 2;
}
if (buildingSlot == -1)
Logger.error("No available slot for NPC: " + abstractCharacter.getObjectUUID());
// Pets are regular mobiles not hirelings (Siege engines)
if (abstractCharacter.contract != null)
abstractCharacter.building.getHirelings().put(abstractCharacter, buildingSlot);
// Override bind and location for this npc derived
@@ -227,235 +370,4 @@ public enum NPCManager {
return buildingSlot;
}
public static void AssignPatrolPoints(Mob mob) {
mob.patrolPoints = new ArrayList<>();
for (int i = 0; i < 5; ++i) {
float patrolRadius = mob.getSpawnRadius();
if (patrolRadius > 256)
patrolRadius = 256;
if (patrolRadius < 60)
patrolRadius = 60;
Vector3fImmutable newPatrolPoint = Vector3fImmutable.getRandomPointInCircle(mob.getBindLoc(), patrolRadius);
mob.patrolPoints.add(newPatrolPoint);
if (i == 1) {
mob.setLoc(newPatrolPoint);
mob.endLoc = newPatrolPoint;
}
}
}
public static void applyGuardStanceModifiers(Mob guard){
float damageModifier = 1;
float attackRatingModifier = 1;
float defenseModifier = 1;
float attackSpeedModifier = 1;
float powerDamageModifier = 1;
//handle stance modifiers for guard mob
if(guard.agentType.equals(Enum.AIAgentType.GUARDWALLARCHER)){
//apply rogue bonuses
attackRatingModifier += 0.5f;
defenseModifier += 0.5f;
damageModifier += 0.5f;
attackSpeedModifier -= 0.36f;
}else {
Integer contractID;
if (guard.agentType.equals(Enum.AIAgentType.GUARDMINION)) {
contractID = guard.guardCaptain.contract.getContractID();
} else{
contractID = guard.contract.getContractID();
}
if (Enum.MinionType.ContractToMinionMap.get(contractID) != null && Enum.MinionType.ContractToMinionMap.get(contractID).isMage()){
//apply mage offensive Stance
powerDamageModifier += 0.5f;
} else{
//apply fighter offensive stance
damageModifier += 0.5f;
attackSpeedModifier -= 0.36f;
}
}
guard.minDamageHandOne *= damageModifier;
guard.minDamageHandTwo *= damageModifier;
guard.maxDamageHandOne *= damageModifier;
guard.maxDamageHandTwo *= damageModifier;
guard.atrHandOne *= attackRatingModifier;
guard.atrHandTwo *= attackRatingModifier;
guard.defenseRating *= defenseModifier;
guard.speedHandOne *= attackSpeedModifier;
guard.speedHandTwo *= attackSpeedModifier;
//TODO figure out how to apply +50% powerdamage to mage guards
}
public static void setDamageAndSpeedForGuard(Mob guard){
float rankModifier = 1 + (guard.getRank() * 0.1f);
int primaryStat = 0;
if(guard.equip == null) {
guard.minDamageHandOne = (int)((guard.mobBase.getDamageMin()) * rankModifier);
guard.maxDamageHandOne = (int)((guard.mobBase.getDamageMax()) * rankModifier);
guard.speedHandOne = 30.0f;
}else{
if(guard.equip.containsKey(1)){
//has main hand weapon
ItemBase weapon = guard.equip.get(1).getItemBase();
if(weapon.isStrBased())
primaryStat = guard.getStatStrCurrent();
else
primaryStat = guard.getStatDexCurrent();
guard.minDamageHandOne = (int)((guard.mobBase.getDamageMin() + weapon.getMinDamage()) * rankModifier) + primaryStat;
guard.maxDamageHandOne = (int)((guard.mobBase.getDamageMax() + weapon.getMaxDamage()) * rankModifier) + primaryStat;
guard.speedHandOne = weapon.getSpeed();
guard.rangeHandOne = weapon.getRange();
} else if(guard.equip.containsKey(2) && !guard.equip.get(2).getItemBase().isShield()){
//has off hand weapon
ItemBase weapon = guard.equip.get(2).getItemBase();
if(weapon.isStrBased())
primaryStat = guard.getStatStrCurrent();
else
primaryStat = guard.getStatDexCurrent();
guard.minDamageHandTwo = (int)((guard.mobBase.getDamageMin() + weapon.getMinDamage()) * rankModifier) + primaryStat;
guard.maxDamageHandTwo = (int)((guard.mobBase.getDamageMax() + weapon.getMaxDamage()) * rankModifier) + primaryStat;
guard.speedHandTwo = weapon.getSpeed();
guard.rangeHandTwo = weapon.getRange();
} else {
primaryStat = guard.getStatStrCurrent();
guard.minDamageHandOne = (int)((guard.mobBase.getDamageMin()) * rankModifier) + primaryStat;
guard.maxDamageHandOne = (int)((guard.mobBase.getDamageMax()) * rankModifier) + primaryStat;
guard.speedHandOne = 30.0f;
guard.rangeHandOne = 3;
}
}
}
public static void setDefenseForGuard(Mob guard){
int dexterity = guard.getStatDexCurrent();
if(dexterity < 1)
dexterity = 1;
int baseDef = guard.mobBase.getDefenseRating();
int armorDefense = 0;
for(MobEquipment equipped : guard.equip.values())
if(equipped.getItemBase().isArmor() || equipped.getItemBase().isShield())
armorDefense += equipped.getItemBase().getDefense();
guard.defenseRating = dexterity + baseDef + armorDefense;
}
public static void setAttackRatingForGuard(Mob guard) {
int strength = guard.getStatStrCurrent();
int baseAtr = guard.mobBase.getAttackRating();
if (guard.equip.get(1) != null)
guard.atrHandOne = baseAtr + (int) ((strength * 0.5f) + (guard.equip.get(1).getItemBase().getPercentRequired() * 4) + (guard.equip.get(1).getItemBase().getPercentRequired() * 3));
else if (guard.equip.get(2) != null && !guard.equip.get(2).getItemBase().isShield())
guard.atrHandTwo = baseAtr + (int) ((strength * 0.5f) + (guard.equip.get(2).getItemBase().getPercentRequired() * 4) + (guard.equip.get(2).getItemBase().getPercentRequired() * 3));
else
guard.atrHandOne = baseAtr;
}
public static void setMaxHealthForGuard(Mob guard){
//values derived fom reading memory address for health on client when selecting player guards
switch(guard.getRank()){
default:
guard.healthMax = 750; //rank 1
break;
case 2:
guard.healthMax = 2082;
break;
case 3:
guard.healthMax = 2740;
break;
case 4:
guard.healthMax = 3414;
break;
case 5:
guard.healthMax = 4080;
break;
case 6:
guard.healthMax = 4746;
break;
case 7:
guard.healthMax = 5412;
break;
}
}
public static void applyMobbaseEffects(Mob mob) {
EffectsBase effectsBase;
for (MobBaseEffects mbe : mob.mobBase.effectsList) {
effectsBase = PowersManager.getEffectByToken(mbe.getToken());
if (effectsBase == null) {
Logger.info("Mob: " + mob.getObjectUUID() + " EffectsBase Null for Token " + mbe.getToken());
continue;
}
//check to upgrade effects if needed.
if (mob.effects.containsKey(Integer.toString(effectsBase.getUUID()))) {
if (mbe.getReqLvl() > (int) mob.level)
continue;
Effect eff = mob.effects.get(Integer.toString(effectsBase.getUUID()));
if (eff == null)
continue;
//Current effect is a higher rank, dont apply.
if (eff.getTrains() > mbe.getRank())
continue;
//new effect is of a higher rank. remove old effect and apply new one.
eff.cancelJob();
mob.addEffectNoTimer(Integer.toString(effectsBase.getUUID()), effectsBase, mbe.getRank(), true);
} else {
if (mbe.getReqLvl() > (int) mob.level)
continue;
mob.addEffectNoTimer(Integer.toString(effectsBase.getUUID()), effectsBase, mbe.getRank(), true);
}
}
}
public static void applyEquipmentResists(Mob mob){
if(mob.equip != null){
for(MobEquipment equipped : mob.equip.values()){
ItemBase itemBase = equipped.getItemBase();
if(itemBase.isHeavyArmor() || itemBase.isLightArmor() || itemBase.isMediumArmor()){
mob.resists.setResist(Enum.DamageType.Crush, mob.resists.getResist(Enum.DamageType.Crush,0) + itemBase.getCrushResist());
mob.resists.setResist(Enum.DamageType.Slash, mob.resists.getResist(Enum.DamageType.Slash,0) + itemBase.getCrushResist());
mob.resists.setResist(Enum.DamageType.Pierce, mob.resists.getResist(Enum.DamageType.Pierce,0) + itemBase.getCrushResist());
}
}
}
}
public static void applyMobbaseSkill(Mob mob) {
SkillsBase baseSkill = DbManager.SkillsBaseQueries.GET_BASE_BY_TOKEN(mob.mobBase.getMobBaseStats().getBaseSkill());
if(baseSkill != null)
mob.getSkills().put(baseSkill.getName(),new CharacterSkill(baseSkill,mob,mob.mobBase.getMobBaseStats().getBaseSkillAmount()));
}
public static void applyRuneSkills(Mob mob, int runeID){
//load mob skill adjustments from mobbase rune
if(PowersManager._allRuneSkillAdjusts.containsKey(runeID))
for(RuneSkillAdjustEntry entry : PowersManager._allRuneSkillAdjusts.get(runeID)) {
if(SkillsBase.getFromCache(entry.skill_type) == null)
SkillsBase.putInCache(DbManager.SkillsBaseQueries.GET_BASE_BY_NAME(entry.skill_type));
SkillsBase skillBase = SkillsBase.getFromCache(entry.skill_type);
if(skillBase == null)
continue;
if (entry.level <= mob.level)
if (mob.skills.containsKey(entry.name) == false)
mob.skills.put(entry.skill_type, new CharacterSkill(skillBase, mob, entry.rank));
else
mob.skills.put(entry.skill_type, new CharacterSkill(skillBase, mob, entry.rank + mob.skills.get(entry.skill_type).getNumTrains()));
}
}
}
+9 -12
View File
@@ -53,10 +53,13 @@ public enum PowersManager {
public static HashMap<Integer, AbstractPowerAction> powerActionsByID = new HashMap<>();
public static HashMap<String, Integer> ActionTokenByIDString = new HashMap<>();
public static HashMap<String, Integer> AnimationOverrides = new HashMap<>();
public static HashMap<Integer, ArrayList<RunePowerEntry>> _allRunePowers;
public static HashMap<Integer, ArrayList<RuneSkillAdjustEntry>> _allRuneSkillAdjusts;
public static HashMap<Integer, ArrayList<MobPowerEntry>> AllMobPowers;
private static JobScheduler js;
private PowersManager() {
}
public static void initPowersManager(boolean fullPowersLoad) {
if (fullPowersLoad)
@@ -100,16 +103,6 @@ public enum PowersManager {
}
}
public static ArrayList<RunePowerEntry> getPowersForRune(int rune_id) {
ArrayList<RunePowerEntry> powerEntries = PowersManager._allRunePowers.get(rune_id);
if (powerEntries == null)
powerEntries = new ArrayList<>();
return powerEntries;
}
// This pre-loads all powers and effects
public static void InitializePowers() {
@@ -846,6 +839,8 @@ public enum PowersManager {
return;
}
playerCharacter.setHateValue(pb.getHateValue(trains));
//Send Cast Message.
// PerformActionMsg castMsg = new PerformActionMsg(msg);
// castMsg.setNumTrains(9999);
@@ -896,6 +891,8 @@ public enum PowersManager {
//Power is aiding a target, handle aggro if combat target is a Mob.
if (!pb.isHarmful() && target.getObjectType() == GameObjectType.PlayerCharacter) {
PlayerCharacter pcTarget = (PlayerCharacter) target;
if (!pb.isHarmful())
Mob.HandleAssistedAggro(playerCharacter, pcTarget);
}
// update target of used power timer
+2 -2
View File
@@ -29,7 +29,7 @@ public class EndFearJob extends AbstractEffectJob {
if (this.target == null || (!(this.target instanceof Mob)))
return;
((Mob) this.target).fearedObject = null;
((Mob) this.target).setFearedObject(null);
}
@Override
@@ -40,6 +40,6 @@ public class EndFearJob extends AbstractEffectJob {
if (this.target == null || (!(this.target instanceof Mob)))
return;
((Mob) this.target).fearedObject = null;
((Mob) this.target).setFearedObject(null);
}
}
+300 -222
View File
@@ -23,7 +23,6 @@ import engine.net.client.msg.PowerProjectileMsg;
import engine.objects.*;
import engine.powers.ActionsBase;
import engine.powers.PowersBase;
import engine.powers.RunePowerEntry;
import engine.server.MBServerStatics;
import org.pmw.tinylog.Logger;
@@ -50,19 +49,17 @@ public class MobAI {
return;
}
if (target.getObjectType().equals(Enum.GameObjectType.PlayerCharacter) &&
!mob.canSee((AbstractCharacter) target)) {
mob.setCombatTarget(null);
return;
}
if (target.getObjectType() == Enum.GameObjectType.PlayerCharacter && canCast(mob)) {
if (MobCast(mob)) {
if (mob.isPlayerGuard() == false && MobCast(mob)) {
mob.updateLocation();
return;
}
if (mob.isPlayerGuard() == true && GuardCast(mob)) {
mob.updateLocation();
return;
}
}
if (!CombatUtilities.inRangeToAttack(mob, target))
@@ -99,7 +96,7 @@ public class MobAI {
return;
}
if (mob.behaviourType.callsForHelp)
if (mob.BehaviourType.callsForHelp)
MobCallForHelp(mob);
if (!MovementUtilities.inRangeDropAggro(mob, target)) {
@@ -168,7 +165,7 @@ public class MobAI {
if (playercity != null)
for (Mob guard : playercity.getParent().zoneMobSet)
if (guard.agentType.equals(Enum.AIAgentType.GUARDCAPTAIN))
if (guard.BehaviourType != null && guard.BehaviourType.ordinal() == Enum.MobBehaviourType.GuardCaptain.ordinal())
if (guard.getCombatTarget() == null && !guard.getGuild().equals(mob.getGuild()))
guard.setCombatTarget(mob);
@@ -252,22 +249,18 @@ public class MobAI {
try {
//make sure mob is out of combat stance
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.
// Minions are force marched if captain is alive
boolean forced = mob.agentType.equals(Enum.AIAgentType.GUARDMINION) &&
mob.guardCaptain.isAlive();
//early exit while waiting to patrol again
if (mob.stopPatrolTime + (patrolDelay * 1000) > System.currentTimeMillis())
if (!forced)
return;
//guards inherit barracks patrol points dynamically
//guard captains inherit barracks patrol points dynamically
if (mob.patrolPoints == null || mob.patrolPoints.isEmpty())
if (mob.agentType.equals(Enum.AIAgentType.GUARDCAPTAIN) || mob.agentType.equals(Enum.AIAgentType.GUARDMINION)) {
if (mob.BehaviourType.ordinal() == Enum.MobBehaviourType.GuardCaptain.ordinal()) {
Building barracks = mob.building;
@@ -282,28 +275,24 @@ public class MobAI {
if (mob.lastPatrolPointIndex > mob.patrolPoints.size() - 1)
mob.lastPatrolPointIndex = 0;
// Minions are given marching orders by the captain if he is alive
if (mob.agentType.equals(Enum.AIAgentType.GUARDMINION)) {
Mob captain = (Mob) mob.guardCaptain;
mob.destination = captain.destination.add(Formation.getOffset(2, mob.guardCaptain.minions.indexOf(mob.getObjectUUID()) + 3));
mob.lastPatrolPointIndex = captain.lastPatrolPointIndex;
} else {
mob.destination = mob.patrolPoints.get(mob.lastPatrolPointIndex);
mob.lastPatrolPointIndex += 1;
}
// Captain orders minions to patrol
if (mob.agentType.equals(Enum.AIAgentType.GUARDCAPTAIN))
for (Integer minionUUID : mob.minions) {
Mob minion = Mob.getMob(minionUUID);
if (minion.isAlive() && minion.combatTarget == null)
MobAI.Patrol(minion);
}
MovementUtilities.aiMove(mob, mob.destination, true);
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 (MovementUtilities.canMove(minion.getKey())) {
Vector3f minionOffset = Formation.getOffset(2, minion.getValue() + 3);
minion.getKey().updateLocation();
Vector3fImmutable formationPatrolPoint = new Vector3fImmutable(mob.destination.x + minionOffset.x, mob.destination.y, mob.destination.z + minionOffset.z);
MovementUtilities.aiMove(minion.getKey(), formationPatrolPoint, true);
}
}
} catch (Exception e) {
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: AttackTarget" + " " + e.getMessage());
}
@@ -311,8 +300,6 @@ public class MobAI {
public static boolean canCast(Mob mob) {
int contractID = 0;
try {
// Performs validation to determine if a
@@ -321,27 +308,26 @@ public class MobAI {
if (mob == null)
return false;
if (mob.isPlayerGuard() == true) {
if(mob.isPlayerGuard == true){
if(mob.agentType.equals(Enum.AIAgentType.GUARDWALLARCHER))
return false; //wall archers don't cast
if (mob.agentType.equals(Enum.AIAgentType.GUARDMINION))
contractID = mob.guardCaptain.contract.getContractID();
int contractID;
if(mob.BehaviourType.equals(Enum.MobBehaviourType.GuardMinion))
contractID = mob.npcOwner.contract.getContractID();
else
contractID = mob.contract.getContractID();
// exception allowing werewolf and werebear guard captains to cast
if (Enum.MinionType.ContractToMinionMap.get(contractID).isMage() == false && contractID != 980103 && contractID != 980104)
if(Enum.MinionType.ContractToMinionMap.get(contractID).isMage() == false)
return false;
}
// Mobile has no powers defined in mobbase or contract..
if (PowersManager.getPowersForRune(mob.getMobBaseID()).isEmpty() &&
PowersManager.getPowersForRune(contractID).isEmpty())
if (mob.mobPowers.isEmpty())
return false;
if (!mob.canSee((PlayerCharacter) mob.getCombatTarget())) {
mob.setCombatTarget(null);
return false;
}
if (mob.nextCastTime == 0)
mob.nextCastTime = System.currentTimeMillis();
@@ -360,67 +346,47 @@ public class MobAI {
// and casts it on the current target (or itself). Validation
// (including empty lists) is done previously within canCast();
ArrayList<RunePowerEntry> powerEntries;
ArrayList<RunePowerEntry> purgeEntries;
ArrayList<Integer> powerTokens;
ArrayList<Integer> purgeTokens;
AbstractCharacter target = (AbstractCharacter) mob.getCombatTarget();
if (mob.behaviourType.callsForHelp)
if (mob.BehaviourType.callsForHelp)
MobCallForHelp(mob);
// Generate a list of tokens from the mob powers for this mobile.
powerEntries = new ArrayList<>(PowersManager.getPowersForRune(mob.getMobBaseID()));
purgeEntries = new ArrayList<>();
// Additional powers may come from the contract ID. This is to support
// powers for player guards irrespective of the mobbase used.
if (mob.isPlayerGuard()) {
ArrayList<RunePowerEntry> contractEntries = new ArrayList<>();
if (mob.contract != null)
contractEntries = PowersManager.getPowersForRune(mob.contractUUID);
if (mob.agentType.equals(Enum.AIAgentType.GUARDMINION))
contractEntries = PowersManager.getPowersForRune(mob.guardCaptain.contractUUID);
powerEntries.addAll(contractEntries);
}
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 (RunePowerEntry runePowerEntry : powerEntries) {
for (int powerToken : powerTokens) {
PowersBase powerBase = PowersManager.getPowerByToken(runePowerEntry.token);
PowersBase powerBase = PowersManager.getPowerByToken(powerToken);
for (ActionsBase actionBase : powerBase.getActions()) {
String stackType = actionBase.stackType;
if (target.getEffects() != null && target.getEffects().containsKey(stackType))
purgeEntries.add(runePowerEntry);
purgeTokens.add(powerToken);
}
}
powerEntries.removeAll(purgeEntries);
powerTokens.removeAll(purgeTokens);
// Sanity check
if (powerEntries.isEmpty())
if (powerTokens.isEmpty())
return false;
// Pick random spell from our list of powers
RunePowerEntry runePowerEntry = powerEntries.get(ThreadLocalRandom.current().nextInt(powerEntries.size()));
int powerToken = powerTokens.get(ThreadLocalRandom.current().nextInt(powerTokens.size()));
int powerRank = mob.mobPowers.get(powerToken);
PowersBase mobPower = PowersManager.getPowerByToken(runePowerEntry.token);
int powerRank = runePowerEntry.rank;
if (mob.isPlayerGuard())
powerRank = getGuardPowerRank(mob);
PowersBase mobPower = PowersManager.getPowerByToken(powerToken);
//check for hit-roll
@@ -445,7 +411,7 @@ public class MobAI {
msg.setUnknown04(2);
PowersManager.finishUseMobPower(msg, mob, 0, 0);
long randomCooldown = (long) ((ThreadLocalRandom.current().nextInt(10, 15) * 1000) * MobAIThread.AI_CAST_FREQUENCY);
long randomCooldown = (long)((ThreadLocalRandom.current().nextInt(10,15) * 1000) * MobAIThread.AI_CAST_FREQUENCY);
mob.nextCastTime = System.currentTimeMillis() + randomCooldown;
return true;
@@ -456,10 +422,64 @@ public class MobAI {
return false;
}
public static int getGuardPowerRank(Mob mob) {
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()) {
switch(mob.getRank()){
case 1:
powerRank = 10;
break;
@@ -482,7 +502,47 @@ public class MobAI {
powerRank = 40;
break;
}
return powerRank;
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);
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 void MobCallForHelp(Mob mob) {
@@ -504,7 +564,7 @@ public class MobAI {
Zone mobCamp = mob.getParentZone();
for (Mob helper : mobCamp.zoneMobSet) {
if (helper.behaviourType.respondsToCallForHelp && helper.behaviourType.BehaviourHelperType.equals(mob.behaviourType)) {
if (helper.BehaviourType.respondsToCallForHelp && helper.BehaviourType.BehaviourHelperType.equals(mob.BehaviourType)) {
helper.setCombatTarget(mob.getCombatTarget());
callGotResponse = true;
}
@@ -546,10 +606,10 @@ public class MobAI {
//override for guards
if (mob.despawned && mob.isPlayerGuard()) {
if (mob.despawned && mob.isPlayerGuard) {
if (mob.agentType.equals(Enum.AIAgentType.GUARDMINION)) {
if (mob.guardCaptain.isAlive() == false || ((Mob) mob.guardCaptain).despawned == true) {
if (mob.BehaviourType.ordinal() == Enum.MobBehaviourType.GuardMinion.ordinal()) {
if (mob.npcOwner.isAlive() == false || ((Mob) mob.npcOwner).despawned == true) {
//minions don't respawn while guard captain is dead
@@ -565,7 +625,7 @@ public class MobAI {
//check to send mob home for player guards to prevent exploit of dragging guards away and then teleporting
if (!mob.agentType.equals(Enum.AIAgentType.PET))
if (mob.BehaviourType.ordinal() != Enum.MobBehaviourType.Pet1.ordinal())
CheckToSendMobHome(mob);
return;
@@ -578,23 +638,15 @@ public class MobAI {
return;
}
//no players loaded, no need to proceed unless it's a player guard
boolean bypassLoadedPlayerCheck = false;
if(mob.isPlayerGuard() || mob.isSiege()) {
bypassLoadedPlayerCheck = true;
if(mob.combatTarget != null && mob.combatTarget.getObjectType().equals(Enum.GameObjectType.PlayerCharacter))
if(mob.combatTarget.loc.distanceSquared(mob.loc) > 10000)
mob.setCombatTarget(null);
}
//no players loaded, no need to proceed
if (mob.playerAgroMap.isEmpty() && !bypassLoadedPlayerCheck) {
if (mob.getCombatTarget() != null)
if (mob.playerAgroMap.isEmpty()) {
if(mob.getCombatTarget() != null)
mob.setCombatTarget(null);
return;
}
if (mob.agentType.equals(Enum.AIAgentType.PET) == false)
if (mob.BehaviourType.ordinal() != Enum.MobBehaviourType.Pet1.ordinal())
CheckToSendMobHome(mob);
if (mob.getCombatTarget() != null) {
@@ -621,14 +673,17 @@ public class MobAI {
}
}
switch (mob.behaviourType) {
switch (mob.BehaviourType) {
case GuardCaptain:
GuardCaptainLogic(mob);
break;
case GuardMinion:
GuardMinionLogic(mob);
break;
case GuardWallArcher:
GuardLogic(mob);
GuardWallArcherLogic(mob);
break;
case Pet1:
case SiegeEngine:
PetLogic(mob);
break;
case HamletGuard:
@@ -638,6 +693,8 @@ public class MobAI {
DefaultLogic(mob);
break;
}
if(mob.isAlive())
RecoverHealth(mob);
} catch (Exception e) {
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: DetermineAction" + " " + e.getMessage());
}
@@ -652,7 +709,7 @@ public class MobAI {
if (!aiAgent.isAlive())
return;
ConcurrentHashMap<Integer, Float> loadedPlayers = aiAgent.playerAgroMap;
ConcurrentHashMap<Integer, Boolean> loadedPlayers = aiAgent.playerAgroMap;
for (Entry playerEntry : loadedPlayers.entrySet()) {
@@ -692,6 +749,7 @@ public class MobAI {
aiAgent.setCombatTarget(loadedPlayer);
return;
}
}
if (aiAgent.getCombatTarget() == null) {
@@ -726,49 +784,52 @@ public class MobAI {
mob.updateLocation();
switch (mob.behaviourType) {
switch (mob.BehaviourType) {
case Pet1:
if (mob.guardCaptain == null)
if (mob.getOwner() == null)
return;
//mob no longer has its owner loaded, translate pet to owner
if (!mob.playerAgroMap.containsKey(mob.getOwner().getObjectUUID())) {
if (!mob.playerAgroMap.containsKey(mob.guardCaptain.getObjectUUID())) {
MovementManager.translocate(mob, mob.guardCaptain.getLoc(), null);
//mob no longer has its owner loaded, translocate pet to owner
MovementManager.translocate(mob, mob.getOwner().getLoc(), null);
return;
}
if (mob.getCombatTarget() == null) {
//move back to owner
if (CombatUtilities.inRange2D(mob, mob.guardCaptain, 6))
if (CombatUtilities.inRange2D(mob, mob.getOwner(), 6))
return;
mob.destination = mob.guardCaptain.getLoc();
MovementUtilities.moveToLocation(mob, mob.destination, 5, false);
mob.destination = mob.getOwner().getLoc();
MovementUtilities.moveToLocation(mob, mob.destination, 5);
} else
chaseTarget(mob);
break;
case GuardMinion:
if (!mob.npcOwner.isAlive() && mob.getCombatTarget() == null)
randomGuardPatrolPoint(mob);
else {
if (mob.getCombatTarget() != null) {
chaseTarget(mob);
}
}
break;
default:
if (mob.getCombatTarget() == null) {
if (!mob.isMoving()) {
// Minions only patrol on their own if captain is dead.
if (mob.agentType.equals(Enum.AIAgentType.GUARDMINION) == false)
if (!mob.isMoving())
Patrol(mob);
else if (mob.guardCaptain.isAlive() == false)
Patrol(mob);
} else
else {
mob.stopPatrolTime = System.currentTimeMillis();
}
} else {
chaseTarget(mob);
}
break;
}
} catch (Exception e) {
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: CheckMobMovement" + " " + e.getMessage());
@@ -835,8 +896,7 @@ public class MobAI {
if (mob.getCombatTarget() == null)
return;
if (mob.getCombatTarget().getObjectType().equals(Enum.GameObjectType.PlayerCharacter) && MovementUtilities.inRangeDropAggro(mob, (PlayerCharacter) mob.getCombatTarget()) == false &&
mob.agentType.equals(Enum.AIAgentType.PET) == false) {
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);
return;
@@ -852,6 +912,15 @@ public class MobAI {
private static void CheckToSendMobHome(Mob mob) {
try {
if (mob.BehaviourType.isAgressive) {
if (mob.isPlayerGuard()) {
if (mob.BehaviourType.ordinal() == Enum.MobBehaviourType.GuardCaptain.ordinal())
CheckForPlayerGuardAggro(mob);
} else {
CheckForAggro(mob);
}
}
if (mob.getCombatTarget() != null && CombatUtilities.inRange2D(mob, mob.getCombatTarget(), MobAIThread.AI_BASE_AGGRO_RANGE * 0.5f))
return;
@@ -866,15 +935,13 @@ public class MobAI {
PowersManager.useMobPower(mob, mob, recall, 40);
mob.setCombatTarget(null);
if (mob.agentType.equals(Enum.AIAgentType.GUARDCAPTAIN) && mob.isAlive()) {
if (mob.BehaviourType.ordinal() == Enum.MobBehaviourType.GuardCaptain.ordinal() && mob.isAlive()) {
//guard captain pulls his minions home with him
for (Integer minionUUID : mob.minions) {
Mob minion = Mob.getMob(minionUUID);
PowersManager.useMobPower(minion, minion, recall, 40);
minion.setCombatTarget(null);
for (Entry<Mob, Integer> minion : mob.siegeMinionMap.entrySet()) {
PowersManager.useMobPower(minion.getKey(), minion.getKey(), recall, 40);
minion.getKey().setCombatTarget(null);
}
}
}
@@ -884,8 +951,8 @@ public class MobAI {
PowersManager.useMobPower(mob, mob, recall, 40);
mob.setCombatTarget(null);
for (Integer playerEntry : mob.playerAgroMap.keySet())
mob.playerAgroMap.put(playerEntry, 0f);
for (Entry playerEntry : mob.playerAgroMap.entrySet())
PlayerCharacter.getFromCache((int) playerEntry.getKey()).setHateValue(0);
}
} catch (Exception e) {
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: CheckToSendMobHome" + " " + e.getMessage());
@@ -896,10 +963,16 @@ public class MobAI {
try {
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, false);
MovementUtilities.moveToLocation(mob, mob.destination, 0);
} else {
//check if building
@@ -908,11 +981,11 @@ public class MobAI {
case PlayerCharacter:
case Mob:
mob.destination = MovementUtilities.GetDestinationToCharacter(mob, (AbstractCharacter) mob.getCombatTarget());
MovementUtilities.moveToLocation(mob, mob.destination, mob.getRange() + 1, false);
MovementUtilities.moveToLocation(mob, mob.destination, mob.getRange() + 1);
break;
case Building:
mob.destination = mob.getCombatTarget().getLoc();
MovementUtilities.moveToLocation(mob, mob.getCombatTarget().getLoc(), 0, false);
MovementUtilities.moveToLocation(mob, mob.getCombatTarget().getLoc(), 0);
break;
}
}
@@ -933,17 +1006,17 @@ public class MobAI {
//dont scan self.
if (mob.equals(awoMob) || (mob.agentType.equals(Enum.AIAgentType.GUARDCAPTAIN)) == true)
if (mob.equals(awoMob) || (mob.agentType.equals(Enum.AIAgentType.GUARD)) == true)
continue;
Mob aggroMob = (Mob) awoMob;
//don't attack other guards
if ((aggroMob.agentType.equals(Enum.AIAgentType.GUARDCAPTAIN)))
if ((aggroMob.agentType.equals(Enum.AIAgentType.GUARD)))
continue;
if (aggroMob.agentType.equals(Enum.AIAgentType.PET))
if(aggroMob.BehaviourType.equals(Enum.MobBehaviourType.Pet1))
continue;
if (mob.getLoc().distanceSquared2D(aggroMob.getLoc()) > sqr(50))
@@ -956,13 +1029,12 @@ public class MobAI {
}
}
public static void GuardLogic(Mob mob) {
public static void GuardCaptainLogic(Mob mob) {
try {
if (mob.getCombatTarget() == null) {
if (mob.getCombatTarget() == null)
CheckForPlayerGuardAggro(mob);
} else {
//do not need to look to change target if target is already null
AbstractWorldObject newTarget = ChangeTargetFromHateValue(mob);
if (newTarget != null) {
@@ -972,17 +1044,44 @@ public class MobAI {
mob.setCombatTarget(newTarget);
} else
mob.setCombatTarget(newTarget);
}
}
if(mob.behaviourType.canRoam)
CheckMobMovement(mob);//all guards that can move check to move
if(mob.combatTarget != null)
CheckForAttack(mob); //only check to attack if combat target is not null
CheckMobMovement(mob);
CheckForAttack(mob);
} catch (Exception e) {
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: GuardLogic" + " " + e.getMessage());
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: GuardCaptainLogic" + " " + e.getMessage());
}
}
public static void GuardMinionLogic(Mob mob) {
try {
boolean isComanded = mob.npcOwner.isAlive();
if (!isComanded) {
GuardCaptainLogic(mob);
}else {
if (mob.npcOwner.getCombatTarget() != null)
mob.setCombatTarget(mob.npcOwner.getCombatTarget());
else
if (mob.getCombatTarget() != null)
mob.setCombatTarget(null);
}
CheckMobMovement(mob);
CheckForAttack(mob);
} catch (Exception e) {
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: GuardMinionLogic" + " " + e.getMessage());
}
}
public static void GuardWallArcherLogic(Mob mob) {
try {
if (mob.getCombatTarget() == null)
CheckForPlayerGuardAggro(mob);
else
CheckForAttack(mob);
} catch (Exception e) {
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: GuardWallArcherLogic" + " " + e.getMessage());
}
}
@@ -990,30 +1089,14 @@ public class MobAI {
try {
if (mob.guardCaptain == null && mob.isNecroPet() == false && mob.isSiege() == false)
if (mob.getOwner() == null && mob.isNecroPet() == false && mob.isSiege() == false)
if (ZoneManager.getSeaFloor().zoneMobSet.contains(mob))
mob.killCharacter("no owner");
if (MovementUtilities.canMove(mob) && mob.behaviourType.canRoam)
if (MovementUtilities.canMove(mob) && mob.BehaviourType.canRoam)
CheckMobMovement(mob);
CheckForAttack(mob);
//recover health
if (mob.getTimestamps().containsKey("HEALTHRECOVERED") == false)
mob.getTimestamps().put("HEALTHRECOVERED", System.currentTimeMillis());
if (mob.isSit() && mob.getTimeStamp("HEALTHRECOVERED") < System.currentTimeMillis() + 3000)
if (mob.getHealth() < mob.getHealthMax()) {
float recoveredHealth = mob.getHealthMax() * ((1 + mob.getBonuses().getFloatPercentAll(Enum.ModType.HealthRecoverRate, Enum.SourceType.None)) * 0.01f);
mob.setHealth(mob.getHealth() + recoveredHealth);
mob.getTimestamps().put("HEALTHRECOVERED", System.currentTimeMillis());
if (mob.getHealth() > mob.getHealthMax())
mob.setHealth(mob.getHealthMax());
}
} catch (Exception e) {
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: PetLogic" + " " + e.getMessage());
}
@@ -1044,7 +1127,7 @@ public class MobAI {
if (mob.getCombatTarget() != null && mob.playerAgroMap.containsKey(mob.getCombatTarget().getObjectUUID()) == false)
mob.setCombatTarget(null);
if (mob.behaviourType.isAgressive) {
if (mob.BehaviourType.isAgressive) {
AbstractWorldObject newTarget = ChangeTargetFromHateValue(mob);
@@ -1052,7 +1135,7 @@ public class MobAI {
mob.setCombatTarget(newTarget);
else {
if (mob.getCombatTarget() == null) {
if (mob.behaviourType == Enum.MobBehaviourType.HamletGuard)
if (mob.BehaviourType == Enum.MobBehaviourType.HamletGuard)
SafeGuardAggro(mob); //safehold guard
else
CheckForAggro(mob); //normal aggro
@@ -1062,12 +1145,12 @@ public class MobAI {
//check if mob can move for patrol or moving to target
if (mob.behaviourType.canRoam)
if (mob.BehaviourType.canRoam)
CheckMobMovement(mob);
//check if mob can attack if it isn't wimpy
if (!mob.behaviourType.isWimpy && mob.getCombatTarget() != null)
if (!mob.BehaviourType.isWimpy && mob.getCombatTarget() != null)
CheckForAttack(mob);
} catch (Exception e) {
@@ -1084,16 +1167,7 @@ public class MobAI {
if (!mob.isAlive())
return;
// Defer to captain if possible for current target
if (mob.agentType.equals(Enum.AIAgentType.GUARDMINION) &&
mob.guardCaptain.isAlive()
&& mob.guardCaptain.combatTarget != null) {
mob.setCombatTarget(mob.guardCaptain.combatTarget);
return;
}
ConcurrentHashMap<Integer, Float> loadedPlayers = mob.playerAgroMap;
ConcurrentHashMap<Integer, Boolean> loadedPlayers = mob.playerAgroMap;
for (Entry playerEntry : loadedPlayers.entrySet()) {
@@ -1128,39 +1202,27 @@ public class MobAI {
mob.setCombatTarget(loadedPlayer);
return;
}
}
if (mob.getCombatTarget() == null) {
//look for siege equipment to aggro if no players found to aggro
HashSet<AbstractWorldObject> awoList = WorldGrid.getObjectsInRangePartial(mob, MobAIThread.AI_BASE_AGGRO_RANGE, MBServerStatics.MASK_SIEGE);
for (AbstractWorldObject awoMob : awoList) {
Mob aggroMob = (Mob) awoMob;
if(GuardCanAggro(mob,aggroMob)) {
mob.setCombatTarget(aggroMob);
return;
}
}
}
} catch (Exception e) {
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: CheckForPlayerGuardAggro" + e.getMessage());
}
}
public static Boolean GuardCanAggro(Mob mob, AbstractCharacter target) {
public static Boolean GuardCanAggro(Mob mob, PlayerCharacter target) {
try {
if (mob.guardedCity.cityOutlaws.contains(target.getObjectUUID()) == true)
return true;
if (mob.getGuild().getNation().equals(target.getGuild().getNation()))
return false;
if (mob.BehaviourType.ordinal() == Enum.MobBehaviourType.GuardMinion.ordinal()) {
if (((Mob) mob.npcOwner).building.getCity().cityOutlaws.contains(target.getObjectUUID()) == true) {
return true;
}
} else if (mob.building.getCity().cityOutlaws.contains(target.getObjectUUID()) == true) {
return true;
}
//first check condemn list for aggro allowed (allies button is checked)
if (ZoneManager.getCityAtLocation(mob.getLoc()).getTOL().reverseKOS) {
@@ -1238,19 +1300,17 @@ public class MobAI {
MovementUtilities.aiMove(mob, mob.destination, true);
if (mob.agentType.equals(Enum.AIAgentType.GUARDCAPTAIN)) {
for (Integer minionUUID : mob.minions) {
Mob minion = Mob.getMob(minionUUID);
if (mob.BehaviourType.ordinal() == Enum.MobBehaviourType.GuardCaptain.ordinal()) {
for (Entry<Mob, Integer> minion : mob.siegeMinionMap.entrySet()) {
//make sure mob is out of combat stance
if (minion.despawned == false) {
if (MovementUtilities.canMove(minion)) {
Vector3f minionOffset = Formation.getOffset(2, mob.minions.indexOf(minionUUID) + 3);
minion.updateLocation();
if (minion.getKey().despawned == false) {
if (MovementUtilities.canMove(minion.getKey())) {
Vector3f minionOffset = Formation.getOffset(2, minion.getValue() + 3);
minion.getKey().updateLocation();
Vector3fImmutable formationPatrolPoint = new Vector3fImmutable(mob.destination.x + minionOffset.x, mob.destination.y, mob.destination.z + minionOffset.z);
MovementUtilities.aiMove(minion, formationPatrolPoint, true);
MovementUtilities.aiMove(minion.getKey(), formationPatrolPoint, true);
}
}
}
@@ -1267,7 +1327,7 @@ public class MobAI {
float CurrentHateValue = 0;
if (mob.getCombatTarget() != null && mob.getCombatTarget().getObjectType().equals(Enum.GameObjectType.PlayerCharacter))
CurrentHateValue = mob.playerAgroMap.get(mob.combatTarget.getObjectUUID()).floatValue();
CurrentHateValue = ((PlayerCharacter) mob.getCombatTarget()).getHateValue();
AbstractWorldObject mostHatedTarget = null;
@@ -1278,8 +1338,8 @@ public class MobAI {
if (potentialTarget.equals(mob.getCombatTarget()))
continue;
if (potentialTarget != null && mob.playerAgroMap.get(potentialTarget.getObjectUUID()).floatValue() > CurrentHateValue && MovementUtilities.inRangeToAggro(mob, potentialTarget)) {
CurrentHateValue = mob.playerAgroMap.get(potentialTarget.getObjectUUID()).floatValue();
if (potentialTarget != null && potentialTarget.getHateValue() > CurrentHateValue && MovementUtilities.inRangeToAggro(mob, potentialTarget)) {
CurrentHateValue = potentialTarget.getHateValue();
mostHatedTarget = potentialTarget;
}
@@ -1290,4 +1350,22 @@ public class MobAI {
}
return null;
}
public static void RecoverHealth(Mob mob){
//recover health
if (mob.getTimestamps().containsKey("HEALTHRECOVERED") == false)
mob.getTimestamps().put("HEALTHRECOVERED", System.currentTimeMillis());
if (mob.isSit() && mob.getTimeStamp("HEALTHRECOVERED") < System.currentTimeMillis() + 3000)
if (mob.getHealth() < mob.getHealthMax()) {
float recoveredHealth = mob.getHealthMax() * ((1 + mob.getBonuses().getFloatPercentAll(Enum.ModType.HealthRecoverRate, Enum.SourceType.None)) * 0.01f);
mob.setHealth(mob.getHealth() + recoveredHealth);
mob.getTimestamps().put("HEALTHRECOVERED", System.currentTimeMillis());
if (mob.getHealth() > mob.getHealthMax())
mob.setHealth(mob.getHealthMax());
}
}
}
@@ -48,7 +48,7 @@ public class CombatUtilities {
}
public static boolean inRange2D(AbstractWorldObject entity1, AbstractWorldObject entity2, double range) {
return entity1.getLoc().distanceSquared2D(entity2.getLoc()) < range * range;
return entity1.getLoc().distance2D(entity2.getLoc()) < range;
}
public static void swingIsBlock(Mob agent, AbstractWorldObject target, int animation) {
@@ -264,9 +264,19 @@ public class CombatUtilities {
swingIsBlock(agent, target, passiveAnim);
return;
}
if (agent.getEquip().get(1) != null && agent.getEquip().get(2) != null && agent.getEquip().get(2).getItemBase().isShield() == false) {
//mob is duel wielding and should conduct an attack for each hand
ItemBase weapon1 = agent.getEquip().get(1).getItemBase();
double range1 = getMaxDmg(weapon1.getMinDamage(), agent, weapon1) - getMinDmg(weapon1.getMinDamage(), agent, weapon1);
double damage1 = getMinDmg(weapon1.getMinDamage(), agent, weapon1) + ((ThreadLocalRandom.current().nextFloat() * range1) + (ThreadLocalRandom.current().nextFloat() * range1)) / 2;
swingIsDamage(agent, target, (float) damage1, CombatManager.getSwingAnimation(weapon1, null, true));
ItemBase weapon2 = agent.getEquip().get(2).getItemBase();
double range2 = getMaxDmg(weapon2.getMinDamage(), agent, weapon2) - getMinDmg(weapon2.getMinDamage(), agent, weapon2);
double damage2 = getMinDmg(weapon2.getMinDamage(), agent, weapon2) + ((ThreadLocalRandom.current().nextFloat() * range2) + (ThreadLocalRandom.current().nextFloat() * range2)) / 2;
swingIsDamage(agent, target, (float) damage2, CombatManager.getSwingAnimation(weapon1, null, false));
} else {
swingIsDamage(agent, target, determineDamage(agent), anim);
}
if (agent.getWeaponPower() != null)
agent.getWeaponPower().attack(target, MBServerStatics.ONE_MINUTE);
@@ -309,10 +319,19 @@ public class CombatUtilities {
if (target == null)
return 0;
int damage = 0;
float damage = 0;
DamageType dt = getDamageType(agent);
damage = ThreadLocalRandom.current().nextInt((int)getMinDmg(agent), (int)getMaxDmg(agent) + 1);
if ((agent.agentType.equals(AIAgentType.PET)) == true || agent.isPet() == true || agent.isNecroPet() == true) {
damage = calculatePetDamage(agent);
} else if (agent.isPlayerGuard() == true) {
//damage = calculateGuardDamage(agent);
damage = calculateMobDamage(agent);
} else if (agent.getLevel() > 80) {
damage = calculateEpicDamage(agent);
} else {
damage = calculateMobDamage(agent);
}
if (AbstractWorldObject.IsAbstractCharacter(target)) {
if (((AbstractCharacter) target).isSit()) {
damage *= 2.5f; //increase damage if sitting
@@ -338,16 +357,158 @@ public class CombatUtilities {
return dt;
}
public static double getMinDmg(Mob agent) {
if(agent.equip.get(2) != null && !agent.equip.get(2).getItemBase().isShield())
return agent.minDamageHandTwo;
else return agent.minDamageHandOne;
public static int calculatePetDamage(Mob agent) {
//damage calc for pet
float range;
float damage;
float min = 40;
float max = 60;
float dmgMultiplier = 1 + agent.getBonuses().getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.None);
double minDmg = getMinDmg(min, agent, null);
double maxDmg = getMaxDmg(max, agent, null);
dmgMultiplier += agent.getLevel() * 0.1f;
range = (float) (maxDmg - minDmg);
damage = min + ((ThreadLocalRandom.current().nextFloat() * range) + (ThreadLocalRandom.current().nextFloat() * range)) / 2;
return (int) (damage * dmgMultiplier);
}
public static double getMaxDmg(Mob agent) {
if(agent.equip.get(2) != null && !agent.equip.get(2).getItemBase().isShield())
return agent.maxDamageHandTwo;
else return agent.maxDamageHandOne;
public static int calculateGuardDamage(Mob agent) {
//damage calc for guard
ItemBase weapon = agent.getEquip().get(1).getItemBase();
AbstractWorldObject target = agent.getCombatTarget();
float dmgMultiplier = 1 + agent.getBonuses().getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.None);
double minDmg = weapon.getMinDamage();
double maxDmg = weapon.getMaxDamage();
double min = getMinDmg(minDmg, agent, weapon);
double max = getMaxDmg(maxDmg, agent, weapon);
DamageType dt = weapon.getDamageType();
double range = max - min;
double damage = min + ((ThreadLocalRandom.current().nextFloat() * range) + (ThreadLocalRandom.current().nextFloat() * range)) / 2;
if (AbstractWorldObject.IsAbstractCharacter(target))
if (((AbstractCharacter) target).isSit())
damage *= 2.5f; //increase damage if sitting
if (AbstractWorldObject.IsAbstractCharacter(target))
return (int) (((AbstractCharacter) target).getResists().getResistedDamage(agent, (AbstractCharacter) target, dt, (float) damage, 0) * dmgMultiplier);
return 0;
}
public static int calculateEpicDamage(Mob agent) {
//handle r8 mob damage
DamageType dt = DamageType.Crush;
AbstractWorldObject target = agent.getCombatTarget();
float dmgMultiplier = 1 + agent.getBonuses().getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.None);
double min = agent.getMinDamageHandOne();
double max = agent.getMaxDamageHandOne();
if (agent.getEquip().get(1) != null) {
if (agent.getEquip().get(1).getItemBase() != null) {
dt = agent.getEquip().get(1).getItemBase().getDamageType();
min = agent.getMinDamageHandOne();
max = agent.getMaxDamageHandOne();
} else if (agent.getEquip().get(2).getItemBase() != null && agent.getEquip().get(2).getItemBase().isShield() == false) {
dt = agent.getEquip().get(2).getItemBase().getDamageType();
min = agent.getMinDamageHandTwo();
max = agent.getMaxDamageHandTwo();
}
}
double range = max - min;
double damage = min + ((ThreadLocalRandom.current().nextFloat() * range) + (ThreadLocalRandom.current().nextFloat() * range)) / 2;
return (int) (((AbstractCharacter) target).getResists().getResistedDamage(agent, (AbstractCharacter) target, dt, (float) damage, 0) * dmgMultiplier);
}
public static int calculateMobDamage(Mob agent) {
ItemBase weapon = null;
double minDmg;
double maxDmg;
DamageType dt;
//main hand or offhand damage
if (agent.getEquip().get(1) != null)
weapon = agent.getEquip().get(1).getItemBase();
else if (agent.getEquip().get(2) != null)
weapon = agent.getEquip().get(2).getItemBase();
if (weapon != null) {
minDmg = getMinDmg(weapon.getMinDamage(), agent, weapon);
maxDmg = getMaxDmg(weapon.getMaxDamage(), agent, weapon);
dt = weapon.getDamageType();
} else {
minDmg = agent.getMobBase().getDamageMin();
maxDmg = agent.getMobBase().getDamageMax();
dt = DamageType.Crush;
}
AbstractWorldObject target = agent.getCombatTarget();
float dmgMultiplier = 1 + agent.getBonuses().getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.None);
double range = maxDmg - minDmg;
double damage = minDmg + ((ThreadLocalRandom.current().nextFloat() * range) + (ThreadLocalRandom.current().nextFloat() * range)) / 2;
if (AbstractWorldObject.IsAbstractCharacter(target))
if (((AbstractCharacter) target).isSit())
damage *= 2.5f; //increase damage if sitting
if (AbstractWorldObject.IsAbstractCharacter(target))
return (int) (((AbstractCharacter) target).getResists().getResistedDamage(agent, (AbstractCharacter) target, dt, (float) damage, 0) * dmgMultiplier);
return 0;
}
public static double getMinDmg(double min, Mob agent, ItemBase weapon) {
int primary = agent.getStatStrCurrent();
int secondary = agent.getStatDexCurrent();
int focusLevel = 0;
int masteryLevel = 0;
if (weapon != null) {
if (weapon.isStrBased() == true) {
primary = agent.getStatStrCurrent();
secondary = agent.getStatDexCurrent();
} else {
primary = agent.getStatDexCurrent();
secondary = agent.getStatStrCurrent();
if (agent.getSkills().containsKey(weapon.getSkillRequired())) {
focusLevel = (int) agent.getSkills().get(weapon.getSkillRequired()).getModifiedAmount();
}
if (agent.getSkills().containsKey(weapon.getMastery())) {
masteryLevel = (int) agent.getSkills().get(weapon.getMastery()).getModifiedAmount();
}
}
}
return min * (pow(0.0048 * primary + .049 * (primary - 0.75), 0.5) + pow(0.0066 * secondary + 0.064 * (secondary - 0.75), 0.5) + +0.01 * (focusLevel + masteryLevel));
}
public static double getMaxDmg(double max, Mob agent, ItemBase weapon) {
int primary = agent.getStatStrCurrent();
int secondary = agent.getStatDexCurrent();
int focusLevel = 0;
int masteryLevel = 0;
if (weapon != null) {
if (weapon.isStrBased() == true) {
primary = agent.getStatStrCurrent();
secondary = agent.getStatDexCurrent();
} else {
primary = agent.getStatDexCurrent();
secondary = agent.getStatStrCurrent();
}
if (agent.getSkills().containsKey(weapon.getSkillRequired()))
focusLevel = (int) agent.getSkills().get(weapon.getSkillRequired()).getModifiedAmount();
if (agent.getSkills().containsKey(weapon.getSkillRequired()))
masteryLevel = (int) agent.getSkills().get(weapon.getMastery()).getModifiedAmount();
}
return max * (pow(0.0124 * primary + 0.118 * (primary - 0.75), 0.5) + pow(0.0022 * secondary + 0.028 * (secondary - 0.75), 0.5) + 0.0075 * (focusLevel + masteryLevel));
}
}
@@ -13,10 +13,10 @@ import engine.Enum;
import engine.Enum.GameObjectType;
import engine.Enum.ModType;
import engine.Enum.SourceType;
import engine.mobileAI.Threads.MobAIThread;
import engine.exception.MsgSendException;
import engine.gameManager.MovementManager;
import engine.math.Vector3fImmutable;
import engine.mobileAI.Threads.MobAIThread;
import engine.net.client.msg.MoveToPointMsg;
import engine.objects.*;
import org.pmw.tinylog.Logger;
@@ -38,7 +38,7 @@ public class MovementUtilities {
if (agent.getContract() != null)
guardCaptain = agent;
else
guardCaptain = (Mob) agent.guardCaptain;
guardCaptain = (Mob) agent.npcOwner;
if (guardCaptain != null) {
Building barracks = guardCaptain.building;
@@ -147,7 +147,7 @@ public class MovementUtilities {
return aiAgent.getLoc().ClosestPointOnLine(aggroTarget.getLoc(), aggroTarget.getEndLoc());
}
public static void moveToLocation(Mob agent, Vector3fImmutable newLocation, float offset, boolean isWalking) {
public static void moveToLocation(Mob agent, Vector3fImmutable newLocation, float offset) {
try {
//don't move farther than 30 units from player.
@@ -158,7 +158,7 @@ public class MovementUtilities {
agent.setFaceDir(newLoc.subtract2D(agent.getLoc()).normalize());
aiMove(agent, newLoc, isWalking);
aiMove(agent, newLoc, false);
} catch (Exception e) {
Logger.error(e.toString());
}
@@ -244,10 +244,10 @@ public class MovementUtilities {
msg.setSourceID(agent.getObjectUUID());
msg.setStartCoord(startLoc);
msg.setEndCoord(endLoc);
msg.setInBuildingFloor(-1);
msg.setUnknown01(-1);
msg.setInBuilding(-1);
msg.setStartLocType(0);
msg.setInBuildingUUID(0);
msg.setTargetType(0);
msg.setTargetID(0);
try {
+1 -1
View File
@@ -28,7 +28,7 @@ import static engine.net.MessageDispatcher.maxRecipients;
/*
* Dispatch Message is the main interface to Magicbane's threaded
* async message delivery system.
* asynch message delivery system.
*/
public class DispatchMessage {
+4 -1
View File
@@ -643,7 +643,7 @@ public class ClientMessagePump implements NetMsgHandler {
moveMsg.setStartCoord(sourcePlayer.getLoc());
moveMsg.setEndCoord(sourcePlayer.getLoc());
moveMsg.setInBuilding(-1);
moveMsg.setInBuildingFloor(-1);
moveMsg.setUnknown01(-1);
dispatch = Dispatch.borrow(sourcePlayer, moveMsg);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY);
@@ -1892,6 +1892,9 @@ public class ClientMessagePump implements NetMsgHandler {
case POWER:
PowersManager.usePower((PerformActionMsg) msg, origin, false);
break;
case REQUESTMELEEATTACK:
CombatManager.setAttackTarget((AttackCmdMsg) msg, origin);
break;
case READYTOENTER:
break;
case OPENVAULT:
+1 -1
View File
@@ -173,7 +173,7 @@ public enum Protocol {
REPAIROBJECT(0x782219CE, RepairMsg.class, null), //Repair Window Req/Ack, RepairObject item Req/Ack
REQUESTCONTENTS(0xA786B0A2, LootWindowRequestMsg.class, null), // MoveObjectToContainer Window Request
REQUESTGUILDLIST(0x85DCC6D7, ReqGuildListMsg.class, RequestGuildListHandler.class),
REQUESTMELEEATTACK(0x98C71545, AttackCmdMsg.class, AttackCmdMsgHandler.class), // Attack
REQUESTMELEEATTACK(0x98C71545, AttackCmdMsg.class, null), // Attack
REQUESTMEMBERLIST(0x3235E5EA, GuildControlMsg.class, GuildControlHandler.class), // Part of Promote/Demote, Also Player History
REQUESTTOOPENBANK(0xF26E453F, null, null), // RequestToOpenBankMsg
REQUESTTOTRADE(0x4D84259B, TradeRequestMsg.class, null), // Trade Request
@@ -1,86 +0,0 @@
package engine.net.client.handlers;
import engine.Enum;
import engine.exception.MsgSendException;
import engine.gameManager.BuildingManager;
import engine.gameManager.CombatManager;
import engine.net.client.ClientConnection;
import engine.net.client.msg.AttackCmdMsg;
import engine.net.client.msg.ClientNetMsg;
import engine.net.client.msg.TargetedActionMsg;
import engine.objects.*;
/*
* @Author:
* @Summary: Processes application protocol message which keeps
* client's tcp connection open.
*/
public class AttackCmdMsgHandler extends AbstractClientMsgHandler {
public AttackCmdMsgHandler() {
super(AttackCmdMsg.class);
}
@Override
protected boolean _handleNetMsg(ClientNetMsg baseMsg, ClientConnection origin) throws MsgSendException {
PlayerCharacter playerCharacter = origin.getPlayerCharacter();
// Member variable declaration
AttackCmdMsg msg;
// Member variable assignment
msg = (AttackCmdMsg) baseMsg;
if (TargetedActionMsg.un2cnt == 60 || TargetedActionMsg.un2cnt == 70)
return true;
if (playerCharacter == null)
return true;
AbstractWorldObject target = null;
Enum.GameObjectType targetType;
targetType = Enum.GameObjectType.values()[msg.getTargetType()];
switch(targetType){
case Mob:
target = Mob.getMob(msg.getTargetID());
break;
case PlayerCharacter:
target = PlayerCharacter.getPlayerCharacter(msg.getTargetID());
break;
case Building:
target = BuildingManager.getBuilding(msg.getTargetID());
break;
case NPC:
target = NPC.getNPC(msg.getTargetID());
break;
}
if(target == null) {
playerCharacter.setCombatTarget(null);
return true; // cannot attack a null target
}
//set sources target
playerCharacter.setCombatTarget(target);
//put in combat if not already
if (!playerCharacter.isCombat())
CombatManager.toggleCombat(true, origin);
//make character stand if sitting
if (playerCharacter.isSit())
CombatManager.toggleSit(false, origin);
CombatManager.AttackTarget(playerCharacter, target);
return true;
}
}
@@ -8,6 +8,7 @@ import engine.gameManager.BuildingManager;
import engine.gameManager.DbManager;
import engine.gameManager.NPCManager;
import engine.gameManager.SessionManager;
import engine.math.Vector3fImmutable;
import engine.net.Dispatch;
import engine.net.DispatchMessage;
import engine.net.client.ClientConnection;
@@ -15,6 +16,9 @@ import engine.net.client.msg.*;
import engine.objects.*;
import org.pmw.tinylog.Logger;
import java.util.ArrayList;
import java.util.HashMap;
/*
* @Author:
* @Summary: Processes application protocol message which
@@ -23,6 +27,8 @@ import org.pmw.tinylog.Logger;
public class MinionTrainingMsgHandler extends AbstractClientMsgHandler {
public static HashMap<Integer, ArrayList<Integer>> _minionsByCaptain = null;
public MinionTrainingMsgHandler() {
super(MinionTrainingMessage.class);
}
@@ -32,9 +38,9 @@ public class MinionTrainingMsgHandler extends AbstractClientMsgHandler {
MinionTrainingMessage minionMsg = (MinionTrainingMessage) baseMsg;
PlayerCharacter playerCharacter = SessionManager.getPlayerCharacter(origin);
PlayerCharacter player = SessionManager.getPlayerCharacter(origin);
if (playerCharacter == null)
if (player == null)
return true;
if (minionMsg.getNpcType() == Enum.GameObjectType.NPC.ordinal()) {
@@ -44,24 +50,23 @@ public class MinionTrainingMsgHandler extends AbstractClientMsgHandler {
if (npc == null)
return true;
Building building = BuildingManager.getBuildingFromCache(minionMsg.getBuildingID());
Building b = BuildingManager.getBuildingFromCache(minionMsg.getBuildingID());
if (building == null)
if (b == null)
return true;
//clear minion
if (npc.minionLock.writeLock().tryLock()) {
try {
if (minionMsg.getType() == 2) {
Mob toRemove = Mob.getFromCache(minionMsg.getUUID());
if (!npc.minions.contains(toRemove.getObjectUUID()))
if (!npc.getSiegeMinionMap().containsKey(toRemove))
return true;
npc.minions.remove(Integer.valueOf(toRemove.getObjectUUID()));
npc.getSiegeMinionMap().remove(toRemove);
WorldGrid.RemoveWorldObject(toRemove);
@@ -69,35 +74,33 @@ public class MinionTrainingMsgHandler extends AbstractClientMsgHandler {
toRemove.getParentZone().zoneMobSet.remove(toRemove);
DbManager.removeFromCache(toRemove);
if(toRemove.guardCaptain.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) {
PlayerCharacter petOwner = (PlayerCharacter) toRemove.guardCaptain;
PlayerCharacter petOwner = toRemove.getOwner();
if (petOwner != null) {
petOwner.setPet(null);
toRemove.guardCaptain = null;
toRemove.setOwner(null);
PetMsg petMsg = new PetMsg(5, null);
Dispatch dispatch = Dispatch.borrow(petOwner, petMsg);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
}
}
ManageCityAssetsMsg mca1 = new ManageCityAssetsMsg(playerCharacter, building);
// we Found the move to remove, lets break the for loop so it doesnt look for more.
ManageCityAssetsMsg mca1 = new ManageCityAssetsMsg(player, b);
mca1.actionType = 3;
mca1.setTargetType(building.getObjectType().ordinal());
mca1.setTargetID(building.getObjectUUID());
mca1.setTargetType(b.getObjectType().ordinal());
mca1.setTargetID(b.getObjectUUID());
mca1.setTargetType3(npc.getObjectType().ordinal());
mca1.setTargetID3(npc.getObjectUUID());
mca1.setAssetName1(building.getName());
mca1.setAssetName1(b.getName());
mca1.setUnknown54(1);
Dispatch dispatch = Dispatch.borrow(playerCharacter, mca1);
Dispatch dispatch = Dispatch.borrow(player, mca1);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
ManageNPCMsg mnm = new ManageNPCMsg(npc);
dispatch = Dispatch.borrow(playerCharacter, mnm);
dispatch = Dispatch.borrow(player, mnm);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
//Add Minion
@@ -112,7 +115,7 @@ public class MinionTrainingMsgHandler extends AbstractClientMsgHandler {
if (npc.getContractID() == 842)
maxSlots = 1;
if (npc.minions.size() == maxSlots)
if (npc.getSiegeMinionMap().size() == maxSlots)
return true;
int mobBase;
@@ -143,15 +146,47 @@ public class MinionTrainingMsgHandler extends AbstractClientMsgHandler {
if (mobBase == 0)
return true;
Mob siegeMob = Mob.createSiegeMinion(npc, mobBase);
Mob siegeMob = Mob.createSiegeMob(npc, mobBase, npc.getGuild(), zone, b.getLoc(), (short) 1);
if (siegeMob == null)
return true;
if (siegeMob != null) {
siegeMob.setSpawnTime(60 * 15);
Building building = BuildingManager.getBuilding(((MinionTrainingMessage) baseMsg).getBuildingID());
siegeMob.building = building;
siegeMob.parentZone = zone;
// Slot siege minion
// Can be either corner tower or bulwark.
int slot;
if (building.getBlueprint().getBuildingGroup().equals(Enum.BuildingGroup.ARTYTOWER))
slot = 2;
else
slot = ((NPC) siegeMob.npcOwner).getSiegeMinionMap().get(siegeMob) + 1; // First slot is for the captain
BuildingLocation slotLocation = BuildingManager._slotLocations.get(building.meshUUID).get(slot);
siegeMob.bindLoc = building.getLoc().add(slotLocation.getLocation());
// Rotate slot position by the building rotation
siegeMob.bindLoc = Vector3fImmutable.rotateAroundPoint(building.getLoc(), siegeMob.bindLoc, building.getBounds().getQuaternion().angleY);
siegeMob.loc = new Vector3fImmutable(siegeMob.bindLoc);
siegeMob.endLoc = new Vector3fImmutable(siegeMob.bindLoc);
zone.zoneMobSet.add(siegeMob);
siegeMob.setLoc(siegeMob.bindLoc);
}
}
ManageNPCMsg mnm = new ManageNPCMsg(npc);
mnm.setMessageType(1);
Dispatch dispatch = Dispatch.borrow(playerCharacter, mnm);
Dispatch dispatch = Dispatch.borrow(player, mnm);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
} finally {
@@ -179,13 +214,13 @@ public class MinionTrainingMsgHandler extends AbstractClientMsgHandler {
Mob toRemove = Mob.getFromCache(minionMsg.getUUID());
if (!npc.minions.contains(toRemove.getObjectUUID()))
if (!npc.getSiegeMinionMap().containsKey(toRemove))
return true;
if (!DbManager.MobQueries.REMOVE_GUARD_MINION(npc.getObjectUUID(), toRemove.firstName))
if (!DbManager.MobQueries.REMOVE_FROM_GUARDS(npc.getObjectUUID(), toRemove.getMobBaseID(), npc.getSiegeMinionMap().get(toRemove)))
return true;
npc.minions.remove(Integer.valueOf(toRemove.getObjectUUID()));
npc.getSiegeMinionMap().remove(toRemove);
WorldGrid.RemoveWorldObject(toRemove);
@@ -193,22 +228,17 @@ public class MinionTrainingMsgHandler extends AbstractClientMsgHandler {
toRemove.getParentZone().zoneMobSet.remove(toRemove);
DbManager.removeFromCache(toRemove);
PlayerCharacter petOwner = toRemove.getOwner();
if (toRemove.agentType.equals(Enum.AIAgentType.SIEGEENGINE)) {
PlayerCharacter trebOwner = (PlayerCharacter) toRemove.guardCaptain;
if (trebOwner != null) {
trebOwner.setPet(null);
toRemove.guardCaptain = null;
if (petOwner != null) {
petOwner.setPet(null);
toRemove.setOwner(null);
PetMsg petMsg = new PetMsg(5, null);
Dispatch dispatch = Dispatch.borrow(trebOwner, petMsg);
Dispatch dispatch = Dispatch.borrow(petOwner, petMsg);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
}
}
ManageCityAssetsMsg mca1 = new ManageCityAssetsMsg(playerCharacter, building);
ManageCityAssetsMsg mca1 = new ManageCityAssetsMsg(player, building);
mca1.actionType = 3;
mca1.setTargetType(building.getObjectType().ordinal());
mca1.setTargetID(building.getObjectUUID());
@@ -218,11 +248,11 @@ public class MinionTrainingMsgHandler extends AbstractClientMsgHandler {
mca1.setAssetName1(building.getName());
mca1.setUnknown54(1);
Dispatch dispatch = Dispatch.borrow(playerCharacter, mca1);
Dispatch dispatch = Dispatch.borrow(player, mca1);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
ManageNPCMsg mnm = new ManageNPCMsg(npc);
dispatch = Dispatch.borrow(playerCharacter, mnm);
dispatch = Dispatch.borrow(player, mnm);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
//Add Minion
@@ -258,7 +288,7 @@ public class MinionTrainingMsgHandler extends AbstractClientMsgHandler {
break;
}
if (npc.minions.size() == maxSlots)
if (npc.getSiegeMinionMap().size() == maxSlots)
return true;
int mobBase = npc.getMobBaseID();
@@ -268,12 +298,12 @@ public class MinionTrainingMsgHandler extends AbstractClientMsgHandler {
String pirateName = NPCManager.getPirateName(mobBase);
Mob toCreate = Mob.createGuardMinion(npc, npc.getLevel(), pirateName);
if (toCreate == null)
if (!DbManager.MobQueries.ADD_TO_GUARDS(npc.getObjectUUID(), mobBase, pirateName, npc.getSiegeMinionMap().size() + 1))
return true;
if (!DbManager.MobQueries.ADD_GUARD_MINION(npc.getObjectUUID(), pirateName))
Mob toCreate = Mob.createGuardMob(npc, npc.getGuild(), zone, building.getLoc(), npc.getLevel(), pirateName);
if (toCreate == null)
return true;
if (toCreate != null) {
@@ -284,7 +314,7 @@ public class MinionTrainingMsgHandler extends AbstractClientMsgHandler {
ManageNPCMsg mnm = new ManageNPCMsg(npc);
mnm.setMessageType(1);
Dispatch dispatch = Dispatch.borrow(playerCharacter, mnm);
Dispatch dispatch = Dispatch.borrow(player, mnm);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
} catch (Exception e) {
@@ -9,14 +9,12 @@
package engine.net.client.handlers;
import engine.Enum;
import engine.exception.MsgSendException;
import engine.gameManager.BuildingManager;
import engine.gameManager.MovementManager;
import engine.net.client.ClientConnection;
import engine.net.client.msg.ClientNetMsg;
import engine.net.client.msg.MoveToPointMsg;
import engine.objects.*;
import engine.objects.PlayerCharacter;
public class MoveToPointHandler extends AbstractClientMsgHandler {
@@ -28,11 +26,13 @@ public class MoveToPointHandler extends AbstractClientMsgHandler {
protected boolean _handleNetMsg(ClientNetMsg baseMsg,
ClientConnection origin) throws MsgSendException {
MoveToPointMsg msg = (MoveToPointMsg) baseMsg;
PlayerCharacter pc = origin.getPlayerCharacter();
if(pc == null)
return true;
PlayerCharacter pc = (origin != null) ? (origin.getPlayerCharacter()) : null;
if (pc == null)
return false;
MovementManager.movement(msg, pc);
return true;
}
}
@@ -7,6 +7,7 @@ import engine.Enum.ProfitType;
import engine.exception.MsgSendException;
import engine.gameManager.BuildingManager;
import engine.gameManager.DbManager;
import engine.gameManager.NPCManager;
import engine.gameManager.SessionManager;
import engine.math.FastMath;
import engine.math.Vector3fImmutable;
@@ -36,7 +37,7 @@ public class OrderNPCMsgHandler extends AbstractClientMsgHandler {
super(OrderNPCMsg.class);
}
public static void processRedeedHireling(AbstractCharacter hireling, Building building, ClientConnection origin) {
public static void processRedeedMob(Mob mob, Building building, ClientConnection origin) {
PlayerCharacter player;
Contract contract;
@@ -47,28 +48,33 @@ public class OrderNPCMsgHandler extends AbstractClientMsgHandler {
player = SessionManager.getPlayerCharacter(origin);
itemMan = player.getCharItemManager();
contract = hireling.contract;
contract = mob.getContract();
if (!player.getCharItemManager().hasRoomInventory((short) 1)) {
ErrorPopupMsg.sendErrorPopup(player, 21);
return;
}
if (!building.getHirelings().containsKey(hireling))
if (!building.getHirelings().containsKey(mob))
return;
BuildingManager.removeHireling(building, hireling);
if (!NPCManager.removeMobileFromBuilding(mob, building)) {
PlaceAssetMsg.sendPlaceAssetError(player.getClientConnection(), 1, "A Serious error has occurred. Please post details for to ensure transaction integrity");
return;
}
building.getHirelings().remove(mob);
itemBase = ItemBase.getItemBase(contract.getContractID());
if (itemBase == null) {
Logger.error("Could not find Contract for npc: " + hireling.getObjectUUID());
Logger.error("Could not find Contract for npc: " + mob.getObjectUUID());
return;
}
boolean itemWorked = false;
item = new Item(itemBase, player.getObjectUUID(), Enum.OwnerType.PlayerCharacter, (byte) ((byte) hireling.getRank() - 1), (byte) ((byte) hireling.getRank() - 1), (short) 1, (short) 1, true, false, Enum.ItemContainerType.INVENTORY, (byte) 0, new ArrayList<>(), "");
item = new Item(itemBase, player.getObjectUUID(), Enum.OwnerType.PlayerCharacter, (byte) ((byte) mob.getRank() - 1), (byte) ((byte) mob.getRank() - 1), (short) 1, (short) 1, true, false, Enum.ItemContainerType.INVENTORY, (byte) 0, new ArrayList<>(), "");
item.setNumOfItems(1);
item.containerType = Enum.ItemContainerType.INVENTORY;
@@ -206,6 +212,10 @@ public class OrderNPCMsgHandler extends AbstractClientMsgHandler {
return;
}
for (AbstractCharacter guard : building.getHirelings().keySet()) {
if (guard.getObjectType() == GameObjectType.Mob)
((Mob) guard).setPatrolPointIndex(0);
}
} else if (building.getPatrolPoints() != null)
ClearPatrolPoints(building.getObjectUUID());
@@ -213,6 +223,10 @@ public class OrderNPCMsgHandler extends AbstractClientMsgHandler {
AddSentryPoints(building.getObjectUUID(), orderNpcMsg.getSentryPoints());
} else if (building.getSentryPoints() != null)
ClearSentryPoints(building.getObjectUUID());
// Dispatch dispatch = Dispatch.borrow(pc, msg);
// DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
}
private static void processUpgradeNPC(PlayerCharacter player, AbstractCharacter abstractCharacter) {
@@ -276,6 +290,28 @@ public class OrderNPCMsgHandler extends AbstractClientMsgHandler {
}
}
private static synchronized void processRedeedNPC(AbstractCharacter abstractCharacter, Building building, ClientConnection origin) {
// Member variable declaration
switch (abstractCharacter.getObjectType()) {
case NPC:
NPC npc = (NPC) abstractCharacter;
Building cityBuilding = npc.getBuilding();
if (cityBuilding == null)
return;
BuildingManager.processRedeedNPC(npc, npc.building, origin);
break;
case Mob:
Mob mob = (Mob) abstractCharacter;
processRedeedMob(mob, mob.building, origin);
break;
}
}
private static boolean AddPatrolPoints(int buildingID, ArrayList<Vector3fImmutable> patrolPoints) {
Building building = BuildingManager.getBuildingFromCache(buildingID);
@@ -466,7 +502,7 @@ public class OrderNPCMsgHandler extends AbstractClientMsgHandler {
if (BuildingManager.PlayerCanControlNotOwner(building, player) == false)
return true;
processRedeedHireling(npc, building, origin);
processRedeedNPC(npc, building, origin);
return true;
//MB TODO HANDLE all profits.
case 7:
@@ -505,7 +541,7 @@ public class OrderNPCMsgHandler extends AbstractClientMsgHandler {
} else if (orderNPCMsg.getObjectType() == GameObjectType.Mob.ordinal()) {
mob = Mob.getMob(orderNPCMsg.getNpcUUID());
mob = Mob.getFromCacheDBID(orderNPCMsg.getNpcUUID());
if (mob == null)
return true;
@@ -534,7 +570,10 @@ public class OrderNPCMsgHandler extends AbstractClientMsgHandler {
if (building.getHirelings().containsKey(mob) == false)
return true;
BuildingManager.removeHireling(building, mob);
if (NPCManager.removeMobileFromBuilding(mob, building) == false) {
PlaceAssetMsg.sendPlaceAssetError(player.getClientConnection(), 1, "A Serious error has occurred. Please post details for to ensure transaction integrity");
return true;
}
ManageCityAssetsMsg manageCityAssetsMsg = new ManageCityAssetsMsg();
manageCityAssetsMsg.actionType = SVR_CLOSE_WINDOW;
@@ -569,7 +608,7 @@ public class OrderNPCMsgHandler extends AbstractClientMsgHandler {
if (BuildingManager.PlayerCanControlNotOwner(building, player) == false)
return true;
processRedeedHireling(mob, building, origin);
processRedeedNPC(mob, building, origin);
return true;
//MB TODO HANDLE all profits.
case 7:
+15 -18
View File
@@ -27,6 +27,7 @@ import org.pmw.tinylog.Logger;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
/**
@@ -95,7 +96,7 @@ public class ManageNPCMsg extends ClientNetMsg {
writer.putString("A weapon suited to laying siege");
}
private static void serializeGuardList(ByteBufferWriter writer, int minion, Mob captain) {
private static void serializeGuardList(ByteBufferWriter writer, int minion) {
writer.putInt(1);
@@ -105,7 +106,7 @@ public class ManageNPCMsg extends ClientNetMsg {
writer.putInt(minion);
writer.putInt(1);
writer.putInt(minion);
writer.putInt(captain.getRank());//minion rank
writer.putInt(1);
writer.put((byte) 0);
writer.putInt(600); //roll time
@@ -342,17 +343,14 @@ public class ManageNPCMsg extends ClientNetMsg {
writer.putInt(0); //runemaster list
//artillery captain list
writer.putInt(1 + npc.minions.size());
ConcurrentHashMap<Mob, Integer> siegeMinions = npc.getSiegeMinionMap();
writer.putInt(1 + siegeMinions.size());
serializeBulwarkList(writer, 1); //Trebuchet
//serializeBulwarkList(writer, 2); //Ballista
if (npc.minions != null && npc.minions.size() > 0)
for (Integer minionUUID : npc.minions) {
Mob mob = Mob.getMob(minionUUID);
if (siegeMinions != null && siegeMinions.size() > 0)
for (Mob mob : siegeMinions.keySet()) {
this.unknown83 = mob.getObjectUUID();
writer.putInt(2);
writer.putInt(mob.getObjectType().ordinal());
@@ -368,7 +366,7 @@ public class ManageNPCMsg extends ClientNetMsg {
long timeLife = upgradeTime - curTime;
if (upgradeTime * 1000 > System.currentTimeMillis()) {
if (mob.guardCaptain.isAlive()) {
if (mob.npcOwner.isAlive()) {
writer.put((byte) 0);//shows respawning timer
writer.putInt(mob.spawnTime);
writer.putInt(mob.spawnTime);
@@ -559,7 +557,7 @@ public class ManageNPCMsg extends ClientNetMsg {
} else if (this.targetType == GameObjectType.Mob.ordinal()) {
mobA = Mob.getMob(this.targetID);
mobA = Mob.getFromCacheDBID(this.targetID);
if (mobA == null) {
Logger.error("Missing Mob of ID " + this.targetID);
@@ -668,15 +666,14 @@ public class ManageNPCMsg extends ClientNetMsg {
writer.putInt(0); //runemaster list
//artillery captain list
ConcurrentHashMap<Mob, Integer> siegeMinions = mobA.getSiegeMinionMap();
writer.putInt(mobA.minions.size() + 1);
writer.putInt(siegeMinions.size() + 1);
serializeGuardList(writer, mobA.getContract().getContractID()); //Guard
serializeGuardList(writer, mobA.getContract().getContractID(), mobA); //Guard
if (siegeMinions != null && siegeMinions.size() > 0)
if (mobA.minions != null && mobA.minions.size() > 0)
for (Integer minionUUID : mobA.minions) {
Mob mob = Mob.getMob(minionUUID);
for (Mob mob : siegeMinions.keySet()) {
this.unknown83 = mob.getObjectUUID();
writer.putInt(2);
writer.putInt(mob.getObjectType().ordinal());
@@ -692,7 +689,7 @@ public class ManageNPCMsg extends ClientNetMsg {
long timeLife = upgradeTime - curTime;
if (upgradeTime * 1000 > System.currentTimeMillis()) {
if (mob.guardCaptain.isAlive()) {
if (mob.npcOwner.isAlive()) {
writer.put((byte) 0);//shows respawning timer
writer.putInt(mob.spawnTime);
writer.putInt(mob.spawnTime);
+55 -56
View File
@@ -10,7 +10,6 @@
package engine.net.client.msg;
import engine.Enum.GameObjectType;
import engine.gameManager.BuildingManager;
import engine.gameManager.ZoneManager;
import engine.math.Vector3fImmutable;
import engine.net.AbstractConnection;
@@ -22,19 +21,19 @@ import engine.objects.Building;
public class MoveToPointMsg extends ClientNetMsg {
private int sourceType; //ordinal of the character type that sent this message 54=PlayerCharacter
private int sourceID; // uuid of the source character of this message
private float startLat; //start loc of move message (offset if inside a building not world loc)
private float startLon; //start loc of move message (offset if inside a building not world loc)
private float startAlt; //start loc of move message (offset if inside a building not world loc)
private float endLat; //end loc of move message (offset if inside a building not world loc)
private float endLon; //end loc of move message (offset if inside a building not world loc)
private float endAlt; //end loc of move message (offset if inside a building not world loc)
private int startLocType; // enum ordinal of the object player is inside 0=nothing 8=building
private int inBuildingUUID; // uuid of the building character is currently inside
private int inBuilding; // is inside a building 0=true -1=false
private int inBuildingFloor; // floor of building character is currently in -1=not inside building 0/1/2/3 = floor number
private byte initiatedByAttack; // move message sent as a result of move to target to attack 0=false 1=true
private int sourceType;
private int sourceID;
private float startLat;
private float startLon;
private float startAlt;
private float endLat;
private float endLon;
private float endAlt;
private int targetType;
private int targetID;
private int inBuilding; // 0=true, -1=false 0/1/2 = floor you are on
private int unknown01;
private byte unknown02;
private byte unknown03;
/**
@@ -55,11 +54,11 @@ public class MoveToPointMsg extends ClientNetMsg {
this.endLat = msg.endLat;
this.endLon = msg.endLon;
this.endAlt = msg.endAlt;
this.startLocType = msg.startLocType;
this.inBuildingUUID = msg.inBuildingUUID;
this.targetType = msg.targetType;
this.targetID = msg.targetID;
this.inBuilding = msg.inBuilding;
this.inBuildingFloor = msg.inBuildingFloor;
this.initiatedByAttack = msg.initiatedByAttack;
this.unknown01 = msg.unknown01;
this.unknown02 = msg.unknown02;
this.unknown03 = msg.unknown03;
}
@@ -74,11 +73,11 @@ public class MoveToPointMsg extends ClientNetMsg {
this.endLat = building.getLoc().x;
this.endLon = building.getLoc().z;
this.endAlt = building.getLoc().y;
this.startLocType = 0;
this.inBuildingUUID = 0;
this.targetType = 0;
this.targetID = 0;
this.inBuilding = -1;
this.inBuildingFloor = -1;
this.initiatedByAttack = 0;
this.unknown01 = -1;
this.unknown02 = 0;
this.unknown03 = 0;
}
@@ -109,11 +108,11 @@ public class MoveToPointMsg extends ClientNetMsg {
writer.putFloat(this.endAlt);
writer.putFloat(this.endLon);
writer.putInt(this.startLocType);
writer.putInt(this.inBuildingUUID);
writer.putInt(this.targetType);
writer.putInt(this.targetID);
writer.putInt(this.inBuilding);
writer.putInt(this.inBuildingFloor);
writer.putInt(this.unknown01);
writer.put((byte) 0);
writer.put((byte) 0);
@@ -136,13 +135,13 @@ public class MoveToPointMsg extends ClientNetMsg {
this.endAlt = reader.getFloat();
this.endLon = reader.getFloat();
this.startLocType = reader.getInt();
this.inBuildingUUID = reader.getInt();
this.targetType = reader.getInt();
this.targetID = reader.getInt();
this.inBuilding = reader.getInt();
this.inBuildingFloor = reader.getInt();
this.unknown01 = reader.getInt();
this.initiatedByAttack = reader.get();
this.unknown02 = reader.get();
this.unknown03 = reader.get();
}
@@ -210,20 +209,20 @@ public class MoveToPointMsg extends ClientNetMsg {
this.endAlt = value;
}
public int getStartLocType() {
return this.startLocType;
public int getTargetType() {
return this.targetType;
}
public void setStartLocType(int value) {
this.startLocType = value;
public void setTargetType(int value) {
this.targetType = value;
}
public int getInBuildingUUID() {
return this.inBuildingUUID;
public int getTargetID() {
return this.targetID;
}
public void setInBuildingUUID(int value) {
this.inBuildingUUID = value;
public void setTargetID(int value) {
this.targetID = value;
}
public int getInBuilding() {
@@ -234,8 +233,12 @@ public class MoveToPointMsg extends ClientNetMsg {
this.inBuilding = value;
}
public void setInBuildingFloor(int value) {
this.inBuildingFloor = value;
public int getUnknown01() {
return this.unknown01;
}
public void setUnknown01(int value) {
this.unknown01 = value;
}
public void setStartCoord(Vector3fImmutable value) {
@@ -251,8 +254,8 @@ public class MoveToPointMsg extends ClientNetMsg {
}
public void clearTarget() {
this.startLocType = 0;
this.inBuildingUUID = 0;
this.targetType = 0;
this.targetID = 0;
}
public void setPlayer(AbstractCharacter ac) {
@@ -260,10 +263,10 @@ public class MoveToPointMsg extends ClientNetMsg {
this.sourceID = ac.getObjectUUID();
this.setStartCoord(ac.getLoc());
this.setEndCoord(ac.getEndLoc());
this.startLocType = 0;
this.inBuildingUUID = 0;
this.targetType = 0;
this.targetID = 0;
this.inBuilding = ac.getInBuilding();
this.inBuildingFloor = ac.getInFloorID();
this.unknown01 = ac.getInFloorID();
}
@@ -271,10 +274,10 @@ public class MoveToPointMsg extends ClientNetMsg {
if (target == null) {
this.setStartCoord(ac.getLoc());
this.setEndCoord(ac.getEndLoc());
this.startLocType = 0;
this.inBuildingUUID = 0;
this.targetType = 0;
this.targetID = 0;
this.inBuilding = -1;
this.inBuildingFloor = -1;
this.unknown01 = -1;
} else {
Vector3fImmutable convertLocStart = ZoneManager.convertWorldToLocal(target, ac.getLoc());
Vector3fImmutable convertLocEnd = convertLocStart;
@@ -283,10 +286,10 @@ public class MoveToPointMsg extends ClientNetMsg {
this.setStartCoord(convertLocStart);
this.setEndCoord(convertLocEnd);
this.startLocType = GameObjectType.Building.ordinal();
this.inBuildingUUID = target.getObjectUUID();
this.targetType = GameObjectType.Building.ordinal();
this.targetID = target.getObjectUUID();
this.inBuilding = ac.getInBuilding();
this.inBuildingFloor = ac.getInFloorID();
this.unknown01 = ac.getInFloorID();
}
}
@@ -295,11 +298,7 @@ public class MoveToPointMsg extends ClientNetMsg {
return unknown03;
}
public int getInitiatedFromAttack() {
return initiatedByAttack;
}
public int getInBuildingFloor() {
return this.inBuildingFloor;
public int getUnknown02() {
return unknown02;
}
}
+56 -62
View File
@@ -14,7 +14,10 @@ import engine.Enum.*;
import engine.InterestManagement.InterestManager;
import engine.InterestManagement.WorldGrid;
import engine.exception.SerializationException;
import engine.gameManager.*;
import engine.gameManager.CombatManager;
import engine.gameManager.ConfigManager;
import engine.gameManager.MovementManager;
import engine.gameManager.PowersManager;
import engine.job.AbstractJob;
import engine.job.JobContainer;
import engine.job.JobScheduler;
@@ -36,7 +39,6 @@ import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.ReentrantReadWriteLock;
@@ -50,8 +52,8 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
public int contractUUID;
public Contract contract;
public String firstName;
public String lastName;
protected String firstName;
protected String lastName;
protected short statStrCurrent;
protected short statDexCurrent;
protected short statConCurrent;
@@ -69,7 +71,7 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
public Guild guild;
protected byte runningTrains;
protected ConcurrentHashMap<Integer, CharacterPower> powers;
public ConcurrentHashMap<String, CharacterSkill> skills;
protected ConcurrentHashMap<String, CharacterSkill> skills;
// Variables NOT to be stored in db
protected boolean sit = false;
protected boolean walkMode;
@@ -86,20 +88,20 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
protected AtomicFloat mana = new AtomicFloat();
protected float manaMax; // Health/Mana/Stamina
protected AtomicBoolean isAlive = new AtomicBoolean(true);
public Resists resists = new Resists("Genric");
protected Resists resists = new Resists("Genric");
protected ConcurrentHashMap<String, JobContainer> timers;
protected ConcurrentHashMap<String, Long> timestamps;
public int atrHandOne;
public int atrHandTwo;
public int minDamageHandOne;
public int maxDamageHandOne;
public int minDamageHandTwo;
public int maxDamageHandTwo;
public float rangeHandOne;
public float rangeHandTwo;
public float speedHandOne;
public float speedHandTwo;
public int defenseRating;
protected int atrHandOne;
protected int atrHandTwo;
protected int minDamageHandOne;
protected int maxDamageHandOne;
protected int minDamageHandTwo;
protected int maxDamageHandTwo;
protected float rangeHandOne;
protected float rangeHandTwo;
protected float speedHandOne;
protected float speedHandTwo;
protected int defenseRating;
protected boolean isActive; // <-Do not use this for deleting character!
protected float altitude = 0; // 0=on terrain, 1=tier 1, 2=tier 2, etc.
protected ConcurrentHashMap<Integer, JobContainer> recycleTimers;
@@ -115,35 +117,16 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
protected boolean movingUp = false;
private float desiredAltitude = 0;
private long takeOffTime = 0;
private float hateValue = 0;
private long lastHateUpdate = 0;
private boolean collided = false;
private byte aoecntr = 0;
public int hidden = 0; // current rank of hide/sneak/invis
public CopyOnWriteArrayList<Integer> minions = new CopyOnWriteArrayList();
public AbstractCharacter() {
super();
this.firstName = "";
this.lastName = "";
this.statStrCurrent = (short) 0;
this.statDexCurrent = (short) 0;
this.statConCurrent = (short) 0;
this.statIntCurrent = (short) 0;
this.statSpiCurrent = (short) 0;
this.unusedStatPoints = (short) 0;
this.level = (short) 0; // TODO get this from MobsBase later
this.exp = 1;
this.walkMode = true;
this.bindLoc = Vector3fImmutable.ZERO;
this.faceDir = Vector3fImmutable.ZERO;
this.runningTrains = (byte) 0;
this.skills = new ConcurrentHashMap<>();
this.powers = new ConcurrentHashMap<>();
this.powers = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
this.skills = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
this.initializeCharacter();
}
@@ -231,6 +214,8 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
this.skills = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
this.initializeCharacter();
// Dangerous to use THIS in a constructor!!!
this.charItemManager = new CharacterItemManager(this);
}
/**
@@ -273,6 +258,8 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
this.powers = new ConcurrentHashMap<>();
this.initializeCharacter();
// Dangerous to use THIS in a constructor!!!
this.charItemManager = new CharacterItemManager(this);
}
/**
@@ -304,6 +291,8 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
this.powers = new ConcurrentHashMap<>();
initializeCharacter();
// Dangerous to use THIS in a constructor!!!
this.charItemManager = new CharacterItemManager(this);
}
/**
@@ -353,6 +342,9 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
this.powers = new ConcurrentHashMap<>();
this.initializeCharacter();
// Dangerous to use THIS in a constructor!!!
this.charItemManager = new CharacterItemManager(this);
}
public static int getBankCapacity() {
@@ -1104,7 +1096,6 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
}
public final void setCombatTarget(final AbstractWorldObject value) {
if(this.getObjectTypeMask() == 2050) {//MOB?
if (value == null) {
if (this.isCombat()) {
@@ -1122,9 +1113,7 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
}
}
}
this.combatTarget = value;
}
public final ConcurrentHashMap<String, JobContainer> getTimers() {
@@ -1241,29 +1230,11 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
CombatManager.handleRetaliate(this, attacker);
}
if(this.getObjectType().equals(GameObjectType.Mob)){
//handle hate value addition
Mob target = (Mob)this;
if (attacker.getObjectType().equals(GameObjectType.PlayerCharacter)) {
target.playerAgroMap.put(attacker.getObjectUUID(), target.playerAgroMap.get(attacker.getObjectUUID()) + value);
if (target.isPlayerGuard()){
if(target.guardedCity != null && target.guardedCity.cityOutlaws.contains(attacker.getObjectUUID()) == false)
target.guardedCity.cityOutlaws.add(attacker.getObjectUUID());
}
}
} else if(this.getObjectType().equals(GameObjectType.PlayerCharacter)){
City playerCity = ZoneManager.getCityAtLocation(this.loc);
if(playerCity != null){
if(!attacker.getGuild().getNation().equals(playerCity.getGuild().getNation()))
if(!playerCity.getGuild().getNation().getAllyList().contains(attacker.getGuild().getNation()))
if(!playerCity.cityOutlaws.contains(attacker.getObjectUUID()))
playerCity.cityOutlaws.add(attacker.getObjectUUID());
}
}
return newHealth - oldHealth;
} finally {
this.healthLock.writeLock().unlock();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
@@ -1787,6 +1758,29 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
this.inBuildingID = inBuildingID;
}
public float getHateValue() {
if (this.hateValue <= 0) {
this.hateValue = 0;
return hateValue;
}
if (this.lastHateUpdate == 0) {
this.lastHateUpdate = System.currentTimeMillis();
return this.hateValue;
}
long duration = System.currentTimeMillis() - this.lastHateUpdate;
//convert duration to seconds and multiply Hate Delimiter.
float modAmount = duration / 1000 * MBServerStatics.PLAYER_HATE_DELIMITER;
this.hateValue -= modAmount;
this.lastHateUpdate = System.currentTimeMillis();
return this.hateValue;
}
public void setHateValue(float hateValue) {
this.lastHateUpdate = System.currentTimeMillis();
this.hateValue = hateValue;
}
public int getInFloorID() {
return inFloorID;
}
@@ -9,7 +9,6 @@
package engine.objects;
import ch.claude_martin.enumbitset.EnumBitSet;
import engine.Enum;
import engine.Enum.GameObjectType;
import engine.Enum.ModType;
@@ -33,19 +32,6 @@ public abstract class AbstractIntelligenceAgent extends AbstractCharacter {
public boolean assist = false;
public Enum.AIAgentType agentType = Enum.AIAgentType.MOBILE;
public AbstractCharacter guardCaptain;
public EnumBitSet<Enum.MonsterType> notEnemy = EnumBitSet.noneOf(Enum.MonsterType.class);
public EnumBitSet<Enum.MonsterType> enemy = EnumBitSet.noneOf(Enum.MonsterType.class);
;
public Enum.MobBehaviourType behaviourType;
public ArrayList<Vector3fImmutable> patrolPoints;
public int lastPatrolPointIndex = 0;
public long stopPatrolTime = 0;
public City guardedCity;
public AbstractIntelligenceAgent() {
super();
}
public AbstractIntelligenceAgent(ResultSet rs) throws SQLException {
super(rs);
@@ -101,8 +87,7 @@ public abstract class AbstractIntelligenceAgent extends AbstractCharacter {
this.agentType = Enum.AIAgentType.CHARMED;
if (this.getObjectType().equals(GameObjectType.Mob)) {
((Mob) this).guardCaptain = owner;
((Mob) this).setOwner(owner);
}
}
@@ -125,6 +110,14 @@ public abstract class AbstractIntelligenceAgent extends AbstractCharacter {
return 0;
}
public PlayerCharacter getOwner() {
if (this.getObjectType().equals(GameObjectType.Mob))
return this.getOwner();
return null;
}
public boolean getSafeZone() {
ArrayList<Zone> allIn = ZoneManager.getAllZonesIn(this.getLoc());
@@ -163,11 +156,9 @@ public abstract class AbstractIntelligenceAgent extends AbstractCharacter {
this.setCombatTarget(null);
}
// clear owner and set not alive
//clear owner
this.isAlive.set(false);
PlayerCharacter owner = (PlayerCharacter) this.guardCaptain;
PlayerCharacter owner = this.getOwner();
//close pet window
@@ -183,7 +174,7 @@ public abstract class AbstractIntelligenceAgent extends AbstractCharacter {
owner.setPet(null);
if (this.getObjectType().equals(GameObjectType.Mob))
this.guardCaptain = null;
((Mob) this).setOwner(null);
}
+1 -3
View File
@@ -357,9 +357,7 @@ public abstract class AbstractWorldObject extends AbstractGameObject {
Mob mob = (Mob) this;
if (mob.isSiege()) {
if (mob.isPet()) {
PlayerCharacter petOwner = (PlayerCharacter) mob.guardCaptain;
PlayerCharacter petOwner = mob.getOwner();
if (petOwner != null && source.equals(EffectSourceType.Effect)) {
petOwner.dismissPet();
return;
-12
View File
@@ -537,18 +537,6 @@ public class Building extends AbstractWorldObject {
if (value < 0)
Mine.SendMineAttackMessage(this);
City playerCity = ZoneManager.getCityAtLocation(this.loc);
if(playerCity != null){
if(this.getGuild().getNation().equals(playerCity.getTOL().getGuild().getNation())){
//friendly building has been attacked, add attacker to city outlaw list
if(!playerCity.cityOutlaws.contains(attacker.getObjectUUID()) && attacker.getObjectType().equals(GameObjectType.PlayerCharacter))
playerCity.cityOutlaws.add(attacker.getObjectUUID());
for(Mob guard : playerCity.getParent().zoneMobSet)
if(guard.combatTarget == null)
guard.setCombatTarget(attacker);
}
}
return newHealth - oldHealth;
+25 -31
View File
@@ -223,7 +223,7 @@ public class CharacterSkill extends AbstractGameObject {
this.numTrains.set(0);
this.ownerUID = pc.getObjectUUID();
calculateBaseAmount();
calculateModifiedAmount(false);
calculateModifiedAmount();
this.skillType = CharacterSkills.GetCharacterSkillByToken(this.skillsBase.getToken());
}
@@ -238,7 +238,7 @@ public class CharacterSkill extends AbstractGameObject {
this.ownerUID = pc.getObjectUUID();
this.trained = true;
calculateBaseAmount();
calculateModifiedAmount(false);
calculateModifiedAmount();
this.skillType = CharacterSkills.GetCharacterSkillByToken(this.skillsBase.getToken());
}
@@ -254,7 +254,7 @@ public class CharacterSkill extends AbstractGameObject {
this.numTrains.set(rs.getShort("trains"));
this.ownerUID = pc.getObjectUUID();
calculateBaseAmount();
calculateModifiedAmount(false);
calculateModifiedAmount();
this.skillType = CharacterSkills.GetCharacterSkillByToken(this.skillsBase.getToken());
}
@@ -264,9 +264,8 @@ public class CharacterSkill extends AbstractGameObject {
this.numTrains.set(trains);
this.ownerUID = mob.getObjectUUID();
this.isMobOwner = true;
boolean isGuard = mob.agentType.equals(Enum.AIAgentType.GUARDCAPTAIN) || mob.agentType.equals(Enum.AIAgentType.GUARDMINION);
calculateMobBaseAmount(isGuard);
calculateModifiedAmount(isGuard);
calculateMobBaseAmount();
calculateModifiedAmount();
this.skillType = CharacterSkills.GetCharacterSkillByToken(this.skillsBase.getToken());
}
@@ -278,7 +277,7 @@ public class CharacterSkill extends AbstractGameObject {
this.ownerUID = rs.getInt("CharacterID");
// this.owner = DbManager.PlayerCharacterQueries.GET_PLAYER_CHARACTER(rs.getInt("CharacterID"));
calculateBaseAmount();
calculateModifiedAmount(false);
calculateModifiedAmount();
this.skillType = CharacterSkills.GetCharacterSkillByToken(this.skillsBase.getToken());
}
@@ -371,7 +370,7 @@ public class CharacterSkill extends AbstractGameObject {
String name = it.next();
CharacterSkill cs = skills.get(name);
if (cs != null)
cs.calculateModifiedAmount(false);
cs.calculateModifiedAmount();
}
@@ -757,7 +756,7 @@ public class CharacterSkill extends AbstractGameObject {
//recalculate this skill
calculateBaseAmount();
calculateModifiedAmount(false);
calculateModifiedAmount();
//see if any new skills or powers granted
pc.calculateSkills();
@@ -849,7 +848,7 @@ public class CharacterSkill extends AbstractGameObject {
if (recalculate) {
//recalculate this skill
calculateBaseAmount();
calculateModifiedAmount(false);
calculateModifiedAmount();
//see if any skills or powers removed
pc.calculateSkills();
@@ -888,7 +887,7 @@ public class CharacterSkill extends AbstractGameObject {
if (recalculate) {
//recalculate this skill
calculateBaseAmount();
calculateModifiedAmount(false);
calculateModifiedAmount();
//see if any skills or powers removed
pc.calculateSkills();
@@ -1017,8 +1016,7 @@ public class CharacterSkill extends AbstractGameObject {
this.modifiedAmountBeforeMods = Math.round(this.baseAmountBeforeMods + calculateAmountAfterTrains());
}
public void calculateMobBaseAmount(boolean isGuard) {
if(!isGuard) {
public void calculateMobBaseAmount() {
if (CharacterSkill.GetOwner(this) == null) {
Logger.error("owner not found for owner uuid : " + this.ownerUID);
this.baseAmount = 1;
@@ -1032,19 +1030,19 @@ public class CharacterSkill extends AbstractGameObject {
this.modifiedAmount = 1;
return;
}
}
//Get any rune bonus
float bonus = 0f;
//TODO SKILLS RUNES
float base = 7f;
float statMod = 0.5f;
if (CharacterSkill.GetOwner(this) != null && CharacterSkill.GetOwner(this).getBonuses() != null) {
if (CharacterSkill.GetOwner(this).getBonuses() != null) {
//Get bonuses from runes
bonus = CharacterSkill.GetOwner(this).getBonuses().getSkillBonus(this.skillsBase.sourceType);
}
//Get Base skill for unmodified stats
float base = 7f;
float statMod = 0.5f;
if (this.skillsBase.getStrMod() > 0)
statMod += (float) this.skillsBase.getStrMod() * (float) ((Mob) CharacterSkill.GetOwner(this)).getMobBase().getMobBaseStats().getBaseStr() / 100f;
if (this.skillsBase.getDexMod() > 0)
@@ -1059,7 +1057,6 @@ public class CharacterSkill extends AbstractGameObject {
statMod = 1f;
else if (statMod > 600)
statMod = 600f;
}
base += CharacterSkill.baseSkillValues[(int) statMod];
if (base + bonus < 1f)
@@ -1069,27 +1066,25 @@ public class CharacterSkill extends AbstractGameObject {
this.modifiedAmountBeforeMods = (int) (this.baseAmountBeforeMods + calculateAmountAfterTrains());
}
public void calculateModifiedAmount(boolean isGuard) {
if(!isGuard) {
public void calculateModifiedAmount() {
if (CharacterSkill.GetOwner(this) == null || this.skillsBase == null) {
Logger.error("owner or SkillsBase not found for skill " + this.getObjectUUID());
this.baseAmount = 1;
this.modifiedAmount = 1;
return;
}
}
//Get any rune bonus
float bonus = 0f;
float base = 7f;
float statMod = 0.5f;
if (CharacterSkill.GetOwner(this) != null && CharacterSkill.GetOwner(this).getBonuses() != null) {
if (CharacterSkill.GetOwner(this).getBonuses() != null) {
//Get bonuses from runes
bonus = CharacterSkill.GetOwner(this).getBonuses().getSkillBonus(this.skillsBase.sourceType);
}
//Get Base skill for modified stats
//TODO this fomula needs verified
float base = 7f;
float statMod = 0.5f;
if (this.skillsBase.getStrMod() > 0)
statMod += (float) this.skillsBase.getStrMod() * (float) CharacterSkill.GetOwner(this).getStatStrCurrent() / 100f;
if (this.skillsBase.getDexMod() > 0)
@@ -1104,13 +1099,12 @@ public class CharacterSkill extends AbstractGameObject {
statMod = 1f;
else if (statMod > 600)
statMod = 600f;
}
base += CharacterSkill.baseSkillValues[(int) statMod];
SourceType sourceType = SourceType.GetSourceType(this.skillsBase.getNameNoSpace());
//Get any rune, effect and item bonus
if (CharacterSkill.GetOwner(this) != null && CharacterSkill.GetOwner(this).getBonuses() != null) {
if (CharacterSkill.GetOwner(this).getBonuses() != null) {
//add bonuses from effects/items and runes
base += bonus + CharacterSkill.GetOwner(this).getBonuses().getFloat(ModType.Skill, sourceType);
}
@@ -1122,7 +1116,7 @@ public class CharacterSkill extends AbstractGameObject {
float modAmount = this.baseAmount + calculateAmountAfterTrains();
if (CharacterSkill.GetOwner(this) != null && CharacterSkill.GetOwner(this).getBonuses() != null) {
if (CharacterSkill.GetOwner(this).getBonuses() != null) {
//Multiply any percent bonuses
modAmount *= (1 + CharacterSkill.GetOwner(this).getBonuses().getFloatPercentAll(ModType.Skill, sourceType));
}
+1 -1
View File
@@ -1083,7 +1083,7 @@ public class City extends AbstractWorldObject {
Thread destroyCityThread = new Thread(new DestroyCityThread(this));
destroyCityThread.setName("destroyCity:" + this.getName());
destroyCityThread.setName("deestroyCity:" + this.getName());
destroyCityThread.start();
}
-17
View File
@@ -914,21 +914,4 @@ public class ItemBase {
public void setAutoID(boolean autoID) {
this.autoID = autoID;
}
public boolean isArmor(){
if(this.isHeavyArmor())
return true;
if(this.isMediumArmor())
return true;
if(this.isLightArmor())
return true;
if(this.isClothArmor())
return true;
return false;
}
}
File diff suppressed because it is too large Load Diff
+28 -3
View File
@@ -27,7 +27,6 @@ public class MobBase extends AbstractGameObject {
private final String firstName;
private final byte level;
private final float scale;
public final ArrayList<MobBaseEffects> effectsList;
public int bootySet;
public Enum.MobBehaviourType fsm;
public EnumBitSet<Enum.MonsterType> notEnemy;
@@ -43,6 +42,10 @@ public class MobBase extends AbstractGameObject {
private int goldMod;
private int seeInvis;
private int spawnTime = 0;
private int defense = 0;
private int atr = 0;
private float minDmg = 0;
private float maxDmg = 0;
private float attackRange;
private boolean isNecroPet = false;
private MobBaseStats mobBaseStats;
@@ -105,8 +108,6 @@ public class MobBase extends AbstractGameObject {
this.mobBaseStats = DbManager.MobBaseQueries.LOAD_STATS(this.loadID);
DbManager.MobBaseQueries.LOAD_ALL_MOBBASE_SPEEDS(this);
//load effects for mobbase
this.effectsList = DbManager.MobBaseQueries.GET_RUNEBASE_EFFECTS(this.loadID);
}
@@ -244,6 +245,30 @@ public class MobBase extends AbstractGameObject {
return mobBaseStats;
}
public float getMaxDmg() {
return maxDmg;
}
public float getMinDmg() {
return minDmg;
}
public int getAtr() {
return atr;
}
public void setAtr(int atr) {
this.atr = atr;
}
public int getDefense() {
return defense;
}
public void setDefense(int defense) {
this.defense = defense;
}
public float getAttackRange() {
return attackRange;
}
-10
View File
@@ -21,9 +21,6 @@ public class MobBaseStats {
private final int baseSpi;
private final int baseDex;
private final int mobbaseSkill;
private final int mobbaseSkillAmount;
/**
* ResultSet Constructor
@@ -34,8 +31,6 @@ public class MobBaseStats {
this.baseCon = rs.getInt("Constitution");
this.baseSpi = rs.getInt("Spirit");
this.baseDex = rs.getInt("Dexterity");
this.mobbaseSkill = rs.getInt("baseSkills");
this.mobbaseSkillAmount = rs.getInt("skillAmount");
}
/**
@@ -48,8 +43,6 @@ public class MobBaseStats {
this.baseCon = 0;
this.baseSpi = 0;
this.baseDex = 0;
this.mobbaseSkill = 0;
this.mobbaseSkillAmount = 0;
}
public static MobBaseStats GetGenericStats() {
@@ -79,8 +72,5 @@ public class MobBaseStats {
return baseDex;
}
public int getBaseSkill(){return mobbaseSkill;}
public int getBaseSkillAmount(){return mobbaseSkillAmount;}
}
+19 -18
View File
@@ -50,6 +50,7 @@ public class NPC extends AbstractCharacter {
// Used for thread safety
public final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
private final ArrayList<MobLoot> rolling = new ArrayList<>();
private final ConcurrentHashMap<Mob, Integer> siegeMinionMap = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
public ReentrantReadWriteLock minionLock = new ReentrantReadWriteLock();
public ArrayList<ProducedItem> forgedItems = new ArrayList<>();
public HashMap<Integer, MobEquipment> equip = null;
@@ -85,7 +86,6 @@ public class NPC extends AbstractCharacter {
public NPC() {
super();
this.dbID = MBServerStatics.NO_DB_ROW_ASSIGNED_YET;
this.currentID = MBServerStatics.NO_DB_ROW_ASSIGNED_YET;
}
@@ -470,7 +470,8 @@ public class NPC extends AbstractCharacter {
newNPC.bindLoc = Vector3fImmutable.ZERO;
newNPC.parentZoneUUID = parent.getObjectUUID();
newNPC.guildUUID = guild.getObjectUUID();
// guild may be null when spawning via ./npc; default to 0
newNPC.guildUUID = (guild != null) ? guild.getObjectUUID() : 0;
if (building == null)
newNPC.buildingUUID = 0;
@@ -640,31 +641,26 @@ public class NPC extends AbstractCharacter {
public void removeMinions() {
for (Integer minionUUID : this.minions) {
Mob minionMob = Mob.getMob(minionUUID);
for (Mob toRemove : this.siegeMinionMap.keySet()) {
try {
minionMob.clearEffects();
toRemove.clearEffects();
} catch (Exception e) {
Logger.error(e.getMessage());
}
if (minionMob.getParentZone() != null)
minionMob.getParentZone().zoneMobSet.remove(minionMob);
if (toRemove.getParentZone() != null)
toRemove.getParentZone().zoneMobSet.remove(toRemove);
WorldGrid.RemoveWorldObject(minionMob);
DbManager.removeFromCache(minionMob);
WorldGrid.RemoveWorldObject(toRemove);
DbManager.removeFromCache(toRemove);
PlayerCharacter petOwner = (PlayerCharacter) minionMob.guardCaptain;
PlayerCharacter petOwner = toRemove.getOwner();
if (petOwner != null) {
petOwner.setPet(null);
minionMob.guardCaptain = null;
toRemove.setOwner(null);
PetMsg petMsg = new PetMsg(5, null);
Dispatch dispatch = Dispatch.borrow(petOwner, petMsg);
@@ -672,7 +668,6 @@ public class NPC extends AbstractCharacter {
}
}
}
@Override
@@ -811,8 +806,6 @@ public class NPC extends AbstractCharacter {
@Override
public void runAfterLoad() {
this.charItemManager = new CharacterItemManager(this);
if (ConfigManager.serverType.equals(ServerType.LOGINSERVER))
return;
@@ -854,6 +847,10 @@ public class NPC extends AbstractCharacter {
if (wordCount(this.name) < 2 && this.contract != null)
this.name += " the " + this.contract.getName();
// Initialize inventory
this.charItemManager = new CharacterItemManager(this);
// Configure parent zone adding this NPC to the
// zone collection
@@ -1107,6 +1104,10 @@ public class NPC extends AbstractCharacter {
return (int) time;
}
public ConcurrentHashMap<Mob, Integer> getSiegeMinionMap() {
return siegeMinionMap;
}
public boolean remove() {
Building building;
+16 -10
View File
@@ -135,6 +135,7 @@ public class PlayerCharacter extends AbstractCharacter {
private Vector3fImmutable lastStaticLoc = new Vector3fImmutable(0.0f, 0.0f, 0.0f);
private GameObjectType lastTargetType;
private int lastTargetID;
private int hidden = 0; // current rank of hide/sneak/invis
private int seeInvis = 0; // current rank of see invis
private float speedMod;
private boolean teleportMode = false; // Teleport on MoveToPoint
@@ -143,6 +144,7 @@ public class PlayerCharacter extends AbstractCharacter {
private long lastUpdateTime = System.currentTimeMillis();
private long lastStamUpdateTime = System.currentTimeMillis();
private boolean safeZone = false;
private int bindBuildingID;
/*
DataWarehouse based kill/death tracking.
@@ -203,18 +205,15 @@ public class PlayerCharacter extends AbstractCharacter {
this.spiMod.set(spiMod);
this.guildStatus = new AtomicInteger(0);
this.buildingUUID = -1;
this.bindBuildingID = -1;
}
/**
* ResultSet Constructor
*/
public PlayerCharacter(ResultSet rs) throws SQLException {
super(rs, true);
this.charItemManager = new CharacterItemManager(this);
this.runes = DbManager.CharacterRuneQueries.GET_RUNES_FOR_CHARACTER(this.getObjectUUID());
int accountID = rs.getInt("parent");
this.account = DbManager.AccountQueries.GET_ACCOUNT(accountID);
@@ -266,7 +265,7 @@ public class PlayerCharacter extends AbstractCharacter {
this.intMod.set(rs.getShort("char_intMod"));
this.spiMod.set(rs.getShort("char_spiMod"));
this.buildingUUID = rs.getInt("char_bindBuilding");
this.bindBuildingID = rs.getInt("char_bindBuilding");
this.hash = rs.getString("hash");
@@ -2722,12 +2721,12 @@ public class PlayerCharacter extends AbstractCharacter {
*/
public synchronized int getBindBuildingID() {
return this.buildingUUID;
return this.bindBuildingID;
}
public synchronized void setBindBuildingID(int value) {
DbManager.PlayerCharacterQueries.SET_BIND_BUILDING(this, value);
this.buildingUUID = value;
this.bindBuildingID = value;
}
public AbstractGameObject getLastTarget() {
@@ -2773,6 +2772,10 @@ public class PlayerCharacter extends AbstractCharacter {
this.lastStaticLoc = value;
}
public int getHidden() {
return this.hidden;
}
public void setHidden(int value) {
this.hidden = value;
}
@@ -4558,6 +4561,10 @@ public class PlayerCharacter extends AbstractCharacter {
@Override
public void runAfterLoad() {
// Init inventory
this.charItemManager = new CharacterItemManager(this);
Bounds playerBounds = Bounds.borrow();
playerBounds.setBounds(this.getLoc());
this.setBounds(playerBounds);
@@ -4685,8 +4692,7 @@ public class PlayerCharacter extends AbstractCharacter {
} else if (currentPet.isSiege()) {
currentPet.agentType = AIAgentType.MOBILE;
currentPet.guardCaptain = null;
currentPet.setOwner(null);
currentPet.setCombatTarget(null);
if (currentPet.isAlive())
WorldGrid.updateObject(currentPet);
@@ -5353,7 +5359,7 @@ public class PlayerCharacter extends AbstractCharacter {
moveToMsg.setStartCoord(this.getLoc());
moveToMsg.setEndCoord(endLoc);
moveToMsg.setInBuilding(-1);
moveToMsg.setInBuildingFloor(-1);
moveToMsg.setUnknown01(-1);
moveToMsg.setSourceType(GameObjectType.PlayerCharacter.ordinal());
moveToMsg.setSourceID(this.getObjectUUID());
+17
View File
@@ -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");
}
}
-29
View File
@@ -1,29 +0,0 @@
// ·. · · · · .
// · ·
// · ·
//
// · · ·
// Magicbane Emulator Project © 2013 - 2022
// www.magicbane.com
package engine.powers;
import java.sql.ResultSet;
import java.sql.SQLException;
public class RunePowerEntry {
public String name;
public int token;
public String power_type;
public int rank;
public RunePowerEntry(ResultSet rs) throws SQLException {
this.name = rs.getString("name");
this.token = rs.getInt("token");
this.power_type = rs.getString("power_type");
this.rank = rs.getInt("rank");
}
}
@@ -1,31 +0,0 @@
// ·. · · · · .
// · ·
// · ·
//
// · · ·
// Magicbane Emulator Project © 2013 - 2022
// www.magicbane.com
package engine.powers;
import java.sql.ResultSet;
import java.sql.SQLException;
public class RuneSkillAdjustEntry {
public String name;
public int token;
public String skill_type;
public int rank;
public int level;
public RuneSkillAdjustEntry(ResultSet rs) throws SQLException {
this.name = rs.getString("name");
this.token = rs.getInt("token");
this.skill_type = rs.getString("skill_type");
this.rank = rs.getInt("rank");
this.level = rs.getInt("level");
}
}
@@ -11,7 +11,6 @@ package engine.powers.poweractions;
import engine.Enum.GameObjectType;
import engine.Enum.ModType;
import engine.Enum.SourceType;
import engine.InterestManagement.WorldGrid;
import engine.gameManager.ChatManager;
import engine.jobs.ChantJob;
import engine.jobs.DeferredPowerJob;
@@ -23,7 +22,6 @@ import engine.objects.*;
import engine.powers.ActionsBase;
import engine.powers.EffectsBase;
import engine.powers.PowersBase;
import engine.server.MBServerStatics;
import org.pmw.tinylog.Logger;
import java.sql.ResultSet;
@@ -119,12 +117,20 @@ public class ApplyEffectPowerAction extends AbstractPowerAction {
awo.addEffect(stackType, duration, eff, effect, trains);
} else
awo.applyAllBonuses();
// //TODO if chant, start cycle
// if (pb.isChant() && source.equals(awo)) {
// ChantJob cj = new ChantJob(source, awo, stackType, trains, ab, pb, effect, eff);
// source.setLastChant((int)(pb.getChantDuration()-2) * 1000, cj);
// eff.setChant(true);
// }
if (this.effectID.equals("TAUNT")) {
if (awo != null && awo.getObjectType() == GameObjectType.Mob) {
((Mob) awo).setCombatTarget(source);
ChatSystemMsg msg = ChatManager.CombatInfo(source, awo);
DispatchMessage.sendToAllInRange(source, msg);
((Mob)awo).refresh();
}
}
if (awo != null && awo.getObjectType() == GameObjectType.Mob) {
@@ -134,22 +140,8 @@ public class ApplyEffectPowerAction extends AbstractPowerAction {
}
this.effect.startEffect(source, awo, trains, eff);
}
//apply effects to mobs within range for chants
if(pb.isChant){
for(AbstractGameObject ago : WorldGrid.getObjectsInRangePartial(awo.loc,pb.range, MBServerStatics.MASK_MOB)){
Mob mob = (Mob)ago;
if(mob.playerAgroMap.containsKey(source.getObjectUUID()))
mob.playerAgroMap.put(source.getObjectUUID(), mob.playerAgroMap.get(source.getObjectUUID()).floatValue() + pb.hateValue);
}
}else {
if (awo != null && awo.getObjectType() == GameObjectType.Mob) {
Mob mob = (Mob) awo;
if (mob.playerAgroMap.containsKey(source.getObjectUUID()))
mob.playerAgroMap.put(source.getObjectUUID(), mob.playerAgroMap.get(source.getObjectUUID()).floatValue() + pb.hateValue);
}
}
}
protected void _applyEffectForItem(Item item, int trains) {
if (item == null || this.effect == null)
@@ -12,6 +12,7 @@ package engine.powers.poweractions;
import engine.Enum;
import engine.InterestManagement.WorldGrid;
import engine.gameManager.DbManager;
import engine.gameManager.MovementManager;
import engine.gameManager.NPCManager;
import engine.gameManager.ZoneManager;
import engine.math.Vector3fImmutable;
@@ -74,7 +75,7 @@ public class CreateMobPowerAction extends AbstractPowerAction {
return;
//create Pet
Mob pet = Mob.createPetMinion(mobID, seaFloor, owner, (short) mobLevel);
Mob pet = Mob.createPet(mobID, guild, seaFloor, owner, (short) mobLevel);
if (pet.getMobBaseID() == 12021 || pet.getMobBaseID() == 12022) { //is a necro pet
@@ -83,6 +84,8 @@ public class CreateMobPowerAction extends AbstractPowerAction {
WorldGrid.RemoveWorldObject(currentPet);
currentPet.setCombatTarget(null);
//if (currentPet.getParentZone() != null)
//currentPet.getParentZone().zoneMobSet.remove(currentPet);
seaFloor.zoneMobSet.remove(currentPet);
currentPet.playerAgroMap.clear();
@@ -92,10 +95,10 @@ public class CreateMobPowerAction extends AbstractPowerAction {
Logger.error(e.getMessage());
}
//currentPet.disableIntelligence();
} else if (currentPet != null && currentPet.isSiege()) {
currentPet.agentType = Enum.AIAgentType.MOBILE;
currentPet.guardCaptain = null;
currentPet.setOwner(null);
currentPet.setCombatTarget(null);
if (currentPet.isAlive())
@@ -103,6 +106,7 @@ public class CreateMobPowerAction extends AbstractPowerAction {
}
//remove 10th pet
NPCManager.spawnNecroPet(owner, pet);
} else { //is not a necro pet
@@ -111,7 +115,7 @@ public class CreateMobPowerAction extends AbstractPowerAction {
DbManager.removeFromCache(currentPet);
currentPet.setCombatTarget(null);
currentPet.guardCaptain = null;
currentPet.setOwner(null);
WorldGrid.RemoveWorldObject(currentPet);
//currentPet.getParentZone().zoneMobSet.remove(currentPet);
seaFloor.zoneMobSet.remove(currentPet);
@@ -121,8 +125,7 @@ public class CreateMobPowerAction extends AbstractPowerAction {
} else {
if (currentPet.isSiege()) {
currentPet.agentType = Enum.AIAgentType.MOBILE;
currentPet.guardCaptain = null;
currentPet.setOwner(null);
currentPet.setCombatTarget(null);
if (currentPet.isAlive())
@@ -134,9 +137,26 @@ public class CreateMobPowerAction extends AbstractPowerAction {
NPCManager.resetNecroPets(owner);
}
}
/* if(owner.getPet() != null) {
if(owner.getPet().getMobBaseID() != 12021 && owner.getPet().getMobBaseID() != 12022) {
//if not a necro pet, remove pet
WorldGrid.removeWorldObject(owner.getPet());
owner.getPet().disableIntelligence();
Mob.removePet(owner.getPet().getUUID());
owner.setPet(null);
}
else {
//if it is a necro pet, add it to the line and set as mob
owner.getPet().setMob();
}
}*/
// if (mobID == 12021 || mobID == 12022) //Necro Pets
// pet.setPet(owner, true);
owner.setPet(pet);
if(pet.isSiege() == false) {
MovementManager.translocate(pet, owner.getLoc(), owner.region);
}
pet.recalculateStats();
pet.healthMax = pet.level * 0.5f * 120;
pet.setHealth(pet.healthMax);
@@ -59,7 +59,7 @@ public class FearPowerAction extends AbstractPowerAction {
int duration = 10 + ((int) (trains * 0.5));
String stackType = ab.getStackType();
EndFearJob efj = new EndFearJob(source, awo, stackType, trains, ab, pb, null);
((Mob) awo).fearedObject = source;
((Mob) awo).setFearedObject(source);
JobScheduler.getInstance().scheduleJob(efj, duration * 1000);
}
+31 -33
View File
@@ -10,6 +10,7 @@
package engine.server.world;
import engine.Enum;
import engine.Enum.BuildingGroup;
import engine.Enum.DispatchChannel;
import engine.Enum.MinionType;
import engine.Enum.SupportMsgType;
@@ -17,7 +18,6 @@ import engine.InterestManagement.HeightMap;
import engine.InterestManagement.RealmMap;
import engine.InterestManagement.WorldGrid;
import engine.db.archive.DataWarehouse;
import engine.db.handlers.dbRuneBaseHandler;
import engine.exception.MsgSendException;
import engine.gameManager.*;
import engine.job.JobContainer;
@@ -334,7 +334,7 @@ public class WorldServer {
DbManager.PromotionQueries.GET_ALL_PROMOTIONS();
Logger.info("Loading NPC and Mob Rune Sets");
NPCManager._runeSetMap = DbManager.ItemBaseQueries.LOAD_RUNES_FOR_NPC_AND_MOBS();
NPCManager.LoadAllRuneSets();
Logger.info("Loading Booty Sets");
LootManager._bootySetMap = DbManager.LootQueries.LOAD_BOOTY_TABLES();
@@ -351,11 +351,8 @@ public class WorldServer {
Logger.info("Loading MobBases.");
DbManager.MobBaseQueries.GET_ALL_MOBBASES();
Logger.info("Loading Rune Powers");
PowersManager._allRunePowers = dbRuneBaseHandler.LOAD_RUNE_POWERS();
Logger.info("Loading Rune Skill Adjusts");
PowersManager._allRuneSkillAdjusts = dbRuneBaseHandler.LOAD_RUNE_SKILL_ADJUSTS();
Logger.info("Loading Mob Powers");
PowersManager.AllMobPowers = DbManager.PowerQueries.LOAD_MOB_POWERS();
Logger.info("Loading item enchants");
DbManager.LootQueries.LOAD_ENCHANT_VALUES();
@@ -554,40 +551,44 @@ public class WorldServer {
}
//Set sea floor object for server
Zone seaFloor = rootParent.get(0);
seaFloor.setParent(null);
ZoneManager.setSeaFloor(seaFloor);
// zoneManager.addZone(seaFloor.getLoadNum(), seaFloor); <- DIE IN A FUCKING CAR FIRE BONUS CODE LIKE THIS SUCKS FUCKING DICK
rootParent.addAll(DbManager.ZoneQueries.GET_ALL_NODES(seaFloor));
long start = System.currentTimeMillis();
for (Zone zone : rootParent) {
try {
ZoneManager.addZone(zone.getLoadNum(), zone);
zone.generateWorldAltitude();
try {
zone.generateWorldAltitude();
} catch (Exception e) {
Logger.error(e.getMessage());
e.printStackTrace();
}
//Handle Buildings
try {
ArrayList<Building> bList;
bList = DbManager.BuildingQueries.GET_ALL_BUILDINGS_FOR_ZONE(zone);
for (Building b : bList) {
try {
b.setObjectTypeMask(MBServerStatics.MASK_BUILDING);
b.setLoc(b.getLoc());
}
} catch (Exception e) {
Logger.error(e);
e.printStackTrace();
Logger.error(b.getObjectUUID() + " returned an Error Message :" + e.getMessage());
}
}
//Handle Mobs
try {
ArrayList<Mob> mobs;
mobs = DbManager.MobQueries.GET_ALL_MOBS_FOR_ZONE(zone);
@@ -595,22 +596,15 @@ public class WorldServer {
m.setObjectTypeMask(MBServerStatics.MASK_MOB | m.getTypeMasks());
m.setLoc(m.getLoc());
// Load Minions for Guard Captains here.
if (m.building != null && m.building.getBlueprint() != null && m.building.getBlueprint().getBuildingGroup() == Enum.BuildingGroup.BARRACK)
DbManager.MobQueries.LOAD_GUARD_MINIONS(m);
}
} catch (Exception e) {
Logger.error(e);
e.printStackTrace();
//ADD GUARDS HERE.
if (m.building != null && m.building.getBlueprint() != null && m.building.getBlueprint().getBuildingGroup() == BuildingGroup.BARRACK)
DbManager.MobQueries.LOAD_PATROL_POINTS(m);
}
//Handle NPCs
try {
//Handle npc's
ArrayList<NPC> npcs;
// Ignore NPCs on the seafloor (npc guild leaders, etc)
// Ignore npc's on the seafloor (npc guild leaders, etc)
if (zone.equals(seaFloor))
continue;
@@ -618,22 +612,26 @@ public class WorldServer {
npcs = DbManager.NPCQueries.GET_ALL_NPCS_FOR_ZONE(zone);
for (NPC n : npcs) {
try {
n.setObjectTypeMask(MBServerStatics.MASK_NPC);
n.setLoc(n.getLoc());
} catch (Exception e) {
Logger.error(n.getObjectUUID() + " returned an Error Message :" + e.getMessage());
}
}
} catch (Exception e) {
Logger.error(e);
e.printStackTrace();
}
//Handle cities
ZoneManager.loadCities(zone);
ZoneManager.populateWorldZones(zone);
} catch (Exception e) {
Logger.info(e.getMessage() + zone.getName() + ' ' + zone.getObjectUUID());
}
}
Logger.info("time to load World Objects: " + (System.currentTimeMillis() - start) + " ms");
Logger.info("time to load: " + (System.currentTimeMillis() - start) + " ms");
}
/**
@@ -706,7 +704,7 @@ public class WorldServer {
return;
}
//remove player from loaded mobs agro maps
for (AbstractWorldObject awo : WorldGrid.getObjectsInRangePartial(player.getLoc(), MBServerStatics.CHARACTER_LOAD_RANGE, MBServerStatics.MASK_MOB)) {
for(AbstractWorldObject awo : WorldGrid.getObjectsInRangePartial(player.getLoc(),MBServerStatics.CHARACTER_LOAD_RANGE,MBServerStatics.MASK_MOB)) {
Mob loadedMob = (Mob) awo;
loadedMob.playerAgroMap.remove(player.getObjectUUID());
}