ABS char skill system
This commit is contained in:
@@ -11,10 +11,7 @@ package engine.db.handlers;
|
|||||||
|
|
||||||
import engine.Enum;
|
import engine.Enum;
|
||||||
import engine.gameManager.DbManager;
|
import engine.gameManager.DbManager;
|
||||||
import engine.objects.AbstractWorldObject;
|
import engine.objects.*;
|
||||||
import engine.objects.Heraldry;
|
|
||||||
import engine.objects.PlayerCharacter;
|
|
||||||
import engine.objects.PlayerFriends;
|
|
||||||
import engine.server.MBServerStatics;
|
import engine.server.MBServerStatics;
|
||||||
import org.pmw.tinylog.Logger;
|
import org.pmw.tinylog.Logger;
|
||||||
|
|
||||||
@@ -45,8 +42,8 @@ public class dbPlayerCharacterHandler extends dbHandlerBase {
|
|||||||
preparedStatement.setLong(1, toAdd.getAccount().getObjectUUID());
|
preparedStatement.setLong(1, toAdd.getAccount().getObjectUUID());
|
||||||
preparedStatement.setString(2, toAdd.getFirstName());
|
preparedStatement.setString(2, toAdd.getFirstName());
|
||||||
preparedStatement.setString(3, toAdd.getLastName());
|
preparedStatement.setString(3, toAdd.getLastName());
|
||||||
preparedStatement.setInt(4, toAdd.getRace().getRaceRuneID());
|
preparedStatement.setInt(4, toAdd.race.getRaceRuneID());
|
||||||
preparedStatement.setInt(5, toAdd.getBaseClass().getObjectUUID());
|
preparedStatement.setInt(5, toAdd.baseClass.getObjectUUID());
|
||||||
preparedStatement.setInt(6, toAdd.getStrMod());
|
preparedStatement.setInt(6, toAdd.getStrMod());
|
||||||
preparedStatement.setInt(7, toAdd.getDexMod());
|
preparedStatement.setInt(7, toAdd.getDexMod());
|
||||||
preparedStatement.setInt(8, toAdd.getConMod());
|
preparedStatement.setInt(8, toAdd.getConMod());
|
||||||
|
|||||||
@@ -253,9 +253,9 @@ public class InfoCmd extends AbstractDevCmd {
|
|||||||
output += newline;
|
output += newline;
|
||||||
output += "InSession : " + SessionManager.getPlayerCharacterByID(target.getObjectUUID()) != null ? " true " : " false";
|
output += "InSession : " + SessionManager.getPlayerCharacterByID(target.getObjectUUID()) != null ? " true " : " false";
|
||||||
output += newline;
|
output += newline;
|
||||||
output += "RaceType: " + targetPC.getRace().getRaceType().name();
|
output += "RaceType: " + targetPC.race.getRaceType().name();
|
||||||
output += newline;
|
output += newline;
|
||||||
output += "Race: " + targetPC.getRace().getName();
|
output += "Race: " + targetPC.race.getName();
|
||||||
output += newline;
|
output += newline;
|
||||||
output += "Safe:" + targetPC.inSafeZone();
|
output += "Safe:" + targetPC.inSafeZone();
|
||||||
output += newline;
|
output += newline;
|
||||||
@@ -291,7 +291,7 @@ public class InfoCmd extends AbstractDevCmd {
|
|||||||
output += "inFloor :" + targetPC.getInFloorID();
|
output += "inFloor :" + targetPC.getInFloorID();
|
||||||
output += newline;
|
output += newline;
|
||||||
|
|
||||||
BaseClass baseClass = targetPC.getBaseClass();
|
BaseClass baseClass = targetPC.baseClass;
|
||||||
|
|
||||||
if (baseClass != null)
|
if (baseClass != null)
|
||||||
output += StringUtils.addWS("Class: " + baseClass.getName(), 20);
|
output += StringUtils.addWS("Class: " + baseClass.getName(), 20);
|
||||||
|
|||||||
@@ -412,7 +412,7 @@ public enum ChatManager {
|
|||||||
chatGuildMsg.setUnknown04(sender.getGuild() != null ? sender.getGuild()
|
chatGuildMsg.setUnknown04(sender.getGuild() != null ? sender.getGuild()
|
||||||
.getCharter() : 0); // Charter?
|
.getCharter() : 0); // Charter?
|
||||||
chatGuildMsg.setUnknown05(GuildStatusController.getTitle(sender.getGuildStatus())); // Title?
|
chatGuildMsg.setUnknown05(GuildStatusController.getTitle(sender.getGuildStatus())); // Title?
|
||||||
chatGuildMsg.setUnknown06(sender.getRace().getRaceType().getCharacterSex().equals(Enum.CharacterSex.MALE) ? 1 : 2); // isMale?, seen 1 and 2
|
chatGuildMsg.setUnknown06(sender.race.getRaceType().getCharacterSex().equals(Enum.CharacterSex.MALE) ? 1 : 2); // isMale?, seen 1 and 2
|
||||||
|
|
||||||
// Send dispatch to each player
|
// Send dispatch to each player
|
||||||
|
|
||||||
|
|||||||
@@ -1188,8 +1188,8 @@ public enum PowersManager {
|
|||||||
PlayerCharacter pc = (PlayerCharacter) target;
|
PlayerCharacter pc = (PlayerCharacter) target;
|
||||||
int raceID = 0;
|
int raceID = 0;
|
||||||
|
|
||||||
if (pc.getRace() != null)
|
if (pc.race != null)
|
||||||
raceID = pc.getRace().getRaceRuneID();
|
raceID = pc.race.getRaceRuneID();
|
||||||
|
|
||||||
switch (mtp) {
|
switch (mtp) {
|
||||||
case "Shade":
|
case "Shade":
|
||||||
@@ -1334,7 +1334,7 @@ public enum PowersManager {
|
|||||||
timers.get("Summon").cancelJob();
|
timers.get("Summon").cancelJob();
|
||||||
|
|
||||||
// get time to wait before summons goes through
|
// get time to wait before summons goes through
|
||||||
BaseClass base = source.getBaseClass();
|
BaseClass base = source.baseClass;
|
||||||
PromotionClass promo = source.getPromotionClass();
|
PromotionClass promo = source.getPromotionClass();
|
||||||
int duration;
|
int duration;
|
||||||
|
|
||||||
|
|||||||
@@ -609,12 +609,12 @@ public class MobAI {
|
|||||||
|
|
||||||
// No aggro for this race type
|
// No aggro for this race type
|
||||||
|
|
||||||
if (aiAgent.notEnemy.size() > 0 && aiAgent.notEnemy.contains(loadedPlayer.getRace().getRaceType().getMonsterType()) == true)
|
if (aiAgent.notEnemy.size() > 0 && aiAgent.notEnemy.contains(loadedPlayer.race.getRaceType().getMonsterType()) == true)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
//mob has enemies and this player race is not it
|
//mob has enemies and this player race is not it
|
||||||
|
|
||||||
if (aiAgent.enemy.size() > 0 && aiAgent.enemy.contains(loadedPlayer.getRace().getRaceType().getMonsterType()) == false)
|
if (aiAgent.enemy.size() > 0 && aiAgent.enemy.contains(loadedPlayer.race.getRaceType().getMonsterType()) == false)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (MovementUtilities.inRangeToAggro(aiAgent, loadedPlayer)) {
|
if (MovementUtilities.inRangeToAggro(aiAgent, loadedPlayer)) {
|
||||||
|
|||||||
@@ -12,10 +12,7 @@ import engine.net.client.msg.ArcLoginNotifyMsg;
|
|||||||
import engine.net.client.msg.ClientNetMsg;
|
import engine.net.client.msg.ClientNetMsg;
|
||||||
import engine.net.client.msg.HotzoneChangeMsg;
|
import engine.net.client.msg.HotzoneChangeMsg;
|
||||||
import engine.net.client.msg.PetMsg;
|
import engine.net.client.msg.PetMsg;
|
||||||
import engine.objects.Account;
|
import engine.objects.*;
|
||||||
import engine.objects.Guild;
|
|
||||||
import engine.objects.PlayerCharacter;
|
|
||||||
import engine.objects.PlayerFriends;
|
|
||||||
import engine.server.MBServerStatics;
|
import engine.server.MBServerStatics;
|
||||||
import engine.session.Session;
|
import engine.session.Session;
|
||||||
import org.pmw.tinylog.Logger;
|
import org.pmw.tinylog.Logger;
|
||||||
@@ -73,7 +70,7 @@ public class ArcLoginNotifyMsgHandler extends AbstractClientMsgHandler {
|
|||||||
ChatManager.sendSystemMessage(player, ConfigManager.currentRepoBranch);
|
ChatManager.sendSystemMessage(player, ConfigManager.currentRepoBranch);
|
||||||
|
|
||||||
// Set player mask for QT
|
// Set player mask for QT
|
||||||
if (player.getRace() != null && player.getRace().getToken() == -524731385)
|
if (player.race != null && player.race.getToken() == -524731385)
|
||||||
player.setObjectTypeMask(MBServerStatics.MASK_PLAYER | MBServerStatics.MASK_UNDEAD);
|
player.setObjectTypeMask(MBServerStatics.MASK_PLAYER | MBServerStatics.MASK_UNDEAD);
|
||||||
else
|
else
|
||||||
player.setObjectTypeMask(MBServerStatics.MASK_PLAYER);
|
player.setObjectTypeMask(MBServerStatics.MASK_PLAYER);
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ public class ChangeRankHandler extends AbstractClientMsgHandler {
|
|||||||
targetPlayer.setGuildTitle(msg.getNewRank());
|
targetPlayer.setGuildTitle(msg.getNewRank());
|
||||||
|
|
||||||
targetName = targetPlayer.getFirstName();
|
targetName = targetPlayer.getFirstName();
|
||||||
isMale = targetPlayer.getRace().getRaceType().getCharacterSex().equals(Enum.CharacterSex.MALE);
|
isMale = targetPlayer.race.getRaceType().getCharacterSex().equals(Enum.CharacterSex.MALE);
|
||||||
} else {
|
} else {
|
||||||
DbManager.GuildQueries.UPDATE_GUILD_RANK_OFFLINE(msg.getPlayerUUID(), msg.getNewRank(), sourcePlayer.getGuild().getObjectUUID());
|
DbManager.GuildQueries.UPDATE_GUILD_RANK_OFFLINE(msg.getPlayerUUID(), msg.getNewRank(), sourcePlayer.getGuild().getObjectUUID());
|
||||||
|
|
||||||
|
|||||||
@@ -376,14 +376,14 @@ public class VendorDialogMsgHandler extends AbstractClientMsgHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// verify race valid for profession
|
// verify race valid for profession
|
||||||
Race race = pc.getRace();
|
Race race = pc.race;
|
||||||
if (race == null || !promo.isAllowedRune(race.getToken())) {
|
if (race == null || !promo.isAllowedRune(race.getToken())) {
|
||||||
// TODO send client promotion error
|
// TODO send client promotion error
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// verify baseclass valid for profession
|
// verify baseclass valid for profession
|
||||||
BaseClass bc = pc.getBaseClass();
|
BaseClass bc = pc.baseClass;
|
||||||
if (bc == null || !promo.isAllowedRune(bc.getToken())) {
|
if (bc == null || !promo.isAllowedRune(bc.getToken())) {
|
||||||
// TODO send client promotion error
|
// TODO send client promotion error
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -14,10 +14,7 @@ import engine.gameManager.SessionManager;
|
|||||||
import engine.net.*;
|
import engine.net.*;
|
||||||
import engine.net.client.ClientConnection;
|
import engine.net.client.ClientConnection;
|
||||||
import engine.net.client.Protocol;
|
import engine.net.client.Protocol;
|
||||||
import engine.objects.Guild;
|
import engine.objects.*;
|
||||||
import engine.objects.GuildStatusController;
|
|
||||||
import engine.objects.PlayerCharacter;
|
|
||||||
import engine.objects.PromotionClass;
|
|
||||||
import engine.server.MBServerStatics;
|
import engine.server.MBServerStatics;
|
||||||
import org.pmw.tinylog.Logger;
|
import org.pmw.tinylog.Logger;
|
||||||
|
|
||||||
@@ -91,7 +88,7 @@ public class WhoResponseMsg extends ClientNetMsg {
|
|||||||
if (player != null)
|
if (player != null)
|
||||||
if (!isAdmin(player))
|
if (!isAdmin(player))
|
||||||
if (player.isActive()) {
|
if (player.isActive()) {
|
||||||
String[] race = player.getRace().getName().split(",");
|
String[] race = player.race.getName().split(",");
|
||||||
if (filter.compareTo(race[0]) == 0)
|
if (filter.compareTo(race[0]) == 0)
|
||||||
if (!HandleSet(set, player, playerCharacter, msg))
|
if (!HandleSet(set, player, playerCharacter, msg))
|
||||||
break;
|
break;
|
||||||
@@ -101,7 +98,7 @@ public class WhoResponseMsg extends ClientNetMsg {
|
|||||||
if (player != null)
|
if (player != null)
|
||||||
if (!isAdmin(player))
|
if (!isAdmin(player))
|
||||||
if (player.isActive()) {
|
if (player.isActive()) {
|
||||||
if (filter.compareTo(player.getBaseClass().getName()) == 0 || (player.getPromotionClass() != null && filter.compareTo(player.getPromotionClass().getName()) == 0))
|
if (filter.compareTo(player.baseClass.getName()) == 0 || (player.getPromotionClass() != null && filter.compareTo(player.getPromotionClass().getName()) == 0))
|
||||||
if (!HandleSet(set, player, playerCharacter, msg))
|
if (!HandleSet(set, player, playerCharacter, msg))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
@@ -136,6 +136,16 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
|
|||||||
public Enum.SexType absGender = null;
|
public Enum.SexType absGender = null;
|
||||||
public EnumSet<DisciplineType> absDisciplines;
|
public EnumSet<DisciplineType> absDisciplines;
|
||||||
|
|
||||||
|
// Modifiers
|
||||||
|
public short statStrBase;
|
||||||
|
public short statDexBase;
|
||||||
|
public short statConBase;
|
||||||
|
public short statIntBase;
|
||||||
|
public short statSpiBase;
|
||||||
|
public Race race;
|
||||||
|
public BaseClass baseClass;
|
||||||
|
public PromotionClass promotionClass;
|
||||||
|
|
||||||
public AbstractCharacter() {
|
public AbstractCharacter() {
|
||||||
super();
|
super();
|
||||||
this.firstName = "";
|
this.firstName = "";
|
||||||
@@ -468,7 +478,7 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
|
|||||||
//do this after all bonus updates, but before recalculations.
|
//do this after all bonus updates, but before recalculations.
|
||||||
// recalculate everything
|
// recalculate everything
|
||||||
//calculate item bonuses
|
//calculate item bonuses
|
||||||
playerCharacter.calculateItemBonuses();
|
calculateItemBonuses(playerCharacter);
|
||||||
|
|
||||||
//recalculate formulas
|
//recalculate formulas
|
||||||
PlayerCharacter.recalculatePlayerStatsOnLoad(playerCharacter);
|
PlayerCharacter.recalculatePlayerStatsOnLoad(playerCharacter);
|
||||||
@@ -587,6 +597,470 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ Calculates Atr (both hands) Defense, and Damage for pc
|
||||||
|
* @param playerCharacter
|
||||||
|
*/
|
||||||
|
public static void calculateAtrDefenseDamage(AbstractCharacter playerCharacter) {
|
||||||
|
if (playerCharacter.charItemManager == null || playerCharacter.charItemManager.getEquipped() == null || playerCharacter.skills == null) {
|
||||||
|
Logger.error("Player " + playerCharacter.getObjectUUID() + " missing skills or equipment");
|
||||||
|
defaultAtrAndDamage(playerCharacter,true);
|
||||||
|
defaultAtrAndDamage(playerCharacter,false);
|
||||||
|
playerCharacter.defenseRating = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ConcurrentHashMap<EquipSlotType, Item> equipped = playerCharacter.charItemManager.getEquipped();
|
||||||
|
|
||||||
|
// // Reset passives
|
||||||
|
// if (this.bonuses != null) {
|
||||||
|
// this.bonuses.setBool("Block", false);
|
||||||
|
// this.bonuses.setBool("Parry", false);
|
||||||
|
// if (this.baseClass != null && this.baseClass.getUUID() == 2502)
|
||||||
|
// this.bonuses.setBool("Dodge", true);
|
||||||
|
// else
|
||||||
|
// this.bonuses.setBool("Dodge", false);
|
||||||
|
// }
|
||||||
|
// calculate atr and damage for each hand
|
||||||
|
calculateAtrDamageForWeapon(playerCharacter,equipped.get(EquipSlotType.RHELD), true, equipped.get(EquipSlotType.RHELD));
|
||||||
|
calculateAtrDamageForWeapon(playerCharacter,equipped.get(EquipSlotType.LHELD), false, equipped.get(EquipSlotType.LHELD));
|
||||||
|
|
||||||
|
// No Defense while in DeathShroud
|
||||||
|
if (playerCharacter.effects != null && playerCharacter.effects.containsKey("DeathShroud"))
|
||||||
|
playerCharacter.defenseRating = (short) 0;
|
||||||
|
else {
|
||||||
|
// calculate defense for equipment
|
||||||
|
float defense = playerCharacter.statDexCurrent * 2;
|
||||||
|
defense += getShieldDefense(playerCharacter,equipped.get(EquipSlotType.LHELD));
|
||||||
|
defense += getArmorDefense(playerCharacter,equipped.get(EquipSlotType.HELM));
|
||||||
|
defense += getArmorDefense(playerCharacter,equipped.get(EquipSlotType.CHEST));
|
||||||
|
defense += getArmorDefense(playerCharacter,equipped.get(EquipSlotType.UPARM));
|
||||||
|
defense += getArmorDefense(playerCharacter,equipped.get(EquipSlotType.HANDS));
|
||||||
|
defense += getArmorDefense(playerCharacter,equipped.get(EquipSlotType.LEGS));
|
||||||
|
defense += getArmorDefense(playerCharacter,equipped.get(EquipSlotType.FEET));
|
||||||
|
defense += getWeaponDefense(playerCharacter,equipped);
|
||||||
|
|
||||||
|
if (playerCharacter.bonuses != null) {
|
||||||
|
// add any bonuses
|
||||||
|
defense += (short) playerCharacter.bonuses.getFloat(ModType.DCV, SourceType.NONE);
|
||||||
|
|
||||||
|
// Finally multiply any percent modifiers. DO THIS LAST!
|
||||||
|
float pos_Bonus = playerCharacter.bonuses.getFloatPercentPositive(ModType.DCV, SourceType.NONE);
|
||||||
|
defense = (short) (defense * (1 + pos_Bonus));
|
||||||
|
|
||||||
|
//Lucky rune applies next
|
||||||
|
//applied runes will be calculated and added to the normal bonuses. no need for this garbage anymore
|
||||||
|
//defense = (short) (defense * (1 + ((float) this.bonuses.getShort("rune.Defense") / 100)));
|
||||||
|
|
||||||
|
//and negative percent modifiers
|
||||||
|
//already done...
|
||||||
|
float neg_Bonus = playerCharacter.bonuses.getFloatPercentNegative(ModType.DCV, SourceType.NONE);
|
||||||
|
defense = (short) (defense * (1 + neg_Bonus));
|
||||||
|
|
||||||
|
} else
|
||||||
|
// TODO add error log here
|
||||||
|
Logger.error("Error: missing bonuses");
|
||||||
|
|
||||||
|
defense = (defense < 1) ? 1 : defense;
|
||||||
|
playerCharacter.defenseRating = (short) (defense + 0.5f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ Calculates Atr, and Damage for each weapon
|
||||||
|
*/
|
||||||
|
private static void calculateAtrDamageForWeapon(AbstractCharacter playerCharacter, Item weapon, boolean mainHand, Item otherHand) {
|
||||||
|
|
||||||
|
// make sure weapon exists
|
||||||
|
boolean noWeapon = false;
|
||||||
|
ItemBase wb = null;
|
||||||
|
if (weapon == null)
|
||||||
|
noWeapon = true;
|
||||||
|
else {
|
||||||
|
ItemBase ib = weapon.getItemBase();
|
||||||
|
if (ib == null)
|
||||||
|
noWeapon = true;
|
||||||
|
else if (!weapon.template.item_type.equals(ItemType.WEAPON)) {
|
||||||
|
defaultAtrAndDamage(playerCharacter,mainHand);
|
||||||
|
return;
|
||||||
|
} else
|
||||||
|
wb = ib;
|
||||||
|
}
|
||||||
|
float skillPercentage, masteryPercentage;
|
||||||
|
float mastDam;
|
||||||
|
float min, max;
|
||||||
|
float speed = 20f;
|
||||||
|
boolean strBased = false;
|
||||||
|
|
||||||
|
ItemBase wbMain = (weapon != null) ? weapon.getItemBase() : null;
|
||||||
|
ItemBase wbOff = (otherHand != null) ? otherHand.getItemBase() : null;
|
||||||
|
|
||||||
|
// get skill percentages and min and max damage for weapons
|
||||||
|
if (noWeapon) {
|
||||||
|
if (mainHand) {
|
||||||
|
Item off = playerCharacter.charItemManager.getEquipped().get(EquipSlotType.LHELD);
|
||||||
|
if (off != null && off.getItemBase() != null && off.template.item_type.equals(ItemType.WEAPON))
|
||||||
|
playerCharacter.rangeHandOne = 10 * (1 + (playerCharacter.statStrBase / 600)); // Set
|
||||||
|
// to
|
||||||
|
// no
|
||||||
|
// weapon
|
||||||
|
// range
|
||||||
|
else
|
||||||
|
playerCharacter.rangeHandOne = -1; // set to do not attack
|
||||||
|
} else
|
||||||
|
playerCharacter.rangeHandTwo = -1; // set to do not attack
|
||||||
|
|
||||||
|
skillPercentage = getModifiedAmount(playerCharacter.skills.get("Unarmed Combat"));
|
||||||
|
masteryPercentage = getModifiedAmount(playerCharacter.skills.get("Unarmed Combat Mastery"));
|
||||||
|
if (masteryPercentage == 0f)
|
||||||
|
mastDam = CharacterSkill.getQuickMastery(playerCharacter, "Unarmed Combat Mastery");
|
||||||
|
else
|
||||||
|
mastDam = masteryPercentage;
|
||||||
|
// TODO Correct these
|
||||||
|
min = 1;
|
||||||
|
max = 3;
|
||||||
|
} else {
|
||||||
|
if (mainHand)
|
||||||
|
playerCharacter.rangeHandOne = weapon.getItemBase().getRange() * (1 + (playerCharacter.statStrBase / 600));
|
||||||
|
else
|
||||||
|
playerCharacter.rangeHandTwo = weapon.getItemBase().getRange() * (1 + (playerCharacter.statStrBase / 600));
|
||||||
|
|
||||||
|
if (playerCharacter.bonuses != null) {
|
||||||
|
float range_bonus = 1 + playerCharacter.bonuses.getFloatPercentAll(ModType.WeaponRange, SourceType.NONE);
|
||||||
|
|
||||||
|
if (mainHand)
|
||||||
|
playerCharacter.rangeHandOne *= range_bonus;
|
||||||
|
else
|
||||||
|
playerCharacter.rangeHandTwo *= range_bonus;
|
||||||
|
|
||||||
|
}
|
||||||
|
skillPercentage = getModifiedAmount(playerCharacter.skills.get(weapon.template.item_skill_used));
|
||||||
|
masteryPercentage = getModifiedAmount(playerCharacter.skills.get(wb.getMastery()));
|
||||||
|
if (masteryPercentage == 0f)
|
||||||
|
mastDam = 0f;
|
||||||
|
// mastDam = CharacterSkill.getQuickMastery(this, wb.getMastery());
|
||||||
|
else
|
||||||
|
mastDam = masteryPercentage;
|
||||||
|
min = (float) wb.getMinDamage();
|
||||||
|
max = (float) wb.getMaxDamage();
|
||||||
|
strBased = wb.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 (playerCharacter.effects != null && playerCharacter.effects.containsKey("DeathShroud"))
|
||||||
|
// No Atr in deathshroud.
|
||||||
|
if (mainHand)
|
||||||
|
playerCharacter.atrHandOne = (short) 0;
|
||||||
|
else
|
||||||
|
playerCharacter.atrHandTwo = (short) 0;
|
||||||
|
else {
|
||||||
|
// calculate atr
|
||||||
|
float atr = 0;
|
||||||
|
atr += (int) skillPercentage * 4f; //<-round down skill% -
|
||||||
|
atr += (int) masteryPercentage * 3f;
|
||||||
|
if (playerCharacter.statStrCurrent > playerCharacter.statDexCurrent)
|
||||||
|
atr += playerCharacter.statStrCurrent / 2;
|
||||||
|
else
|
||||||
|
atr += playerCharacter.statDexCurrent / 2;
|
||||||
|
|
||||||
|
// add in any bonuses to atr
|
||||||
|
if (playerCharacter.bonuses != null) {
|
||||||
|
// Add any base bonuses
|
||||||
|
atr += playerCharacter.bonuses.getFloat(ModType.OCV, SourceType.NONE);
|
||||||
|
|
||||||
|
// Finally use any multipliers. DO THIS LAST!
|
||||||
|
float pos_Bonus = (1 + playerCharacter.bonuses.getFloatPercentPositive(ModType.OCV, SourceType.NONE));
|
||||||
|
atr *= pos_Bonus;
|
||||||
|
|
||||||
|
// next precise
|
||||||
|
//runes will have their own bonuses.
|
||||||
|
// atr *= (1 + ((float) this.bonuses.getShort("rune.Attack") / 100));
|
||||||
|
|
||||||
|
//and negative percent modifiers
|
||||||
|
float neg_Bonus = playerCharacter.bonuses.getFloatPercentNegative(ModType.OCV, SourceType.NONE);
|
||||||
|
|
||||||
|
atr *= (1 + neg_Bonus);
|
||||||
|
}
|
||||||
|
|
||||||
|
atr = (atr < 1) ? 1 : atr;
|
||||||
|
|
||||||
|
// set atr
|
||||||
|
if (mainHand)
|
||||||
|
playerCharacter.atrHandOne = (short) (atr + 0.5f);
|
||||||
|
else
|
||||||
|
playerCharacter.atrHandTwo = (short) (atr + 0.5f);
|
||||||
|
}
|
||||||
|
|
||||||
|
//calculate speed
|
||||||
|
if (wb != null)
|
||||||
|
speed = wb.getSpeed();
|
||||||
|
else
|
||||||
|
speed = 20f; //unarmed attack speed
|
||||||
|
if (weapon != null)
|
||||||
|
speed *= (1 + playerCharacter.bonuses.getFloatPercentAll(ModType.WeaponSpeed, SourceType.NONE));
|
||||||
|
speed *= (1 + playerCharacter.bonuses.getFloatPercentAll(ModType.AttackDelay, SourceType.NONE));
|
||||||
|
if (speed < 10)
|
||||||
|
speed = 10;
|
||||||
|
|
||||||
|
//add min/max damage bonuses for weapon
|
||||||
|
if (weapon != null) {
|
||||||
|
// Add any base bonuses
|
||||||
|
|
||||||
|
min += weapon.getBonus(ModType.MinDamage, SourceType.NONE);
|
||||||
|
max += weapon.getBonus(ModType.MaxDamage, SourceType.NONE);
|
||||||
|
|
||||||
|
min += weapon.getBonus(ModType.MeleeDamageModifier, SourceType.NONE);
|
||||||
|
max += weapon.getBonus(ModType.MeleeDamageModifier, SourceType.NONE);
|
||||||
|
// Finally use any multipliers. DO THIS LAST!
|
||||||
|
|
||||||
|
float percentMinDamage = 1;
|
||||||
|
float percentMaxDamage = 1;
|
||||||
|
|
||||||
|
percentMinDamage += weapon.getBonusPercent(ModType.MinDamage, SourceType.NONE);
|
||||||
|
percentMinDamage += weapon.getBonusPercent(ModType.MeleeDamageModifier, SourceType.NONE);
|
||||||
|
|
||||||
|
percentMaxDamage += weapon.getBonusPercent(ModType.MaxDamage, SourceType.NONE);
|
||||||
|
percentMaxDamage += weapon.getBonusPercent(ModType.MeleeDamageModifier, SourceType.NONE);
|
||||||
|
|
||||||
|
|
||||||
|
min *= percentMinDamage;
|
||||||
|
max *= percentMaxDamage;
|
||||||
|
}
|
||||||
|
|
||||||
|
//if duel wielding, cut damage by 30%
|
||||||
|
if (otherHand != null) {
|
||||||
|
ItemBase ibo = otherHand.getItemBase();
|
||||||
|
if (ibo != null && otherHand.template.equals(ItemType.WEAPON)) {
|
||||||
|
min *= 0.7f;
|
||||||
|
max *= 0.7f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// calculate damage
|
||||||
|
float minDamage;
|
||||||
|
float maxDamage;
|
||||||
|
float pri = (strBased) ? (float) playerCharacter.statStrCurrent : (float) playerCharacter.statDexCurrent;
|
||||||
|
float sec = (strBased) ? (float) playerCharacter.statDexCurrent : (float) playerCharacter.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
|
||||||
|
|
||||||
|
// Half damage if in death shroud
|
||||||
|
if (playerCharacter.effects != null && playerCharacter.effects.containsKey("DeathShroud")) {
|
||||||
|
minDamage *= 0.5f;
|
||||||
|
maxDamage *= 0.5f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// add in any bonuses to damage
|
||||||
|
if (playerCharacter.bonuses != null) {
|
||||||
|
// Add any base bonuses
|
||||||
|
minDamage += playerCharacter.bonuses.getFloat(ModType.MinDamage, SourceType.NONE);
|
||||||
|
maxDamage += playerCharacter.bonuses.getFloat(ModType.MaxDamage, SourceType.NONE);
|
||||||
|
|
||||||
|
minDamage += playerCharacter.bonuses.getFloat(ModType.MeleeDamageModifier, SourceType.NONE);
|
||||||
|
maxDamage += playerCharacter.bonuses.getFloat(ModType.MeleeDamageModifier, SourceType.NONE);
|
||||||
|
// Finally use any multipliers. DO THIS LAST!
|
||||||
|
|
||||||
|
float percentMinDamage = 1;
|
||||||
|
float percentMaxDamage = 1;
|
||||||
|
|
||||||
|
percentMinDamage += playerCharacter.bonuses.getFloatPercentAll(ModType.MinDamage, SourceType.NONE);
|
||||||
|
percentMinDamage += playerCharacter.bonuses.getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.NONE);
|
||||||
|
|
||||||
|
percentMaxDamage += playerCharacter.bonuses.getFloatPercentAll(ModType.MaxDamage, SourceType.NONE);
|
||||||
|
percentMaxDamage += playerCharacter.bonuses.getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.NONE);
|
||||||
|
|
||||||
|
minDamage *= percentMinDamage;
|
||||||
|
maxDamage *= percentMaxDamage;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// set damages
|
||||||
|
if (mainHand) {
|
||||||
|
playerCharacter.minDamageHandOne = (int) minDamage;
|
||||||
|
playerCharacter.maxDamageHandOne = (int) maxDamage;
|
||||||
|
playerCharacter.speedHandOne = speed;
|
||||||
|
} else {
|
||||||
|
playerCharacter.minDamageHandTwo = (int) minDamage;
|
||||||
|
playerCharacter.maxDamageHandTwo = (int) maxDamage;
|
||||||
|
playerCharacter.speedHandTwo = speed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ Calculates Defense for shield
|
||||||
|
*/
|
||||||
|
private static float getShieldDefense(AbstractCharacter playerCharacter, Item shield) {
|
||||||
|
|
||||||
|
if (shield == null)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (ItemTemplate.isShield(shield) == false)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
ItemBase ab = shield.getItemBase();
|
||||||
|
|
||||||
|
if (ab == null)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
CharacterSkill blockSkill = playerCharacter.skills.get("Block");
|
||||||
|
|
||||||
|
float skillMod;
|
||||||
|
|
||||||
|
if (blockSkill == null) {
|
||||||
|
skillMod = 0;
|
||||||
|
} else
|
||||||
|
skillMod = blockSkill.getModifiedAmount();
|
||||||
|
|
||||||
|
float def = ab.getDefense();
|
||||||
|
|
||||||
|
//apply item defense bonuses
|
||||||
|
if (shield != null) {
|
||||||
|
def += shield.getBonus(ModType.DR, SourceType.NONE);
|
||||||
|
def *= (1 + shield.getBonusPercent(ModType.DR, SourceType.NONE));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// float val = ((float)ab.getDefense()) * (1 + (skillMod / 100));
|
||||||
|
return (def * (1 + ((int) skillMod / 100f)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ Calculates Defense for armor
|
||||||
|
*/
|
||||||
|
private static float getArmorDefense(AbstractCharacter playerCharacter, Item armor) {
|
||||||
|
|
||||||
|
if (armor == null)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
ItemBase ib = armor.getItemBase();
|
||||||
|
|
||||||
|
if (ib == null)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!armor.template.item_type.equals(ItemType.ARMOR))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (armor.template.item_skill_used.isEmpty())
|
||||||
|
return ib.getDefense();
|
||||||
|
|
||||||
|
CharacterSkill armorSkill = playerCharacter.skills.get(armor.template.item_skill_used);
|
||||||
|
if (armorSkill == null) {
|
||||||
|
Logger.error("Player " + playerCharacter.getObjectUUID()
|
||||||
|
+ " has armor equipped without the nescessary skill to equip it");
|
||||||
|
return ib.getDefense();
|
||||||
|
}
|
||||||
|
|
||||||
|
float def = ib.getDefense();
|
||||||
|
//apply item defense bonuses
|
||||||
|
if (armor != null) {
|
||||||
|
def += armor.getBonus(ModType.DR, SourceType.NONE);
|
||||||
|
def *= (1 + armor.getBonusPercent(ModType.DR, SourceType.NONE));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return (def * (1 + ((int) armorSkill.getModifiedAmount() / 50f)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ Calculates Defense for weapon
|
||||||
|
*/
|
||||||
|
private static float getWeaponDefense(AbstractCharacter playerCharacter, ConcurrentHashMap<EquipSlotType, Item> equipped) {
|
||||||
|
Item weapon = equipped.get(EquipSlotType.RHELD);
|
||||||
|
ItemBase wb = null;
|
||||||
|
CharacterSkill skill, mastery;
|
||||||
|
float val = 0;
|
||||||
|
boolean unarmed = false;
|
||||||
|
if (weapon == null) {
|
||||||
|
weapon = equipped.get(EquipSlotType.LHELD);
|
||||||
|
if (weapon == null || ItemTemplate.isShield(weapon))
|
||||||
|
unarmed = true;
|
||||||
|
else
|
||||||
|
wb = weapon.getItemBase();
|
||||||
|
} else
|
||||||
|
wb = weapon.getItemBase();
|
||||||
|
if (wb == null)
|
||||||
|
unarmed = true;
|
||||||
|
if (unarmed) {
|
||||||
|
skill = playerCharacter.skills.get("Unarmed Combat");
|
||||||
|
mastery = playerCharacter.skills.get("Unarmed Combat Mastery");
|
||||||
|
} else {
|
||||||
|
skill = playerCharacter.skills.get(weapon.template.item_skill_used);
|
||||||
|
mastery = playerCharacter.skills.get(wb.getMastery());
|
||||||
|
}
|
||||||
|
if (skill != null)
|
||||||
|
val += (int) skill.getModifiedAmount() / 2f;
|
||||||
|
if (mastery != null)
|
||||||
|
val += (int) mastery.getModifiedAmount() / 2f;
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Don't call this function directly. linked from pc.calculateSkills()
|
||||||
|
//through SkillCalcJob. Designed to only run from one worker thread
|
||||||
|
public static void runSkillCalc(AbstractCharacter playerCharacter) {
|
||||||
|
try {
|
||||||
|
|
||||||
|
//see if any new skills or powers granted
|
||||||
|
CharacterSkill.calculateSkills(playerCharacter);
|
||||||
|
// calculate granted Trains in powers.
|
||||||
|
CharacterPower.grantTrains(playerCharacter);
|
||||||
|
//see if any new powers unlocked from previous check
|
||||||
|
CharacterPower.calculatePowers(playerCharacter);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//calculate item bonuses here
|
||||||
|
public static void calculateItemBonuses(AbstractCharacter playerCharacter) {
|
||||||
|
if (playerCharacter.charItemManager == null || playerCharacter.bonuses == null)
|
||||||
|
return;
|
||||||
|
ConcurrentHashMap<EquipSlotType, Item> equipped = playerCharacter.charItemManager.getEquipped();
|
||||||
|
for (Item item : equipped.values()) {
|
||||||
|
ItemBase ib = item.getItemBase();
|
||||||
|
if (ib == null)
|
||||||
|
continue;
|
||||||
|
//TODO add effect bonuses in here for equipped items
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ Defaults ATR, Defense and Damage for player
|
||||||
|
*/
|
||||||
|
private static void defaultAtrAndDamage(AbstractCharacter playerCharacter, boolean mainHand) {
|
||||||
|
if (mainHand) {
|
||||||
|
playerCharacter.atrHandOne = 0;
|
||||||
|
playerCharacter.minDamageHandOne = 0;
|
||||||
|
playerCharacter.maxDamageHandOne = 0;
|
||||||
|
playerCharacter.rangeHandOne = -1;
|
||||||
|
playerCharacter.speedHandOne = 20;
|
||||||
|
} else {
|
||||||
|
playerCharacter.atrHandTwo = 0;
|
||||||
|
playerCharacter.minDamageHandTwo = 0;
|
||||||
|
playerCharacter.maxDamageHandTwo = 0;
|
||||||
|
playerCharacter.rangeHandTwo = -1;
|
||||||
|
playerCharacter.speedHandTwo = 20;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static float getModifiedAmount(CharacterSkill skill) {
|
||||||
|
if (skill == null)
|
||||||
|
return 0f;
|
||||||
|
return skill.getModifiedAmount();
|
||||||
|
}
|
||||||
|
|
||||||
private void initializeCharacter() {
|
private void initializeCharacter() {
|
||||||
this.timers = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
|
this.timers = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
|
||||||
this.timestamps = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
|
this.timestamps = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
|
||||||
@@ -1850,7 +2324,7 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
|
|||||||
PlayerCharacter pc = (PlayerCharacter) this;
|
PlayerCharacter pc = (PlayerCharacter) this;
|
||||||
|
|
||||||
//calculate item bonuses
|
//calculate item bonuses
|
||||||
pc.calculateItemBonuses();
|
calculateItemBonuses(pc);
|
||||||
|
|
||||||
//recalculate formulas
|
//recalculate formulas
|
||||||
pc.recalculatePlayerStats(true);
|
pc.recalculatePlayerStats(true);
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
package engine.objects;
|
package engine.objects;
|
||||||
|
|
||||||
|
import engine.Enum;
|
||||||
import engine.gameManager.DbManager;
|
import engine.gameManager.DbManager;
|
||||||
import engine.gameManager.PowersManager;
|
import engine.gameManager.PowersManager;
|
||||||
import engine.net.ByteBufferWriter;
|
import engine.net.ByteBufferWriter;
|
||||||
@@ -97,28 +98,29 @@ public class CharacterPower extends AbstractGameObject {
|
|||||||
* This iterates through players runes and adds and removes powers as needed
|
* This iterates through players runes and adds and removes powers as needed
|
||||||
* Don't Call this directly. Instead call pc.calculateSkills().
|
* Don't Call this directly. Instead call pc.calculateSkills().
|
||||||
*/
|
*/
|
||||||
public static void calculatePowers(PlayerCharacter pc) {
|
public static void calculatePowers(AbstractCharacter absChar) {
|
||||||
if (pc == null)
|
if (absChar == null || absChar.getObjectType().equals(Enum.GameObjectType.PlayerCharacter) == false)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
PlayerCharacter pc = (PlayerCharacter) absChar;
|
||||||
// First add powers that don't exist
|
// First add powers that don't exist
|
||||||
ConcurrentHashMap<Integer, CharacterPower> powers = pc.getPowers();
|
ConcurrentHashMap<Integer, CharacterPower> powers = pc.getPowers();
|
||||||
// ArrayList<PowerReq> genericPowers = PowerReq.getPowerReqsForAll();
|
// ArrayList<PowerReq> genericPowers = PowerReq.getPowerReqsForAll();
|
||||||
// CharacterPower.grantPowers(genericPowers, powers, pc);
|
// CharacterPower.grantPowers(genericPowers, powers, pc);
|
||||||
Race race = pc.getRace();
|
Race race = pc.race;
|
||||||
if (race != null) {
|
if (race != null) {
|
||||||
CharacterPower.grantPowers(race.getPowersGranted(), powers, pc);
|
CharacterPower.grantPowers(race.getPowersGranted(), powers, pc);
|
||||||
} else
|
} else
|
||||||
Logger.error("Failed to find Race for player " + pc.getObjectUUID());
|
Logger.error("Failed to find Race for player " + pc.getObjectUUID());
|
||||||
BaseClass bc = pc.getBaseClass();
|
BaseClass bc = pc.baseClass;
|
||||||
if (bc != null) {
|
if (bc != null) {
|
||||||
CharacterPower.grantPowers(bc.getPowersGranted(), powers, pc);
|
CharacterPower.grantPowers(bc.getPowersGranted(), powers, pc);
|
||||||
} else
|
} else
|
||||||
Logger.error("Failed to find BaseClass for player " + pc.getObjectUUID());
|
Logger.error("Failed to find BaseClass for player " + pc.getObjectUUID());
|
||||||
PromotionClass promo = pc.getPromotionClass();
|
PromotionClass promo = pc.promotionClass;
|
||||||
if (promo != null)
|
if (promo != null)
|
||||||
CharacterPower.grantPowers(promo.getPowersGranted(), powers, pc);
|
CharacterPower.grantPowers(promo.getPowersGranted(), powers, pc);
|
||||||
ArrayList<CharacterRune> runes = pc.getRunes();
|
ArrayList<CharacterRune> runes = pc.runes;
|
||||||
if (runes != null) {
|
if (runes != null) {
|
||||||
for (CharacterRune rune : runes) {
|
for (CharacterRune rune : runes) {
|
||||||
CharacterPower.grantPowers(rune.getPowersGranted(), powers, pc);
|
CharacterPower.grantPowers(rune.getPowersGranted(), powers, pc);
|
||||||
@@ -242,9 +244,11 @@ public class CharacterPower extends AbstractGameObject {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void grantTrains(PlayerCharacter pc) {
|
public static void grantTrains(AbstractCharacter absChar) {
|
||||||
if (pc == null)
|
if (absChar == null || absChar.getObjectType().equals(Enum.GameObjectType.PlayerCharacter) == false)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
PlayerCharacter pc = (PlayerCharacter) absChar;
|
||||||
ConcurrentHashMap<Integer, CharacterPower> powers = pc.getPowers();
|
ConcurrentHashMap<Integer, CharacterPower> powers = pc.getPowers();
|
||||||
for (CharacterPower cp : powers.values()) {
|
for (CharacterPower cp : powers.values()) {
|
||||||
cp.grantedTrains = cp.getGrantedTrains(pc);
|
cp.grantedTrains = cp.getGrantedTrains(pc);
|
||||||
@@ -526,13 +530,13 @@ public class CharacterPower extends AbstractGameObject {
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
ConcurrentHashMap<Integer, CharacterPower> powers = pc.getPowers();
|
ConcurrentHashMap<Integer, CharacterPower> powers = pc.getPowers();
|
||||||
Race race = pc.getRace();
|
Race race = pc.race;
|
||||||
if (race != null) {
|
if (race != null) {
|
||||||
if (!canRefine(race.getPowersGranted(), powers, pc))
|
if (!canRefine(race.getPowersGranted(), powers, pc))
|
||||||
return false;
|
return false;
|
||||||
} else
|
} else
|
||||||
return false;
|
return false;
|
||||||
BaseClass bc = pc.getBaseClass();
|
BaseClass bc = pc.baseClass;
|
||||||
if (bc != null) {
|
if (bc != null) {
|
||||||
if (!canRefine(bc.getPowersGranted(), powers, pc))
|
if (!canRefine(bc.getPowersGranted(), powers, pc))
|
||||||
return false;
|
return false;
|
||||||
@@ -585,13 +589,13 @@ public class CharacterPower extends AbstractGameObject {
|
|||||||
return false;
|
return false;
|
||||||
int token = this.power.getToken();
|
int token = this.power.getToken();
|
||||||
boolean valid = false;
|
boolean valid = false;
|
||||||
Race race = pc.getRace();
|
Race race = pc.race;
|
||||||
if (race != null) {
|
if (race != null) {
|
||||||
if (CharacterPower.powerAllowed(token, race.getPowersGranted(), pc))
|
if (CharacterPower.powerAllowed(token, race.getPowersGranted(), pc))
|
||||||
return true;
|
return true;
|
||||||
} else
|
} else
|
||||||
return false;
|
return false;
|
||||||
BaseClass bc = pc.getBaseClass();
|
BaseClass bc = pc.baseClass;
|
||||||
if (bc != null) {
|
if (bc != null) {
|
||||||
if (CharacterPower.powerAllowed(token, bc.getPowersGranted(), pc))
|
if (CharacterPower.powerAllowed(token, bc.getPowersGranted(), pc))
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -378,7 +378,7 @@ public class CharacterSkill extends AbstractGameObject {
|
|||||||
|
|
||||||
if (pc == null)
|
if (pc == null)
|
||||||
return 0;
|
return 0;
|
||||||
if (pc.getRace() == null || pc.getBaseClass() == null) {
|
if (pc.race == null || pc.baseClass == null) {
|
||||||
Logger.error("Race or BaseClass not found for player " + pc.getObjectUUID());
|
Logger.error("Race or BaseClass not found for player " + pc.getObjectUUID());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -388,12 +388,12 @@ public class CharacterSkill extends AbstractGameObject {
|
|||||||
int available = 0;
|
int available = 0;
|
||||||
|
|
||||||
//get racial bonus;
|
//get racial bonus;
|
||||||
if (pc.getRace().getRaceType().equals(Enum.RaceType.HUMANMALE) ||
|
if (pc.race.getRaceType().equals(Enum.RaceType.HUMANMALE) ||
|
||||||
pc.getRace().getRaceType().equals(Enum.RaceType.HUMANFEMALE))
|
pc.race.getRaceType().equals(Enum.RaceType.HUMANFEMALE))
|
||||||
raceBonus = 1; //Human racial bonus;
|
raceBonus = 1; //Human racial bonus;
|
||||||
|
|
||||||
//get base class trains
|
//get base class trains
|
||||||
if (pc.getBaseClass().getObjectUUID() == 2500 || pc.getBaseClass().getObjectUUID() == 2502) {
|
if (pc.baseClass.getObjectUUID() == 2500 || pc.baseClass.getObjectUUID() == 2502) {
|
||||||
baseMod = 4; //Fighter or Rogue
|
baseMod = 4; //Fighter or Rogue
|
||||||
} else {
|
} else {
|
||||||
baseMod = 5; //Healer or Mage
|
baseMod = 5; //Healer or Mage
|
||||||
@@ -480,24 +480,26 @@ public class CharacterSkill extends AbstractGameObject {
|
|||||||
* This iterates through players runes and adds and removes skills as needed
|
* This iterates through players runes and adds and removes skills as needed
|
||||||
* Don't Call this directly. Instead call pc.calculateSkills().
|
* Don't Call this directly. Instead call pc.calculateSkills().
|
||||||
*/
|
*/
|
||||||
public static void calculateSkills(PlayerCharacter pc) {
|
public static void calculateSkills(AbstractCharacter absChar) {
|
||||||
if (pc == null)
|
if (absChar == null && absChar.getObjectType().equals(Enum.GameObjectType.PlayerCharacter) == false)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
PlayerCharacter pc = (PlayerCharacter)absChar;
|
||||||
|
|
||||||
ConcurrentHashMap<String, CharacterSkill> skills = pc.getSkills();
|
ConcurrentHashMap<String, CharacterSkill> skills = pc.getSkills();
|
||||||
|
|
||||||
//First add skills that don't exist
|
//First add skills that don't exist
|
||||||
Race race = pc.getRace();
|
Race race = pc.race;
|
||||||
if (race != null) {
|
if (race != null) {
|
||||||
CharacterSkill.grantSkills(race.getSkillsGranted(), pc);
|
CharacterSkill.grantSkills(race.getSkillsGranted(), pc);
|
||||||
} else
|
} else
|
||||||
Logger.error("Failed to find Race for player " + pc.getObjectUUID());
|
Logger.error("Failed to find Race for player " + pc.getObjectUUID());
|
||||||
BaseClass bc = pc.getBaseClass();
|
BaseClass bc = pc.baseClass;
|
||||||
if (bc != null) {
|
if (bc != null) {
|
||||||
CharacterSkill.grantSkills(bc.getSkillsGranted(), pc);
|
CharacterSkill.grantSkills(bc.getSkillsGranted(), pc);
|
||||||
} else
|
} else
|
||||||
Logger.error("Failed to find BaseClass for player " + pc.getObjectUUID());
|
Logger.error("Failed to find BaseClass for player " + pc.getObjectUUID());
|
||||||
PromotionClass promo = pc.getPromotionClass();
|
PromotionClass promo = pc.promotionClass;
|
||||||
if (promo != null)
|
if (promo != null)
|
||||||
CharacterSkill.grantSkills(promo.getSkillsGranted(), pc);
|
CharacterSkill.grantSkills(promo.getSkillsGranted(), pc);
|
||||||
ArrayList<CharacterRune> runes = pc.getRunes();
|
ArrayList<CharacterRune> runes = pc.getRunes();
|
||||||
|
|||||||
@@ -1500,44 +1500,6 @@ public class Mob extends AbstractIntelligenceAgent implements Delayed {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public ItemBase getWeaponItemBase(boolean mainHand) {
|
|
||||||
|
|
||||||
if (this.equipmentSetID != 0)
|
|
||||||
if (charItemManager.equipped != null) {
|
|
||||||
Item me;
|
|
||||||
|
|
||||||
if (mainHand)
|
|
||||||
me = charItemManager.equipped.get(EquipSlotType.RHELD); //mainHand
|
|
||||||
else
|
|
||||||
me = charItemManager.equipped.get(EquipSlotType.LHELD); //offHand
|
|
||||||
|
|
||||||
if (me != null) {
|
|
||||||
|
|
||||||
ItemBase ib = me.getItemBase();
|
|
||||||
|
|
||||||
if (ib != null)
|
|
||||||
return ib;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
MobBase mb = this.mobBase;
|
|
||||||
|
|
||||||
if (mb != null)
|
|
||||||
if (this.charItemManager.equipped.isEmpty() == false) {
|
|
||||||
|
|
||||||
Item me;
|
|
||||||
|
|
||||||
if (mainHand)
|
|
||||||
me = this.charItemManager.equipped.get(EquipSlotType.RHELD); //mainHand
|
|
||||||
else
|
|
||||||
me = this.charItemManager.equipped.get(EquipSlotType.LHELD); //offHand
|
|
||||||
|
|
||||||
if (me != null)
|
|
||||||
return me.getItemBase();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void runAfterLoad() {
|
public void runAfterLoad() {
|
||||||
|
|
||||||
@@ -1767,9 +1729,6 @@ public class Mob extends AbstractIntelligenceAgent implements Delayed {
|
|||||||
return lastAttackTime;
|
return lastAttackTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLastAttackTime(long lastAttackTime) {
|
|
||||||
this.lastAttackTime = lastAttackTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDeathTime(long deathTime) {
|
public void setDeathTime(long deathTime) {
|
||||||
this.deathTime = deathTime;
|
this.deathTime = deathTime;
|
||||||
@@ -1779,10 +1738,6 @@ public class Mob extends AbstractIntelligenceAgent implements Delayed {
|
|||||||
return hasLoot;
|
return hasLoot;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DeferredPowerJob getWeaponPower() {
|
|
||||||
return weaponPower;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setWeaponPower(DeferredPowerJob weaponPower) {
|
public void setWeaponPower(DeferredPowerJob weaponPower) {
|
||||||
this.weaponPower = weaponPower;
|
this.weaponPower = weaponPower;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -90,11 +90,11 @@ public class PlayerBonuses {
|
|||||||
//recalculate race
|
//recalculate race
|
||||||
|
|
||||||
|
|
||||||
if (pc.getRace() != null) {
|
if (pc.race != null) {
|
||||||
|
|
||||||
|
|
||||||
if (pc.getRace().getEffectsList() != null)
|
if (pc.race.getEffectsList() != null)
|
||||||
for (MobBaseEffects raceEffect : pc.getRace().getEffectsList()) {
|
for (MobBaseEffects raceEffect : pc.race.getEffectsList()) {
|
||||||
EffectsBase eb = PowersManager.getEffectByToken(raceEffect.getToken());
|
EffectsBase eb = PowersManager.getEffectByToken(raceEffect.getToken());
|
||||||
|
|
||||||
if (eb == null)
|
if (eb == null)
|
||||||
@@ -125,10 +125,10 @@ public class PlayerBonuses {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//calculate baseclass effects
|
//calculate baseclass effects
|
||||||
if (pc.getBaseClass() != null) {
|
if (pc.baseClass != null) {
|
||||||
|
|
||||||
if (pc.getBaseClass().getEffectsList() != null)
|
if (pc.baseClass.getEffectsList() != null)
|
||||||
for (MobBaseEffects classEffect : pc.getBaseClass().getEffectsList()) {
|
for (MobBaseEffects classEffect : pc.baseClass.getEffectsList()) {
|
||||||
EffectsBase eb = PowersManager.getEffectByToken(classEffect.getToken());
|
EffectsBase eb = PowersManager.getEffectByToken(classEffect.getToken());
|
||||||
|
|
||||||
if (eb == null)
|
if (eb == null)
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
public final ReadWriteLock respawnLock = new ReentrantReadWriteLock(true);
|
public final ReadWriteLock respawnLock = new ReentrantReadWriteLock(true);
|
||||||
public final ArrayList<Mob> necroPets = new ArrayList<>();
|
public final ArrayList<Mob> necroPets = new ArrayList<>();
|
||||||
private final Account account;
|
private final Account account;
|
||||||
private final Race race;
|
|
||||||
private final byte skinColor;
|
private final byte skinColor;
|
||||||
private final byte hairColor;
|
private final byte hairColor;
|
||||||
private final byte beardColor;
|
private final byte beardColor;
|
||||||
@@ -99,12 +99,7 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
public short statIntMin;
|
public short statIntMin;
|
||||||
public short statSpiMin;
|
public short statSpiMin;
|
||||||
// Current Stats before Equip and Effect
|
// Current Stats before Equip and Effect
|
||||||
// Modifiers
|
|
||||||
public short statStrBase;
|
|
||||||
public short statDexBase;
|
|
||||||
public short statConBase;
|
|
||||||
public short statIntBase;
|
|
||||||
public short statSpiBase;
|
|
||||||
public short trainedStatPoints = 0;
|
public short trainedStatPoints = 0;
|
||||||
public boolean isCSR = false;
|
public boolean isCSR = false;
|
||||||
//TODO Public fields break OO!!!
|
//TODO Public fields break OO!!!
|
||||||
@@ -117,8 +112,8 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
public float landingAltitude = 0;
|
public float landingAltitude = 0;
|
||||||
public int bindBuilding = 0;
|
public int bindBuilding = 0;
|
||||||
public FriendStatus friendStatus = FriendStatus.Available;
|
public FriendStatus friendStatus = FriendStatus.Available;
|
||||||
private BaseClass baseClass;
|
|
||||||
private PromotionClass promotionClass;
|
|
||||||
private ConcurrentHashMap<Integer, String> ignoredPlayerIDs = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
|
private ConcurrentHashMap<Integer, String> ignoredPlayerIDs = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
|
||||||
private boolean lfGroup = false;
|
private boolean lfGroup = false;
|
||||||
private boolean lfGuild = false;
|
private boolean lfGuild = false;
|
||||||
@@ -1342,7 +1337,7 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
|
|
||||||
|
|
||||||
//calculate ATR, damage and defense
|
//calculate ATR, damage and defense
|
||||||
pc.calculateAtrDefenseDamage();
|
AbstractCharacter.calculateAtrDefenseDamage(pc);
|
||||||
|
|
||||||
//calculate movement bonus
|
//calculate movement bonus
|
||||||
pc.calculateSpeedMod();
|
pc.calculateSpeedMod();
|
||||||
@@ -1369,12 +1364,6 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
return ab.getDexPenalty();
|
return ab.getDexPenalty();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static float getModifiedAmount(CharacterSkill skill) {
|
|
||||||
if (skill == null)
|
|
||||||
return 0f;
|
|
||||||
return skill.getModifiedAmount();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void InitializeSkillsOnLoad(PlayerCharacter pc) {
|
public static void InitializeSkillsOnLoad(PlayerCharacter pc) {
|
||||||
try {
|
try {
|
||||||
{
|
{
|
||||||
@@ -2116,9 +2105,7 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
/**
|
/**
|
||||||
* @return the race
|
* @return the race
|
||||||
*/
|
*/
|
||||||
public Race getRace() {
|
|
||||||
return race;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getRaceID() {
|
public int getRaceID() {
|
||||||
if (race != null)
|
if (race != null)
|
||||||
@@ -2129,9 +2116,7 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
/**
|
/**
|
||||||
* @return the baseClass
|
* @return the baseClass
|
||||||
*/
|
*/
|
||||||
public BaseClass getBaseClass() {
|
|
||||||
return baseClass;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getBaseClassID() {
|
public int getBaseClassID() {
|
||||||
if (baseClass != null)
|
if (baseClass != null)
|
||||||
@@ -3359,7 +3344,7 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
|
|
||||||
|
|
||||||
//calculate ATR, damage and defense
|
//calculate ATR, damage and defense
|
||||||
calculateAtrDefenseDamage();
|
calculateAtrDefenseDamage(this);
|
||||||
|
|
||||||
//calculate movement bonus
|
//calculate movement bonus
|
||||||
calculateSpeedMod();
|
calculateSpeedMod();
|
||||||
@@ -3779,344 +3764,6 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
this.follow = false;
|
this.follow = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @ Calculates Atr (both hands) Defense, and Damage for pc
|
|
||||||
*/
|
|
||||||
public void calculateAtrDefenseDamage() {
|
|
||||||
if (this.charItemManager == null || this.charItemManager.getEquipped() == null || this.skills == null) {
|
|
||||||
Logger.error("Player " + this.getObjectUUID() + " missing skills or equipment");
|
|
||||||
defaultAtrAndDamage(true);
|
|
||||||
defaultAtrAndDamage(false);
|
|
||||||
this.defenseRating = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ConcurrentHashMap<EquipSlotType, Item> equipped = this.charItemManager.getEquipped();
|
|
||||||
|
|
||||||
// // Reset passives
|
|
||||||
// if (this.bonuses != null) {
|
|
||||||
// this.bonuses.setBool("Block", false);
|
|
||||||
// this.bonuses.setBool("Parry", false);
|
|
||||||
// if (this.baseClass != null && this.baseClass.getUUID() == 2502)
|
|
||||||
// this.bonuses.setBool("Dodge", true);
|
|
||||||
// else
|
|
||||||
// this.bonuses.setBool("Dodge", false);
|
|
||||||
// }
|
|
||||||
// calculate atr and damage for each hand
|
|
||||||
calculateAtrDamageForWeapon(equipped.get(EquipSlotType.RHELD), true, equipped.get(EquipSlotType.RHELD));
|
|
||||||
calculateAtrDamageForWeapon(equipped.get(EquipSlotType.LHELD), false, equipped.get(EquipSlotType.LHELD));
|
|
||||||
|
|
||||||
// No Defense while in DeathShroud
|
|
||||||
if (this.effects != null && this.effects.containsKey("DeathShroud"))
|
|
||||||
this.defenseRating = (short) 0;
|
|
||||||
else {
|
|
||||||
// calculate defense for equipment
|
|
||||||
float defense = this.statDexCurrent * 2;
|
|
||||||
defense += getShieldDefense(equipped.get(EquipSlotType.LHELD));
|
|
||||||
defense += getArmorDefense(equipped.get(EquipSlotType.HELM));
|
|
||||||
defense += getArmorDefense(equipped.get(EquipSlotType.CHEST));
|
|
||||||
defense += getArmorDefense(equipped.get(EquipSlotType.UPARM));
|
|
||||||
defense += getArmorDefense(equipped.get(EquipSlotType.HANDS));
|
|
||||||
defense += getArmorDefense(equipped.get(EquipSlotType.LEGS));
|
|
||||||
defense += getArmorDefense(equipped.get(EquipSlotType.FEET));
|
|
||||||
defense += getWeaponDefense(equipped);
|
|
||||||
|
|
||||||
if (this.bonuses != null) {
|
|
||||||
// add any bonuses
|
|
||||||
defense += (short) this.bonuses.getFloat(ModType.DCV, SourceType.NONE);
|
|
||||||
|
|
||||||
// Finally multiply any percent modifiers. DO THIS LAST!
|
|
||||||
float pos_Bonus = this.bonuses.getFloatPercentPositive(ModType.DCV, SourceType.NONE);
|
|
||||||
defense = (short) (defense * (1 + pos_Bonus));
|
|
||||||
|
|
||||||
//Lucky rune applies next
|
|
||||||
//applied runes will be calculated and added to the normal bonuses. no need for this garbage anymore
|
|
||||||
//defense = (short) (defense * (1 + ((float) this.bonuses.getShort("rune.Defense") / 100)));
|
|
||||||
|
|
||||||
//and negative percent modifiers
|
|
||||||
//already done...
|
|
||||||
float neg_Bonus = this.bonuses.getFloatPercentNegative(ModType.DCV, SourceType.NONE);
|
|
||||||
defense = (short) (defense * (1 + neg_Bonus));
|
|
||||||
|
|
||||||
} else
|
|
||||||
// TODO add error log here
|
|
||||||
Logger.error("Error: missing bonuses");
|
|
||||||
|
|
||||||
defense = (defense < 1) ? 1 : defense;
|
|
||||||
this.defenseRating = (short) (defense + 0.5f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ Calculates Atr, and Damage for each weapon
|
|
||||||
*/
|
|
||||||
private void calculateAtrDamageForWeapon(Item weapon, boolean mainHand, Item otherHand) {
|
|
||||||
|
|
||||||
// make sure weapon exists
|
|
||||||
boolean noWeapon = false;
|
|
||||||
ItemBase wb = null;
|
|
||||||
if (weapon == null)
|
|
||||||
noWeapon = true;
|
|
||||||
else {
|
|
||||||
ItemBase ib = weapon.getItemBase();
|
|
||||||
if (ib == null)
|
|
||||||
noWeapon = true;
|
|
||||||
else if (!weapon.template.item_type.equals(ItemType.WEAPON)) {
|
|
||||||
defaultAtrAndDamage(mainHand);
|
|
||||||
return;
|
|
||||||
} else
|
|
||||||
wb = ib;
|
|
||||||
}
|
|
||||||
float skillPercentage, masteryPercentage;
|
|
||||||
float mastDam;
|
|
||||||
float min, max;
|
|
||||||
float speed = 20f;
|
|
||||||
boolean strBased = false;
|
|
||||||
|
|
||||||
ItemBase wbMain = (weapon != null) ? weapon.getItemBase() : null;
|
|
||||||
ItemBase wbOff = (otherHand != null) ? otherHand.getItemBase() : null;
|
|
||||||
|
|
||||||
// get skill percentages and min and max damage for weapons
|
|
||||||
if (noWeapon) {
|
|
||||||
if (mainHand) {
|
|
||||||
Item off = this.charItemManager.getEquipped().get(EquipSlotType.LHELD);
|
|
||||||
if (off != null && off.getItemBase() != null && off.template.item_type.equals(ItemType.WEAPON))
|
|
||||||
this.rangeHandOne = 10 * (1 + (this.statStrBase / 600)); // Set
|
|
||||||
// to
|
|
||||||
// no
|
|
||||||
// weapon
|
|
||||||
// range
|
|
||||||
else
|
|
||||||
this.rangeHandOne = -1; // set to do not attack
|
|
||||||
} else
|
|
||||||
this.rangeHandTwo = -1; // set to do not attack
|
|
||||||
|
|
||||||
skillPercentage = getModifiedAmount(this.skills.get("Unarmed Combat"));
|
|
||||||
masteryPercentage = getModifiedAmount(this.skills.get("Unarmed Combat Mastery"));
|
|
||||||
if (masteryPercentage == 0f)
|
|
||||||
mastDam = CharacterSkill.getQuickMastery(this, "Unarmed Combat Mastery");
|
|
||||||
else
|
|
||||||
mastDam = masteryPercentage;
|
|
||||||
// TODO Correct these
|
|
||||||
min = 1;
|
|
||||||
max = 3;
|
|
||||||
} else {
|
|
||||||
if (mainHand)
|
|
||||||
this.rangeHandOne = weapon.getItemBase().getRange() * (1 + (this.statStrBase / 600));
|
|
||||||
else
|
|
||||||
this.rangeHandTwo = weapon.getItemBase().getRange() * (1 + (this.statStrBase / 600));
|
|
||||||
|
|
||||||
if (this.bonuses != null) {
|
|
||||||
float range_bonus = 1 + this.bonuses.getFloatPercentAll(ModType.WeaponRange, SourceType.NONE);
|
|
||||||
|
|
||||||
if (mainHand)
|
|
||||||
this.rangeHandOne *= range_bonus;
|
|
||||||
else
|
|
||||||
this.rangeHandTwo *= range_bonus;
|
|
||||||
|
|
||||||
}
|
|
||||||
skillPercentage = getModifiedAmount(this.skills.get(weapon.template.item_skill_used));
|
|
||||||
masteryPercentage = getModifiedAmount(this.skills.get(wb.getMastery()));
|
|
||||||
if (masteryPercentage == 0f)
|
|
||||||
mastDam = 0f;
|
|
||||||
// mastDam = CharacterSkill.getQuickMastery(this, wb.getMastery());
|
|
||||||
else
|
|
||||||
mastDam = masteryPercentage;
|
|
||||||
min = (float) wb.getMinDamage();
|
|
||||||
max = (float) wb.getMaxDamage();
|
|
||||||
strBased = wb.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"))
|
|
||||||
// No Atr in deathshroud.
|
|
||||||
if (mainHand)
|
|
||||||
this.atrHandOne = (short) 0;
|
|
||||||
else
|
|
||||||
this.atrHandTwo = (short) 0;
|
|
||||||
else {
|
|
||||||
// calculate atr
|
|
||||||
float atr = 0;
|
|
||||||
atr += (int) skillPercentage * 4f; //<-round down skill% -
|
|
||||||
atr += (int) masteryPercentage * 3f;
|
|
||||||
if (this.statStrCurrent > this.statDexCurrent)
|
|
||||||
atr += statStrCurrent / 2;
|
|
||||||
else
|
|
||||||
atr += statDexCurrent / 2;
|
|
||||||
|
|
||||||
// add in any bonuses to atr
|
|
||||||
if (this.bonuses != null) {
|
|
||||||
// Add any base bonuses
|
|
||||||
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;
|
|
||||||
|
|
||||||
// next precise
|
|
||||||
//runes will have their own bonuses.
|
|
||||||
// atr *= (1 + ((float) this.bonuses.getShort("rune.Attack") / 100));
|
|
||||||
|
|
||||||
//and negative percent modifiers
|
|
||||||
float neg_Bonus = this.bonuses.getFloatPercentNegative(ModType.OCV, SourceType.NONE);
|
|
||||||
|
|
||||||
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 (weapon != null)
|
|
||||||
speed *= (1 + this.bonuses.getFloatPercentAll(ModType.WeaponSpeed, SourceType.NONE));
|
|
||||||
speed *= (1 + this.bonuses.getFloatPercentAll(ModType.AttackDelay, SourceType.NONE));
|
|
||||||
if (speed < 10)
|
|
||||||
speed = 10;
|
|
||||||
|
|
||||||
//add min/max damage bonuses for weapon
|
|
||||||
if (weapon != null) {
|
|
||||||
// Add any base bonuses
|
|
||||||
|
|
||||||
min += weapon.getBonus(ModType.MinDamage, SourceType.NONE);
|
|
||||||
max += weapon.getBonus(ModType.MaxDamage, SourceType.NONE);
|
|
||||||
|
|
||||||
min += weapon.getBonus(ModType.MeleeDamageModifier, SourceType.NONE);
|
|
||||||
max += weapon.getBonus(ModType.MeleeDamageModifier, SourceType.NONE);
|
|
||||||
// Finally use any multipliers. DO THIS LAST!
|
|
||||||
|
|
||||||
float percentMinDamage = 1;
|
|
||||||
float percentMaxDamage = 1;
|
|
||||||
|
|
||||||
percentMinDamage += weapon.getBonusPercent(ModType.MinDamage, SourceType.NONE);
|
|
||||||
percentMinDamage += weapon.getBonusPercent(ModType.MeleeDamageModifier, SourceType.NONE);
|
|
||||||
|
|
||||||
percentMaxDamage += weapon.getBonusPercent(ModType.MaxDamage, SourceType.NONE);
|
|
||||||
percentMaxDamage += weapon.getBonusPercent(ModType.MeleeDamageModifier, SourceType.NONE);
|
|
||||||
|
|
||||||
|
|
||||||
min *= percentMinDamage;
|
|
||||||
max *= percentMaxDamage;
|
|
||||||
}
|
|
||||||
|
|
||||||
//if duel wielding, cut damage by 30%
|
|
||||||
if (otherHand != null) {
|
|
||||||
ItemBase ibo = otherHand.getItemBase();
|
|
||||||
if (ibo != null && otherHand.template.equals(ItemType.WEAPON)) {
|
|
||||||
min *= 0.7f;
|
|
||||||
max *= 0.7f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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
|
|
||||||
|
|
||||||
// Half damage if in death shroud
|
|
||||||
if (this.effects != null && this.effects.containsKey("DeathShroud")) {
|
|
||||||
minDamage *= 0.5f;
|
|
||||||
maxDamage *= 0.5f;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
|
|
||||||
minDamage += this.bonuses.getFloat(ModType.MeleeDamageModifier, SourceType.NONE);
|
|
||||||
maxDamage += this.bonuses.getFloat(ModType.MeleeDamageModifier, SourceType.NONE);
|
|
||||||
// Finally use any multipliers. DO THIS LAST!
|
|
||||||
|
|
||||||
float percentMinDamage = 1;
|
|
||||||
float percentMaxDamage = 1;
|
|
||||||
|
|
||||||
percentMinDamage += this.bonuses.getFloatPercentAll(ModType.MinDamage, SourceType.NONE);
|
|
||||||
percentMinDamage += this.bonuses.getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.NONE);
|
|
||||||
|
|
||||||
percentMaxDamage += this.bonuses.getFloatPercentAll(ModType.MaxDamage, SourceType.NONE);
|
|
||||||
percentMaxDamage += this.bonuses.getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.NONE);
|
|
||||||
|
|
||||||
minDamage *= percentMinDamage;
|
|
||||||
maxDamage *= percentMaxDamage;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// set damages
|
|
||||||
if (mainHand) {
|
|
||||||
this.minDamageHandOne = (int) minDamage;
|
|
||||||
this.maxDamageHandOne = (int) maxDamage;
|
|
||||||
this.speedHandOne = speed;
|
|
||||||
} else {
|
|
||||||
this.minDamageHandTwo = (int) minDamage;
|
|
||||||
this.maxDamageHandTwo = (int) maxDamage;
|
|
||||||
this.speedHandTwo = speed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ Calculates Defense for shield
|
|
||||||
*/
|
|
||||||
private float getShieldDefense(Item shield) {
|
|
||||||
|
|
||||||
if (shield == null)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (ItemTemplate.isShield(shield) == false)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
ItemBase ab = shield.getItemBase();
|
|
||||||
|
|
||||||
if (ab == null)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
CharacterSkill blockSkill = this.skills.get("Block");
|
|
||||||
|
|
||||||
float skillMod;
|
|
||||||
|
|
||||||
if (blockSkill == null) {
|
|
||||||
skillMod = 0;
|
|
||||||
} else
|
|
||||||
skillMod = blockSkill.getModifiedAmount();
|
|
||||||
|
|
||||||
float def = ab.getDefense();
|
|
||||||
|
|
||||||
//apply item defense bonuses
|
|
||||||
if (shield != null) {
|
|
||||||
def += shield.getBonus(ModType.DR, SourceType.NONE);
|
|
||||||
def *= (1 + shield.getBonusPercent(ModType.DR, SourceType.NONE));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// float val = ((float)ab.getDefense()) * (1 + (skillMod / 100));
|
|
||||||
return (def * (1 + ((int) skillMod / 100f)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPassives() {
|
public void setPassives() {
|
||||||
if (this.bonuses != null) {
|
if (this.bonuses != null) {
|
||||||
ConcurrentHashMap<EquipSlotType, Item> equipped = this.charItemManager.getEquipped();
|
ConcurrentHashMap<EquipSlotType, Item> equipped = this.charItemManager.getEquipped();
|
||||||
@@ -4153,134 +3800,15 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @ Calculates Defense for armor
|
|
||||||
*/
|
|
||||||
private float getArmorDefense(Item armor) {
|
|
||||||
|
|
||||||
if (armor == null)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
ItemBase ib = armor.getItemBase();
|
|
||||||
|
|
||||||
if (ib == null)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (!armor.template.item_type.equals(ItemType.ARMOR))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (armor.template.item_skill_used.isEmpty())
|
|
||||||
return ib.getDefense();
|
|
||||||
|
|
||||||
CharacterSkill armorSkill = this.skills.get(armor.template.item_skill_used);
|
|
||||||
if (armorSkill == null) {
|
|
||||||
Logger.error("Player " + this.getObjectUUID()
|
|
||||||
+ " has armor equipped without the nescessary skill to equip it");
|
|
||||||
return ib.getDefense();
|
|
||||||
}
|
|
||||||
|
|
||||||
float def = ib.getDefense();
|
|
||||||
//apply item defense bonuses
|
|
||||||
if (armor != null) {
|
|
||||||
def += armor.getBonus(ModType.DR, SourceType.NONE);
|
|
||||||
def *= (1 + armor.getBonusPercent(ModType.DR, SourceType.NONE));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return (def * (1 + ((int) armorSkill.getModifiedAmount() / 50f)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ Calculates Defense for weapon
|
|
||||||
*/
|
|
||||||
private float getWeaponDefense(ConcurrentHashMap<EquipSlotType, Item> equipped) {
|
|
||||||
Item weapon = equipped.get(EquipSlotType.RHELD);
|
|
||||||
ItemBase wb = null;
|
|
||||||
CharacterSkill skill, mastery;
|
|
||||||
float val = 0;
|
|
||||||
boolean unarmed = false;
|
|
||||||
if (weapon == null) {
|
|
||||||
weapon = equipped.get(EquipSlotType.LHELD);
|
|
||||||
if (weapon == null || ItemTemplate.isShield(weapon))
|
|
||||||
unarmed = true;
|
|
||||||
else
|
|
||||||
wb = weapon.getItemBase();
|
|
||||||
} else
|
|
||||||
wb = weapon.getItemBase();
|
|
||||||
if (wb == null)
|
|
||||||
unarmed = true;
|
|
||||||
if (unarmed) {
|
|
||||||
skill = this.skills.get("Unarmed Combat");
|
|
||||||
mastery = this.skills.get("Unarmed Combat Mastery");
|
|
||||||
} else {
|
|
||||||
skill = this.skills.get(weapon.template.item_skill_used);
|
|
||||||
mastery = this.skills.get(wb.getMastery());
|
|
||||||
}
|
|
||||||
if (skill != null)
|
|
||||||
val += (int) skill.getModifiedAmount() / 2f;
|
|
||||||
if (mastery != null)
|
|
||||||
val += (int) mastery.getModifiedAmount() / 2f;
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Call this function to recalculate granted skills and powers for player
|
//Call this function to recalculate granted skills and powers for player
|
||||||
public synchronized void calculateSkills() {
|
public synchronized void calculateSkills() {
|
||||||
//tell the player to applyBonuses because something has changed
|
//tell the player to applyBonuses because something has changed
|
||||||
|
|
||||||
runSkillCalc();
|
AbstractCharacter.runSkillCalc(this);
|
||||||
|
|
||||||
//start running the skill/power calculations
|
//start running the skill/power calculations
|
||||||
}
|
}
|
||||||
|
|
||||||
//Don't call this function directly. linked from pc.calculateSkills()
|
|
||||||
//through SkillCalcJob. Designed to only run from one worker thread
|
|
||||||
public void runSkillCalc() {
|
|
||||||
try {
|
|
||||||
|
|
||||||
//see if any new skills or powers granted
|
|
||||||
CharacterSkill.calculateSkills(this);
|
|
||||||
// calculate granted Trains in powers.
|
|
||||||
CharacterPower.grantTrains(this);
|
|
||||||
//see if any new powers unlocked from previous check
|
|
||||||
CharacterPower.calculatePowers(this);
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//calculate item bonuses here
|
|
||||||
public void calculateItemBonuses() {
|
|
||||||
if (this.charItemManager == null || this.bonuses == null)
|
|
||||||
return;
|
|
||||||
ConcurrentHashMap<EquipSlotType, Item> equipped = this.charItemManager.getEquipped();
|
|
||||||
for (Item item : equipped.values()) {
|
|
||||||
ItemBase ib = item.getItemBase();
|
|
||||||
if (ib == null)
|
|
||||||
continue;
|
|
||||||
//TODO add effect bonuses in here for equipped items
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ Defaults ATR, Defense and Damage for player
|
|
||||||
*/
|
|
||||||
private void defaultAtrAndDamage(boolean mainHand) {
|
|
||||||
if (mainHand) {
|
|
||||||
this.atrHandOne = 0;
|
|
||||||
this.minDamageHandOne = 0;
|
|
||||||
this.maxDamageHandOne = 0;
|
|
||||||
this.rangeHandOne = -1;
|
|
||||||
this.speedHandOne = 20;
|
|
||||||
} else {
|
|
||||||
this.atrHandTwo = 0;
|
|
||||||
this.minDamageHandTwo = 0;
|
|
||||||
this.maxDamageHandTwo = 0;
|
|
||||||
this.rangeHandTwo = -1;
|
|
||||||
this.speedHandTwo = 20;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void calculateMaxHealthManaStamina() {
|
public void calculateMaxHealthManaStamina() {
|
||||||
float h = 1f;
|
float h = 1f;
|
||||||
float m = 0f;
|
float m = 0f;
|
||||||
@@ -4431,36 +3959,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;
|
||||||
|
|
||||||
@@ -4475,40 +3973,6 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
return !this.isAlive();
|
return !this.isAlive();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ResetLevel(short targetLevel) {
|
|
||||||
|
|
||||||
if (targetLevel > 13) {
|
|
||||||
ChatManager.chatSystemError(this, "Please choose a level between 1 and 13.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.promotionClass = null;
|
|
||||||
if (targetLevel > 10) {
|
|
||||||
this.level = 10;
|
|
||||||
this.exp = Experience.getBaseExperience(11);
|
|
||||||
int maxEXP = Experience.getBaseExperience(targetLevel); //target level exp;
|
|
||||||
this.overFlowEXP = maxEXP - this.exp;
|
|
||||||
} else {
|
|
||||||
this.level = targetLevel;
|
|
||||||
this.exp = Experience.getBaseExperience(level);
|
|
||||||
this.overFlowEXP = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
for (CharacterSkill skill : this.getSkills().values()) {
|
|
||||||
skill.reset(this, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (CharacterPower power : this.getPowers().values()) {
|
|
||||||
power.reset(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.recalculatePlayerStats(initialized);
|
|
||||||
this.recalculate();
|
|
||||||
|
|
||||||
ChatManager.chatSystemInfo(this, "Character reset to " + targetLevel + ". All training points have been refunded. Relog to update changes on client.");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeFromCache() {
|
public void removeFromCache() {
|
||||||
Logger.info("Removing " + this.getName() + " from Object Cache.");
|
Logger.info("Removing " + this.getName() + " from Object Cache.");
|
||||||
@@ -4545,10 +4009,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()) {
|
||||||
@@ -4572,11 +4032,11 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
this.setBounds(playerBounds);
|
this.setBounds(playerBounds);
|
||||||
|
|
||||||
//assign enum values for restrictions
|
//assign enum values for restrictions
|
||||||
String race = this.getRace().getName().replace("-", "").replace(", Male", "").replace(", Female", "");
|
String race = this.race.getName().replace("-", "").replace(", Male", "").replace(", Female", "");
|
||||||
this.absRace = Enum.MonsterType.valueOf(race);
|
this.absRace = Enum.MonsterType.valueOf(race);
|
||||||
|
|
||||||
if (this.baseClass != null)
|
if (this.baseClass != null)
|
||||||
this.absBaseClass = ClassType.valueOf(this.getBaseClass().getName());
|
this.absBaseClass = ClassType.valueOf(this.baseClass.getName());
|
||||||
|
|
||||||
if (this.promotionClass != null)
|
if (this.promotionClass != null)
|
||||||
this.absPromotionClass = ClassType.valueOf(this.getPromotionClass().getName());
|
this.absPromotionClass = ClassType.valueOf(this.getPromotionClass().getName());
|
||||||
|
|||||||
@@ -53,12 +53,12 @@ public class PowerGrant extends AbstractGameObject {
|
|||||||
ArrayList<Integer> toks = new ArrayList<>();
|
ArrayList<Integer> toks = new ArrayList<>();
|
||||||
|
|
||||||
//get race ID
|
//get race ID
|
||||||
Race race = pc.getRace();
|
Race race = pc.race;
|
||||||
if (race != null)
|
if (race != null)
|
||||||
toks.add(race.getRaceRuneID());
|
toks.add(race.getRaceRuneID());
|
||||||
|
|
||||||
//get baseClass ID
|
//get baseClass ID
|
||||||
BaseClass bc = pc.getBaseClass();
|
BaseClass bc = pc.baseClass;
|
||||||
if (bc != null)
|
if (bc != null)
|
||||||
toks.add(bc.getObjectUUID());
|
toks.add(bc.getObjectUUID());
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user