Files
prestonbane/src/engine/objects/PlayerCombatStats.java
T

445 lines
17 KiB
Java
Raw Normal View History

2025-01-21 13:23:04 -06:00
package engine.objects;
import engine.Enum;
import engine.powers.effectmodifiers.AbstractEffectModifier;
import java.util.ArrayList;
import java.util.HashMap;
public class PlayerCombatStats {
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();
}
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;
}
2025-01-21 18:43:27 -06:00
float skillLevel = 5;
float masteryLevel = 5;
2025-01-21 13:23:04 -06:00
if(this.owner.skills.containsKey(skill))
2025-01-21 18:43:27 -06:00
skillLevel = this.owner.skills.get(skill).getTotalSkillPercet();
2025-01-21 13:23:04 -06:00
if(this.owner.skills.containsKey(mastery))
2025-01-21 18:43:27 -06:00
masteryLevel = this.owner.skills.get(mastery).getTotalSkillPercet();
2025-01-21 13:23:04 -06:00
2025-01-21 20:37:17 -06:00
float masteryCalc = masteryLevel * 3;
2025-01-21 13:23:04 -06:00
float primaryCalc = primary * 0.5f;
float skillCalc = skillLevel * 4;
2025-01-21 20:37:17 -06:00
2025-01-21 13:23:04 -06:00
float atrEnchants = 0;
float stanceValue = 0.0f;
for(String effID : this.owner.effects.keySet()){
if(effID.contains("Stance")){
2025-01-21 13:23:04 -06:00
for(AbstractEffectModifier mod : this.owner.effects.get(effID).getEffectModifiers()){
if(mod.modType.equals(Enum.ModType.OCV)){
float percent = mod.getPercentMod();
int trains = this.owner.effects.get(effID).getTrains();
float modValue = percent + (trains * mod.getRamp());
stanceValue += modValue * 0.01f;
2025-01-21 13:23:04 -06:00
}
}
}
}
if(this.owner.bonuses != null){
atrEnchants = this.owner.bonuses.getFloat(Enum.ModType.OCV, Enum.SourceType.None);
}
atr = primaryCalc + skillCalc + masteryCalc + atrEnchants;
2025-01-21 19:43:16 -06:00
atr *= 1 + (this.owner.bonuses.getFloatPercentAll(Enum.ModType.OCV, Enum.SourceType.None) - stanceValue);
2025-01-21 13:23:04 -06:00
atr *= 1 + stanceValue;
2025-01-21 21:07:17 -06:00
atr = (float) Math.ceil(atr);
2025-01-21 13:23:04 -06:00
if(mainHand){
this.atrHandOne = atr;
}else{
this.atrHandTwo = atr;
2025-01-21 18:43:27 -06:00
if(this.owner.charItemManager.getEquipped(1) == null && this.owner.charItemManager.getEquipped(2) != null){
2025-01-21 20:37:17 -06:00
if(!this.owner.charItemManager.getEquipped(2).getItemBase().isShield())
this.atrHandOne = 0.0f;
2025-01-21 18:43:27 -06:00
}
2025-01-21 13:23:04 -06:00
}
}
public void calculateMin(boolean mainHand) {
Item weapon;
2025-01-21 20:18:19 -06:00
float baseDMG = 1;
2025-01-21 13:23:04 -06:00
int primaryStat = this.owner.statDexCurrent;
int secondaryStat = this.owner.statStrCurrent;
2025-01-21 18:43:27 -06:00
double weaponSkill = 5;
double weaponMastery = 5;
2025-01-21 13:23:04 -06:00
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) {
2025-01-21 13:33:49 -06:00
baseDMG = weapon.getItemBase().getMinDamage();
2025-01-21 13:23:04 -06:00
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)) {
2025-01-21 20:18:19 -06:00
weaponSkill = this.owner.skills.get(skill).getTotalSkillPercet();
2025-01-21 13:23:04 -06:00
}
if (this.owner.skills.containsKey(mastery)) {
2025-01-21 20:18:19 -06:00
weaponMastery = this.owner.skills.get(mastery).getTotalSkillPercet();
2025-01-21 13:23:04 -06:00
}
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)
);
2025-01-21 19:51:59 -06:00
if(this.owner.bonuses != null){
minDMG += this.owner.bonuses.getFloat(Enum.ModType.MinDamage, Enum.SourceType.None);
2025-01-21 20:18:19 -06:00
minDMG *= 1 + this.owner.bonuses.getFloatPercentAll(Enum.ModType.MeleeDamageModifier, Enum.SourceType.None);
2025-01-21 19:51:59 -06:00
}
2025-01-21 20:18:19 -06:00
int roundedMin = (int)Math.round(minDMG);
2025-01-21 13:23:04 -06:00
if (mainHand) {
2025-01-21 20:18:19 -06:00
this.minDamageHandOne = roundedMin;
2025-01-21 13:23:04 -06:00
} else {
2025-01-21 20:18:19 -06:00
this.minDamageHandTwo = roundedMin;
2025-01-21 18:43:27 -06:00
if(this.owner.charItemManager.getEquipped(1) == null && this.owner.charItemManager.getEquipped(2) != null){
2025-01-21 20:37:17 -06:00
if(!this.owner.charItemManager.getEquipped(2).getItemBase().isShield())
this.minDamageHandOne = 0;
2025-01-21 18:43:27 -06:00
}
2025-01-21 13:23:04 -06:00
}
}
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;
2025-01-21 19:55:32 -06:00
double weaponSkill = 5;
double weaponMastery = 5;
2025-01-21 13:23:04 -06:00
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 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)
);
2025-01-21 19:51:59 -06:00
if(this.owner.bonuses != null){
maxDMG += this.owner.bonuses.getFloat(Enum.ModType.MaxDamage, Enum.SourceType.None);
2025-01-21 19:55:32 -06:00
maxDMG *= 1 + this.owner.bonuses.getFloatPercentAll(Enum.ModType.MeleeDamageModifier, Enum.SourceType.None);
2025-01-21 19:51:59 -06:00
}
2025-01-21 20:18:19 -06:00
int roundedMax = (int)Math.round(maxDMG);
2025-01-21 13:23:04 -06:00
if(mainHand){
2025-01-21 20:18:19 -06:00
this.maxDamageHandOne = roundedMax;
2025-01-21 13:23:04 -06:00
}else{
2025-01-21 20:18:19 -06:00
this.maxDamageHandTwo = roundedMax;
2025-01-21 18:43:27 -06:00
if(this.owner.charItemManager.getEquipped(1) == null && this.owner.charItemManager.getEquipped(2) != null){
2025-01-21 20:37:17 -06:00
if(!this.owner.charItemManager.getEquipped(2).getItemBase().isShield())
this.maxDamageHandOne = 0;
2025-01-21 18:43:27 -06:00
}
2025-01-21 13:23:04 -06:00
}
}
public void calculateAttackSpeed(boolean mainHand){
Item weapon;
float speed;
if(mainHand) {
weapon = this.owner.charItemManager.getEquipped(1);
}else {
weapon = this.owner.charItemManager.getEquipped(2);
}
2025-01-21 19:40:49 -06:00
float weaponSpecificValues = 0.0f;
2025-01-21 13:23:04 -06:00
if(weapon == null) {
speed = 20.0f;
}else{
speed = weapon.getItemBase().getSpeed();
for(Effect eff : weapon.effects.values()){
for(AbstractEffectModifier mod : eff.getEffectModifiers()){
2025-01-21 19:40:49 -06:00
if(mod.modType.equals(Enum.ModType.WeaponSpeed) || mod.modType.equals(Enum.ModType.AttackDelay)){
2025-01-21 13:23:04 -06:00
speed *= 1 + (mod.getPercentMod() * 0.01f);
2025-01-21 19:40:49 -06:00
weaponSpecificValues += (mod.getPercentMod() * 0.01f);
2025-01-21 13:23:04 -06:00
}
}
}
}
2025-01-21 13:33:49 -06:00
float stanceValue = 0.0f;
2025-01-21 13:23:04 -06:00
for(String effID : this.owner.effects.keySet()){
2025-01-21 18:43:27 -06:00
if(effID.contains("Stance")){
2025-01-21 19:40:49 -06:00
if(this.owner.effects != null) {
for (AbstractEffectModifier mod : this.owner.effects.get(effID).getEffectModifiers()) {
if (mod.modType.equals(Enum.ModType.AttackDelay)) {
float percent = mod.getPercentMod();
int trains = this.owner.effects.get(effID).getTrains();
float modValue = percent + (trains * mod.getRamp());
stanceValue += modValue * 0.01f;
}
2025-01-21 13:23:04 -06:00
}
}
}
}
2025-01-21 13:33:49 -06:00
float bonusValues = 1 + this.owner.bonuses.getFloatPercentAll(Enum.ModType.AttackDelay,Enum.SourceType.None);//1.0f;
2025-01-21 13:23:04 -06:00
2025-01-21 19:40:49 -06:00
bonusValues -= (stanceValue + weaponSpecificValues); // take away stance modifier from alac bonus values
2025-01-21 13:23:04 -06:00
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;
2025-01-21 18:43:27 -06:00
if(this.owner.charItemManager.getEquipped(1) == null && this.owner.charItemManager.getEquipped(2) != null){
2025-01-21 20:37:17 -06:00
if(!this.owner.charItemManager.getEquipped(2).getItemBase().isShield())
this.attackSpeedHandOne = 0.0f;
2025-01-21 18:43:27 -06:00
}
2025-01-21 13:23:04 -06:00
}
}
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;
2025-01-21 18:43:27 -06:00
if(this.owner.charItemManager.getEquipped(1) == null && this.owner.charItemManager.getEquipped(2) != null){
2025-01-21 20:37:17 -06:00
if(!this.owner.charItemManager.getEquipped(2).getItemBase().isShield())
this.rangeHandOne = 0.0f;
2025-01-21 18:43:27 -06:00
}
2025-01-21 13:23:04 -06:00
}
}
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;
}
}
2025-01-21 20:01:20 -06:00
public void calculateDefense() {
2025-01-21 13:23:04 -06:00
int armorDefense = 0;
int shieldDefense = 0;
int dexterity = this.owner.statDexCurrent;
double armorSkill = 0;
double blockSkill = 0;
double weaponSkill = 0;
double weaponMastery = 0;
//armor defense value need to loop all equipped items and log armor defense values
ArrayList<String> armorTypes = new ArrayList<>();
2025-01-21 20:01:20 -06:00
if (this.owner.charItemManager != null) {
for (Item equipped : this.owner.charItemManager.getEquippedList()) {
if (equipped.getItemBase().isHeavyArmor()) {
2025-01-21 13:23:04 -06:00
armorDefense += equipped.getItemBase().getDefense();
2025-01-21 20:01:20 -06:00
if (!armorTypes.contains(equipped.getItemBase().getSkillRequired()))
2025-01-21 13:23:04 -06:00
armorTypes.add(equipped.getItemBase().getSkillRequired());
2025-01-21 20:01:20 -06:00
} else if (equipped.getItemBase().isLightArmor()) {
2025-01-21 13:23:04 -06:00
armorDefense += equipped.getItemBase().getDefense();
2025-01-21 20:01:20 -06:00
if (!armorTypes.contains(equipped.getItemBase().getSkillRequired()))
2025-01-21 13:23:04 -06:00
armorTypes.add(equipped.getItemBase().getSkillRequired());
2025-01-21 20:01:20 -06:00
} else if (equipped.getItemBase().isMediumArmor()) {
2025-01-21 13:23:04 -06:00
armorDefense += equipped.getItemBase().getDefense();
2025-01-21 20:01:20 -06:00
if (!armorTypes.contains(equipped.getItemBase().getSkillRequired()))
2025-01-21 13:23:04 -06:00
armorTypes.add(equipped.getItemBase().getSkillRequired());
2025-01-21 20:01:20 -06:00
} else if (equipped.getItemBase().isClothArmor()) {
2025-01-21 13:23:04 -06:00
armorDefense += equipped.getItemBase().getDefense();
2025-01-21 20:01:20 -06:00
} else if (equipped.getItemBase().isShield()) {
2025-01-21 13:23:04 -06:00
shieldDefense += equipped.getItemBase().getDefense();
}
}
}
//armor skill needs to calculate all trains in armor types
2025-01-21 20:01:20 -06:00
for (String armorType : armorTypes) {
if (this.owner.skills != null) {
if (this.owner.skills.containsKey(armorType)) {
2025-01-21 13:23:04 -06:00
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);
2025-01-21 20:01:20 -06:00
if (weapon == null) {
2025-01-21 13:23:04 -06:00
weapon = this.owner.charItemManager.getEquipped(2);
}
2025-01-21 20:01:20 -06:00
if (weapon != null) {
2025-01-21 13:23:04 -06:00
primarySkillName = weapon.getItemBase().getSkillRequired();
primaryMasteryName = weapon.getItemBase().getMastery();
}
2025-01-21 20:01:20 -06:00
if (this.owner.skills != null) {
if (this.owner.skills.containsKey(primarySkillName)) {
2025-01-21 13:23:04 -06:00
weaponSkill = this.owner.skills.get(primarySkillName).getModifiedAmount();
}
2025-01-21 20:01:20 -06:00
if (this.owner.skills.containsKey(primaryMasteryName)) {
2025-01-21 13:23:04 -06:00
weaponMastery = this.owner.skills.get(primaryMasteryName).getModifiedAmount();
}
}
float stanceValue = 0.0f;
2025-01-21 20:01:20 -06:00
float bonusValues = 0;
float percentBonus = 0;
if (this.owner.bonuses != null) {
for (String effID : this.owner.effects.keySet()) {
if (effID.contains("Stance")) {
if (this.owner.effects != null) {
for (AbstractEffectModifier mod : this.owner.effects.get(effID).getEffectModifiers()) {
if (mod.modType.equals(Enum.ModType.DCV)) {
float percent = mod.getPercentMod();
int trains = this.owner.effects.get(effID).getTrains();
float modValue = percent + (trains * mod.getRamp());
stanceValue += modValue * 0.01f;
2025-01-21 20:01:20 -06:00
}
2025-01-21 13:23:04 -06:00
}
}
}
}
2025-01-21 20:01:20 -06:00
bonusValues = this.owner.bonuses.getFloat(Enum.ModType.DCV, Enum.SourceType.None);
percentBonus = this.owner.bonuses.getFloatPercentAll(Enum.ModType.DCV, Enum.SourceType.None) - stanceValue;
2025-01-21 13:23:04 -06:00
}
double defense = (1 + armorSkill / 50.0) * armorDefense +
(1 + blockSkill / 100.0) * shieldDefense +
(weaponSkill / 2.0) +
(weaponMastery / 2.0) +
dexterity * 2.0 +
2025-01-21 20:01:20 -06:00
bonusValues;
2025-01-21 20:24:15 -06:00
defense *= 1.0f + percentBonus + stanceValue;
//defense *= 1.0f + stanceValue;
defense = Math.round(defense);
2025-01-21 20:01:20 -06:00
this.defense = (int) defense;
2025-01-21 13:23:04 -06:00
}
}