forked from MagicBane/Server
Compare commits
282 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 943a4c8926 | |||
| e257f0a591 | |||
| 76bb31be84 | |||
| 15bea0df04 | |||
| 7f3d37e4f7 | |||
| 4c49575bc7 | |||
| a3ffd53f53 | |||
| e6e1cab715 | |||
| 0b5c3c7c9b | |||
| da42e2baf4 | |||
| 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 | |||
| 30488e5da6 | |||
| b7e798a950 | |||
| e999ca3f68 | |||
| 039638c0d8 | |||
| f282504896 | |||
| 0062936ac6 | |||
| 19c41daa86 | |||
| d860b16cfd | |||
| e3b42a8ad9 | |||
| 20bd7a82af | |||
| e607eb8220 | |||
| 38ca49d1a5 | |||
| a21bdfe031 | |||
| f95832b87c | |||
| feff9b3540 | |||
| 78118aa08c | |||
| 3539372437 | |||
| 7c498625bd | |||
| e379016123 | |||
| afa68b840c | |||
| 1926deb7f9 | |||
| 25c1f34c23 | |||
| d0e04e53ad | |||
| e475fb5cc9 | |||
| f72f632cd8 | |||
| 02ea27fc6f | |||
| 5d338bb87c | |||
| f9f08c2886 | |||
| dcc139043d | |||
| 520219404c | |||
| f97991f00d | |||
| 7b7e1c5337 | |||
| 6e66659940 | |||
| 3d83baed78 | |||
| 049b27da96 | |||
| 6bcbe0f633 | |||
| 8c44e39275 | |||
| e36ab1f5d2 | |||
| 865c775f41 | |||
| 198778ba2d | |||
| 215aabdc5f | |||
| 8d92c8be37 | |||
| 93b3ce07f0 | |||
| f9b7c8b851 | |||
| b3cf72abdc | |||
| 65fddd06a9 | |||
| 41f4a8ff58 | |||
| a13d5018b9 | |||
| 2ac3ce5bc8 | |||
| 85514987e7 | |||
| c9eb07b5ba | |||
| 7201b61498 | |||
| 55b3161900 | |||
| 9d5c4424a1 | |||
| d507ba2339 | |||
| 4ec5103454 | |||
| 3e09cd415e | |||
| 1098265145 | |||
| df7a106237 | |||
| 00b38970a1 | |||
| c1004e5817 | |||
| 13e9738345 | |||
| 1a7c1e2544 | |||
| ff082487b5 | |||
| 14cac0d892 | |||
| a8347e0b53 | |||
| a73c3453ea | |||
| a64932b2c9 | |||
| 685297171c | |||
| 2e3e403165 | |||
| fbd910ef50 | |||
| 30129d161f | |||
| a6510af56d | |||
| 9830920635 | |||
| 93025b72cd | |||
| 22639baa4c | |||
| 1aba8dfb11 | |||
| 8b4eb96262 | |||
| cafe6cd2fe | |||
| da6140f6f4 | |||
| 3fc68ce2ff | |||
| 5e8927245b | |||
| 75de1b3ae8 | |||
| 6743114d19 | |||
| 28cca67cb3 | |||
| bad7c6e798 | |||
| ecd3b38d3a | |||
| 8f09f16603 | |||
| 80812cb402 | |||
| 66fbf7aee6 | |||
| a92c603ab2 | |||
| 365438370d | |||
| a40b8fc915 | |||
| 5d92c1c86d | |||
| c526fd8847 | |||
| cd767dc68c | |||
| e21ebc75ee | |||
| 931eaaae4a | |||
| 4d487e6bf0 | |||
| 6c45a6573a | |||
| 45b0dda7d9 | |||
| caf3bc7470 | |||
| 5259b801f7 | |||
| 77e6d0db75 | |||
| b2d7e5ec1e | |||
| 15bc99d216 | |||
| 63c6e2abd7 | |||
| 8ab97a1b36 | |||
| d1aa581879 | |||
| 5f56143c5e | |||
| 1a2b558ac3 | |||
| 4f4ff74bf1 | |||
| ded3b08080 | |||
| 14a29c8612 | |||
| e66e430d30 | |||
| c833f560c1 | |||
| 454c721842 | |||
| 26eda324dc | |||
| 16951d36a2 | |||
| e1d36125d2 | |||
| 7a3c259d2f | |||
| aa5fb2a2c5 | |||
| a92cc6506c | |||
| 3971548142 | |||
| d94de771bf | |||
| c5f47ffcd4 | |||
| b336235ad7 | |||
| eea07309aa | |||
| 5529170036 | |||
| 3d745e93b6 | |||
| 019082bec7 | |||
| 855cceea70 | |||
| 487eae85e1 | |||
| 5d188e61c0 | |||
| 546c335198 | |||
| aaecc5eda2 | |||
| d13e939ddd | |||
| afea79474e | |||
| 05f555b5b5 | |||
| 85931b6dc2 | |||
| 9f0c7f6a76 | |||
| 022c06c803 | |||
| 1b72e7d6b7 | |||
| 666ac6df5b | |||
| 36481a53d9 | |||
| 5a9901d775 | |||
| b3a24d0158 | |||
| 8890826070 | |||
| daa84a1fef | |||
| a4bd47f001 | |||
| d031f1be01 | |||
| a48abc59ce | |||
| 878f05c323 | |||
| d462711d25 | |||
| 40a0120a28 | |||
| ac812eaeae | |||
| 9965223d9b | |||
| 08b99d0d3a | |||
| 519a6a2b1e | |||
| 524f5d470b | |||
| 6631c6a5d7 | |||
| 10f95fb0d9 | |||
| a315366026 | |||
| 1901c9a679 | |||
| 415ad5402f | |||
| 9a40e12dbc | |||
| a1af663796 | |||
| 78b7ddb32a | |||
| 5e5ee4fed1 | |||
| 84c022a39b | |||
| 300741b05a | |||
| dc685a01c6 | |||
| 752f897a34 | |||
| 722cb6b1fd | |||
| 50c095cd09 | |||
| c23546eb46 | |||
| 36340c4e52 | |||
| a7ab38f40c | |||
| 0901c03b74 | |||
| 50817352c1 | |||
| ee4a7447bc | |||
| a6d3c827ad | |||
| d4ea31b91f |
+14
-10
@@ -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;
|
||||
|
||||
@@ -211,8 +209,7 @@ public class Enum {
|
||||
STANDARD(6.1900001f, 13.97f, 4.2199998f, 13.97f, 6.3299999f, 18.379999f, 6.5f),
|
||||
CENTAUR(6.1900001f, 16.940001f, 5.5500002f, 16.940001f, 6.3299999f, 18.379999f, 6.5f),
|
||||
MINOTAUR(6.6300001f, 15.95f, 4.2199998f, 15.95f, 6.3299999f, 18.379999f, 6.5f),
|
||||
IREKEI(6.1900001f, 13.97f, 4.2199998f, 13.97f, 6.3299999f, 18.379999f, 6.5f);
|
||||
|
||||
IREKEI(6.499500105f, 14.6685f, 4.2199998f, 14.6685f, 6.3299999f, 18.379999f, 6.5f);
|
||||
private float walkStandard;
|
||||
private float walkCombat;
|
||||
private float runStandard;
|
||||
@@ -472,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);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -779,6 +779,7 @@ public class Enum {
|
||||
Combat,
|
||||
Spires,
|
||||
Snare,
|
||||
Snared,
|
||||
Stun,
|
||||
Blind,
|
||||
Root,
|
||||
@@ -881,6 +882,7 @@ public class Enum {
|
||||
Siege,
|
||||
Slash,
|
||||
Snare,
|
||||
Snared,
|
||||
Sorcery,
|
||||
Spear,
|
||||
SpearMastery,
|
||||
@@ -1030,6 +1032,7 @@ public class Enum {
|
||||
Silence,
|
||||
Slash,
|
||||
Snare,
|
||||
Snared,
|
||||
Stance,
|
||||
Stun,
|
||||
Summon,
|
||||
@@ -1154,6 +1157,7 @@ public class Enum {
|
||||
SkillDebuff,
|
||||
SlashResistanceDebuff,
|
||||
Snare,
|
||||
Snared,
|
||||
StackableAttrCONBuff,
|
||||
StackableAttrDEXBuff,
|
||||
StackableAttrSTRBuff,
|
||||
|
||||
@@ -19,10 +19,7 @@ import engine.net.AbstractNetMsg;
|
||||
import engine.net.Dispatch;
|
||||
import engine.net.DispatchMessage;
|
||||
import engine.net.client.ClientConnection;
|
||||
import engine.net.client.msg.LoadCharacterMsg;
|
||||
import engine.net.client.msg.LoadStructureMsg;
|
||||
import engine.net.client.msg.MoveToPointMsg;
|
||||
import engine.net.client.msg.UnloadObjectsMsg;
|
||||
import engine.net.client.msg.*;
|
||||
import engine.objects.*;
|
||||
import engine.server.MBServerStatics;
|
||||
import org.pmw.tinylog.Logger;
|
||||
@@ -525,11 +522,6 @@ public enum InterestManager implements Runnable {
|
||||
player.setDirtyLoad(true);
|
||||
updateStaticList(player, origin);
|
||||
updateMobileList(player, origin);
|
||||
if(player.level < 10) {
|
||||
player.setLevel((short) 10);
|
||||
player.getCharItemManager().addGoldToInventory(1000,false);
|
||||
player.getCharItemManager().addItemToInventory(new MobLoot(player,ItemBase.getItemBase(980066),1,false).promoteToItem(player));
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void HandleLoadForTeleport(PlayerCharacter playerCharacter) {
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
package engine.QuestSystem;
|
||||
|
||||
import engine.InterestManagement.WorldGrid;
|
||||
import engine.gameManager.ChatManager;
|
||||
import engine.net.client.msg.ErrorPopupMsg;
|
||||
import engine.objects.*;
|
||||
import engine.server.MBServerStatics;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Random;
|
||||
|
||||
public class QuestManager {
|
||||
public static HashMap<PlayerCharacter,QuestObject> acceptedQuests = new HashMap<>();
|
||||
public static HashMap<PlayerCharacter,ArrayList<String>> completedQuests = new HashMap<>();
|
||||
|
||||
public static boolean grantsQuest(NPC npc){
|
||||
if(npc == null)
|
||||
return false;
|
||||
|
||||
if(npc.contract == null)
|
||||
return false;
|
||||
|
||||
return npc.contract.getName().contains("ZoneLore") || npc.contract.getName().equals("Barrowlands Sentry");
|
||||
}
|
||||
|
||||
public static void displayCurrentQuest(PlayerCharacter pc){
|
||||
if(acceptedQuests.containsKey(pc)){
|
||||
QuestObject obj = acceptedQuests.get(pc);
|
||||
String output = "You have embarked on the noble quest: ";
|
||||
output += obj.QuestName + ". ";
|
||||
output += obj.description;
|
||||
output += ". " + obj.objectiveCount + " / " + obj.objectiveCountRequired;
|
||||
ErrorPopupMsg.sendErrorMsg(pc, output);
|
||||
}else{
|
||||
ErrorPopupMsg.sendErrorMsg(pc, "You have no active quest.");
|
||||
}
|
||||
}
|
||||
|
||||
public static void acceptQuest(PlayerCharacter pc, QuestObject obj){
|
||||
if (completedQuests.containsKey(pc)) {
|
||||
if(completedQuests.get(pc).contains(obj.QuestName)){
|
||||
ErrorPopupMsg.sendErrorMsg(pc, "You have already completed the quest: " + obj.QuestName);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(acceptedQuests.containsKey(pc)){
|
||||
if(acceptedQuests.get(pc)!= null){
|
||||
ErrorPopupMsg.sendErrorMsg(pc, "You have already embarked on a noble quest.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
acceptedQuests.put(pc,obj);
|
||||
displayCurrentQuest(pc);
|
||||
}
|
||||
|
||||
public static void completeQuest(PlayerCharacter pc, QuestObject obj){
|
||||
|
||||
if(obj.objectiveCount < obj.objectiveCountRequired) {
|
||||
ChatManager.chatSystemInfo(pc, obj.QuestName + " Progress: " + obj.objectiveCount + " / " + obj.objectiveCountRequired);
|
||||
return;
|
||||
}
|
||||
|
||||
//notify the player they have completed their quest
|
||||
ErrorPopupMsg.sendErrorMsg(pc, "You have completed the quest: " + obj.QuestName +"!");
|
||||
|
||||
//add completed quest to completion log
|
||||
if (completedQuests.containsKey(pc)) {
|
||||
completedQuests.get(pc).add(obj.QuestName);
|
||||
}else{
|
||||
ArrayList<String> completed = new ArrayList<>();
|
||||
completed.add(obj.QuestName);
|
||||
completedQuests.put(pc,completed);
|
||||
}
|
||||
|
||||
//remove current quest from active log
|
||||
if(acceptedQuests.containsKey(pc))
|
||||
acceptedQuests.remove(pc);
|
||||
|
||||
//grant rewards
|
||||
//only grant XP if level is below 75
|
||||
if(pc.level < 75) {
|
||||
int xpGrant = (int) (Experience.maxXPPerKill(pc.getLevel()) * 10);
|
||||
pc.grantXP(xpGrant);
|
||||
ChatManager.chatSystemInfo(pc, "Your Quest Has Granted you: " + xpGrant + " Experience Points");
|
||||
}
|
||||
|
||||
int goldGrant = (int) Experience.maxXPPerKill(pc.getLevel());
|
||||
pc.getCharItemManager().addGoldToInventory(goldGrant,false);
|
||||
ChatManager.chatSystemInfo(pc, "Your Quest Has Granted you: " + goldGrant + " Gold Coins");
|
||||
|
||||
pc.getCharItemManager().updateInventory();
|
||||
}
|
||||
|
||||
public static QuestObject getQuestForContract(NPC npc){
|
||||
QuestObject obj = new QuestObject();
|
||||
obj.QuestName = npc.getFirstName() + "'s Quest";
|
||||
|
||||
HashSet<AbstractWorldObject> mobs = WorldGrid.getObjectsInRangePartial(npc.loc,2048, MBServerStatics.MASK_MOB);
|
||||
if (mobs.isEmpty())
|
||||
return null; // Handle the case where the set is empty
|
||||
|
||||
// Convert HashSet to a List
|
||||
ArrayList<AbstractWorldObject> mobList = new ArrayList<>(mobs);
|
||||
|
||||
Mob mob = null;
|
||||
|
||||
while(mob == null || Mob.discDroppers.contains(mob)) {
|
||||
// Generate a random index
|
||||
Random random = new Random();
|
||||
int randomIndex = random.nextInt(mobList.size());
|
||||
|
||||
if (mobList.get(randomIndex) == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
mob = (Mob) mobList.get(randomIndex);
|
||||
}
|
||||
obj.progressionNames = new ArrayList<>();
|
||||
obj.progressionNames.add(mob.getFirstName());
|
||||
|
||||
obj.objectiveCountRequired = 10;
|
||||
obj.objectiveCount = 0;
|
||||
|
||||
obj.description = "These lands are plagued with " + mob.getFirstName() + " complete the quest by slaying 10 of them!";
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package engine.QuestSystem;
|
||||
|
||||
import engine.objects.ItemBase;
|
||||
import engine.objects.NPC;
|
||||
import engine.objects.PlayerCharacter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class QuestObject {
|
||||
|
||||
public String QuestName;
|
||||
public String description;
|
||||
public int objectiveCount;
|
||||
public int objectiveCountRequired;
|
||||
public ArrayList<String> progressionNames;
|
||||
public PlayerCharacter owner;
|
||||
|
||||
public QuestObject(){
|
||||
|
||||
}
|
||||
public void tryProgress(String option){
|
||||
if(this.progressionNames.contains(option))
|
||||
this.objectiveCount++;
|
||||
else
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -10,17 +10,13 @@
|
||||
package engine.db.handlers;
|
||||
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.objects.Bane;
|
||||
import engine.objects.Building;
|
||||
import engine.objects.City;
|
||||
import engine.objects.PlayerCharacter;
|
||||
import engine.gameManager.ZoneManager;
|
||||
import engine.math.Vector3fImmutable;
|
||||
import engine.objects.*;
|
||||
import org.joda.time.DateTime;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.*;
|
||||
|
||||
public class dbBaneHandler extends dbHandlerBase {
|
||||
|
||||
@@ -89,6 +85,139 @@ public class dbBaneHandler extends dbHandlerBase {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean SET_BANE_TIME_NEW(int hour, int cityUUID) {
|
||||
hour += 12; // Adjust hour
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement getStatement = connection.prepareStatement("SELECT `placementDate`, `liveDate` FROM `dyn_banes` WHERE `cityUUID`=?");
|
||||
PreparedStatement updateStatement = connection.prepareStatement("UPDATE `dyn_banes` SET `liveDate`=?, `time_set`=? WHERE `cityUUID`=?")) {
|
||||
|
||||
// Retrieve placementDate and liveDate
|
||||
getStatement.setInt(1, cityUUID);
|
||||
try (ResultSet rs = getStatement.executeQuery()) {
|
||||
if (rs.next()) {
|
||||
DateTime placementDate = new DateTime(rs.getTimestamp("placementDate").getTime());
|
||||
Timestamp liveDateTimestamp = rs.getTimestamp("liveDate");
|
||||
|
||||
// Explicitly check if liveDate is null
|
||||
DateTime toSet;
|
||||
if (liveDateTimestamp == null) {
|
||||
// If liveDate is null, default to placementDate
|
||||
toSet = placementDate;
|
||||
} else {
|
||||
// If liveDate is not null, use it
|
||||
DateTime liveDate = new DateTime(liveDateTimestamp.getTime());
|
||||
toSet = liveDate;
|
||||
}
|
||||
|
||||
// Adjust the time
|
||||
toSet = toSet.withHourOfDay(hour).withMinuteOfHour(0).withSecondOfMinute(0).withMillisOfSecond(0);
|
||||
|
||||
// Update liveDate and time_set flag
|
||||
updateStatement.setTimestamp(1, new java.sql.Timestamp(toSet.getMillis()));
|
||||
updateStatement.setInt(2, 1); // time_set flag
|
||||
updateStatement.setInt(3, cityUUID);
|
||||
|
||||
updateStatement.execute();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
} catch (SQLException e) {
|
||||
Logger.error(e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean SET_BANE_DAY_NEW(int dayOffset, int cityUUID) {
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement getStatement = connection.prepareStatement("SELECT `placementDate`, `liveDate` FROM `dyn_banes` WHERE `cityUUID`=?");
|
||||
PreparedStatement updateStatement = connection.prepareStatement("UPDATE `dyn_banes` SET `liveDate`=?, `day_set`=? WHERE `cityUUID`=?")) {
|
||||
|
||||
// Retrieve placementDate and liveDate
|
||||
getStatement.setInt(1, cityUUID);
|
||||
try (ResultSet rs = getStatement.executeQuery()) {
|
||||
if (rs.next()) {
|
||||
DateTime placementDate = new DateTime(rs.getTimestamp("placementDate").getTime());
|
||||
Timestamp liveDateTimestamp = rs.getTimestamp("liveDate");
|
||||
|
||||
// Explicitly check if liveDate is null
|
||||
DateTime liveDate;
|
||||
if (liveDateTimestamp == null) {
|
||||
// If liveDate is null, default to placementDate
|
||||
liveDate = placementDate;
|
||||
} else {
|
||||
// If liveDate is not null, use it
|
||||
liveDate = new DateTime(liveDateTimestamp.getTime());
|
||||
}
|
||||
|
||||
// Calculate the new liveDate while preserving the time component
|
||||
DateTime updatedDate = placementDate.plusDays(dayOffset)
|
||||
.withHourOfDay(liveDate.getHourOfDay())
|
||||
.withMinuteOfHour(liveDate.getMinuteOfHour())
|
||||
.withSecondOfMinute(liveDate.getSecondOfMinute())
|
||||
.withMillisOfSecond(liveDate.getMillisOfSecond());
|
||||
|
||||
// Update liveDate and day_set flag
|
||||
updateStatement.setTimestamp(1, new java.sql.Timestamp(updatedDate.getMillis()));
|
||||
updateStatement.setInt(2, 1); // day_set flag
|
||||
updateStatement.setInt(3, cityUUID);
|
||||
|
||||
updateStatement.execute();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
} catch (SQLException e) {
|
||||
Logger.error(e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public boolean SET_BANE_CAP_NEW(int count, int cityUUID) {
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE `dyn_banes` SET `cap_size`=? WHERE `cityUUID`=?")) {
|
||||
|
||||
preparedStatement.setInt(1, count);
|
||||
preparedStatement.setLong(2, cityUUID);
|
||||
|
||||
preparedStatement.execute();
|
||||
|
||||
} catch (SQLException e) {
|
||||
Logger.error(e);
|
||||
return false;
|
||||
}
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE `dyn_banes` SET `cap_set`=? WHERE `cityUUID`=?")) {
|
||||
|
||||
preparedStatement.setInt(1, 1);
|
||||
preparedStatement.setLong(2, cityUUID);
|
||||
|
||||
preparedStatement.execute();
|
||||
|
||||
} catch (SQLException e) {
|
||||
Logger.error(e);
|
||||
return false;
|
||||
}
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE `dyn_banes` SET `cap_size`=? WHERE `cityUUID`=?")) {
|
||||
|
||||
preparedStatement.setInt(1, count);
|
||||
preparedStatement.setLong(2, cityUUID);
|
||||
|
||||
preparedStatement.execute();
|
||||
|
||||
} catch (SQLException e) {
|
||||
Logger.error(e);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean REMOVE_BANE(Bane bane) {
|
||||
|
||||
if (bane == null)
|
||||
@@ -107,4 +236,25 @@ public class dbBaneHandler extends dbHandlerBase {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public DateTime getLiveDate(int cityUUID) {
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement statement = connection.prepareStatement("SELECT `liveDate` FROM `dyn_banes` WHERE `cityUUID`=?")) {
|
||||
|
||||
statement.setInt(1, cityUUID);
|
||||
|
||||
try (ResultSet rs = statement.executeQuery()) {
|
||||
if (rs.next()) {
|
||||
Timestamp liveDateTimestamp = rs.getTimestamp("liveDate");
|
||||
if (liveDateTimestamp != null) {
|
||||
return new DateTime(liveDateTimestamp.getTime());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch (SQLException e) {
|
||||
Logger.error(e);
|
||||
}
|
||||
return null; // Return null if liveDate is not found or an error occurs
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,32 +98,54 @@ public class dbContractHandler extends dbHandlerBase {
|
||||
|
||||
public void LOAD_SELL_LIST_FOR_CONTRACT(final Contract contract) {
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_npc_contract_selltype` WHERE `contractID` = ?;")) {
|
||||
if(!contract.getName().contains("Sage")) {
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_npc_contract_selltype` WHERE `contractID` = ?;")) {
|
||||
|
||||
preparedStatement.setInt(1, contract.getObjectUUID());
|
||||
preparedStatement.setInt(1, contract.getObjectUUID());
|
||||
|
||||
ResultSet rs = preparedStatement.executeQuery();
|
||||
ResultSet rs = preparedStatement.executeQuery();
|
||||
|
||||
while (rs.next()) {
|
||||
while (rs.next()) {
|
||||
|
||||
int type = rs.getInt("type");
|
||||
int value = rs.getInt("value");
|
||||
int type = rs.getInt("type");
|
||||
int value = rs.getInt("value");
|
||||
|
||||
switch (type) {
|
||||
case 1:
|
||||
contract.getBuyItemType().add(value);
|
||||
break;
|
||||
case 2:
|
||||
contract.getBuySkillToken().add(value);
|
||||
break;
|
||||
case 3:
|
||||
contract.getBuyUnknownToken().add(value);
|
||||
break;
|
||||
switch (type) {
|
||||
case 1:
|
||||
contract.getBuyItemType().add(value);
|
||||
break;
|
||||
case 2:
|
||||
contract.getBuySkillToken().add(value);
|
||||
break;
|
||||
case 3:
|
||||
contract.getBuyUnknownToken().add(value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
Logger.error(e);
|
||||
}
|
||||
}else{
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_npc_contract_selltype`;")) {
|
||||
|
||||
ResultSet rs = preparedStatement.executeQuery();
|
||||
|
||||
while (rs.next()) {
|
||||
int value = rs.getInt("value");
|
||||
if(!contract.getBuySkillToken().contains(value))
|
||||
contract.getBuySkillToken().add(value);
|
||||
|
||||
if(!contract.getBuyItemType().contains(value))
|
||||
contract.getBuyItemType().add(value);
|
||||
|
||||
if(!contract.getBuyUnknownToken().contains(value))
|
||||
contract.getBuyUnknownToken().add(value);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
Logger.error(e);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
Logger.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -56,6 +56,13 @@ public abstract class dbHandlerBase {
|
||||
while (rs.next()) {
|
||||
|
||||
int id = rs.getInt(1);
|
||||
try {
|
||||
if (rs.getInt("capSize") == 0) {
|
||||
continue;
|
||||
}
|
||||
}catch(Exception e){
|
||||
//not a mine
|
||||
}
|
||||
|
||||
if (DbManager.inCache(localObjectType, id)) {
|
||||
objectList.add((T) DbManager.getFromCache(localObjectType, id));
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -131,6 +131,32 @@ public class dbNPCHandler extends dbHandlerBase {
|
||||
return npc;
|
||||
}
|
||||
|
||||
public int BANE_COMMANDER_EXISTS(final int objectUUID) {
|
||||
|
||||
int uid = 0;
|
||||
|
||||
String query = "SELECT `UID` FROM `obj_npc` WHERE `npc_buildingID` = ? LIMIT 1;";
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement(query)) {
|
||||
|
||||
preparedStatement.setInt(1, objectUUID);
|
||||
|
||||
try (ResultSet rs = preparedStatement.executeQuery()) {
|
||||
if (rs.next()) {
|
||||
// Retrieve the UID column value
|
||||
uid = rs.getInt("UID");
|
||||
}
|
||||
}
|
||||
|
||||
} catch (SQLException e) {
|
||||
Logger.error(e);
|
||||
}
|
||||
|
||||
return uid;
|
||||
}
|
||||
|
||||
|
||||
public int MOVE_NPC(long npcID, long parentID, float locX, float locY, float locZ) {
|
||||
|
||||
int rowCount;
|
||||
@@ -176,6 +202,18 @@ public class dbNPCHandler extends dbHandlerBase {
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void updateSpecialPricing(final NPC npc){
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE obj_npc SET specialPrice=? WHERE UID = ?")) {
|
||||
preparedStatement.setInt(1, npc.getSpecialPrice());
|
||||
preparedStatement.setInt(2, npc.getDBID());
|
||||
|
||||
preparedStatement.executeUpdate();
|
||||
|
||||
} catch (SQLException e) {
|
||||
Logger.error(e);
|
||||
}
|
||||
}
|
||||
public void updateDatabase(final NPC npc) {
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
|
||||
@@ -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;
|
||||
@@ -493,13 +497,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() + " " + eb.getIDString() + 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 +537,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);
|
||||
|
||||
@@ -54,6 +54,7 @@ public class SimulateBootyCmd extends AbstractDevCmd {
|
||||
ArrayList<Item> Resources = new ArrayList<Item>();
|
||||
ArrayList<Item> Runes = new ArrayList<Item>();
|
||||
ArrayList<Item> Contracts = new ArrayList<Item>();
|
||||
ArrayList<Item> GuardContracts = new ArrayList<Item>();
|
||||
ArrayList<Item> Offerings = new ArrayList<Item>();
|
||||
ArrayList<Item> OtherDrops = new ArrayList<Item>();
|
||||
ArrayList<Item> EquipmentDrops = new ArrayList<Item>();
|
||||
@@ -68,7 +69,10 @@ public class SimulateBootyCmd extends AbstractDevCmd {
|
||||
for (Item lootItem : mob.getCharItemManager().getInventory()) {
|
||||
switch (lootItem.getItemBase().getType()) {
|
||||
case CONTRACT: //CONTRACT
|
||||
Contracts.add(lootItem);
|
||||
if(lootItem.getName().contains("Captain"))
|
||||
GuardContracts.add(lootItem);
|
||||
else
|
||||
Contracts.add(lootItem);
|
||||
break;
|
||||
case OFFERING: //OFFERING
|
||||
Offerings.add(lootItem);
|
||||
@@ -140,9 +144,17 @@ public class SimulateBootyCmd extends AbstractDevCmd {
|
||||
}
|
||||
}
|
||||
|
||||
int baseBound = 100000;
|
||||
int levelPenalty = (int) (Math.max(0, Math.abs(50 - mob.level)) * 0.01 * 100000);
|
||||
int totalRange = baseBound + levelPenalty;
|
||||
if(mob.level >= 50){
|
||||
totalRange = baseBound;
|
||||
}
|
||||
output += "TOTAL ROLL POTENTIAL: " + totalRange + newline;
|
||||
output += "GLASS DROPS: " + GlassItems.size() + newline;
|
||||
output += "RUNE DROPS: " + Runes.size() + newline;
|
||||
output += "CONTRACTS DROPS: " + Contracts.size() + newline;
|
||||
output += "GUARD CONTRACTS DROPS: " + GuardContracts.size() + newline;
|
||||
output += "RESOURCE DROPS: " + Resources.size() + newline;
|
||||
output += "OFFERINGS DROPPED: " + Offerings.size() + newline;
|
||||
output += "ENCHANTED ITEMS DROPPED: " + OtherDrops.size() + newline;
|
||||
|
||||
@@ -0,0 +1,168 @@
|
||||
package engine.gameManager;
|
||||
|
||||
import engine.Enum;
|
||||
import engine.InterestManagement.WorldGrid;
|
||||
import engine.exception.MsgSendException;
|
||||
import engine.math.Vector3f;
|
||||
import engine.math.Vector3fImmutable;
|
||||
import engine.objects.*;
|
||||
import engine.server.MBServerStatics;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
public class ArenaManager {
|
||||
private static final List<Arena> activeArenas = new ArrayList<>();
|
||||
public static final List<PlayerCharacter> playerQueue = new ArrayList<>();
|
||||
public static Long pulseDelay = 180000L;
|
||||
public static Long lastExecution = 0L;
|
||||
|
||||
public static void pulseArenas() {
|
||||
if(lastExecution == 0L){
|
||||
lastExecution = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
if(activeArenas.isEmpty() && playerQueue.isEmpty())
|
||||
return;
|
||||
|
||||
Iterator<Arena> iterator = activeArenas.iterator();
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
Arena arena = iterator.next();
|
||||
if (arena.checkToComplete()) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
|
||||
if(lastExecution + pulseDelay > System.currentTimeMillis())
|
||||
return;
|
||||
|
||||
lastExecution = System.currentTimeMillis();
|
||||
|
||||
while (playerQueue.size() > 1) {
|
||||
createArena();
|
||||
}
|
||||
}
|
||||
|
||||
public static void joinQueue(PlayerCharacter player) {
|
||||
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() {
|
||||
if (playerQueue.size() > 1) {
|
||||
|
||||
Collections.shuffle(playerQueue);
|
||||
Arena newArena = new Arena();
|
||||
|
||||
//set starting time
|
||||
newArena.startTime = System.currentTimeMillis();
|
||||
|
||||
//decide an arena location
|
||||
newArena.loc = selectRandomArenaLocation();
|
||||
|
||||
// Assign players to the arena
|
||||
newArena.player1 = playerQueue.remove(0);
|
||||
newArena.player2 = playerQueue.remove(0);
|
||||
|
||||
// Teleport players to the arena location
|
||||
Zone sdr = ZoneManager.getZoneByUUID(656);
|
||||
MovementManager.translocate(newArena.player1, Vector3fImmutable.getRandomPointOnCircle(newArena.loc,75f), null);
|
||||
MovementManager.translocate(newArena.player2, Vector3fImmutable.getRandomPointOnCircle(newArena.loc,75f), null);
|
||||
|
||||
// Add the new arena to the active arenas list
|
||||
activeArenas.add(newArena);
|
||||
}
|
||||
}
|
||||
|
||||
public static void endArena(Arena arena, PlayerCharacter winner, PlayerCharacter loser, String condition){
|
||||
if (winner != null && loser != null) {
|
||||
Logger.info("[ARENA] The fight between {} and {} is concluded. Victor: {}",
|
||||
arena.player1.getName(), arena.player2.getName(), winner.getName());
|
||||
} else {
|
||||
Logger.info("[ARENA] The fight between {} and {} is concluded. No Winner Declared.",
|
||||
arena.player1.getName(), arena.player2.getName());
|
||||
}
|
||||
// Teleport players to the arena location
|
||||
Zone sdr = ZoneManager.getZoneByUUID(656);
|
||||
MovementManager.translocate(arena.player1, Vector3fImmutable.getRandomPointOnCircle(sdr.getLoc(),50f), null);
|
||||
MovementManager.translocate(arena.player2, Vector3fImmutable.getRandomPointOnCircle(sdr.getLoc(),50f), null);
|
||||
|
||||
|
||||
|
||||
activeArenas.remove(arena);
|
||||
|
||||
if(winner != null){
|
||||
ChatManager.chatPVP("[ARENA] " + winner.getName() + " has slain " + loser.getName() + " in the arena!");
|
||||
//handle prize distribution
|
||||
//ItemBase specialLoot = ItemBase.getItemBase(866);
|
||||
//Item promoted = new MobLoot(winner, specialLoot, 1, false).promoteToItem(winner);
|
||||
//promoted.setNumOfItems(21235);
|
||||
//promoted.setName("Special Banker(21235)");
|
||||
//DbManager.ItemQueries.UPDATE_NUM_ITEMS(promoted,21235);
|
||||
//winner.getCharItemManager().addItemToInventory(promoted);
|
||||
//winner.getCharItemManager().updateInventory();
|
||||
}
|
||||
}
|
||||
|
||||
public static Vector3fImmutable selectRandomArenaLocation() {
|
||||
boolean locSet = false;
|
||||
Vector3fImmutable loc = Vector3fImmutable.ZERO;
|
||||
|
||||
while (!locSet) {
|
||||
try {
|
||||
float x = ThreadLocalRandom.current().nextInt(114300, 123600);
|
||||
float z = ThreadLocalRandom.current().nextInt(82675, 91700);
|
||||
float y = 0; // Y coordinate is always 0
|
||||
|
||||
loc = new Vector3fImmutable(x, y, z * -1);
|
||||
HashSet<AbstractWorldObject> inRange = WorldGrid.getObjectsInRangePartial(loc,500f, MBServerStatics.MASK_PLAYER);
|
||||
if(inRange.isEmpty() && !isUnderWater(loc))
|
||||
locSet = true;
|
||||
//}
|
||||
}catch(Exception e){
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return loc;
|
||||
}
|
||||
|
||||
public static boolean isUnderWater(Vector3fImmutable loc) {
|
||||
|
||||
try {
|
||||
|
||||
Zone zone = ZoneManager.findSmallestZone(loc);
|
||||
|
||||
if (zone.getSeaLevel() != 0) {
|
||||
|
||||
float localAltitude = loc.y;
|
||||
if (localAltitude < zone.getSeaLevel())
|
||||
return true;
|
||||
} else {
|
||||
if (loc.y < 0)
|
||||
return true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -438,6 +438,18 @@ public enum BuildingManager {
|
||||
|
||||
public static boolean IsPlayerHostile(Building building, PlayerCharacter player) {
|
||||
|
||||
if(building.getBlueprint() != null && building.getBlueprint().getBuildingGroup() != null && building.getBlueprint().getBuildingGroup().equals(BuildingGroup.BANESTONE))
|
||||
{
|
||||
Guild playerNation = player.guild.getNation();
|
||||
City banedCity = ZoneManager.getCityAtLocation(building.loc);
|
||||
if(banedCity != null){
|
||||
if(banedCity.getGuild().getNation().equals(playerNation)){
|
||||
return false;
|
||||
}else{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
//Nation Members and Guild members are not hostile.
|
||||
// if (building.getGuild() != null){
|
||||
// if (pc.getGuild() != null)
|
||||
|
||||
@@ -14,6 +14,7 @@ import engine.Enum.GameObjectType;
|
||||
import engine.Enum.ModType;
|
||||
import engine.Enum.SourceType;
|
||||
import engine.InterestManagement.WorldGrid;
|
||||
import engine.QuestSystem.QuestManager;
|
||||
import engine.db.archive.BaneRecord;
|
||||
import engine.db.archive.PvpRecord;
|
||||
import engine.net.Dispatch;
|
||||
@@ -108,9 +109,9 @@ public enum ChatManager {
|
||||
ChatManager.chatIC(pc, (ChatICMsg) msg);
|
||||
return;
|
||||
case LEADERCHANNELMESSAGE:
|
||||
case GLOBALCHANNELMESSAGE:
|
||||
ChatManager.chatGlobal(pc, msg.getMessage(), isFlood);
|
||||
return;
|
||||
case GLOBALCHANNELMESSAGE:
|
||||
case CHATPVP:
|
||||
case CHATCITY:
|
||||
case CHATINFO:
|
||||
@@ -199,6 +200,11 @@ public enum ChatManager {
|
||||
return;
|
||||
}
|
||||
|
||||
if(text.equalsIgnoreCase("show_quest()")){
|
||||
QuestManager.displayCurrentQuest(pcSender);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ChatManager.isVersionRequest(text) == true) {
|
||||
sendSystemMessage(pcSender, ConfigManager.MB_WORLD_GREETING.getValue());
|
||||
return;
|
||||
|
||||
@@ -662,9 +662,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 +692,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 +713,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -916,7 +927,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);
|
||||
}
|
||||
@@ -1242,14 +1259,17 @@ public enum CombatManager {
|
||||
DispatchMessage.dispatchMsgToInterestArea(pc, rwss, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, false, false);
|
||||
}
|
||||
|
||||
private static void toggleSit(boolean toggle, ClientConnection origin) {
|
||||
public static void toggleSit(boolean toggle, ClientConnection origin) {
|
||||
|
||||
PlayerCharacter pc = SessionManager.getPlayerCharacter(origin);
|
||||
|
||||
if (pc == null)
|
||||
return;
|
||||
|
||||
pc.setSit(toggle);
|
||||
if(pc.isFlying())
|
||||
pc.setSit(false);
|
||||
else
|
||||
pc.setSit(toggle);
|
||||
|
||||
UpdateStateMsg rwss = new UpdateStateMsg();
|
||||
rwss.setPlayer(pc);
|
||||
@@ -1327,6 +1347,13 @@ public enum CombatManager {
|
||||
return;
|
||||
|
||||
retaliater.setCombatTarget(ac);
|
||||
if(retaliater.isPlayerGuard && (retaliater.BehaviourType.equals(MobBehaviourType.GuardMinion) || retaliater.BehaviourType.equals(MobBehaviourType.GuardCaptain))){
|
||||
for(Mob guard : retaliater.guardedCity.getParent().zoneMobSet){
|
||||
if(guard.isPlayerGuard && guard.combatTarget == null){
|
||||
guard.setCombatTarget(ac);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1443,19 +1470,28 @@ public enum CombatManager {
|
||||
((AbstractCharacter) awo).getCharItemManager().damageRandomArmor(1);
|
||||
}
|
||||
|
||||
public static boolean LandHit(int atr, int defense){
|
||||
public static boolean LandHit(int C5, int D5){
|
||||
|
||||
float chance = (C5-((C5+D5)*.315f)) / ((D5-((C5+D5)*.315f)) + (C5-((C5+D5)*.315f)));
|
||||
int convertedChance = Math.round(chance * 100);
|
||||
//convertedChance = Math.max(5, Math.min(95, convertedChance));
|
||||
|
||||
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 ot miss
|
||||
return false;
|
||||
|
||||
if(connvertedChance < 5)
|
||||
connvertedChance = 5;
|
||||
return roll <= convertedChance;
|
||||
}
|
||||
|
||||
if(connvertedChance > 95)
|
||||
connvertedChance = 95;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,6 +65,7 @@ public enum ConfigManager {
|
||||
MB_WORLD_MAINTENANCE,
|
||||
MB_WORLD_GREETING,
|
||||
MB_WORLD_KEYCLONE_MAX,
|
||||
MB_WORLD_TESTMODE,
|
||||
MB_USE_RUINS,
|
||||
|
||||
// Mobile AI modifiers
|
||||
|
||||
@@ -180,16 +180,20 @@ public enum DevCmdManager {
|
||||
//kill any commands not available to everyone on production server
|
||||
//only admin level can run dev commands on production
|
||||
boolean playerAllowed = false;
|
||||
switch(adc.getMainCmdString()){
|
||||
case "printresists":
|
||||
case "printstats":
|
||||
case "printskills":
|
||||
case "printpowers":
|
||||
case "gimme":
|
||||
playerAllowed = true;
|
||||
if(!a.status.equals(Enum.AccountStatus.ADMIN))
|
||||
target = pcSender;
|
||||
break;
|
||||
if(ConfigManager.MB_WORLD_TESTMODE.getValue().equals("true")) {
|
||||
switch (adc.getMainCmdString()) {
|
||||
case "printresists":
|
||||
case "printstats":
|
||||
case "printskills":
|
||||
case "printpowers":
|
||||
case "gimme":
|
||||
case "goto":
|
||||
case "teleportmode":
|
||||
playerAllowed = true;
|
||||
if (!a.status.equals(Enum.AccountStatus.ADMIN))
|
||||
target = pcSender;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!playerAllowed && !a.status.equals(Enum.AccountStatus.ADMIN)) {
|
||||
Logger.info("Account " + a.getUname() + "attempted to use dev command " + cmd);
|
||||
|
||||
@@ -40,6 +40,7 @@ public enum LootManager {
|
||||
public static final ArrayList<Integer> vorg_ma_uuids = new ArrayList<>(Arrays.asList(27570,188900,188910,188920,188930,188940,188950,189500));
|
||||
public static final ArrayList<Integer> vorg_la_uuids = new ArrayList<>(Arrays.asList(27550,27560,189100,189110,189120,189130,189140,189150));
|
||||
public static final ArrayList<Integer> vorg_cloth_uuids = new ArrayList<>(Arrays.asList(27600,188700,188720,189550,189560));
|
||||
public static final ArrayList<Integer> racial_guard_uuids = new ArrayList<>(Arrays.asList(841,951,952,1050,1052,1180,1182,1250,1252,1350,1352,1450,1452,1500,1502,1525,1527,1550,1552,1575,1577,1600,1602,1650,1652,1700,980100,980102));
|
||||
|
||||
// Drop Rates
|
||||
|
||||
@@ -74,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;
|
||||
|
||||
@@ -125,36 +131,70 @@ public enum LootManager {
|
||||
boolean hotzoneWasRan = false;
|
||||
float dropRate;
|
||||
|
||||
if(!mob.getSafeZone()) {
|
||||
int specialCaseRoll = ThreadLocalRandom.current().nextInt(1, 100000);
|
||||
//Special Case Contract Drop
|
||||
if(specialCaseRoll < 100){
|
||||
SpecialCaseResourceDrop(mob,entries);
|
||||
} else if(specialCaseRoll > 100 && specialCaseRoll < 500){
|
||||
SpecialCaseContractDrop(mob,entries);
|
||||
}else if(specialCaseRoll > 500 && specialCaseRoll < 900){
|
||||
SpecialCaseRuneDrop(mob,entries);
|
||||
} else if(specialCaseRoll > 900 && specialCaseRoll < 910){
|
||||
if (!mob.getSafeZone()) {
|
||||
int contractLow = 1, contractHigh = 400;
|
||||
int runeLow = 401, runeHigh = 800;
|
||||
int resourceLow = 801, resourceHigh = 900;
|
||||
int glassLow = 901, glassHigh = 910;
|
||||
int guardLow = 911, guardHigh = 920;
|
||||
|
||||
// Pre-compute adjusted high values
|
||||
int contractAdjust = 0, runeAdjust = 0, resourceAdjust = 0, glassAdjust = 0, guardAdjust = 0;
|
||||
if (mob.level < 50) {
|
||||
int dif = 50 - mob.level;
|
||||
contractAdjust = (int)(400 * (dif * 0.02f));
|
||||
runeAdjust = (int)(400 * (dif * 0.02f));
|
||||
resourceAdjust = (int)(100 * (dif * 0.02f));
|
||||
glassAdjust = (int)(10 * (dif * 0.02f));
|
||||
guardAdjust = (int)(10 * (dif * 0.02f));
|
||||
}
|
||||
|
||||
// Generate a single random roll
|
||||
int specialCaseRoll = ThreadLocalRandom.current().nextInt(1, 100001);
|
||||
|
||||
// Calculate adjusted high values once
|
||||
int contractHighAdjusted = contractHigh - contractAdjust;
|
||||
int runeHighAdjusted = runeHigh - runeAdjust;
|
||||
int resourceHighAdjusted = resourceHigh - resourceAdjust;
|
||||
int glassHighAdjusted = glassHigh - glassAdjust;
|
||||
int guardHighAdjusted = guardHigh - guardAdjust;
|
||||
|
||||
// Check the roll range and handle accordingly
|
||||
if (specialCaseRoll >= contractLow && specialCaseRoll <= contractHighAdjusted) {
|
||||
SpecialCaseContractDrop(mob, entries);
|
||||
} else if (specialCaseRoll >= runeLow && specialCaseRoll <= runeHighAdjusted) {
|
||||
SpecialCaseRuneDrop(mob, entries);
|
||||
} else if (specialCaseRoll >= resourceLow && specialCaseRoll <= resourceHighAdjusted) {
|
||||
SpecialCaseResourceDrop(mob, entries);
|
||||
} else if (specialCaseRoll >= glassLow && specialCaseRoll <= glassHighAdjusted) {
|
||||
int glassID = rollRandomItem(126);
|
||||
ItemBase glassItem = ItemBase.getItemBase(glassID);
|
||||
if (glassItem != null) {
|
||||
MobLoot toAddGlass = new MobLoot(mob, glassItem, false);
|
||||
|
||||
if (toAddGlass != null)
|
||||
mob.getCharItemManager().addItemToInventory(toAddGlass);
|
||||
mob.getCharItemManager().addItemToInventory(toAddGlass);
|
||||
}
|
||||
} else if (specialCaseRoll >= guardLow && specialCaseRoll <= guardHighAdjusted) {
|
||||
int guardContractID = racial_guard_uuids.get(new java.util.Random().nextInt(racial_guard_uuids.size()));
|
||||
ItemBase guardContract = ItemBase.getItemBase(guardContractID);
|
||||
if (guardContract != null) {
|
||||
MobLoot toAddContract = new MobLoot(mob, guardContract, false);
|
||||
mob.getCharItemManager().addItemToInventory(toAddContract);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 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;
|
||||
|
||||
@@ -122,9 +122,9 @@ public enum MaintenanceManager {
|
||||
|
||||
|
||||
//no maintenance if day of week doesnt match
|
||||
if (LocalDateTime.now().getDayOfWeek().ordinal() != building.maintDateTime.getDayOfWeek().ordinal()) {
|
||||
continue;
|
||||
}
|
||||
//if (LocalDateTime.now().getDayOfWeek().ordinal() != building.maintDateTime.getDayOfWeek().ordinal()) {
|
||||
// continue;
|
||||
//}
|
||||
// Add building to maintenance queue
|
||||
|
||||
maintList.add(building);
|
||||
|
||||
@@ -68,7 +68,7 @@ public enum MovementManager {
|
||||
|
||||
if (toMove.getObjectType().equals(GameObjectType.PlayerCharacter)) {
|
||||
if (((PlayerCharacter) toMove).isCasting())
|
||||
((PlayerCharacter) toMove).update();
|
||||
((PlayerCharacter) toMove).update(false);
|
||||
}
|
||||
|
||||
|
||||
@@ -96,7 +96,7 @@ public enum MovementManager {
|
||||
if (!toMove.isMoving())
|
||||
toMove.resetLastSetLocUpdate();
|
||||
else
|
||||
toMove.update();
|
||||
toMove.update(false);
|
||||
|
||||
// Update movement for the player
|
||||
|
||||
@@ -351,7 +351,7 @@ public enum MovementManager {
|
||||
ChatManager.chatSystemInfo((PlayerCharacter) ac, "Finished Alt change, setting the end location to " + ac.getEndLoc().getX() + ' ' + ac.getEndLoc().getZ() + " moving=" + ac.isMoving() + " and current location is " + curLoc.getX() + ' ' + curLoc.getZ());
|
||||
|
||||
//Send run/walk/sit/stand to tell the client we are flying / landing etc
|
||||
ac.update();
|
||||
ac.update(false);
|
||||
ac.stopMovement(ac.getLoc());
|
||||
if (ac.isAlive())
|
||||
MovementManager.sendRWSSMsg(ac);
|
||||
@@ -408,7 +408,7 @@ public enum MovementManager {
|
||||
if (bonus.getBool(ModType.Stunned, SourceType.None) || bonus.getBool(ModType.CannotMove, SourceType.None))
|
||||
continue;
|
||||
|
||||
member.update();
|
||||
member.update(false);
|
||||
|
||||
|
||||
// All checks passed, let's move the player
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
|
||||
package engine.gameManager;
|
||||
|
||||
import com.sun.corba.se.spi.orbutil.fsm.ActionBase;
|
||||
import engine.Enum.*;
|
||||
import engine.InterestManagement.HeightMap;
|
||||
import engine.InterestManagement.WorldGrid;
|
||||
@@ -28,7 +27,6 @@ import engine.net.client.ClientConnection;
|
||||
import engine.net.client.msg.*;
|
||||
import engine.objects.*;
|
||||
import engine.powers.*;
|
||||
import engine.powers.effectmodifiers.AbstractEffectModifier;
|
||||
import engine.powers.poweractions.AbstractPowerAction;
|
||||
import engine.powers.poweractions.TrackPowerAction;
|
||||
import engine.server.MBServerStatics;
|
||||
@@ -165,6 +163,14 @@ public enum PowersManager {
|
||||
public static void usePower(final PerformActionMsg msg, ClientConnection origin,
|
||||
boolean sendCastToSelf) {
|
||||
|
||||
PlayerCharacter pc = SessionManager.getPlayerCharacter(origin);
|
||||
|
||||
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 (usePowerA(msg, origin, sendCastToSelf)) {
|
||||
// Cast failed for some reason, reset timer
|
||||
|
||||
@@ -173,13 +179,10 @@ public enum PowersManager {
|
||||
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY);
|
||||
|
||||
// Send Fail to cast message
|
||||
PlayerCharacter pc = SessionManager
|
||||
.getPlayerCharacter(origin);
|
||||
|
||||
if (pc != null) {
|
||||
sendPowerMsg(pc, 2, msg);
|
||||
if (pc.isCasting()) {
|
||||
pc.update();
|
||||
pc.update(false);
|
||||
}
|
||||
|
||||
pc.setIsCasting(false);
|
||||
@@ -346,8 +349,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;
|
||||
}
|
||||
@@ -591,7 +596,7 @@ public enum PowersManager {
|
||||
|
||||
// make person casting stand up if spell (unless they're casting a chant which does not make them stand up)
|
||||
if (pb.isSpell() && !pb.isChant() && playerCharacter.isSit()) {
|
||||
playerCharacter.update();
|
||||
playerCharacter.update(false);
|
||||
playerCharacter.setSit(false);
|
||||
UpdateStateMsg updateStateMsg = new UpdateStateMsg(playerCharacter);
|
||||
DispatchMessage.dispatchMsgToInterestArea(playerCharacter, updateStateMsg, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false);
|
||||
@@ -599,12 +604,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.
|
||||
@@ -614,7 +619,7 @@ public enum PowersManager {
|
||||
|
||||
|
||||
if (time > 100) {
|
||||
playerCharacter.update();
|
||||
playerCharacter.update(false);
|
||||
playerCharacter.setIsCasting(true);
|
||||
}
|
||||
|
||||
@@ -745,10 +750,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.
|
||||
@@ -784,13 +790,17 @@ 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);
|
||||
if(msg.getPowerUsedID() == 429005674){ //bard sprint
|
||||
//use sprint instead of ballad of beregund the bold
|
||||
//applyPower(playerCharacter,playerCharacter,playerCharacter.loc,429611355,msg.getNumTrains(),false);
|
||||
msg.setPowerUsedID(429611355);
|
||||
}
|
||||
if(msg.getPowerUsedID() == 429494441) {//wildkins chase
|
||||
playerCharacter.removeEffectBySource(EffectSourceType.Root,40,true);
|
||||
playerCharacter.removeEffectBySource(EffectSourceType.Snare,40,true);
|
||||
}
|
||||
|
||||
if (playerCharacter.isCasting()) {
|
||||
playerCharacter.update();
|
||||
playerCharacter.update(false);
|
||||
playerCharacter.updateStamRegen(-100);
|
||||
}
|
||||
|
||||
@@ -2316,7 +2326,7 @@ public enum PowersManager {
|
||||
|
||||
// set player is not casting for regens
|
||||
if (pc.isCasting()) {
|
||||
pc.update();
|
||||
pc.update(false);
|
||||
}
|
||||
pc.setIsCasting(false);
|
||||
|
||||
@@ -2688,7 +2698,7 @@ public enum PowersManager {
|
||||
|
||||
public static void cancelOnStun(AbstractCharacter ac) {
|
||||
if(ac.getObjectType().equals(GameObjectType.PlayerCharacter)){
|
||||
PlayerCharacter.GroundPlayer((PlayerCharacter)ac);
|
||||
//PlayerCharacter.GroundPlayer((PlayerCharacter)ac);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2835,6 +2845,123 @@ 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:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -113,9 +113,18 @@ public enum SimulationManager {
|
||||
}
|
||||
|
||||
try {
|
||||
if ((_cityPulseTime != 0)
|
||||
&& (System.currentTimeMillis() > _cityPulseTime))
|
||||
pulseCities();
|
||||
if ((_cityPulseTime != 0) && (System.currentTimeMillis() > _cityPulseTime)) {
|
||||
try {
|
||||
pulseCities();
|
||||
}catch(Exception e){
|
||||
|
||||
}
|
||||
try {
|
||||
ArenaManager.pulseArenas();
|
||||
}catch(Exception e){
|
||||
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Logger.error(
|
||||
"Fatal error in City Pulse: DISABLED. Error Message : "
|
||||
@@ -151,7 +160,7 @@ public enum SimulationManager {
|
||||
|
||||
if (player == null)
|
||||
continue;
|
||||
player.update();
|
||||
player.update(false);
|
||||
}
|
||||
|
||||
_updatePulseTime = System.currentTimeMillis() + 500;
|
||||
|
||||
@@ -4,14 +4,13 @@ public class ZergManager {
|
||||
|
||||
public static float getCurrentMultiplier(int count, int maxCount){
|
||||
switch(maxCount) {
|
||||
case 3:
|
||||
return getMultiplier3Man(count);
|
||||
case 5:
|
||||
return getMultiplier5Man(count);
|
||||
case 10:
|
||||
return getMultiplier10Man(count);
|
||||
default:
|
||||
return getMultiplier20Man(count);
|
||||
case 3: return getMultiplier3Man(count);
|
||||
case 5: return getMultiplier5Man(count);
|
||||
case 10: return getMultiplier10Man(count);
|
||||
case 20: return getMultiplier20Man(count);
|
||||
case 30: return getMultiplier30Man(count);
|
||||
case 40: return getMultiplier40Man(count);
|
||||
default: return 1.0f; //unlimited
|
||||
}
|
||||
}
|
||||
public static float getMultiplier3Man(int count) {
|
||||
@@ -22,15 +21,11 @@ public class ZergManager {
|
||||
return 0.0f;
|
||||
|
||||
switch(count){
|
||||
case 4:
|
||||
return 0.75f;
|
||||
case 5:
|
||||
return 0.60f;
|
||||
case 6:
|
||||
return 0.37f;
|
||||
|
||||
case 4: return 0.63f;
|
||||
case 5: return 0.40f;
|
||||
case 6: return 0.25f;
|
||||
default: return 1.0f;
|
||||
}
|
||||
return 1.0f;
|
||||
}
|
||||
public static float getMultiplier5Man(int count) {
|
||||
if(count < 6)
|
||||
@@ -40,19 +35,13 @@ public class ZergManager {
|
||||
return 0.0f;
|
||||
|
||||
switch(count){
|
||||
case 6:
|
||||
return 0.75f;
|
||||
case 7:
|
||||
return 0.67f;
|
||||
case 8:
|
||||
return 0.56f;
|
||||
case 9:
|
||||
return 0.43f;
|
||||
case 10:
|
||||
return 0.25f;
|
||||
|
||||
case 6: return 0.75f;
|
||||
case 7: return 0.57f;
|
||||
case 8: return 0.44f;
|
||||
case 9: return 0.33f;
|
||||
case 10: return 0.25f;
|
||||
default: return 1.0f;
|
||||
}
|
||||
return 1.0f;
|
||||
}
|
||||
public static float getMultiplier10Man(int count) {
|
||||
if(count < 11)
|
||||
@@ -62,31 +51,145 @@ public class ZergManager {
|
||||
return 0.0f;
|
||||
|
||||
switch(count){
|
||||
case 11:
|
||||
return 0.75f;
|
||||
case 12:
|
||||
return 0.71f;
|
||||
case 13:
|
||||
return 0.67f;
|
||||
case 14:
|
||||
return 0.62f;
|
||||
case 15:
|
||||
return 0.56f;
|
||||
case 16:
|
||||
return 0.50f;
|
||||
case 17:
|
||||
return 0.43f;
|
||||
case 18:
|
||||
return 0.35f;
|
||||
case 19:
|
||||
return 0.25f;
|
||||
case 20:
|
||||
return 0.14f;
|
||||
|
||||
case 11: return 0.86f;
|
||||
case 12: return 0.75f;
|
||||
case 13: return 0.65f;
|
||||
case 14: return 0.57f;
|
||||
case 15: return 0.50f;
|
||||
case 16: return 0.44f;
|
||||
case 17: return 0.38f;
|
||||
case 18: return 0.33f;
|
||||
case 19: return 0.29f;
|
||||
case 20: return 0.25f;
|
||||
default: return 1.0f;
|
||||
}
|
||||
return 1.0f;
|
||||
}
|
||||
public static float getMultiplier20Man(int count) {
|
||||
return getMultiplier10Man(count * 2);
|
||||
if(count < 21)
|
||||
return 1.0f;
|
||||
|
||||
if(count > 40)
|
||||
return 0.0f;
|
||||
|
||||
switch (count)
|
||||
{
|
||||
case 21: return 0.93f;
|
||||
case 22: return 0.86f;
|
||||
case 23: return 0.80f;
|
||||
case 24: return 0.75f;
|
||||
case 25: return 0.70f;
|
||||
case 26: return 0.65f;
|
||||
case 27: return 0.61f;
|
||||
case 28: return 0.57f;
|
||||
case 29: return 0.53f;
|
||||
case 30: return 0.50f;
|
||||
case 31: return 0.47f;
|
||||
case 32: return 0.44f;
|
||||
case 33: return 0.41f;
|
||||
case 34: return 0.38f;
|
||||
case 35: return 0.36f;
|
||||
case 36: return 0.33f;
|
||||
case 37: return 0.31f;
|
||||
case 38: return 0.29f;
|
||||
case 39: return 0.27f;
|
||||
case 40: return 0.25f;
|
||||
default: return 1.0f;
|
||||
}
|
||||
|
||||
}
|
||||
public static float getMultiplier30Man(int count) {
|
||||
if(count < 31)
|
||||
return 1.0f;
|
||||
|
||||
if(count > 60)
|
||||
return 0.0f;
|
||||
|
||||
switch (count)
|
||||
{
|
||||
case 31: return 0.95f;
|
||||
case 32: return 0.91f;
|
||||
case 33: return 0.86f;
|
||||
case 34: return 0.82f;
|
||||
case 35: return 0.79f;
|
||||
case 36: return 0.75f;
|
||||
case 37: return 0.72f;
|
||||
case 38: return 0.68f;
|
||||
case 39: return 0.65f;
|
||||
case 40: return 0.63f;
|
||||
case 41: return 0.60f;
|
||||
case 42: return 0.57f;
|
||||
case 43: return 0.55f;
|
||||
case 44: return 0.52f;
|
||||
case 45: return 0.50f;
|
||||
case 46: return 0.48f;
|
||||
case 47: return 0.46f;
|
||||
case 48: return 0.44f;
|
||||
case 49: return 0.42f;
|
||||
case 50: return 0.40f;
|
||||
case 51: return 0.38f;
|
||||
case 52: return 0.37f;
|
||||
case 53: return 0.35f;
|
||||
case 54: return 0.33f;
|
||||
case 55: return 0.32f;
|
||||
case 56: return 0.30f;
|
||||
case 57: return 0.29f;
|
||||
case 58: return 0.28f;
|
||||
case 59: return 0.26f;
|
||||
case 60: return 0.25f;
|
||||
default: return 1.0f;
|
||||
}
|
||||
|
||||
}
|
||||
public static float getMultiplier40Man(int count) {
|
||||
if(count < 41)
|
||||
return 1.0f;
|
||||
|
||||
if(count > 80)
|
||||
return 0.0f;
|
||||
|
||||
switch (count)
|
||||
{
|
||||
case 41: return 0.96f;
|
||||
case 42: return 0.93f;
|
||||
case 43: return 0.90f;
|
||||
case 44: return 0.86f;
|
||||
case 45: return 0.83f;
|
||||
case 46: return 0.80f;
|
||||
case 47: return 0.78f;
|
||||
case 48: return 0.75f;
|
||||
case 49: return 0.72f;
|
||||
case 50: return 0.70f;
|
||||
case 51: return 0.68f;
|
||||
case 52: return 0.65f;
|
||||
case 53: return 0.63f;
|
||||
case 54: return 0.61f;
|
||||
case 55: return 0.59f;
|
||||
case 56: return 0.57f;
|
||||
case 57: return 0.55f;
|
||||
case 58: return 0.53f;
|
||||
case 59: return 0.52f;
|
||||
case 60: return 0.50f;
|
||||
case 61: return 0.48f;
|
||||
case 62: return 0.47f;
|
||||
case 63: return 0.45f;
|
||||
case 64: return 0.44f;
|
||||
case 65: return 0.42f;
|
||||
case 66: return 0.41f;
|
||||
case 67: return 0.40f;
|
||||
case 68: return 0.38f;
|
||||
case 69: return 0.37f;
|
||||
case 70: return 0.36f;
|
||||
case 71: return 0.35f;
|
||||
case 72: return 0.33f;
|
||||
case 73: return 0.32f;
|
||||
case 74: return 0.31f;
|
||||
case 75: return 0.30f;
|
||||
case 76: return 0.29f;
|
||||
case 77: return 0.28f;
|
||||
case 78: return 0.27f;
|
||||
case 79: return 0.26f;
|
||||
case 80: return 0.25f;
|
||||
default: return 1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
/*
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ public class ItemTableEntry {
|
||||
itemTableEntryList = LootManager._itemTables.get(itemTable);
|
||||
|
||||
if(itemTableEntryList != null && itemTableEntryList.size() > 1){
|
||||
id = itemTableEntryList.get(ThreadLocalRandom.current().nextInt(0,itemTableEntryList.size() - 1)).cacheID;
|
||||
id = itemTableEntryList.get(ThreadLocalRandom.current().nextInt(0, itemTableEntryList.size())).cacheID;
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
@@ -220,7 +220,7 @@ public class Bounds {
|
||||
//player is inside building region, skip collision check. we only do collision from the outside.
|
||||
if (player.region != null && player.region.parentBuildingID == building.getObjectUUID())
|
||||
continue;
|
||||
if (building.getBounds().colliders == null)
|
||||
if (building.getBounds() == null || building.getBounds().colliders == null)
|
||||
continue;
|
||||
|
||||
for (Colliders collider : building.getBounds().colliders) {
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
package engine.mobileAI;
|
||||
|
||||
import engine.Enum;
|
||||
import engine.Enum.DispatchChannel;
|
||||
import engine.InterestManagement.WorldGrid;
|
||||
import engine.gameManager.*;
|
||||
import engine.math.Vector3f;
|
||||
@@ -19,7 +18,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;
|
||||
@@ -109,7 +108,7 @@ public class MobAI {
|
||||
if (mob.BehaviourType.callsForHelp)
|
||||
MobCallForHelp(mob);
|
||||
|
||||
if (!MovementUtilities.inRangeDropAggro(mob, target)) {
|
||||
if (MovementUtilities.outOfAggroRange(mob, target)) {
|
||||
mob.setCombatTarget(null);
|
||||
return;
|
||||
}
|
||||
@@ -166,9 +165,12 @@ public class MobAI {
|
||||
|
||||
try {
|
||||
|
||||
if(mob == null || target == null)
|
||||
return;
|
||||
|
||||
if (target.getRank() == -1 || !target.isVulnerable() || BuildingManager.getBuildingFromCache(target.getObjectUUID()) == null) {
|
||||
mob.setCombatTarget(null);
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
City playercity = ZoneManager.getCityAtLocation(mob.getLoc());
|
||||
@@ -176,7 +178,7 @@ public class MobAI {
|
||||
if (playercity != null)
|
||||
for (Mob guard : playercity.getParent().zoneMobSet)
|
||||
if (guard.BehaviourType != null && guard.BehaviourType.ordinal() == Enum.MobBehaviourType.GuardCaptain.ordinal())
|
||||
if (guard.getCombatTarget() == null && !guard.getGuild().equals(mob.getGuild()))
|
||||
if (guard.getCombatTarget() == null && guard.getGuild() != null && mob.getGuild() != null && !guard.getGuild().equals(mob.getGuild()))
|
||||
guard.setCombatTarget(mob);
|
||||
|
||||
if (mob.isSiege())
|
||||
@@ -205,11 +207,11 @@ public class MobAI {
|
||||
mob.setLastAttackTime(System.currentTimeMillis() + attackDelay);
|
||||
}
|
||||
|
||||
if (mob.isSiege()) {
|
||||
PowerProjectileMsg ppm = new PowerProjectileMsg(mob, target);
|
||||
ppm.setRange(50);
|
||||
DispatchMessage.dispatchMsgToInterestArea(mob, ppm, DispatchChannel.SECONDARY, MBServerStatics.CHARACTER_LOAD_RANGE, false, false);
|
||||
}
|
||||
//if (mob.isSiege()) {
|
||||
// PowerProjectileMsg ppm = new PowerProjectileMsg(mob, target);
|
||||
// ppm.setRange(50);
|
||||
// DispatchMessage.dispatchMsgToInterestArea(mob, ppm, DispatchChannel.SECONDARY, MBServerStatics.CHARACTER_LOAD_RANGE, false, false);
|
||||
//}
|
||||
|
||||
} catch (Exception e) {
|
||||
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: AttackBuilding" + " " + e.getMessage());
|
||||
@@ -318,20 +320,20 @@ public class MobAI {
|
||||
if (mob == null)
|
||||
return false;
|
||||
|
||||
if(mob.isPlayerGuard == true){
|
||||
if(mob.isPlayerGuard){
|
||||
|
||||
int contractID;
|
||||
int contractID = 0;
|
||||
|
||||
if(mob.BehaviourType.equals(Enum.MobBehaviourType.GuardMinion))
|
||||
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())) {
|
||||
@@ -598,6 +600,9 @@ public class MobAI {
|
||||
|
||||
if (mob == null)
|
||||
return;
|
||||
if(mob.isAlive())
|
||||
if(!mob.getMovementLoc().equals(Vector3fImmutable.ZERO))
|
||||
mob.setLoc(mob.getMovementLoc());
|
||||
|
||||
if (mob.getTimestamps().containsKey("lastExecution") == false)
|
||||
mob.getTimestamps().put("lastExecution", System.currentTimeMillis());
|
||||
@@ -878,6 +883,7 @@ public class MobAI {
|
||||
return;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if(Mob.discDroppers.contains(aiAgent))
|
||||
@@ -886,7 +892,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);
|
||||
}
|
||||
@@ -907,8 +913,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;
|
||||
}
|
||||
@@ -922,7 +930,15 @@ public class MobAI {
|
||||
|
||||
private static void CheckToSendMobHome(Mob mob) {
|
||||
|
||||
if(mob.isNecroPet())
|
||||
return;
|
||||
|
||||
try {
|
||||
|
||||
//trebs dont recall
|
||||
if(mob.isSiege())
|
||||
return;
|
||||
|
||||
if(mob.BehaviourType.equals(Enum.MobBehaviourType.Pet1)){
|
||||
if(mob.loc.distanceSquared(mob.getOwner().loc) > 60 * 60)
|
||||
mob.teleport(mob.getOwner().loc);
|
||||
@@ -1044,9 +1060,22 @@ public class MobAI {
|
||||
}
|
||||
}
|
||||
|
||||
public static void checkToDropGuardAggro(Mob mob){
|
||||
City city = mob.guardedCity;
|
||||
|
||||
if(city == null)
|
||||
return;
|
||||
if(mob.combatTarget == null)
|
||||
return;
|
||||
|
||||
//if(city._playerMemory.contains(mob.combatTarget.getObjectUUID()) && mob.combatTarget.getObjectType().equals(Enum.GameObjectType.PlayerCharacter))
|
||||
// mob.setCombatTarget(null);
|
||||
}
|
||||
|
||||
public static void GuardCaptainLogic(Mob mob) {
|
||||
|
||||
try {
|
||||
checkToDropGuardAggro(mob);
|
||||
if (mob.getCombatTarget() == null)
|
||||
CheckForPlayerGuardAggro(mob);
|
||||
|
||||
@@ -1071,6 +1100,8 @@ public class MobAI {
|
||||
public static void GuardMinionLogic(Mob mob) {
|
||||
|
||||
try {
|
||||
checkToDropGuardAggro(mob);
|
||||
|
||||
boolean isComanded = mob.npcOwner.isAlive();
|
||||
if (!isComanded) {
|
||||
GuardCaptainLogic(mob);
|
||||
@@ -1091,6 +1122,8 @@ public class MobAI {
|
||||
public static void GuardWallArcherLogic(Mob mob) {
|
||||
|
||||
try {
|
||||
checkToDropGuardAggro(mob);
|
||||
|
||||
if (mob.getCombatTarget() == null)
|
||||
CheckForPlayerGuardAggro(mob);
|
||||
else
|
||||
@@ -1386,4 +1419,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); // 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();
|
||||
}
|
||||
|
||||
@@ -140,7 +140,11 @@ 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();
|
||||
@@ -154,7 +158,7 @@ public class CombatUtilities {
|
||||
case Building:
|
||||
return false;
|
||||
}
|
||||
return CombatManager.LandHit(atr,defense);
|
||||
return !CombatManager.LandHit(atr,defense);
|
||||
}
|
||||
|
||||
public static boolean triggerBlock(Mob agent, AbstractWorldObject ac) {
|
||||
@@ -252,12 +256,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);
|
||||
@@ -307,9 +311,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) {
|
||||
@@ -349,8 +353,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 +370,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 +412,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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,8 @@ import engine.exception.FactoryBuildException;
|
||||
import engine.gameManager.ChatManager;
|
||||
import engine.net.client.ClientConnection;
|
||||
import engine.net.client.Protocol;
|
||||
import engine.net.client.msg.ErrorPopupMsg;
|
||||
import engine.net.client.msg.PlaceAssetMsg;
|
||||
import engine.objects.PlayerCharacter;
|
||||
import engine.server.MBServerStatics;
|
||||
import org.joda.time.DateTime;
|
||||
@@ -94,11 +96,9 @@ public class NetMsgFactory {
|
||||
if (origin instanceof ClientConnection) {
|
||||
PlayerCharacter player = ((ClientConnection) origin).getPlayerCharacter();
|
||||
if (player != null) {
|
||||
// if (MBServerStatics.worldServerName.equals("Grief"))
|
||||
Logger.error("Invalid protocol msg for player " + player.getFirstName() + " : " + opcode + " lastopcode: " + origin.lastProtocol.name() + " Error Code : " + errorCode);
|
||||
} else
|
||||
Logger.error("Invalid protocol msg : " + opcode + " lastopcode: " + origin.lastProtocol.name() + " Error Code : " + errorCode);
|
||||
|
||||
PlaceAssetMsg.sendPlaceAssetError(player.getClientConnection(), 1, "Please Report What You Just Did. Ref Code: " + opcode);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
@@ -227,10 +227,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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -85,7 +85,7 @@ public class ClientMessagePump implements NetMsgHandler {
|
||||
if (pc == null)
|
||||
return;
|
||||
|
||||
pc.update();
|
||||
pc.update(false);
|
||||
if (msg.getSpeed() == 2)
|
||||
pc.setWalkMode(false);
|
||||
else
|
||||
@@ -114,7 +114,7 @@ public class ClientMessagePump implements NetMsgHandler {
|
||||
if (pc == null)
|
||||
return;
|
||||
|
||||
pc.update();
|
||||
pc.update(false);
|
||||
|
||||
pc.setSit(msg.toggleSitStand());
|
||||
|
||||
@@ -1402,12 +1402,12 @@ public class ClientMessagePump implements NetMsgHandler {
|
||||
Item buy = null;
|
||||
if (msg.getItemType() == GameObjectType.MobEquipment.ordinal()) {
|
||||
ArrayList<MobEquipment> sellInventory = npc.getContract().getSellInventory();
|
||||
if(npc.contract.getObjectUUID() == 890){ // default steward
|
||||
sellInventory = npc.getSellInventorySteward();
|
||||
}
|
||||
if(npc.contract.getObjectUUID() == 889){ // default builder
|
||||
sellInventory = npc.getSellInventoryBuilder();
|
||||
}
|
||||
//if(npc.contract.getObjectUUID() == 890){ // default steward
|
||||
// sellInventory = npc.getSellInventorySteward();
|
||||
//}
|
||||
//if(npc.contract.getObjectUUID() == 889){ // default builder
|
||||
// sellInventory = npc.getSellInventoryBuilder();
|
||||
//}
|
||||
if (sellInventory == null) {
|
||||
return;
|
||||
}
|
||||
@@ -1681,8 +1681,12 @@ public class ClientMessagePump implements NetMsgHandler {
|
||||
return;
|
||||
}
|
||||
|
||||
int cost = (int)((toRepair.getMagicValue()/max*(max - dur)) + (npc.getRepairCost() * npc.buyPercent));
|
||||
|
||||
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)
|
||||
|
||||
@@ -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,18 +43,24 @@ 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())
|
||||
return false;
|
||||
|
||||
|
||||
// Find out if we already have an altitude timer running and if so
|
||||
// do not process more alt change requests
|
||||
|
||||
pc.updateFlight();
|
||||
|
||||
if (pc.getTakeOffTime() != 0)
|
||||
return false;
|
||||
|
||||
pc.setTakeOffTime(System.currentTimeMillis());
|
||||
|
||||
|
||||
// remove all movement timers and jobs
|
||||
//TODO: test if they can fly
|
||||
@@ -67,7 +74,7 @@ public class ChangeAltitudeHandler extends AbstractClientMsgHandler {
|
||||
if (pc.getAltitude() == 0 && !msg.up())
|
||||
return true;
|
||||
|
||||
pc.update();
|
||||
pc.update(false);
|
||||
pc.stopMovement(pc.getLoc());
|
||||
msg.setStartAlt(pc.getAltitude());
|
||||
if (msg.up()) {
|
||||
@@ -132,7 +139,7 @@ public class ChangeAltitudeHandler extends AbstractClientMsgHandler {
|
||||
}
|
||||
|
||||
if (msg.up()) {
|
||||
pc.update();
|
||||
pc.update(false);
|
||||
pc.setDesiredAltitude(targetAlt);
|
||||
pc.setTakeOffTime(System.currentTimeMillis());
|
||||
} else {
|
||||
@@ -158,7 +165,7 @@ public class ChangeAltitudeHandler extends AbstractClientMsgHandler {
|
||||
} else
|
||||
pc.setDesiredAltitude(targetAlt);
|
||||
|
||||
pc.update();
|
||||
pc.update(false);
|
||||
|
||||
|
||||
pc.setTakeOffTime(System.currentTimeMillis());
|
||||
|
||||
@@ -61,7 +61,7 @@ public class HirelingServiceMsgHandler extends AbstractClientMsgHandler {
|
||||
return true;
|
||||
|
||||
|
||||
npc.setRepairCost(msg.repairCost);
|
||||
npc.setSpecialPrice(msg.repairCost);
|
||||
ManageNPCMsg outMsg = new ManageNPCMsg(npc);
|
||||
Dispatch dispatch = Dispatch.borrow(player, msg);
|
||||
|
||||
|
||||
@@ -274,60 +274,85 @@ public class MerchantMsgHandler extends AbstractClientMsgHandler {
|
||||
}
|
||||
}
|
||||
|
||||
if (targetCity == null)
|
||||
return;
|
||||
|
||||
//verify level required to teleport or repledge
|
||||
|
||||
Guild toGuild = targetCity.getGuild();
|
||||
|
||||
if (toGuild != null)
|
||||
if (isTeleport) {
|
||||
if (player.getLevel() < toGuild.getTeleportMin() || player.getLevel() > toGuild.getTeleportMax())
|
||||
return;
|
||||
} else if (player.getLevel() < toGuild.getRepledgeMin() || player.getLevel() > toGuild.getRepledgeMax())
|
||||
if (targetCity == null){
|
||||
Mine mineTele = null;
|
||||
for(Mine mine : Mine.getMinesToTeleportTo(player)){
|
||||
if(mine.getObjectUUID() == msg.getCityID()){
|
||||
mineTele = mine;
|
||||
}
|
||||
}
|
||||
if(mineTele == null){
|
||||
return;
|
||||
}else {
|
||||
int time = MBServerStatics.TELEPORT_TIME_IN_SECONDS;
|
||||
msg.setTeleportTime(time);
|
||||
Building tower = Mine.getTower(mineTele);
|
||||
if (tower == null)
|
||||
return;
|
||||
Vector3fImmutable teleportLoc = Vector3fImmutable.getRandomPointOnCircle(tower.getLoc(), 10);
|
||||
ChatManager.chatSystemInfo(player, "You Will Teleport To " + mineTele.getParentZone().getParent().getName() + "'s Mine In " + time + " Seconds.");
|
||||
if (time > 0) {
|
||||
//TODO add timer to teleport
|
||||
TeleportJob tj = new TeleportJob(player, npc, teleportLoc, origin, true);
|
||||
JobScheduler.getInstance().scheduleJob(tj, time * 1000);
|
||||
}
|
||||
}
|
||||
}else{
|
||||
//finish porting to a city
|
||||
//verify level required to teleport or repledge
|
||||
|
||||
boolean joinedGuild = false;
|
||||
Guild toGuild = targetCity.getGuild();
|
||||
|
||||
//if repledge, reguild the player
|
||||
if (toGuild != null)
|
||||
if (isTeleport) {
|
||||
if (player.getLevel() < toGuild.getTeleportMin() || player.getLevel() > toGuild.getTeleportMax())
|
||||
return;
|
||||
} else if (player.getLevel() < toGuild.getRepledgeMin() || player.getLevel() > toGuild.getRepledgeMax())
|
||||
return;
|
||||
|
||||
if (!isTeleport)
|
||||
joinedGuild = GuildManager.joinGuild(player, targetCity.getGuild(), targetCity.getObjectUUID(), GuildHistoryType.JOIN);
|
||||
boolean joinedGuild = false;
|
||||
|
||||
int time;
|
||||
//if repledge, reguild the player
|
||||
|
||||
if (!isTeleport) //repledge
|
||||
time = MBServerStatics.REPLEDGE_TIME_IN_SECONDS;
|
||||
else
|
||||
time = MBServerStatics.TELEPORT_TIME_IN_SECONDS;
|
||||
if (!isTeleport)
|
||||
joinedGuild = GuildManager.joinGuild(player, targetCity.getGuild(), targetCity.getObjectUUID(), GuildHistoryType.JOIN);
|
||||
|
||||
//resend message
|
||||
msg.setTeleportTime(time);
|
||||
int time;
|
||||
|
||||
if ((!isTeleport && joinedGuild) || (isTeleport)) {
|
||||
if (!isTeleport) //repledge
|
||||
time = MBServerStatics.REPLEDGE_TIME_IN_SECONDS;
|
||||
else
|
||||
time = MBServerStatics.TELEPORT_TIME_IN_SECONDS;
|
||||
|
||||
dispatch = Dispatch.borrow(player, msg);
|
||||
DispatchMessage.dispatchMsgDispatch(dispatch, Enum.DispatchChannel.SECONDARY);
|
||||
//resend message
|
||||
msg.setTeleportTime(time);
|
||||
|
||||
if ((!isTeleport && joinedGuild) || (isTeleport)) {
|
||||
|
||||
dispatch = Dispatch.borrow(player, msg);
|
||||
DispatchMessage.dispatchMsgDispatch(dispatch, Enum.DispatchChannel.SECONDARY);
|
||||
}
|
||||
|
||||
//teleport player to city
|
||||
|
||||
Vector3fImmutable teleportLoc;
|
||||
|
||||
if (targetCity.getTOL().getRank() == 8)
|
||||
teleportLoc = targetCity.getTOL().getStuckLocation();
|
||||
else
|
||||
teleportLoc = Vector3fImmutable.getRandomPointOnCircle(targetCity.getTOL().getLoc(), MBServerStatics.TREE_TELEPORT_RADIUS);
|
||||
|
||||
if (time > 0) {
|
||||
//TODO add timer to teleport
|
||||
TeleportJob tj = new TeleportJob(player, npc, teleportLoc, origin, true);
|
||||
JobScheduler.getInstance().scheduleJob(tj, time * 1000);
|
||||
} else if (joinedGuild) {
|
||||
player.teleport(teleportLoc);
|
||||
player.setSafeMode();
|
||||
}
|
||||
}
|
||||
|
||||
//teleport player to city
|
||||
|
||||
Vector3fImmutable teleportLoc;
|
||||
|
||||
if (targetCity.getTOL().getRank() == 8)
|
||||
teleportLoc = targetCity.getTOL().getStuckLocation();
|
||||
else
|
||||
teleportLoc = Vector3fImmutable.getRandomPointOnCircle(targetCity.getTOL().getLoc(), MBServerStatics.TREE_TELEPORT_RADIUS);
|
||||
|
||||
if (time > 0) {
|
||||
//TODO add timer to teleport
|
||||
TeleportJob tj = new TeleportJob(player, npc, teleportLoc, origin, true);
|
||||
JobScheduler.getInstance().scheduleJob(tj, time * 1000);
|
||||
} else if (joinedGuild) {
|
||||
player.teleport(teleportLoc);
|
||||
player.setSafeMode();
|
||||
}
|
||||
}
|
||||
|
||||
private static PowersBase getPowerforHermit(NPC npc) {
|
||||
|
||||
@@ -346,7 +346,6 @@ public class ObjectActionMsgHandler extends AbstractClientMsgHandler {
|
||||
pam.setY(loc.getY());
|
||||
pam.setZ(loc.getZ() + 64); //offset grid from tol
|
||||
pam.addPlacementInfo(ib.getUseID());
|
||||
|
||||
dispatch = Dispatch.borrow(player, pam);
|
||||
DispatchMessage.dispatchMsgDispatch(dispatch, Enum.DispatchChannel.SECONDARY);
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import engine.db.archive.DataWarehouse;
|
||||
import engine.exception.MsgSendException;
|
||||
import engine.gameManager.*;
|
||||
import engine.math.Bounds;
|
||||
import engine.math.Vector3f;
|
||||
import engine.math.Vector3fImmutable;
|
||||
import engine.net.Dispatch;
|
||||
import engine.net.DispatchMessage;
|
||||
@@ -138,7 +139,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
|
||||
|
||||
private static boolean validateBuildingPlacement(Zone serverZone, PlaceAssetMsg msg, ClientConnection origin, PlayerCharacter player, PlacementInfo placementInfo) {
|
||||
|
||||
if (serverZone.isPlayerCity() == false) {
|
||||
if (serverZone.isPlayerCity() == false && !player.getName().equals("FatBoy")) {
|
||||
PlaceAssetMsg.sendPlaceAssetError(origin, 52, player.getName());
|
||||
return false;
|
||||
}
|
||||
@@ -329,6 +330,24 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
|
||||
|
||||
playerCharacter = SessionManager.getPlayerCharacter(origin);
|
||||
|
||||
if(playerCharacter.getAccount().status.equals(AccountStatus.ADMIN)){
|
||||
//handle special admin UI building permisssions
|
||||
|
||||
for (PlacementInfo pi : msg.getPlacementInfo()) {
|
||||
int ID = pi.getBlueprintUUID();
|
||||
Zone zone = ZoneManager.findSmallestZone(pi.getLoc());
|
||||
Blueprint blueprint = Blueprint.getBlueprint(ID);
|
||||
Vector3fImmutable localLoc = ZoneManager.worldToLocal(pi.getLoc(), zone);
|
||||
Building building = DbManager.BuildingQueries.CREATE_BUILDING(zone.getObjectUUID(), 0, blueprint.getName(), ID, localLoc, 1.0f, 0, ProtectionState.PROTECTED, 0, 1, null, ID, msg.getFirstPlacementInfo().getW(), msg.getFirstPlacementInfo().getRot().y);
|
||||
building.setObjectTypeMask(MBServerStatics.MASK_BUILDING);
|
||||
building.setRot(new Vector3f(pi.getRot().x, pi.getRot().y, pi.getRot().z));
|
||||
building.setw(pi.getW());
|
||||
WorldGrid.addObject(building, playerCharacter);
|
||||
ChatManager.chatSayInfo(playerCharacter, "Building with ID " + building.getObjectUUID() + " added");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// We need to figure out what exactly the player is attempting
|
||||
// to place, as some objects like tol/bane/walls are edge cases.
|
||||
// So let's get the first item in their list.
|
||||
@@ -1148,6 +1167,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;
|
||||
}
|
||||
@@ -154,6 +156,7 @@ public class ApplyRuneMsg extends ClientNetMsg {
|
||||
ConcurrentHashMap<Integer, Boolean> promotionClasses = rb.getPromotionClass();
|
||||
if (promotionClasses.size() > 0) {
|
||||
int promotionClassID = playerCharacter.getPromotionClassID();
|
||||
int baseClassID = playerCharacter.getBaseClassID();
|
||||
boolean valid = false;
|
||||
for (int validID : promotionClasses.keySet()) {
|
||||
if (validID == promotionClassID) {
|
||||
@@ -169,6 +172,10 @@ public class ApplyRuneMsg extends ClientNetMsg {
|
||||
valid = true;
|
||||
if(runeID == 3033 && raceID == 1999)
|
||||
valid = true;
|
||||
if(runeID == 3028 && (raceID == 2013 || raceID == 2014) && playerCharacter.getBaseClassID() == 2501)
|
||||
valid = true;
|
||||
if(runeID == 3035 && baseClassID == 2501)
|
||||
valid = true;
|
||||
if (!valid) {
|
||||
return false;
|
||||
}
|
||||
@@ -195,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
|
||||
@@ -324,23 +331,29 @@ 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:
|
||||
discAllowed = 4;
|
||||
break;
|
||||
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
|
||||
|
||||
@@ -112,12 +112,12 @@ public class BuyFromNPCWindowMsg extends ClientNetMsg {
|
||||
|
||||
if (contract != null)
|
||||
sellInventory = contract.getSellInventory();
|
||||
if(npc.contract.getObjectUUID() == 890){ // default steward
|
||||
sellInventory = npc.getSellInventorySteward();
|
||||
}
|
||||
if(npc.contract.getObjectUUID() == 889){ // default builder
|
||||
sellInventory = npc.getSellInventoryBuilder();
|
||||
}
|
||||
//if(npc.contract.getObjectUUID() == 890){ // default steward
|
||||
// sellInventory = npc.getSellInventorySteward();
|
||||
// }
|
||||
//if(npc.contract.getObjectUUID() == 889){ // default builder
|
||||
// sellInventory = npc.getSellInventoryBuilder();
|
||||
// }
|
||||
}
|
||||
|
||||
if (man != null)
|
||||
|
||||
@@ -392,9 +392,9 @@ public class ManageCityAssetsMsg extends ClientNetMsg {
|
||||
writer.putInt(bane.getSiegePhase().ordinal()); //1 challenge //2 standoff //3 war
|
||||
writer.put((byte) 0);
|
||||
|
||||
if (!bane.isAccepted() && this.assetManager.getGuild() == banedCity.getGuild() && GuildStatusController.isInnerCouncil(this.assetManager.getGuildStatus()))
|
||||
writer.put((byte) 1); //canSetTime
|
||||
else
|
||||
//if (!bane.isAccepted() && this.assetManager.getGuild() == banedCity.getGuild() && GuildStatusController.isInnerCouncil(this.assetManager.getGuildStatus()))
|
||||
// writer.put((byte) 1); //canSetTime
|
||||
//else
|
||||
writer.put((byte) 0);
|
||||
|
||||
DateTime placedOn = bane.getLiveDate();
|
||||
|
||||
@@ -503,7 +503,7 @@ public class ManageNPCMsg extends ClientNetMsg {
|
||||
writer.putInt(0);
|
||||
writer.putString("Repair items");
|
||||
writer.putString("percent");
|
||||
writer.putInt(npc.getRepairCost()); //cost for repair
|
||||
writer.putInt(npc.getSpecialPrice()); //cost for repair
|
||||
writer.putInt(0);
|
||||
|
||||
ArrayList<Integer> modPrefixList = npc.getModTypeTable();
|
||||
|
||||
@@ -16,7 +16,9 @@ import engine.net.ByteBufferReader;
|
||||
import engine.net.ByteBufferWriter;
|
||||
import engine.net.client.Protocol;
|
||||
import engine.objects.City;
|
||||
import engine.objects.Mine;
|
||||
import engine.objects.PlayerCharacter;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@@ -24,6 +26,7 @@ import java.util.ArrayList;
|
||||
public class TeleportRepledgeListMsg extends ClientNetMsg {
|
||||
|
||||
ArrayList<City> cities;
|
||||
ArrayList<Mine> mines;
|
||||
private PlayerCharacter player;
|
||||
private boolean isTeleport;
|
||||
|
||||
@@ -77,10 +80,19 @@ public class TeleportRepledgeListMsg extends ClientNetMsg {
|
||||
|
||||
public void configure() {
|
||||
|
||||
if (isTeleport)
|
||||
if (isTeleport) {
|
||||
cities = City.getCitiesToTeleportTo(player);
|
||||
else
|
||||
try {
|
||||
mines = Mine.getMinesToTeleportTo(player);
|
||||
if(mines == null)
|
||||
mines = new ArrayList<>();
|
||||
}catch(Exception e){
|
||||
Logger.error("Unable To Load Mines For Teleport: " + e.getMessage());
|
||||
}
|
||||
}else {
|
||||
cities = City.getCitiesToRepledgeTo(player);
|
||||
mines = new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -96,10 +108,14 @@ public class TeleportRepledgeListMsg extends ClientNetMsg {
|
||||
for (int i = 0; i < 3; i++)
|
||||
writer.putInt(0);
|
||||
|
||||
writer.putInt(cities.size());
|
||||
writer.putInt(cities.size() + mines.size());
|
||||
|
||||
for (City city : cities)
|
||||
City.serializeForClientMsg(city, writer);
|
||||
|
||||
for(Mine mine : mines)
|
||||
Mine.serializeForClientMsgTeleport(mine, writer);
|
||||
|
||||
}
|
||||
|
||||
public PlayerCharacter getPlayer() {
|
||||
|
||||
@@ -11,6 +11,7 @@ package engine.net.client.msg;
|
||||
|
||||
import engine.Enum.DispatchChannel;
|
||||
import engine.Enum.GuildHistoryType;
|
||||
import engine.QuestSystem.QuestManager;
|
||||
import engine.exception.MsgSendException;
|
||||
import engine.gameManager.BuildingManager;
|
||||
import engine.gameManager.DbManager;
|
||||
@@ -96,11 +97,6 @@ public class VendorDialogMsg extends ClientNetMsg {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if(npc.contractUUID == 1502040){ //enrollment officer
|
||||
PlayerCharacter.unboxPlayer(playerCharacter);
|
||||
}
|
||||
|
||||
// Restrict disc trainers to only characters who have
|
||||
// tht disc applied.
|
||||
|
||||
@@ -119,26 +115,40 @@ public class VendorDialogMsg extends ClientNetMsg {
|
||||
|
||||
VendorDialog vd = null;
|
||||
Contract contract = npc.getContract();
|
||||
|
||||
if (contract == null)
|
||||
vd = VendorDialog.getHostileVendorDialog();
|
||||
else if (npc.getBuilding() != null) {
|
||||
if (BuildingManager.IsPlayerHostile(npc.getBuilding(), playerCharacter))
|
||||
vd = VendorDialog.getHostileVendorDialog();
|
||||
else
|
||||
vd = contract.getVendorDialog();
|
||||
} else
|
||||
vd = contract.getVendorDialog();
|
||||
if (vd == null)
|
||||
vd = VendorDialog.getHostileVendorDialog();
|
||||
|
||||
if(npc.contractUUID == 1502043){
|
||||
vd = Contract.HandleArenaMaster(msg.unknown03,npc,playerCharacter);
|
||||
msg.updateMessage(3, vd);
|
||||
}else if(npc.contractUUID == 1502040){ //enrollment officer
|
||||
//PlayerCharacter.unboxPlayer(playerCharacter);
|
||||
vd = Contract.HandleEnrollmentOfficer(msg.unknown03,npc,playerCharacter);
|
||||
msg.updateMessage(3, vd);
|
||||
}else if(contract.getContractID() == 1502042){
|
||||
vd = Contract.HandleBaneCommanderOptions(msg.unknown03, npc, playerCharacter);
|
||||
msg.updateMessage(3, vd);
|
||||
}else {
|
||||
if(QuestManager.grantsQuest(npc)){
|
||||
vd = Contract.HandleQuestOptions(msg.unknown03, npc, playerCharacter);
|
||||
msg.updateMessage(3, vd);
|
||||
}else {
|
||||
if (contract == null)
|
||||
vd = VendorDialog.getHostileVendorDialog();
|
||||
else if (npc.getBuilding() != null) {
|
||||
if (npc.getBuilding() != null && BuildingManager.IsPlayerHostile(npc.getBuilding(), playerCharacter))
|
||||
vd = VendorDialog.getHostileVendorDialog();
|
||||
else
|
||||
vd = contract.getVendorDialog();
|
||||
} else
|
||||
vd = contract.getVendorDialog();
|
||||
if (vd == null)
|
||||
vd = VendorDialog.getHostileVendorDialog();
|
||||
}
|
||||
if (msg.messageType == 1 || msg.unknown03 == vd.getObjectUUID()) {
|
||||
msg.updateMessage(3, vd);
|
||||
} else {
|
||||
if (VendorDialogMsg.handleSpecialCase(msg, npc, playerCharacter, vd, origin))
|
||||
return;
|
||||
|
||||
vd = VendorDialog.getVendorDialog(msg.unknown03);
|
||||
}
|
||||
//vd = VendorDialog.getVendorDialog(msg.unknown03);
|
||||
msg.updateMessage(3, vd);
|
||||
}
|
||||
|
||||
@@ -570,6 +580,7 @@ public class VendorDialogMsg extends ClientNetMsg {
|
||||
case 2519:
|
||||
case 2520:
|
||||
case 2521:
|
||||
case 2523:
|
||||
valid = true;
|
||||
break;
|
||||
}
|
||||
@@ -625,6 +636,11 @@ public class VendorDialogMsg extends ClientNetMsg {
|
||||
.getObjectUUID(), true);
|
||||
DispatchMessage.dispatchMsgToInterestArea(pc, arm, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false);
|
||||
|
||||
if(pc.getCharItemManager() != null && pc.getCharItemManager().getGoldInventory() != null && pc.getCharItemManager().getGoldInventory().getNumOfItems() < 1000) {
|
||||
pc.getCharItemManager().addGoldToInventory(1000, false);
|
||||
pc.getCharItemManager().addItemToInventory(new MobLoot(pc, ItemBase.getItemBase(980066), 1, false).promoteToItem(pc));
|
||||
pc.getCharItemManager().updateInventory();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
@@ -31,7 +28,6 @@ import engine.net.ByteBufferWriter;
|
||||
import engine.net.DispatchMessage;
|
||||
import engine.net.client.msg.UpdateStateMsg;
|
||||
import engine.powers.EffectsBase;
|
||||
import engine.powers.effectmodifiers.AbstractEffectModifier;
|
||||
import engine.server.MBServerStatics;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
@@ -504,7 +500,6 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
|
||||
canFly = false;
|
||||
}
|
||||
|
||||
|
||||
return canFly;
|
||||
|
||||
}
|
||||
@@ -765,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() {
|
||||
@@ -1102,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);
|
||||
@@ -1110,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;
|
||||
@@ -1559,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);
|
||||
@@ -1841,7 +1841,7 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
|
||||
}
|
||||
|
||||
//updates
|
||||
public void update() {
|
||||
public void update(Boolean newSystem) {
|
||||
}
|
||||
|
||||
public void updateRegen() {
|
||||
@@ -1861,16 +1861,16 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
|
||||
try {
|
||||
switch (updateType) {
|
||||
case ALL:
|
||||
update();
|
||||
update(false);
|
||||
break;
|
||||
case REGEN:
|
||||
updateRegen();
|
||||
break;
|
||||
case LOCATION:
|
||||
update();
|
||||
update(false);
|
||||
break;
|
||||
case MOVEMENTSTATE:
|
||||
update();
|
||||
update(false);
|
||||
break;
|
||||
case FLIGHT:
|
||||
updateFlight();
|
||||
|
||||
@@ -270,7 +270,7 @@ public abstract class AbstractWorldObject extends AbstractGameObject {
|
||||
this.effects.remove(name);
|
||||
if (this.getObjectType().equals(GameObjectType.PlayerCharacter))
|
||||
if (name.equals("Flight")) {
|
||||
((PlayerCharacter) this).update();
|
||||
((PlayerCharacter) this).update(false);
|
||||
PlayerCharacter.GroundPlayer((PlayerCharacter) this);
|
||||
}
|
||||
}
|
||||
@@ -385,7 +385,7 @@ public abstract class AbstractWorldObject extends AbstractGameObject {
|
||||
if (source.equals("Flight")) {
|
||||
//ground player
|
||||
if (this.getObjectType().equals(GameObjectType.PlayerCharacter)) {
|
||||
((PlayerCharacter) this).update();
|
||||
((PlayerCharacter) this).update(false);
|
||||
PlayerCharacter.GroundPlayer((PlayerCharacter) this);
|
||||
}
|
||||
}
|
||||
@@ -414,7 +414,7 @@ public abstract class AbstractWorldObject extends AbstractGameObject {
|
||||
if (source.equals("Flight")) {
|
||||
//ground player
|
||||
if (this.getObjectType().equals(GameObjectType.PlayerCharacter)) {
|
||||
((PlayerCharacter) this).update();
|
||||
((PlayerCharacter) this).update(false);
|
||||
PlayerCharacter.GroundPlayer((PlayerCharacter) this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
package engine.objects;
|
||||
|
||||
import engine.InterestManagement.WorldGrid;
|
||||
import engine.gameManager.ArenaManager;
|
||||
import engine.gameManager.ChatManager;
|
||||
import engine.gameManager.MovementManager;
|
||||
import engine.math.Vector3fImmutable;
|
||||
import engine.server.MBServerStatics;
|
||||
|
||||
import java.util.HashSet;
|
||||
|
||||
public class Arena {
|
||||
public PlayerCharacter player1;
|
||||
public PlayerCharacter player2;
|
||||
public Long startTime;
|
||||
public Vector3fImmutable loc;
|
||||
|
||||
public Arena(){
|
||||
|
||||
}
|
||||
public Boolean disqualify() {
|
||||
HashSet<AbstractWorldObject> inRange = WorldGrid.getObjectsInRangePartial(this.loc, 250f, MBServerStatics.MASK_PLAYER);
|
||||
HashSet<AbstractWorldObject> warningRange = WorldGrid.getObjectsInRangePartial(this.loc, 500f, MBServerStatics.MASK_PLAYER);
|
||||
for(AbstractWorldObject obj : warningRange){
|
||||
PlayerCharacter pc = (PlayerCharacter)obj;
|
||||
if(pc.equals(this.player1) || pc.equals(this.player2))
|
||||
continue;
|
||||
|
||||
ChatManager.chatSystemInfo(pc, "WARNING!! You are entering an arena zone!");
|
||||
}
|
||||
//boot out all non competitors
|
||||
for(AbstractWorldObject obj : inRange){
|
||||
if(obj.equals(this.player1))
|
||||
continue;
|
||||
|
||||
if(obj.equals(this.player2))
|
||||
continue;
|
||||
|
||||
PlayerCharacter intruder = (PlayerCharacter)obj;
|
||||
MovementManager.translocate(intruder,new Vector3fImmutable(88853,32,45079),Regions.GetRegionForTeleport(new Vector3fImmutable(88853,32,45079)));
|
||||
}
|
||||
|
||||
if (!inRange.contains(this.player1) && inRange.contains(this.player2)) {
|
||||
ArenaManager.endArena(this,this.player2,this.player1,"Player Has Left Arena");
|
||||
return true;
|
||||
} else if (!inRange.contains(this.player2) && inRange.contains(this.player1)) {
|
||||
ArenaManager.endArena(this,this.player1,this.player2,"Player Has Left Arena");
|
||||
return true;
|
||||
}else if (!inRange.contains(this.player2) && !inRange.contains(this.player1)) {
|
||||
ArenaManager.endArena(this,null,null,"Both Parties Have Left The Arena");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public Boolean checkToComplete(){
|
||||
|
||||
if(this.startTime == null)
|
||||
this.startTime = System.currentTimeMillis();
|
||||
|
||||
if(System.currentTimeMillis() - this.startTime < 10000L)
|
||||
return false;
|
||||
|
||||
if(this.disqualify())
|
||||
return true;
|
||||
|
||||
if(!this.player1.isAlive() && this.player2.isAlive()){
|
||||
ArenaManager.endArena(this,this.player2,this.player1,"Player Has Died");
|
||||
return true;
|
||||
} else if(this.player1.isAlive() && !this.player2.isAlive()){
|
||||
ArenaManager.endArena(this,this.player1,this.player2,"Player Has Died");
|
||||
return true;
|
||||
} else if(!this.player1.isAlive() && !this.player2.isAlive()){
|
||||
ArenaManager.endArena(this,null,null,"Both Players Have Died");
|
||||
return true;
|
||||
} else if(this.startTime + 300000L < System.currentTimeMillis()){
|
||||
ArenaManager.endArena(this,null,null,"Time Has Elapsed");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
+152
-25
@@ -14,19 +14,19 @@ import engine.Enum.ProtectionState;
|
||||
import engine.Enum.SiegePhase;
|
||||
import engine.Enum.SiegeResult;
|
||||
import engine.InterestManagement.HeightMap;
|
||||
import engine.InterestManagement.InterestManager;
|
||||
import engine.InterestManagement.WorldGrid;
|
||||
import engine.db.archive.BaneRecord;
|
||||
import engine.db.archive.DataWarehouse;
|
||||
import engine.gameManager.BuildingManager;
|
||||
import engine.gameManager.ChatManager;
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.gameManager.ZoneManager;
|
||||
import engine.gameManager.*;
|
||||
import engine.job.JobScheduler;
|
||||
import engine.jobs.ActivateBaneJob;
|
||||
import engine.jobs.BaneDefaultTimeJob;
|
||||
import engine.math.Vector3fImmutable;
|
||||
import engine.net.Dispatch;
|
||||
import engine.net.DispatchMessage;
|
||||
import engine.net.client.ClientConnection;
|
||||
import engine.net.client.msg.CityDataMsg;
|
||||
import engine.net.client.msg.PlaceAssetMsg;
|
||||
import engine.net.client.msg.chat.ChatSystemMsg;
|
||||
import engine.server.MBServerStatics;
|
||||
@@ -37,6 +37,7 @@ import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public final class Bane {
|
||||
@@ -48,6 +49,10 @@ public final class Bane {
|
||||
private DateTime placementDate = null;
|
||||
private DateTime liveDate = null;
|
||||
private BaneDefaultTimeJob defaultTimeJob;
|
||||
public boolean timeSet = false;
|
||||
public boolean daySet = false;
|
||||
public boolean capSet = false;
|
||||
public int capSize = 10;
|
||||
|
||||
// Internal cache for banes
|
||||
private ActivateBaneJob activateBaneJob;
|
||||
@@ -64,6 +69,12 @@ public final class Bane {
|
||||
this.ownerUUID = rs.getInt("ownerUUID");
|
||||
this.stoneUUID = rs.getInt("stoneUUID");
|
||||
|
||||
this.timeSet = rs.getInt("time_set") == 1;
|
||||
this.daySet = rs.getInt("day_set") == 1;
|
||||
this.capSet = rs.getInt("cap_set") == 1;
|
||||
this.capSize = rs.getInt("cap_size");
|
||||
|
||||
|
||||
sqlDateTime = rs.getTimestamp("placementDate");
|
||||
|
||||
if (sqlDateTime != null)
|
||||
@@ -100,12 +111,11 @@ public final class Bane {
|
||||
abtj = new ActivateBaneJob(cityUUID);
|
||||
JobScheduler.getInstance().scheduleJob(abtj, this.liveDate.getMillis());
|
||||
this.activateBaneJob = abtj;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (this.liveDate == null)
|
||||
setDefaultTime();
|
||||
//add bane commander NPC
|
||||
//summonBaneCommander(this);
|
||||
}
|
||||
|
||||
public static boolean summonBanestone(PlayerCharacter player, ClientConnection origin, int rank) {
|
||||
@@ -266,9 +276,58 @@ public final class Bane {
|
||||
BaneRecord baneRecord = BaneRecord.borrow(bane, Enum.RecordEventType.PENDING);
|
||||
DataWarehouse.pushToWarehouse(baneRecord);
|
||||
|
||||
//add bane commander NPC
|
||||
summonBaneCommander(bane);
|
||||
|
||||
try {
|
||||
//update map for all players online
|
||||
for (PlayerCharacter playerCharacter : SessionManager.getAllActivePlayerCharacters()) {
|
||||
CityDataMsg cityDataMsg = new CityDataMsg(SessionManager.getSession(playerCharacter), false);
|
||||
cityDataMsg.updateMines(true);
|
||||
cityDataMsg.updateCities(true);
|
||||
Dispatch dispatch = Dispatch.borrow(playerCharacter, cityDataMsg);
|
||||
DispatchMessage.dispatchMsgDispatch(dispatch, Enum.DispatchChannel.SECONDARY);
|
||||
}
|
||||
}catch(Exception e){
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void summonBaneCommander(Bane bane){
|
||||
Vector3fImmutable spawnLoc = Vector3fImmutable.getRandomPointOnCircle(bane.getStone().loc,6);
|
||||
NPC baneCommander;
|
||||
int commanderuuid = DbManager.NPCQueries.BANE_COMMANDER_EXISTS(bane.getStone().getObjectUUID());
|
||||
|
||||
if(commanderuuid == 0) {
|
||||
//add bane commander NPC
|
||||
int contractID = 1502042;
|
||||
baneCommander = NPC.createNPC("Bane Commander", contractID, spawnLoc, bane.getCity().getGuild(), ZoneManager.findSmallestZone(bane.getStone().loc), (short) 70, bane.getStone());
|
||||
try {
|
||||
NPCManager.slotCharacterInBuilding(baneCommander);
|
||||
}catch(Exception e){
|
||||
|
||||
}
|
||||
WorldGrid.addObject(baneCommander,spawnLoc.x,spawnLoc.z);
|
||||
WorldGrid.updateObject(baneCommander);
|
||||
}
|
||||
else
|
||||
{
|
||||
baneCommander = NPC.getNPC(commanderuuid);
|
||||
}
|
||||
//try {
|
||||
// NPCManager.slotCharacterInBuilding(baneCommander);
|
||||
//}catch (Exception e){
|
||||
//swallow it
|
||||
//}
|
||||
baneCommander.runAfterLoad();
|
||||
//baneCommander.setLoc(spawnLoc);
|
||||
InterestManager.setObjectDirty(baneCommander);
|
||||
|
||||
baneCommander.updateLocation();
|
||||
}
|
||||
|
||||
public static Bane getBane(int cityUUID) {
|
||||
|
||||
Bane outBane;
|
||||
@@ -369,28 +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))
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -448,6 +503,16 @@ public final class Bane {
|
||||
return false;
|
||||
}
|
||||
|
||||
//Remove bane commander NPC
|
||||
if(!baneStone.getHirelings().isEmpty()) {
|
||||
NPC npc = (NPC)baneStone.getHirelings().keySet().stream().findFirst().orElse(null);
|
||||
if(npc != null) {
|
||||
DbManager.NPCQueries.DELETE_NPC(npc);
|
||||
DbManager.removeFromCache(npc);
|
||||
WorldGrid.RemoveWorldObject(npc);
|
||||
WorldGrid.removeObject(npc);
|
||||
}
|
||||
}
|
||||
// Remove object from simulation
|
||||
|
||||
baneStone.removeFromCache();
|
||||
@@ -469,6 +534,9 @@ public final class Bane {
|
||||
return liveDate;
|
||||
}
|
||||
|
||||
public void setLiveDate_NEW(DateTime baneTime) {
|
||||
|
||||
}
|
||||
public void setLiveDate(DateTime baneTime) {
|
||||
|
||||
if (DbManager.BaneQueries.SET_BANE_TIME(baneTime, this.getCity().getObjectUUID())) {
|
||||
@@ -644,4 +712,63 @@ public final class Bane {
|
||||
return cityUUID;
|
||||
}
|
||||
|
||||
public void applyZergBuffs(){
|
||||
City city = this.getCity();
|
||||
if(city == null)
|
||||
return;
|
||||
|
||||
city.onEnter();
|
||||
|
||||
ArrayList<Integer> attackers = new ArrayList<>();
|
||||
ArrayList<Integer> defenders = new ArrayList<>();
|
||||
Guild attackNation = this.getOwner().getGuild().getNation();
|
||||
Guild defendNation = this.getCity().getGuild().getNation();
|
||||
HashSet<AbstractWorldObject> inSiegeRange = WorldGrid.getObjectsInRangePartial(city.getTOL().loc,1750f,1);
|
||||
for(AbstractWorldObject obj : inSiegeRange){
|
||||
int uuid = obj.getObjectUUID();
|
||||
PlayerCharacter player = PlayerCharacter.getPlayerCharacter(uuid);
|
||||
if(player == null)
|
||||
continue;
|
||||
Guild playerNation = player.guild.getNation();
|
||||
//separate the players into categories
|
||||
if(playerNation.equals(defendNation))
|
||||
defenders.add(uuid);
|
||||
else if(playerNation.equals(attackNation))
|
||||
attackers.add(uuid);
|
||||
else
|
||||
MovementManager.translocate(player,Vector3fImmutable.getRandomPointOnCircle(ZoneManager.getZoneByUUID(656).getLoc(),30f),Regions.GetRegionForTeleport(ZoneManager.getZoneByUUID(656).getLoc()));
|
||||
}
|
||||
int attackerSize = 0;
|
||||
int defenderSize = 0;
|
||||
for(int uuid : city.baneAttendees.keySet()){
|
||||
PlayerCharacter player = PlayerCharacter.getPlayerCharacter(uuid);
|
||||
if(player == null)
|
||||
continue;
|
||||
if(player.guild.getNation().equals(defendNation))
|
||||
defenderSize += 1;
|
||||
else if(player.guild.getNation().equals(attackNation))
|
||||
attackerSize += 1;
|
||||
}
|
||||
|
||||
//apply zerg mechanic for attackers
|
||||
float attackerMultiplier = ZergManager.getCurrentMultiplier(attackerSize,this.capSize);
|
||||
float defenderMultiplier = ZergManager.getCurrentMultiplier(defenderSize,this.capSize);
|
||||
for(int uuid : attackers){
|
||||
PlayerCharacter player = PlayerCharacter.getPlayerCharacter(uuid);
|
||||
if(inSiegeRange.contains(player)) //player is still physically here, needs updated multiplier
|
||||
player.ZergMultiplier = attackerMultiplier;
|
||||
else
|
||||
player.ZergMultiplier = 1.0f;
|
||||
}
|
||||
|
||||
for(int uuid : defenders){
|
||||
PlayerCharacter player = PlayerCharacter.getPlayerCharacter(uuid);
|
||||
if(inSiegeRange.contains(player)) //player is still physically here, needs updated multiplier
|
||||
player.ZergMultiplier = defenderMultiplier;
|
||||
else
|
||||
player.ZergMultiplier = 1.0f;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -1056,6 +1056,7 @@ public class CharacterItemManager {
|
||||
// add to Bank
|
||||
this.bank.add(i);
|
||||
i.addToCache();
|
||||
i.stripCastableEnchants();
|
||||
|
||||
calculateWeights();
|
||||
|
||||
@@ -1204,6 +1205,7 @@ public class CharacterItemManager {
|
||||
|
||||
calculateWeights();
|
||||
|
||||
i.stripCastableEnchants();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@ import java.sql.SQLException;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
@@ -88,6 +89,8 @@ public class City extends AbstractWorldObject {
|
||||
private boolean reverseKOS = false;
|
||||
private String hash;
|
||||
|
||||
public HashMap<Integer, Long> baneAttendees = new HashMap<>();
|
||||
|
||||
/**
|
||||
* ResultSet Constructor
|
||||
*/
|
||||
@@ -234,7 +237,24 @@ public class City extends AbstractWorldObject {
|
||||
writer.putInt(rulingGuild.getObjectUUID());
|
||||
|
||||
writer.putString(rulingGuild.getName());
|
||||
writer.putString(city.motto);
|
||||
try {
|
||||
if (city.getBane() != null) {
|
||||
Bane bane = city.getBane();
|
||||
if (bane.daySet && bane.timeSet && bane.getLiveDate() != null) {
|
||||
int day = bane.getLiveDate().dayOfMonth().get();
|
||||
int month = bane.getLiveDate().getMonthOfYear();
|
||||
int year = bane.getLiveDate().year().get();
|
||||
int hour = bane.getLiveDate().getHourOfDay();
|
||||
writer.putString("BANE SET: " + month + "/" + day + "/" + year + " " + hour + ":00 CST");
|
||||
} else {
|
||||
writer.putString("BANED!: Unset");
|
||||
}
|
||||
} else {
|
||||
writer.putString(city.motto);
|
||||
}
|
||||
}catch(Exception e){
|
||||
writer.putString(city.motto);
|
||||
}
|
||||
writer.putString(rulingGuild.getLeadershipType());
|
||||
|
||||
// Serialize guild ruler's name
|
||||
@@ -320,8 +340,11 @@ public class City extends AbstractWorldObject {
|
||||
writer.putFloat(city.location.y);
|
||||
writer.putFloat(city.location.z);
|
||||
|
||||
writer.putInt(city.siegesWithstood);
|
||||
|
||||
if(city.getBane() != null) {
|
||||
writer.putInt(city.getBane().capSize);
|
||||
}else{
|
||||
writer.putInt(0);
|
||||
}
|
||||
writer.put((byte) 1);
|
||||
writer.put((byte) 0);
|
||||
writer.putInt(0x64);
|
||||
@@ -989,7 +1012,7 @@ public class City extends AbstractWorldObject {
|
||||
|
||||
// Gather current list of players within the zone bounds
|
||||
|
||||
currentPlayers = WorldGrid.getObjectsInRangePartial(this.location, CityBoundsType.ZONE.extents, MBServerStatics.MASK_PLAYER);
|
||||
currentPlayers = WorldGrid.getObjectsInRangePartial(this.location, 1500, MBServerStatics.MASK_PLAYER);
|
||||
currentMemory = new HashSet<>();
|
||||
|
||||
for (AbstractWorldObject playerObject : currentPlayers) {
|
||||
@@ -1001,7 +1024,15 @@ public class City extends AbstractWorldObject {
|
||||
currentMemory.add(player.getObjectUUID());
|
||||
|
||||
// Player is already in our memory
|
||||
|
||||
if(this.getBane() != null){
|
||||
//handle zerg mechanics here
|
||||
if(this.getBane().getSiegePhase().equals(SiegePhase.WAR)){
|
||||
//bane is live, start tallying players
|
||||
if(!this.baneAttendees.containsKey(player.getObjectUUID())){
|
||||
this.baneAttendees.put(player.getObjectUUID(),System.currentTimeMillis());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (_playerMemory.contains(player.getObjectUUID()))
|
||||
continue;
|
||||
|
||||
@@ -1028,14 +1059,29 @@ public class City extends AbstractWorldObject {
|
||||
} catch (Exception e) {
|
||||
Logger.error(e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void onExitBane() {
|
||||
ArrayList<Integer> toRemove = new ArrayList<>();
|
||||
for (Integer uuid : this.baneAttendees.keySet()) {
|
||||
if (!_playerMemory.contains(uuid)) {
|
||||
long timeGone = System.currentTimeMillis() - this.baneAttendees.get(uuid).longValue();
|
||||
if (timeGone > 180000L) { // 3 minutes
|
||||
toRemove.add(uuid); // Mark for removal
|
||||
}
|
||||
}
|
||||
}
|
||||
for(int uuid : toRemove){
|
||||
this.baneAttendees.remove(uuid);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void onExit(HashSet<Integer> currentMemory) {
|
||||
|
||||
PlayerCharacter player;
|
||||
int playerUUID = 0;
|
||||
HashSet<Integer> toRemove = new HashSet<>();
|
||||
HashSet<Integer> toRemoveStandard = new HashSet<>();
|
||||
Iterator<Integer> iter = _playerMemory.iterator();
|
||||
|
||||
while (iter.hasNext()) {
|
||||
@@ -1057,21 +1103,28 @@ public class City extends AbstractWorldObject {
|
||||
|
||||
this.removeAllCityEffects(player, false);
|
||||
|
||||
player.ZergMultiplier = 1.0f;
|
||||
// We will remove this player after iteration is complete
|
||||
// so store it in a temporary collection
|
||||
|
||||
toRemove.add(playerUUID);
|
||||
toRemoveStandard.add(playerUUID);
|
||||
// ***For debugging
|
||||
// Logger.info("PlayerMemory for ", this.getCityName() + ": " + _playerMemory.size());
|
||||
}
|
||||
|
||||
// Remove players from city memory
|
||||
|
||||
_playerMemory.removeAll(toRemove);
|
||||
for (Integer removalUUID : toRemove) {
|
||||
_playerMemory.removeAll(toRemoveStandard);
|
||||
for (Integer removalUUID : toRemoveStandard) {
|
||||
if (this.cityOutlaws.contains(removalUUID))
|
||||
this.cityOutlaws.remove(removalUUID);
|
||||
}
|
||||
if(this.getBane() != null){
|
||||
//handle zerg mechanics here
|
||||
if(this.getBane().getSiegePhase().equals(SiegePhase.WAR)){
|
||||
this.onExitBane();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int getWarehouseBuildingID() {
|
||||
|
||||
@@ -11,7 +11,13 @@ package engine.objects;
|
||||
|
||||
import ch.claude_martin.enumbitset.EnumBitSet;
|
||||
import engine.Enum;
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.QuestSystem.QuestManager;
|
||||
import engine.gameManager.*;
|
||||
import engine.net.Dispatch;
|
||||
import engine.net.DispatchMessage;
|
||||
import engine.net.client.msg.CityDataMsg;
|
||||
import engine.net.client.msg.ErrorPopupMsg;
|
||||
import org.joda.time.DateTime;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
@@ -190,6 +196,303 @@ public class Contract extends AbstractGameObject {
|
||||
return this.vendorDialog;
|
||||
}
|
||||
|
||||
public static VendorDialog HandleArenaMaster(int optionId, NPC npc, PlayerCharacter pc){
|
||||
//1502043
|
||||
pc.setLastNPCDialog(npc);
|
||||
VendorDialog vd = new VendorDialog(VendorDialog.getHostileVendorDialog().getDialogType(),VendorDialog.getHostileVendorDialog().getIntro(),-1);//VendorDialog.getHostileVendorDialog();
|
||||
vd.getOptions().clear();
|
||||
|
||||
switch(optionId){
|
||||
case 15020431:
|
||||
//if(pc.isBoxed){
|
||||
// ChatManager.chatSystemInfo(pc, "You Cannot Join The Que, You Are Boxed");
|
||||
//}else {
|
||||
if (ArenaManager.playerQueue.contains(pc)) {
|
||||
ChatManager.chatSystemInfo(pc, "You Are Already In The Arena Que");
|
||||
} else {
|
||||
ArenaManager.joinQueue(pc);
|
||||
ChatManager.chatSystemInfo(pc, "You Have Joined The Arena Que");
|
||||
}
|
||||
//}
|
||||
break;
|
||||
case 15020432:
|
||||
if(ArenaManager.playerQueue.contains(pc)) {
|
||||
ArenaManager.leaveQueue(pc);
|
||||
ChatManager.chatSystemInfo(pc, "You Have Left The Arena Que");
|
||||
}else{
|
||||
ChatManager.chatSystemInfo(pc, "You Are Not In The Arena Que");
|
||||
}
|
||||
break;
|
||||
}
|
||||
MenuOption option1 = new MenuOption(15020431, "Join Arena Que", 15020431);
|
||||
vd.getOptions().add(option1);
|
||||
MenuOption option2 = new MenuOption(15020432, "Leave Arena Que", 15020432);
|
||||
vd.getOptions().add(option2);
|
||||
return vd;
|
||||
}
|
||||
public static VendorDialog HandleEnrollmentOfficer(int optionId, NPC npc, PlayerCharacter pc){
|
||||
pc.setLastNPCDialog(npc);
|
||||
//VendorDialog vd = new VendorDialog(npc.contract.getVendorDialog().getDialogType(),npc.contract.getVendorDialog().getIntro(),-1);//VendorDialog.getHostileVendorDialog();
|
||||
VendorDialog vd = new VendorDialog(npc.contract.getVendorDialog().getDialogType(),npc.contract.getVendorDialog().getIntro(),-1);//VendorDialog.getHostileVendorDialog();
|
||||
vd.getOptions().clear();
|
||||
switch(optionId) {
|
||||
default:
|
||||
if (pc.isBoxed) {
|
||||
MenuOption option1 = new MenuOption(15020401, "Unbox Character", 15020401);
|
||||
vd.getOptions().add(option1);
|
||||
}
|
||||
break;
|
||||
case 15020401:
|
||||
PlayerCharacter.unboxPlayer(pc);
|
||||
vd.getOptions().clear();
|
||||
break;
|
||||
}
|
||||
return vd;
|
||||
}
|
||||
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();
|
||||
vd.getOptions().clear();
|
||||
Building building = npc.building;
|
||||
Bane bane = null;
|
||||
int updateBaneTime = 0;
|
||||
int updateBaneDay = 0;
|
||||
int updateBaneCap = 0;
|
||||
|
||||
int treesInNation = 0;
|
||||
if(building != null)
|
||||
{
|
||||
City city = ZoneManager.getCityAtLocation(building.loc);
|
||||
if(city != null){
|
||||
bane = city.getBane();
|
||||
if(!city.getGuild().equals(pc.guild))
|
||||
return vd;
|
||||
|
||||
if(!GuildStatusController.isInnerCouncil(pc.getGuildStatus()) && !GuildStatusController.isGuildLeader(pc.getGuildStatus())){
|
||||
return vd;
|
||||
}
|
||||
for(Guild sub : city.getGuild().getNation().getSubGuildList()){
|
||||
if(sub.getOwnedCity() != null){
|
||||
treesInNation += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(bane == null){
|
||||
return VendorDialog.getHostileVendorDialog();
|
||||
}
|
||||
if(bane.timeSet && bane.capSet && bane.daySet){
|
||||
vd.getOptions().clear();
|
||||
return vd;
|
||||
}
|
||||
|
||||
DateTime placement = bane.getPlacementDate();
|
||||
vd.getOptions().clear();
|
||||
switch(optionId){
|
||||
default:
|
||||
if(!bane.daySet) {
|
||||
MenuOption option1 = new MenuOption(796, "Set Bane Day", 796);
|
||||
vd.getOptions().add(option1);
|
||||
}
|
||||
if(!bane.timeSet) {
|
||||
MenuOption option2 = new MenuOption(797, "Set Bane Time", 797);
|
||||
vd.getOptions().add(option2);
|
||||
}
|
||||
if(!bane.capSet) {
|
||||
MenuOption option3 = new MenuOption(797, "Set Bane Cap", 798);
|
||||
vd.getOptions().add(option3);
|
||||
}
|
||||
break;
|
||||
case 796: // set bane day
|
||||
DateTime dayOption1Date = placement.plusDays(3);
|
||||
MenuOption dayOption1 = new MenuOption(7961, dayOption1Date.toString("yyyy-MM-dd"), 7961);
|
||||
vd.getOptions().add(dayOption1);
|
||||
|
||||
DateTime dayOption2Date = placement.plusDays(4);
|
||||
MenuOption dayOption2 = new MenuOption(7962, dayOption2Date.toString("yyyy-MM-dd"), 7962);
|
||||
vd.getOptions().add(dayOption2);
|
||||
|
||||
DateTime dayOption3Date = placement.plusDays(5);
|
||||
MenuOption dayOption3 = new MenuOption(7963, dayOption3Date.toString("yyyy-MM-dd"), 7963);
|
||||
vd.getOptions().add(dayOption3);
|
||||
|
||||
DateTime dayOption4Date = placement.plusDays(6);
|
||||
MenuOption dayOption4 = new MenuOption(7964, dayOption4Date.toString("yyyy-MM-dd"), 7964);
|
||||
vd.getOptions().add(dayOption4);
|
||||
|
||||
DateTime dayOption5Date = placement.plusDays(7);
|
||||
MenuOption dayOption5 = new MenuOption(7965, dayOption5Date.toString("yyyy-MM-dd"), 7965);
|
||||
vd.getOptions().add(dayOption5);
|
||||
break;
|
||||
case 797: // set bane time
|
||||
MenuOption timeOption1 = new MenuOption(7971, "6:00 pm CST", 7971);
|
||||
vd.getOptions().add(timeOption1);
|
||||
|
||||
MenuOption timeOption2 = new MenuOption(7972, "7:00 pm CST", 7972);
|
||||
vd.getOptions().add(timeOption2);
|
||||
|
||||
MenuOption timeOption3 = new MenuOption(7973, "8:00 pm CST", 7973);
|
||||
vd.getOptions().add(timeOption3);
|
||||
|
||||
MenuOption timeOption4 = new MenuOption(7974, "9:00 pm CST", 7974);
|
||||
vd.getOptions().add(timeOption4);
|
||||
|
||||
MenuOption timeOption5 = new MenuOption(7975, "10:00 pm CST", 7975);
|
||||
vd.getOptions().add(timeOption5);
|
||||
break;
|
||||
case 798: // set bane cap
|
||||
if(treesInNation < 6) {
|
||||
MenuOption capOption1 = new MenuOption(7981, "10 Maximum Players", 7981);
|
||||
vd.getOptions().add(capOption1);
|
||||
}
|
||||
|
||||
if(treesInNation < 11) {
|
||||
MenuOption capOption2 = new MenuOption(7982, "20 Maximum Players", 7982);
|
||||
vd.getOptions().add(capOption2);
|
||||
}
|
||||
|
||||
MenuOption capOption3 = new MenuOption(7983, "30 Maximum Players", 7983);
|
||||
vd.getOptions().add(capOption3);
|
||||
|
||||
MenuOption capOption4 = new MenuOption(7984, "40 Maximum Players", 7984);
|
||||
vd.getOptions().add(capOption4);
|
||||
|
||||
MenuOption capOption5 = new MenuOption(7985, "Unlimited Players", 7985);
|
||||
vd.getOptions().add(capOption5);
|
||||
|
||||
break;
|
||||
|
||||
case 7961: //3 days after placement
|
||||
ErrorPopupMsg.sendErrorMsg(pc, "Bane Set 3 Days From Placement Date");
|
||||
updateBaneDay = 3;
|
||||
break;
|
||||
case 7962: //4 days after placement
|
||||
ErrorPopupMsg.sendErrorMsg(pc, "Bane Set 4 Days From Placement Date");
|
||||
updateBaneDay = 4;
|
||||
break;
|
||||
case 7963: //5 days after placement
|
||||
ErrorPopupMsg.sendErrorMsg(pc, "Bane Set 5 Days From Placement Date");
|
||||
updateBaneDay = 5;
|
||||
break;
|
||||
case 7964: //6 days after placement
|
||||
ErrorPopupMsg.sendErrorMsg(pc, "Bane Set 6 Days From Placement Date");
|
||||
updateBaneDay = 6;
|
||||
break;
|
||||
case 7965: //7 days after placement
|
||||
ErrorPopupMsg.sendErrorMsg(pc, "Bane Set 7 Days From Placement Date");
|
||||
updateBaneDay = 7;
|
||||
break;
|
||||
case 7971: //6:00pm CST
|
||||
ErrorPopupMsg.sendErrorMsg(pc, "Bane Set For 6:00 pm CST");
|
||||
updateBaneTime = 6;
|
||||
break;
|
||||
case 7972: //7:00pm CST
|
||||
ErrorPopupMsg.sendErrorMsg(pc, "Bane Set For 7:00 pm CST");
|
||||
updateBaneTime = 7;
|
||||
break;
|
||||
case 7973: //8:00pm CST
|
||||
ErrorPopupMsg.sendErrorMsg(pc, "Bane Set For 8:00 pm CST");
|
||||
updateBaneTime = 8;
|
||||
break;
|
||||
case 7974: //9:00pm CST
|
||||
ErrorPopupMsg.sendErrorMsg(pc, "Bane Set For 9:00 pm CST");
|
||||
updateBaneTime = 9;
|
||||
break;
|
||||
case 7975: //10:00pm CST
|
||||
ErrorPopupMsg.sendErrorMsg(pc, "Bane Set For 10:00 pm CST");
|
||||
updateBaneTime = 10;
|
||||
break;
|
||||
case 7981: //cap = 10
|
||||
ErrorPopupMsg.sendErrorMsg(pc, "Bane Cap Set To 10 Players On Each Side");
|
||||
updateBaneCap = 10;
|
||||
break;
|
||||
case 7982: //cap = 20
|
||||
ErrorPopupMsg.sendErrorMsg(pc, "Bane Cap Set To 20 Players On Each Side");
|
||||
updateBaneCap = 20;
|
||||
break;
|
||||
case 7983: //cap = 30
|
||||
ErrorPopupMsg.sendErrorMsg(pc, "Bane Cap Set To 30 Players On Each Side");
|
||||
updateBaneCap = 30;
|
||||
break;
|
||||
case 7984: //cap = 40
|
||||
ErrorPopupMsg.sendErrorMsg(pc, "Bane Cap Set To 40 Players On Each Side");
|
||||
updateBaneCap = 40;
|
||||
break;
|
||||
case 7985: //cap = Unlimited
|
||||
ErrorPopupMsg.sendErrorMsg(pc, "Bane Cap Set To Unlimited Players On Each Side");
|
||||
updateBaneCap = 9999;
|
||||
break;
|
||||
}
|
||||
if (updateBaneDay > 0) {
|
||||
if(DbManager.BaneQueries.SET_BANE_DAY_NEW(updateBaneDay,bane.getCityUUID())){
|
||||
bane.daySet = true;
|
||||
if(bane.getLiveDate() == null) {
|
||||
bane.setLiveDate_NEW(bane.getPlacementDate().plusDays(updateBaneDay));
|
||||
}else{
|
||||
bane.setLiveDate_NEW(bane.getLiveDate().plusDays(updateBaneDay));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (updateBaneTime > 0) {
|
||||
if(DbManager.BaneQueries.SET_BANE_TIME_NEW(updateBaneTime,bane.getCityUUID())){
|
||||
bane.timeSet = true;
|
||||
if(bane.getLiveDate() == null) {
|
||||
bane.setLiveDate_NEW(bane.getPlacementDate().withHourOfDay(12 + updateBaneTime));
|
||||
}else{
|
||||
bane.setLiveDate_NEW(bane.getLiveDate().withHourOfDay(12 + updateBaneTime));
|
||||
}
|
||||
}
|
||||
bane.setLiveDate(DbManager.BaneQueries.getLiveDate(bane.getCityUUID()));
|
||||
}
|
||||
if (updateBaneCap > 0) {
|
||||
if(DbManager.BaneQueries.SET_BANE_CAP_NEW(updateBaneCap,bane.getCityUUID())){
|
||||
bane.capSet = true;
|
||||
bane.capSize = updateBaneCap;
|
||||
}
|
||||
}
|
||||
|
||||
if(updateBaneCap > 0 || updateBaneTime > 0 || updateBaneDay > 0) {
|
||||
bane.getSiegePhase();
|
||||
for (PlayerCharacter playerCharacter : SessionManager.getAllActivePlayerCharacters()) {
|
||||
CityDataMsg cityDataMsg = new CityDataMsg(SessionManager.getSession(playerCharacter), false);
|
||||
cityDataMsg.updateMines(true);
|
||||
cityDataMsg.updateCities(true);
|
||||
Dispatch dispatch = Dispatch.borrow(playerCharacter, cityDataMsg);
|
||||
DispatchMessage.dispatchMsgDispatch(dispatch, Enum.DispatchChannel.SECONDARY);
|
||||
}
|
||||
vd.getOptions().clear();
|
||||
if(!bane.daySet) {
|
||||
MenuOption option1 = new MenuOption(796, "Set Bane Day", 796);
|
||||
vd.getOptions().add(option1);
|
||||
}
|
||||
if(!bane.timeSet) {
|
||||
MenuOption option2 = new MenuOption(797, "Set Bane Time", 797);
|
||||
vd.getOptions().add(option2);
|
||||
}
|
||||
if(!bane.capSet) {
|
||||
MenuOption option3 = new MenuOption(797, "Set Bane Cap", 798);
|
||||
vd.getOptions().add(option3);
|
||||
}
|
||||
}
|
||||
|
||||
return vd;
|
||||
}
|
||||
|
||||
public static VendorDialog HandleQuestOptions(int optionId, NPC npc, PlayerCharacter pc){
|
||||
VendorDialog vd = new VendorDialog(npc.contract.getVendorDialog().getDialogType(),npc.contract.getVendorDialog().getIntro(),-1);
|
||||
//vd.getOptions().clear();
|
||||
switch(optionId) {
|
||||
default:
|
||||
MenuOption optionAcceptQuest = new MenuOption(25020401, "Accept Quest", 25020401);
|
||||
vd.getOptions().add(optionAcceptQuest);
|
||||
break;
|
||||
case 25020401:
|
||||
QuestManager.acceptQuest(pc,QuestManager.getQuestForContract(npc));
|
||||
break;
|
||||
}
|
||||
return vd;
|
||||
}
|
||||
|
||||
public ArrayList<Integer> getNPCMenuOptions() {
|
||||
return this.npcMenuOptions;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -346,6 +346,12 @@ public class Experience {
|
||||
if (killer == null || mob == null)
|
||||
return;
|
||||
|
||||
if(killer.equals(mob))
|
||||
return;
|
||||
|
||||
if(killer.pvpKills.contains(mob.getObjectUUID()))
|
||||
return;
|
||||
|
||||
double grantedExperience = 0.0;
|
||||
|
||||
if (g != null) { // Do group EXP stuff
|
||||
@@ -403,6 +409,7 @@ 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);
|
||||
|
||||
@@ -1085,6 +1085,7 @@ public class Item extends AbstractWorldObject {
|
||||
this.ownerID = pc.getObjectUUID();
|
||||
this.ownerType = OwnerType.PlayerCharacter;
|
||||
this.containerType = ItemContainerType.INVENTORY;
|
||||
this.stripCastableEnchants();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1105,6 +1106,7 @@ public class Item extends AbstractWorldObject {
|
||||
this.ownerID = npc.getObjectUUID();
|
||||
this.ownerType = OwnerType.Npc;
|
||||
this.containerType = Enum.ItemContainerType.INVENTORY;
|
||||
this.stripCastableEnchants();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1225,7 +1227,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() {
|
||||
|
||||
@@ -215,7 +215,7 @@ public class ItemFactory {
|
||||
pi.setAmount(itemsToRoll);
|
||||
pi.setRandom(false);
|
||||
|
||||
ItemQueue produced = ItemQueue.borrow(pi, (long) (time * Float.parseFloat(ConfigManager.MB_PRODUCTION_RATE.getValue())));
|
||||
ItemQueue produced = ItemQueue.borrow(pi, (long) time);
|
||||
ItemProductionManager.send(produced);
|
||||
|
||||
return ml;
|
||||
@@ -410,7 +410,7 @@ public class ItemFactory {
|
||||
|
||||
if (overdraft > 0 && !useWarehouse) {
|
||||
if (pc != null)
|
||||
ErrorPopupMsg.sendErrorMsg(pc, "Not enough gold in building strongbox." + ib.getName());
|
||||
ErrorPopupMsg.sendErrorMsg(pc, "Not enough gold in building strongbox. " + ib.getName());
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -936,7 +936,7 @@ public class ItemFactory {
|
||||
|
||||
//calculate gold costs and remove from the warehouse
|
||||
if (prefix != null || suffix != null) {
|
||||
int costToCreate = (int) (ib.getBaseValue() + ib.getBaseValue() * .10f);
|
||||
int costToCreate = ib.getBaseValue();
|
||||
int buildingWithdraw = BuildingManager.GetWithdrawAmountForRolling(forge, costToCreate);
|
||||
int overdraft = BuildingManager.GetOverdraft(forge, costToCreate);
|
||||
|
||||
|
||||
@@ -31,6 +31,13 @@ public class MenuOption extends AbstractGameObject {
|
||||
this.prereq = rs.getInt("prereq");
|
||||
}
|
||||
|
||||
public MenuOption(int id, String msg, int option){
|
||||
this.menuID = id;
|
||||
this.message = msg;
|
||||
this.optionID = option;
|
||||
this.prereq = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Getters
|
||||
*/
|
||||
|
||||
@@ -72,14 +72,30 @@ public class Mine extends AbstractGameObject {
|
||||
public Mine(ResultSet rs) throws SQLException, UnknownHostException {
|
||||
super(rs);
|
||||
|
||||
if (rs.getInt("capSize") == 0) {
|
||||
throw new IllegalArgumentException("Mine creation canceled: capSize cannot be 0");
|
||||
}
|
||||
|
||||
this.mineType = MineProduction.getByName(rs.getString("mine_type"));
|
||||
|
||||
int ownerUID = rs.getInt("mine_ownerUID");
|
||||
this.buildingID = rs.getInt("mine_buildingUID");
|
||||
this.flags = rs.getInt("flags");
|
||||
int parent = rs.getInt("parent");
|
||||
this.parentZone = ZoneManager.getZoneByUUID(parent);
|
||||
this.zoneName = this.parentZone.getParent().getName();
|
||||
if(ZoneManager.getZoneByUUID(parent) != null) {
|
||||
this.parentZone = ZoneManager.getZoneByUUID(parent);
|
||||
this.zoneName = this.parentZone.getParent().getName();
|
||||
}else{
|
||||
this.parentZone = ZoneManager.getSeaFloor();
|
||||
if(this.parentZone.getParent() != null)
|
||||
this.zoneName = this.parentZone.getParent().getName();
|
||||
else
|
||||
this.zoneName = "FAILED TO LOAD ZONE";
|
||||
Logger.error("MINE FAILED TO LOAD PARENT: ");
|
||||
Logger.error("MINE UID: " + rs.getInt("UID"));
|
||||
Logger.error("MINE buildingID: " + buildingID);
|
||||
|
||||
}
|
||||
|
||||
this.owningGuild = Guild.getGuild(ownerUID);
|
||||
Guild nation = null;
|
||||
@@ -319,6 +335,17 @@ public class Mine extends AbstractGameObject {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static ArrayList<Mine> getMinesToTeleportTo(PlayerCharacter player) {
|
||||
ArrayList<Mine> mines = new ArrayList<>();
|
||||
for(Mine mine : Mine.getMines())
|
||||
if(!mine.isActive)
|
||||
if(mine.getOwningGuild() != null)
|
||||
if(mine.getOwningGuild().getNation().equals(player.getGuild().getNation()))
|
||||
mines.add(mine);
|
||||
|
||||
return mines;
|
||||
}
|
||||
|
||||
public boolean changeProductionType(Resource resource) {
|
||||
if (!this.validForMine(resource))
|
||||
return false;
|
||||
@@ -418,7 +445,7 @@ public class Mine extends AbstractGameObject {
|
||||
writer.putInt(this.getModifiedProductionAmount());
|
||||
writer.putInt(this.getModifiedProductionAmount()); //TODO calculate range penalty here
|
||||
writer.putInt(3600); //window in seconds
|
||||
writer.putInt(this.isExpansion() ? this.mineType.xpacHash : this.mineType.hash);
|
||||
writer.putInt(this.mineType.hash);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -661,4 +688,134 @@ public class Mine extends AbstractGameObject {
|
||||
|
||||
_playerMemory.removeAll(toRemove);
|
||||
}
|
||||
public static Building getTower(Mine mine){
|
||||
Building tower = BuildingManager.getBuildingFromCache(mine.buildingID);
|
||||
if(tower != null)
|
||||
return tower;
|
||||
else
|
||||
return null;
|
||||
}
|
||||
public static void serializeForClientMsgTeleport(Mine mine, ByteBufferWriter writer) {
|
||||
AbstractCharacter guildRuler;
|
||||
Guild rulingGuild;
|
||||
Guild rulingNation;
|
||||
java.time.LocalDateTime dateTime1900;
|
||||
|
||||
// Cities aren't a mine without a TOL. Time to early exit.
|
||||
// No need to spam the log here as non-existant TOL's are indicated
|
||||
// during bootstrap routines.
|
||||
Building tower = Mine.getTower(mine);
|
||||
if (tower == null) {
|
||||
|
||||
Logger.error("NULL TOWER FOR " + mine.zoneName + " mine");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Assign mine owner
|
||||
|
||||
if (tower.getOwner() != null)
|
||||
guildRuler = tower.getOwner();
|
||||
else
|
||||
guildRuler = null;
|
||||
|
||||
// If is an errant tree, use errant guild for serialization.
|
||||
// otherwise we serialize the soverign guild
|
||||
|
||||
if (guildRuler == null)
|
||||
rulingGuild = Guild.getErrantGuild();
|
||||
else
|
||||
rulingGuild = guildRuler.getGuild();
|
||||
|
||||
rulingNation = rulingGuild.getNation();
|
||||
|
||||
// Begin Serialzing soverign guild data
|
||||
writer.putInt(mine.getObjectType().ordinal());
|
||||
writer.putInt(mine.getObjectUUID());
|
||||
writer.putString(mine.zoneName + " Mine");
|
||||
writer.putInt(rulingGuild.getObjectType().ordinal());
|
||||
writer.putInt(rulingGuild.getObjectUUID());
|
||||
|
||||
writer.putString(rulingGuild.getName());
|
||||
writer.putString("");
|
||||
writer.putString(rulingGuild.getLeadershipType());
|
||||
|
||||
// Serialize guild ruler's name
|
||||
// If tree is abandoned blank out the name
|
||||
// to allow them a rename.
|
||||
|
||||
if (guildRuler == null)
|
||||
writer.putString("");
|
||||
else
|
||||
writer.putString(guildRuler.getFirstName() + ' ' + guildRuler.getLastName());
|
||||
|
||||
writer.putInt(rulingGuild.getCharter());
|
||||
writer.putInt(0); // always 00000000
|
||||
|
||||
writer.put((byte)0);
|
||||
|
||||
writer.put((byte) 1);
|
||||
writer.put((byte) 1); // *** Refactor: What are these flags?
|
||||
writer.put((byte) 1);
|
||||
writer.put((byte) 1);
|
||||
writer.put((byte) 1);
|
||||
|
||||
GuildTag._serializeForDisplay(rulingGuild.getGuildTag(), writer);
|
||||
GuildTag._serializeForDisplay(rulingNation.getGuildTag(), writer);
|
||||
|
||||
writer.putInt(0);// TODO Implement description text
|
||||
|
||||
writer.put((byte) 1);
|
||||
writer.put((byte) 0);
|
||||
writer.put((byte) 1);
|
||||
|
||||
// Begin serializing nation guild info
|
||||
|
||||
if (rulingNation.isEmptyGuild()) {
|
||||
writer.putInt(rulingGuild.getObjectType().ordinal());
|
||||
writer.putInt(rulingGuild.getObjectUUID());
|
||||
} else {
|
||||
writer.putInt(rulingNation.getObjectType().ordinal());
|
||||
writer.putInt(rulingNation.getObjectUUID());
|
||||
}
|
||||
|
||||
|
||||
// Serialize nation name
|
||||
|
||||
if (rulingNation.isEmptyGuild())
|
||||
writer.putString("None");
|
||||
else
|
||||
writer.putString(rulingNation.getName());
|
||||
|
||||
writer.putInt(1);
|
||||
|
||||
writer.putInt(0xFFFFFFFF);
|
||||
|
||||
writer.putInt(0);
|
||||
|
||||
if (rulingNation.isEmptyGuild())
|
||||
writer.putString(" ");
|
||||
else
|
||||
writer.putString(Guild.GetGL(rulingNation).getFirstName() + ' ' + Guild.GetGL(rulingNation).getLastName());
|
||||
|
||||
writer.putLocalDateTime(LocalDateTime.now());
|
||||
|
||||
if(tower != null) {
|
||||
writer.putFloat(tower.loc.x);
|
||||
writer.putFloat(tower.loc.y);
|
||||
writer.putFloat(tower.loc.z);
|
||||
} else{
|
||||
writer.putFloat(0);
|
||||
writer.putFloat(0);
|
||||
writer.putFloat(0);
|
||||
}
|
||||
writer.putInt(0);
|
||||
|
||||
writer.put((byte) 1);
|
||||
writer.put((byte) 0);
|
||||
writer.putInt(0x64);
|
||||
writer.put((byte) 0);
|
||||
writer.put((byte) 0);
|
||||
writer.put((byte) 0);
|
||||
}
|
||||
}
|
||||
|
||||
+126
-220
@@ -12,7 +12,9 @@ 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.QuestSystem.QuestManager;
|
||||
import engine.exception.SerializationException;
|
||||
import engine.gameManager.*;
|
||||
import engine.job.JobScheduler;
|
||||
@@ -1270,6 +1272,15 @@ public class Mob extends AbstractIntelligenceAgent {
|
||||
// Give XP, now handled inside the Experience Object
|
||||
if (!this.isPet() && !this.isNecroPet() && !(this.agentType.equals(AIAgentType.PET)) && !this.isPlayerGuard)
|
||||
Experience.doExperience((PlayerCharacter) attacker, this, g);
|
||||
|
||||
//handle quest updates
|
||||
PlayerCharacter pc = (PlayerCharacter)attacker;
|
||||
if(QuestManager.acceptedQuests.containsKey(pc)){
|
||||
QuestManager.acceptedQuests.get(pc).tryProgress(this.firstName);
|
||||
QuestManager.completeQuest(pc,QuestManager.acceptedQuests.get(pc));
|
||||
}
|
||||
|
||||
|
||||
} else if (attacker.getObjectType().equals(GameObjectType.Mob)) {
|
||||
Mob mobAttacker = (Mob) attacker;
|
||||
|
||||
@@ -1326,8 +1337,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 +1416,8 @@ public class Mob extends AbstractIntelligenceAgent {
|
||||
Logger.error(e);
|
||||
}
|
||||
this.updateLocation();
|
||||
//resync corpses
|
||||
InterestManager.setObjectDirty(this);
|
||||
}
|
||||
|
||||
public void respawn() {
|
||||
@@ -1441,6 +1452,8 @@ public class Mob extends AbstractIntelligenceAgent {
|
||||
loadInventory();
|
||||
|
||||
this.updateLocation();
|
||||
this.stopPatrolTime = 0;
|
||||
this.lastPatrolPointIndex = 0;
|
||||
}
|
||||
|
||||
public void despawn() {
|
||||
@@ -1635,65 +1648,75 @@ 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;
|
||||
if(this.isDropper || Mob.discDroppers.contains(this)){
|
||||
this.defenseRating *= 2;
|
||||
this.atrHandOne *= 2;
|
||||
this.atrHandTwo *= 2;
|
||||
this.minDamageHandOne *= 2;
|
||||
this.minDamageHandTwo *= 2;
|
||||
this.maxDamageHandOne *= 2;
|
||||
this.maxDamageHandTwo *= 2;
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
public static int GetDefense(int defense, Mob mob){
|
||||
@@ -1829,168 +1852,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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2060,6 +1961,9 @@ public class Mob extends AbstractIntelligenceAgent {
|
||||
if(this.isDropper){
|
||||
this.setLevel((short)65);
|
||||
this.setResists(new Resists("Dropper"));
|
||||
this.atrHandOne *= 2;
|
||||
this.atrHandTwo *= 2;
|
||||
|
||||
}
|
||||
try {
|
||||
if (this.equipmentSetID != 0)
|
||||
@@ -2101,6 +2005,7 @@ public class Mob extends AbstractIntelligenceAgent {
|
||||
|
||||
try {
|
||||
NPCManager.applyRuneSetEffects(this);
|
||||
MobBase.applyMobbaseEffects(this);
|
||||
recalculateStats();
|
||||
this.setHealth(this.healthMax);
|
||||
|
||||
@@ -2152,6 +2057,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,19 @@ public class MobBase extends AbstractGameObject {
|
||||
return runCombat;
|
||||
}
|
||||
|
||||
public static void applyMobbaseEffects(Mob mob){
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ public class NPC extends AbstractCharacter {
|
||||
private HashSet<Integer> canRoll = null;
|
||||
public int parentZoneUUID;
|
||||
public int equipmentSetID = 0;
|
||||
private int repairCost = 5;
|
||||
private int specialPrice = 5;
|
||||
|
||||
// New NPC constructor. Fill in the blanks and then call
|
||||
// PERSIST.
|
||||
@@ -153,6 +153,12 @@ public class NPC extends AbstractCharacter {
|
||||
|
||||
this.name = rs.getString("npc_name");
|
||||
|
||||
try {
|
||||
this.specialPrice = rs.getInt("specialPrice");
|
||||
}catch(Exception e){
|
||||
this.specialPrice = 5;
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
Logger.error("NPC: " + this.dbID + " :" + e);
|
||||
e.printStackTrace();
|
||||
@@ -798,7 +804,7 @@ public class NPC extends AbstractCharacter {
|
||||
|
||||
@Override
|
||||
public void updateDatabase() {
|
||||
DbManager.NPCQueries.updateDatabase(this);
|
||||
DbManager.NPCQueries.updateSpecialPricing(this);
|
||||
}
|
||||
|
||||
public int getSymbol() {
|
||||
@@ -1290,12 +1296,13 @@ public class NPC extends AbstractCharacter {
|
||||
return name;
|
||||
}
|
||||
|
||||
public int getRepairCost() {
|
||||
return repairCost;
|
||||
public int getSpecialPrice() {
|
||||
return specialPrice;
|
||||
}
|
||||
|
||||
public void setRepairCost(int repairCost) {
|
||||
this.repairCost = repairCost;
|
||||
public void setSpecialPrice(int specialPrice) {
|
||||
this.specialPrice = specialPrice;
|
||||
DbManager.NPCQueries.updateSpecialPricing(this);
|
||||
}
|
||||
|
||||
public void processUpgradeNPC(PlayerCharacter player) {
|
||||
|
||||
@@ -26,7 +26,6 @@ import engine.job.JobScheduler;
|
||||
import engine.jobs.DeferredPowerJob;
|
||||
import engine.jobs.FinishSpireEffectJob;
|
||||
import engine.jobs.NoTimeJob;
|
||||
import engine.jobs.RefreshGroupJob;
|
||||
import engine.math.Bounds;
|
||||
import engine.math.FastMath;
|
||||
import engine.math.Vector3fImmutable;
|
||||
@@ -1301,7 +1300,7 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
|
||||
|
||||
if (ConfigManager.serverType.equals(ServerType.WORLDSERVER))
|
||||
player.setLoc(player.bindLoc);
|
||||
player.setLoc(player.getBindLoc());
|
||||
player.endLoc = Vector3fImmutable.ZERO;
|
||||
|
||||
//get level based on experience
|
||||
@@ -2048,7 +2047,8 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
public void respawn(boolean setAlive, boolean enterWorld, boolean makeCorpse) {
|
||||
|
||||
// Recalculate everything
|
||||
|
||||
if(this.timestamps.containsKey("DeathTime"))
|
||||
this.timestamps.remove("DeathTime");
|
||||
|
||||
this.recalculatePlayerStats(true);
|
||||
this.setCombat(false);
|
||||
@@ -2101,7 +2101,7 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
this.lastUpdateTime = System.currentTimeMillis();
|
||||
this.lastStamUpdateTime = System.currentTimeMillis();
|
||||
|
||||
this.update();
|
||||
this.update(false);
|
||||
|
||||
PowersManager.applyPower(this, this, Vector3fImmutable.ZERO, -1661758934, 40, false);
|
||||
|
||||
@@ -2206,6 +2206,10 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
if (bindLocation == null)
|
||||
bindLocation = Enum.Ruins.getRandomRuin().getLocation();
|
||||
|
||||
if(this.guild.getNation().equals(Guild.getErrantGuild())){
|
||||
bindLocation = Vector3fImmutable.getRandomPointOnCircle(BuildingManager.getBuilding(27977).loc,20f);
|
||||
}
|
||||
|
||||
return bindLocation;
|
||||
|
||||
}
|
||||
@@ -2891,7 +2895,7 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
|
||||
float speed;
|
||||
|
||||
if (this.getAltitude() > 0)
|
||||
if (this.isFlying())
|
||||
if (this.walkMode) {
|
||||
speed = race.getRaceType().getRunSpeed().getFlyWalk();
|
||||
} else {
|
||||
@@ -2911,7 +2915,8 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
speed = race.getRaceType().getRunSpeed().getRunStandard();
|
||||
}
|
||||
|
||||
float endSpeed = speed * this.speedMod;
|
||||
float mod = this.speedMod;
|
||||
float endSpeed = speed * mod;
|
||||
|
||||
if (endSpeed > 41 && !this.isCSR)
|
||||
endSpeed = 41;
|
||||
@@ -2920,6 +2925,24 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
}
|
||||
|
||||
public synchronized void grantXP(int xp) {
|
||||
int groupSize = 1;
|
||||
if(GroupManager.getGroup(this)!= null)
|
||||
groupSize = GroupManager.getGroup(this).members.size();
|
||||
if(this.promotionClass == null && this.level == 10){
|
||||
this.setOverFlowEXP(0);
|
||||
this.update(false);
|
||||
this.incVer();
|
||||
this.recalculate();
|
||||
this.calculateMaxHealthManaStamina();
|
||||
this.setHealth(this.healthMax);
|
||||
this.mana.set(this.manaMax);
|
||||
this.stamina.set(this.staminaMax);
|
||||
//LoadJob.reloadCharacter(this);
|
||||
DbManager.PlayerCharacterQueries.SET_PROPERTY(this, "char_experience", this.exp);
|
||||
// updateDatabase();
|
||||
DbManager.AccountQueries.INVALIDATE_LOGIN_CACHE(this.getObjectUUID(), "character");
|
||||
return;
|
||||
}
|
||||
// Stop players from getting experience past the cap
|
||||
if (this.exp + xp >= Experience.getBaseExperience(MBServerStatics.LEVELCAP))
|
||||
xp = Experience.getBaseExperience(MBServerStatics.LEVELCAP) - this.exp + 1;
|
||||
@@ -3055,6 +3078,14 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
SetObjectValueMsg upm = new SetObjectValueMsg(this, 9);
|
||||
DispatchMessage.dispatchMsgToInterestArea(this, upm, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, false, false);
|
||||
checkGuildStatus();
|
||||
|
||||
//give gold for level up if level is under or equal to 20 and over 10
|
||||
if(!this.isBoxed && this.level > 10 && this.level <= 20) {
|
||||
int gold = (int) ((100000 * (this.level - 10) / 55.0) );
|
||||
this.charItemManager.addGoldToInventory(gold, false);
|
||||
this.charItemManager.updateInventory();
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
this.exp += remainingXP;
|
||||
@@ -3068,7 +3099,7 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
}
|
||||
|
||||
if (charReloadRequired) {
|
||||
this.update();
|
||||
this.update(false);
|
||||
this.incVer();
|
||||
this.recalculate();
|
||||
this.calculateMaxHealthManaStamina();
|
||||
@@ -3102,26 +3133,8 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
public void calculateSpeedMod() {
|
||||
// get base race speed modifer
|
||||
|
||||
|
||||
//this is retarded. *** Refactor
|
||||
// if (this.race != null) {
|
||||
// int ID = this.race.getObjectUUID();
|
||||
// if (ID == 2004 || ID == 2005)
|
||||
// this.raceRunMod = 1.21f; // centaur run bonus 22%
|
||||
//// else if (ID == 2017)
|
||||
//// this.raceRunMod = 1.14f; // mino run bonus 15%
|
||||
// else
|
||||
// this.raceRunMod = 1;
|
||||
// } else
|
||||
// this.raceRunMod = 1;
|
||||
|
||||
|
||||
float bonus = 1f;
|
||||
|
||||
// // TODO: hardcoded, as didnt have time to introduce DB column to base object
|
||||
// if (baseClass.getName().equals("Fighter") || baseClass.getName().equals("Rogue"))
|
||||
// bonus += .05f;
|
||||
|
||||
// get running skill
|
||||
if (this.skills != null) {
|
||||
CharacterSkill running = this.skills.get("Running");
|
||||
@@ -3141,7 +3154,7 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
bonus += this.bonuses.getFloatPercentNullZero(ModType.Speed, SourceType.None);
|
||||
|
||||
// TODO get equip bonus
|
||||
this.update();
|
||||
this.update(false);
|
||||
this.speedMod = bonus;
|
||||
}
|
||||
|
||||
@@ -3174,14 +3187,6 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
return this.follow;
|
||||
}
|
||||
|
||||
public int getLastGroupToInvite() {
|
||||
return this.lastGroupToInvite;
|
||||
}
|
||||
|
||||
public void setLastGroupToInvite(int value) {
|
||||
this.lastGroupToInvite = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getAltitude() {
|
||||
if (this.altitude < 0)
|
||||
@@ -3230,10 +3235,6 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
return this.loadedStaticObjects;
|
||||
}
|
||||
|
||||
public void setLoadedStaticObjects(HashSet<AbstractWorldObject> value) {
|
||||
this.loadedStaticObjects = value;
|
||||
}
|
||||
|
||||
public boolean isTeleportMode() {
|
||||
return teleportMode;
|
||||
}
|
||||
@@ -3241,20 +3242,6 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
public void setTeleportMode(boolean teleportMode) {
|
||||
this.teleportMode = teleportMode;
|
||||
}
|
||||
|
||||
// public ConcurrentHashMap<Integer, FinishRecycleTimeJob>
|
||||
// getRecycleTimers() {
|
||||
// return this.recycleTimers;
|
||||
// }
|
||||
// public UsePowerJob getLastPower() {
|
||||
// return this.lastPower;
|
||||
// }
|
||||
// public void setLastPower(UsePowerJob value) {
|
||||
// this.lastPower = value;
|
||||
// }
|
||||
// public void clearLastPower() {
|
||||
// this.lastPower = null;
|
||||
// }
|
||||
public long chatFloodTime(int chatOpcode, long chatTimeMilli, int qtyToSave) {
|
||||
if (qtyToSave < 1)
|
||||
return 0L; // disabled
|
||||
@@ -3374,11 +3361,11 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
public void recalculatePlayerStats(boolean initialized) {
|
||||
|
||||
//calculate base stats
|
||||
calculateBaseStats();
|
||||
this.calculateBaseStats();
|
||||
|
||||
//calculate base skills
|
||||
CharacterSkill.updateAllBaseAmounts(this);
|
||||
calculateModifiedStats();
|
||||
this.calculateModifiedStats();
|
||||
|
||||
//calculate modified skills
|
||||
CharacterSkill.updateAllModifiedAmounts(this);
|
||||
@@ -3388,13 +3375,13 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
|
||||
|
||||
//calculate ATR, damage and defense
|
||||
calculateAtrDefenseDamage();
|
||||
this.calculateAtrDefenseDamage();
|
||||
|
||||
//calculate movement bonus
|
||||
calculateSpeedMod();
|
||||
this.calculateSpeedMod();
|
||||
|
||||
// recalculate Max Health/Mana/Stamina
|
||||
calculateMaxHealthManaStamina();
|
||||
this.calculateMaxHealthManaStamina();
|
||||
|
||||
// recalculate Resists
|
||||
Resists.calculateResists(this);
|
||||
@@ -3768,22 +3755,6 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
return this.statStrCurrent - this.race.getStrStart() - this.baseClass.getStrMod();
|
||||
}
|
||||
|
||||
public int getDexForClient() {
|
||||
return this.statDexCurrent - this.race.getDexStart() - this.baseClass.getDexMod();
|
||||
}
|
||||
|
||||
public int getConForClient() {
|
||||
return this.statConCurrent - this.race.getConStart() - this.baseClass.getConMod();
|
||||
}
|
||||
|
||||
public int getIntForClient() {
|
||||
return this.statIntCurrent - this.race.getIntStart() - this.baseClass.getIntMod();
|
||||
}
|
||||
|
||||
public int getSpiForClient() {
|
||||
return this.statSpiCurrent - this.race.getSpiStart() - this.baseClass.getSpiMod();
|
||||
}
|
||||
|
||||
public int getTrainsAvailable() {
|
||||
return this.trainsAvailable.get();
|
||||
}
|
||||
@@ -3821,15 +3792,6 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
}
|
||||
ConcurrentHashMap<Integer, Item> equipped = this.charItemManager.getEquipped();
|
||||
|
||||
// // Reset passives
|
||||
// if (this.bonuses != null) {
|
||||
// this.bonuses.setBool("Block", false);
|
||||
// this.bonuses.setBool("Parry", false);
|
||||
// if (this.baseClass != null && this.baseClass.getUUID() == 2502)
|
||||
// this.bonuses.setBool("Dodge", true);
|
||||
// else
|
||||
// this.bonuses.setBool("Dodge", false);
|
||||
// }
|
||||
// calculate atr and damage for each hand
|
||||
calculateAtrDamageForWeapon(equipped.get(MBServerStatics.SLOT_MAINHAND), true, equipped.get(MBServerStatics.SLOT_OFFHAND));
|
||||
calculateAtrDamageForWeapon(equipped.get(MBServerStatics.SLOT_OFFHAND), false, equipped.get(MBServerStatics.SLOT_MAINHAND));
|
||||
@@ -3882,7 +3844,7 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
|
||||
// make sure weapon exists
|
||||
boolean noWeapon = false;
|
||||
ItemBase wb = null;
|
||||
ItemBase weaponBase = null;
|
||||
if (weapon == null)
|
||||
noWeapon = true;
|
||||
else {
|
||||
@@ -3893,7 +3855,7 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
defaultAtrAndDamage(mainHand);
|
||||
return;
|
||||
} else
|
||||
wb = ib;
|
||||
weaponBase = ib;
|
||||
}
|
||||
float skillPercentage, masteryPercentage;
|
||||
float mastDam;
|
||||
@@ -3943,28 +3905,17 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
this.rangeHandTwo *= range_bonus;
|
||||
|
||||
}
|
||||
skillPercentage = getModifiedAmount(this.skills.get(wb.getSkillRequired()));
|
||||
masteryPercentage = getModifiedAmount(this.skills.get(wb.getMastery()));
|
||||
skillPercentage = getModifiedAmount(this.skills.get(weaponBase.getSkillRequired()));
|
||||
masteryPercentage = getModifiedAmount(this.skills.get(weaponBase.getMastery()));
|
||||
if (masteryPercentage == 0f)
|
||||
mastDam = 0f;
|
||||
// mastDam = CharacterSkill.getQuickMastery(this, wb.getMastery());
|
||||
// mastDam = CharacterSkill.getQuickMastery(this, weaponBase.getMastery());
|
||||
else
|
||||
mastDam = masteryPercentage;
|
||||
min = (float) wb.getMinDamage();
|
||||
max = (float) wb.getMaxDamage();
|
||||
strBased = wb.isStrBased();
|
||||
min = (float) weaponBase.getMinDamage();
|
||||
max = (float) weaponBase.getMaxDamage();
|
||||
strBased = weaponBase.isStrBased();
|
||||
|
||||
//
|
||||
// Add parry bonus for weapon and allow parry if needed
|
||||
|
||||
// // Only Fighters and Thieves can Parry
|
||||
// if ((this.baseClass != null && this.baseClass.getUUID() == 2500)
|
||||
// || (this.promotionClass != null && this.promotionClass.getUUID() == 2520)) {
|
||||
// if (wbMain == null || wbMain.getRange() < MBServerStatics.RANGED_WEAPON_RANGE)
|
||||
// if (wbOff == null || wbOff.getRange() < MBServerStatics.RANGED_WEAPON_RANGE)
|
||||
// this.bonuses.setBool("Parry", true);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
if (this.effects != null && this.effects.containsKey("DeathShroud"))
|
||||
@@ -3975,13 +3926,18 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
this.atrHandTwo = (short) 0;
|
||||
else {
|
||||
// calculate atr
|
||||
//(Primary Stat / 2) + (Weapon Skill * 4) + (Weapon Mastery * 3) + (ATR Enchantments) * 1.stance modifier
|
||||
float atr = 0;
|
||||
atr += (int) skillPercentage * 4f; //<-round down skill% -
|
||||
atr += (int) masteryPercentage * 3f;
|
||||
if (this.statStrCurrent > this.statDexCurrent)
|
||||
atr += statStrCurrent / 2;
|
||||
else
|
||||
atr += statDexCurrent / 2;
|
||||
int primaryStat;
|
||||
int dexMod = this.getDexMod();
|
||||
int strMod = this.getStrMod();
|
||||
if(weaponBase != null && weaponBase.isStrBased()){
|
||||
primaryStat = this.statStrCurrent;
|
||||
}else{
|
||||
primaryStat = this.statDexCurrent;
|
||||
}
|
||||
|
||||
atr = (primaryStat * 0.5f) + (skillPercentage * 4) + (masteryPercentage * 3);
|
||||
|
||||
// add in any bonuses to atr
|
||||
if (this.bonuses != null) {
|
||||
@@ -3992,10 +3948,6 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
float pos_Bonus = (1 + this.bonuses.getFloatPercentPositive(ModType.OCV, SourceType.None));
|
||||
atr *= pos_Bonus;
|
||||
|
||||
// next precise
|
||||
//runes will have their own bonuses.
|
||||
// atr *= (1 + ((float) this.bonuses.getShort("rune.Attack") / 100));
|
||||
|
||||
//and negative percent modifiers
|
||||
float neg_Bonus = this.bonuses.getFloatPercentNegative(ModType.OCV, SourceType.None);
|
||||
|
||||
@@ -4012,8 +3964,8 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
}
|
||||
|
||||
//calculate speed
|
||||
if (wb != null)
|
||||
speed = wb.getSpeed();
|
||||
if (weaponBase != null)
|
||||
speed = weaponBase.getSpeed();
|
||||
else
|
||||
speed = 20f; //unarmed attack speed
|
||||
if (weapon != null)
|
||||
@@ -4448,36 +4400,6 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
return (amount - attackerLevel + this.getLevel()) / 4;
|
||||
}
|
||||
|
||||
public float getPassiveChance1(ModType modType, SourceType sourceType, int attackerLevel, boolean fromCombat) {
|
||||
if (this.skills == null || this.bonuses == null)
|
||||
return 0f;
|
||||
|
||||
// must be allowed to use this passive
|
||||
if (!this.bonuses.getBool(modType, sourceType))
|
||||
return 0f;
|
||||
|
||||
// must not be stunned
|
||||
if (this.bonuses.getBool(ModType.Stunned, SourceType.None))
|
||||
return 0f;
|
||||
|
||||
// Get base skill amount
|
||||
CharacterSkill sk = this.skills.get(sourceType.name());
|
||||
float amount;
|
||||
if (sk == null)
|
||||
amount = CharacterSkill.getQuickMastery(this, modType.name());
|
||||
else
|
||||
amount = sk.getModifiedAmount();
|
||||
|
||||
// Add bonuses
|
||||
amount += this.bonuses.getFloat(modType, sourceType);
|
||||
|
||||
// Add item bonuses and return
|
||||
if (sourceType.equals(SourceType.Dodge) && !fromCombat)
|
||||
return ((amount / 4) - attackerLevel + this.getLevel()) / 4;
|
||||
else
|
||||
return (amount - attackerLevel + this.getLevel()) / 4;
|
||||
}
|
||||
|
||||
public float getRegenModifier(ModType type) {
|
||||
float regen = 1f;
|
||||
|
||||
@@ -4562,10 +4484,6 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
super.removeFromCache();
|
||||
}
|
||||
|
||||
public void storeIgnoreListDB() {
|
||||
|
||||
}
|
||||
|
||||
public void updateSkillsAndPowersToDatabase() {
|
||||
if (this.skills != null)
|
||||
for (CharacterSkill skill : this.skills.values()) {
|
||||
@@ -4620,7 +4538,7 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
|
||||
tmpLevel = targetLevel;
|
||||
|
||||
tmpLevel = (short) Math.min(tmpLevel, 75);
|
||||
tmpLevel = (short) Math.min(tmpLevel, MBServerStatics.LEVELCAP);
|
||||
|
||||
while (this.level < tmpLevel) {
|
||||
grantXP(Experience.getBaseExperience(tmpLevel) - this.exp);
|
||||
@@ -4734,17 +4652,6 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Method is called by Server Heartbeat simulation tick.
|
||||
// Stat regen and transform updates should go in here.
|
||||
|
||||
public boolean isNoTeleScreen() {
|
||||
return noTeleScreen;
|
||||
}
|
||||
|
||||
public void setNoTeleScreen(boolean noTeleScreen) {
|
||||
this.noTeleScreen = noTeleScreen;
|
||||
}
|
||||
|
||||
private double getDeltaTime() {
|
||||
|
||||
return (System.currentTimeMillis() - lastUpdateTime) * .001f;
|
||||
@@ -4786,101 +4693,47 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isSwimming(Vector3fImmutable currentLoc) {
|
||||
|
||||
// If char is flying they aren't quite swimming
|
||||
try {
|
||||
|
||||
float localAltitude = HeightMap.getWorldHeight(currentLoc);
|
||||
|
||||
Zone zone = ZoneManager.findSmallestZone(currentLoc);
|
||||
|
||||
if (zone.getSeaLevel() != 0) {
|
||||
|
||||
if (localAltitude < zone.getSeaLevel())
|
||||
return true;
|
||||
} else {
|
||||
if (localAltitude < 0)
|
||||
return true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Logger.info(this.getName() + e);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void forceRespawn(PlayerCharacter sourcePlayer) throws MsgSendException {
|
||||
|
||||
if (sourcePlayer == null)
|
||||
return;
|
||||
|
||||
if (sourcePlayer.isAlive()) {
|
||||
Logger.error("Player " + sourcePlayer.getObjectUUID() + " respawning while alive");
|
||||
return;
|
||||
}
|
||||
// ResetAfterDeath player
|
||||
sourcePlayer.respawnLock.writeLock().lock();
|
||||
try {
|
||||
sourcePlayer.respawn(true, false, true);
|
||||
|
||||
sourcePlayer.getClientConnection().disconnect();
|
||||
} catch (Exception e) {
|
||||
Logger.error(e);
|
||||
} finally {
|
||||
sourcePlayer.respawnLock.writeLock().unlock();
|
||||
|
||||
}
|
||||
RespawnMsg msg = new RespawnMsg();
|
||||
// Echo ResetAfterDeath message back
|
||||
msg.setPlayerHealth(sourcePlayer.getHealth());
|
||||
// TODO calculate any experience loss before this point
|
||||
msg.setPlayerExp(sourcePlayer.getExp() + sourcePlayer.getOverFlowEXP());
|
||||
Dispatch dispatch = Dispatch.borrow(sourcePlayer, msg);
|
||||
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY);
|
||||
|
||||
MoveToPointMsg moveMsg = new MoveToPointMsg();
|
||||
moveMsg.setPlayer(sourcePlayer);
|
||||
moveMsg.setStartCoord(sourcePlayer.getLoc());
|
||||
moveMsg.setEndCoord(sourcePlayer.getLoc());
|
||||
moveMsg.setInBuilding(-1);
|
||||
moveMsg.setUnknown01(-1);
|
||||
|
||||
dispatch = Dispatch.borrow(sourcePlayer, moveMsg);
|
||||
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY);
|
||||
|
||||
MovementManager.sendRWSSMsg(sourcePlayer);
|
||||
|
||||
// refresh the whole group with what just happened
|
||||
JobScheduler.getInstance().scheduleJob(new RefreshGroupJob(sourcePlayer), MBServerStatics.LOAD_OBJECT_DELAY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
public void update(Boolean newSystem) {
|
||||
|
||||
//if(!newSystem)
|
||||
// return;
|
||||
|
||||
if (this.updateLock.writeLock().tryLock()) {
|
||||
try {
|
||||
|
||||
if (!this.isAlive()) {
|
||||
if (!this.isAlive() && this.isEnteredWorld()) {
|
||||
if(!this.timestamps.containsKey("DeathTime")){
|
||||
this.timestamps.put("DeathTime",System.currentTimeMillis());
|
||||
}
|
||||
if((System.currentTimeMillis() - this.timestamps.get("DeathTime")) > 600000)
|
||||
}else if((System.currentTimeMillis() - this.timestamps.get("DeathTime")) > 600000)
|
||||
forceRespawn(this);
|
||||
return;
|
||||
}
|
||||
updateLocation();
|
||||
updateMovementState();
|
||||
updateRegen();
|
||||
this.updateLocation();
|
||||
this.updateMovementState();
|
||||
this.updateRegen();
|
||||
|
||||
if (this.getStamina() < 10) {
|
||||
if (this.getAltitude() > 0 || this.getDesiredAltitude() > 0) {
|
||||
PlayerCharacter.GroundPlayer(this);
|
||||
updateRegen();
|
||||
this.updateRegen();
|
||||
}
|
||||
}
|
||||
|
||||
RealmMap.updateRealm(this);
|
||||
updateBlessingMessage();
|
||||
this.updateBlessingMessage();
|
||||
|
||||
this.safeZone = this.isInSafeZone();
|
||||
if(!this.timestamps.containsKey("nextBoxCheck"))
|
||||
@@ -4891,6 +4744,13 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
this.timestamps.put("nextBoxCheck", System.currentTimeMillis() + 10000);
|
||||
}
|
||||
|
||||
if(this.level < 10 && this.enteredWorld) {
|
||||
// this.setLevel((short) 10);
|
||||
while (this.level < 10) {
|
||||
grantXP(Experience.getBaseExperience(this.level + 1) - this.exp);
|
||||
}
|
||||
}
|
||||
|
||||
if(this.isBoxed && !this.containsEffect(1672601862)) {
|
||||
PowersManager.applyPower(this, this, Vector3fImmutable.ZERO, 1672601862, 40, false);
|
||||
}
|
||||
@@ -4901,6 +4761,22 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
GroundPlayer(this);
|
||||
//ChatManager.chatSystemInfo(this, "You Cannot Fly While Having A MovementBuff");
|
||||
}
|
||||
if(!this.timestamps.containsKey("StunGrounded"))
|
||||
this.timestamps.put("StunGrounded",System.currentTimeMillis() - 1000L);
|
||||
if(this.bonuses.getBool(ModType.Stunned, SourceType.None) && this.timestamps.get("StunGrounded") < System.currentTimeMillis()){
|
||||
boolean isFlyMoving = this.getDesiredAltitude() != this.altitude;
|
||||
if(!isFlyMoving && this.bonuses.getBool(ModType.Stunned, SourceType.None)){
|
||||
this.setDesiredAltitude(this.altitude - 10);
|
||||
this.setTakeOffTime(System.currentTimeMillis());
|
||||
|
||||
ChangeAltitudeMsg msg = new ChangeAltitudeMsg(this.getObjectType().ordinal(), this.getObjectUUID(), false, this.getAltitude(), this.getDesiredAltitude(), this.getAltitude());
|
||||
// force a landing
|
||||
DispatchMessage.dispatchMsgToInterestArea(this, msg, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false);
|
||||
this.timestamps.put("StunGrounded",System.currentTimeMillis() + 1500L);
|
||||
ChatManager.chatSystemInfo(this,"Applying 1 Tier Ground");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
@@ -4929,6 +4805,9 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
|
||||
}
|
||||
public static boolean checkIfBoxed(PlayerCharacter player){
|
||||
if(ConfigManager.MB_WORLD_TESTMODE.getValue().equals("true")) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
String machineID = player.getClientConnection().machineID;
|
||||
ArrayList<PlayerCharacter> sameMachine = new ArrayList<>();
|
||||
@@ -5032,7 +4911,6 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
ChatManager.chatSystemInfo(this,
|
||||
"Arrived at End location. " + this.getEndLoc());
|
||||
return;
|
||||
//Next upda
|
||||
}
|
||||
|
||||
setLoc(newLoc);
|
||||
@@ -5044,11 +4922,6 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
|
||||
if (this.getStamina() < 10)
|
||||
MovementManager.sendOOS(this);
|
||||
|
||||
// if (MBServerStatics.MOVEMENT_SYNC_DEBUG || this.getDebug(1))
|
||||
// Logger.info("MovementManager", "Updating movement current loc:" + this.getLoc().getX() + " " + this.getLoc().getZ()
|
||||
// + " end loc: " + this.getEndLoc().getX() + " " + this.getEndLoc().getZ() + " distance " + this.getEndLoc().distance2D(this.getLoc()));
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -5114,6 +4987,9 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
@Override
|
||||
public void updateRegen() {
|
||||
|
||||
if(true)
|
||||
return;
|
||||
|
||||
float healthRegen = 0f;
|
||||
float manaRegen = 0f;
|
||||
float stamRegen = 0f;
|
||||
@@ -5138,7 +5014,7 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
if (this.walkMode)
|
||||
manaRegen = ((this.manaMax * MBServerStatics.MANA_REGEN_IDLE) * getRegenModifier(ModType.ManaRecoverRate));
|
||||
else if (!this.isCasting() && !this.isItemCasting())
|
||||
manaRegen = ((this.manaMax * MBServerStatics.MANA_REGEN_IDLE) * getRegenModifier(ModType.ManaRecoverRate));
|
||||
manaRegen = ((this.manaMax * MBServerStatics.MANA_REGEN_RUN) * getRegenModifier(ModType.ManaRecoverRate));
|
||||
else
|
||||
manaRegen = 0;
|
||||
|
||||
@@ -5422,23 +5298,11 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
return movementState;
|
||||
}
|
||||
|
||||
public boolean isHasAnniversery() {
|
||||
return hasAnniversery;
|
||||
}
|
||||
|
||||
public void setHasAnniversery(boolean hasAnniversery) {
|
||||
DbManager.PlayerCharacterQueries.SET_ANNIVERSERY(this, hasAnniversery);
|
||||
this.hasAnniversery = hasAnniversery;
|
||||
}
|
||||
|
||||
public int getSpamCount() {
|
||||
return spamCount;
|
||||
}
|
||||
|
||||
public void setSpamCount(int spamCount) {
|
||||
this.spamCount = spamCount;
|
||||
}
|
||||
|
||||
public String getHash() {
|
||||
return hash;
|
||||
}
|
||||
@@ -5464,10 +5328,6 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
this.lastRealmID = lastRealmID;
|
||||
}
|
||||
|
||||
public int getSubRaceID() {
|
||||
return subRaceID;
|
||||
}
|
||||
|
||||
public void setSubRaceID(int subRaceID) {
|
||||
this.subRaceID = subRaceID;
|
||||
}
|
||||
@@ -5480,29 +5340,6 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
this.guildHistory = guildHistory;
|
||||
}
|
||||
|
||||
public void moveTo(Vector3fImmutable endLoc) {
|
||||
this.setInBuilding(-1);
|
||||
this.setInFloorID(-1);
|
||||
MoveToPointMsg moveToMsg = new MoveToPointMsg();
|
||||
moveToMsg.setStartCoord(this.getLoc());
|
||||
moveToMsg.setEndCoord(endLoc);
|
||||
moveToMsg.setInBuilding(-1);
|
||||
moveToMsg.setUnknown01(-1);
|
||||
moveToMsg.setSourceType(GameObjectType.PlayerCharacter.ordinal());
|
||||
moveToMsg.setSourceID(this.getObjectUUID());
|
||||
|
||||
Dispatch dispatch = Dispatch.borrow(this, moveToMsg);
|
||||
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY);
|
||||
|
||||
try {
|
||||
MovementManager.movement(moveToMsg, this);
|
||||
} catch (MsgSendException e) {
|
||||
// TODO Auto-generated catch block
|
||||
Logger.error("Player.MoveTo", this.getName() + " tripped error " + e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void updateScaleHeight() {
|
||||
|
||||
float strengthScale = 0;
|
||||
@@ -5539,10 +5376,6 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
this.overFlowEXP = overFlowEXP;
|
||||
}
|
||||
|
||||
public MovementState getLastMovementState() {
|
||||
return lastMovementState;
|
||||
}
|
||||
|
||||
public void setLastMovementState(MovementState lastMovementState) {
|
||||
this.lastMovementState = lastMovementState;
|
||||
}
|
||||
@@ -5550,7 +5383,7 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
@Override
|
||||
public final void setIsCasting(final boolean isCasting) {
|
||||
if (this.isCasting != isCasting)
|
||||
this.update();
|
||||
this.update(false);
|
||||
this.isCasting = isCasting;
|
||||
}
|
||||
|
||||
@@ -5564,20 +5397,16 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
public void resetRegenUpdateTime() {
|
||||
this.lastUpdateTime = System.currentTimeMillis();
|
||||
this.lastStamUpdateTime = System.currentTimeMillis();
|
||||
this.timestamps.put("LastRegenHealth", System.currentTimeMillis());
|
||||
this.timestamps.put("LastRegenMana", System.currentTimeMillis());
|
||||
this.timestamps.put("LastRegenStamina", System.currentTimeMillis());
|
||||
this.timestamps.put("LastConsumeStamina", System.currentTimeMillis());
|
||||
}
|
||||
|
||||
public float getCharacterHeight() {
|
||||
return characterHeight;
|
||||
}
|
||||
|
||||
public void setCharacterHeight(float characterHeight) {
|
||||
this.characterHeight = characterHeight;
|
||||
}
|
||||
|
||||
public void setCenterHeight(float centerHeight) {
|
||||
this.centerHeight = centerHeight;
|
||||
}
|
||||
|
||||
public boolean isEnteredWorld() {
|
||||
return enteredWorld;
|
||||
}
|
||||
@@ -5586,26 +5415,10 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
this.enteredWorld = enteredWorld;
|
||||
}
|
||||
|
||||
public long getChannelMute() {
|
||||
return channelMute;
|
||||
}
|
||||
|
||||
public void setChannelMute(long channelMute) {
|
||||
this.channelMute = channelMute;
|
||||
}
|
||||
|
||||
public boolean isLastSwimming() {
|
||||
return lastSwimming;
|
||||
}
|
||||
|
||||
public boolean isTeleporting() {
|
||||
return isTeleporting;
|
||||
}
|
||||
|
||||
public void setTeleporting(boolean isTeleporting) {
|
||||
this.isTeleporting = isTeleporting;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void teleport(final Vector3fImmutable targetLoc) {
|
||||
|
||||
@@ -5654,4 +5467,212 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
this.dirtyLoad = dirtyLoad;
|
||||
dirtyLock.writeLock().unlock();
|
||||
}
|
||||
|
||||
public void doRegen(){
|
||||
if(!this.timestamps.containsKey("SyncClient"))
|
||||
this.timestamps.put("SyncClient",System.currentTimeMillis());
|
||||
if (this.updateLock.writeLock().tryLock()) {
|
||||
try {
|
||||
if(!this.isAlive() || !this.enteredWorld || !this.isActive) {
|
||||
this.resetRegenUpdateTime();
|
||||
return;
|
||||
}
|
||||
this.updateMovementState();
|
||||
boolean updateHealth = this.regenerateHealth();
|
||||
boolean updateMana = this.regenerateMana();
|
||||
boolean updateStamina = this.regenerateStamina();
|
||||
boolean consumeStamina = this.consumeStamina();
|
||||
if(this.timestamps.get("SyncClient") + 5000L > System.currentTimeMillis())
|
||||
if(updateHealth || updateMana || updateStamina || consumeStamina)
|
||||
this.syncClient();
|
||||
} catch (Exception e) {
|
||||
Logger.error(e);
|
||||
} finally {
|
||||
this.updateLock.writeLock().unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean regenerateHealth(){
|
||||
Long regenTime;
|
||||
Long currentTime = System.currentTimeMillis();
|
||||
regenTime = this.timestamps.getOrDefault("LastRegenHealth", currentTime);
|
||||
float secondsPassed = (currentTime - regenTime) / 1000f;
|
||||
float onePercent = this.healthMax * 0.01f;
|
||||
float rate = 1.0f / RecoveryType.getRecoveryType(this).healthRate;
|
||||
rate *= this.getRegenModifier(ModType.HealthRecoverRate);
|
||||
|
||||
if(this.isMoving() && !this.walkMode)
|
||||
rate = 0.0f;
|
||||
|
||||
float healthRegenerated = onePercent * rate * secondsPassed;
|
||||
//ChatManager.chatSystemInfo(this,"HEALTH REGENERATED: " + healthRegenerated + " SECONDS PASSED: " + secondsPassed);
|
||||
boolean workedHealth = false;
|
||||
float old = this.health.get();
|
||||
float mod = old + healthRegenerated;
|
||||
while(!workedHealth) {
|
||||
if (mod > this.healthMax)
|
||||
mod = healthMax;
|
||||
else if (mod <= 0) {
|
||||
if (this.isAlive.compareAndSet(true, false))
|
||||
killCharacter("Water");
|
||||
return false;
|
||||
}
|
||||
workedHealth = this.health.compareAndSet(old, mod);
|
||||
}
|
||||
|
||||
this.timestamps.put("LastRegenHealth",currentTime);
|
||||
return mod > old;
|
||||
}
|
||||
public boolean regenerateMana(){
|
||||
Long regenTime;
|
||||
Long currentTime = System.currentTimeMillis();
|
||||
regenTime = this.timestamps.getOrDefault("LastRegenMana", currentTime);
|
||||
float secondsPassed = (currentTime - regenTime) / 1000f;
|
||||
float onePercent = this.manaMax * 0.01f;
|
||||
float rate = 1.0f / RecoveryType.getRecoveryType(this).manaRate;
|
||||
rate *= this.getRegenModifier(ModType.ManaRecoverRate);
|
||||
|
||||
if(this.isMoving() && !this.walkMode)
|
||||
rate = 0.0f;
|
||||
|
||||
float manaRegenerated = onePercent * secondsPassed * rate;
|
||||
|
||||
boolean workedMana = false;
|
||||
float old = this.mana.get();
|
||||
float mod = old + manaRegenerated;
|
||||
while(!workedMana) {
|
||||
|
||||
if (mod > this.manaMax)
|
||||
mod = manaMax;
|
||||
else if (mod < 0)
|
||||
mod = 0;
|
||||
workedMana = this.mana.compareAndSet(old, mod);
|
||||
}
|
||||
|
||||
this.timestamps.put("LastRegenMana",currentTime);
|
||||
return mod > old;
|
||||
}
|
||||
public boolean regenerateStamina(){
|
||||
|
||||
Long currentTime = System.currentTimeMillis();
|
||||
|
||||
if(this.isMoving() || this.isFlying() || !this.canBreathe) {
|
||||
this.timestamps.put("LastRegenStamina",currentTime);
|
||||
return false;
|
||||
}
|
||||
|
||||
Long regenTime;
|
||||
|
||||
regenTime = this.timestamps.getOrDefault("LastRegenStamina", currentTime);
|
||||
float secondsPassed = (currentTime - regenTime) / 1000f;
|
||||
|
||||
float secondsToRecover1 = RecoveryType.getRecoveryType(this).staminaRate;
|
||||
|
||||
float ratio = secondsPassed / secondsToRecover1;
|
||||
//rate *= this.getRegenModifier(ModType.StaminaRecoverRate); // Adjust rate with modifiers
|
||||
|
||||
//float staminaRegenerated = secondsPassed / rate; // Stamina regenerates 1 point per `rate` seconds
|
||||
float staminaRegenerated = secondsPassed * ratio; // Stamina regenerates 1 point per `rate` seconds
|
||||
|
||||
boolean workedStamina = false;
|
||||
float old = this.stamina.get();
|
||||
float mod = old + staminaRegenerated;
|
||||
while (!workedStamina) {
|
||||
if (mod > this.staminaMax)
|
||||
mod = staminaMax;
|
||||
else if (mod < 0)
|
||||
mod = 0;
|
||||
workedStamina = this.stamina.compareAndSet(old, mod);
|
||||
}
|
||||
//ChatManager.chatSystemInfo(this, "STAM: " + this.stamina.get() + " / " + this.staminaMax);
|
||||
this.timestamps.put("LastRegenStamina", currentTime);
|
||||
return mod > old;
|
||||
}
|
||||
public boolean consumeStamina(){
|
||||
Long regenTime;
|
||||
Long currentTime = System.currentTimeMillis();
|
||||
regenTime = this.timestamps.getOrDefault("LastConsumeStamina", currentTime);
|
||||
float secondsPassed = (currentTime - regenTime) / 1000f;
|
||||
|
||||
float consumption;
|
||||
|
||||
if(!this.isMoving() && !this.isFlying() && this.canBreathe) {
|
||||
this.timestamps.put("LastConsumeStamina",currentTime);
|
||||
return false;
|
||||
}
|
||||
if(!this.combat){
|
||||
consumption = 0.4f * secondsPassed;
|
||||
}else{
|
||||
consumption = 0.65f * secondsPassed;
|
||||
}
|
||||
if(this.movementState.equals(MovementState.SWIMMING))
|
||||
consumption = 1.5f * secondsPassed;
|
||||
else if(this.isFlying())
|
||||
consumption = 2.0f * secondsPassed;
|
||||
|
||||
boolean workedStamina = false;
|
||||
float old = this.stamina.get();
|
||||
float mod = old - consumption;
|
||||
while (!workedStamina) {
|
||||
if (mod <= 0)
|
||||
mod = 0;
|
||||
workedStamina = this.stamina.compareAndSet(old, mod);
|
||||
}
|
||||
//ChatManager.chatSystemInfo(this, "STAM: " + this.stamina.get() + " / " + this.staminaMax);
|
||||
this.timestamps.put("LastConsumeStamina",currentTime);
|
||||
if(this.stamina.get() == 0){
|
||||
return this.consumeHealth(secondsPassed);
|
||||
}
|
||||
return mod < old;
|
||||
}
|
||||
|
||||
public boolean consumeHealth(float secondsPassed){
|
||||
float consumption = 2.0f * secondsPassed;
|
||||
boolean workedHealth = false;
|
||||
float old = this.health.get();
|
||||
float mod = old - consumption;
|
||||
while(!workedHealth) {
|
||||
|
||||
if (mod > this.healthMax)
|
||||
mod = healthMax;
|
||||
else if (mod <= 0) {
|
||||
if (this.isAlive.compareAndSet(true, false))
|
||||
killCharacter("Water");
|
||||
return true;
|
||||
}
|
||||
workedHealth = this.health.compareAndSet(old, mod);
|
||||
}
|
||||
return mod < old;
|
||||
}
|
||||
|
||||
enum RecoveryType{
|
||||
//Values for health and mana are in terms of the number of seconds it takes to recover 1% of max pool
|
||||
//Values for stamina are in terms of the number of seconds it takes to recover 1 point
|
||||
RESTING(3.0f,1.2f,0.5f), //sitting
|
||||
IDLING(15.0f,6.0f,5.0f), //standing not moving
|
||||
WALKING(20.0f,8.0f,0.0f), // moving in walk mode
|
||||
RUNNING(0.0f,0.0f,0.0f); // moving in run mode
|
||||
public float healthRate;
|
||||
public float manaRate;
|
||||
public float staminaRate;
|
||||
RecoveryType(float health, float mana, float stamina) {
|
||||
this.healthRate = health;
|
||||
this.manaRate = mana;
|
||||
this.staminaRate = stamina;
|
||||
}
|
||||
public static RecoveryType getRecoveryType(PlayerCharacter pc){
|
||||
if (pc.isMoving()) {
|
||||
if(pc.walkMode){
|
||||
return RecoveryType.WALKING;
|
||||
}else{
|
||||
return RecoveryType.RUNNING;
|
||||
}
|
||||
}else if(pc.isSit()){
|
||||
return RecoveryType.RESTING;
|
||||
}else{
|
||||
return RecoveryType.IDLING;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,10 +10,14 @@
|
||||
package engine.objects;
|
||||
|
||||
import engine.Enum;
|
||||
import engine.InterestManagement.InterestManager;
|
||||
import engine.InterestManagement.RealmMap;
|
||||
import engine.InterestManagement.WorldGrid;
|
||||
import engine.db.archive.DataWarehouse;
|
||||
import engine.db.archive.RealmRecord;
|
||||
import engine.gameManager.BuildingManager;
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.gameManager.NPCManager;
|
||||
import engine.gameManager.PowersManager;
|
||||
import engine.net.ByteBufferWriter;
|
||||
import engine.powers.PowersBase;
|
||||
@@ -379,6 +383,16 @@ public class Realm {
|
||||
|
||||
public void abandonRealm() {
|
||||
|
||||
for(AbstractWorldObject awo : WorldGrid.getObjectsInRangePartial(this.getRulingCity().loc,1750,MBServerStatics.MASK_BUILDING)){
|
||||
Building wall = (Building)awo;
|
||||
if(wall.getBlueprint() != null && wall.getBlueprint().getBuildingGroup() != null && wall.getBlueprint().isWallPiece()){
|
||||
float currentHealthRatio = wall.getCurrentHitpoints()/wall.healthMax;
|
||||
float newMax = wall.getBlueprint().getMaxHealth(1);
|
||||
wall.setMaxHitPoints(newMax);
|
||||
wall.setHealth(wall.healthMax * currentHealthRatio);
|
||||
}
|
||||
}
|
||||
|
||||
// Push event to warehouse
|
||||
|
||||
RealmRecord realmRecord = RealmRecord.borrow(this, Enum.RecordEventType.LOST);
|
||||
@@ -406,6 +420,17 @@ public class Realm {
|
||||
this.configure();
|
||||
this.updateDatabase();
|
||||
|
||||
for(AbstractWorldObject awo : WorldGrid.getObjectsInRangePartial(city.loc,1750,MBServerStatics.MASK_BUILDING)){
|
||||
Building wall = (Building)awo;
|
||||
if(wall.getBlueprint() != null && wall.getBlueprint().getBuildingGroup() != null && wall.getBlueprint().isWallPiece()){
|
||||
float currentHealthRatio = wall.getCurrentHitpoints()/wall.healthMax;
|
||||
float newMax = wall.healthMax * 1.1f;
|
||||
wall.setMaxHitPoints(newMax);
|
||||
wall.setHealth(wall.healthMax * currentHealthRatio);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Push event to warehouse
|
||||
|
||||
RealmRecord realmRecord = RealmRecord.borrow(this, Enum.RecordEventType.CAPTURE);
|
||||
|
||||
@@ -11,6 +11,7 @@ package engine.powers;
|
||||
|
||||
import engine.Enum.PowerCategoryType;
|
||||
import engine.Enum.PowerTargetType;
|
||||
import engine.gameManager.PowersManager;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
@@ -109,6 +110,8 @@ public class PowersBase {
|
||||
public PowerCategoryType powerCategory;
|
||||
public String description;
|
||||
|
||||
public boolean breaksForm = true;
|
||||
|
||||
/**
|
||||
* No Table ID Constructor
|
||||
*/
|
||||
@@ -325,6 +328,8 @@ public class PowersBase {
|
||||
ct = rs.getString("monsterTypeRestrict3").trim();
|
||||
if (!ct.isEmpty())
|
||||
this.monsterTypeRestrictions.add(ct);
|
||||
|
||||
this.breaksForm = PowersManager.breakForm(this.token);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ public class AttributeEffectModifier extends AbstractEffectModifier {
|
||||
@Override
|
||||
public void applyBonus(AbstractCharacter ac, int trains) {
|
||||
|
||||
ac.update();
|
||||
ac.update(false);
|
||||
Float amount = 0f;
|
||||
PlayerBonuses bonus = ac.getBonuses();
|
||||
if (this.percentMod != 0f) { //Stat Percent Modifiers
|
||||
|
||||
@@ -29,7 +29,7 @@ public class HealthRecoverRateEffectModifier extends AbstractEffectModifier {
|
||||
@Override
|
||||
public void applyBonus(AbstractCharacter ac, int trains) {
|
||||
|
||||
ac.update();
|
||||
ac.update(false);
|
||||
Float amount = 0f;
|
||||
PlayerBonuses bonus = ac.getBonuses();
|
||||
if (this.useRampAdd)
|
||||
|
||||
@@ -39,7 +39,7 @@ public class NoModEffectModifier extends AbstractEffectModifier {
|
||||
PlayerCharacter flyer = (PlayerCharacter) ac;
|
||||
|
||||
if (flyer.getAltitude() > 0)
|
||||
flyer.update();
|
||||
flyer.update(false);
|
||||
PlayerCharacter.GroundPlayer(flyer);
|
||||
break;
|
||||
|
||||
|
||||
@@ -130,7 +130,7 @@ public class ApplyEffectPowerAction extends AbstractPowerAction {
|
||||
((Mob) awo).setCombatTarget(source);
|
||||
ChatSystemMsg msg = ChatManager.CombatInfo(source, awo);
|
||||
DispatchMessage.sendToAllInRange(source, msg);
|
||||
((Mob)awo).refresh();
|
||||
//((Mob)awo).refresh();
|
||||
}
|
||||
}
|
||||
if (awo != null && awo.getObjectType() == GameObjectType.Mob) {
|
||||
|
||||
@@ -312,10 +312,10 @@ public class MBServerStatics {
|
||||
public static final float HEALTH_REGEN_SWIM_NOSTAMINA_STATIC = 0f; // 100%
|
||||
// weapon
|
||||
public static final float MANA_REGEN_STATIC = 0.16666666666666666666666666666667f;
|
||||
public static final float MANA_REGEN_SIT = 0.008333333f; // 100% in 2
|
||||
public static final float MANA_REGEN_IDLE = 0.00166667f; // 100% in 10
|
||||
public static final float MANA_REGEN_WALK = 0.00125f; // 100% in 13.333
|
||||
public static final float MANA_REGEN_RUN = 0f;
|
||||
public static final float MANA_REGEN_SIT = 0.8333333f; // 1% every 1.2 seconds
|
||||
public static final float MANA_REGEN_IDLE = 0.1666667f; // 1% every 6 seconds
|
||||
public static final float MANA_REGEN_WALK = 0.125f; // 1% every 8 seconds
|
||||
public static final float MANA_REGEN_RUN = 0.0f; // No regeneration while running
|
||||
public static final float STAMINA_REGEN_SIT = 2f; // 2 per second
|
||||
public static final float STAMINA_REGEN_IDLE = 0.2f; // 1 per 5 seconds
|
||||
public static final float STAMINA_REGEN_WALK = 0f;
|
||||
@@ -326,7 +326,7 @@ public class MBServerStatics {
|
||||
public static final int REGEN_SENSITIVITY_MOB = 1000; // calc regen ever X
|
||||
public static final int TOMBSTONE = 2024;
|
||||
public static final int LOGOUT_TIMER_MS = 1000; // logout delay applied
|
||||
public static final int CORPSE_CLEANUP_TIMER_MS = 15 * 60 * 1000; // Cleanup
|
||||
public static final int CORPSE_CLEANUP_TIMER_MS = 10 * 60 * 1000; // Cleanup
|
||||
public static final int DEFAULT_SPAWN_TIME_MS = 3 * 60 * 1000; // 3 minute
|
||||
public static final int SESSION_CLEANUP_TIMER_MS = 30 * 1000; // cleanup
|
||||
public static final int MOVEMENT_FREQUENCY_MS = 1000; // Update movement
|
||||
|
||||
@@ -450,7 +450,7 @@ public class LoginServer {
|
||||
objectUUID = rs.getInt("UID");
|
||||
objectType = rs.getString("type");
|
||||
|
||||
Logger.info("INVALIDATED : " + objectType + " UUID: " + objectUUID);
|
||||
//Logger.info("INVALIDATED : " + objectType + " UUID: " + objectUUID);
|
||||
|
||||
switch (objectType) {
|
||||
|
||||
@@ -462,7 +462,7 @@ public class LoginServer {
|
||||
PlayerCharacter player = (PlayerCharacter) DbManager.getObject(Enum.GameObjectType.PlayerCharacter, objectUUID);
|
||||
PlayerCharacter.initializePlayer(player);
|
||||
player.getAccount().characterMap.replace(player.getObjectUUID(), player);
|
||||
Logger.info("Player active state is : " + player.isActive());
|
||||
//Logger.info("Player active state is : " + player.isActive());
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -513,9 +513,53 @@ public class WorldServer {
|
||||
|
||||
Logger.info("Running garbage collection...");
|
||||
System.gc();
|
||||
|
||||
Logger.info("Starting Bane Thread");
|
||||
BaneThread.startBaneThread();
|
||||
|
||||
Logger.info("Starting Player Regen Thread");
|
||||
UpdateThread.startUpdateThread();
|
||||
|
||||
|
||||
printThreads();
|
||||
Logger.info("Threads Running:");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void printThreads() {
|
||||
// Get the root thread group
|
||||
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
|
||||
Logger.info("Total threads in application: " + threads.length + " / " + availableThreads + " Total Threads On Machine");
|
||||
if(threads.length > (int)(availableThreads * 0.75f)){
|
||||
Logger.error("WARNING! Too many threads are being used, hardware update recommended");
|
||||
}
|
||||
|
||||
// Optionally, list the thread names
|
||||
Logger.info("Active threads:");
|
||||
for (Thread thread : threads) {
|
||||
if (thread != null) {
|
||||
Logger.info(thread.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean initDatabaselayer() {
|
||||
|
||||
// Try starting a GOM <-> DB connection.
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.workthreads;
|
||||
|
||||
import engine.Enum;
|
||||
import engine.InterestManagement.WorldGrid;
|
||||
import engine.db.archive.DataWarehouse;
|
||||
import engine.db.archive.MineRecord;
|
||||
import engine.gameManager.BuildingManager;
|
||||
import engine.gameManager.ChatManager;
|
||||
import engine.gameManager.StrongholdManager;
|
||||
import engine.mobileAI.Threads.MobAIThread;
|
||||
import engine.net.DispatchMessage;
|
||||
import engine.net.client.msg.chat.ChatSystemMsg;
|
||||
import engine.objects.*;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class BaneThread implements Runnable {
|
||||
|
||||
private volatile Long lastRun;
|
||||
public static final Long instancedelay = 1000L;
|
||||
public BaneThread() {
|
||||
Logger.info(" BaneThread thread has started!");
|
||||
}
|
||||
|
||||
|
||||
public void processBanesWindow() {
|
||||
|
||||
try {
|
||||
synchronized (Bane.banes) {
|
||||
for (int baneId : Bane.banes.keySet()) {
|
||||
Bane bane = Bane.banes.get(baneId);
|
||||
if (bane != null && bane.getSiegePhase().equals(Enum.SiegePhase.WAR)) {
|
||||
bane.applyZergBuffs();
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Logger.error("BANE ERROR",e);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void run() {
|
||||
lastRun = System.currentTimeMillis();
|
||||
while (true) {
|
||||
if (System.currentTimeMillis() >= lastRun + instancedelay) { // Correct condition
|
||||
this.processBanesWindow();
|
||||
lastRun = System.currentTimeMillis(); // Update lastRun after processing
|
||||
}else {
|
||||
try {
|
||||
Thread.sleep(100); // Pause for 100ms to reduce CPU usage
|
||||
} catch (InterruptedException e) {
|
||||
Logger.error("Thread interrupted", e);
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void startBaneThread() {
|
||||
Thread baneThread;
|
||||
baneThread = new Thread(new BaneThread());
|
||||
baneThread.setName("baneThread");
|
||||
baneThread.start();
|
||||
}
|
||||
}
|
||||
@@ -88,5 +88,11 @@ public class HourlyJobThread implements Runnable {
|
||||
Logger.info(SimulationManager.getPopulationString());
|
||||
Logger.info(MessageDispatcher.getNetstatString());
|
||||
Logger.info(PurgeOprhans.recordsDeleted.toString() + "orphaned items deleted");
|
||||
|
||||
for (Bane bane : Bane.banes.values()){
|
||||
if(bane.getSiegePhase().equals(Enum.SiegePhase.CHALLENGE)){
|
||||
bane.setDefaultTime();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.workthreads;
|
||||
|
||||
import engine.Enum;
|
||||
import engine.gameManager.SessionManager;
|
||||
import engine.gameManager.SimulationManager;
|
||||
import engine.objects.Bane;
|
||||
import engine.objects.PlayerCharacter;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
public class UpdateThread implements Runnable {
|
||||
|
||||
private volatile Long lastRun;
|
||||
|
||||
public static final Long instancedelay = 1000L;
|
||||
public UpdateThread() {
|
||||
Logger.info(" UpdateThread thread has started!");
|
||||
}
|
||||
|
||||
|
||||
public void processPlayerUpdate() {
|
||||
|
||||
try {
|
||||
for(PlayerCharacter player : SessionManager.getAllActivePlayerCharacters()){
|
||||
if (player != null) {
|
||||
player.doRegen();
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Logger.error("UPDATE ERROR",e);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void run() {
|
||||
lastRun = System.currentTimeMillis();
|
||||
while (true) {
|
||||
if (System.currentTimeMillis() >= lastRun + instancedelay) { // Correct condition
|
||||
this.processPlayerUpdate();
|
||||
lastRun = System.currentTimeMillis(); // Update lastRun after processing
|
||||
}else {
|
||||
try {
|
||||
Thread.sleep(100); // Pause for 10ms to reduce CPU usage
|
||||
} catch (InterruptedException e) {
|
||||
Logger.error("Thread interrupted", e);
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void startUpdateThread() {
|
||||
Thread updateThread;
|
||||
updateThread = new Thread(new UpdateThread());
|
||||
updateThread.setName("updateThread");
|
||||
updateThread.start();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user