PlayerCombatStats object
This commit is contained in:
@@ -180,6 +180,8 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
|
||||
public boolean isBoxed = false;
|
||||
|
||||
public PlayerCombatStats combatStats;
|
||||
|
||||
/**
|
||||
* No Id Constructor
|
||||
*/
|
||||
@@ -5106,6 +5108,13 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
|
||||
}
|
||||
|
||||
|
||||
if(this.combatStats == null){
|
||||
this.combatStats = new PlayerCombatStats(this);
|
||||
}
|
||||
PlayerCombatStats cStats = this.combatStats;
|
||||
cStats.update();
|
||||
|
||||
} catch (Exception e) {
|
||||
Logger.error(e);
|
||||
} finally {
|
||||
|
||||
@@ -0,0 +1,405 @@
|
||||
package engine.objects;
|
||||
|
||||
import engine.Enum;
|
||||
import engine.powers.effectmodifiers.AbstractEffectModifier;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class PlayerCombatStats {
|
||||
public static HashMap<PlayerCharacter, PlayerCombatStats> combatstats = new HashMap<>();
|
||||
|
||||
public PlayerCharacter owner;
|
||||
//main hand data
|
||||
public int minDamageHandOne;
|
||||
public int maxDamageHandOne;
|
||||
public float attackSpeedHandOne;
|
||||
public float rangeHandOne;
|
||||
public float atrHandOne;
|
||||
//off hand data
|
||||
public int minDamageHandTwo;
|
||||
public int maxDamageHandTwo;
|
||||
public float attackSpeedHandTwo;
|
||||
public float rangeHandTwo;
|
||||
public float atrHandTwo;
|
||||
//defense
|
||||
public int defense;
|
||||
//regen rates
|
||||
public float healthRegen;
|
||||
public float manaRegen;
|
||||
public float staminaRegen;
|
||||
|
||||
public PlayerCombatStats(PlayerCharacter pc) {
|
||||
this.owner = pc;
|
||||
this.update();
|
||||
}
|
||||
|
||||
public void update() {
|
||||
this.calculateATR(true);
|
||||
this.calculateATR(false);
|
||||
this.calculateMin(true);
|
||||
this.calculateMin(false);
|
||||
this.calculateMax(true);
|
||||
this.calculateMax(false);
|
||||
this.calculateAttackSpeed(true);
|
||||
this.calculateAttackSpeed(false);
|
||||
this.calculateAttackRange(true);
|
||||
this.calculateAttackRange(false);
|
||||
this.calculateRegen();
|
||||
this.calculateDefense();
|
||||
combatstats.put(this.owner, this);
|
||||
}
|
||||
|
||||
public void calculateATR(boolean mainHand) {
|
||||
Item weapon;
|
||||
float atr;
|
||||
if(mainHand) {
|
||||
weapon = this.owner.charItemManager.getEquipped(1);
|
||||
}else {
|
||||
weapon = this.owner.charItemManager.getEquipped(2);
|
||||
}
|
||||
|
||||
String skill = "Unarmed Combat";
|
||||
String mastery = "Unarmed Combat Mastery";
|
||||
int primary = this.owner.statDexCurrent;
|
||||
if(weapon != null) {
|
||||
skill= weapon.getItemBase().getSkillRequired();
|
||||
mastery = weapon.getItemBase().getMastery();
|
||||
if(weapon.getItemBase().isStrBased())
|
||||
primary = this.owner.statStrCurrent;
|
||||
}
|
||||
|
||||
float skillLevel = 0;
|
||||
float masteryLevel = 0;
|
||||
|
||||
if(this.owner.skills.containsKey(skill))
|
||||
skillLevel = this.owner.skills.get(skill).getModifiedAmount();
|
||||
|
||||
if(this.owner.skills.containsKey(mastery))
|
||||
masteryLevel = this.owner.skills.get(mastery).getModifiedAmount();
|
||||
|
||||
float primaryCalc = primary * 0.5f;
|
||||
float skillCalc = skillLevel * 4;
|
||||
float masteryCalc = masteryLevel * 3;
|
||||
float atrEnchants = 0;
|
||||
float stanceValue = 0.0f;
|
||||
|
||||
for(String effID : this.owner.effects.keySet()){
|
||||
if(effID.contains("STC")){
|
||||
for(AbstractEffectModifier mod : this.owner.effects.get(effID).getEffectModifiers()){
|
||||
if(mod.modType.equals(Enum.ModType.AttackDelay)){
|
||||
stanceValue = mod.getPercentMod() * 0.01f; // account for weapon prefix and suffix mods
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(this.owner.bonuses != null){
|
||||
atrEnchants = this.owner.bonuses.getFloat(Enum.ModType.OCV, Enum.SourceType.None);
|
||||
}
|
||||
|
||||
atrEnchants -= stanceValue;
|
||||
|
||||
atr = primaryCalc + skillCalc + masteryCalc + atrEnchants;
|
||||
atr *= 1 + stanceValue;
|
||||
|
||||
if(mainHand){
|
||||
this.atrHandOne = atr;
|
||||
}else{
|
||||
this.atrHandTwo = atr;
|
||||
}
|
||||
}
|
||||
|
||||
public void calculateMin(boolean mainHand) {
|
||||
Item weapon;
|
||||
double baseDMG = 6;
|
||||
int primaryStat = this.owner.statDexCurrent;
|
||||
int secondaryStat = this.owner.statStrCurrent;
|
||||
double weaponSkill = 0;
|
||||
double weaponMastery = 0;
|
||||
|
||||
if (mainHand) {
|
||||
weapon = this.owner.charItemManager.getEquipped(1);
|
||||
} else {
|
||||
weapon = this.owner.charItemManager.getEquipped(2);
|
||||
}
|
||||
|
||||
String skill = "Unarmed Combat";
|
||||
String mastery = "Unarmed Combat Mastery";
|
||||
|
||||
if (weapon != null) {
|
||||
baseDMG = weapon.getItemBase().getMaxDamage();
|
||||
skill = weapon.getItemBase().getSkillRequired();
|
||||
mastery = weapon.getItemBase().getMastery();
|
||||
if (weapon.getItemBase().isStrBased()) {
|
||||
primaryStat = this.owner.statStrCurrent;
|
||||
secondaryStat = this.owner.statDexCurrent;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.owner.skills.containsKey(skill)) {
|
||||
weaponSkill = this.owner.skills.get(skill).getModifiedAmount();
|
||||
}
|
||||
|
||||
if (this.owner.skills.containsKey(mastery)) {
|
||||
weaponMastery = this.owner.skills.get(mastery).getModifiedAmount();
|
||||
}
|
||||
|
||||
double minDMG = baseDMG * (
|
||||
0.0048 * primaryStat +
|
||||
0.049 * Math.sqrt(primaryStat - 0.75) +
|
||||
0.0066 * secondaryStat +
|
||||
0.064 * Math.sqrt(secondaryStat - 0.75) +
|
||||
0.01 * (weaponSkill + weaponMastery)
|
||||
);
|
||||
|
||||
if (mainHand) {
|
||||
this.minDamageHandOne = (int) minDMG;
|
||||
} else {
|
||||
this.minDamageHandTwo = (int) minDMG;
|
||||
}
|
||||
}
|
||||
|
||||
public void calculateMax(boolean mainHand) {
|
||||
//Weapon Max DMG = BaseDMG * (0.0124*Primary Stat + 0.118*(Primary Stat -0.75)^0.5
|
||||
// + 0.0022*Secondary Stat + 0.028*(Secondary Stat-0.75)^0.5 + 0.0075*(Weapon Skill + Weapon Mastery))
|
||||
Item weapon;
|
||||
double baseDMG = 6;
|
||||
int primaryStat = this.owner.statDexCurrent;
|
||||
int secondaryStat = this.owner.statStrCurrent;
|
||||
double weaponSkill = 0;
|
||||
double weaponMastery = 0;
|
||||
|
||||
if (mainHand) {
|
||||
weapon = this.owner.charItemManager.getEquipped(1);
|
||||
} else {
|
||||
weapon = this.owner.charItemManager.getEquipped(2);
|
||||
}
|
||||
|
||||
String skill = "Unarmed Combat";
|
||||
String mastery = "Unarmed Combat Mastery";
|
||||
|
||||
if (weapon != null) {
|
||||
baseDMG = weapon.getItemBase().getMaxDamage();
|
||||
skill = weapon.getItemBase().getSkillRequired();
|
||||
mastery = weapon.getItemBase().getMastery();
|
||||
if (weapon.getItemBase().isStrBased()) {
|
||||
primaryStat = this.owner.statStrCurrent;
|
||||
secondaryStat = this.owner.statDexCurrent;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.owner.skills.containsKey(skill)) {
|
||||
weaponSkill = this.owner.skills.get(skill).getModifiedAmount();
|
||||
}else{
|
||||
|
||||
}
|
||||
|
||||
if (this.owner.skills.containsKey(mastery)) {
|
||||
weaponMastery = this.owner.skills.get(mastery).getModifiedAmount();
|
||||
}
|
||||
|
||||
double maxDMG = baseDMG * (
|
||||
0.0124 * primaryStat +
|
||||
0.118 * Math.sqrt(primaryStat - 0.75) +
|
||||
0.0022 * secondaryStat +
|
||||
0.028 * Math.sqrt(secondaryStat - 0.75) +
|
||||
0.0075 * (weaponSkill + weaponMastery)
|
||||
);
|
||||
|
||||
if(mainHand){
|
||||
this.maxDamageHandOne = (int) maxDMG;
|
||||
}else{
|
||||
this.maxDamageHandTwo = (int) maxDMG;
|
||||
}
|
||||
}
|
||||
|
||||
public void calculateAttackSpeed(boolean mainHand){
|
||||
Item weapon;
|
||||
float speed;
|
||||
if(mainHand) {
|
||||
weapon = this.owner.charItemManager.getEquipped(1);
|
||||
}else {
|
||||
weapon = this.owner.charItemManager.getEquipped(2);
|
||||
}
|
||||
|
||||
if(weapon == null) {
|
||||
speed = 20.0f;
|
||||
}else{
|
||||
speed = weapon.getItemBase().getSpeed();
|
||||
for(Effect eff : weapon.effects.values()){
|
||||
for(AbstractEffectModifier mod : eff.getEffectModifiers()){
|
||||
if(mod.modType.equals(Enum.ModType.WeaponProc)){
|
||||
speed *= 1 + (mod.getPercentMod() * 0.01f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float stanceValue = 1.0f;
|
||||
for(String effID : this.owner.effects.keySet()){
|
||||
if(effID.contains("STC")){
|
||||
for(AbstractEffectModifier mod : this.owner.effects.get(effID).getEffectModifiers()){
|
||||
if(mod.modType.equals(Enum.ModType.AttackDelay)){
|
||||
stanceValue = mod.getPercentMod() * 0.01f; // account for weapon prefix and suffix mods
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float bonusValues = 1.0f;
|
||||
if(this.owner.bonuses != null){
|
||||
for(AbstractEffectModifier mod : this.owner.bonuses.bonusFloats.keySet()){
|
||||
if(mod.modType.equals(Enum.ModType.AttackDelay)){
|
||||
bonusValues += mod.getPercentMod() * 0.01f; // calculate all alac bonuses
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bonusValues -= stanceValue; // take away stance modifier from alac bonus values
|
||||
speed *= 1 + stanceValue; // apply stance bonus
|
||||
speed *= bonusValues; // apply alac bonuses without stance mod
|
||||
|
||||
if(speed < 10.0f)
|
||||
speed = 10.0f;
|
||||
|
||||
if(mainHand){
|
||||
this.attackSpeedHandOne = speed;
|
||||
}else{
|
||||
this.attackSpeedHandTwo = speed;
|
||||
}
|
||||
}
|
||||
|
||||
public void calculateAttackRange(boolean mainHand){
|
||||
Item weapon;
|
||||
float range;
|
||||
if(mainHand) {
|
||||
weapon = this.owner.charItemManager.getEquipped(1);
|
||||
}else {
|
||||
weapon = this.owner.charItemManager.getEquipped(2);
|
||||
}
|
||||
|
||||
if(weapon == null) {
|
||||
range = 6.0f;
|
||||
}else{
|
||||
range = weapon.getItemBase().getRange();
|
||||
}
|
||||
if(owner.bonuses != null){
|
||||
range *= 1 + this.owner.bonuses.getFloatPercentAll(Enum.ModType.WeaponRange, Enum.SourceType.None);
|
||||
}
|
||||
if(mainHand){
|
||||
this.rangeHandOne = range;
|
||||
}else{
|
||||
this.rangeHandTwo = range;
|
||||
}
|
||||
}
|
||||
|
||||
public void calculateRegen(){
|
||||
if(owner.bonuses != null){
|
||||
this.healthRegen = 1.0f + this.owner.bonuses.getFloatPercentAll(Enum.ModType.HealthRecoverRate, Enum.SourceType.None);
|
||||
this.manaRegen = 1.0f + this.owner.bonuses.getFloatPercentAll(Enum.ModType.ManaRecoverRate, Enum.SourceType.None);
|
||||
this.staminaRegen = 1.0f + this.owner.bonuses.getFloatPercentAll(Enum.ModType.StaminaRecoverRate, Enum.SourceType.None);
|
||||
|
||||
}else{
|
||||
this.healthRegen = 1.0f;
|
||||
this.manaRegen = 1.0f;
|
||||
this.staminaRegen = 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
public void calculateDefense(){
|
||||
int armorDefense = 0;
|
||||
int shieldDefense = 0;
|
||||
int dexterity = this.owner.statDexCurrent;
|
||||
double armorSkill = 0;
|
||||
double blockSkill = 0;
|
||||
double weaponSkill = 0;
|
||||
double weaponMastery = 0;
|
||||
int flatBonuses = 0;
|
||||
|
||||
//armor defense value need to loop all equipped items and log armor defense values
|
||||
ArrayList<String> armorTypes = new ArrayList<>();
|
||||
if(this.owner.charItemManager != null){
|
||||
for(Item equipped : this.owner.charItemManager.getEquippedList()){
|
||||
if(equipped.getItemBase().isHeavyArmor()){
|
||||
armorDefense += equipped.getItemBase().getDefense();
|
||||
if(!armorTypes.contains(equipped.getItemBase().getSkillRequired()))
|
||||
armorTypes.add(equipped.getItemBase().getSkillRequired());
|
||||
} else if(equipped.getItemBase().isLightArmor()){
|
||||
armorDefense += equipped.getItemBase().getDefense();
|
||||
if(!armorTypes.contains(equipped.getItemBase().getSkillRequired()))
|
||||
armorTypes.add(equipped.getItemBase().getSkillRequired());
|
||||
} else if(equipped.getItemBase().isMediumArmor()){
|
||||
armorDefense += equipped.getItemBase().getDefense();
|
||||
if(!armorTypes.contains(equipped.getItemBase().getSkillRequired()))
|
||||
armorTypes.add(equipped.getItemBase().getSkillRequired());
|
||||
} else if(equipped.getItemBase().isClothArmor()){
|
||||
armorDefense += equipped.getItemBase().getDefense();
|
||||
}else if(equipped.getItemBase().isShield()){
|
||||
shieldDefense += equipped.getItemBase().getDefense();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//armor skill needs to calculate all trains in armor types
|
||||
for(String armorType : armorTypes){
|
||||
if(this.owner.skills!= null){
|
||||
if(this.owner.skills.containsKey(armorType)){
|
||||
armorSkill += this.owner.skills.get(armorType).getModifiedAmount();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (this.owner.skills.containsKey("Block")) {
|
||||
blockSkill = this.owner.skills.get("Block").getModifiedAmount();
|
||||
}
|
||||
|
||||
String primarySkillName = "Unarmed Combat";
|
||||
String primaryMasteryName = "Unarmed Combat Mastery";
|
||||
Item weapon = this.owner.charItemManager.getEquipped(1);
|
||||
if(weapon == null){
|
||||
weapon = this.owner.charItemManager.getEquipped(2);
|
||||
}
|
||||
if(weapon != null){
|
||||
primarySkillName = weapon.getItemBase().getSkillRequired();
|
||||
primaryMasteryName = weapon.getItemBase().getMastery();
|
||||
}
|
||||
|
||||
if(this.owner.skills != null){
|
||||
if(this.owner.skills.containsKey(primarySkillName)){
|
||||
weaponSkill = this.owner.skills.get(primarySkillName).getModifiedAmount();
|
||||
}
|
||||
if(this.owner.skills.containsKey(primaryMasteryName)){
|
||||
weaponMastery = this.owner.skills.get(primaryMasteryName).getModifiedAmount();
|
||||
}
|
||||
}
|
||||
|
||||
float stanceValue = 0.0f;
|
||||
if(this.owner.bonuses != null){
|
||||
for(String effID : this.owner.effects.keySet()){
|
||||
if(effID.contains("STC")){
|
||||
for(AbstractEffectModifier mod : this.owner.effects.get(effID).getEffectModifiers()){
|
||||
if(mod.modType.equals(Enum.ModType.AttackDelay)){
|
||||
stanceValue = mod.getPercentMod() * 0.01f; // account for weapon prefix and suffix mods
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float bonusValues = 1.0f + this.owner.bonuses.getFloat(Enum.ModType.DCV, Enum.SourceType.None);
|
||||
|
||||
bonusValues -= stanceValue; // take away stance modifier from alac bonus values
|
||||
flatBonuses += bonusValues; // apply alac bonuses without stance mod
|
||||
}
|
||||
|
||||
double defense = (1 + armorSkill / 50.0) * armorDefense +
|
||||
(1 + blockSkill / 100.0) * shieldDefense +
|
||||
(weaponSkill / 2.0) +
|
||||
(weaponMastery / 2.0) +
|
||||
dexterity * 2.0 +
|
||||
flatBonuses;
|
||||
|
||||
this.defense = (int) (defense * 1.0f + stanceValue);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user