forked from MagicBane/Server
				
			
				 2 changed files with 414 additions and 0 deletions
			
			
		| @ -0,0 +1,405 @@@@ -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); | ||||
|     } | ||||
| } | ||||
					Loading…
					
					
				
		Reference in new issue