forked from MagicBane/Server
				
			
				 2 changed files with 414 additions and 0 deletions
			
			
		| @ -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