Compare commits
99 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 |
+9
-17
@@ -9,15 +9,13 @@
|
|||||||
package engine;
|
package engine;
|
||||||
|
|
||||||
import ch.claude_martin.enumbitset.EnumBitSetHelper;
|
import ch.claude_martin.enumbitset.EnumBitSetHelper;
|
||||||
|
import engine.gameManager.BuildingManager;
|
||||||
import engine.gameManager.ConfigManager;
|
import engine.gameManager.ConfigManager;
|
||||||
import engine.gameManager.PowersManager;
|
import engine.gameManager.PowersManager;
|
||||||
import engine.gameManager.ZoneManager;
|
import engine.gameManager.ZoneManager;
|
||||||
import engine.math.Vector2f;
|
import engine.math.Vector2f;
|
||||||
import engine.math.Vector3fImmutable;
|
import engine.math.Vector3fImmutable;
|
||||||
import engine.objects.AbstractCharacter;
|
import engine.objects.*;
|
||||||
import engine.objects.ItemBase;
|
|
||||||
import engine.objects.Shrine;
|
|
||||||
import engine.objects.Zone;
|
|
||||||
import engine.powers.EffectsBase;
|
import engine.powers.EffectsBase;
|
||||||
import org.pmw.tinylog.Logger;
|
import org.pmw.tinylog.Logger;
|
||||||
|
|
||||||
@@ -471,11 +469,14 @@ public class Enum {
|
|||||||
|
|
||||||
// 14001 does not have a banestone to bind at
|
// 14001 does not have a banestone to bind at
|
||||||
|
|
||||||
if (ruinZone.getLoadNum() == 14001)
|
if (ruinZone.getLoadNum() == 14001) {
|
||||||
spawnLocation = Vector3fImmutable.getRandomPointOnCircle(ruinZone.getLoc(), 30);
|
spawnLocation = Vector3fImmutable.getRandomPointOnCircle(ruinZone.getLoc(), 30);
|
||||||
else
|
}else {
|
||||||
spawnLocation = Vector3fImmutable.getRandomPointOnCircle(ruinZone.getLoc()
|
//spawnLocation = Vector3fImmutable.getRandomPointOnCircle(ruinZone.getLoc()
|
||||||
.add(new Vector3fImmutable(-196.016f, 2.812f, 203.621f)), 30);
|
//.add(new Vector3fImmutable(-196.016f, 2.812f, 203.621f)), 30);
|
||||||
|
spawnLocation = Vector3fImmutable.getRandomPointOnCircle(BuildingManager.getBuilding(27977).loc,30f);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1090,15 +1091,6 @@ public class Enum {
|
|||||||
DamageShield,
|
DamageShield,
|
||||||
DeathShroud,
|
DeathShroud,
|
||||||
DefenseBuff,
|
DefenseBuff,
|
||||||
DefenseBuffAss,
|
|
||||||
DefenseBuffChn,
|
|
||||||
DefenseBuffDsr,
|
|
||||||
DefenseBuffFur,
|
|
||||||
DefenseBuffNec,
|
|
||||||
DefenseBuffNsr,
|
|
||||||
DefenseBuffPrl,
|
|
||||||
DefenseBuffRng,
|
|
||||||
DefenseBuffWiz,
|
|
||||||
DefenseBuffGroup,
|
DefenseBuffGroup,
|
||||||
DefenseDebuff,
|
DefenseDebuff,
|
||||||
DetectInvis,
|
DetectInvis,
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -134,9 +134,13 @@ public class dbItemHandler extends dbHandlerBase {
|
|||||||
|
|
||||||
ResultSet rs = preparedStatement.executeQuery();
|
ResultSet rs = preparedStatement.executeQuery();
|
||||||
|
|
||||||
if (rs.next())
|
if (rs.next()) {
|
||||||
worked = rs.getBoolean("result");
|
try {
|
||||||
|
worked = rs.getBoolean("result");
|
||||||
|
}catch(Exception e){
|
||||||
|
worked = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
Logger.error(e);
|
Logger.error(e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,9 +15,13 @@ import engine.Enum.GameObjectType;
|
|||||||
import engine.Enum.TargetColor;
|
import engine.Enum.TargetColor;
|
||||||
import engine.devcmd.AbstractDevCmd;
|
import engine.devcmd.AbstractDevCmd;
|
||||||
import engine.gameManager.BuildingManager;
|
import engine.gameManager.BuildingManager;
|
||||||
|
import engine.gameManager.PowersManager;
|
||||||
import engine.gameManager.SessionManager;
|
import engine.gameManager.SessionManager;
|
||||||
import engine.math.Vector3fImmutable;
|
import engine.math.Vector3fImmutable;
|
||||||
import engine.objects.*;
|
import engine.objects.*;
|
||||||
|
import engine.powers.EffectsBase;
|
||||||
|
import engine.powers.PowersBase;
|
||||||
|
import engine.server.MBServerStatics;
|
||||||
import engine.util.StringUtils;
|
import engine.util.StringUtils;
|
||||||
|
|
||||||
import java.text.DecimalFormat;
|
import java.text.DecimalFormat;
|
||||||
@@ -493,13 +497,16 @@ public class InfoCmd extends AbstractDevCmd {
|
|||||||
output += newline;
|
output += newline;
|
||||||
output += "No building found." + newline;
|
output += "No building found." + newline;
|
||||||
}
|
}
|
||||||
int max = (int)(4.882 * targetMob.level + 121.0);
|
|
||||||
if(max > 321){
|
output += "Damage: " + targetMob.mobBase.getDamageMin() + " - " + targetMob.mobBase.getDamageMax() + newline;
|
||||||
max = 321;
|
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;
|
break;
|
||||||
case Item: //intentional passthrough
|
case Item: //intentional passthrough
|
||||||
case MobLoot:
|
case MobLoot:
|
||||||
@@ -530,6 +537,13 @@ public class InfoCmd extends AbstractDevCmd {
|
|||||||
}
|
}
|
||||||
|
|
||||||
break;
|
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);
|
throwbackInfo(pc, output);
|
||||||
|
|||||||
@@ -49,10 +49,20 @@ public class ArenaManager {
|
|||||||
if (!playerQueue.contains(player)) {
|
if (!playerQueue.contains(player)) {
|
||||||
playerQueue.add(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) {
|
public static void leaveQueue(PlayerCharacter player) {
|
||||||
playerQueue.remove(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() {
|
private static void createArena() {
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import engine.Enum.GameObjectType;
|
|||||||
import engine.Enum.ModType;
|
import engine.Enum.ModType;
|
||||||
import engine.Enum.SourceType;
|
import engine.Enum.SourceType;
|
||||||
import engine.InterestManagement.WorldGrid;
|
import engine.InterestManagement.WorldGrid;
|
||||||
|
import engine.QuestSystem.QuestManager;
|
||||||
import engine.db.archive.BaneRecord;
|
import engine.db.archive.BaneRecord;
|
||||||
import engine.db.archive.PvpRecord;
|
import engine.db.archive.PvpRecord;
|
||||||
import engine.net.Dispatch;
|
import engine.net.Dispatch;
|
||||||
@@ -108,9 +109,9 @@ public enum ChatManager {
|
|||||||
ChatManager.chatIC(pc, (ChatICMsg) msg);
|
ChatManager.chatIC(pc, (ChatICMsg) msg);
|
||||||
return;
|
return;
|
||||||
case LEADERCHANNELMESSAGE:
|
case LEADERCHANNELMESSAGE:
|
||||||
|
case GLOBALCHANNELMESSAGE:
|
||||||
ChatManager.chatGlobal(pc, msg.getMessage(), isFlood);
|
ChatManager.chatGlobal(pc, msg.getMessage(), isFlood);
|
||||||
return;
|
return;
|
||||||
case GLOBALCHANNELMESSAGE:
|
|
||||||
case CHATPVP:
|
case CHATPVP:
|
||||||
case CHATCITY:
|
case CHATCITY:
|
||||||
case CHATINFO:
|
case CHATINFO:
|
||||||
@@ -199,6 +200,11 @@ public enum ChatManager {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(text.equalsIgnoreCase("show_quest()")){
|
||||||
|
QuestManager.displayCurrentQuest(pcSender);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (ChatManager.isVersionRequest(text) == true) {
|
if (ChatManager.isVersionRequest(text) == true) {
|
||||||
sendSystemMessage(pcSender, ConfigManager.MB_WORLD_GREETING.getValue());
|
sendSystemMessage(pcSender, ConfigManager.MB_WORLD_GREETING.getValue());
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -662,9 +662,8 @@ public enum CombatManager {
|
|||||||
|
|
||||||
DeferredPowerJob dpj = null;
|
DeferredPowerJob dpj = null;
|
||||||
|
|
||||||
|
boolean hitLanded = LandHit((int)atr,(int)defense);
|
||||||
|
if (hitLanded) {
|
||||||
if (LandHit((int)atr,(int)defense)) {
|
|
||||||
|
|
||||||
if (ac.getObjectType().equals(GameObjectType.PlayerCharacter))
|
if (ac.getObjectType().equals(GameObjectType.PlayerCharacter))
|
||||||
updateAttackTimers((PlayerCharacter) ac, target, true);
|
updateAttackTimers((PlayerCharacter) ac, target, true);
|
||||||
@@ -693,7 +692,13 @@ public enum CombatManager {
|
|||||||
|
|
||||||
PlayerBonuses bonus = ac.getBonuses();
|
PlayerBonuses bonus = ac.getBonuses();
|
||||||
float attackRange = getWeaponRange(wb, bonus);
|
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))
|
if (dpj.getPower() != null && (dpj.getPowerToken() == -1851459567 || dpj.getPowerToken() == -1851489518))
|
||||||
((PlayerCharacter) ac).setWeaponPower(dpj);
|
((PlayerCharacter) ac).setWeaponPower(dpj);
|
||||||
@@ -708,7 +713,13 @@ public enum CombatManager {
|
|||||||
|
|
||||||
if (dpj != null && dpj.getPower() != null && (dpj.getPowerToken() == -1851459567 || dpj.getPowerToken() == -1851489518)) {
|
if (dpj != null && dpj.getPower() != null && (dpj.getPowerToken() == -1851459567 || dpj.getPowerToken() == -1851489518)) {
|
||||||
float attackRange = getWeaponRange(wb, bonuses);
|
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) {
|
if (wp.requiresHitRoll() == false) {
|
||||||
PlayerBonuses bonus = ac.getBonuses();
|
PlayerBonuses bonus = ac.getBonuses();
|
||||||
float attackRange = getWeaponRange(wb, bonus);
|
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
|
} else
|
||||||
((PlayerCharacter) ac).setWeaponPower(null);
|
((PlayerCharacter) ac).setWeaponPower(null);
|
||||||
}
|
}
|
||||||
@@ -1453,19 +1470,28 @@ public enum CombatManager {
|
|||||||
((AbstractCharacter) awo).getCharItemManager().damageRandomArmor(1);
|
((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);
|
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)
|
return roll <= convertedChance;
|
||||||
connvertedChance = 5;
|
}
|
||||||
|
|
||||||
if(connvertedChance > 95)
|
public static boolean specialCaseHitRoll(int powerID){
|
||||||
connvertedChance = 95;
|
switch(powerID) {
|
||||||
|
case 563200808: // Naargal's Bite
|
||||||
return connvertedChance > roll;
|
case 563205337: // Naargal's Dart
|
||||||
|
case 563205930: // Sword of Saint Malorn
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,6 +75,11 @@ public enum LootManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void GenerateMobLoot(Mob mob) {
|
public static void GenerateMobLoot(Mob mob) {
|
||||||
|
|
||||||
|
if(mob == null){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//determine if mob is in hotzone
|
//determine if mob is in hotzone
|
||||||
boolean inHotzone = false;
|
boolean inHotzone = false;
|
||||||
|
|
||||||
@@ -180,14 +185,16 @@ public enum LootManager {
|
|||||||
|
|
||||||
|
|
||||||
// Iterate all entries in this bootySet and process accordingly
|
// Iterate all entries in this bootySet and process accordingly
|
||||||
|
Zone zone = ZoneManager.findSmallestZone(mob.loc);
|
||||||
for (BootySetEntry bse : entries) {
|
for (BootySetEntry bse : entries) {
|
||||||
switch (bse.bootyType) {
|
switch (bse.bootyType) {
|
||||||
case "GOLD":
|
case "GOLD":
|
||||||
|
if (zone != null && zone.getSafeZone() == (byte)1)
|
||||||
|
return; // no loot to drop in safezones
|
||||||
GenerateGoldDrop(mob, bse, inHotzone);
|
GenerateGoldDrop(mob, bse, inHotzone);
|
||||||
break;
|
break;
|
||||||
case "LOOT":
|
case "LOOT":
|
||||||
|
if (zone != null && zone.getSafeZone() == (byte)1)
|
||||||
if (mob.getSafeZone())
|
|
||||||
return; // no loot to drop in safezones
|
return; // no loot to drop in safezones
|
||||||
|
|
||||||
dropRate = LootManager.NORMAL_DROP_RATE;
|
dropRate = LootManager.NORMAL_DROP_RATE;
|
||||||
|
|||||||
@@ -165,7 +165,7 @@ public enum PowersManager {
|
|||||||
|
|
||||||
PlayerCharacter pc = SessionManager.getPlayerCharacter(origin);
|
PlayerCharacter pc = SessionManager.getPlayerCharacter(origin);
|
||||||
|
|
||||||
if(!pc.isFlying()) //cant be sitting if flying
|
if(!pc.isFlying() && powersBaseByToken.get(msg.getPowerUsedID()) != null && powersBaseByToken.get(msg.getPowerUsedID()).isSpell) //cant be sitting if flying
|
||||||
CombatManager.toggleSit(false,origin);
|
CombatManager.toggleSit(false,origin);
|
||||||
|
|
||||||
if(pc.isMoving())
|
if(pc.isMoving())
|
||||||
@@ -349,8 +349,10 @@ public enum PowersManager {
|
|||||||
msg.setNumTrains(trains);
|
msg.setNumTrains(trains);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//double stack point values for some useless disc spells
|
||||||
switch(pb.token){
|
switch(pb.token){
|
||||||
case 429420458: // BH eyes
|
case 429420458: // BH eyes
|
||||||
|
case 429601664: // huntsman skin the beast
|
||||||
msg.setNumTrains(msg.getNumTrains() * 2);
|
msg.setNumTrains(msg.getNumTrains() * 2);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -602,12 +604,12 @@ public enum PowersManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// update cast (use skill) fail condition
|
// update cast (use skill) fail condition
|
||||||
if(pb.token != 429396028) {
|
if(pb.token != 429396028 && pb.breaksForm) {
|
||||||
playerCharacter.cancelOnCast();
|
playerCharacter.cancelOnCast();
|
||||||
}
|
}
|
||||||
|
|
||||||
// update castSpell (use spell) fail condition if spell
|
// update castSpell (use spell) fail condition if spell
|
||||||
if (pb.isSpell())
|
if (pb.isSpell() && pb.breaksForm)
|
||||||
playerCharacter.cancelOnSpell();
|
playerCharacter.cancelOnSpell();
|
||||||
|
|
||||||
// get cast time in ms.
|
// get cast time in ms.
|
||||||
@@ -748,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)
|
// 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
|
// update cast (use skill) fail condition
|
||||||
caster.cancelOnCast();
|
if(pb.breaksForm)
|
||||||
|
caster.cancelOnCast();
|
||||||
|
|
||||||
// update castSpell (use spell) fail condition if spell
|
// update castSpell (use spell) fail condition if spell
|
||||||
if (pb.isSpell())
|
if (pb.isSpell() && pb.breaksForm)
|
||||||
caster.cancelOnSpell();
|
caster.cancelOnSpell();
|
||||||
|
|
||||||
// get cast time in ms.
|
// get cast time in ms.
|
||||||
@@ -787,9 +790,10 @@ public enum PowersManager {
|
|||||||
if (playerCharacter == null || msg == null)
|
if (playerCharacter == null || msg == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if((msg.getPowerUsedID() == 429495514 || msg.getPowerUsedID() == 429407306) && playerCharacter.getRace().getName().toLowerCase().contains("shade")){
|
if(msg.getPowerUsedID() == 429005674){ //bard sprint
|
||||||
//msg.setPowerUsedID(407015607);
|
//use sprint instead of ballad of beregund the bold
|
||||||
applyPower(playerCharacter,playerCharacter,playerCharacter.loc,429397210,msg.getNumTrains(),false);
|
//applyPower(playerCharacter,playerCharacter,playerCharacter.loc,429611355,msg.getNumTrains(),false);
|
||||||
|
msg.setPowerUsedID(429611355);
|
||||||
}
|
}
|
||||||
if(msg.getPowerUsedID() == 429494441) {//wildkins chase
|
if(msg.getPowerUsedID() == 429494441) {//wildkins chase
|
||||||
playerCharacter.removeEffectBySource(EffectSourceType.Root,40,true);
|
playerCharacter.removeEffectBySource(EffectSourceType.Root,40,true);
|
||||||
@@ -2841,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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ public abstract class AbstractEffectJob extends AbstractScheduleJob {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void endEffect() {
|
public void endEffect() {
|
||||||
if (this.eb == null)
|
if (this.eb == null || this.power == null)
|
||||||
return;
|
return;
|
||||||
this.eb.endEffect(this.source, this.target, this.trains, this.power, this);
|
this.eb.endEffect(this.source, this.target, this.trains, this.power, this);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
package engine.jobs;
|
package engine.jobs;
|
||||||
|
|
||||||
|
import engine.gameManager.ZoneManager;
|
||||||
import engine.job.AbstractScheduleJob;
|
import engine.job.AbstractScheduleJob;
|
||||||
import engine.objects.Building;
|
import engine.objects.Building;
|
||||||
|
import engine.objects.City;
|
||||||
import org.pmw.tinylog.Logger;
|
import org.pmw.tinylog.Logger;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -41,6 +43,18 @@ public class UpgradeBuildingJob extends AbstractScheduleJob {
|
|||||||
|
|
||||||
rankingBuilding.setRank(rankingBuilding.getRank() + 1);
|
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
|
// Reload the object
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,6 @@
|
|||||||
package engine.mobileAI;
|
package engine.mobileAI;
|
||||||
|
|
||||||
import engine.Enum;
|
import engine.Enum;
|
||||||
import engine.Enum.DispatchChannel;
|
|
||||||
import engine.InterestManagement.WorldGrid;
|
import engine.InterestManagement.WorldGrid;
|
||||||
import engine.gameManager.*;
|
import engine.gameManager.*;
|
||||||
import engine.math.Vector3f;
|
import engine.math.Vector3f;
|
||||||
@@ -19,7 +18,7 @@ import engine.mobileAI.utilities.CombatUtilities;
|
|||||||
import engine.mobileAI.utilities.MovementUtilities;
|
import engine.mobileAI.utilities.MovementUtilities;
|
||||||
import engine.net.DispatchMessage;
|
import engine.net.DispatchMessage;
|
||||||
import engine.net.client.msg.PerformActionMsg;
|
import engine.net.client.msg.PerformActionMsg;
|
||||||
import engine.net.client.msg.PowerProjectileMsg;
|
import engine.net.client.msg.UpdateStateMsg;
|
||||||
import engine.objects.*;
|
import engine.objects.*;
|
||||||
import engine.powers.ActionsBase;
|
import engine.powers.ActionsBase;
|
||||||
import engine.powers.PowersBase;
|
import engine.powers.PowersBase;
|
||||||
@@ -109,7 +108,7 @@ public class MobAI {
|
|||||||
if (mob.BehaviourType.callsForHelp)
|
if (mob.BehaviourType.callsForHelp)
|
||||||
MobCallForHelp(mob);
|
MobCallForHelp(mob);
|
||||||
|
|
||||||
if (!MovementUtilities.inRangeDropAggro(mob, target)) {
|
if (MovementUtilities.outOfAggroRange(mob, target)) {
|
||||||
mob.setCombatTarget(null);
|
mob.setCombatTarget(null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -321,20 +320,20 @@ public class MobAI {
|
|||||||
if (mob == null)
|
if (mob == null)
|
||||||
return false;
|
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();
|
contractID = mob.npcOwner.contract.getContractID();
|
||||||
else
|
else if(mob.contract != null)
|
||||||
contractID = mob.contract.getContractID();
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mob.mobPowers.isEmpty())
|
if (mob.mobPowers == null || mob.mobPowers.isEmpty())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!mob.canSee((PlayerCharacter) mob.getCombatTarget())) {
|
if (!mob.canSee((PlayerCharacter) mob.getCombatTarget())) {
|
||||||
@@ -884,6 +883,7 @@ public class MobAI {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Mob.discDroppers.contains(aiAgent))
|
if(Mob.discDroppers.contains(aiAgent))
|
||||||
@@ -892,7 +892,7 @@ public class MobAI {
|
|||||||
if(aiAgent.StrongholdGuardian || aiAgent.StrongholdEpic || aiAgent.StrongholdCommander)
|
if(aiAgent.StrongholdGuardian || aiAgent.StrongholdEpic || aiAgent.StrongholdCommander)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (System.currentTimeMillis() > (aiAgent.deathTime + (aiAgent.spawnTime * 1000L))) {
|
if (aiAgent.despawned && System.currentTimeMillis() > (aiAgent.deathTime + (aiAgent.spawnTime * 1000L))) {
|
||||||
if (!Zone.respawnQue.contains(aiAgent)) {
|
if (!Zone.respawnQue.contains(aiAgent)) {
|
||||||
Zone.respawnQue.add(aiAgent);
|
Zone.respawnQue.add(aiAgent);
|
||||||
}
|
}
|
||||||
@@ -913,8 +913,10 @@ public class MobAI {
|
|||||||
if (mob.getCombatTarget() == null)
|
if (mob.getCombatTarget() == null)
|
||||||
return;
|
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);
|
mob.setCombatTarget(null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1066,8 +1068,8 @@ public class MobAI {
|
|||||||
if(mob.combatTarget == null)
|
if(mob.combatTarget == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(city._playerMemory.contains(mob.combatTarget.getObjectUUID()) && mob.combatTarget.getObjectType().equals(Enum.GameObjectType.PlayerCharacter))
|
//if(city._playerMemory.contains(mob.combatTarget.getObjectUUID()) && mob.combatTarget.getObjectType().equals(Enum.GameObjectType.PlayerCharacter))
|
||||||
mob.setCombatTarget(null);
|
// mob.setCombatTarget(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void GuardCaptainLogic(Mob mob) {
|
public static void GuardCaptainLogic(Mob mob) {
|
||||||
@@ -1417,4 +1419,11 @@ public class MobAI {
|
|||||||
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: RecoverHealth" + " " + e.getMessage());
|
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()));
|
AI_BASE_AGGRO_RANGE = (int)(60 * Float.parseFloat(ConfigManager.MB_AI_AGGRO_RANGE.getValue()));
|
||||||
while (true) {
|
while (true) {
|
||||||
for (Zone zone : ZoneManager.getAllZones()) {
|
for (Zone zone : ZoneManager.getAllZones()) {
|
||||||
|
if (zone != null && zone.zoneMobSet != null) {
|
||||||
for (Mob mob : zone.zoneMobSet) {
|
synchronized (zone.zoneMobSet) {
|
||||||
|
for (Mob mob : zone.zoneMobSet) {
|
||||||
try {
|
try {
|
||||||
if (mob != null)
|
if (mob != null) {
|
||||||
MobAI.DetermineAction(mob);
|
MobAI.DetermineAction(mob);
|
||||||
} catch (Exception e) {
|
}
|
||||||
Logger.error("Mob: " + mob.getName() + " UUID: " + mob.getObjectUUID() + " ERROR: " + e);
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
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() {
|
public static void startAIThread() {
|
||||||
|
|||||||
@@ -13,6 +13,9 @@ import engine.objects.Mob;
|
|||||||
import engine.objects.Zone;
|
import engine.objects.Zone;
|
||||||
import org.pmw.tinylog.Logger;
|
import org.pmw.tinylog.Logger;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Thread blocks until MagicBane dispatch messages are
|
* Thread blocks until MagicBane dispatch messages are
|
||||||
* enqueued then processes them in FIFO order. The collection
|
* enqueued then processes them in FIFO order. The collection
|
||||||
@@ -25,41 +28,48 @@ import org.pmw.tinylog.Logger;
|
|||||||
|
|
||||||
public class MobRespawnThread implements Runnable {
|
public class MobRespawnThread implements Runnable {
|
||||||
|
|
||||||
|
private volatile boolean running = true;
|
||||||
|
private static final long RESPAWN_INTERVAL = 100; // Configurable interval
|
||||||
|
|
||||||
public MobRespawnThread() {
|
public MobRespawnThread() {
|
||||||
Logger.info(" MobRespawnThread thread has started!");
|
Logger.info("MobRespawnThread initialized.");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
while (running) {
|
||||||
while (true) {
|
|
||||||
|
|
||||||
try {
|
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) {
|
||||||
Mob respawner = zone.respawnQue.iterator().next();
|
respawner.respawn();
|
||||||
|
zone.respawnQue.remove(respawner);
|
||||||
if (respawner == null)
|
zone.lastRespawn = System.currentTimeMillis();
|
||||||
continue;
|
}
|
||||||
|
}
|
||||||
respawner.respawn();
|
}
|
||||||
zone.respawnQue.remove(respawner);
|
|
||||||
zone.lastRespawn = System.currentTimeMillis();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Thread.sleep(100); // Prevent busy-waiting
|
||||||
} catch (Exception e) {
|
} 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() {
|
public static void startRespawnThread() {
|
||||||
Thread respawnThread;
|
Thread respawnThread = new Thread(new MobRespawnThread());
|
||||||
respawnThread = new Thread(new MobRespawnThread());
|
|
||||||
respawnThread.setName("respawnThread");
|
respawnThread.setName("respawnThread");
|
||||||
respawnThread.start();
|
respawnThread.start();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -140,7 +140,11 @@ public class CombatUtilities {
|
|||||||
|
|
||||||
public static boolean triggerDefense(Mob agent, AbstractWorldObject target) {
|
public static boolean triggerDefense(Mob agent, AbstractWorldObject target) {
|
||||||
int defense = 0;
|
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()) {
|
switch (target.getObjectType()) {
|
||||||
case PlayerCharacter:
|
case PlayerCharacter:
|
||||||
defense = ((AbstractCharacter) target).getDefenseRating();
|
defense = ((AbstractCharacter) target).getDefenseRating();
|
||||||
@@ -154,7 +158,7 @@ public class CombatUtilities {
|
|||||||
case Building:
|
case Building:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return CombatManager.LandHit(atr,defense);
|
return !CombatManager.LandHit(atr,defense);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean triggerBlock(Mob agent, AbstractWorldObject ac) {
|
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) {
|
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
|
//mob is duel wielding and should conduct an attack for each hand
|
||||||
ItemBase weapon1 = agent.getEquip().get(1).getItemBase();
|
ItemBase weapon1 = agent.getEquip().get(1).getItemBase();
|
||||||
double range1 = getMaxDmg(weapon1.getMinDamage(), agent, weapon1) - getMinDmg(weapon1.getMinDamage(), agent, weapon1);
|
double range1 = getMaxDmg(agent) - getMinDmg(agent);
|
||||||
double damage1 = getMinDmg(weapon1.getMinDamage(), agent, weapon1) + ((ThreadLocalRandom.current().nextFloat() * range1) + (ThreadLocalRandom.current().nextFloat() * range1)) / 2;
|
double damage1 = getMinDmg(agent) + ((ThreadLocalRandom.current().nextFloat() * range1) + (ThreadLocalRandom.current().nextFloat() * range1)) / 2;
|
||||||
swingIsDamage(agent, target, (float) damage1, CombatManager.getSwingAnimation(weapon1, null, true));
|
swingIsDamage(agent, target, (float) damage1, CombatManager.getSwingAnimation(weapon1, null, true));
|
||||||
ItemBase weapon2 = agent.getEquip().get(2).getItemBase();
|
ItemBase weapon2 = agent.getEquip().get(2).getItemBase();
|
||||||
double range2 = getMaxDmg(weapon2.getMinDamage(), agent, weapon2) - getMinDmg(weapon2.getMinDamage(), agent, weapon2);
|
double range2 = getMaxDmg(agent) - getMinDmg(agent);
|
||||||
double damage2 = getMinDmg(weapon2.getMinDamage(), agent, weapon2) + ((ThreadLocalRandom.current().nextFloat() * range2) + (ThreadLocalRandom.current().nextFloat() * range2)) / 2;
|
double damage2 = getMinDmg(agent) + ((ThreadLocalRandom.current().nextFloat() * range2) + (ThreadLocalRandom.current().nextFloat() * range2)) / 2;
|
||||||
swingIsDamage(agent, target, (float) damage2, CombatManager.getSwingAnimation(weapon1, null, false));
|
swingIsDamage(agent, target, (float) damage2, CombatManager.getSwingAnimation(weapon1, null, false));
|
||||||
} else {
|
} else {
|
||||||
swingIsDamage(agent, target, determineDamage(agent), anim);
|
swingIsDamage(agent, target, determineDamage(agent), anim);
|
||||||
@@ -307,9 +311,9 @@ public class CombatUtilities {
|
|||||||
float damage = 0;
|
float damage = 0;
|
||||||
|
|
||||||
DamageType dt = getDamageType(agent);
|
DamageType dt = getDamageType(agent);
|
||||||
if ((agent.agentType.equals(AIAgentType.PET)) == true || agent.isPet() == true || agent.isNecroPet() == true) {
|
if (agent.BehaviourType.equals(MobBehaviourType.Pet1)) {
|
||||||
damage = calculatePetDamage(agent);
|
damage = calculateMobDamage(agent);
|
||||||
} else if (agent.isPlayerGuard() == true) {
|
} else if (agent.isPlayerGuard()) {
|
||||||
//damage = calculateGuardDamage(agent);
|
//damage = calculateGuardDamage(agent);
|
||||||
damage = calculateMobDamage(agent);
|
damage = calculateMobDamage(agent);
|
||||||
} else if (agent.getLevel() > 80) {
|
} else if (agent.getLevel() > 80) {
|
||||||
@@ -349,8 +353,8 @@ public class CombatUtilities {
|
|||||||
float min = 40;
|
float min = 40;
|
||||||
float max = 60;
|
float max = 60;
|
||||||
float dmgMultiplier = 1 + agent.getBonuses().getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.None);
|
float dmgMultiplier = 1 + agent.getBonuses().getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.None);
|
||||||
double minDmg = getMinDmg(min, agent, null);
|
double minDmg = getMinDmg(agent);
|
||||||
double maxDmg = getMaxDmg(max, agent, null);
|
double maxDmg = getMaxDmg(agent);
|
||||||
dmgMultiplier += agent.getLevel() * 0.1f;
|
dmgMultiplier += agent.getLevel() * 0.1f;
|
||||||
range = (float) (maxDmg - minDmg);
|
range = (float) (maxDmg - minDmg);
|
||||||
damage = min + ((ThreadLocalRandom.current().nextFloat() * range) + (ThreadLocalRandom.current().nextFloat() * range)) / 2;
|
damage = min + ((ThreadLocalRandom.current().nextFloat() * range) + (ThreadLocalRandom.current().nextFloat() * range)) / 2;
|
||||||
@@ -366,8 +370,8 @@ public class CombatUtilities {
|
|||||||
|
|
||||||
double minDmg = weapon.getMinDamage();
|
double minDmg = weapon.getMinDamage();
|
||||||
double maxDmg = weapon.getMaxDamage();
|
double maxDmg = weapon.getMaxDamage();
|
||||||
double min = getMinDmg(minDmg, agent, weapon);
|
double min = getMinDmg(agent);
|
||||||
double max = getMaxDmg(maxDmg, agent, weapon);
|
double max = getMaxDmg(agent);
|
||||||
|
|
||||||
DamageType dt = weapon.getDamageType();
|
DamageType dt = weapon.getDamageType();
|
||||||
|
|
||||||
@@ -408,92 +412,48 @@ public class CombatUtilities {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static int calculateMobDamage(Mob agent) {
|
public static int calculateMobDamage(Mob agent) {
|
||||||
ItemBase weapon = null;
|
double minDmg = getMinDmg(agent);
|
||||||
double minDmg;
|
double maxDmg = getMaxDmg(agent);
|
||||||
double maxDmg;
|
DamageType dt = getDamageType(agent);
|
||||||
DamageType dt;
|
|
||||||
|
|
||||||
//main hand or offhand damage
|
|
||||||
|
|
||||||
if (agent.getEquip().get(1) != null)
|
|
||||||
weapon = agent.getEquip().get(1).getItemBase();
|
|
||||||
else if (agent.getEquip().get(2) != null)
|
|
||||||
weapon = agent.getEquip().get(2).getItemBase();
|
|
||||||
|
|
||||||
if (weapon != null) {
|
|
||||||
minDmg = getMinDmg(weapon.getMinDamage(), agent, weapon);
|
|
||||||
maxDmg = getMaxDmg(weapon.getMaxDamage(), agent, weapon);
|
|
||||||
dt = weapon.getDamageType();
|
|
||||||
} else {
|
|
||||||
minDmg = agent.getMobBase().getDamageMin();
|
|
||||||
maxDmg = agent.getMobBase().getDamageMax();
|
|
||||||
dt = DamageType.Crush;
|
|
||||||
}
|
|
||||||
|
|
||||||
AbstractWorldObject target = agent.getCombatTarget();
|
AbstractWorldObject target = agent.getCombatTarget();
|
||||||
|
|
||||||
float dmgMultiplier = 1 + agent.getBonuses().getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.None);
|
double damage = ThreadLocalRandom.current().nextInt((int)minDmg,(int)maxDmg + 1);
|
||||||
double range = maxDmg - minDmg;
|
|
||||||
double damage = minDmg + ((ThreadLocalRandom.current().nextFloat() * range) + (ThreadLocalRandom.current().nextFloat() * range)) / 2;
|
|
||||||
|
|
||||||
if (AbstractWorldObject.IsAbstractCharacter(target))
|
if (AbstractWorldObject.IsAbstractCharacter(target))
|
||||||
if (((AbstractCharacter) target).isSit())
|
if (((AbstractCharacter) target).isSit())
|
||||||
damage *= 2.5f; //increase damage if sitting
|
damage *= 2.5f; //increase damage if sitting
|
||||||
if (AbstractWorldObject.IsAbstractCharacter(target))
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static double getMinDmg(double min, Mob agent, ItemBase weapon) {
|
public static double getMinDmg(Mob agent) {
|
||||||
|
if(agent.getEquip() != null){
|
||||||
int primary = agent.getStatStrCurrent();
|
if(agent.getEquip().get(ItemSlotType.RHELD) != null){
|
||||||
int secondary = agent.getStatDexCurrent();
|
return agent.minDamageHandOne;
|
||||||
int focusLevel = 0;
|
}else if(agent.getEquip().get(ItemSlotType.LHELD) != null){
|
||||||
int masteryLevel = 0;
|
return agent.getMinDamageHandTwo();
|
||||||
|
}else{
|
||||||
if (weapon != null) {
|
return agent.minDamageHandOne;
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
}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) {
|
public static double getMaxDmg(Mob agent) {
|
||||||
|
if(agent.getEquip() != null){
|
||||||
int primary = agent.getStatStrCurrent();
|
if(agent.getEquip().get(ItemSlotType.RHELD) != null){
|
||||||
int secondary = agent.getStatDexCurrent();
|
return agent.maxDamageHandOne;
|
||||||
int focusLevel = 0;
|
}else if(agent.getEquip().get(ItemSlotType.LHELD) != null){
|
||||||
int masteryLevel = 0;
|
return agent.getMaxDamageHandTwo();
|
||||||
|
}else{
|
||||||
if (weapon != null) {
|
return agent.maxDamageHandOne;
|
||||||
|
}
|
||||||
if (weapon.isStrBased() == true) {
|
}else{
|
||||||
primary = agent.getStatStrCurrent();
|
return agent.maxDamageHandOne;
|
||||||
secondary = agent.getStatDexCurrent();
|
|
||||||
} else {
|
|
||||||
primary = agent.getStatDexCurrent();
|
|
||||||
secondary = agent.getStatStrCurrent();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (agent.getSkills().containsKey(weapon.getSkillRequired()))
|
|
||||||
focusLevel = (int) agent.getSkills().get(weapon.getSkillRequired()).getModifiedAmount();
|
|
||||||
|
|
||||||
if (agent.getSkills().containsKey(weapon.getSkillRequired()))
|
|
||||||
masteryLevel = (int) agent.getSkills().get(weapon.getMastery()).getModifiedAmount();
|
|
||||||
|
|
||||||
}
|
|
||||||
return max * (pow(0.0124 * primary + 0.118 * (primary - 0.75), 0.5) + pow(0.0022 * secondary + 0.028 * (secondary - 0.75), 0.5) + 0.0075 * (focusLevel + masteryLevel));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 sl = agent.getLoc();
|
||||||
Vector3fImmutable tl = target.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 range = agent.getRange() + 150;
|
||||||
|
|
||||||
|
|
||||||
|
//float distanceSquaredToTarget = sl.distanceSquared2D(tl) - sqr(agent.calcHitBox() + target.calcHitBox()); //distance to center of target
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (range > 200)
|
if (range > 200)
|
||||||
range = 200;
|
range = 200;
|
||||||
|
|
||||||
|
|
||||||
return distanceSquaredToTarget < sqr(range);
|
return disSq > (range * range);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -227,10 +227,10 @@ public class ClientConnection extends AbstractConnection {
|
|||||||
SessionManager.remSession(
|
SessionManager.remSession(
|
||||||
SessionManager.getSession(sessionID));
|
SessionManager.getSession(sessionID));
|
||||||
} catch (NullPointerException e) {
|
} catch (NullPointerException e) {
|
||||||
Logger
|
//Logger
|
||||||
.error(
|
//.error(
|
||||||
"Tried to remove improperly initialized session. Skipping." +
|
//"Tried to remove improperly initialized session. Skipping." +
|
||||||
e);
|
//e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1681,15 +1681,12 @@ public class ClientMessagePump implements NetMsgHandler {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cost = ((int)((toRepair.getMagicValue()/max*(max - dur)) + (npc.getSpecialPrice() * npc.buyPercent))) + (int)(npc.getSpecialPrice() * (max - dur));
|
int pointsToRepair = max - dur;
|
||||||
|
double damageRatio = (double)1.0d - (toRepair.getDurabilityMax() - toRepair.getDurabilityCurrent()) / toRepair.getDurabilityMax();
|
||||||
//int pointsToRepair = max - dur;
|
int modifiedValue = (int)(damageRatio * toRepair.getMagicValue());
|
||||||
//int magicValue = toRepair.getMagicValue();
|
int costPerPoint = modifiedValue / toRepair.getDurabilityMax();
|
||||||
//if(magicValue == 0)
|
int modifiedRepairCost = (int)(pointsToRepair * costPerPoint)+ npc.getSpecialPrice();
|
||||||
// magicValue = 1;
|
int cost = (int)(modifiedRepairCost * 1 + npc.buyPercent) + npc.getSpecialPrice();
|
||||||
//int calculatedValue = toRepair.getDurabilityMax() * magicValue;
|
|
||||||
//float costPerPoint = (magicValue / max) * ( 1 + npc.buyPercent);
|
|
||||||
//cost = (int)(pointsToRepair * costPerPoint) + npc.getSpecialPrice();
|
|
||||||
Building b = (!npc.isStatic()) ? npc.getBuilding() : null;
|
Building b = (!npc.isStatic()) ? npc.getBuilding() : null;
|
||||||
|
|
||||||
if (b != null)
|
if (b != null)
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ public class ActivateNPCMsgHandler extends AbstractClientMsgHandler {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (building.getBlueprint().getMaxSlots() == building.getHirelings().size())
|
if (building.getBlueprint().getMaxSlots() == building.getHirelings().size() && building.getRank() != 8)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
Item contractItem = Item.getFromCache(msg.getContractItem());
|
Item contractItem = Item.getFromCache(msg.getContractItem());
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
package engine.net.client.handlers;
|
package engine.net.client.handlers;
|
||||||
|
|
||||||
|
import engine.Enum;
|
||||||
import engine.Enum.DispatchChannel;
|
import engine.Enum.DispatchChannel;
|
||||||
import engine.exception.MsgSendException;
|
import engine.exception.MsgSendException;
|
||||||
import engine.net.DispatchMessage;
|
import engine.net.DispatchMessage;
|
||||||
@@ -42,6 +43,9 @@ public class ChangeAltitudeHandler extends AbstractClientMsgHandler {
|
|||||||
if (!AbstractCharacter.CanFly(pc))
|
if (!AbstractCharacter.CanFly(pc))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if(pc.getBonuses().getBool(Enum.ModType.Stunned, Enum.SourceType.None))
|
||||||
|
return false;
|
||||||
|
|
||||||
if (pc.isSwimming())
|
if (pc.isSwimming())
|
||||||
return false;
|
return false;
|
||||||
if (pc.region != null && !pc.region.isOutside())
|
if (pc.region != null && !pc.region.isOutside())
|
||||||
|
|||||||
@@ -346,7 +346,6 @@ public class ObjectActionMsgHandler extends AbstractClientMsgHandler {
|
|||||||
pam.setY(loc.getY());
|
pam.setY(loc.getY());
|
||||||
pam.setZ(loc.getZ() + 64); //offset grid from tol
|
pam.setZ(loc.getZ() + 64); //offset grid from tol
|
||||||
pam.addPlacementInfo(ib.getUseID());
|
pam.addPlacementInfo(ib.getUseID());
|
||||||
|
|
||||||
dispatch = Dispatch.borrow(player, pam);
|
dispatch = Dispatch.borrow(player, pam);
|
||||||
DispatchMessage.dispatchMsgDispatch(dispatch, Enum.DispatchChannel.SECONDARY);
|
DispatchMessage.dispatchMsgDispatch(dispatch, Enum.DispatchChannel.SECONDARY);
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import engine.db.archive.DataWarehouse;
|
|||||||
import engine.exception.MsgSendException;
|
import engine.exception.MsgSendException;
|
||||||
import engine.gameManager.*;
|
import engine.gameManager.*;
|
||||||
import engine.math.Bounds;
|
import engine.math.Bounds;
|
||||||
|
import engine.math.Vector3f;
|
||||||
import engine.math.Vector3fImmutable;
|
import engine.math.Vector3fImmutable;
|
||||||
import engine.net.Dispatch;
|
import engine.net.Dispatch;
|
||||||
import engine.net.DispatchMessage;
|
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) {
|
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());
|
PlaceAssetMsg.sendPlaceAssetError(origin, 52, player.getName());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -329,6 +330,24 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
|
|||||||
|
|
||||||
playerCharacter = SessionManager.getPlayerCharacter(origin);
|
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
|
// We need to figure out what exactly the player is attempting
|
||||||
// to place, as some objects like tol/bane/walls are edge cases.
|
// to place, as some objects like tol/bane/walls are edge cases.
|
||||||
// So let's get the first item in their list.
|
// So let's get the first item in their list.
|
||||||
@@ -1148,6 +1167,15 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
|
|||||||
wallPiece.setProtectionState(ProtectionState.PROTECTED);
|
wallPiece.setProtectionState(ProtectionState.PROTECTED);
|
||||||
PlaceAssetMsg.sendPlaceAssetConfirmWall(origin, serverZone);
|
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
|
// Deduct gold from character's inventory
|
||||||
|
|||||||
@@ -146,6 +146,8 @@ public class ApplyRuneMsg extends ClientNetMsg {
|
|||||||
valid = true;
|
valid = true;
|
||||||
if(runeID == 3035 && baseClassID == 2501)
|
if(runeID == 3035 && baseClassID == 2501)
|
||||||
valid = true;
|
valid = true;
|
||||||
|
if(runeID == 3028 && baseClassID == 2501 && playerCharacter.getRace().getName().contains("Irekei"))
|
||||||
|
valid = true;
|
||||||
if (!valid) {
|
if (!valid) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -200,7 +202,7 @@ public class ApplyRuneMsg extends ClientNetMsg {
|
|||||||
for (CharacterRune cr : runes) {
|
for (CharacterRune cr : runes) {
|
||||||
int runeBaseID = cr.getRuneBaseID();
|
int runeBaseID = cr.getRuneBaseID();
|
||||||
//count number of discipline runes
|
//count number of discipline runes
|
||||||
if (runeBaseID > 3000 && runeBaseID < 3049) {
|
if(isDiscipline(runeBaseID)){
|
||||||
discCount++;
|
discCount++;
|
||||||
}
|
}
|
||||||
//see if rune is already applied
|
//see if rune is already applied
|
||||||
@@ -329,23 +331,29 @@ public class ApplyRuneMsg extends ClientNetMsg {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
//if discipline, check number applied
|
//if discipline, check number applied
|
||||||
|
int discAllowed = 0;
|
||||||
if (isDiscipline(runeID)) {
|
if (isDiscipline(runeID)) {
|
||||||
switch(playerCharacter.getRank()){
|
switch(playerCharacter.getRank()){
|
||||||
case 1:
|
case 1:
|
||||||
|
discAllowed = 0;
|
||||||
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
case 3:
|
case 3:
|
||||||
case 4:
|
case 4:
|
||||||
case 5:
|
case 5:
|
||||||
case 6:
|
case 6:
|
||||||
if(discCount > 3)
|
discAllowed = 3;
|
||||||
return false;
|
|
||||||
break;
|
break;
|
||||||
case 7:
|
case 7:
|
||||||
|
discAllowed = 4;
|
||||||
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
if(discCount > 5)
|
discAllowed = 5;
|
||||||
return false;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(discCount >= discAllowed)
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
//Everything succeeded. Let's apply the rune
|
//Everything succeeded. Let's apply the rune
|
||||||
//Attempt add rune to database
|
//Attempt add rune to database
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ package engine.net.client.msg;
|
|||||||
|
|
||||||
import engine.Enum.DispatchChannel;
|
import engine.Enum.DispatchChannel;
|
||||||
import engine.Enum.GuildHistoryType;
|
import engine.Enum.GuildHistoryType;
|
||||||
|
import engine.QuestSystem.QuestManager;
|
||||||
import engine.exception.MsgSendException;
|
import engine.exception.MsgSendException;
|
||||||
import engine.gameManager.BuildingManager;
|
import engine.gameManager.BuildingManager;
|
||||||
import engine.gameManager.DbManager;
|
import engine.gameManager.DbManager;
|
||||||
@@ -125,18 +126,22 @@ public class VendorDialogMsg extends ClientNetMsg {
|
|||||||
vd = Contract.HandleBaneCommanderOptions(msg.unknown03, npc, playerCharacter);
|
vd = Contract.HandleBaneCommanderOptions(msg.unknown03, npc, playerCharacter);
|
||||||
msg.updateMessage(3, vd);
|
msg.updateMessage(3, vd);
|
||||||
}else {
|
}else {
|
||||||
|
if(QuestManager.grantsQuest(npc)){
|
||||||
if (contract == null)
|
vd = Contract.HandleQuestOptions(msg.unknown03, npc, playerCharacter);
|
||||||
vd = VendorDialog.getHostileVendorDialog();
|
msg.updateMessage(3, vd);
|
||||||
else if (npc.getBuilding() != null) {
|
}else {
|
||||||
if (npc.getBuilding() != null && BuildingManager.IsPlayerHostile(npc.getBuilding(), playerCharacter))
|
if (contract == null)
|
||||||
vd = VendorDialog.getHostileVendorDialog();
|
vd = VendorDialog.getHostileVendorDialog();
|
||||||
else
|
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();
|
vd = contract.getVendorDialog();
|
||||||
} else
|
if (vd == null)
|
||||||
vd = contract.getVendorDialog();
|
vd = VendorDialog.getHostileVendorDialog();
|
||||||
if (vd == null)
|
}
|
||||||
vd = VendorDialog.getHostileVendorDialog();
|
|
||||||
if (msg.messageType == 1 || msg.unknown03 == vd.getObjectUUID()) {
|
if (msg.messageType == 1 || msg.unknown03 == vd.getObjectUUID()) {
|
||||||
msg.updateMessage(3, vd);
|
msg.updateMessage(3, vd);
|
||||||
} else {
|
} else {
|
||||||
@@ -631,6 +636,11 @@ public class VendorDialogMsg extends ClientNetMsg {
|
|||||||
.getObjectUUID(), true);
|
.getObjectUUID(), true);
|
||||||
DispatchMessage.dispatchMsgToInterestArea(pc, arm, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false);
|
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) {
|
public static void HandleResponse(int set, int filterType, String filter, ClientConnection origin) {
|
||||||
|
|
||||||
|
if (filter.equals("")) {
|
||||||
|
filter = "Saetor";
|
||||||
|
}
|
||||||
WhoResponseMsg msg = new WhoResponseMsg();
|
WhoResponseMsg msg = new WhoResponseMsg();
|
||||||
WhoResponseMsg.setWorldPop(SessionManager.getAllActivePlayerCharacters().size());
|
WhoResponseMsg.setWorldPop(SessionManager.getAllActivePlayerCharacters().size());
|
||||||
|
|
||||||
|
|||||||
@@ -14,10 +14,7 @@ import engine.Enum.*;
|
|||||||
import engine.InterestManagement.InterestManager;
|
import engine.InterestManagement.InterestManager;
|
||||||
import engine.InterestManagement.WorldGrid;
|
import engine.InterestManagement.WorldGrid;
|
||||||
import engine.exception.SerializationException;
|
import engine.exception.SerializationException;
|
||||||
import engine.gameManager.CombatManager;
|
import engine.gameManager.*;
|
||||||
import engine.gameManager.ConfigManager;
|
|
||||||
import engine.gameManager.MovementManager;
|
|
||||||
import engine.gameManager.PowersManager;
|
|
||||||
import engine.job.AbstractJob;
|
import engine.job.AbstractJob;
|
||||||
import engine.job.JobContainer;
|
import engine.job.JobContainer;
|
||||||
import engine.job.JobScheduler;
|
import engine.job.JobScheduler;
|
||||||
@@ -503,7 +500,6 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
|
|||||||
canFly = false;
|
canFly = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return canFly;
|
return canFly;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -764,7 +760,11 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
|
|||||||
public abstract Vector3fImmutable getBindLoc();
|
public abstract Vector3fImmutable getBindLoc();
|
||||||
|
|
||||||
public final void setBindLoc(final Vector3fImmutable value) {
|
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() {
|
public final Vector3fImmutable getFaceDir() {
|
||||||
@@ -1101,7 +1101,7 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final void setCombatTarget(final AbstractWorldObject value) {
|
public final void setCombatTarget(final AbstractWorldObject value) {
|
||||||
if(this.getObjectTypeMask() == 2050) {//MOB?
|
if (this.getObjectTypeMask() == 2050) {//MOB?
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
if (this.isCombat()) {
|
if (this.isCombat()) {
|
||||||
this.setCombat(false);
|
this.setCombat(false);
|
||||||
@@ -1109,13 +1109,6 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
|
|||||||
rwss.setPlayer(this);
|
rwss.setPlayer(this);
|
||||||
DispatchMessage.sendToAllInRange(this, rwss);
|
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;
|
this.combatTarget = value;
|
||||||
@@ -1558,7 +1551,15 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
|
|||||||
Effect eff = this.effects.get(s);
|
Effect eff = this.effects.get(s);
|
||||||
if (eff == null)
|
if (eff == null)
|
||||||
continue;
|
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");
|
//System.out.println("canceling on Move");
|
||||||
eff.cancelJob();
|
eff.cancelJob();
|
||||||
this.effects.remove(s);
|
this.effects.remove(s);
|
||||||
|
|||||||
@@ -428,32 +428,24 @@ public final class Bane {
|
|||||||
|
|
||||||
// Cache access
|
// Cache access
|
||||||
|
|
||||||
private void setDefaultTime() {
|
public void setDefaultTime() {
|
||||||
|
|
||||||
DateTime timeToSetDefault = new DateTime(this.placementDate);
|
DateTime timeToSetDefault = new DateTime(this.placementDate);
|
||||||
timeToSetDefault = timeToSetDefault.plusDays(1);
|
timeToSetDefault = timeToSetDefault.plusDays(1);
|
||||||
|
|
||||||
DateTime currentTime = DateTime.now();
|
if (DateTime.now().isAfter(timeToSetDefault)){
|
||||||
DateTime defaultTime = new DateTime(this.placementDate);
|
if(!this.capSet){
|
||||||
defaultTime = defaultTime.plusDays(2);
|
DbManager.BaneQueries.SET_BANE_CAP_NEW(20,this.getCityUUID());
|
||||||
defaultTime = defaultTime.hourOfDay().setCopy(22);
|
this.capSet = true;
|
||||||
defaultTime = defaultTime.minuteOfHour().setCopy(0);
|
}
|
||||||
defaultTime = defaultTime.secondOfMinute().setCopy(0);
|
if(!this.daySet){
|
||||||
|
DbManager.BaneQueries.SET_BANE_DAY_NEW(3,this.getCityUUID());
|
||||||
if (currentTime.isAfter(timeToSetDefault)){
|
this.daySet = true;
|
||||||
DbManager.BaneQueries.SET_BANE_CAP_NEW(20,this.getCityUUID());
|
}
|
||||||
DbManager.BaneQueries.SET_BANE_TIME_NEW(9,this.getCityUUID());
|
if(!this.timeSet){
|
||||||
DbManager.BaneQueries.SET_BANE_DAY_NEW(3,this.getCityUUID());
|
DbManager.BaneQueries.SET_BANE_TIME_NEW(9,this.getCityUUID());
|
||||||
}
|
this.timeSet = true;
|
||||||
//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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -360,6 +360,10 @@ this.maxRank = rs.getInt("MaxRank");
|
|||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(bg != null && bg.equals(BuildingGroup.TOL) && currentRank == 8){
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
|
||||||
if (this.maxRank == 1 && currentRank == 1)
|
if (this.maxRank == 1 && currentRank == 1)
|
||||||
return getMaxSlots();
|
return getMaxSlots();
|
||||||
|
|
||||||
|
|||||||
@@ -160,23 +160,16 @@ public class Building extends AbstractWorldObject {
|
|||||||
// in City resulting in a stack ovreflow.
|
// in City resulting in a stack ovreflow.
|
||||||
|
|
||||||
if (blueprint != null) {
|
if (blueprint != null) {
|
||||||
|
|
||||||
// Only switch mesh for player dropped structures
|
// Only switch mesh for player dropped structures
|
||||||
|
|
||||||
if (this.blueprintUUID != 0)
|
if (this.blueprintUUID != 0)
|
||||||
this.meshUUID = blueprint.getMeshForRank(rank);
|
this.meshUUID = blueprint.getMeshForRank(rank);
|
||||||
|
|
||||||
this.healthMax = blueprint.getMaxHealth(this.rank);
|
this.healthMax = blueprint.getMaxHealth(this.rank);
|
||||||
|
|
||||||
// If this object has no blueprint but is a blueprint
|
// If this object has no blueprint but is a blueprint
|
||||||
// mesh then set it's current health to max health
|
// mesh then set it's current health to max health
|
||||||
|
|
||||||
if (this.blueprintUUID == 0)
|
if (this.blueprintUUID == 0)
|
||||||
this.setHealth(healthMax);
|
this.setHealth(healthMax);
|
||||||
|
|
||||||
if (blueprint.getBuildingGroup().equals(BuildingGroup.BARRACK))
|
if (blueprint.getBuildingGroup().equals(BuildingGroup.BARRACK))
|
||||||
this.patrolPoints = DbManager.BuildingQueries.LOAD_PATROL_POINTS(this);
|
this.patrolPoints = DbManager.BuildingQueries.LOAD_PATROL_POINTS(this);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
this.healthMax = 100000; // Structures with no blueprint mesh
|
this.healthMax = 100000; // Structures with no blueprint mesh
|
||||||
this.setHealth(healthMax);
|
this.setHealth(healthMax);
|
||||||
@@ -419,6 +412,22 @@ public class Building extends AbstractWorldObject {
|
|||||||
this.healthMax = this.getBlueprint().getMaxHealth(this.rank);
|
this.healthMax = this.getBlueprint().getMaxHealth(this.rank);
|
||||||
this.setCurrentHitPoints(this.healthMax);
|
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)
|
if (this.getUpgradeDateTime() != null)
|
||||||
BuildingManager.setUpgradeDateTime(this, null, 0);
|
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
|
// Set bounds for this building
|
||||||
|
|
||||||
Bounds buildingBounds = Bounds.borrow();
|
Bounds buildingBounds = Bounds.borrow();
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ package engine.objects;
|
|||||||
|
|
||||||
import ch.claude_martin.enumbitset.EnumBitSet;
|
import ch.claude_martin.enumbitset.EnumBitSet;
|
||||||
import engine.Enum;
|
import engine.Enum;
|
||||||
|
import engine.QuestSystem.QuestManager;
|
||||||
import engine.gameManager.*;
|
import engine.gameManager.*;
|
||||||
import engine.net.Dispatch;
|
import engine.net.Dispatch;
|
||||||
import engine.net.DispatchMessage;
|
import engine.net.DispatchMessage;
|
||||||
@@ -477,6 +478,21 @@ public class Contract extends AbstractGameObject {
|
|||||||
return vd;
|
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() {
|
public ArrayList<Integer> getNPCMenuOptions() {
|
||||||
return this.npcMenuOptions;
|
return this.npcMenuOptions;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ public class Corpse extends AbstractWorldObject {
|
|||||||
private int inBuildingID = 0;
|
private int inBuildingID = 0;
|
||||||
private int inFloorID = -1;
|
private int inFloorID = -1;
|
||||||
private int inBuilding = -1;
|
private int inBuilding = -1;
|
||||||
|
public Long spawnedTime = 0L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* No Id Constructor
|
* No Id Constructor
|
||||||
@@ -74,6 +75,7 @@ public class Corpse extends AbstractWorldObject {
|
|||||||
}
|
}
|
||||||
this.setObjectTypeMask(MBServerStatics.MASK_CORPSE);
|
this.setObjectTypeMask(MBServerStatics.MASK_CORPSE);
|
||||||
|
|
||||||
|
this.spawnedTime = System.currentTimeMillis();
|
||||||
if (!safeZone)
|
if (!safeZone)
|
||||||
transferInventory(belongsTo, enterWorld);
|
transferInventory(belongsTo, enterWorld);
|
||||||
|
|
||||||
|
|||||||
@@ -349,6 +349,9 @@ public class Experience {
|
|||||||
if(killer.equals(mob))
|
if(killer.equals(mob))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if(killer.pvpKills.contains(mob.getObjectUUID()))
|
||||||
|
return;
|
||||||
|
|
||||||
double grantedExperience = 0.0;
|
double grantedExperience = 0.0;
|
||||||
|
|
||||||
if (g != null) { // Do group EXP stuff
|
if (g != null) { // Do group EXP stuff
|
||||||
|
|||||||
@@ -1227,7 +1227,10 @@ public class Item extends AbstractWorldObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final int getMagicValue() {
|
public final int getMagicValue() {
|
||||||
return this.magicValue;
|
int val = this.calcMagicValue();
|
||||||
|
if(val == 0)
|
||||||
|
val = 1;
|
||||||
|
return val + this.getItemBase().getMagicValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getBaseValue() {
|
public int getBaseValue() {
|
||||||
|
|||||||
+115
-222
@@ -12,7 +12,9 @@ package engine.objects;
|
|||||||
import ch.claude_martin.enumbitset.EnumBitSet;
|
import ch.claude_martin.enumbitset.EnumBitSet;
|
||||||
import engine.Enum;
|
import engine.Enum;
|
||||||
import engine.Enum.*;
|
import engine.Enum.*;
|
||||||
|
import engine.InterestManagement.InterestManager;
|
||||||
import engine.InterestManagement.WorldGrid;
|
import engine.InterestManagement.WorldGrid;
|
||||||
|
import engine.QuestSystem.QuestManager;
|
||||||
import engine.exception.SerializationException;
|
import engine.exception.SerializationException;
|
||||||
import engine.gameManager.*;
|
import engine.gameManager.*;
|
||||||
import engine.job.JobScheduler;
|
import engine.job.JobScheduler;
|
||||||
@@ -1270,6 +1272,15 @@ public class Mob extends AbstractIntelligenceAgent {
|
|||||||
// Give XP, now handled inside the Experience Object
|
// Give XP, now handled inside the Experience Object
|
||||||
if (!this.isPet() && !this.isNecroPet() && !(this.agentType.equals(AIAgentType.PET)) && !this.isPlayerGuard)
|
if (!this.isPet() && !this.isNecroPet() && !(this.agentType.equals(AIAgentType.PET)) && !this.isPlayerGuard)
|
||||||
Experience.doExperience((PlayerCharacter) attacker, this, g);
|
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)) {
|
} else if (attacker.getObjectType().equals(GameObjectType.Mob)) {
|
||||||
Mob mobAttacker = (Mob) attacker;
|
Mob mobAttacker = (Mob) attacker;
|
||||||
|
|
||||||
@@ -1326,8 +1337,6 @@ public class Mob extends AbstractIntelligenceAgent {
|
|||||||
Dispatch dispatch;
|
Dispatch dispatch;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
//resync corpses
|
|
||||||
//this.setLoc(this.getMovementLoc());
|
|
||||||
if (this.isSiege) {
|
if (this.isSiege) {
|
||||||
this.deathTime = System.currentTimeMillis();
|
this.deathTime = System.currentTimeMillis();
|
||||||
//this.state = STATE.Dead;
|
//this.state = STATE.Dead;
|
||||||
@@ -1407,6 +1416,8 @@ public class Mob extends AbstractIntelligenceAgent {
|
|||||||
Logger.error(e);
|
Logger.error(e);
|
||||||
}
|
}
|
||||||
this.updateLocation();
|
this.updateLocation();
|
||||||
|
//resync corpses
|
||||||
|
InterestManager.setObjectDirty(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void respawn() {
|
public void respawn() {
|
||||||
@@ -1441,6 +1452,8 @@ public class Mob extends AbstractIntelligenceAgent {
|
|||||||
loadInventory();
|
loadInventory();
|
||||||
|
|
||||||
this.updateLocation();
|
this.updateLocation();
|
||||||
|
this.stopPatrolTime = 0;
|
||||||
|
this.lastPatrolPointIndex = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void despawn() {
|
public void despawn() {
|
||||||
@@ -1635,66 +1648,66 @@ public class Mob extends AbstractIntelligenceAgent {
|
|||||||
this.defenseRating = defense;
|
this.defenseRating = defense;
|
||||||
this.atrHandOne = atr;
|
this.atrHandOne = atr;
|
||||||
return;
|
return;
|
||||||
|
}else {
|
||||||
|
if (this.charItemManager == null || this.equip == null) {
|
||||||
|
Logger.error("Player " + currentID + " missing skills or equipment");
|
||||||
|
defaultAtrAndDamage(true);
|
||||||
|
defaultAtrAndDamage(false);
|
||||||
|
this.defenseRating = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
calculateAtrDamageForWeapon(this.equip.get(MBServerStatics.SLOT_MAINHAND), true);
|
||||||
|
} catch (Exception e) {
|
||||||
|
|
||||||
|
this.atrHandOne = GetAttackRating(this.mobBase.getAttackRating(), this);
|
||||||
|
this.minDamageHandOne = (short) this.mobBase.getDamageMin();
|
||||||
|
this.maxDamageHandOne = (short) this.mobBase.getDamageMax();
|
||||||
|
this.rangeHandOne = 6.5f;
|
||||||
|
this.speedHandOne = 20;
|
||||||
|
Logger.info("Mobbase ID " + this.getMobBaseID() + " returned an error. setting to default ATR and Damage." + e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
calculateAtrDamageForWeapon(this.equip.get(MBServerStatics.SLOT_OFFHAND), false);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
|
||||||
|
this.atrHandTwo = GetAttackRating(this.mobBase.getAttackRating(), this);
|
||||||
|
this.minDamageHandTwo = (short) this.mobBase.getDamageMin();
|
||||||
|
this.maxDamageHandTwo = (short) this.mobBase.getDamageMax();
|
||||||
|
this.rangeHandTwo = 6.5f;
|
||||||
|
this.speedHandTwo = 20;
|
||||||
|
Logger.info("Mobbase ID " + this.getMobBaseID() + " returned an error. setting to default ATR and Damage." + e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
float defense = this.mobBase.getDefenseRating();
|
||||||
|
defense += getShieldDefense(equip.get(MBServerStatics.SLOT_OFFHAND));
|
||||||
|
defense += getArmorDefense(equip.get(MBServerStatics.SLOT_HELMET));
|
||||||
|
defense += getArmorDefense(equip.get(MBServerStatics.SLOT_CHEST));
|
||||||
|
defense += getArmorDefense(equip.get(MBServerStatics.SLOT_ARMS));
|
||||||
|
defense += getArmorDefense(equip.get(MBServerStatics.SLOT_GLOVES));
|
||||||
|
defense += getArmorDefense(equip.get(MBServerStatics.SLOT_LEGGINGS));
|
||||||
|
defense += getArmorDefense(equip.get(MBServerStatics.SLOT_FEET));
|
||||||
|
defense += getWeaponDefense(equip);
|
||||||
|
|
||||||
|
// TODO add error log here
|
||||||
|
if (this.bonuses != null) {
|
||||||
|
defense = GetDefense((int) defense, this);
|
||||||
|
|
||||||
|
} else
|
||||||
|
Logger.error("Error: missing bonuses");
|
||||||
|
|
||||||
|
defense = (defense < 1) ? 1 : defense;
|
||||||
|
this.defenseRating = (short) (defense + 0.5f);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Logger.info("Mobbase ID " + this.getMobBaseID() + " returned an error. Setting to Default Defense." + e.getMessage());
|
||||||
|
this.defenseRating = (short) this.mobBase.getDefense();
|
||||||
|
}
|
||||||
|
// calculate defense for equipment
|
||||||
}
|
}
|
||||||
if (this.charItemManager == null || this.equip == null) {
|
|
||||||
Logger.error("Player " + currentID + " missing skills or equipment");
|
|
||||||
defaultAtrAndDamage(true);
|
|
||||||
defaultAtrAndDamage(false);
|
|
||||||
this.defenseRating = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
calculateAtrDamageForWeapon(this.equip.get(MBServerStatics.SLOT_MAINHAND), true);
|
|
||||||
} catch (Exception e) {
|
|
||||||
|
|
||||||
this.atrHandOne = GetAttackRating(this.mobBase.getAttackRating(), this);
|
|
||||||
this.minDamageHandOne = (short) this.mobBase.getMinDmg();
|
|
||||||
this.maxDamageHandOne = (short) this.mobBase.getMaxDmg();
|
|
||||||
this.rangeHandOne = 6.5f;
|
|
||||||
this.speedHandOne = 20;
|
|
||||||
Logger.info("Mobbase ID " + this.getMobBaseID() + " returned an error. setting to default ATR and Damage." + e.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
calculateAtrDamageForWeapon(this.equip.get(MBServerStatics.SLOT_OFFHAND), false);
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
|
|
||||||
this.atrHandTwo = GetAttackRating(this.mobBase.getAttackRating(), this);
|
|
||||||
this.minDamageHandTwo = (short) this.mobBase.getMinDmg();
|
|
||||||
this.maxDamageHandTwo = (short) this.mobBase.getMaxDmg();
|
|
||||||
this.rangeHandTwo = 6.5f;
|
|
||||||
this.speedHandTwo = 20;
|
|
||||||
Logger.info("Mobbase ID " + this.getMobBaseID() + " returned an error. setting to default ATR and Damage." + e.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
float defense = this.mobBase.getDefenseRating();
|
|
||||||
defense += getShieldDefense(equip.get(MBServerStatics.SLOT_OFFHAND));
|
|
||||||
defense += getArmorDefense(equip.get(MBServerStatics.SLOT_HELMET));
|
|
||||||
defense += getArmorDefense(equip.get(MBServerStatics.SLOT_CHEST));
|
|
||||||
defense += getArmorDefense(equip.get(MBServerStatics.SLOT_ARMS));
|
|
||||||
defense += getArmorDefense(equip.get(MBServerStatics.SLOT_GLOVES));
|
|
||||||
defense += getArmorDefense(equip.get(MBServerStatics.SLOT_LEGGINGS));
|
|
||||||
defense += getArmorDefense(equip.get(MBServerStatics.SLOT_FEET));
|
|
||||||
defense += getWeaponDefense(equip);
|
|
||||||
|
|
||||||
// TODO add error log here
|
|
||||||
if (this.bonuses != null) {
|
|
||||||
defense = GetDefense((int)defense, this);
|
|
||||||
|
|
||||||
} else
|
|
||||||
Logger.error("Error: missing bonuses");
|
|
||||||
|
|
||||||
defense = (defense < 1) ? 1 : defense;
|
|
||||||
this.defenseRating = (short) (defense + 0.5f);
|
|
||||||
} catch (Exception e) {
|
|
||||||
Logger.info("Mobbase ID " + this.getMobBaseID() + " returned an error. Setting to Default Defense." + e.getMessage());
|
|
||||||
this.defenseRating = (short) this.mobBase.getDefense();
|
|
||||||
}
|
|
||||||
// calculate defense for equipment
|
|
||||||
|
|
||||||
if(this.isDropper || Mob.discDroppers.contains(this)){
|
if(this.isDropper || Mob.discDroppers.contains(this)){
|
||||||
this.defenseRating *= 2;
|
this.defenseRating *= 2;
|
||||||
this.atrHandOne *= 2;
|
this.atrHandOne *= 2;
|
||||||
@@ -1839,168 +1852,46 @@ public class Mob extends AbstractIntelligenceAgent {
|
|||||||
|
|
||||||
private void calculateAtrDamageForWeapon(MobEquipment weapon, boolean mainHand) {
|
private void calculateAtrDamageForWeapon(MobEquipment weapon, boolean mainHand) {
|
||||||
|
|
||||||
int baseStrength = 0;
|
if(mainHand){
|
||||||
|
int min = (int)this.mobBase.getDamageMin();
|
||||||
float skillPercentage, masteryPercentage;
|
int max = (int)this.mobBase.getDamageMax();
|
||||||
float mastDam;
|
int atr = this.mobBase.getAtr();
|
||||||
|
if(this.bonuses != null){
|
||||||
// make sure weapon exists
|
min *= 1 + this.bonuses.getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.None);
|
||||||
|
max *= 1 + this.bonuses.getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.None);
|
||||||
boolean noWeapon = false;
|
atr *= 1 + this.bonuses.getFloatPercentAll(ModType.OCV,SourceType.None);
|
||||||
ItemBase wb = null;
|
atr += this.bonuses.getFloat(ModType.OCV,SourceType.None);
|
||||||
|
}
|
||||||
if (weapon == null)
|
this.minDamageHandOne = min;
|
||||||
noWeapon = true;
|
this.maxDamageHandOne = max;
|
||||||
|
this.atrHandOne = atr;
|
||||||
else {
|
if(weapon == null){
|
||||||
|
|
||||||
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)
|
|
||||||
this.rangeHandOne = this.mobBase.getAttackRange();
|
this.rangeHandOne = this.mobBase.getAttackRange();
|
||||||
else
|
this.speedHandTwo = 20.0f;
|
||||||
this.rangeHandTwo = -1; // set to do not attack
|
}else{
|
||||||
|
this.rangeHandOne = weapon.getItemBase().getRange();
|
||||||
skillPercentage = getModifiedAmount(this.skills.get("Unarmed Combat"));
|
this.speedHandTwo = weapon.getItemBase().getSpeed();
|
||||||
masteryPercentage = getModifiedAmount(this.skills.get("Unarmed Combat Mastery"));
|
}
|
||||||
|
}else{
|
||||||
if (masteryPercentage == 0f)
|
int min = (int)this.mobBase.getDamageMin();
|
||||||
mastDam = CharacterSkill.getQuickMastery(this, "Unarmed Combat Mastery");
|
int max = (int)this.mobBase.getDamageMax();
|
||||||
else
|
int atr = this.mobBase.getAtr();
|
||||||
mastDam = masteryPercentage;
|
if(this.bonuses != null){
|
||||||
|
min *= 1 + this.bonuses.getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.None);
|
||||||
// TODO Correct these
|
max *= 1 + this.bonuses.getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.None);
|
||||||
min = this.mobBase.getMinDmg();
|
atr *= 1 + this.bonuses.getFloatPercentAll(ModType.OCV,SourceType.None);
|
||||||
max = this.mobBase.getMaxDmg();
|
atr += this.bonuses.getFloat(ModType.OCV,SourceType.None);
|
||||||
} else {
|
}
|
||||||
|
this.minDamageHandTwo = min;
|
||||||
if (mainHand)
|
this.maxDamageHandTwo = max;
|
||||||
this.rangeHandOne = weapon.getItemBase().getRange() * (1 + (baseStrength / 600.0f));
|
this.atrHandTwo = atr;
|
||||||
else
|
if(weapon == null){
|
||||||
this.rangeHandTwo = weapon.getItemBase().getRange() * (1 + (baseStrength / 600.0f));
|
this.rangeHandTwo = this.mobBase.getAttackRange();
|
||||||
|
this.speedHandTwo = 20.0f;
|
||||||
skillPercentage = getModifiedAmount(this.skills.get(wb.getSkillRequired()));
|
}else{
|
||||||
masteryPercentage = getModifiedAmount(this.skills.get(wb.getMastery()));
|
this.rangeHandTwo = weapon.getItemBase().getRange();
|
||||||
|
this.speedHandTwo = weapon.getItemBase().getSpeed();
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2114,6 +2005,7 @@ public class Mob extends AbstractIntelligenceAgent {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
NPCManager.applyRuneSetEffects(this);
|
NPCManager.applyRuneSetEffects(this);
|
||||||
|
MobBase.applyMobbaseEffects(this);
|
||||||
recalculateStats();
|
recalculateStats();
|
||||||
this.setHealth(this.healthMax);
|
this.setHealth(this.healthMax);
|
||||||
|
|
||||||
@@ -2165,6 +2057,7 @@ public class Mob extends AbstractIntelligenceAgent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.deathTime = 0;
|
this.deathTime = 0;
|
||||||
|
InterestManager.setObjectDirty(this);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Logger.error(e.getMessage());
|
Logger.error(e.getMessage());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,8 +13,11 @@ import ch.claude_martin.enumbitset.EnumBitSet;
|
|||||||
import engine.Enum;
|
import engine.Enum;
|
||||||
import engine.gameManager.DbManager;
|
import engine.gameManager.DbManager;
|
||||||
import engine.gameManager.LootManager;
|
import engine.gameManager.LootManager;
|
||||||
|
import engine.gameManager.PowersManager;
|
||||||
import engine.loot.BootySetEntry;
|
import engine.loot.BootySetEntry;
|
||||||
|
import engine.powers.EffectsBase;
|
||||||
import engine.server.MBServerStatics;
|
import engine.server.MBServerStatics;
|
||||||
|
import org.pmw.tinylog.Logger;
|
||||||
|
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
@@ -54,6 +57,8 @@ public class MobBase extends AbstractGameObject {
|
|||||||
private float walkCombat = 0;
|
private float walkCombat = 0;
|
||||||
private float runCombat = 0;
|
private float runCombat = 0;
|
||||||
|
|
||||||
|
public ArrayList<MobBaseEffects> mobbaseEffects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ResultSet Constructor
|
* ResultSet Constructor
|
||||||
*/
|
*/
|
||||||
@@ -108,6 +113,7 @@ public class MobBase extends AbstractGameObject {
|
|||||||
|
|
||||||
this.mobBaseStats = DbManager.MobBaseQueries.LOAD_STATS(this.loadID);
|
this.mobBaseStats = DbManager.MobBaseQueries.LOAD_STATS(this.loadID);
|
||||||
DbManager.MobBaseQueries.LOAD_ALL_MOBBASE_SPEEDS(this);
|
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() {
|
public int getAtr() {
|
||||||
return atr;
|
return attackRating;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAtr(int atr) {
|
public void setAtr(int atr) {
|
||||||
@@ -301,4 +307,19 @@ public class MobBase extends AbstractGameObject {
|
|||||||
return runCombat;
|
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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1300,7 +1300,7 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
|
|
||||||
|
|
||||||
if (ConfigManager.serverType.equals(ServerType.WORLDSERVER))
|
if (ConfigManager.serverType.equals(ServerType.WORLDSERVER))
|
||||||
player.setLoc(player.bindLoc);
|
player.setLoc(player.getBindLoc());
|
||||||
player.endLoc = Vector3fImmutable.ZERO;
|
player.endLoc = Vector3fImmutable.ZERO;
|
||||||
|
|
||||||
//get level based on experience
|
//get level based on experience
|
||||||
@@ -2925,6 +2925,9 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void grantXP(int xp) {
|
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){
|
if(this.promotionClass == null && this.level == 10){
|
||||||
this.setOverFlowEXP(0);
|
this.setOverFlowEXP(0);
|
||||||
this.update(false);
|
this.update(false);
|
||||||
@@ -3075,6 +3078,14 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
SetObjectValueMsg upm = new SetObjectValueMsg(this, 9);
|
SetObjectValueMsg upm = new SetObjectValueMsg(this, 9);
|
||||||
DispatchMessage.dispatchMsgToInterestArea(this, upm, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, false, false);
|
DispatchMessage.dispatchMsgToInterestArea(this, upm, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, false, false);
|
||||||
checkGuildStatus();
|
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 {
|
} else {
|
||||||
|
|
||||||
this.exp += remainingXP;
|
this.exp += remainingXP;
|
||||||
@@ -3122,26 +3133,8 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
public void calculateSpeedMod() {
|
public void calculateSpeedMod() {
|
||||||
// get base race speed modifer
|
// 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;
|
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
|
// get running skill
|
||||||
if (this.skills != null) {
|
if (this.skills != null) {
|
||||||
CharacterSkill running = this.skills.get("Running");
|
CharacterSkill running = this.skills.get("Running");
|
||||||
@@ -3194,14 +3187,6 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
return this.follow;
|
return this.follow;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getLastGroupToInvite() {
|
|
||||||
return this.lastGroupToInvite;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLastGroupToInvite(int value) {
|
|
||||||
this.lastGroupToInvite = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float getAltitude() {
|
public float getAltitude() {
|
||||||
if (this.altitude < 0)
|
if (this.altitude < 0)
|
||||||
@@ -3250,10 +3235,6 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
return this.loadedStaticObjects;
|
return this.loadedStaticObjects;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLoadedStaticObjects(HashSet<AbstractWorldObject> value) {
|
|
||||||
this.loadedStaticObjects = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isTeleportMode() {
|
public boolean isTeleportMode() {
|
||||||
return teleportMode;
|
return teleportMode;
|
||||||
}
|
}
|
||||||
@@ -3261,20 +3242,6 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
public void setTeleportMode(boolean teleportMode) {
|
public void setTeleportMode(boolean teleportMode) {
|
||||||
this.teleportMode = 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) {
|
public long chatFloodTime(int chatOpcode, long chatTimeMilli, int qtyToSave) {
|
||||||
if (qtyToSave < 1)
|
if (qtyToSave < 1)
|
||||||
return 0L; // disabled
|
return 0L; // disabled
|
||||||
@@ -3788,22 +3755,6 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
return this.statStrCurrent - this.race.getStrStart() - this.baseClass.getStrMod();
|
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() {
|
public int getTrainsAvailable() {
|
||||||
return this.trainsAvailable.get();
|
return this.trainsAvailable.get();
|
||||||
}
|
}
|
||||||
@@ -3841,15 +3792,6 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
}
|
}
|
||||||
ConcurrentHashMap<Integer, Item> equipped = this.charItemManager.getEquipped();
|
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
|
// calculate atr and damage for each hand
|
||||||
calculateAtrDamageForWeapon(equipped.get(MBServerStatics.SLOT_MAINHAND), true, equipped.get(MBServerStatics.SLOT_OFFHAND));
|
calculateAtrDamageForWeapon(equipped.get(MBServerStatics.SLOT_MAINHAND), true, equipped.get(MBServerStatics.SLOT_OFFHAND));
|
||||||
calculateAtrDamageForWeapon(equipped.get(MBServerStatics.SLOT_OFFHAND), false, equipped.get(MBServerStatics.SLOT_MAINHAND));
|
calculateAtrDamageForWeapon(equipped.get(MBServerStatics.SLOT_OFFHAND), false, equipped.get(MBServerStatics.SLOT_MAINHAND));
|
||||||
@@ -3902,7 +3844,7 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
|
|
||||||
// make sure weapon exists
|
// make sure weapon exists
|
||||||
boolean noWeapon = false;
|
boolean noWeapon = false;
|
||||||
ItemBase wb = null;
|
ItemBase weaponBase = null;
|
||||||
if (weapon == null)
|
if (weapon == null)
|
||||||
noWeapon = true;
|
noWeapon = true;
|
||||||
else {
|
else {
|
||||||
@@ -3913,7 +3855,7 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
defaultAtrAndDamage(mainHand);
|
defaultAtrAndDamage(mainHand);
|
||||||
return;
|
return;
|
||||||
} else
|
} else
|
||||||
wb = ib;
|
weaponBase = ib;
|
||||||
}
|
}
|
||||||
float skillPercentage, masteryPercentage;
|
float skillPercentage, masteryPercentage;
|
||||||
float mastDam;
|
float mastDam;
|
||||||
@@ -3963,28 +3905,17 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
this.rangeHandTwo *= range_bonus;
|
this.rangeHandTwo *= range_bonus;
|
||||||
|
|
||||||
}
|
}
|
||||||
skillPercentage = getModifiedAmount(this.skills.get(wb.getSkillRequired()));
|
skillPercentage = getModifiedAmount(this.skills.get(weaponBase.getSkillRequired()));
|
||||||
masteryPercentage = getModifiedAmount(this.skills.get(wb.getMastery()));
|
masteryPercentage = getModifiedAmount(this.skills.get(weaponBase.getMastery()));
|
||||||
if (masteryPercentage == 0f)
|
if (masteryPercentage == 0f)
|
||||||
mastDam = 0f;
|
mastDam = 0f;
|
||||||
// mastDam = CharacterSkill.getQuickMastery(this, wb.getMastery());
|
// mastDam = CharacterSkill.getQuickMastery(this, weaponBase.getMastery());
|
||||||
else
|
else
|
||||||
mastDam = masteryPercentage;
|
mastDam = masteryPercentage;
|
||||||
min = (float) wb.getMinDamage();
|
min = (float) weaponBase.getMinDamage();
|
||||||
max = (float) wb.getMaxDamage();
|
max = (float) weaponBase.getMaxDamage();
|
||||||
strBased = wb.isStrBased();
|
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"))
|
if (this.effects != null && this.effects.containsKey("DeathShroud"))
|
||||||
@@ -3995,13 +3926,18 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
this.atrHandTwo = (short) 0;
|
this.atrHandTwo = (short) 0;
|
||||||
else {
|
else {
|
||||||
// calculate atr
|
// calculate atr
|
||||||
|
//(Primary Stat / 2) + (Weapon Skill * 4) + (Weapon Mastery * 3) + (ATR Enchantments) * 1.stance modifier
|
||||||
float atr = 0;
|
float atr = 0;
|
||||||
atr += (int) skillPercentage * 4f; //<-round down skill% -
|
int primaryStat;
|
||||||
atr += (int) masteryPercentage * 3f;
|
int dexMod = this.getDexMod();
|
||||||
if (this.statStrCurrent > this.statDexCurrent)
|
int strMod = this.getStrMod();
|
||||||
atr += statStrCurrent / 2;
|
if(weaponBase != null && weaponBase.isStrBased()){
|
||||||
else
|
primaryStat = this.statStrCurrent;
|
||||||
atr += statDexCurrent / 2;
|
}else{
|
||||||
|
primaryStat = this.statDexCurrent;
|
||||||
|
}
|
||||||
|
|
||||||
|
atr = (primaryStat * 0.5f) + (skillPercentage * 4) + (masteryPercentage * 3);
|
||||||
|
|
||||||
// add in any bonuses to atr
|
// add in any bonuses to atr
|
||||||
if (this.bonuses != null) {
|
if (this.bonuses != null) {
|
||||||
@@ -4012,10 +3948,6 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
float pos_Bonus = (1 + this.bonuses.getFloatPercentPositive(ModType.OCV, SourceType.None));
|
float pos_Bonus = (1 + this.bonuses.getFloatPercentPositive(ModType.OCV, SourceType.None));
|
||||||
atr *= pos_Bonus;
|
atr *= pos_Bonus;
|
||||||
|
|
||||||
// next precise
|
|
||||||
//runes will have their own bonuses.
|
|
||||||
// atr *= (1 + ((float) this.bonuses.getShort("rune.Attack") / 100));
|
|
||||||
|
|
||||||
//and negative percent modifiers
|
//and negative percent modifiers
|
||||||
float neg_Bonus = this.bonuses.getFloatPercentNegative(ModType.OCV, SourceType.None);
|
float neg_Bonus = this.bonuses.getFloatPercentNegative(ModType.OCV, SourceType.None);
|
||||||
|
|
||||||
@@ -4032,8 +3964,8 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//calculate speed
|
//calculate speed
|
||||||
if (wb != null)
|
if (weaponBase != null)
|
||||||
speed = wb.getSpeed();
|
speed = weaponBase.getSpeed();
|
||||||
else
|
else
|
||||||
speed = 20f; //unarmed attack speed
|
speed = 20f; //unarmed attack speed
|
||||||
if (weapon != null)
|
if (weapon != null)
|
||||||
@@ -4468,36 +4400,6 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
return (amount - attackerLevel + this.getLevel()) / 4;
|
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) {
|
public float getRegenModifier(ModType type) {
|
||||||
float regen = 1f;
|
float regen = 1f;
|
||||||
|
|
||||||
@@ -4582,10 +4484,6 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
super.removeFromCache();
|
super.removeFromCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void storeIgnoreListDB() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updateSkillsAndPowersToDatabase() {
|
public void updateSkillsAndPowersToDatabase() {
|
||||||
if (this.skills != null)
|
if (this.skills != null)
|
||||||
for (CharacterSkill skill : this.skills.values()) {
|
for (CharacterSkill skill : this.skills.values()) {
|
||||||
@@ -4640,7 +4538,7 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
|
|
||||||
tmpLevel = targetLevel;
|
tmpLevel = targetLevel;
|
||||||
|
|
||||||
tmpLevel = (short) Math.min(tmpLevel, 75);
|
tmpLevel = (short) Math.min(tmpLevel, MBServerStatics.LEVELCAP);
|
||||||
|
|
||||||
while (this.level < tmpLevel) {
|
while (this.level < tmpLevel) {
|
||||||
grantXP(Experience.getBaseExperience(tmpLevel) - this.exp);
|
grantXP(Experience.getBaseExperience(tmpLevel) - this.exp);
|
||||||
@@ -4754,17 +4652,6 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
return true;
|
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() {
|
private double getDeltaTime() {
|
||||||
|
|
||||||
return (System.currentTimeMillis() - lastUpdateTime) * .001f;
|
return (System.currentTimeMillis() - lastUpdateTime) * .001f;
|
||||||
@@ -4806,30 +4693,6 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
return false;
|
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 {
|
private static void forceRespawn(PlayerCharacter sourcePlayer) throws MsgSendException {
|
||||||
|
|
||||||
if (sourcePlayer == null)
|
if (sourcePlayer == null)
|
||||||
@@ -4845,8 +4708,8 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
@Override
|
@Override
|
||||||
public void update(Boolean newSystem) {
|
public void update(Boolean newSystem) {
|
||||||
|
|
||||||
if(!newSystem)
|
//if(!newSystem)
|
||||||
return;
|
// return;
|
||||||
|
|
||||||
if (this.updateLock.writeLock().tryLock()) {
|
if (this.updateLock.writeLock().tryLock()) {
|
||||||
try {
|
try {
|
||||||
@@ -4858,19 +4721,19 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
forceRespawn(this);
|
forceRespawn(this);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
updateLocation();
|
this.updateLocation();
|
||||||
updateMovementState();
|
this.updateMovementState();
|
||||||
updateRegen();
|
this.updateRegen();
|
||||||
|
|
||||||
if (this.getStamina() < 10) {
|
if (this.getStamina() < 10) {
|
||||||
if (this.getAltitude() > 0 || this.getDesiredAltitude() > 0) {
|
if (this.getAltitude() > 0 || this.getDesiredAltitude() > 0) {
|
||||||
PlayerCharacter.GroundPlayer(this);
|
PlayerCharacter.GroundPlayer(this);
|
||||||
updateRegen();
|
this.updateRegen();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RealmMap.updateRealm(this);
|
RealmMap.updateRealm(this);
|
||||||
updateBlessingMessage();
|
this.updateBlessingMessage();
|
||||||
|
|
||||||
this.safeZone = this.isInSafeZone();
|
this.safeZone = this.isInSafeZone();
|
||||||
if(!this.timestamps.containsKey("nextBoxCheck"))
|
if(!this.timestamps.containsKey("nextBoxCheck"))
|
||||||
@@ -4886,11 +4749,6 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
while (this.level < 10) {
|
while (this.level < 10) {
|
||||||
grantXP(Experience.getBaseExperience(this.level + 1) - this.exp);
|
grantXP(Experience.getBaseExperience(this.level + 1) - this.exp);
|
||||||
}
|
}
|
||||||
if(this.charItemManager != null && this.charItemManager.getGoldInventory() != null && this.charItemManager.getGoldInventory().getNumOfItems() < 1000) {
|
|
||||||
this.getCharItemManager().addGoldToInventory(1000, false);
|
|
||||||
this.getCharItemManager().addItemToInventory(new MobLoot(this, ItemBase.getItemBase(980066), 1, false).promoteToItem(this));
|
|
||||||
this.getCharItemManager().updateInventory();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(this.isBoxed && !this.containsEffect(1672601862)) {
|
if(this.isBoxed && !this.containsEffect(1672601862)) {
|
||||||
@@ -4903,6 +4761,22 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
GroundPlayer(this);
|
GroundPlayer(this);
|
||||||
//ChatManager.chatSystemInfo(this, "You Cannot Fly While Having A MovementBuff");
|
//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) {
|
} catch (Exception e) {
|
||||||
@@ -5037,7 +4911,6 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
ChatManager.chatSystemInfo(this,
|
ChatManager.chatSystemInfo(this,
|
||||||
"Arrived at End location. " + this.getEndLoc());
|
"Arrived at End location. " + this.getEndLoc());
|
||||||
return;
|
return;
|
||||||
//Next upda
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setLoc(newLoc);
|
setLoc(newLoc);
|
||||||
@@ -5049,11 +4922,6 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
|
|
||||||
if (this.getStamina() < 10)
|
if (this.getStamina() < 10)
|
||||||
MovementManager.sendOOS(this);
|
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
|
@Override
|
||||||
@@ -5119,6 +4987,9 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
@Override
|
@Override
|
||||||
public void updateRegen() {
|
public void updateRegen() {
|
||||||
|
|
||||||
|
if(true)
|
||||||
|
return;
|
||||||
|
|
||||||
float healthRegen = 0f;
|
float healthRegen = 0f;
|
||||||
float manaRegen = 0f;
|
float manaRegen = 0f;
|
||||||
float stamRegen = 0f;
|
float stamRegen = 0f;
|
||||||
@@ -5143,7 +5014,7 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
if (this.walkMode)
|
if (this.walkMode)
|
||||||
manaRegen = ((this.manaMax * MBServerStatics.MANA_REGEN_IDLE) * getRegenModifier(ModType.ManaRecoverRate));
|
manaRegen = ((this.manaMax * MBServerStatics.MANA_REGEN_IDLE) * getRegenModifier(ModType.ManaRecoverRate));
|
||||||
else if (!this.isCasting() && !this.isItemCasting())
|
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
|
else
|
||||||
manaRegen = 0;
|
manaRegen = 0;
|
||||||
|
|
||||||
@@ -5427,23 +5298,11 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
return movementState;
|
return movementState;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isHasAnniversery() {
|
|
||||||
return hasAnniversery;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setHasAnniversery(boolean hasAnniversery) {
|
public void setHasAnniversery(boolean hasAnniversery) {
|
||||||
DbManager.PlayerCharacterQueries.SET_ANNIVERSERY(this, hasAnniversery);
|
DbManager.PlayerCharacterQueries.SET_ANNIVERSERY(this, hasAnniversery);
|
||||||
this.hasAnniversery = hasAnniversery;
|
this.hasAnniversery = hasAnniversery;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getSpamCount() {
|
|
||||||
return spamCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSpamCount(int spamCount) {
|
|
||||||
this.spamCount = spamCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getHash() {
|
public String getHash() {
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
@@ -5469,10 +5328,6 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
this.lastRealmID = lastRealmID;
|
this.lastRealmID = lastRealmID;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getSubRaceID() {
|
|
||||||
return subRaceID;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSubRaceID(int subRaceID) {
|
public void setSubRaceID(int subRaceID) {
|
||||||
this.subRaceID = subRaceID;
|
this.subRaceID = subRaceID;
|
||||||
}
|
}
|
||||||
@@ -5485,29 +5340,6 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
this.guildHistory = guildHistory;
|
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() {
|
public void updateScaleHeight() {
|
||||||
|
|
||||||
float strengthScale = 0;
|
float strengthScale = 0;
|
||||||
@@ -5544,10 +5376,6 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
this.overFlowEXP = overFlowEXP;
|
this.overFlowEXP = overFlowEXP;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MovementState getLastMovementState() {
|
|
||||||
return lastMovementState;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLastMovementState(MovementState lastMovementState) {
|
public void setLastMovementState(MovementState lastMovementState) {
|
||||||
this.lastMovementState = lastMovementState;
|
this.lastMovementState = lastMovementState;
|
||||||
}
|
}
|
||||||
@@ -5569,20 +5397,16 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
public void resetRegenUpdateTime() {
|
public void resetRegenUpdateTime() {
|
||||||
this.lastUpdateTime = System.currentTimeMillis();
|
this.lastUpdateTime = System.currentTimeMillis();
|
||||||
this.lastStamUpdateTime = 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() {
|
public float getCharacterHeight() {
|
||||||
return characterHeight;
|
return characterHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCharacterHeight(float characterHeight) {
|
|
||||||
this.characterHeight = characterHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCenterHeight(float centerHeight) {
|
|
||||||
this.centerHeight = centerHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isEnteredWorld() {
|
public boolean isEnteredWorld() {
|
||||||
return enteredWorld;
|
return enteredWorld;
|
||||||
}
|
}
|
||||||
@@ -5591,26 +5415,10 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
this.enteredWorld = enteredWorld;
|
this.enteredWorld = enteredWorld;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getChannelMute() {
|
|
||||||
return channelMute;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setChannelMute(long channelMute) {
|
|
||||||
this.channelMute = channelMute;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isLastSwimming() {
|
public boolean isLastSwimming() {
|
||||||
return lastSwimming;
|
return lastSwimming;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isTeleporting() {
|
|
||||||
return isTeleporting;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTeleporting(boolean isTeleporting) {
|
|
||||||
this.isTeleporting = isTeleporting;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void teleport(final Vector3fImmutable targetLoc) {
|
public final void teleport(final Vector3fImmutable targetLoc) {
|
||||||
|
|
||||||
@@ -5659,4 +5467,212 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
this.dirtyLoad = dirtyLoad;
|
this.dirtyLoad = dirtyLoad;
|
||||||
dirtyLock.writeLock().unlock();
|
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;
|
package engine.objects;
|
||||||
|
|
||||||
import engine.Enum;
|
import engine.Enum;
|
||||||
|
import engine.InterestManagement.InterestManager;
|
||||||
import engine.InterestManagement.RealmMap;
|
import engine.InterestManagement.RealmMap;
|
||||||
|
import engine.InterestManagement.WorldGrid;
|
||||||
import engine.db.archive.DataWarehouse;
|
import engine.db.archive.DataWarehouse;
|
||||||
import engine.db.archive.RealmRecord;
|
import engine.db.archive.RealmRecord;
|
||||||
|
import engine.gameManager.BuildingManager;
|
||||||
import engine.gameManager.DbManager;
|
import engine.gameManager.DbManager;
|
||||||
|
import engine.gameManager.NPCManager;
|
||||||
import engine.gameManager.PowersManager;
|
import engine.gameManager.PowersManager;
|
||||||
import engine.net.ByteBufferWriter;
|
import engine.net.ByteBufferWriter;
|
||||||
import engine.powers.PowersBase;
|
import engine.powers.PowersBase;
|
||||||
@@ -379,6 +383,16 @@ public class Realm {
|
|||||||
|
|
||||||
public void abandonRealm() {
|
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
|
// Push event to warehouse
|
||||||
|
|
||||||
RealmRecord realmRecord = RealmRecord.borrow(this, Enum.RecordEventType.LOST);
|
RealmRecord realmRecord = RealmRecord.borrow(this, Enum.RecordEventType.LOST);
|
||||||
@@ -406,6 +420,17 @@ public class Realm {
|
|||||||
this.configure();
|
this.configure();
|
||||||
this.updateDatabase();
|
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
|
// Push event to warehouse
|
||||||
|
|
||||||
RealmRecord realmRecord = RealmRecord.borrow(this, Enum.RecordEventType.CAPTURE);
|
RealmRecord realmRecord = RealmRecord.borrow(this, Enum.RecordEventType.CAPTURE);
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ package engine.powers;
|
|||||||
|
|
||||||
import engine.Enum.PowerCategoryType;
|
import engine.Enum.PowerCategoryType;
|
||||||
import engine.Enum.PowerTargetType;
|
import engine.Enum.PowerTargetType;
|
||||||
|
import engine.gameManager.PowersManager;
|
||||||
import org.pmw.tinylog.Logger;
|
import org.pmw.tinylog.Logger;
|
||||||
|
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
@@ -109,6 +110,8 @@ public class PowersBase {
|
|||||||
public PowerCategoryType powerCategory;
|
public PowerCategoryType powerCategory;
|
||||||
public String description;
|
public String description;
|
||||||
|
|
||||||
|
public boolean breaksForm = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* No Table ID Constructor
|
* No Table ID Constructor
|
||||||
*/
|
*/
|
||||||
@@ -325,6 +328,8 @@ public class PowersBase {
|
|||||||
ct = rs.getString("monsterTypeRestrict3").trim();
|
ct = rs.getString("monsterTypeRestrict3").trim();
|
||||||
if (!ct.isEmpty())
|
if (!ct.isEmpty())
|
||||||
this.monsterTypeRestrictions.add(ct);
|
this.monsterTypeRestrictions.add(ct);
|
||||||
|
|
||||||
|
this.breaksForm = PowersManager.breakForm(this.token);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ public class ApplyEffectPowerAction extends AbstractPowerAction {
|
|||||||
((Mob) awo).setCombatTarget(source);
|
((Mob) awo).setCombatTarget(source);
|
||||||
ChatSystemMsg msg = ChatManager.CombatInfo(source, awo);
|
ChatSystemMsg msg = ChatManager.CombatInfo(source, awo);
|
||||||
DispatchMessage.sendToAllInRange(source, msg);
|
DispatchMessage.sendToAllInRange(source, msg);
|
||||||
((Mob)awo).refresh();
|
//((Mob)awo).refresh();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (awo != null && awo.getObjectType() == GameObjectType.Mob) {
|
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%
|
public static final float HEALTH_REGEN_SWIM_NOSTAMINA_STATIC = 0f; // 100%
|
||||||
// weapon
|
// weapon
|
||||||
public static final float MANA_REGEN_STATIC = 0.16666666666666666666666666666667f;
|
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_SIT = 0.8333333f; // 1% every 1.2 seconds
|
||||||
public static final float MANA_REGEN_IDLE = 0.00166667f; // 100% in 10
|
public static final float MANA_REGEN_IDLE = 0.1666667f; // 1% every 6 seconds
|
||||||
public static final float MANA_REGEN_WALK = 0.00125f; // 100% in 13.333
|
public static final float MANA_REGEN_WALK = 0.125f; // 1% every 8 seconds
|
||||||
public static final float MANA_REGEN_RUN = 0f;
|
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_SIT = 2f; // 2 per second
|
||||||
public static final float STAMINA_REGEN_IDLE = 0.2f; // 1 per 5 seconds
|
public static final float STAMINA_REGEN_IDLE = 0.2f; // 1 per 5 seconds
|
||||||
public static final float STAMINA_REGEN_WALK = 0f;
|
public static final float STAMINA_REGEN_WALK = 0f;
|
||||||
|
|||||||
@@ -450,7 +450,7 @@ public class LoginServer {
|
|||||||
objectUUID = rs.getInt("UID");
|
objectUUID = rs.getInt("UID");
|
||||||
objectType = rs.getString("type");
|
objectType = rs.getString("type");
|
||||||
|
|
||||||
Logger.info("INVALIDATED : " + objectType + " UUID: " + objectUUID);
|
//Logger.info("INVALIDATED : " + objectType + " UUID: " + objectUUID);
|
||||||
|
|
||||||
switch (objectType) {
|
switch (objectType) {
|
||||||
|
|
||||||
@@ -462,7 +462,7 @@ public class LoginServer {
|
|||||||
PlayerCharacter player = (PlayerCharacter) DbManager.getObject(Enum.GameObjectType.PlayerCharacter, objectUUID);
|
PlayerCharacter player = (PlayerCharacter) DbManager.getObject(Enum.GameObjectType.PlayerCharacter, objectUUID);
|
||||||
PlayerCharacter.initializePlayer(player);
|
PlayerCharacter.initializePlayer(player);
|
||||||
player.getAccount().characterMap.replace(player.getObjectUUID(), 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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -517,7 +517,7 @@ public class WorldServer {
|
|||||||
Logger.info("Starting Bane Thread");
|
Logger.info("Starting Bane Thread");
|
||||||
BaneThread.startBaneThread();
|
BaneThread.startBaneThread();
|
||||||
|
|
||||||
Logger.info("Starting Player Update Thread");
|
Logger.info("Starting Player Regen Thread");
|
||||||
UpdateThread.startUpdateThread();
|
UpdateThread.startUpdateThread();
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ import java.util.ArrayList;
|
|||||||
|
|
||||||
public class BaneThread implements Runnable {
|
public class BaneThread implements Runnable {
|
||||||
|
|
||||||
public Long lastRun;
|
private volatile Long lastRun;
|
||||||
public static int instancedelay = 10000;
|
public static final Long instancedelay = 1000L;
|
||||||
public BaneThread() {
|
public BaneThread() {
|
||||||
Logger.info(" BaneThread thread has started!");
|
Logger.info(" BaneThread thread has started!");
|
||||||
}
|
}
|
||||||
@@ -37,14 +37,16 @@ public class BaneThread implements Runnable {
|
|||||||
public void processBanesWindow() {
|
public void processBanesWindow() {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
for(int baneId : Bane.banes.keySet()){
|
synchronized (Bane.banes) {
|
||||||
Bane bane = Bane.banes.get(baneId);
|
for (int baneId : Bane.banes.keySet()) {
|
||||||
if(bane.getSiegePhase().equals(Enum.SiegePhase.WAR)){
|
Bane bane = Bane.banes.get(baneId);
|
||||||
bane.applyZergBuffs();
|
if (bane != null && bane.getSiegePhase().equals(Enum.SiegePhase.WAR)) {
|
||||||
|
bane.applyZergBuffs();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Logger.error("BANE ERROR");
|
Logger.error("BANE ERROR",e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -56,6 +58,13 @@ public class BaneThread implements Runnable {
|
|||||||
if (System.currentTimeMillis() >= lastRun + instancedelay) { // Correct condition
|
if (System.currentTimeMillis() >= lastRun + instancedelay) { // Correct condition
|
||||||
this.processBanesWindow();
|
this.processBanesWindow();
|
||||||
lastRun = System.currentTimeMillis(); // Update lastRun after processing
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -88,5 +88,11 @@ public class HourlyJobThread implements Runnable {
|
|||||||
Logger.info(SimulationManager.getPopulationString());
|
Logger.info(SimulationManager.getPopulationString());
|
||||||
Logger.info(MessageDispatcher.getNetstatString());
|
Logger.info(MessageDispatcher.getNetstatString());
|
||||||
Logger.info(PurgeOprhans.recordsDeleted.toString() + "orphaned items deleted");
|
Logger.info(PurgeOprhans.recordsDeleted.toString() + "orphaned items deleted");
|
||||||
|
|
||||||
|
for (Bane bane : Bane.banes.values()){
|
||||||
|
if(bane.getSiegePhase().equals(Enum.SiegePhase.CHALLENGE)){
|
||||||
|
bane.setDefaultTime();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,8 +18,9 @@ import org.pmw.tinylog.Logger;
|
|||||||
|
|
||||||
public class UpdateThread implements Runnable {
|
public class UpdateThread implements Runnable {
|
||||||
|
|
||||||
public Long lastRun;
|
private volatile Long lastRun;
|
||||||
public static int instancedelay = 1000;
|
|
||||||
|
public static final Long instancedelay = 1000L;
|
||||||
public UpdateThread() {
|
public UpdateThread() {
|
||||||
Logger.info(" UpdateThread thread has started!");
|
Logger.info(" UpdateThread thread has started!");
|
||||||
}
|
}
|
||||||
@@ -29,10 +30,12 @@ public class UpdateThread implements Runnable {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
for(PlayerCharacter player : SessionManager.getAllActivePlayerCharacters()){
|
for(PlayerCharacter player : SessionManager.getAllActivePlayerCharacters()){
|
||||||
player.update(true);
|
if (player != null) {
|
||||||
|
player.doRegen();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Logger.error("UPDATE ERROR");
|
Logger.error("UPDATE ERROR",e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -44,6 +47,13 @@ public class UpdateThread implements Runnable {
|
|||||||
if (System.currentTimeMillis() >= lastRun + instancedelay) { // Correct condition
|
if (System.currentTimeMillis() >= lastRun + instancedelay) { // Correct condition
|
||||||
this.processPlayerUpdate();
|
this.processPlayerUpdate();
|
||||||
lastRun = System.currentTimeMillis(); // Update lastRun after processing
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user