Compare commits
321 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 76284cf3c9 | |||
| 9d79afa395 | |||
| 944290f958 | |||
| e6eb753666 | |||
| 4ad7e0f021 | |||
| 8d587538e0 | |||
| 4ae64ab94c | |||
| c5e6205801 | |||
| 5a3f4e690f | |||
| 048474b014 | |||
| 24e01acff4 | |||
| a75670bf0e | |||
| d56d58492a | |||
| 7b33c1392a | |||
| 86c95f0eb5 | |||
| 6ed648d6d4 | |||
| c722450f65 | |||
| c3a7262a7f | |||
| d1c6d9edec | |||
| 1e865eecbc | |||
| 5f735a49c1 | |||
| e609c015b9 | |||
| 5a198669b9 | |||
| fe399664f3 | |||
| 3bc62e9baa | |||
| cf23266f31 | |||
| b097472402 | |||
| 57b18c2d15 | |||
| 040eef576e | |||
| d76403a0c8 | |||
| 8ce1054599 | |||
| 0daf8cfe4c | |||
| 898c4c2fa0 | |||
| ecba693105 | |||
| dbc0da20df | |||
| 354d0ab283 | |||
| c1b66269bb | |||
| 7981acb582 | |||
| 03448397ee | |||
| 685dc572e8 | |||
| 5a161a0808 | |||
| 3e4aad9db9 | |||
| 47981872be | |||
| daea835613 | |||
| 55923559cd | |||
| 9efde874f3 | |||
| 9b2b0073a5 | |||
| 33328f74db | |||
| 41023fb890 | |||
| 54a279c3e6 | |||
| 29aea83217 | |||
| 30d27f8a68 | |||
| 17e54ea4aa | |||
| 86c0bbb065 | |||
| ec4cad5e19 | |||
| b674625f7b | |||
| d57b45ef9c | |||
| 2a38c60a67 | |||
| cd1e38b184 | |||
| 69457d5f7e | |||
| 7728a800d9 | |||
| 8b2c018103 | |||
| 76d39f5cc3 | |||
| 826457fb25 | |||
| 0681d3d116 | |||
| ccdea6f970 | |||
| ab00fd7a85 | |||
| 70d67a2b7f | |||
| f5b27e0c5b | |||
| 3c26df5f86 | |||
| 9ed43b5891 | |||
| 4814404f1c | |||
| b1d41e8e85 | |||
| cc5aa4c140 | |||
| 934c0a98f8 | |||
| 91c2cd47fb | |||
| 22f14fb8f1 | |||
| 93a975dd42 | |||
| 7d1570fdca | |||
| 76db3e1f96 | |||
| afbe23fc03 | |||
| 4e417c8810 | |||
| d79c69658a | |||
| 0d125e2640 | |||
| e4a3405032 | |||
| c391272e5b | |||
| 0d3423d51b | |||
| 549ca25483 | |||
| 603d4ca3a8 | |||
| fababd3e42 | |||
| bec6230a06 | |||
| 773b6253b9 | |||
| 1ffcc1086b | |||
| 992d52a389 | |||
| 61088d0b59 | |||
| 601e97eaca | |||
| eae4675f85 | |||
| 84410114e7 | |||
| 70855acbcf | |||
| 2a8e0dea73 | |||
| 6c4f18218c | |||
| 0b5f469b13 | |||
| 68a43388ff | |||
| 5fe12df436 | |||
| caa0aa5172 | |||
| 37a81ed53e | |||
| 39afb33186 | |||
| 228152596c | |||
| d75a052bd3 | |||
| 81d6a55096 | |||
| 55d9cf6d26 | |||
| 9cf69ec73f | |||
| 4595582def | |||
| 0b2d598261 | |||
| cf342cd1a6 | |||
| 05bb323c0c | |||
| c415bb15e2 | |||
| eac58b086b | |||
| fea39ffa85 | |||
| fb8971ce86 | |||
| e44dd5e2cc | |||
| 3ed303bec4 | |||
| f4267c3c92 | |||
| c5f678ea0e | |||
| 4fe3d92b3f | |||
| 284fc7e37e | |||
| 402d69312c | |||
| 198648d3db | |||
| 3a01dbf5f6 | |||
| 0ec505e37f | |||
| 1e26d7f38c | |||
| 64f9f4d4b9 | |||
| 89c06f714f | |||
| 157d116626 | |||
| de229ddde5 | |||
| 8b456f66ef | |||
| 2e35e35a6e | |||
| cca078f017 | |||
| f658a30132 | |||
| 0a827d2404 | |||
| 806adee3de | |||
| bdd108065b | |||
| 8d41c5475c | |||
| 99ad461a82 | |||
| 9da56b4226 | |||
| beeca529cd | |||
| ebb765ae82 | |||
| 65e391f6f7 | |||
| ab45d92bd1 | |||
| a366c95941 | |||
| f2d9eb003c | |||
| bb1a99912c | |||
| fd30e52741 | |||
| 58a0b6150f | |||
| 9aa053beb6 | |||
| 7eb084efaa | |||
| 1568377725 | |||
| 7b32cfe235 | |||
| 7ef3efafd3 | |||
| ffdd79c497 | |||
| b156da7ded | |||
| 9278954f2f | |||
| 4324ebe855 | |||
| 4a69dca5cc | |||
| 2cc54b4002 | |||
| eac0aebd59 | |||
| 172dcfb6d8 | |||
| d320d83c22 | |||
| af2dd004e4 | |||
| dfbace76db | |||
| 119f762492 | |||
| e586c442c1 | |||
| c01e87ee8b | |||
| af4025d948 | |||
| b7c2b7a0d5 | |||
| f073a93d47 | |||
| 47914838f5 | |||
| 69e2630d77 | |||
| 08148c058c | |||
| a7ee8f553b | |||
| 8395bb80f1 | |||
| becd3cbf65 | |||
| 80ec681a2c | |||
| 96a80ce1b6 | |||
| f18cf5c8a6 | |||
| 4c21159553 | |||
| 475c0a9b09 | |||
| f80ad61179 | |||
| 10ccfb1086 | |||
| 44197fd83c | |||
| 0d9e03f848 | |||
| 810812d06b | |||
| 539d7f6e79 | |||
| 3358d9e943 | |||
| eeffd9b357 | |||
| b33f41200e | |||
| 030d1110b9 | |||
| 09af8084b9 | |||
| 0cff9524c2 | |||
| f6299f5b97 | |||
| b1250ae4e4 | |||
| a9144471b1 | |||
| 9f924da18b | |||
| aac92f1760 | |||
| fdf42bd913 | |||
| ecee2f2e8c | |||
| 1b487fdbb6 | |||
| bb7bd6d71b | |||
| 34178906a3 | |||
| c689722459 | |||
| 8e4ff8c67f | |||
| 4ff22d1d20 | |||
| 5ed7712aed | |||
| a6fcb5ea00 | |||
| 8f402c8c03 | |||
| 5761e313fd | |||
| 441771839a | |||
| ad6700974f | |||
| 499aec2c61 | |||
| ceed4c641a | |||
| 669c0b4cd7 | |||
| 7964de1045 | |||
| 961e2915b4 | |||
| 6c6a64fa98 | |||
| 7a8a751bca | |||
| 69bf6ef8cd | |||
| 05e542215d | |||
| 868eaab5ed | |||
| e7d22717cd | |||
| bbabf814e1 | |||
| 938fcb1352 | |||
| 42a71396cd | |||
| 9ec95b974f | |||
| 49ea9e50cf | |||
| 456edce9fc | |||
| 537512ed5d | |||
| d0efd08a84 | |||
| bb7ba9a6df | |||
| 09695d97db | |||
| 4fe4835c29 | |||
| 86435a3563 | |||
| bc84c7537b | |||
| 29736f9c8f | |||
| 99a9cd297c | |||
| e86749febd | |||
| 4b86fbb12c | |||
| 4c342c9b9a | |||
| d2e0b7b95c | |||
| 53fe763764 | |||
| 86d7233aa4 | |||
| d19ea0968a | |||
| 7eb49446c1 | |||
| 01a88c85a6 | |||
| 5492374f2c | |||
| 9ca00be694 | |||
| 23d9807fe3 | |||
| 8a3e3ae866 | |||
| 117646cda4 | |||
| 6cf502c4bb | |||
| 1bb99127c4 | |||
| 8aeccd35c9 | |||
| c90b94d1ec | |||
| 031fd24842 | |||
| e1c07deb52 | |||
| 5f10c24f03 | |||
| f643caacbe | |||
| cb5ab26924 | |||
| 94c9e92553 | |||
| 507638594d | |||
| e72c4886e8 | |||
| 5ba11a6238 | |||
| 2fc7671051 | |||
| d142097b0f | |||
| 4330bb3ecd | |||
| 2e1dd27332 | |||
| 4f08d7286e | |||
| 7f8fb13552 | |||
| 93e0d119b0 | |||
| a9bc44f19b | |||
| 83bc09f34b | |||
| 4386e1c828 | |||
| 72b2e54331 | |||
| e912c24025 | |||
| c9c1f6ba1c | |||
| abda30fc25 | |||
| 62c188c5c7 | |||
| 67f7b6f3f8 | |||
| f04ccb9403 | |||
| b71bb60669 | |||
| 5eab1ad1c0 | |||
| f96d0caf3c | |||
| 3e6655a199 | |||
| 386cdc8c18 | |||
| 63b40c27a5 | |||
| 6985dffda4 | |||
| 88e16448a8 | |||
| 4cb428e993 | |||
| af9945f9db | |||
| f0594fb1b2 | |||
| a155bc0308 | |||
| dce7444483 | |||
| 76eed79b0a | |||
| f73ed17c05 | |||
| b049d21aff | |||
| f6cce5ee1f | |||
| 8038c2ebe2 | |||
| 9f51b9af57 | |||
| cbc75bf9d7 | |||
| 0ecfa546cd | |||
| b89fb0803d | |||
| 11005d58a7 | |||
| b0c6239314 | |||
| 67f66155e9 | |||
| 7fbae12e99 | |||
| 65580c0a47 | |||
| 236afe4cc6 | |||
| c23a6af28f | |||
| 2535106d2c | |||
| d8379ae5a9 | |||
| 9f13f5fc5d | |||
| 884cb30ebd |
+9
-17
@@ -9,15 +9,13 @@
|
||||
package engine;
|
||||
|
||||
import ch.claude_martin.enumbitset.EnumBitSetHelper;
|
||||
import engine.gameManager.BuildingManager;
|
||||
import engine.gameManager.ConfigManager;
|
||||
import engine.gameManager.PowersManager;
|
||||
import engine.gameManager.ZoneManager;
|
||||
import engine.math.Vector2f;
|
||||
import engine.math.Vector3fImmutable;
|
||||
import engine.objects.AbstractCharacter;
|
||||
import engine.objects.ItemBase;
|
||||
import engine.objects.Shrine;
|
||||
import engine.objects.Zone;
|
||||
import engine.objects.*;
|
||||
import engine.powers.EffectsBase;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
@@ -471,11 +469,14 @@ public class Enum {
|
||||
|
||||
// 14001 does not have a banestone to bind at
|
||||
|
||||
if (ruinZone.getLoadNum() == 14001)
|
||||
if (ruinZone.getLoadNum() == 14001) {
|
||||
spawnLocation = Vector3fImmutable.getRandomPointOnCircle(ruinZone.getLoc(), 30);
|
||||
else
|
||||
spawnLocation = Vector3fImmutable.getRandomPointOnCircle(ruinZone.getLoc()
|
||||
.add(new Vector3fImmutable(-196.016f, 2.812f, 203.621f)), 30);
|
||||
}else {
|
||||
//spawnLocation = Vector3fImmutable.getRandomPointOnCircle(ruinZone.getLoc()
|
||||
//.add(new Vector3fImmutable(-196.016f, 2.812f, 203.621f)), 30);
|
||||
spawnLocation = Vector3fImmutable.getRandomPointOnCircle(BuildingManager.getBuilding(27977).loc,30f);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1090,15 +1091,6 @@ public class Enum {
|
||||
DamageShield,
|
||||
DeathShroud,
|
||||
DefenseBuff,
|
||||
DefenseBuffAss,
|
||||
DefenseBuffChn,
|
||||
DefenseBuffDsr,
|
||||
DefenseBuffFur,
|
||||
DefenseBuffNec,
|
||||
DefenseBuffNsr,
|
||||
DefenseBuffPrl,
|
||||
DefenseBuffRng,
|
||||
DefenseBuffWiz,
|
||||
DefenseBuffGroup,
|
||||
DefenseDebuff,
|
||||
DetectInvis,
|
||||
|
||||
@@ -22,6 +22,7 @@ import java.util.HashMap;
|
||||
|
||||
public class dbItemBaseHandler extends dbHandlerBase {
|
||||
|
||||
public static final HashMap<Integer,Float> dexReductions = new HashMap<>();
|
||||
public dbItemBaseHandler() {
|
||||
|
||||
}
|
||||
@@ -45,6 +46,14 @@ public class dbItemBaseHandler extends dbHandlerBase {
|
||||
}
|
||||
}
|
||||
|
||||
public void LOAD_DEX_REDUCTION(ItemBase itemBase) {
|
||||
if(dexReductions.containsKey(itemBase.getUUID())){
|
||||
itemBase.dexReduction = dexReductions.get(itemBase.getUUID());
|
||||
}else{
|
||||
itemBase.dexReduction = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
public void LOAD_ANIMATIONS(ItemBase itemBase) {
|
||||
|
||||
ArrayList<Integer> tempList = new ArrayList<>();
|
||||
@@ -94,6 +103,21 @@ public class dbItemBaseHandler extends dbHandlerBase {
|
||||
}
|
||||
|
||||
Logger.info("read: " + recordsRead + " cached: " + ItemBase.getUUIDCache().size());
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_item_dexpenalty`")) {
|
||||
|
||||
ResultSet rs = preparedStatement.executeQuery();
|
||||
|
||||
// Check if a result was found
|
||||
if (rs.next()) {
|
||||
int ID = rs.getInt("ID");
|
||||
float factor = rs.getInt("item_bulk_factor");
|
||||
dexReductions.put(ID,factor);
|
||||
}
|
||||
|
||||
} catch (SQLException e) {
|
||||
Logger.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
public HashMap<Integer, ArrayList<Integer>> LOAD_RUNES_FOR_NPC_AND_MOBS() {
|
||||
|
||||
@@ -134,9 +134,13 @@ public class dbItemHandler extends dbHandlerBase {
|
||||
|
||||
ResultSet rs = preparedStatement.executeQuery();
|
||||
|
||||
if (rs.next())
|
||||
worked = rs.getBoolean("result");
|
||||
|
||||
if (rs.next()) {
|
||||
try {
|
||||
worked = rs.getBoolean("result");
|
||||
}catch(Exception e){
|
||||
worked = false;
|
||||
}
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
Logger.error(e);
|
||||
}
|
||||
|
||||
@@ -15,9 +15,13 @@ import engine.Enum.GameObjectType;
|
||||
import engine.Enum.TargetColor;
|
||||
import engine.devcmd.AbstractDevCmd;
|
||||
import engine.gameManager.BuildingManager;
|
||||
import engine.gameManager.PowersManager;
|
||||
import engine.gameManager.SessionManager;
|
||||
import engine.math.Vector3fImmutable;
|
||||
import engine.objects.*;
|
||||
import engine.powers.EffectsBase;
|
||||
import engine.powers.PowersBase;
|
||||
import engine.server.MBServerStatics;
|
||||
import engine.util.StringUtils;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
@@ -338,7 +342,8 @@ public class InfoCmd extends AbstractDevCmd {
|
||||
output += newline;
|
||||
output += "isMoving : " + targetPC.isMoving();
|
||||
output += newline;
|
||||
output += "Zerg Multiplier : " + targetPC.ZergMultiplier;
|
||||
output += "Zerg Multiplier : " + targetPC.ZergMultiplier+ newline;
|
||||
output += "Hidden : " + targetPC.getHidden();
|
||||
break;
|
||||
|
||||
case NPC:
|
||||
@@ -493,13 +498,16 @@ public class InfoCmd extends AbstractDevCmd {
|
||||
output += newline;
|
||||
output += "No building found." + newline;
|
||||
}
|
||||
int max = (int)(4.882 * targetMob.level + 121.0);
|
||||
if(max > 321){
|
||||
max = 321;
|
||||
|
||||
output += "Damage: " + targetMob.mobBase.getDamageMin() + " - " + targetMob.mobBase.getDamageMax() + newline;
|
||||
output += "ATR: " + targetMob.mobBase.getAttackRating() + newline;
|
||||
output += "DEF: " + targetMob.defenseRating + newline;
|
||||
output += "RANGE: " + targetMob.getRange() + newline;
|
||||
output += "Effects:" + newline;
|
||||
for(MobBaseEffects mbe : targetMob.mobBase.mobbaseEffects){
|
||||
EffectsBase eb = PowersManager.getEffectByToken(mbe.getToken());
|
||||
output += eb.getName() + newline;
|
||||
}
|
||||
int min = (int)(4.469 * targetMob.level - 3.469);
|
||||
output += "Min Loot Roll = " + min;
|
||||
output += "Max Loot Roll = " + max;
|
||||
break;
|
||||
case Item: //intentional passthrough
|
||||
case MobLoot:
|
||||
@@ -530,6 +538,13 @@ public class InfoCmd extends AbstractDevCmd {
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case Corpse:
|
||||
Corpse corpse = (Corpse)target;
|
||||
Long timeLeft = MBServerStatics.CORPSE_CLEANUP_TIMER_MS - (System.currentTimeMillis() - corpse.spawnedTime);
|
||||
output += "Despawn in: " + timeLeft;
|
||||
output += newline;
|
||||
break;
|
||||
}
|
||||
|
||||
throwbackInfo(pc, output);
|
||||
|
||||
@@ -49,6 +49,8 @@ public class PrintSkillsCmd extends AbstractDevCmd {
|
||||
+ skill.getModifiedAmount() + '('
|
||||
+ skill.getTotalSkillPercet() + " )");
|
||||
}
|
||||
//throwbackInfo(pc, "= = = = = NEW CALCULATIONS = = = = =");
|
||||
// PlayerCombatStats.PrintSkillsToClient(pc);
|
||||
} else
|
||||
throwbackInfo(pc, "Skills not found for player");
|
||||
}
|
||||
|
||||
@@ -57,27 +57,36 @@ public class PrintStatsCmd extends AbstractDevCmd {
|
||||
|
||||
public void printStatsPlayer(PlayerCharacter pc, PlayerCharacter tar) {
|
||||
String newline = "\r\n ";
|
||||
String out = "Server stats for Player " + tar.getFirstName() + newline;
|
||||
out += "Unused Stats: " + tar.getUnusedStatPoints() + newline;
|
||||
out += "Stats Base (Modified)" + newline;
|
||||
out += " Str: " + (int) tar.statStrBase + " (" + tar.getStatStrCurrent() + ')' + ", maxStr: " + tar.getStrMax() + newline;
|
||||
out += " Dex: " + (int) tar.statDexBase + " (" + tar.getStatDexCurrent() + ')' + ", maxDex: " + tar.getDexMax() + newline;
|
||||
out += " Con: " + (int) tar.statConBase + " (" + tar.getStatConCurrent() + ')' + ", maxCon: " + tar.getConMax() + newline;
|
||||
out += " Int: " + (int) tar.statIntBase + " (" + tar.getStatIntCurrent() + ')' + ", maxInt: " + tar.getIntMax() + newline;
|
||||
out += " Spi: " + (int) tar.statSpiBase + " (" + tar.getStatSpiCurrent() + ')' + ", maxSpi: " + tar.getSpiMax() + newline;
|
||||
throwbackInfo(pc, out);
|
||||
out = "Health: " + tar.getHealth() + ", maxHealth: " + tar.getHealthMax() + newline;
|
||||
out += "Mana: " + tar.getMana() + ", maxMana: " + tar.getManaMax() + newline;
|
||||
out += "Stamina: " + tar.getStamina() + ", maxStamina: " + tar.getStaminaMax() + newline;
|
||||
out += "Defense: " + tar.getDefenseRating() + newline;
|
||||
out += "Main Hand: atr: " + tar.getAtrHandOne() + ", damage: " + tar.getMinDamageHandOne() + " to " + tar.getMaxDamageHandOne() + ", speed: " + tar.getSpeedHandOne() + newline;
|
||||
out += "Off Hand: atr: " + tar.getAtrHandTwo() + ", damage: " + tar.getMinDamageHandTwo() + " to " + tar.getMaxDamageHandTwo() + ", speed: " + tar.getSpeedHandTwo() + newline;
|
||||
out += "isAlive: " + tar.isAlive() + ", Combat: " + tar.isCombat() + newline;
|
||||
out += "Move Speed: " + tar.getSpeed() + newline;
|
||||
out += "Health Regen: " + tar.getRegenModifier(Enum.ModType.HealthRecoverRate) + newline;
|
||||
out += "Mana Regen: " + tar.getRegenModifier(Enum.ModType.ManaRecoverRate) + newline;
|
||||
out += "Stamina Regen: " + tar.getRegenModifier(Enum.ModType.StaminaRecoverRate) + newline;
|
||||
throwbackInfo(pc, out);
|
||||
|
||||
String newOut = "Server stats for Player " + tar.getFirstName() + newline;
|
||||
newOut += "HEALTH: " + tar.getHealth() + " / " + tar.getHealthMax() + newline;
|
||||
newOut += "MANA: " + tar.getMana() + " / " + tar.getManaMax() + newline;
|
||||
newOut += "STAMINA: " + tar.getStamina() + " / " + tar.getStaminaMax() + newline;
|
||||
newOut += "Unused Stats: " + tar.getUnusedStatPoints() + newline;
|
||||
newOut += "Stats Base (Modified)" + newline;
|
||||
newOut += " Str: " + (int) tar.statStrBase + " (" + tar.getStatStrCurrent() + ')' + ", maxStr: " + tar.getStrMax() + newline;
|
||||
newOut += " Dex: " + (int) tar.statDexBase + " (" + tar.getStatDexCurrent() + ')' + ", maxDex: " + tar.getDexMax() + newline;
|
||||
newOut += " Con: " + (int) tar.statConBase + " (" + tar.getStatConCurrent() + ')' + ", maxCon: " + tar.getConMax() + newline;
|
||||
newOut += " Int: " + (int) tar.statIntBase + " (" + tar.getStatIntCurrent() + ')' + ", maxInt: " + tar.getIntMax() + newline;
|
||||
newOut += " Spi: " + (int) tar.statSpiBase + " (" + tar.getStatSpiCurrent() + ')' + ", maxSpi: " + tar.getSpiMax() + newline;
|
||||
newOut += "Move Speed: " + tar.getSpeed() + newline;
|
||||
newOut += "Health Regen: " + tar.combatStats.healthRegen + newline;
|
||||
newOut += "Mana Regen: " + tar.combatStats.manaRegen + newline;
|
||||
newOut += "Stamina Regen: " + tar.combatStats.staminaRegen + newline;
|
||||
newOut += "DEFENSE: " + tar.combatStats.defense + newline;
|
||||
newOut += "HAND ONE" + newline;
|
||||
newOut += "ATR: " + tar.combatStats.atrHandOne + newline;
|
||||
newOut += "MIN: " + tar.combatStats.minDamageHandOne + newline;
|
||||
newOut += "MAX: " + tar.combatStats.maxDamageHandOne + newline;
|
||||
newOut += "RANGE: " + tar.combatStats.rangeHandOne + newline;
|
||||
newOut += "ATTACK SPEED: " + tar.combatStats.attackSpeedHandOne + newline;
|
||||
newOut += "HAND TWO" + newline;
|
||||
newOut += "ATR: " + tar.combatStats.atrHandTwo + newline;
|
||||
newOut += "MIN: " + tar.combatStats.minDamageHandTwo + newline;
|
||||
newOut += "MAX: " + tar.combatStats.maxDamageHandTwo + newline;
|
||||
newOut += "RANGE: " + tar.combatStats.rangeHandTwo + newline;
|
||||
newOut += "ATTACK SPEED: " + tar.combatStats.attackSpeedHandTwo + newline;
|
||||
throwbackInfo(pc, newOut);
|
||||
}
|
||||
|
||||
public void printStatsMob(PlayerCharacter pc, Mob tar) {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package engine.devcmd.cmds;
|
||||
|
||||
import engine.Enum;
|
||||
import engine.devcmd.AbstractDevCmd;
|
||||
import engine.gameManager.LootManager;
|
||||
import engine.gameManager.ZoneManager;
|
||||
@@ -26,7 +27,52 @@ public class SimulateBootyCmd extends AbstractDevCmd {
|
||||
String newline = "\r\n ";
|
||||
|
||||
String output;
|
||||
if(target.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)){
|
||||
int ATR = Integer.parseInt(words[0]);
|
||||
int DEF = Integer.parseInt(words[1]);
|
||||
int attacks = Integer.parseInt(words[2]);
|
||||
|
||||
int hits = 0;
|
||||
int misses = 0;
|
||||
int defaultHits = 0;
|
||||
int defualtMisses = 0;
|
||||
|
||||
float chance = (ATR-((ATR+DEF) * 0.315f)) / ((DEF-((ATR+DEF) * 0.315f)) + (ATR-((ATR+DEF) * 0.315f)));
|
||||
float convertedChance = chance * 100;
|
||||
output = "" + newline;
|
||||
output += "DEF VS ATR SIMULATION: " + attacks + " ATTACKS SIMULATED" + newline;
|
||||
output += "DEF = " + DEF + newline;
|
||||
output += "ATR = " + ATR + newline;
|
||||
output += "CHANCE TO LAND HIT: " + convertedChance + "%" + newline;
|
||||
if(convertedChance < 5){
|
||||
output += "CHANCE ADJUSTED TO 5.0%" + newline;
|
||||
convertedChance = 5.0f;
|
||||
}
|
||||
if(convertedChance > 95){
|
||||
output += "CHANCE ADJUSTED TO 95.0%" + newline;
|
||||
convertedChance = 95.0f;
|
||||
}
|
||||
for(int i = 0; i < attacks; i++){
|
||||
int roll = ThreadLocalRandom.current().nextInt(101);
|
||||
|
||||
if(roll <= convertedChance){
|
||||
hits += 1;
|
||||
}else{
|
||||
misses += 1;
|
||||
}
|
||||
}
|
||||
|
||||
float totalHits = defaultHits + hits;
|
||||
float totalMisses = defualtMisses + misses;
|
||||
float hitPercent = Math.round(totalHits / attacks * 100);
|
||||
float missPercent = Math.round(totalMisses / attacks * 100);
|
||||
|
||||
output += "HITS LANDED: " + (defaultHits + hits) + "(" + Math.round(hitPercent) + "%)" + newline;
|
||||
output += "HITS MISSED: " + (defualtMisses + misses) + "(" + Math.round(missPercent) + "%)";
|
||||
|
||||
throwbackInfo(playerCharacter,output);
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
simCount = Integer.parseInt(words[0]);
|
||||
|
||||
@@ -49,10 +49,20 @@ public class ArenaManager {
|
||||
if (!playerQueue.contains(player)) {
|
||||
playerQueue.add(player);
|
||||
}
|
||||
for(PlayerCharacter pc : playerQueue){
|
||||
if(pc.equals(player))
|
||||
continue;
|
||||
ChatManager.chatSystemInfo(pc, player.getName() + " has joined the arena que. There are now " + playerQueue.size() + " players queued.");
|
||||
}
|
||||
}
|
||||
|
||||
public static void leaveQueue(PlayerCharacter player) {
|
||||
playerQueue.remove(player);
|
||||
for(PlayerCharacter pc : playerQueue){
|
||||
if(pc.equals(player))
|
||||
continue;
|
||||
ChatManager.chatSystemInfo(pc, player.getName() + " has left the arena que. There are now " + playerQueue.size() + " players queued.");
|
||||
}
|
||||
}
|
||||
|
||||
private static void createArena() {
|
||||
|
||||
@@ -27,6 +27,7 @@ import engine.objects.*;
|
||||
import engine.server.MBServerStatics;
|
||||
import engine.server.world.WorldServer;
|
||||
import engine.session.Session;
|
||||
import engine.util.KeyCloneAudit;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -84,6 +85,10 @@ public enum ChatManager {
|
||||
if ((checkTime > 0L) && (curMsgTime - checkTime < FLOOD_TIME_THRESHOLD))
|
||||
isFlood = true;
|
||||
|
||||
if(KeyCloneAudit.auditChatMsg(pc,msg.getMessage())){
|
||||
return;
|
||||
}
|
||||
|
||||
switch (protocolMsg) {
|
||||
case CHATSAY:
|
||||
ChatManager.chatSay(pc, msg.getMessage(), isFlood);
|
||||
|
||||
@@ -301,6 +301,17 @@ public enum CombatManager {
|
||||
if (target == null)
|
||||
return 0;
|
||||
|
||||
//pet to assist in attacking target
|
||||
if(abstractCharacter.getObjectType().equals(GameObjectType.PlayerCharacter)){
|
||||
PlayerCharacter attacker = (PlayerCharacter)abstractCharacter;
|
||||
if(attacker.getPet() != null){
|
||||
Mob pet = attacker.getPet();
|
||||
if(pet.combatTarget == null && pet.assist)
|
||||
pet.setCombatTarget(attacker.combatTarget);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//target must be valid type
|
||||
|
||||
if (AbstractWorldObject.IsAbstractCharacter(target)) {
|
||||
@@ -483,16 +494,24 @@ public enum CombatManager {
|
||||
createTimer(abstractCharacter, slot, 20, true); //2 second for no weapon
|
||||
else {
|
||||
int wepSpeed = (int) (wb.getSpeed());
|
||||
if(abstractCharacter.getObjectType().equals(GameObjectType.PlayerCharacter)){
|
||||
PlayerCharacter pc = (PlayerCharacter)abstractCharacter;
|
||||
if(slot == 1){
|
||||
wepSpeed = (int) pc.combatStats.attackSpeedHandOne;
|
||||
}else{
|
||||
wepSpeed = (int) pc.combatStats.attackSpeedHandTwo;
|
||||
}
|
||||
}else {
|
||||
|
||||
if (weapon != null && weapon.getBonusPercent(ModType.WeaponSpeed, SourceType.None) != 0f) //add weapon speed bonus
|
||||
wepSpeed *= (1 + weapon.getBonus(ModType.WeaponSpeed, SourceType.None));
|
||||
if (weapon != null && weapon.getBonusPercent(ModType.WeaponSpeed, SourceType.None) != 0f) //add weapon speed bonus
|
||||
wepSpeed *= (1 + weapon.getBonus(ModType.WeaponSpeed, SourceType.None));
|
||||
|
||||
if (abstractCharacter.getBonuses() != null && abstractCharacter.getBonuses().getFloatPercentAll(ModType.AttackDelay, SourceType.None) != 0f) //add effects speed bonus
|
||||
wepSpeed *= (1 + abstractCharacter.getBonuses().getFloatPercentAll(ModType.AttackDelay, SourceType.None));
|
||||
|
||||
if (wepSpeed < 10)
|
||||
wepSpeed = 10; //Old was 10, but it can be reached lower with legit buffs,effects.
|
||||
if (abstractCharacter.getBonuses() != null && abstractCharacter.getBonuses().getFloatPercentAll(ModType.AttackDelay, SourceType.None) != 0f) //add effects speed bonus
|
||||
wepSpeed *= (1 + abstractCharacter.getBonuses().getFloatPercentAll(ModType.AttackDelay, SourceType.None));
|
||||
|
||||
if (wepSpeed < 10)
|
||||
wepSpeed = 10; //Old was 10, but it can be reached lower with legit buffs,effects.
|
||||
}
|
||||
createTimer(abstractCharacter, slot, wepSpeed, true);
|
||||
}
|
||||
|
||||
@@ -536,15 +555,29 @@ public enum CombatManager {
|
||||
|
||||
if (target == null)
|
||||
return;
|
||||
|
||||
if (mainHand) {
|
||||
atr = ac.getAtrHandOne();
|
||||
minDamage = ac.getMinDamageHandOne();
|
||||
maxDamage = ac.getMaxDamageHandOne();
|
||||
} else {
|
||||
atr = ac.getAtrHandTwo();
|
||||
minDamage = ac.getMinDamageHandTwo();
|
||||
maxDamage = ac.getMaxDamageHandTwo();
|
||||
if(ac.getObjectType().equals(GameObjectType.PlayerCharacter)){
|
||||
PlayerCharacter pc = (PlayerCharacter) ac;
|
||||
pc.combatStats.calculateATR(true);
|
||||
pc.combatStats.calculateATR(false);
|
||||
if (mainHand) {
|
||||
atr = pc.combatStats.atrHandOne;
|
||||
minDamage = pc.combatStats.minDamageHandOne;
|
||||
maxDamage = pc.combatStats.maxDamageHandOne;
|
||||
} else {
|
||||
atr = pc.combatStats.atrHandTwo;
|
||||
minDamage = pc.combatStats.minDamageHandTwo;
|
||||
maxDamage = pc.combatStats.maxDamageHandTwo;
|
||||
}
|
||||
}else {
|
||||
if (mainHand) {
|
||||
atr = ac.getAtrHandOne();
|
||||
minDamage = ac.getMinDamageHandOne();
|
||||
maxDamage = ac.getMaxDamageHandOne();
|
||||
} else {
|
||||
atr = ac.getAtrHandTwo();
|
||||
minDamage = ac.getMinDamageHandTwo();
|
||||
maxDamage = ac.getMaxDamageHandTwo();
|
||||
}
|
||||
}
|
||||
|
||||
boolean tarIsRat = false;
|
||||
@@ -638,7 +671,12 @@ public enum CombatManager {
|
||||
}
|
||||
} else {
|
||||
AbstractCharacter tar = (AbstractCharacter) target;
|
||||
defense = tar.getDefenseRating();
|
||||
if(tar.getObjectType().equals(GameObjectType.PlayerCharacter)){
|
||||
((PlayerCharacter)tar).combatStats.calculateDefense();
|
||||
defense = ((PlayerCharacter)tar).combatStats.defense;
|
||||
}else {
|
||||
defense = tar.getDefenseRating();
|
||||
}
|
||||
handleRetaliate(tar, ac); //Handle target attacking back if in combat and has no other target
|
||||
}
|
||||
|
||||
@@ -647,7 +685,7 @@ public enum CombatManager {
|
||||
//Get hit chance
|
||||
|
||||
//int chance;
|
||||
float dif = atr - defense;
|
||||
//float dif = atr - defense;
|
||||
|
||||
//if (dif > 100)
|
||||
// chance = 94;
|
||||
@@ -662,9 +700,8 @@ public enum CombatManager {
|
||||
|
||||
DeferredPowerJob dpj = null;
|
||||
|
||||
|
||||
|
||||
if (LandHit((int)atr,(int)defense)) {
|
||||
boolean hitLanded = LandHit((int)atr,(int)defense);
|
||||
if (hitLanded) {
|
||||
|
||||
if (ac.getObjectType().equals(GameObjectType.PlayerCharacter))
|
||||
updateAttackTimers((PlayerCharacter) ac, target, true);
|
||||
@@ -693,7 +730,13 @@ public enum CombatManager {
|
||||
|
||||
PlayerBonuses bonus = ac.getBonuses();
|
||||
float attackRange = getWeaponRange(wb, bonus);
|
||||
dpj.attack(target, attackRange);
|
||||
if(specialCaseHitRoll(dpj.getPowerToken())) {
|
||||
if(hitLanded) {
|
||||
dpj.attack(target, attackRange);
|
||||
}
|
||||
}else{
|
||||
dpj.attack(target, attackRange);
|
||||
}
|
||||
|
||||
if (dpj.getPower() != null && (dpj.getPowerToken() == -1851459567 || dpj.getPowerToken() == -1851489518))
|
||||
((PlayerCharacter) ac).setWeaponPower(dpj);
|
||||
@@ -708,7 +751,13 @@ public enum CombatManager {
|
||||
|
||||
if (dpj != null && dpj.getPower() != null && (dpj.getPowerToken() == -1851459567 || dpj.getPowerToken() == -1851489518)) {
|
||||
float attackRange = getWeaponRange(wb, bonuses);
|
||||
dpj.attack(target, attackRange);
|
||||
if(specialCaseHitRoll(dpj.getPowerToken())) {
|
||||
if(hitLanded) {
|
||||
dpj.attack(target, attackRange);
|
||||
}
|
||||
}else{
|
||||
dpj.attack(target, attackRange);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -815,6 +864,22 @@ public enum CombatManager {
|
||||
else
|
||||
damage = calculateDamage(ac, tarAc, minDamage, maxDamage, damageType, resists);
|
||||
|
||||
if(weapon != null && weapon.effects != null){
|
||||
float armorPierce = 0;
|
||||
for(Effect eff : weapon.effects.values()){
|
||||
for(AbstractEffectModifier mod : eff.getEffectModifiers()){
|
||||
if(mod.modType.equals(ModType.ArmorPiercing)){
|
||||
armorPierce += mod.minMod * (mod.getRamp() * eff.getTrains());
|
||||
}
|
||||
}
|
||||
}
|
||||
if(armorPierce > 0){
|
||||
damage *= 1 - armorPierce;
|
||||
}
|
||||
}
|
||||
|
||||
//Resists.handleFortitude(tarAc,damageType,damage);
|
||||
|
||||
float d = 0f;
|
||||
|
||||
errorTrack = 12;
|
||||
@@ -867,27 +932,18 @@ public enum CombatManager {
|
||||
|
||||
if (weapon != null && tarAc != null && tarAc.isAlive()) {
|
||||
|
||||
ConcurrentHashMap<String, Effect> effects = weapon.getEffects();
|
||||
|
||||
for (Effect eff : effects.values()) {
|
||||
if (eff == null)
|
||||
continue;
|
||||
|
||||
HashSet<AbstractEffectModifier> aems = eff.getEffectModifiers();
|
||||
|
||||
if (aems != null) {
|
||||
for (AbstractEffectModifier aem : aems) {
|
||||
|
||||
if (!tarAc.isAlive())
|
||||
break;
|
||||
|
||||
if (aem instanceof WeaponProcEffectModifier) {
|
||||
|
||||
if(weapon.effects != null){
|
||||
for (Effect eff : weapon.effects.values()){
|
||||
for(AbstractEffectModifier mod : eff.getEffectModifiers()){
|
||||
if(mod.modType.equals(ModType.WeaponProc)){
|
||||
int procChance = ThreadLocalRandom.current().nextInt(100);
|
||||
|
||||
if (procChance < MBServerStatics.PROC_CHANCE)
|
||||
((WeaponProcEffectModifier) aem).applyProc(ac, target);
|
||||
|
||||
if (procChance < MBServerStatics.PROC_CHANCE) {
|
||||
try {
|
||||
((WeaponProcEffectModifier) mod).applyProc(ac, target);
|
||||
}catch(Exception e){
|
||||
Logger.error(eff.getName() + " Failed To Cast Proc");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -916,7 +972,13 @@ public enum CombatManager {
|
||||
if (wp.requiresHitRoll() == false) {
|
||||
PlayerBonuses bonus = ac.getBonuses();
|
||||
float attackRange = getWeaponRange(wb, bonus);
|
||||
dpj.attack(target, attackRange);
|
||||
if(specialCaseHitRoll(dpj.getPowerToken())) {
|
||||
if(hitLanded) {
|
||||
dpj.attack(target, attackRange);
|
||||
}
|
||||
}else{
|
||||
dpj.attack(target, attackRange);
|
||||
}
|
||||
} else
|
||||
((PlayerCharacter) ac).setWeaponPower(null);
|
||||
}
|
||||
@@ -1023,10 +1085,12 @@ public enum CombatManager {
|
||||
|
||||
//calculate resists in if any
|
||||
|
||||
|
||||
|
||||
if (resists != null)
|
||||
return resists.getResistedDamage(source, target, damageType, damage, 0);
|
||||
else
|
||||
return damage;
|
||||
damage = resists.getResistedDamage(source, target, damageType, damage, 0);
|
||||
|
||||
return damage;
|
||||
}
|
||||
|
||||
private static void sendPassiveDefenseMessage(AbstractCharacter source, ItemBase wb, AbstractWorldObject target, int passiveType, DeferredPowerJob dpj, boolean mainHand) {
|
||||
@@ -1180,6 +1244,14 @@ public enum CombatManager {
|
||||
|
||||
private static boolean testPassive(AbstractCharacter source, AbstractCharacter target, String type) {
|
||||
|
||||
if(target.getBonuses() != null)
|
||||
if(target.getBonuses().getBool(ModType.Stunned, SourceType.None))
|
||||
return false;
|
||||
|
||||
if(source.getBonuses() != null)
|
||||
if(source.getBonuses().getBool(ModType.IgnorePassiveDefense, SourceType.None))
|
||||
return false;
|
||||
|
||||
float chance = target.getPassiveChance(type, source.getLevel(), true);
|
||||
|
||||
if (chance == 0f)
|
||||
@@ -1190,7 +1262,7 @@ public enum CombatManager {
|
||||
if (chance > 75f)
|
||||
chance = 75f;
|
||||
|
||||
int roll = ThreadLocalRandom.current().nextInt(100);
|
||||
int roll = ThreadLocalRandom.current().nextInt(1,100);
|
||||
|
||||
return roll < chance;
|
||||
|
||||
@@ -1368,9 +1440,9 @@ public enum CombatManager {
|
||||
|
||||
Resists resists = ac.getResists();
|
||||
|
||||
if (resists != null)
|
||||
if (resists != null) {
|
||||
amount = resists.getResistedDamage(target, ac, ds.getDamageType(), amount, 0);
|
||||
|
||||
}
|
||||
total += amount;
|
||||
}
|
||||
|
||||
@@ -1453,19 +1525,31 @@ public enum CombatManager {
|
||||
((AbstractCharacter) awo).getCharItemManager().damageRandomArmor(1);
|
||||
}
|
||||
|
||||
public static boolean LandHit(int atr, int defense){
|
||||
public static boolean LandHit(int ATR, int DEF){
|
||||
|
||||
//float chance = (ATR-((ATR+DEF) * 0.315f)) / ((DEF-((ATR+DEF) * 0.315f)) + (ATR-((ATR+DEF) * 0.315f)));
|
||||
//float convertedChance = chance * 100;
|
||||
|
||||
int roll = ThreadLocalRandom.current().nextInt(101);
|
||||
float chance = (float)((atr-((atr+defense)*0.315))/((defense-((atr+defense)*0.315))+(atr-((atr+defense)*0.315))));
|
||||
|
||||
int connvertedChance = (int)(chance * 100);
|
||||
//if(roll <= 5)//always 5% chance to miss
|
||||
// return false;
|
||||
|
||||
if(connvertedChance < 5)
|
||||
connvertedChance = 5;
|
||||
//if(roll >= 95)//always 5% chance to hit
|
||||
// return true;
|
||||
|
||||
if(connvertedChance > 95)
|
||||
connvertedChance = 95;
|
||||
float chance = PlayerCombatStats.getHitChance(ATR,DEF);
|
||||
return chance >= roll;
|
||||
}
|
||||
|
||||
return connvertedChance > roll;
|
||||
public static boolean specialCaseHitRoll(int powerID){
|
||||
switch(powerID) {
|
||||
case 563200808: // Naargal's Bite
|
||||
case 563205337: // Naargal's Dart
|
||||
case 563205930: // Sword of Saint Malorn
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,7 +98,8 @@ public enum ConfigManager {
|
||||
MB_MAGICBOT_FORTOFIX,
|
||||
MB_MAGICBOT_RECRUIT,
|
||||
MB_MAGICBOT_MAGICBOX,
|
||||
MB_MAGICBOT_ADMINLOG;
|
||||
MB_MAGICBOT_ADMINLOG,
|
||||
MB_WORLD_BOXLIMIT;
|
||||
|
||||
// Map to hold our config pulled in from the environment
|
||||
// We also use the config to point to the current message pump
|
||||
|
||||
@@ -177,6 +177,11 @@ public enum DevCmdManager {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!pcSender.getTimestamps().containsKey("DEVCOMMAND"))
|
||||
pcSender.getTimestamps().put("DEVCOMMAND",System.currentTimeMillis() - 1500L);
|
||||
else if(System.currentTimeMillis() - pcSender.getTimestamps().get("DEVCOMMAND") < 1000L)
|
||||
return false;
|
||||
|
||||
//kill any commands not available to everyone on production server
|
||||
//only admin level can run dev commands on production
|
||||
boolean playerAllowed = false;
|
||||
@@ -189,6 +194,20 @@ public enum DevCmdManager {
|
||||
case "gimme":
|
||||
case "goto":
|
||||
case "teleportmode":
|
||||
case "printbonuses":
|
||||
playerAllowed = true;
|
||||
if (!a.status.equals(Enum.AccountStatus.ADMIN))
|
||||
target = pcSender;
|
||||
break;
|
||||
}
|
||||
}else{
|
||||
switch (adc.getMainCmdString()) {
|
||||
case "printresists":
|
||||
case "printstats":
|
||||
case "printskills":
|
||||
case "printpowers":
|
||||
case "printbonuses":
|
||||
//case "gimme":
|
||||
playerAllowed = true;
|
||||
if (!a.status.equals(Enum.AccountStatus.ADMIN))
|
||||
target = pcSender;
|
||||
|
||||
@@ -75,6 +75,11 @@ public enum LootManager {
|
||||
}
|
||||
|
||||
public static void GenerateMobLoot(Mob mob) {
|
||||
|
||||
if(mob == null){
|
||||
return;
|
||||
}
|
||||
|
||||
//determine if mob is in hotzone
|
||||
boolean inHotzone = false;
|
||||
|
||||
@@ -180,14 +185,16 @@ public enum LootManager {
|
||||
|
||||
|
||||
// Iterate all entries in this bootySet and process accordingly
|
||||
Zone zone = ZoneManager.findSmallestZone(mob.loc);
|
||||
for (BootySetEntry bse : entries) {
|
||||
switch (bse.bootyType) {
|
||||
case "GOLD":
|
||||
if (zone != null && zone.getSafeZone() == (byte)1)
|
||||
return; // no loot to drop in safezones
|
||||
GenerateGoldDrop(mob, bse, inHotzone);
|
||||
break;
|
||||
case "LOOT":
|
||||
|
||||
if (mob.getSafeZone())
|
||||
if (zone != null && zone.getSafeZone() == (byte)1)
|
||||
return; // no loot to drop in safezones
|
||||
|
||||
dropRate = LootManager.NORMAL_DROP_RATE;
|
||||
|
||||
@@ -67,8 +67,10 @@ public enum MovementManager {
|
||||
return;
|
||||
|
||||
if (toMove.getObjectType().equals(GameObjectType.PlayerCharacter)) {
|
||||
if (((PlayerCharacter) toMove).isCasting())
|
||||
((PlayerCharacter) toMove).update(false);
|
||||
if (((PlayerCharacter) toMove).isCasting()) {
|
||||
((PlayerCharacter) toMove).updateLocation();
|
||||
((PlayerCharacter) toMove).updateMovementState();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -408,7 +410,9 @@ public enum MovementManager {
|
||||
if (bonus.getBool(ModType.Stunned, SourceType.None) || bonus.getBool(ModType.CannotMove, SourceType.None))
|
||||
continue;
|
||||
|
||||
member.update(false);
|
||||
//member.update(false);
|
||||
member.updateLocation();
|
||||
member.updateMovementState();
|
||||
|
||||
|
||||
// All checks passed, let's move the player
|
||||
|
||||
@@ -10,6 +10,7 @@ package engine.gameManager;
|
||||
|
||||
import engine.Enum.*;
|
||||
import engine.InterestManagement.HeightMap;
|
||||
import engine.InterestManagement.InterestManager;
|
||||
import engine.InterestManagement.WorldGrid;
|
||||
import engine.db.handlers.dbEffectsBaseHandler;
|
||||
import engine.db.handlers.dbPowerHandler;
|
||||
@@ -165,12 +166,20 @@ public enum PowersManager {
|
||||
|
||||
PlayerCharacter pc = SessionManager.getPlayerCharacter(origin);
|
||||
|
||||
if(!pc.isFlying()) //cant be sitting if flying
|
||||
if(pc == null)
|
||||
return;
|
||||
|
||||
if(!pc.isFlying() && powersBaseByToken.get(msg.getPowerUsedID()) != null && powersBaseByToken.get(msg.getPowerUsedID()).isSpell) //cant be sitting if flying
|
||||
CombatManager.toggleSit(false,origin);
|
||||
|
||||
if(pc.isMoving())
|
||||
pc.stopMovement(pc.getMovementLoc());
|
||||
|
||||
if(msg.getPowerUsedID() == 429429978){
|
||||
applyPower(origin.getPlayerCharacter(),origin.getPlayerCharacter(),origin.getPlayerCharacter().getLoc(),429429978,msg.getNumTrains(),false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (usePowerA(msg, origin, sendCastToSelf)) {
|
||||
// Cast failed for some reason, reset timer
|
||||
|
||||
@@ -197,7 +206,8 @@ public enum PowersManager {
|
||||
msg.setUnknown04(1);
|
||||
|
||||
if (useMobPowerA(msg, caster)) {
|
||||
//sendMobPowerMsg(caster,2,msg); //Lol wtf was i thinking sending msg's to mobs... ZZZZ
|
||||
if(pb.token == -1994153779)
|
||||
InterestManager.setObjectDirty(caster);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -216,16 +226,16 @@ public enum PowersManager {
|
||||
City city = ZoneManager.getCityAtLocation(playerCharacter.loc);
|
||||
if (city == null) {
|
||||
failed = true;
|
||||
}else{
|
||||
Bane bane = city.getBane();
|
||||
if (bane == null) {
|
||||
failed = true;
|
||||
}else{
|
||||
if(!bane.getSiegePhase().equals(SiegePhase.WAR)){
|
||||
failed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}//else{
|
||||
// Bane bane = city.getBane();
|
||||
// if (bane == null) {
|
||||
// failed = true;
|
||||
// }else{
|
||||
// if(!bane.getSiegePhase().equals(SiegePhase.WAR)){
|
||||
// failed = true;
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
if(failed){
|
||||
//check to see if we are at an active mine
|
||||
Zone zone = ZoneManager.findSmallestZone(playerCharacter.loc);
|
||||
@@ -242,8 +252,15 @@ public enum PowersManager {
|
||||
}
|
||||
}
|
||||
|
||||
if(failed)
|
||||
if(failed) {
|
||||
playerCharacter.setIsCasting(false);
|
||||
|
||||
RecyclePowerMsg recyclePowerMsg = new RecyclePowerMsg(msg.getPowerUsedID());
|
||||
Dispatch dispatch = Dispatch.borrow(playerCharacter, recyclePowerMsg);
|
||||
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (MBServerStatics.POWERS_DEBUG) {
|
||||
@@ -329,17 +346,18 @@ public enum PowersManager {
|
||||
|
||||
|
||||
// Check powers for normal users
|
||||
if (playerCharacter.getPowers() == null || !playerCharacter.getPowers().containsKey(msg.getPowerUsedID()))
|
||||
if (!playerCharacter.isCSR()) {
|
||||
if (!MBServerStatics.POWERS_DEBUG) {
|
||||
// ChatManager.chatSayInfo(pc, "You may not cast that spell!");
|
||||
|
||||
Logger.info("usePowerA(): Cheat attempted? '" + msg.getPowerUsedID() + "' was not associated with " + playerCharacter.getName());
|
||||
return true;
|
||||
}
|
||||
} else
|
||||
CSRCast = true;
|
||||
if(msg.getPowerUsedID() != 421084024) {
|
||||
if (playerCharacter.getPowers() == null || !playerCharacter.getPowers().containsKey(msg.getPowerUsedID()))
|
||||
if (!playerCharacter.isCSR()) {
|
||||
if (!MBServerStatics.POWERS_DEBUG) {
|
||||
// ChatManager.chatSayInfo(pc, "You may not cast that spell!");
|
||||
|
||||
Logger.info("usePowerA(): Cheat attempted? '" + msg.getPowerUsedID() + "' was not associated with " + playerCharacter.getName());
|
||||
return true;
|
||||
}
|
||||
} else
|
||||
CSRCast = true;
|
||||
}
|
||||
// get numTrains for power
|
||||
int trains = msg.getNumTrains();
|
||||
|
||||
@@ -349,8 +367,10 @@ public enum PowersManager {
|
||||
msg.setNumTrains(trains);
|
||||
}
|
||||
|
||||
//double stack point values for some useless disc spells
|
||||
switch(pb.token){
|
||||
case 429420458: // BH eyes
|
||||
case 429601664: // huntsman skin the beast
|
||||
msg.setNumTrains(msg.getNumTrains() * 2);
|
||||
break;
|
||||
}
|
||||
@@ -490,6 +510,23 @@ public enum PowersManager {
|
||||
}
|
||||
}
|
||||
|
||||
if(!passed){
|
||||
if (playerCharacter.getRace().getName().contains("Shade")) {
|
||||
if(playerCharacter.getHidden() > 0){
|
||||
switch(msg.getPowerUsedID()){
|
||||
case -1851459567:
|
||||
case 2094922127:
|
||||
case -355707373:
|
||||
case 246186475:
|
||||
case 666419835:
|
||||
case 1480354319:
|
||||
passed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!passed)
|
||||
return true;
|
||||
}
|
||||
@@ -602,12 +639,12 @@ public enum PowersManager {
|
||||
}
|
||||
|
||||
// update cast (use skill) fail condition
|
||||
if(pb.token != 429396028) {
|
||||
if(pb.token != 429396028 && pb.breaksForm) {
|
||||
playerCharacter.cancelOnCast();
|
||||
}
|
||||
|
||||
// update castSpell (use spell) fail condition if spell
|
||||
if (pb.isSpell())
|
||||
if (pb.isSpell() && pb.breaksForm)
|
||||
playerCharacter.cancelOnSpell();
|
||||
|
||||
// get cast time in ms.
|
||||
@@ -748,10 +785,11 @@ public enum PowersManager {
|
||||
|
||||
// make person casting stand up if spell (unless they're casting a chant which does not make them stand up)
|
||||
// update cast (use skill) fail condition
|
||||
caster.cancelOnCast();
|
||||
if(pb.breaksForm)
|
||||
caster.cancelOnCast();
|
||||
|
||||
// update castSpell (use spell) fail condition if spell
|
||||
if (pb.isSpell())
|
||||
if (pb.isSpell() && pb.breaksForm)
|
||||
caster.cancelOnSpell();
|
||||
|
||||
// get cast time in ms.
|
||||
@@ -787,14 +825,36 @@ public enum PowersManager {
|
||||
if (playerCharacter == null || msg == null)
|
||||
return;
|
||||
|
||||
if((msg.getPowerUsedID() == 429495514 || msg.getPowerUsedID() == 429407306) && playerCharacter.getRace().getName().toLowerCase().contains("shade")){
|
||||
//msg.setPowerUsedID(407015607);
|
||||
applyPower(playerCharacter,playerCharacter,playerCharacter.loc,429397210,msg.getNumTrains(),false);
|
||||
|
||||
//handle sprint for bard sprint
|
||||
if(msg.getPowerUsedID() == 429005674){
|
||||
msg.setPowerUsedID(429611355);
|
||||
}
|
||||
if(msg.getPowerUsedID() == 429494441) {//wildkins chase
|
||||
|
||||
//handle root and snare break for wildkin's chase
|
||||
if(msg.getPowerUsedID() == 429494441) {
|
||||
playerCharacter.removeEffectBySource(EffectSourceType.Root,40,true);
|
||||
playerCharacter.removeEffectBySource(EffectSourceType.Snare,40,true);
|
||||
}
|
||||
|
||||
//handle power block portion for shade hide
|
||||
if(playerCharacter.getRace().getName().contains("Shade")) {
|
||||
if (msg.getPowerUsedID() == 429407306 || msg.getPowerUsedID() == 429495514) {
|
||||
int trains = msg.getNumTrains() - 1;
|
||||
if (trains < 1)
|
||||
trains = 1;
|
||||
applyPower(playerCharacter, playerCharacter, playerCharacter.loc, 429397210, trains, false);
|
||||
playerCharacter.removeEffectBySource(EffectSourceType.Invisibility,40,true);
|
||||
applyPower(playerCharacter, playerCharacter, playerCharacter.loc, msg.getPowerUsedID(), msg.getNumTrains(), false);
|
||||
}
|
||||
}
|
||||
if(msg.getTargetType() == GameObjectType.PlayerCharacter.ordinal()) {
|
||||
PlayerCharacter target = PlayerCharacter.getPlayerCharacter(msg.getTargetID());
|
||||
if (msg.getPowerUsedID() == 429601664)
|
||||
if(target.getPromotionClassID() != 2516)
|
||||
PlayerCharacter.getPlayerCharacter(msg.getTargetID()).removeEffectBySource(EffectSourceType.Transform, msg.getNumTrains(), true);
|
||||
}
|
||||
|
||||
if (playerCharacter.isCasting()) {
|
||||
playerCharacter.update(false);
|
||||
playerCharacter.updateStamRegen(-100);
|
||||
@@ -1567,6 +1627,7 @@ public enum PowersManager {
|
||||
case 431511776:
|
||||
case 429578587:
|
||||
case 429503360:
|
||||
case 44106356:
|
||||
trackChars = getTrackList(playerCharacter);
|
||||
break;
|
||||
default:
|
||||
@@ -2405,6 +2466,13 @@ public enum PowersManager {
|
||||
dodgeMsg.setTargetID(awo.getObjectUUID());
|
||||
sendPowerMsg(pc, 4, dodgeMsg);
|
||||
return true;
|
||||
} else if (testPassive(pc, tarAc, "Block")) {
|
||||
// Dodge fired, send dodge message
|
||||
PerformActionMsg dodgeMsg = new PerformActionMsg(msg);
|
||||
dodgeMsg.setTargetType(awo.getObjectType().ordinal());
|
||||
dodgeMsg.setTargetID(awo.getObjectUUID());
|
||||
sendPowerMsg(pc, 4, dodgeMsg);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@@ -2452,7 +2520,12 @@ public enum PowersManager {
|
||||
if (AbstractWorldObject.IsAbstractCharacter(awo)) {
|
||||
AbstractCharacter tarAc = (AbstractCharacter) awo;
|
||||
// Handle Dodge passive
|
||||
return testPassive(caster, tarAc, "Dodge");
|
||||
boolean passiveFired = false;
|
||||
passiveFired = testPassive(caster, tarAc, "Dodge");
|
||||
if(!passiveFired)
|
||||
passiveFired = testPassive(caster, tarAc, "Block");
|
||||
|
||||
return passiveFired;
|
||||
}
|
||||
return false;
|
||||
} else
|
||||
@@ -2841,6 +2914,126 @@ public enum PowersManager {
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean breakForm(int token) {
|
||||
switch (token) {
|
||||
case 429505865:
|
||||
case 429407561:
|
||||
case 429492073:
|
||||
case 429644123:
|
||||
case 429393769:
|
||||
case 429545819:
|
||||
case 429426537:
|
||||
case 429590377:
|
||||
case 429508425:
|
||||
case 429541193:
|
||||
case 429573961:
|
||||
case 427924330:
|
||||
case 429402918:
|
||||
case 429545688:
|
||||
case 429005674:
|
||||
case 429637823:
|
||||
case 429590426:
|
||||
case 428066972:
|
||||
case 429441862:
|
||||
case 431611756:
|
||||
case 431578988:
|
||||
case 429502506:
|
||||
case 429398191:
|
||||
case 429447384:
|
||||
case 428892191:
|
||||
case 431579167:
|
||||
case 430977067:
|
||||
case 429409100:
|
||||
case 429441868:
|
||||
case 429594877:
|
||||
case 427908971:
|
||||
case 683741153:
|
||||
case 429770569:
|
||||
case 429452379:
|
||||
case 429605055:
|
||||
case 429086971:
|
||||
case 429443230:
|
||||
case 429505400:
|
||||
case 429492122:
|
||||
case 429643992:
|
||||
case 550062236:
|
||||
case 429498252:
|
||||
case 429611224:
|
||||
case 429441834:
|
||||
case 428918940:
|
||||
case 429633739:
|
||||
case 429633579:
|
||||
case 429568043:
|
||||
case 429048646:
|
||||
case 428392639:
|
||||
case 428425407:
|
||||
case 429054168:
|
||||
case 429021400:
|
||||
case 428955864:
|
||||
case 429119704:
|
||||
case 428890328:
|
||||
case 428923096:
|
||||
case 429218008:
|
||||
case 429086936:
|
||||
case 428988632:
|
||||
case 428688204:
|
||||
case 429514603:
|
||||
case 428924959:
|
||||
case 429393818:
|
||||
case 429720966:
|
||||
case 428982463:
|
||||
case 427933887:
|
||||
case 429572287:
|
||||
case 429501222:
|
||||
case 430694431:
|
||||
case 429436131:
|
||||
case 430006124:
|
||||
case 429611355:
|
||||
case 428005600:
|
||||
case 427935608:
|
||||
case 428949695:
|
||||
case 427988218:
|
||||
case 429414616:
|
||||
case 429496495:
|
||||
case 429428796:
|
||||
case 563795754:
|
||||
case 428988217:
|
||||
case 429432716:
|
||||
case 428955899:
|
||||
case 429393286:
|
||||
case 550062220:
|
||||
case 429495557:
|
||||
case 429401278:
|
||||
case 428377478:
|
||||
case 429409094:
|
||||
case 428191947:
|
||||
case 429434474:
|
||||
case 429403363:
|
||||
case 429512920:
|
||||
case 429419611:
|
||||
case 429645676:
|
||||
case 429602895:
|
||||
case 429605071:
|
||||
case 429592428:
|
||||
case 429500010:
|
||||
case 429406602:
|
||||
case 429426586:
|
||||
case 429633898:
|
||||
case 550062212:
|
||||
case 429994027:
|
||||
case 430813227:
|
||||
case 429928491:
|
||||
case 430026795:
|
||||
case 429517915:
|
||||
case 431854842:
|
||||
case 429767544:
|
||||
case 429502507:
|
||||
case 428398816:
|
||||
case 429446315:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -93,13 +93,10 @@ public enum SimulationManager {
|
||||
}
|
||||
try {
|
||||
|
||||
if ((_updatePulseTime != 0)
|
||||
&& (System.currentTimeMillis() > _updatePulseTime))
|
||||
if ((_updatePulseTime != 0) && (System.currentTimeMillis() > _updatePulseTime))
|
||||
pulseUpdate();
|
||||
} catch (Exception e) {
|
||||
Logger.error(
|
||||
"Fatal error in Update Pulse: DISABLED");
|
||||
// _runegatePulseTime = 0;
|
||||
Logger.error("Fatal error in Update Pulse: DISABLED");
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -160,7 +157,11 @@ public enum SimulationManager {
|
||||
|
||||
if (player == null)
|
||||
continue;
|
||||
player.update(false);
|
||||
try {
|
||||
player.update(false);
|
||||
}catch(Exception e){
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
_updatePulseTime = System.currentTimeMillis() + 500;
|
||||
|
||||
@@ -68,7 +68,7 @@ public abstract class AbstractJob implements Runnable {
|
||||
this.markStopRunTime();
|
||||
}
|
||||
|
||||
protected abstract void doJob();
|
||||
public abstract void doJob();
|
||||
|
||||
public void executeJob(String threadName) {
|
||||
this.workerID.set(threadName);
|
||||
|
||||
@@ -17,7 +17,7 @@ public abstract class AbstractScheduleJob extends AbstractJob {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected abstract void doJob();
|
||||
public abstract void doJob();
|
||||
|
||||
public void cancelJob() {
|
||||
JobScheduler.getInstance().cancelScheduledJob(this);
|
||||
|
||||
@@ -16,7 +16,7 @@ public class JobContainer implements Comparable<JobContainer> {
|
||||
final long timeOfExecution;
|
||||
final boolean noTimer;
|
||||
|
||||
JobContainer(AbstractJob job, long timeOfExecution) {
|
||||
public JobContainer(AbstractJob job, long timeOfExecution) {
|
||||
if (job == null) {
|
||||
throw new IllegalArgumentException("No 'null' jobs allowed.");
|
||||
}
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
package engine.job;
|
||||
|
||||
import engine.server.world.WorldServer;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
public class JobThread implements Runnable {
|
||||
private final AbstractJob currentJob;
|
||||
private final ReentrantLock lock = new ReentrantLock();
|
||||
|
||||
private static Long nextThreadPrint;
|
||||
|
||||
public JobThread(AbstractJob job){
|
||||
this.currentJob = job;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
if (this.currentJob != null) {
|
||||
if (lock.tryLock(5, TimeUnit.SECONDS)) { // Timeout to prevent deadlock
|
||||
try {
|
||||
this.currentJob.doJob();
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
} else {
|
||||
Logger.warn("JobThread could not acquire lock in time, skipping job.");
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Logger.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void startJobThread(AbstractJob job){
|
||||
JobThread jobThread = new JobThread(job);
|
||||
Thread thread = new Thread(jobThread);
|
||||
thread.setName("JOB THREAD: " + job.getWorkerID());
|
||||
thread.start();
|
||||
|
||||
if(JobThread.nextThreadPrint == null){
|
||||
JobThread.nextThreadPrint = System.currentTimeMillis();
|
||||
}else{
|
||||
if(JobThread.nextThreadPrint < System.currentTimeMillis()){
|
||||
JobThread.tryPrintThreads();
|
||||
JobThread.nextThreadPrint = System.currentTimeMillis() + 10000L;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void tryPrintThreads(){
|
||||
ThreadGroup rootGroup = Thread.currentThread().getThreadGroup();
|
||||
while (rootGroup.getParent() != null) {
|
||||
rootGroup = rootGroup.getParent();
|
||||
}
|
||||
|
||||
// Estimate the number of threads
|
||||
int activeThreads = rootGroup.activeCount();
|
||||
|
||||
// Create an array to hold the threads
|
||||
Thread[] threads = new Thread[activeThreads];
|
||||
|
||||
// Get the active threads
|
||||
rootGroup.enumerate(threads, true);
|
||||
|
||||
int availableThreads = Runtime.getRuntime().availableProcessors();
|
||||
|
||||
// Print the count
|
||||
if(threads.length > 30)
|
||||
Logger.info("Total threads in application: " + threads.length + " / " + availableThreads);
|
||||
}
|
||||
}
|
||||
@@ -58,10 +58,13 @@ public class JobWorker extends ControlledRunnable {
|
||||
} else {
|
||||
|
||||
// execute the new job..
|
||||
this.currentJob.executeJob(this.getThreadName());
|
||||
this.currentJob = null;
|
||||
//this.currentJob.executeJob(this.getThreadName());
|
||||
if(this.currentJob != null) {
|
||||
JobThread.startJobThread(this.currentJob);
|
||||
this.currentJob = null;
|
||||
}
|
||||
}
|
||||
|
||||
Thread.yield();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ public abstract class AbstractEffectJob extends AbstractScheduleJob {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected abstract void doJob();
|
||||
public abstract void doJob();
|
||||
|
||||
@Override
|
||||
protected abstract void _cancelJob();
|
||||
@@ -117,7 +117,7 @@ public abstract class AbstractEffectJob extends AbstractScheduleJob {
|
||||
}
|
||||
|
||||
public void endEffect() {
|
||||
if (this.eb == null)
|
||||
if (this.eb == null || this.power == null)
|
||||
return;
|
||||
this.eb.endEffect(this.source, this.target, this.trains, this.power, this);
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ public class ActivateBaneJob extends AbstractScheduleJob {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doJob() {
|
||||
public void doJob() {
|
||||
|
||||
City city;
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ public class AttackJob extends AbstractJob {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doJob() {
|
||||
public void doJob() {
|
||||
CombatManager.doCombat(this.source, slot);
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ public class BaneDefaultTimeJob extends AbstractScheduleJob {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doJob() {
|
||||
public void doJob() {
|
||||
|
||||
//bane already set.
|
||||
if (this.bane.getLiveDate() != null) {
|
||||
|
||||
@@ -97,7 +97,7 @@ public class BasicScheduledJob extends AbstractJob {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doJob() {
|
||||
public void doJob() {
|
||||
if (execution == null) {
|
||||
Logger.error("BasicScheduledJob executed with nothing to execute.");
|
||||
return;
|
||||
|
||||
@@ -22,7 +22,7 @@ public class BonusCalcJob extends AbstractJob {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doJob() {
|
||||
public void doJob() {
|
||||
if (this.ac != null) {
|
||||
this.ac.applyBonuses();
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ public class CSessionCleanupJob extends AbstractJob {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doJob() {
|
||||
public void doJob() {
|
||||
SessionManager.cSessionCleanup(secKey);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ public class ChangeAltitudeJob extends AbstractScheduleJob {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doJob() {
|
||||
public void doJob() {
|
||||
if (this.ac != null)
|
||||
MovementManager.finishChangeAltitude(ac, targetAlt);
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ public class ChantJob extends AbstractEffectJob {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doJob() {
|
||||
public void doJob() {
|
||||
if (this.aej == null || this.source == null || this.target == null || this.action == null || this.power == null || this.source == null || this.eb == null)
|
||||
return;
|
||||
PlayerBonuses bonuses = null;
|
||||
|
||||
@@ -29,7 +29,7 @@ public class CloseGateJob extends AbstractScheduleJob {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doJob() {
|
||||
public void doJob() {
|
||||
|
||||
if (building == null) {
|
||||
Logger.error("Rungate building was null");
|
||||
|
||||
@@ -37,7 +37,7 @@ public class DamageOverTimeJob extends AbstractEffectJob {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doJob() {
|
||||
public void doJob() {
|
||||
if (this.target.getObjectType().equals(GameObjectType.Building)
|
||||
&& ((Building) this.target).isVulnerable() == false) {
|
||||
_cancelJob();
|
||||
@@ -60,6 +60,8 @@ public class DamageOverTimeJob extends AbstractEffectJob {
|
||||
|
||||
if (this.iteration < 0) {
|
||||
PowersManager.finishEffectTime(this.source, this.target, this.action, this.trains);
|
||||
if (AbstractWorldObject.IsAbstractCharacter(source))
|
||||
eb.startEffect((AbstractCharacter) this.source, this.target, this.trains, this);
|
||||
return;
|
||||
}
|
||||
this.skipSendEffect = true;
|
||||
|
||||
@@ -28,7 +28,7 @@ public class DatabaseUpdateJob extends AbstractScheduleJob {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doJob() {
|
||||
public void doJob() {
|
||||
if (this.ago == null)
|
||||
return;
|
||||
ago.removeDatabaseJob(this.type, false);
|
||||
|
||||
@@ -29,7 +29,7 @@ public class DebugTimerJob extends AbstractScheduleJob {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doJob() {
|
||||
public void doJob() {
|
||||
if (this.pc == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ public class DeferredPowerJob extends AbstractEffectJob {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doJob() {
|
||||
public void doJob() {
|
||||
//Power ended with no attack, cancel weapon power boost
|
||||
if (this.source != null && this.source instanceof PlayerCharacter) {
|
||||
((PlayerCharacter) this.source).setWeaponPower(null);
|
||||
|
||||
@@ -22,7 +22,7 @@ public class DisconnectJob extends AbstractScheduleJob {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doJob() {
|
||||
public void doJob() {
|
||||
if (this.origin != null) {
|
||||
this.origin.disconnect();
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ public class DoorCloseJob extends AbstractScheduleJob {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doJob() {
|
||||
public void doJob() {
|
||||
|
||||
int doorNumber;
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ public class EndFearJob extends AbstractEffectJob {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doJob() {
|
||||
public void doJob() {
|
||||
|
||||
//cancel fear for mob.
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ public class FinishCooldownTimeJob extends AbstractJob {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doJob() {
|
||||
public void doJob() {
|
||||
PowersManager.finishCooldownTime(this.msg, this.pc);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ public class FinishEffectTimeJob extends AbstractEffectJob {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doJob() {
|
||||
public void doJob() {
|
||||
PowersManager.finishEffectTime(this.source, this.target, this.action, this.trains);
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ public class FinishRecycleTimeJob extends AbstractScheduleJob {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doJob() {
|
||||
public void doJob() {
|
||||
PowersManager.finishRecycleTime(this.msg, this.pc, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ public class FinishSpireEffectJob extends AbstractEffectJob {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doJob() {
|
||||
public void doJob() {
|
||||
|
||||
PlayerCharacter pc = (PlayerCharacter) target;
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ public class FinishSummonsJob extends AbstractScheduleJob {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doJob() {
|
||||
public void doJob() {
|
||||
|
||||
if (this.target == null)
|
||||
return;
|
||||
|
||||
@@ -28,7 +28,7 @@ public class LoadEffectsJob extends AbstractJob {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doJob() {
|
||||
public void doJob() {
|
||||
if (this.originToSend == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ public class LogoutCharacterJob extends AbstractScheduleJob {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doJob() {
|
||||
public void doJob() {
|
||||
server.logoutCharacter(this.pc);
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ public class NoTimeJob extends AbstractEffectJob {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doJob() {
|
||||
public void doJob() {
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -40,7 +40,7 @@ public class PersistentAoeJob extends AbstractEffectJob {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doJob() {
|
||||
public void doJob() {
|
||||
|
||||
if (this.aej == null || this.source == null || this.action == null || this.power == null || this.source == null || this.eb == null)
|
||||
return;
|
||||
|
||||
@@ -45,7 +45,7 @@ public class RefreshGroupJob extends AbstractJob {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doJob() {
|
||||
public void doJob() {
|
||||
|
||||
if (this.pc == null || this.origin == null || grp == null) {
|
||||
return;
|
||||
|
||||
@@ -22,7 +22,7 @@ public class RemoveCorpseJob extends AbstractScheduleJob {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doJob() {
|
||||
public void doJob() {
|
||||
|
||||
if (this.corpse != null)
|
||||
Corpse.removeCorpse(corpse, true);
|
||||
|
||||
@@ -25,7 +25,7 @@ public class SiegeSpireWithdrawlJob extends AbstractScheduleJob {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doJob() {
|
||||
public void doJob() {
|
||||
|
||||
if (spire == null)
|
||||
return;
|
||||
|
||||
@@ -30,7 +30,7 @@ public class StuckJob extends AbstractScheduleJob {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doJob() {
|
||||
public void doJob() {
|
||||
|
||||
Vector3fImmutable stuckLoc;
|
||||
Building building = null;
|
||||
|
||||
@@ -27,7 +27,7 @@ public class SummonSendJob extends AbstractScheduleJob {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doJob() {
|
||||
public void doJob() {
|
||||
|
||||
if (this.source == null)
|
||||
return;
|
||||
|
||||
@@ -39,7 +39,7 @@ public class TeleportJob extends AbstractScheduleJob {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doJob() {
|
||||
public void doJob() {
|
||||
|
||||
if (this.pc == null || this.npc == null || this.origin == null)
|
||||
return;
|
||||
|
||||
@@ -35,7 +35,7 @@ public class TrackJob extends AbstractEffectJob {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doJob() {
|
||||
public void doJob() {
|
||||
|
||||
if (this.tpa == null || this.target == null || this.action == null || this.source == null || this.eb == null || !(this.source instanceof PlayerCharacter))
|
||||
return;
|
||||
|
||||
@@ -29,7 +29,7 @@ public class TransferStatOTJob extends AbstractEffectJob {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doJob() {
|
||||
public void doJob() {
|
||||
if (this.dot == null || this.target == null || this.action == null || this.source == null || this.eb == null || this.action == null || this.power == null)
|
||||
return;
|
||||
if (!this.target.isAlive()) {
|
||||
|
||||
@@ -26,7 +26,7 @@ public class UpdateGroupJob extends AbstractScheduleJob {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doJob() {
|
||||
public void doJob() {
|
||||
|
||||
if (this.group == null)
|
||||
return;
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package engine.jobs;
|
||||
|
||||
import engine.gameManager.ZoneManager;
|
||||
import engine.job.AbstractScheduleJob;
|
||||
import engine.objects.Building;
|
||||
import engine.objects.City;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
/*
|
||||
@@ -20,7 +22,7 @@ public class UpgradeBuildingJob extends AbstractScheduleJob {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doJob() {
|
||||
public void doJob() {
|
||||
|
||||
|
||||
// Must have a building to rank!
|
||||
@@ -41,6 +43,18 @@ public class UpgradeBuildingJob extends AbstractScheduleJob {
|
||||
|
||||
rankingBuilding.setRank(rankingBuilding.getRank() + 1);
|
||||
|
||||
if(rankingBuilding.getBlueprint().isWallPiece()){
|
||||
City cityObject = ZoneManager.getCityAtLocation(rankingBuilding.loc);
|
||||
if(cityObject.getTOL().getRank() == 8) {
|
||||
if (rankingBuilding.getBlueprint() != null && rankingBuilding.getBlueprint().getBuildingGroup() != null && rankingBuilding.getBlueprint().isWallPiece()) {
|
||||
float currentHealthRatio = rankingBuilding.getCurrentHitpoints() / rankingBuilding.healthMax;
|
||||
float newMax = rankingBuilding.healthMax * 1.1f;
|
||||
rankingBuilding.setMaxHitPoints(newMax);
|
||||
rankingBuilding.setHealth(rankingBuilding.healthMax * currentHealthRatio);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Reload the object
|
||||
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ public class UpgradeNPCJob extends AbstractScheduleJob {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doJob() {
|
||||
public void doJob() {
|
||||
|
||||
int newRank;
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ public class UseItemJob extends AbstractScheduleJob {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doJob() {
|
||||
public void doJob() {
|
||||
PowersManager.finishApplyPower(ac, target, Vector3fImmutable.ZERO, pb, trains, liveCounter);
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ public class UseMobPowerJob extends AbstractScheduleJob {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doJob() {
|
||||
public void doJob() {
|
||||
PowersManager.finishUseMobPower(this.msg, this.caster, casterLiveCounter, targetLiveCounter);
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ public class UsePowerJob extends AbstractScheduleJob {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doJob() {
|
||||
public void doJob() {
|
||||
PowersManager.finishUsePower(this.msg, this.pc, casterLiveCounter, targetLiveCounter);
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
package engine.mobileAI;
|
||||
|
||||
import engine.Enum;
|
||||
import engine.Enum.DispatchChannel;
|
||||
import engine.InterestManagement.InterestManager;
|
||||
import engine.InterestManagement.WorldGrid;
|
||||
import engine.gameManager.*;
|
||||
import engine.math.Vector3f;
|
||||
@@ -19,7 +19,7 @@ import engine.mobileAI.utilities.CombatUtilities;
|
||||
import engine.mobileAI.utilities.MovementUtilities;
|
||||
import engine.net.DispatchMessage;
|
||||
import engine.net.client.msg.PerformActionMsg;
|
||||
import engine.net.client.msg.PowerProjectileMsg;
|
||||
import engine.net.client.msg.UpdateStateMsg;
|
||||
import engine.objects.*;
|
||||
import engine.powers.ActionsBase;
|
||||
import engine.powers.PowersBase;
|
||||
@@ -49,18 +49,19 @@ public class MobAI {
|
||||
return;
|
||||
}
|
||||
|
||||
if (target.getObjectType() == Enum.GameObjectType.PlayerCharacter && canCast(mob)) {
|
||||
//mob casting disabled
|
||||
//if (target.getObjectType() == Enum.GameObjectType.PlayerCharacter && canCast(mob)) {
|
||||
|
||||
if (mob.isPlayerGuard() == false && MobCast(mob)) {
|
||||
mob.updateLocation();
|
||||
return;
|
||||
}
|
||||
//if (mob.isPlayerGuard() == false && MobCast(mob)) {
|
||||
// mob.updateLocation();
|
||||
// return;
|
||||
//}
|
||||
|
||||
if (mob.isPlayerGuard() == true && GuardCast(mob)) {
|
||||
mob.updateLocation();
|
||||
return;
|
||||
}
|
||||
}
|
||||
//if (mob.isPlayerGuard() == true && GuardCast(mob)) {
|
||||
// mob.updateLocation();
|
||||
// return;
|
||||
//}
|
||||
//}
|
||||
|
||||
if (!CombatUtilities.inRangeToAttack(mob, target))
|
||||
return;
|
||||
@@ -106,10 +107,16 @@ public class MobAI {
|
||||
return;
|
||||
}
|
||||
|
||||
if(target.getPet() != null && target.getPet().isAlive() && !target.getPet().isSiege()){
|
||||
mob.setCombatTarget(target.getPet());
|
||||
AttackTarget(mob,mob.combatTarget);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mob.BehaviourType.callsForHelp)
|
||||
MobCallForHelp(mob);
|
||||
|
||||
if (!MovementUtilities.inRangeDropAggro(mob, target)) {
|
||||
if (MovementUtilities.outOfAggroRange(mob, target)) {
|
||||
mob.setCombatTarget(null);
|
||||
return;
|
||||
}
|
||||
@@ -156,6 +163,12 @@ public class MobAI {
|
||||
if (target.getPet().getCombatTarget() == null && target.getPet().assist == true)
|
||||
target.getPet().setCombatTarget(mob);
|
||||
|
||||
try{
|
||||
InterestManager.forceLoad(mob);
|
||||
}catch(Exception e){
|
||||
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: AttackPlayer" + " " + e.getMessage());
|
||||
}
|
||||
@@ -171,14 +184,14 @@ public class MobAI {
|
||||
|
||||
if (target.getRank() == -1 || !target.isVulnerable() || BuildingManager.getBuildingFromCache(target.getObjectUUID()) == null) {
|
||||
mob.setCombatTarget(null);
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
City playercity = ZoneManager.getCityAtLocation(mob.getLoc());
|
||||
|
||||
if (playercity != null)
|
||||
for (Mob guard : playercity.getParent().zoneMobSet)
|
||||
if (guard.BehaviourType != null && guard.BehaviourType.ordinal() == Enum.MobBehaviourType.GuardCaptain.ordinal())
|
||||
if (guard.BehaviourType != null && guard.BehaviourType.equals(Enum.MobBehaviourType.GuardCaptain))
|
||||
if (guard.getCombatTarget() == null && guard.getGuild() != null && mob.getGuild() != null && !guard.getGuild().equals(mob.getGuild()))
|
||||
guard.setCombatTarget(mob);
|
||||
|
||||
@@ -321,28 +334,32 @@ public class MobAI {
|
||||
if (mob == null)
|
||||
return false;
|
||||
|
||||
if(mob.isPlayerGuard == true){
|
||||
if (mob.nextCastTime == 0)
|
||||
mob.nextCastTime = System.currentTimeMillis() - 1000L;
|
||||
|
||||
int contractID;
|
||||
if(mob.nextCastTime > System.currentTimeMillis())
|
||||
return false;
|
||||
|
||||
if(mob.BehaviourType.equals(Enum.MobBehaviourType.GuardMinion))
|
||||
if(mob.isPlayerGuard){
|
||||
|
||||
int contractID = 0;
|
||||
|
||||
if(mob.BehaviourType.equals(Enum.MobBehaviourType.GuardMinion) && mob.npcOwner != null)
|
||||
contractID = mob.npcOwner.contract.getContractID();
|
||||
else
|
||||
else if(mob.contract != null)
|
||||
contractID = mob.contract.getContractID();
|
||||
|
||||
if(Enum.MinionType.ContractToMinionMap.get(contractID).isMage() == false)
|
||||
if(Enum.MinionType.ContractToMinionMap.containsKey(contractID) && !Enum.MinionType.ContractToMinionMap.get(contractID).isMage())
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mob.mobPowers.isEmpty())
|
||||
if (mob.mobPowers == null || mob.mobPowers.isEmpty())
|
||||
return false;
|
||||
|
||||
if (!mob.canSee((PlayerCharacter) mob.getCombatTarget())) {
|
||||
mob.setCombatTarget(null);
|
||||
return false;
|
||||
}
|
||||
if (mob.nextCastTime == 0)
|
||||
mob.nextCastTime = System.currentTimeMillis();
|
||||
|
||||
return mob.nextCastTime <= System.currentTimeMillis();
|
||||
|
||||
@@ -401,6 +418,9 @@ public class MobAI {
|
||||
|
||||
PowersBase mobPower = PowersManager.getPowerByToken(powerToken);
|
||||
|
||||
if(mobPower.powerCategory.equals(Enum.PowerCategoryType.DEBUFF))
|
||||
return false;
|
||||
|
||||
//check for hit-roll
|
||||
|
||||
if (mobPower.requiresHitRoll)
|
||||
@@ -424,9 +444,9 @@ 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 delay = 20000L;
|
||||
mob.nextCastTime = System.currentTimeMillis() + delay;
|
||||
|
||||
mob.nextCastTime = System.currentTimeMillis() + randomCooldown;
|
||||
return true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
@@ -549,7 +569,6 @@ public class MobAI {
|
||||
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) {
|
||||
@@ -884,6 +903,7 @@ public class MobAI {
|
||||
return;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if(Mob.discDroppers.contains(aiAgent))
|
||||
@@ -892,7 +912,7 @@ public class MobAI {
|
||||
if(aiAgent.StrongholdGuardian || aiAgent.StrongholdEpic || aiAgent.StrongholdCommander)
|
||||
return;
|
||||
|
||||
if (System.currentTimeMillis() > (aiAgent.deathTime + (aiAgent.spawnTime * 1000L))) {
|
||||
if (aiAgent.despawned && System.currentTimeMillis() > (aiAgent.deathTime + (aiAgent.spawnTime * 1000L))) {
|
||||
if (!Zone.respawnQue.contains(aiAgent)) {
|
||||
Zone.respawnQue.add(aiAgent);
|
||||
}
|
||||
@@ -913,8 +933,10 @@ public class MobAI {
|
||||
if (mob.getCombatTarget() == null)
|
||||
return;
|
||||
|
||||
if (mob.getCombatTarget().getObjectType().equals(Enum.GameObjectType.PlayerCharacter) && MovementUtilities.inRangeDropAggro(mob, (PlayerCharacter) mob.getCombatTarget()) == false && mob.BehaviourType.ordinal() != Enum.MobBehaviourType.Pet1.ordinal()) {
|
||||
if(!mob.isCombat())
|
||||
enterCombat(mob);
|
||||
|
||||
if (mob.getCombatTarget().getObjectType().equals(Enum.GameObjectType.PlayerCharacter) && MovementUtilities.outOfAggroRange(mob, (PlayerCharacter) mob.getCombatTarget()) && mob.BehaviourType.ordinal() != Enum.MobBehaviourType.Pet1.ordinal()) {
|
||||
mob.setCombatTarget(null);
|
||||
return;
|
||||
}
|
||||
@@ -962,7 +984,6 @@ public class MobAI {
|
||||
PowersBase recall = PowersManager.getPowerByToken(-1994153779);
|
||||
PowersManager.useMobPower(mob, mob, recall, 40);
|
||||
mob.setCombatTarget(null);
|
||||
|
||||
if (mob.BehaviourType.ordinal() == Enum.MobBehaviourType.GuardCaptain.ordinal() && mob.isAlive()) {
|
||||
|
||||
//guard captain pulls his minions home with him
|
||||
@@ -992,6 +1013,11 @@ public class MobAI {
|
||||
|
||||
try {
|
||||
|
||||
if(mob.combatTarget != null && mob.combatTarget.getObjectType().equals(Enum.GameObjectType.PlayerCharacter) && !mob.canSee((PlayerCharacter)mob.combatTarget)){
|
||||
mob.setCombatTarget(null);
|
||||
return;
|
||||
}
|
||||
|
||||
float rangeSquared = mob.getRange() * mob.getRange();
|
||||
float distanceSquared = mob.getLoc().distanceSquared2D(mob.getCombatTarget().getLoc());
|
||||
|
||||
@@ -1066,8 +1092,8 @@ public class MobAI {
|
||||
if(mob.combatTarget == null)
|
||||
return;
|
||||
|
||||
if(city._playerMemory.contains(mob.combatTarget.getObjectUUID()) && mob.combatTarget.getObjectType().equals(Enum.GameObjectType.PlayerCharacter))
|
||||
mob.setCombatTarget(null);
|
||||
//if(city._playerMemory.contains(mob.combatTarget.getObjectUUID()) && mob.combatTarget.getObjectType().equals(Enum.GameObjectType.PlayerCharacter))
|
||||
// mob.setCombatTarget(null);
|
||||
}
|
||||
|
||||
public static void GuardCaptainLogic(Mob mob) {
|
||||
@@ -1139,6 +1165,10 @@ public class MobAI {
|
||||
if (ZoneManager.getSeaFloor().zoneMobSet.contains(mob))
|
||||
mob.killCharacter("no owner");
|
||||
|
||||
if(!mob.isSiege())
|
||||
mob.BehaviourType.canRoam = true;
|
||||
|
||||
|
||||
if (MovementUtilities.canMove(mob) && mob.BehaviourType.canRoam)
|
||||
CheckMobMovement(mob);
|
||||
|
||||
@@ -1199,6 +1229,7 @@ public class MobAI {
|
||||
if (!mob.BehaviourType.isWimpy && mob.getCombatTarget() != null)
|
||||
CheckForAttack(mob);
|
||||
|
||||
|
||||
} catch (Exception e) {
|
||||
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: DefaultLogic" + " " + e.getMessage());
|
||||
}
|
||||
@@ -1417,4 +1448,11 @@ public class MobAI {
|
||||
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: RecoverHealth" + " " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public static void enterCombat(Mob mob){
|
||||
mob.setCombat(true);
|
||||
UpdateStateMsg rwss = new UpdateStateMsg();
|
||||
rwss.setPlayer(mob);
|
||||
DispatchMessage.sendToAllInRange(mob, rwss);
|
||||
}
|
||||
}
|
||||
@@ -28,18 +28,26 @@ public class MobAIThread implements Runnable{
|
||||
AI_BASE_AGGRO_RANGE = (int)(60 * Float.parseFloat(ConfigManager.MB_AI_AGGRO_RANGE.getValue()));
|
||||
while (true) {
|
||||
for (Zone zone : ZoneManager.getAllZones()) {
|
||||
|
||||
for (Mob mob : zone.zoneMobSet) {
|
||||
|
||||
try {
|
||||
if (mob != null)
|
||||
MobAI.DetermineAction(mob);
|
||||
} catch (Exception e) {
|
||||
Logger.error("Mob: " + mob.getName() + " UUID: " + mob.getObjectUUID() + " ERROR: " + e);
|
||||
e.printStackTrace();
|
||||
if (zone != null && zone.zoneMobSet != null) {
|
||||
synchronized (zone.zoneMobSet) {
|
||||
for (Mob mob : zone.zoneMobSet) {
|
||||
try {
|
||||
if (mob != null) {
|
||||
MobAI.DetermineAction(mob);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Logger.error("Error processing Mob [Name: {}, UUID: {}]", mob.getName(), mob.getObjectUUID(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
} catch (InterruptedException e) {
|
||||
Logger.error("AI Thread interrupted", e);
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
}
|
||||
public static void startAIThread() {
|
||||
|
||||
@@ -13,6 +13,9 @@ import engine.objects.Mob;
|
||||
import engine.objects.Zone;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Thread blocks until MagicBane dispatch messages are
|
||||
* enqueued then processes them in FIFO order. The collection
|
||||
@@ -25,41 +28,48 @@ import org.pmw.tinylog.Logger;
|
||||
|
||||
public class MobRespawnThread implements Runnable {
|
||||
|
||||
private volatile boolean running = true;
|
||||
private static final long RESPAWN_INTERVAL = 100; // Configurable interval
|
||||
|
||||
public MobRespawnThread() {
|
||||
Logger.info(" MobRespawnThread thread has started!");
|
||||
|
||||
Logger.info("MobRespawnThread initialized.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
while (true) {
|
||||
|
||||
while (running) {
|
||||
try {
|
||||
for (Zone zone : ZoneManager.getAllZones()) {
|
||||
Collection<Zone> zones = ZoneManager.getAllZones();
|
||||
if (zones != null) {
|
||||
for (Zone zone : zones) {
|
||||
synchronized (zone) { // Optional: Synchronize on zone
|
||||
if (!Zone.respawnQue.isEmpty() && Zone.lastRespawn + RESPAWN_INTERVAL < System.currentTimeMillis()) {
|
||||
|
||||
if (zone.respawnQue.isEmpty() == false && zone.lastRespawn + 100 < System.currentTimeMillis()) {
|
||||
|
||||
Mob respawner = zone.respawnQue.iterator().next();
|
||||
|
||||
if (respawner == null)
|
||||
continue;
|
||||
|
||||
respawner.respawn();
|
||||
zone.respawnQue.remove(respawner);
|
||||
zone.lastRespawn = System.currentTimeMillis();
|
||||
Mob respawner = Zone.respawnQue.iterator().next();
|
||||
if (respawner != null) {
|
||||
respawner.respawn();
|
||||
Zone.respawnQue.remove(respawner);
|
||||
Zone.lastRespawn = System.currentTimeMillis();
|
||||
Thread.sleep(100);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Thread.sleep(100); // Prevent busy-waiting
|
||||
} catch (Exception e) {
|
||||
Logger.error(e);
|
||||
Logger.error("Error in MobRespawnThread", e);
|
||||
}
|
||||
|
||||
}
|
||||
Logger.info("MobRespawnThread stopped.");
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
running = false;
|
||||
}
|
||||
|
||||
public static void startRespawnThread() {
|
||||
Thread respawnThread;
|
||||
respawnThread = new Thread(new MobRespawnThread());
|
||||
Thread respawnThread = new Thread(new MobRespawnThread());
|
||||
respawnThread.setName("respawnThread");
|
||||
respawnThread.start();
|
||||
}
|
||||
|
||||
@@ -101,9 +101,10 @@ public class CombatUtilities {
|
||||
if (!target.isAlive())
|
||||
return;
|
||||
|
||||
if (AbstractWorldObject.IsAbstractCharacter(target))
|
||||
if (AbstractWorldObject.IsAbstractCharacter(target)) {
|
||||
//damage = Resists.handleFortitude((AbstractCharacter) target,DamageType.Crush,damage);
|
||||
trueDamage = ((AbstractCharacter) target).modifyHealth(-damage, agent, false);
|
||||
else if (target.getObjectType() == GameObjectType.Building)
|
||||
}else if (target.getObjectType() == GameObjectType.Building)
|
||||
trueDamage = ((Building) target).modifyHealth(-damage, agent);
|
||||
|
||||
//Don't send 0 damage kay thanx.
|
||||
@@ -140,21 +141,29 @@ public class CombatUtilities {
|
||||
|
||||
public static boolean triggerDefense(Mob agent, AbstractWorldObject target) {
|
||||
int defense = 0;
|
||||
int atr = agent.getAtrHandOne();
|
||||
int atr = agent.mobBase.getAtr();
|
||||
if(agent.getBonuses() != null){
|
||||
atr += agent.getBonuses().getFloat(ModType.OCV,SourceType.None);
|
||||
atr *= 1 + agent.getBonuses().getFloatPercentAll(ModType.OCV,SourceType.None);
|
||||
}
|
||||
switch (target.getObjectType()) {
|
||||
case PlayerCharacter:
|
||||
defense = ((AbstractCharacter) target).getDefenseRating();
|
||||
PlayerCharacter pc = (PlayerCharacter)target;
|
||||
pc.combatStats.calculateDefense();
|
||||
defense = pc.combatStats.defense;
|
||||
break;
|
||||
case Mob:
|
||||
|
||||
Mob mob = (Mob) target;
|
||||
if (mob.isSiege())
|
||||
defense = atr;
|
||||
else
|
||||
defense = ((Mob) target).mobBase.getDefense();
|
||||
break;
|
||||
case Building:
|
||||
return false;
|
||||
}
|
||||
return CombatManager.LandHit(atr,defense);
|
||||
return !CombatManager.LandHit(atr,defense);
|
||||
}
|
||||
|
||||
public static boolean triggerBlock(Mob agent, AbstractWorldObject ac) {
|
||||
@@ -192,12 +201,10 @@ public class CombatUtilities {
|
||||
return;
|
||||
|
||||
int anim = 75;
|
||||
float speed;
|
||||
|
||||
if (mainHand)
|
||||
speed = agent.getSpeedHandOne();
|
||||
else
|
||||
speed = agent.getSpeedHandTwo();
|
||||
//handle the retaliate here because even if the mob misses you can still retaliate
|
||||
if (AbstractWorldObject.IsAbstractCharacter(target))
|
||||
CombatManager.handleRetaliate((AbstractCharacter) target, agent);
|
||||
|
||||
DamageType dt = DamageType.Crush;
|
||||
|
||||
@@ -252,12 +259,12 @@ public class CombatUtilities {
|
||||
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;
|
||||
double range1 = getMaxDmg(agent) - getMinDmg(agent);
|
||||
double damage1 = getMinDmg(agent) + ((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;
|
||||
double range2 = getMaxDmg(agent) - getMinDmg(agent);
|
||||
double damage2 = getMinDmg(agent) + ((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);
|
||||
@@ -279,11 +286,6 @@ public class CombatUtilities {
|
||||
if (((Mob) target).isSiege())
|
||||
return;
|
||||
|
||||
//handle the retaliate
|
||||
|
||||
if (AbstractWorldObject.IsAbstractCharacter(target))
|
||||
CombatManager.handleRetaliate((AbstractCharacter) target, agent);
|
||||
|
||||
if (target.getObjectType() == GameObjectType.Mob) {
|
||||
Mob targetMob = (Mob) target;
|
||||
if (targetMob.isSiege())
|
||||
@@ -307,9 +309,9 @@ public class CombatUtilities {
|
||||
float damage = 0;
|
||||
|
||||
DamageType dt = getDamageType(agent);
|
||||
if ((agent.agentType.equals(AIAgentType.PET)) == true || agent.isPet() == true || agent.isNecroPet() == true) {
|
||||
damage = calculatePetDamage(agent);
|
||||
} else if (agent.isPlayerGuard() == true) {
|
||||
if (agent.BehaviourType.equals(MobBehaviourType.Pet1)) {
|
||||
damage = calculateMobDamage(agent);
|
||||
} else if (agent.isPlayerGuard()) {
|
||||
//damage = calculateGuardDamage(agent);
|
||||
damage = calculateMobDamage(agent);
|
||||
} else if (agent.getLevel() > 80) {
|
||||
@@ -318,9 +320,9 @@ public class CombatUtilities {
|
||||
damage = calculateMobDamage(agent);
|
||||
}
|
||||
if (AbstractWorldObject.IsAbstractCharacter(target)) {
|
||||
if (((AbstractCharacter) target).isSit()) {
|
||||
damage *= 2.5f; //increase damage if sitting
|
||||
}
|
||||
//if (((AbstractCharacter) target).isSit()) {
|
||||
// damage *= 2.5f; //increase damage if sitting
|
||||
//}
|
||||
return (int) (((AbstractCharacter) target).getResists().getResistedDamage(agent, (AbstractCharacter) target, dt, damage, 0));
|
||||
}
|
||||
if (target.getObjectType() == GameObjectType.Building) {
|
||||
@@ -349,8 +351,8 @@ public class CombatUtilities {
|
||||
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);
|
||||
double minDmg = getMinDmg(agent);
|
||||
double maxDmg = getMaxDmg(agent);
|
||||
dmgMultiplier += agent.getLevel() * 0.1f;
|
||||
range = (float) (maxDmg - minDmg);
|
||||
damage = min + ((ThreadLocalRandom.current().nextFloat() * range) + (ThreadLocalRandom.current().nextFloat() * range)) / 2;
|
||||
@@ -366,8 +368,8 @@ public class CombatUtilities {
|
||||
|
||||
double minDmg = weapon.getMinDamage();
|
||||
double maxDmg = weapon.getMaxDamage();
|
||||
double min = getMinDmg(minDmg, agent, weapon);
|
||||
double max = getMaxDmg(maxDmg, agent, weapon);
|
||||
double min = getMinDmg(agent);
|
||||
double max = getMaxDmg(agent);
|
||||
|
||||
DamageType dt = weapon.getDamageType();
|
||||
|
||||
@@ -408,92 +410,48 @@ public class CombatUtilities {
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
double minDmg = getMinDmg(agent);
|
||||
double maxDmg = getMaxDmg(agent);
|
||||
DamageType dt = getDamageType(agent);
|
||||
|
||||
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;
|
||||
double damage = ThreadLocalRandom.current().nextInt((int)minDmg,(int)maxDmg + 1);
|
||||
|
||||
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 (int) (((AbstractCharacter) target).getResists().getResistedDamage(agent, (AbstractCharacter) target, dt, (float) damage, 0));
|
||||
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();
|
||||
public static double getMinDmg(Mob agent) {
|
||||
if(agent.getEquip() != null){
|
||||
if(agent.getEquip().get(ItemSlotType.RHELD) != null){
|
||||
return agent.minDamageHandOne;
|
||||
}else if(agent.getEquip().get(ItemSlotType.LHELD) != null){
|
||||
return agent.getMinDamageHandTwo();
|
||||
}else{
|
||||
return agent.minDamageHandOne;
|
||||
}
|
||||
}else{
|
||||
return agent.minDamageHandOne;
|
||||
}
|
||||
}
|
||||
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();
|
||||
public static double getMaxDmg(Mob agent) {
|
||||
if(agent.getEquip() != null){
|
||||
if(agent.getEquip().get(ItemSlotType.RHELD) != null){
|
||||
return agent.maxDamageHandOne;
|
||||
}else if(agent.getEquip().get(ItemSlotType.LHELD) != null){
|
||||
return agent.getMaxDamageHandTwo();
|
||||
}else{
|
||||
return agent.maxDamageHandOne;
|
||||
}
|
||||
}else{
|
||||
return agent.maxDamageHandOne;
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -98,20 +98,24 @@ public class MovementUtilities {
|
||||
|
||||
}
|
||||
|
||||
public static boolean inRangeDropAggro(Mob agent, AbstractCharacter target) {
|
||||
public static boolean outOfAggroRange(Mob agent, AbstractCharacter target) {
|
||||
|
||||
Vector3fImmutable sl = agent.getLoc();
|
||||
Vector3fImmutable tl = target.getLoc();
|
||||
|
||||
float distanceSquaredToTarget = sl.distanceSquared2D(tl) - sqr(agent.calcHitBox() + target.calcHitBox()); //distance to center of target
|
||||
|
||||
float disSq = sl.distanceSquared(tl);
|
||||
float range = agent.getRange() + 150;
|
||||
|
||||
|
||||
//float distanceSquaredToTarget = sl.distanceSquared2D(tl) - sqr(agent.calcHitBox() + target.calcHitBox()); //distance to center of target
|
||||
|
||||
|
||||
|
||||
if (range > 200)
|
||||
range = 200;
|
||||
|
||||
|
||||
return distanceSquaredToTarget < sqr(range);
|
||||
return disSq > (range * range);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ public abstract class AbstractConnection implements
|
||||
protected final AtomicBoolean execTask = new AtomicBoolean(false);
|
||||
protected final ReentrantLock writeLock = new ReentrantLock();
|
||||
protected final ReentrantLock readLock = new ReentrantLock();
|
||||
protected long lastMsgTime = System.currentTimeMillis();
|
||||
public long lastMsgTime = System.currentTimeMillis();
|
||||
protected long lastKeepAliveTime = System.currentTimeMillis();
|
||||
protected long lastOpcode = -1;
|
||||
protected ConcurrentLinkedQueue<ByteBuffer> outbox = new ConcurrentLinkedQueue<>();
|
||||
|
||||
@@ -87,6 +87,7 @@ public abstract class AbstractConnectionManager extends ControlledRunnable {
|
||||
|
||||
this.processChangeRequests();
|
||||
this.auditSocketChannelToConnectionMap();
|
||||
//this.selector.select();
|
||||
this.selector.select(250L);
|
||||
this.processNewEvents();
|
||||
|
||||
@@ -664,7 +665,7 @@ public abstract class AbstractConnectionManager extends ControlledRunnable {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doJob() {
|
||||
public void doJob() {
|
||||
if (runStatus) {
|
||||
this.ac.connMan.receive(sk);
|
||||
this.ac.execTask.compareAndSet(true, false);
|
||||
@@ -693,7 +694,7 @@ public abstract class AbstractConnectionManager extends ControlledRunnable {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doJob() {
|
||||
public void doJob() {
|
||||
if (runStatus) {
|
||||
this.ac.connMan.sendFinish(sk);
|
||||
this.ac.execTask.compareAndSet(true, false);
|
||||
|
||||
@@ -23,7 +23,7 @@ public class CheckNetMsgFactoryJob extends AbstractJob {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doJob() {
|
||||
public void doJob() {
|
||||
NetMsgFactory factory = conn.getFactory();
|
||||
|
||||
// Make any/all msg possible
|
||||
|
||||
@@ -26,7 +26,7 @@ public class ConnectionMonitorJob extends AbstractJob {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doJob() {
|
||||
public void doJob() {
|
||||
|
||||
if (this.cnt >= 5) {
|
||||
this.connMan.auditSocketChannelToConnectionMap();
|
||||
|
||||
@@ -44,9 +44,16 @@ public class ClientConnection extends AbstractConnection {
|
||||
public ReentrantLock buyLock = new ReentrantLock();
|
||||
public boolean desyncDebug = false;
|
||||
public byte[] lastByteBuffer;
|
||||
public long lastTargetSwitchTime;
|
||||
protected SessionID sessionID = null;
|
||||
private byte cryptoInitTries = 0;
|
||||
|
||||
public int strikes = 0;
|
||||
public Long lastStrike = 0L;
|
||||
|
||||
public int finalStrikes = 0;
|
||||
public long finalStrikeRefresh = 0L;
|
||||
|
||||
public ClientConnection(ClientConnectionManager connMan,
|
||||
SocketChannel sockChan) {
|
||||
super(connMan, sockChan, true);
|
||||
@@ -227,10 +234,10 @@ public class ClientConnection extends AbstractConnection {
|
||||
SessionManager.remSession(
|
||||
SessionManager.getSession(sessionID));
|
||||
} catch (NullPointerException e) {
|
||||
Logger
|
||||
.error(
|
||||
"Tried to remove improperly initialized session. Skipping." +
|
||||
e);
|
||||
//Logger
|
||||
//.error(
|
||||
//"Tried to remove improperly initialized session. Skipping." +
|
||||
//e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ import engine.objects.*;
|
||||
import engine.server.MBServerStatics;
|
||||
import engine.server.world.WorldServer;
|
||||
import engine.session.Session;
|
||||
import engine.util.KeyCloneAudit;
|
||||
import engine.util.StringUtils;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
@@ -238,6 +239,11 @@ public class ClientMessagePump implements NetMsgHandler {
|
||||
return;
|
||||
}
|
||||
|
||||
if(pc.getRaceID() == 1999 && msg.getSlotNumber() == MBServerStatics.SLOT_FEET){
|
||||
forceTransferFromEquipToInventory(msg, origin, "Saetors Cannot Wear FEET Slot Items");
|
||||
return;
|
||||
}
|
||||
|
||||
//dupe check
|
||||
if (!i.validForInventory(origin, pc, itemManager))
|
||||
return;
|
||||
@@ -1681,15 +1687,12 @@ public class ClientMessagePump implements NetMsgHandler {
|
||||
return;
|
||||
}
|
||||
|
||||
int cost = ((int)((toRepair.getMagicValue()/max*(max - dur)) + (npc.getSpecialPrice() * npc.buyPercent))) + (int)(npc.getSpecialPrice() * (max - dur));
|
||||
|
||||
//int pointsToRepair = max - dur;
|
||||
//int magicValue = toRepair.getMagicValue();
|
||||
//if(magicValue == 0)
|
||||
// magicValue = 1;
|
||||
//int calculatedValue = toRepair.getDurabilityMax() * magicValue;
|
||||
//float costPerPoint = (magicValue / max) * ( 1 + npc.buyPercent);
|
||||
//cost = (int)(pointsToRepair * costPerPoint) + npc.getSpecialPrice();
|
||||
int pointsToRepair = max - dur;
|
||||
double damageRatio = (double)1.0d - (toRepair.getDurabilityMax() - toRepair.getDurabilityCurrent()) / toRepair.getDurabilityMax();
|
||||
int modifiedValue = (int)(damageRatio * toRepair.getMagicValue());
|
||||
int costPerPoint = modifiedValue / toRepair.getDurabilityMax();
|
||||
int modifiedRepairCost = (int)(pointsToRepair * costPerPoint)+ npc.getSpecialPrice();
|
||||
int cost = (int)(modifiedRepairCost * 1 + npc.buyPercent) + npc.getSpecialPrice();
|
||||
Building b = (!npc.isStatic()) ? npc.getBuilding() : null;
|
||||
|
||||
if (b != null)
|
||||
@@ -1883,6 +1886,7 @@ public class ClientMessagePump implements NetMsgHandler {
|
||||
|
||||
switch (protocolMsg) {
|
||||
case SETSELECTEDOBECT:
|
||||
KeyCloneAudit.auditTargetMsg(msg);
|
||||
ClientMessagePump.targetObject((TargetObjectMsg) msg, origin);
|
||||
break;
|
||||
|
||||
|
||||
@@ -78,7 +78,7 @@ public class ActivateNPCMsgHandler extends AbstractClientMsgHandler {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (building.getBlueprint().getMaxSlots() == building.getHirelings().size())
|
||||
if (building.getBlueprint().getMaxSlots() == building.getHirelings().size() && building.getRank() != 8)
|
||||
return false;
|
||||
|
||||
Item contractItem = Item.getFromCache(msg.getContractItem());
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
package engine.net.client.handlers;
|
||||
|
||||
import engine.Enum;
|
||||
import engine.Enum.DispatchChannel;
|
||||
import engine.exception.MsgSendException;
|
||||
import engine.net.DispatchMessage;
|
||||
@@ -42,6 +43,9 @@ public class ChangeAltitudeHandler extends AbstractClientMsgHandler {
|
||||
if (!AbstractCharacter.CanFly(pc))
|
||||
return false;
|
||||
|
||||
if(pc.getBonuses().getBool(Enum.ModType.Stunned, Enum.SourceType.None))
|
||||
return false;
|
||||
|
||||
if (pc.isSwimming())
|
||||
return false;
|
||||
if (pc.region != null && !pc.region.isOutside())
|
||||
|
||||
@@ -232,11 +232,13 @@ public class ObjectActionMsgHandler extends AbstractClientMsgHandler {
|
||||
if (pc == null || origin == null) {
|
||||
return;
|
||||
}
|
||||
ItemBase runeBase = ItemBase.getItemBase(runeID);
|
||||
|
||||
//remove only if rune is discipline
|
||||
if (runeID < 3001 || runeID > 3048) {
|
||||
boolean discRune = runeBase.isDiscRune();
|
||||
boolean statRune = runeBase.isStatRune();
|
||||
if(!runeBase.isDiscRune() && !runeBase.isStatRune())
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//see if pc has rune
|
||||
ArrayList<CharacterRune> runes = pc.getRunes();
|
||||
|
||||
@@ -1148,6 +1148,15 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
|
||||
wallPiece.setProtectionState(ProtectionState.PROTECTED);
|
||||
PlaceAssetMsg.sendPlaceAssetConfirmWall(origin, serverZone);
|
||||
|
||||
//walls in R8 city are immediately granted extra HP by 10%
|
||||
if(cityObject.getTOL().getRank() == 8) {
|
||||
if (wallPiece.getBlueprint() != null && wallPiece.getBlueprint().getBuildingGroup() != null && wallPiece.getBlueprint().isWallPiece()) {
|
||||
float currentHealthRatio = wallPiece.getCurrentHitpoints() / wallPiece.healthMax;
|
||||
float newMax = wallPiece.healthMax * 1.1f;
|
||||
wallPiece.setMaxHitPoints(newMax);
|
||||
wallPiece.setHealth(wallPiece.healthMax * currentHealthRatio);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Deduct gold from character's inventory
|
||||
|
||||
@@ -146,6 +146,8 @@ public class ApplyRuneMsg extends ClientNetMsg {
|
||||
valid = true;
|
||||
if(runeID == 3035 && baseClassID == 2501)
|
||||
valid = true;
|
||||
if(runeID == 3028 && baseClassID == 2501 && playerCharacter.getRace().getName().contains("Irekei"))
|
||||
valid = true;
|
||||
if (!valid) {
|
||||
return false;
|
||||
}
|
||||
@@ -200,7 +202,7 @@ public class ApplyRuneMsg extends ClientNetMsg {
|
||||
for (CharacterRune cr : runes) {
|
||||
int runeBaseID = cr.getRuneBaseID();
|
||||
//count number of discipline runes
|
||||
if (runeBaseID > 3000 && runeBaseID < 3049) {
|
||||
if(isDiscipline(runeBaseID)){
|
||||
discCount++;
|
||||
}
|
||||
//see if rune is already applied
|
||||
@@ -329,23 +331,27 @@ public class ApplyRuneMsg extends ClientNetMsg {
|
||||
break;
|
||||
}
|
||||
//if discipline, check number applied
|
||||
int discAllowed = 0;
|
||||
if (isDiscipline(runeID)) {
|
||||
switch(playerCharacter.getRank()){
|
||||
case 1:
|
||||
discAllowed = 0;
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
if(discCount > 3)
|
||||
return false;
|
||||
discAllowed = 3;
|
||||
break;
|
||||
case 7:
|
||||
case 8:
|
||||
if(discCount > 5)
|
||||
return false;
|
||||
discAllowed = 5;
|
||||
break;
|
||||
}
|
||||
|
||||
if(discCount >= discAllowed)
|
||||
return false;
|
||||
}
|
||||
//Everything succeeded. Let's apply the rune
|
||||
//Attempt add rune to database
|
||||
|
||||
@@ -124,6 +124,9 @@ public class VendorDialogMsg extends ClientNetMsg {
|
||||
}else if(contract.getContractID() == 1502042){
|
||||
vd = Contract.HandleBaneCommanderOptions(msg.unknown03, npc, playerCharacter);
|
||||
msg.updateMessage(3, vd);
|
||||
}else if(contract.getContractID() == 1502044){
|
||||
vd = Contract.HandleGamblerOptions(msg.unknown03, npc, playerCharacter);
|
||||
msg.updateMessage(3, vd);
|
||||
}else {
|
||||
|
||||
if (contract == null)
|
||||
@@ -576,6 +579,7 @@ public class VendorDialogMsg extends ClientNetMsg {
|
||||
case 2520:
|
||||
case 2521:
|
||||
case 2523:
|
||||
case 2525:
|
||||
valid = true;
|
||||
break;
|
||||
}
|
||||
@@ -631,6 +635,11 @@ public class VendorDialogMsg extends ClientNetMsg {
|
||||
.getObjectUUID(), true);
|
||||
DispatchMessage.dispatchMsgToInterestArea(pc, arm, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false);
|
||||
|
||||
if(pc.getCharItemManager() != null && pc.getCharItemManager().getGoldInventory() != null && pc.getCharItemManager().getGoldInventory().getNumOfItems() < 1000) {
|
||||
pc.getCharItemManager().addGoldToInventory(1500, false);
|
||||
pc.getCharItemManager().addItemToInventory(new MobLoot(pc, ItemBase.getItemBase(980066), 1, false).promoteToItem(pc));
|
||||
pc.getCharItemManager().updateInventory();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -63,6 +63,9 @@ public class WhoResponseMsg extends ClientNetMsg {
|
||||
|
||||
public static void HandleResponse(int set, int filterType, String filter, ClientConnection origin) {
|
||||
|
||||
if (filter.equals("")) {
|
||||
filter = "Saetor";
|
||||
}
|
||||
WhoResponseMsg msg = new WhoResponseMsg();
|
||||
WhoResponseMsg.setWorldPop(SessionManager.getAllActivePlayerCharacters().size());
|
||||
|
||||
|
||||
@@ -14,10 +14,7 @@ import engine.Enum.*;
|
||||
import engine.InterestManagement.InterestManager;
|
||||
import engine.InterestManagement.WorldGrid;
|
||||
import engine.exception.SerializationException;
|
||||
import engine.gameManager.CombatManager;
|
||||
import engine.gameManager.ConfigManager;
|
||||
import engine.gameManager.MovementManager;
|
||||
import engine.gameManager.PowersManager;
|
||||
import engine.gameManager.*;
|
||||
import engine.job.AbstractJob;
|
||||
import engine.job.JobContainer;
|
||||
import engine.job.JobScheduler;
|
||||
@@ -503,7 +500,6 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
|
||||
canFly = false;
|
||||
}
|
||||
|
||||
|
||||
return canFly;
|
||||
|
||||
}
|
||||
@@ -764,7 +760,11 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
|
||||
public abstract Vector3fImmutable getBindLoc();
|
||||
|
||||
public final void setBindLoc(final Vector3fImmutable value) {
|
||||
this.bindLoc = value;
|
||||
if(this.getObjectType().equals(GameObjectType.PlayerCharacter) && this.guild.getNation().equals(Guild.getErrantGuild())){
|
||||
this.bindLoc = Vector3fImmutable.getRandomPointOnCircle(BuildingManager.getBuilding(27977).loc,20f);
|
||||
}else {
|
||||
this.bindLoc = value;
|
||||
}
|
||||
}
|
||||
|
||||
public final Vector3fImmutable getFaceDir() {
|
||||
@@ -1101,7 +1101,7 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
|
||||
}
|
||||
|
||||
public final void setCombatTarget(final AbstractWorldObject value) {
|
||||
if(this.getObjectTypeMask() == 2050) {//MOB?
|
||||
if (this.getObjectTypeMask() == 2050) {//MOB?
|
||||
if (value == null) {
|
||||
if (this.isCombat()) {
|
||||
this.setCombat(false);
|
||||
@@ -1109,13 +1109,6 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
|
||||
rwss.setPlayer(this);
|
||||
DispatchMessage.sendToAllInRange(this, rwss);
|
||||
}
|
||||
}else {
|
||||
if (!this.isCombat()) {
|
||||
this.setCombat(true);
|
||||
UpdateStateMsg rwss = new UpdateStateMsg();
|
||||
rwss.setPlayer(this);
|
||||
DispatchMessage.sendToAllInRange(this, rwss);
|
||||
}
|
||||
}
|
||||
}
|
||||
this.combatTarget = value;
|
||||
@@ -1558,7 +1551,15 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
|
||||
Effect eff = this.effects.get(s);
|
||||
if (eff == null)
|
||||
continue;
|
||||
if (eff.cancelOnMove() && eff.cancel()) {
|
||||
|
||||
Boolean override = false;
|
||||
if(this.getObjectType().equals(GameObjectType.PlayerCharacter)) {
|
||||
PlayerCharacter pc = (PlayerCharacter) this;
|
||||
if (eff.getEffectsBase().getIDString().equals("INVIS-B") && s.equals("Invisible") && pc.getRace().getName().contains("Shade"))
|
||||
override = true;
|
||||
}
|
||||
|
||||
if (!override && eff.cancelOnMove() && eff.cancel()) {
|
||||
//System.out.println("canceling on Move");
|
||||
eff.cancelJob();
|
||||
this.effects.remove(s);
|
||||
@@ -1717,7 +1718,11 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
|
||||
|
||||
// clear bonuses and reapply rune bonuses
|
||||
if (this.getObjectType().equals(GameObjectType.PlayerCharacter)) {
|
||||
this.bonuses.calculateRuneBaseEffects((PlayerCharacter) this);
|
||||
try {
|
||||
this.bonuses.calculateRuneBaseEffects((PlayerCharacter) this);
|
||||
}catch(Exception ignored){
|
||||
|
||||
}
|
||||
} else {
|
||||
this.bonuses.clearRuneBaseEffects();
|
||||
}
|
||||
|
||||
@@ -271,7 +271,8 @@ public abstract class AbstractWorldObject extends AbstractGameObject {
|
||||
if (this.getObjectType().equals(GameObjectType.PlayerCharacter))
|
||||
if (name.equals("Flight")) {
|
||||
((PlayerCharacter) this).update(false);
|
||||
PlayerCharacter.GroundPlayer((PlayerCharacter) this);
|
||||
if(!AbstractCharacter.CanFly((PlayerCharacter) this))
|
||||
PlayerCharacter.GroundPlayer((PlayerCharacter) this);
|
||||
}
|
||||
}
|
||||
applyAllBonuses();
|
||||
|
||||
@@ -59,6 +59,11 @@ public class Account extends AbstractGameObject {
|
||||
this.status = Enum.AccountStatus.valueOf(resultSet.getString("status"));
|
||||
}
|
||||
|
||||
public Account() {
|
||||
this.uname = "";
|
||||
this.status = Enum.AccountStatus.ACTIVE;
|
||||
}
|
||||
|
||||
public ArrayList<Item> getVault() {
|
||||
return vault;
|
||||
}
|
||||
|
||||
@@ -428,32 +428,24 @@ public final class Bane {
|
||||
|
||||
// Cache access
|
||||
|
||||
private void setDefaultTime() {
|
||||
public void setDefaultTime() {
|
||||
|
||||
DateTime timeToSetDefault = new DateTime(this.placementDate);
|
||||
timeToSetDefault = timeToSetDefault.plusDays(1);
|
||||
|
||||
DateTime currentTime = DateTime.now();
|
||||
DateTime defaultTime = new DateTime(this.placementDate);
|
||||
defaultTime = defaultTime.plusDays(2);
|
||||
defaultTime = defaultTime.hourOfDay().setCopy(22);
|
||||
defaultTime = defaultTime.minuteOfHour().setCopy(0);
|
||||
defaultTime = defaultTime.secondOfMinute().setCopy(0);
|
||||
|
||||
if (currentTime.isAfter(timeToSetDefault)){
|
||||
DbManager.BaneQueries.SET_BANE_CAP_NEW(20,this.getCityUUID());
|
||||
DbManager.BaneQueries.SET_BANE_TIME_NEW(9,this.getCityUUID());
|
||||
DbManager.BaneQueries.SET_BANE_DAY_NEW(3,this.getCityUUID());
|
||||
}
|
||||
//this.setLiveDate(defaultTime);
|
||||
else {
|
||||
|
||||
if (this.defaultTimeJob != null)
|
||||
this.defaultTimeJob.cancelJob();
|
||||
|
||||
BaneDefaultTimeJob bdtj = new BaneDefaultTimeJob(this);
|
||||
JobScheduler.getInstance().scheduleJob(bdtj, timeToSetDefault.getMillis());
|
||||
this.defaultTimeJob = bdtj;
|
||||
if (DateTime.now().isAfter(timeToSetDefault)){
|
||||
if(!this.capSet){
|
||||
DbManager.BaneQueries.SET_BANE_CAP_NEW(20,this.getCityUUID());
|
||||
this.capSet = true;
|
||||
}
|
||||
if(!this.daySet){
|
||||
DbManager.BaneQueries.SET_BANE_DAY_NEW(3,this.getCityUUID());
|
||||
this.daySet = true;
|
||||
}
|
||||
if(!this.timeSet){
|
||||
DbManager.BaneQueries.SET_BANE_TIME_NEW(9,this.getCityUUID());
|
||||
this.timeSet = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -360,6 +360,10 @@ this.maxRank = rs.getInt("MaxRank");
|
||||
return 3;
|
||||
}
|
||||
|
||||
if(bg != null && bg.equals(BuildingGroup.TOL) && currentRank == 8){
|
||||
return 5;
|
||||
}
|
||||
|
||||
if (this.maxRank == 1 && currentRank == 1)
|
||||
return getMaxSlots();
|
||||
|
||||
|
||||
@@ -160,23 +160,16 @@ public class Building extends AbstractWorldObject {
|
||||
// in City resulting in a stack ovreflow.
|
||||
|
||||
if (blueprint != null) {
|
||||
|
||||
// Only switch mesh for player dropped structures
|
||||
|
||||
if (this.blueprintUUID != 0)
|
||||
this.meshUUID = blueprint.getMeshForRank(rank);
|
||||
|
||||
this.healthMax = blueprint.getMaxHealth(this.rank);
|
||||
|
||||
// If this object has no blueprint but is a blueprint
|
||||
// mesh then set it's current health to max health
|
||||
|
||||
if (this.blueprintUUID == 0)
|
||||
this.setHealth(healthMax);
|
||||
|
||||
if (blueprint.getBuildingGroup().equals(BuildingGroup.BARRACK))
|
||||
this.patrolPoints = DbManager.BuildingQueries.LOAD_PATROL_POINTS(this);
|
||||
|
||||
} else {
|
||||
this.healthMax = 100000; // Structures with no blueprint mesh
|
||||
this.setHealth(healthMax);
|
||||
@@ -419,6 +412,22 @@ public class Building extends AbstractWorldObject {
|
||||
this.healthMax = this.getBlueprint().getMaxHealth(this.rank);
|
||||
this.setCurrentHitPoints(this.healthMax);
|
||||
|
||||
if(!this.ownerIsNPC && this.getBlueprint() != null && this.getBlueprint().isWallPiece()){
|
||||
//add extra HP for city walls of R8 trees
|
||||
City city = ZoneManager.getCityAtLocation(this.loc);
|
||||
if(city != null){
|
||||
Building ToL = city.getTOL();
|
||||
if(ToL != null){
|
||||
if(ToL.rank == 8){
|
||||
float currentHealth = this.health.get();
|
||||
float newHealth = (currentHealth/this.healthMax) * (this.healthMax * 1.1f);
|
||||
this.healthMax *= 1.1f;
|
||||
this.setHealth(newHealth);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this.getUpgradeDateTime() != null)
|
||||
BuildingManager.setUpgradeDateTime(this, null, 0);
|
||||
|
||||
@@ -1128,6 +1137,22 @@ public class Building extends AbstractWorldObject {
|
||||
}
|
||||
}
|
||||
|
||||
if(!this.ownerIsNPC && this.getBlueprint() != null && this.getBlueprint().isWallPiece()){
|
||||
//add extra HP for city walls of R8 trees
|
||||
City city = ZoneManager.getCityAtLocation(this.loc);
|
||||
if(city != null){
|
||||
Building ToL = city.getTOL();
|
||||
if(ToL != null){
|
||||
if(ToL.rank == 8){
|
||||
float currentHealth = this.health.get();
|
||||
float newHealth = (currentHealth/this.healthMax) * (this.healthMax * 1.1f);
|
||||
this.healthMax *= 1.1f;
|
||||
this.setHealth(newHealth);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set bounds for this building
|
||||
|
||||
Bounds buildingBounds = Bounds.borrow();
|
||||
|
||||
@@ -610,7 +610,7 @@ public class CharacterItemManager {
|
||||
if (i == null)
|
||||
return false;
|
||||
|
||||
i.stripCastableEnchants();
|
||||
//i.stripCastableEnchants();
|
||||
|
||||
if (!this.doesCharOwnThisItem(i.getObjectUUID()))
|
||||
return false;
|
||||
@@ -1056,7 +1056,11 @@ public class CharacterItemManager {
|
||||
// add to Bank
|
||||
this.bank.add(i);
|
||||
i.addToCache();
|
||||
i.stripCastableEnchants();
|
||||
try {
|
||||
i.stripCastableEnchants();
|
||||
}catch(Exception ignored){
|
||||
Logger.error("FAILED TO STRIP CASTABLE ENCHANTS: Move Item To Bank");
|
||||
}
|
||||
|
||||
calculateWeights();
|
||||
|
||||
@@ -1197,6 +1201,12 @@ public class CharacterItemManager {
|
||||
} else
|
||||
return false; // NPC's dont have vaults!
|
||||
|
||||
try {
|
||||
i.stripCastableEnchants();
|
||||
}catch(Exception ignored){
|
||||
Logger.error("FAILED TO STRIP CASTABLE ENCHANTS: Move Item To Vault");
|
||||
}
|
||||
|
||||
// remove it from other lists:
|
||||
this.remItemFromLists(i, slot);
|
||||
|
||||
@@ -1205,7 +1215,6 @@ public class CharacterItemManager {
|
||||
|
||||
calculateWeights();
|
||||
|
||||
i.stripCastableEnchants();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -2013,7 +2022,7 @@ public class CharacterItemManager {
|
||||
if (item.getItemBase().getType().equals(ItemType.GOLD)) {
|
||||
int amt = item.getNumOfItems();
|
||||
item.setNumOfItems(0);
|
||||
item.stripCastableEnchants();
|
||||
//item.stripCastableEnchants();
|
||||
MobLoot ml = new MobLoot(this.absCharacter, amt);
|
||||
ml.zeroItem();
|
||||
ml.containerType = Enum.ItemContainerType.INVENTORY;
|
||||
|
||||
@@ -164,6 +164,19 @@ public class CharacterRune extends AbstractGameObject {
|
||||
runes.remove(runes.indexOf(rune));
|
||||
CharacterSkill.calculateSkills(pc);
|
||||
pc.applyBonuses();
|
||||
if(ItemBase.getItemBase(rune.getRuneBaseID()) != null && ItemBase.getItemBase(rune.getRuneBaseID()).isStatRune()){
|
||||
//handle point refund
|
||||
int creationCost = 0;
|
||||
for(RuneBaseAttribute attr : rune.runeBase.getAttrs()){
|
||||
if(attr.getAttributeID() == MBServerStatics.RUNE_COST_ATTRIBUTE_ID){
|
||||
creationCost = (int)attr.getModValue();
|
||||
}
|
||||
}
|
||||
if(creationCost > 0){
|
||||
pc.unusedStatPoints += creationCost;
|
||||
pc.syncClient();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ public class CharacterSkill extends AbstractGameObject {
|
||||
165, 166, 166, 167, 167, //185 to 189
|
||||
168}; //190
|
||||
|
||||
private static final float[] baseSkillValues = {
|
||||
static final float[] baseSkillValues = {
|
||||
0.0f, 0.0f, 0.2f, 0.4f, 0.6f, //0 to 4
|
||||
0.8f, 1.0f, 1.1666666f, 1.3333334f, 1.5f, //5 to 9
|
||||
1.6666667f, 1.8333334f, 2.0f, 2.2f, 2.4f, //10 to 14
|
||||
|
||||
@@ -389,18 +389,22 @@ public class City extends AbstractWorldObject {
|
||||
|
||||
if (pc.getAccount().status.equals(AccountStatus.ADMIN)) {
|
||||
cities.add(city);
|
||||
} else
|
||||
} else {
|
||||
//list Player cities
|
||||
|
||||
//open city, just list
|
||||
if (city.open && city.getTOL() != null && city.getTOL().getRank() > 4) {
|
||||
|
||||
if (!BuildingManager.IsPlayerHostile(city.getTOL(), pc))
|
||||
cities.add(city); //verify nation or guild is same
|
||||
} else if (Guild.sameNationExcludeErrant(city.getGuild(), pcG))
|
||||
cities.add(city);
|
||||
|
||||
|
||||
}else {
|
||||
try {
|
||||
if (city.getGuild().getNation().equals(pc.guild.getNation())) {
|
||||
cities.add(city);
|
||||
}
|
||||
}catch(Exception e){
|
||||
Logger.error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (city.isNpc == 1) {
|
||||
//list NPC cities
|
||||
Guild g = city.getGuild();
|
||||
@@ -811,8 +815,10 @@ public class City extends AbstractWorldObject {
|
||||
|
||||
// Set city motto to current guild motto
|
||||
|
||||
if (BuildingManager.getBuilding(this.treeOfLifeID) == null)
|
||||
if (BuildingManager.getBuilding(this.treeOfLifeID) == null) {
|
||||
Logger.info("City UID " + this.getObjectUUID() + " Failed to Load Tree of Life with ID " + this.treeOfLifeID);
|
||||
this.destroy();
|
||||
}
|
||||
|
||||
if ((ConfigManager.serverType.equals(ServerType.WORLDSERVER))
|
||||
&& (this.isNpc == (byte) 0)) {
|
||||
|
||||
@@ -22,6 +22,7 @@ import org.pmw.tinylog.Logger;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
public class Contract extends AbstractGameObject {
|
||||
|
||||
@@ -248,6 +249,80 @@ public class Contract extends AbstractGameObject {
|
||||
}
|
||||
return vd;
|
||||
}
|
||||
public static VendorDialog HandleGamblerOptions(int optionId, NPC npc, PlayerCharacter pc){
|
||||
pc.setLastNPCDialog(npc);
|
||||
VendorDialog vd = new VendorDialog(VendorDialog.getHostileVendorDialog().getDialogType(),VendorDialog.getHostileVendorDialog().getIntro(),-1);//VendorDialog.getHostileVendorDialog();
|
||||
vd.getOptions().clear();
|
||||
MenuOption option1 = new MenuOption(15020441, "Gamble 1000", 15020441);
|
||||
vd.getOptions().add(option1);
|
||||
|
||||
MenuOption option2 = new MenuOption(15020442, "Gamble 10,000", 15020442);
|
||||
vd.getOptions().add(option2);
|
||||
|
||||
MenuOption option3 = new MenuOption(15020443, "Gamble 100,000", 15020443);
|
||||
vd.getOptions().add(option3);
|
||||
switch(optionId) {
|
||||
case 15020441: // gamble 1000
|
||||
gamble(pc,1000);
|
||||
break;
|
||||
case 15020442: // gamble 10,000
|
||||
gamble(pc,10000);
|
||||
break;
|
||||
case 15020443: // gamble 100,000
|
||||
gamble(pc,100000);
|
||||
break;
|
||||
}
|
||||
return vd;
|
||||
}
|
||||
|
||||
public static void gamble(PlayerCharacter pc, int amount){
|
||||
|
||||
if(!pc.timestamps.containsKey("NextSlot"))
|
||||
pc.timestamps.put("NextSlot",System.currentTimeMillis());
|
||||
|
||||
if(pc.timestamps.get("NextSlot") > System.currentTimeMillis())
|
||||
return;
|
||||
|
||||
pc.timestamps.put("NextSlot",System.currentTimeMillis() + 2000L);
|
||||
|
||||
if(pc.charItemManager == null){
|
||||
return;
|
||||
}
|
||||
|
||||
int goldAmount = pc.charItemManager.getGoldInventory().getNumOfItems();
|
||||
|
||||
if(goldAmount < amount) {
|
||||
ChatManager.chatSystemInfo(pc, "You Cannot Afford This Wager");
|
||||
return;
|
||||
}
|
||||
goldAmount -= amount;
|
||||
|
||||
pc.charItemManager.getGoldInventory().setNumOfItems(goldAmount);
|
||||
pc.charItemManager.updateInventory();
|
||||
|
||||
ChatManager.chatSystemInfo(pc, "You Attempt To Gamble " + amount + " ...");
|
||||
int roll1 = ThreadLocalRandom.current().nextInt(1,7);
|
||||
int roll2 = ThreadLocalRandom.current().nextInt(1,7);
|
||||
int roll3 = ThreadLocalRandom.current().nextInt(1,7);
|
||||
|
||||
ChatManager.chatSystemInfo(pc, "Gambler Has Rolled: " + roll1 + " " + roll2 + " " + roll3);
|
||||
|
||||
int winnings = 0;
|
||||
|
||||
if(roll1 == roll2 && roll1 == roll3)
|
||||
winnings = amount * roll1 * 10;
|
||||
|
||||
if(winnings > 0)
|
||||
ChatManager.chatSystemInfo(pc, "You Have Won " + winnings + " Gold Coins!");
|
||||
else
|
||||
ChatManager.chatSystemInfo(pc, "You Have Lost The Wager");
|
||||
|
||||
goldAmount += winnings;
|
||||
|
||||
pc.charItemManager.getGoldInventory().setNumOfItems(goldAmount);
|
||||
pc.charItemManager.updateInventory();
|
||||
|
||||
}
|
||||
public static VendorDialog HandleBaneCommanderOptions(int optionId, NPC npc, PlayerCharacter pc){
|
||||
pc.setLastNPCDialog(npc);
|
||||
VendorDialog vd = new VendorDialog(VendorDialog.getHostileVendorDialog().getDialogType(),VendorDialog.getHostileVendorDialog().getIntro(),-1);//VendorDialog.getHostileVendorDialog();
|
||||
|
||||
@@ -43,6 +43,7 @@ public class Corpse extends AbstractWorldObject {
|
||||
private int inBuildingID = 0;
|
||||
private int inFloorID = -1;
|
||||
private int inBuilding = -1;
|
||||
public Long spawnedTime = 0L;
|
||||
|
||||
/**
|
||||
* No Id Constructor
|
||||
@@ -74,6 +75,7 @@ public class Corpse extends AbstractWorldObject {
|
||||
}
|
||||
this.setObjectTypeMask(MBServerStatics.MASK_CORPSE);
|
||||
|
||||
this.spawnedTime = System.currentTimeMillis();
|
||||
if (!safeZone)
|
||||
transferInventory(belongsTo, enterWorld);
|
||||
|
||||
|
||||
@@ -326,6 +326,10 @@ public class Effect {
|
||||
writer.putString(item.getName());
|
||||
writer.putFloat(-1000f);
|
||||
} else {
|
||||
if(true){
|
||||
serializeForClientMsg(writer);
|
||||
return;
|
||||
}
|
||||
float duration = this.jc.timeToExecutionLeft() / 1000;
|
||||
writer.putInt(this.eb.getToken());
|
||||
writer.putInt(aej.getTrains());
|
||||
@@ -338,6 +342,10 @@ public class Effect {
|
||||
}
|
||||
|
||||
public void serializeForClientMsg(ByteBufferWriter writer) {
|
||||
if(true){
|
||||
serializeForLoad(writer);
|
||||
return;
|
||||
}
|
||||
AbstractJob aj = this.jc.getJob();
|
||||
if (aj == null || (!(aj instanceof AbstractEffectJob))) {
|
||||
//TODO put error message here
|
||||
|
||||
@@ -349,6 +349,9 @@ public class Experience {
|
||||
if(killer.equals(mob))
|
||||
return;
|
||||
|
||||
if(killer.pvpKills.contains(mob.getObjectUUID()))
|
||||
return;
|
||||
|
||||
double grantedExperience = 0.0;
|
||||
|
||||
if (g != null) { // Do group EXP stuff
|
||||
@@ -406,7 +409,6 @@ public class Experience {
|
||||
|
||||
grantedExperience = (double) LOOTMANAGER.NORMAL_EXP_RATE * maxXPPerKill(playerCharacter.getLevel());
|
||||
|
||||
grantedExperience *= (1/ giveEXPTo.size()+0.9);
|
||||
// Adjust XP for Mob Level
|
||||
|
||||
grantedExperience *= getConMod(playerCharacter, mob);
|
||||
@@ -443,6 +445,9 @@ public class Experience {
|
||||
if (grantedExperience == 0)
|
||||
grantedExperience = 1;
|
||||
|
||||
//scaling
|
||||
grantedExperience *= (1 / giveEXPTo.size()+0.9);
|
||||
|
||||
// Grant the player the EXP
|
||||
playerCharacter.grantXP((int) Math.floor(grantedExperience));
|
||||
}
|
||||
@@ -466,9 +471,13 @@ public class Experience {
|
||||
grantedExperience *= LOOTMANAGER.HOTZONE_EXP_RATE;
|
||||
|
||||
// Errant penalty
|
||||
if (grantedExperience != 1)
|
||||
if (grantedExperience != 1) {
|
||||
if (killer.getGuild().isEmptyGuild())
|
||||
grantedExperience *= .6;
|
||||
grantedExperience *= 0.6f;
|
||||
}
|
||||
|
||||
//bonus for no group
|
||||
grantedExperience *= 1.9f;
|
||||
|
||||
// Grant XP
|
||||
killer.grantXP((int) Math.floor(grantedExperience));
|
||||
|
||||
@@ -818,24 +818,15 @@ public class Item extends AbstractWorldObject {
|
||||
}
|
||||
|
||||
public void stripCastableEnchants(){
|
||||
ArrayList<String> keys =new ArrayList<>();
|
||||
|
||||
for(String eff : this.effects.keySet()){
|
||||
for(AbstractEffectModifier mod : this.effects.get(eff).getEffectsBase().getModifiers()){
|
||||
if(mod.modType.equals(ModType.WeaponProc)){
|
||||
keys.add(eff);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(String eff : keys){
|
||||
try {
|
||||
this.effects.get(eff).endEffect();
|
||||
this.effects.remove(eff);
|
||||
}catch(Exception e){
|
||||
|
||||
ArrayList<Effect> ToRemove = new ArrayList<>();
|
||||
for(Effect eff : this.effects.values()){
|
||||
if(eff.getJobContainer() != null && !eff.getJobContainer().noTimer()){
|
||||
eff.endEffectNoPower();
|
||||
eff.getJobContainer().cancelJob();
|
||||
ToRemove.add(eff);
|
||||
}
|
||||
}
|
||||
this.effects.values().removeAll(ToRemove);
|
||||
}
|
||||
//Only to be used for trading
|
||||
public void setOwnerID(int ownerID) {
|
||||
@@ -1085,7 +1076,7 @@ public class Item extends AbstractWorldObject {
|
||||
this.ownerID = pc.getObjectUUID();
|
||||
this.ownerType = OwnerType.PlayerCharacter;
|
||||
this.containerType = ItemContainerType.INVENTORY;
|
||||
this.stripCastableEnchants();
|
||||
//this.stripCastableEnchants();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1106,7 +1097,7 @@ public class Item extends AbstractWorldObject {
|
||||
this.ownerID = npc.getObjectUUID();
|
||||
this.ownerType = OwnerType.Npc;
|
||||
this.containerType = Enum.ItemContainerType.INVENTORY;
|
||||
this.stripCastableEnchants();
|
||||
//this.stripCastableEnchants();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1124,7 +1115,7 @@ public class Item extends AbstractWorldObject {
|
||||
this.ownerID = 0;
|
||||
this.ownerType = null;
|
||||
this.containerType = Enum.ItemContainerType.INVENTORY;
|
||||
this.stripCastableEnchants();
|
||||
//this.stripCastableEnchants();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1227,7 +1218,10 @@ public class Item extends AbstractWorldObject {
|
||||
}
|
||||
|
||||
public final int getMagicValue() {
|
||||
return this.magicValue;
|
||||
int val = this.calcMagicValue();
|
||||
if(val == 0)
|
||||
val = 1;
|
||||
return val + this.getItemBase().getMagicValue();
|
||||
}
|
||||
|
||||
public int getBaseValue() {
|
||||
@@ -1489,4 +1483,21 @@ public class Item extends AbstractWorldObject {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public float getModifiedSpeed() {
|
||||
float speed = this.getItemBase().getSpeed();
|
||||
try {
|
||||
for (Effect eff : this.effects.values()) {
|
||||
for (AbstractEffectModifier mod : eff.getEffectModifiers()) {
|
||||
if (mod.modType.equals(ModType.WeaponSpeed)) {
|
||||
float modValue = 1 + mod.getPercentMod() * 0.01f;
|
||||
speed *= modValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}catch(Exception e){
|
||||
|
||||
}
|
||||
return speed;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,6 +76,8 @@ public class ItemBase {
|
||||
private ArrayList<Integer> animations = new ArrayList<>();
|
||||
private ArrayList<Integer> offHandAnimations = new ArrayList<>();
|
||||
|
||||
public float dexReduction = 0.0f;
|
||||
|
||||
/**
|
||||
* ResultSet Constructor
|
||||
*/
|
||||
@@ -151,7 +153,7 @@ public class ItemBase {
|
||||
}
|
||||
initBakedInStats();
|
||||
initializeHashes();
|
||||
|
||||
initDexReduction();
|
||||
}
|
||||
|
||||
public static void addToCache(ItemBase itemBase) {
|
||||
@@ -319,6 +321,10 @@ public class ItemBase {
|
||||
DbManager.ItemBaseQueries.LOAD_BAKEDINSTATS(this);
|
||||
}
|
||||
|
||||
private void initDexReduction(){
|
||||
DbManager.ItemBaseQueries.LOAD_DEX_REDUCTION(this);
|
||||
}
|
||||
|
||||
//TODO fix this later. Shouldn't be gotten from item base
|
||||
public int getMagicValue() {
|
||||
return this.value;
|
||||
|
||||
@@ -341,6 +341,7 @@ public class Mine extends AbstractGameObject {
|
||||
if(!mine.isActive)
|
||||
if(mine.getOwningGuild() != null)
|
||||
if(mine.getOwningGuild().getNation().equals(player.getGuild().getNation()))
|
||||
if(!mine.getOwningGuild().equals(Guild.getErrantGuild()))
|
||||
mines.add(mine);
|
||||
|
||||
return mines;
|
||||
|
||||
+114
-225
@@ -12,6 +12,7 @@ package engine.objects;
|
||||
import ch.claude_martin.enumbitset.EnumBitSet;
|
||||
import engine.Enum;
|
||||
import engine.Enum.*;
|
||||
import engine.InterestManagement.InterestManager;
|
||||
import engine.InterestManagement.WorldGrid;
|
||||
import engine.exception.SerializationException;
|
||||
import engine.gameManager.*;
|
||||
@@ -619,6 +620,7 @@ public class Mob extends AbstractIntelligenceAgent {
|
||||
DbManager.addToCache(mob);
|
||||
mob.setPet(owner, true);
|
||||
mob.setWalkMode(false);
|
||||
mob.level = level;
|
||||
mob.runAfterLoad();
|
||||
|
||||
} catch (Exception e) {
|
||||
@@ -627,8 +629,12 @@ public class Mob extends AbstractIntelligenceAgent {
|
||||
createLock.writeLock().unlock();
|
||||
}
|
||||
parent.zoneMobSet.add(mob);
|
||||
mob.level = level;
|
||||
mob.healthMax = mob.getMobBase().getHealthMax() * (mob.level * 0.5f);
|
||||
// mob.level = level;
|
||||
float healthMax = mob.getMobBase().getHealthMax();
|
||||
if(mob.bonuses != null){
|
||||
healthMax += mob.bonuses.getFloat(ModType.HealthFull,SourceType.None);
|
||||
}
|
||||
mob.healthMax = healthMax;
|
||||
mob.health.set(mob.healthMax);
|
||||
return mob;
|
||||
}
|
||||
@@ -1326,8 +1332,6 @@ public class Mob extends AbstractIntelligenceAgent {
|
||||
Dispatch dispatch;
|
||||
|
||||
try {
|
||||
//resync corpses
|
||||
//this.setLoc(this.getMovementLoc());
|
||||
if (this.isSiege) {
|
||||
this.deathTime = System.currentTimeMillis();
|
||||
//this.state = STATE.Dead;
|
||||
@@ -1407,6 +1411,8 @@ public class Mob extends AbstractIntelligenceAgent {
|
||||
Logger.error(e);
|
||||
}
|
||||
this.updateLocation();
|
||||
//resync corpses
|
||||
InterestManager.setObjectDirty(this);
|
||||
}
|
||||
|
||||
public void respawn() {
|
||||
@@ -1441,6 +1447,9 @@ public class Mob extends AbstractIntelligenceAgent {
|
||||
loadInventory();
|
||||
|
||||
this.updateLocation();
|
||||
this.stopPatrolTime = 0;
|
||||
this.lastPatrolPointIndex = 0;
|
||||
InterestManager.setObjectDirty(this);
|
||||
}
|
||||
|
||||
public void despawn() {
|
||||
@@ -1635,67 +1644,67 @@ public class Mob extends AbstractIntelligenceAgent {
|
||||
this.defenseRating = defense;
|
||||
this.atrHandOne = atr;
|
||||
return;
|
||||
}else {
|
||||
if (this.charItemManager == null || this.equip == null) {
|
||||
Logger.error("Player " + currentID + " missing skills or equipment");
|
||||
defaultAtrAndDamage(true);
|
||||
defaultAtrAndDamage(false);
|
||||
this.defenseRating = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
calculateAtrDamageForWeapon(this.equip.get(MBServerStatics.SLOT_MAINHAND), true);
|
||||
} catch (Exception e) {
|
||||
|
||||
this.atrHandOne = GetAttackRating(this.mobBase.getAttackRating(), this);
|
||||
this.minDamageHandOne = (short) this.mobBase.getDamageMin();
|
||||
this.maxDamageHandOne = (short) this.mobBase.getDamageMax();
|
||||
this.rangeHandOne = 6.5f;
|
||||
this.speedHandOne = 20;
|
||||
Logger.info("Mobbase ID " + this.getMobBaseID() + " returned an error. setting to default ATR and Damage." + e.getMessage());
|
||||
}
|
||||
|
||||
try {
|
||||
calculateAtrDamageForWeapon(this.equip.get(MBServerStatics.SLOT_OFFHAND), false);
|
||||
|
||||
} catch (Exception e) {
|
||||
|
||||
this.atrHandTwo = GetAttackRating(this.mobBase.getAttackRating(), this);
|
||||
this.minDamageHandTwo = (short) this.mobBase.getDamageMin();
|
||||
this.maxDamageHandTwo = (short) this.mobBase.getDamageMax();
|
||||
this.rangeHandTwo = 6.5f;
|
||||
this.speedHandTwo = 20;
|
||||
Logger.info("Mobbase ID " + this.getMobBaseID() + " returned an error. setting to default ATR and Damage." + e.getMessage());
|
||||
}
|
||||
|
||||
try {
|
||||
float defense = this.mobBase.getDefenseRating();
|
||||
defense += getShieldDefense(equip.get(MBServerStatics.SLOT_OFFHAND));
|
||||
defense += getArmorDefense(equip.get(MBServerStatics.SLOT_HELMET));
|
||||
defense += getArmorDefense(equip.get(MBServerStatics.SLOT_CHEST));
|
||||
defense += getArmorDefense(equip.get(MBServerStatics.SLOT_ARMS));
|
||||
defense += getArmorDefense(equip.get(MBServerStatics.SLOT_GLOVES));
|
||||
defense += getArmorDefense(equip.get(MBServerStatics.SLOT_LEGGINGS));
|
||||
defense += getArmorDefense(equip.get(MBServerStatics.SLOT_FEET));
|
||||
defense += getWeaponDefense(equip);
|
||||
|
||||
// TODO add error log here
|
||||
if (this.bonuses != null) {
|
||||
defense = GetDefense((int) defense, this);
|
||||
|
||||
} else
|
||||
Logger.error("Error: missing bonuses");
|
||||
|
||||
defense = (defense < 1) ? 1 : defense;
|
||||
this.defenseRating = (short) (defense + 0.5f);
|
||||
} catch (Exception e) {
|
||||
Logger.info("Mobbase ID " + this.getMobBaseID() + " returned an error. Setting to Default Defense." + e.getMessage());
|
||||
this.defenseRating = (short) this.mobBase.getDefense();
|
||||
}
|
||||
// calculate defense for equipment
|
||||
}
|
||||
if (this.charItemManager == null || this.equip == null) {
|
||||
Logger.error("Player " + currentID + " missing skills or equipment");
|
||||
defaultAtrAndDamage(true);
|
||||
defaultAtrAndDamage(false);
|
||||
this.defenseRating = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
calculateAtrDamageForWeapon(this.equip.get(MBServerStatics.SLOT_MAINHAND), true);
|
||||
} catch (Exception e) {
|
||||
|
||||
this.atrHandOne = GetAttackRating(this.mobBase.getAttackRating(), this);
|
||||
this.minDamageHandOne = (short) this.mobBase.getMinDmg();
|
||||
this.maxDamageHandOne = (short) this.mobBase.getMaxDmg();
|
||||
this.rangeHandOne = 6.5f;
|
||||
this.speedHandOne = 20;
|
||||
Logger.info("Mobbase ID " + this.getMobBaseID() + " returned an error. setting to default ATR and Damage." + e.getMessage());
|
||||
}
|
||||
|
||||
try {
|
||||
calculateAtrDamageForWeapon(this.equip.get(MBServerStatics.SLOT_OFFHAND), false);
|
||||
|
||||
} catch (Exception e) {
|
||||
|
||||
this.atrHandTwo = GetAttackRating(this.mobBase.getAttackRating(), this);
|
||||
this.minDamageHandTwo = (short) this.mobBase.getMinDmg();
|
||||
this.maxDamageHandTwo = (short) this.mobBase.getMaxDmg();
|
||||
this.rangeHandTwo = 6.5f;
|
||||
this.speedHandTwo = 20;
|
||||
Logger.info("Mobbase ID " + this.getMobBaseID() + " returned an error. setting to default ATR and Damage." + e.getMessage());
|
||||
}
|
||||
|
||||
try {
|
||||
float defense = this.mobBase.getDefenseRating();
|
||||
defense += getShieldDefense(equip.get(MBServerStatics.SLOT_OFFHAND));
|
||||
defense += getArmorDefense(equip.get(MBServerStatics.SLOT_HELMET));
|
||||
defense += getArmorDefense(equip.get(MBServerStatics.SLOT_CHEST));
|
||||
defense += getArmorDefense(equip.get(MBServerStatics.SLOT_ARMS));
|
||||
defense += getArmorDefense(equip.get(MBServerStatics.SLOT_GLOVES));
|
||||
defense += getArmorDefense(equip.get(MBServerStatics.SLOT_LEGGINGS));
|
||||
defense += getArmorDefense(equip.get(MBServerStatics.SLOT_FEET));
|
||||
defense += getWeaponDefense(equip);
|
||||
|
||||
// TODO add error log here
|
||||
if (this.bonuses != null) {
|
||||
defense = GetDefense((int)defense, this);
|
||||
|
||||
} else
|
||||
Logger.error("Error: missing bonuses");
|
||||
|
||||
defense = (defense < 1) ? 1 : defense;
|
||||
this.defenseRating = (short) (defense + 0.5f);
|
||||
} catch (Exception e) {
|
||||
Logger.info("Mobbase ID " + this.getMobBaseID() + " returned an error. Setting to Default Defense." + e.getMessage());
|
||||
this.defenseRating = (short) this.mobBase.getDefense();
|
||||
}
|
||||
// calculate defense for equipment
|
||||
|
||||
if(this.isDropper || Mob.discDroppers.contains(this)){
|
||||
if((this.isDropper || Mob.discDroppers.contains(this)) && !this.mobBase.getFirstName().contains("Blood Mage")){
|
||||
this.defenseRating *= 2;
|
||||
this.atrHandOne *= 2;
|
||||
this.atrHandTwo *= 2;
|
||||
@@ -1839,168 +1848,46 @@ public class Mob extends AbstractIntelligenceAgent {
|
||||
|
||||
private void calculateAtrDamageForWeapon(MobEquipment weapon, boolean mainHand) {
|
||||
|
||||
int baseStrength = 0;
|
||||
|
||||
float skillPercentage, masteryPercentage;
|
||||
float mastDam;
|
||||
|
||||
// make sure weapon exists
|
||||
|
||||
boolean noWeapon = false;
|
||||
ItemBase wb = null;
|
||||
|
||||
if (weapon == null)
|
||||
noWeapon = true;
|
||||
|
||||
else {
|
||||
|
||||
ItemBase ib = weapon.getItemBase();
|
||||
|
||||
if (ib == null)
|
||||
noWeapon = true;
|
||||
else if (ib.getType().equals(ItemType.WEAPON) == false) {
|
||||
defaultAtrAndDamage(mainHand);
|
||||
return;
|
||||
} else
|
||||
wb = ib;
|
||||
}
|
||||
|
||||
float min, max;
|
||||
float speed;
|
||||
boolean strBased = false;
|
||||
|
||||
// get skill percentages and min and max damage for weapons
|
||||
|
||||
if (noWeapon) {
|
||||
|
||||
if (mainHand)
|
||||
if(mainHand){
|
||||
int min = (int)this.mobBase.getDamageMin();
|
||||
int max = (int)this.mobBase.getDamageMax();
|
||||
int atr = this.mobBase.getAtr();
|
||||
if(this.bonuses != null){
|
||||
min *= 1 + this.bonuses.getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.None);
|
||||
max *= 1 + this.bonuses.getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.None);
|
||||
atr *= 1 + this.bonuses.getFloatPercentAll(ModType.OCV,SourceType.None);
|
||||
atr += this.bonuses.getFloat(ModType.OCV,SourceType.None);
|
||||
}
|
||||
this.minDamageHandOne = min;
|
||||
this.maxDamageHandOne = max;
|
||||
this.atrHandOne = atr;
|
||||
if(weapon == null){
|
||||
this.rangeHandOne = this.mobBase.getAttackRange();
|
||||
else
|
||||
this.rangeHandTwo = -1; // set to do not attack
|
||||
|
||||
skillPercentage = getModifiedAmount(this.skills.get("Unarmed Combat"));
|
||||
masteryPercentage = getModifiedAmount(this.skills.get("Unarmed Combat Mastery"));
|
||||
|
||||
if (masteryPercentage == 0f)
|
||||
mastDam = CharacterSkill.getQuickMastery(this, "Unarmed Combat Mastery");
|
||||
else
|
||||
mastDam = masteryPercentage;
|
||||
|
||||
// TODO Correct these
|
||||
min = this.mobBase.getMinDmg();
|
||||
max = this.mobBase.getMaxDmg();
|
||||
} else {
|
||||
|
||||
if (mainHand)
|
||||
this.rangeHandOne = weapon.getItemBase().getRange() * (1 + (baseStrength / 600.0f));
|
||||
else
|
||||
this.rangeHandTwo = weapon.getItemBase().getRange() * (1 + (baseStrength / 600.0f));
|
||||
|
||||
skillPercentage = getModifiedAmount(this.skills.get(wb.getSkillRequired()));
|
||||
masteryPercentage = getModifiedAmount(this.skills.get(wb.getMastery()));
|
||||
|
||||
if (masteryPercentage == 0f)
|
||||
mastDam = 0f;
|
||||
else
|
||||
mastDam = masteryPercentage;
|
||||
|
||||
min = wb.getMinDamage();
|
||||
max = wb.getMaxDamage();
|
||||
strBased = wb.isStrBased();
|
||||
}
|
||||
|
||||
// calculate atr
|
||||
float atr = this.mobBase.getAttackRating();
|
||||
|
||||
if (this.statStrCurrent > this.statDexCurrent)
|
||||
atr += statStrCurrent * .5;
|
||||
else
|
||||
atr += statDexCurrent * .5;
|
||||
|
||||
// add in any bonuses to atr
|
||||
|
||||
if (this.bonuses != null) {
|
||||
atr += this.bonuses.getFloat(ModType.OCV, SourceType.None);
|
||||
|
||||
// Finally use any multipliers. DO THIS LAST!
|
||||
float pos_Bonus = 1 + this.bonuses.getFloatPercentPositive(ModType.OCV, SourceType.None);
|
||||
|
||||
atr *= pos_Bonus;
|
||||
|
||||
//and negative percent modifiers
|
||||
//TODO DO DEBUFFS AFTER?? wILL TEst when finished
|
||||
float neg_Bonus = this.bonuses.getFloatPercentNegative(ModType.OCV, SourceType.None);
|
||||
|
||||
atr *= (1 + neg_Bonus);
|
||||
}
|
||||
|
||||
atr = (atr < 1) ? 1 : atr;
|
||||
|
||||
// set atr
|
||||
|
||||
if (mainHand)
|
||||
this.atrHandOne = (short) (atr + 0.5f);
|
||||
else
|
||||
this.atrHandTwo = (short) (atr + 0.5f);
|
||||
|
||||
//calculate speed
|
||||
|
||||
if (wb != null)
|
||||
speed = wb.getSpeed();
|
||||
else
|
||||
speed = 20f; //unarmed attack speed
|
||||
|
||||
if (this.bonuses != null && this.bonuses.getFloat(ModType.AttackDelay, SourceType.None) != 0f) //add effects speed bonus
|
||||
speed *= (1 + this.bonuses.getFloatPercentAll(ModType.AttackDelay, SourceType.None));
|
||||
|
||||
if (speed < 10)
|
||||
speed = 10;
|
||||
|
||||
//add min/max damage bonuses for weapon **REMOVED
|
||||
|
||||
//if duel wielding, cut damage by 30%
|
||||
// calculate damage
|
||||
|
||||
float minDamage;
|
||||
float maxDamage;
|
||||
float pri = (strBased) ? (float) this.statStrCurrent : (float) this.statDexCurrent;
|
||||
float sec = (strBased) ? (float) this.statDexCurrent : (float) this.statStrCurrent;
|
||||
|
||||
minDamage = (float) (min * ((0.0315f * Math.pow(pri, 0.75f)) + (0.042f * Math.pow(sec, 0.75f)) + (0.01f * ((int) skillPercentage + (int) mastDam))));
|
||||
maxDamage = (float) (max * ((0.0785f * Math.pow(pri, 0.75f)) + (0.016f * Math.pow(sec, 0.75f)) + (0.0075f * ((int) skillPercentage + (int) mastDam))));
|
||||
|
||||
minDamage = (float) ((int) (minDamage + 0.5f)); //round to nearest decimal
|
||||
maxDamage = (float) ((int) (maxDamage + 0.5f)); //round to nearest decimal
|
||||
|
||||
//add Base damage last.
|
||||
float minDamageMod = this.mobBase.getDamageMin();
|
||||
float maxDamageMod = this.mobBase.getDamageMax();
|
||||
|
||||
minDamage += minDamageMod;
|
||||
maxDamage += maxDamageMod;
|
||||
|
||||
// add in any bonuses to damage
|
||||
|
||||
if (this.bonuses != null) {
|
||||
// Add any base bonuses
|
||||
minDamage += this.bonuses.getFloat(ModType.MinDamage, SourceType.None);
|
||||
maxDamage += this.bonuses.getFloat(ModType.MaxDamage, SourceType.None);
|
||||
|
||||
// Finally use any multipliers. DO THIS LAST!
|
||||
minDamage *= (1 + this.bonuses.getFloatPercentAll(ModType.MinDamage, SourceType.None));
|
||||
maxDamage *= (1 + this.bonuses.getFloatPercentAll(ModType.MaxDamage, SourceType.None));
|
||||
}
|
||||
|
||||
// set damages
|
||||
|
||||
if (mainHand) {
|
||||
this.minDamageHandOne = (short) minDamage;
|
||||
this.maxDamageHandOne = (short) maxDamage;
|
||||
this.speedHandOne = 30;
|
||||
} else {
|
||||
this.minDamageHandTwo = (short) minDamage;
|
||||
this.maxDamageHandTwo = (short) maxDamage;
|
||||
this.speedHandTwo = 30;
|
||||
this.speedHandTwo = 20.0f;
|
||||
}else{
|
||||
this.rangeHandOne = weapon.getItemBase().getRange();
|
||||
this.speedHandTwo = weapon.getItemBase().getSpeed();
|
||||
}
|
||||
}else{
|
||||
int min = (int)this.mobBase.getDamageMin();
|
||||
int max = (int)this.mobBase.getDamageMax();
|
||||
int atr = this.mobBase.getAtr();
|
||||
if(this.bonuses != null){
|
||||
min *= 1 + this.bonuses.getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.None);
|
||||
max *= 1 + this.bonuses.getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.None);
|
||||
atr *= 1 + this.bonuses.getFloatPercentAll(ModType.OCV,SourceType.None);
|
||||
atr += this.bonuses.getFloat(ModType.OCV,SourceType.None);
|
||||
}
|
||||
this.minDamageHandTwo = min;
|
||||
this.maxDamageHandTwo = max;
|
||||
this.atrHandTwo = atr;
|
||||
if(weapon == null){
|
||||
this.rangeHandTwo = this.mobBase.getAttackRange();
|
||||
this.speedHandTwo = 20.0f;
|
||||
}else{
|
||||
this.rangeHandTwo = weapon.getItemBase().getRange();
|
||||
this.speedHandTwo = weapon.getItemBase().getSpeed();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2114,6 +2001,7 @@ public class Mob extends AbstractIntelligenceAgent {
|
||||
|
||||
try {
|
||||
NPCManager.applyRuneSetEffects(this);
|
||||
MobBase.applyMobbaseEffects(this);
|
||||
recalculateStats();
|
||||
this.setHealth(this.healthMax);
|
||||
|
||||
@@ -2165,6 +2053,7 @@ public class Mob extends AbstractIntelligenceAgent {
|
||||
}
|
||||
|
||||
this.deathTime = 0;
|
||||
InterestManager.setObjectDirty(this);
|
||||
} catch (Exception e) {
|
||||
Logger.error(e.getMessage());
|
||||
}
|
||||
|
||||
@@ -13,8 +13,11 @@ import ch.claude_martin.enumbitset.EnumBitSet;
|
||||
import engine.Enum;
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.gameManager.LootManager;
|
||||
import engine.gameManager.PowersManager;
|
||||
import engine.loot.BootySetEntry;
|
||||
import engine.powers.EffectsBase;
|
||||
import engine.server.MBServerStatics;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
@@ -54,6 +57,8 @@ public class MobBase extends AbstractGameObject {
|
||||
private float walkCombat = 0;
|
||||
private float runCombat = 0;
|
||||
|
||||
public ArrayList<MobBaseEffects> mobbaseEffects;
|
||||
|
||||
/**
|
||||
* ResultSet Constructor
|
||||
*/
|
||||
@@ -108,6 +113,7 @@ public class MobBase extends AbstractGameObject {
|
||||
|
||||
this.mobBaseStats = DbManager.MobBaseQueries.LOAD_STATS(this.loadID);
|
||||
DbManager.MobBaseQueries.LOAD_ALL_MOBBASE_SPEEDS(this);
|
||||
this.mobbaseEffects = DbManager.MobBaseQueries.GET_RUNEBASE_EFFECTS(this.getObjectUUID());
|
||||
|
||||
}
|
||||
|
||||
@@ -254,7 +260,7 @@ public class MobBase extends AbstractGameObject {
|
||||
}
|
||||
|
||||
public int getAtr() {
|
||||
return atr;
|
||||
return attackRating;
|
||||
}
|
||||
|
||||
public void setAtr(int atr) {
|
||||
@@ -301,4 +307,23 @@ public class MobBase extends AbstractGameObject {
|
||||
return runCombat;
|
||||
}
|
||||
|
||||
public static void applyMobbaseEffects(Mob mob){
|
||||
if(mob.getMobBaseID() == 12008)
|
||||
mob.level = 65;
|
||||
else if(mob.getMobBaseID() == 12019)
|
||||
mob.level = 80;
|
||||
for(MobBaseEffects mbe : mob.mobBase.mobbaseEffects){
|
||||
if(mob.level >= mbe.getReqLvl()){
|
||||
try {
|
||||
//PowersManager.applyPower(mob, mob, mob.loc, mbe.getToken(), mbe.getRank(), false);
|
||||
EffectsBase effectsBase = PowersManager.getEffectByToken(mbe.getToken());
|
||||
if(effectsBase != null)
|
||||
mob.addEffectNoTimer(Integer.toString(effectsBase.getUUID()), effectsBase, mbe.getRank(), true);
|
||||
}catch(Exception e){
|
||||
Logger.error("NULL POWER FOR MOB: " + mob.getObjectUUID() + ", POWER TOKEN: " + mbe.getToken());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
public class PlayerBonuses {
|
||||
|
||||
//First bonus set
|
||||
private ConcurrentHashMap<AbstractEffectModifier, Float> bonusFloats = new ConcurrentHashMap<>();
|
||||
ConcurrentHashMap<AbstractEffectModifier, Float> bonusFloats = new ConcurrentHashMap<>();
|
||||
private ConcurrentHashMap<AbstractEffectModifier, DamageShield> bonusDamageShields = new ConcurrentHashMap<>();
|
||||
private ConcurrentHashMap<AbstractEffectModifier, String> bonusStrings = new ConcurrentHashMap<>();
|
||||
private ConcurrentHashMap<ModType, HashSet<SourceType>> bonusLists = new ConcurrentHashMap<>();
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user