376 lines
No EOL
15 KiB
C#
376 lines
No EOL
15 KiB
C#
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using WingsAPI.Data.Families;
|
|
using WingsEmu.Core.Extensions;
|
|
using WingsEmu.DTOs.BCards;
|
|
using WingsEmu.Game.Buffs;
|
|
using WingsEmu.Game.Mates;
|
|
using WingsEmu.Packets.Enums;
|
|
using WingsEmu.Packets.Enums.Battle;
|
|
|
|
namespace WingsEmu.Game.EntityStatistics;
|
|
|
|
public class MateStatisticsComponent : IMateStatisticsComponent
|
|
{
|
|
private readonly Dictionary<Statistics, int> _stats = new();
|
|
private IMateEntity _mateEntity;
|
|
|
|
public MateStatisticsComponent(IMateEntity mateEntity) => _mateEntity = mateEntity;
|
|
|
|
public int MinDamage => _mateEntity?.DamagesMinimum + _stats.GetValueOrDefault(Statistics.MIN_DAMAGE) ?? 0;
|
|
public int MaxDamage => _mateEntity?.DamagesMaximum + _stats.GetValueOrDefault(Statistics.MAX_DAMAGE) ?? 0;
|
|
public int HitRate => _mateEntity?.HitRate + _stats.GetValueOrDefault(Statistics.MIN_DAMAGE) ?? 0;
|
|
public int CriticalChance => _mateEntity?.HitCriticalChance + _stats.GetValueOrDefault(Statistics.CRITICAL_CHANCE) ?? 0;
|
|
public int CriticalDamage => _mateEntity?.HitCriticalDamage + _stats.GetValueOrDefault(Statistics.CRITICAL_DAMAGE) ?? 0;
|
|
public int MeleeDefense => _mateEntity?.CloseDefence + _stats.GetValueOrDefault(Statistics.MELEE_DEFENSE) ?? 0;
|
|
public int RangeDefense => _mateEntity?.DistanceDefence + _stats.GetValueOrDefault(Statistics.RANGE_DEFENSE) ?? 0;
|
|
public int MagicDefense => _mateEntity?.MagicDefence + _stats.GetValueOrDefault(Statistics.MAGIC_DEFENSE) ?? 0;
|
|
public int MeleeDodge => _mateEntity?.DefenceDodge + _stats.GetValueOrDefault(Statistics.MELEE_DODGE) ?? 0;
|
|
public int RangeDodge => _mateEntity?.DistanceDodge + _stats.GetValueOrDefault(Statistics.RANGE_DODGE) ?? 0;
|
|
public int FireResistance => _mateEntity?.FireResistance + _stats.GetValueOrDefault(Statistics.FIRE_RESISTANCE) ?? 0;
|
|
public int WaterResistance => _mateEntity?.WaterResistance + _stats.GetValueOrDefault(Statistics.WATER_RESISTANCE) ?? 0;
|
|
public int LightResistance => _mateEntity?.LightResistance + _stats.GetValueOrDefault(Statistics.LIGHT_RESISTANCE) ?? 0;
|
|
public int ShadowResistance => _mateEntity?.DarkResistance + _stats.GetValueOrDefault(Statistics.SHADOW_RESISTANCE) ?? 0;
|
|
|
|
public void RefreshMateStatistics(IMateEntity mateEntity)
|
|
{
|
|
_mateEntity = mateEntity;
|
|
if (_mateEntity.MateType == MateType.Pet)
|
|
{
|
|
return;
|
|
}
|
|
|
|
_stats.Clear();
|
|
int minDamage = 0;
|
|
int maxDamage = 0;
|
|
int hitRate = 0;
|
|
int criticalChance = 0;
|
|
int criticalDamage = 0;
|
|
int meleeDefense = 0;
|
|
int rangeDefense = 0;
|
|
int magicDefense = 0;
|
|
int meleeDodge = 0;
|
|
int rangeDodge = 0;
|
|
int fireResistance = 0;
|
|
int waterResistance = 0;
|
|
int lightResistance = 0;
|
|
int shadowResistance = 0;
|
|
|
|
AttackType attackType = _mateEntity.AttackType;
|
|
|
|
byte playerLevel = _mateEntity.Level;
|
|
|
|
IReadOnlyList<BCardDTO> bCards = _mateEntity.BCardComponent.GetAllBCards();
|
|
IEnumerable<BCardDTO> minMaxDamageBCards = bCards.Where(x => x.Type == (short)BCardType.AttackPower);
|
|
IEnumerable<BCardDTO> hitRateBCards = bCards.Where(x => x.Type == (short)BCardType.Target);
|
|
IEnumerable<BCardDTO> criticalBCards = bCards.Where(x => x.Type == (short)BCardType.Critical);
|
|
IEnumerable<BCardDTO> defenseBCards = bCards.Where(x => x.Type == (short)BCardType.Defence);
|
|
IEnumerable<BCardDTO> dodgeBCards = bCards.Where(x => x.Type == (short)BCardType.DodgeAndDefencePercent);
|
|
IEnumerable<BCardDTO> resistanceBCards = bCards.Where(x => x.Type == (short)BCardType.ElementResistance);
|
|
|
|
foreach (BCardDTO bCard in minMaxDamageBCards)
|
|
{
|
|
int firstData = bCard.FirstDataValue(playerLevel);
|
|
|
|
switch ((AdditionalTypes.AttackPower)bCard.SubType)
|
|
{
|
|
case AdditionalTypes.AttackPower.AllAttacksIncreased:
|
|
minDamage += firstData;
|
|
maxDamage += firstData;
|
|
break;
|
|
case AdditionalTypes.AttackPower.AllAttacksDecreased:
|
|
minDamage -= firstData;
|
|
maxDamage -= firstData;
|
|
break;
|
|
case AdditionalTypes.AttackPower.MeleeAttacksIncreased:
|
|
if (attackType != AttackType.Melee)
|
|
{
|
|
break;
|
|
}
|
|
|
|
minDamage += firstData;
|
|
maxDamage += firstData;
|
|
break;
|
|
case AdditionalTypes.AttackPower.MeleeAttacksDecreased:
|
|
if (attackType != AttackType.Melee)
|
|
{
|
|
break;
|
|
}
|
|
|
|
minDamage -= firstData;
|
|
maxDamage -= firstData;
|
|
break;
|
|
case AdditionalTypes.AttackPower.RangedAttacksIncreased:
|
|
if (attackType != AttackType.Ranged)
|
|
{
|
|
break;
|
|
}
|
|
|
|
minDamage += firstData;
|
|
maxDamage += firstData;
|
|
break;
|
|
case AdditionalTypes.AttackPower.RangedAttacksDecreased:
|
|
if (attackType != AttackType.Ranged)
|
|
{
|
|
break;
|
|
}
|
|
|
|
minDamage -= firstData;
|
|
maxDamage -= firstData;
|
|
break;
|
|
case AdditionalTypes.AttackPower.MagicalAttacksIncreased:
|
|
if (attackType != AttackType.Magical)
|
|
{
|
|
break;
|
|
}
|
|
|
|
minDamage += firstData;
|
|
maxDamage += firstData;
|
|
break;
|
|
case AdditionalTypes.AttackPower.MagicalAttacksDecreased:
|
|
if (attackType != AttackType.Magical)
|
|
{
|
|
break;
|
|
}
|
|
|
|
minDamage -= firstData;
|
|
maxDamage -= firstData;
|
|
break;
|
|
}
|
|
}
|
|
|
|
foreach (BCardDTO bCard in hitRateBCards)
|
|
{
|
|
int firstData = bCard.FirstDataValue(playerLevel);
|
|
switch ((AdditionalTypes.Target)bCard.SubType)
|
|
{
|
|
case AdditionalTypes.Target.AllHitRateIncreased:
|
|
hitRate += firstData;
|
|
break;
|
|
case AdditionalTypes.Target.AllHitRateDecreased:
|
|
hitRate -= firstData;
|
|
break;
|
|
case AdditionalTypes.Target.MeleeHitRateIncreased:
|
|
if (attackType != AttackType.Melee)
|
|
{
|
|
break;
|
|
}
|
|
|
|
hitRate += firstData;
|
|
break;
|
|
case AdditionalTypes.Target.MeleeHitRateDecreased:
|
|
if (attackType != AttackType.Melee)
|
|
{
|
|
break;
|
|
}
|
|
|
|
hitRate -= firstData;
|
|
break;
|
|
case AdditionalTypes.Target.RangedHitRateIncreased:
|
|
if (attackType != AttackType.Ranged)
|
|
{
|
|
break;
|
|
}
|
|
|
|
hitRate += firstData;
|
|
break;
|
|
case AdditionalTypes.Target.RangedHitRateDecreased:
|
|
if (attackType != AttackType.Ranged)
|
|
{
|
|
break;
|
|
}
|
|
|
|
hitRate -= firstData;
|
|
break;
|
|
case AdditionalTypes.Target.MagicalConcentrationIncreased:
|
|
if (attackType != AttackType.Magical)
|
|
{
|
|
break;
|
|
}
|
|
|
|
hitRate += firstData;
|
|
break;
|
|
case AdditionalTypes.Target.MagicalConcentrationDecreased:
|
|
if (attackType != AttackType.Magical)
|
|
{
|
|
break;
|
|
}
|
|
|
|
hitRate -= firstData;
|
|
break;
|
|
}
|
|
}
|
|
|
|
foreach (BCardDTO bCard in criticalBCards)
|
|
{
|
|
int firstData = bCard.FirstDataValue(playerLevel);
|
|
|
|
switch ((AdditionalTypes.Critical)bCard.SubType)
|
|
{
|
|
case AdditionalTypes.Critical.InflictingIncreased:
|
|
if (attackType == AttackType.Magical)
|
|
{
|
|
break;
|
|
}
|
|
|
|
criticalChance += firstData;
|
|
break;
|
|
case AdditionalTypes.Critical.InflictingReduced:
|
|
if (attackType == AttackType.Magical)
|
|
{
|
|
break;
|
|
}
|
|
|
|
criticalChance -= firstData;
|
|
break;
|
|
case AdditionalTypes.Critical.DamageIncreased:
|
|
if (attackType == AttackType.Magical)
|
|
{
|
|
break;
|
|
}
|
|
|
|
criticalDamage += firstData;
|
|
break;
|
|
case AdditionalTypes.Critical.DamageIncreasedInflictingReduced:
|
|
if (attackType == AttackType.Magical)
|
|
{
|
|
break;
|
|
}
|
|
|
|
criticalDamage -= firstData;
|
|
break;
|
|
}
|
|
}
|
|
|
|
foreach (BCardDTO bCard in defenseBCards)
|
|
{
|
|
int firstData = bCard.FirstDataValue(playerLevel);
|
|
|
|
switch ((AdditionalTypes.Defence)bCard.SubType)
|
|
{
|
|
case AdditionalTypes.Defence.AllIncreased:
|
|
meleeDefense += firstData;
|
|
rangeDefense += firstData;
|
|
magicDefense += firstData;
|
|
break;
|
|
case AdditionalTypes.Defence.AllDecreased:
|
|
meleeDefense -= firstData;
|
|
rangeDefense -= firstData;
|
|
magicDefense -= firstData;
|
|
break;
|
|
case AdditionalTypes.Defence.MeleeIncreased:
|
|
meleeDefense += firstData;
|
|
break;
|
|
case AdditionalTypes.Defence.MeleeDecreased:
|
|
meleeDefense -= firstData;
|
|
break;
|
|
case AdditionalTypes.Defence.RangedIncreased:
|
|
rangeDefense += firstData;
|
|
break;
|
|
case AdditionalTypes.Defence.RangedDecreased:
|
|
rangeDefense -= firstData;
|
|
break;
|
|
case AdditionalTypes.Defence.MagicalIncreased:
|
|
magicDefense += firstData;
|
|
break;
|
|
case AdditionalTypes.Defence.MagicalDecreased:
|
|
magicDefense -= firstData;
|
|
break;
|
|
}
|
|
}
|
|
|
|
foreach (BCardDTO bCard in dodgeBCards)
|
|
{
|
|
int firstData = bCard.FirstDataValue(playerLevel);
|
|
|
|
switch ((AdditionalTypes.DodgeAndDefencePercent)bCard.SubType)
|
|
{
|
|
case AdditionalTypes.DodgeAndDefencePercent.DodgeIncreased:
|
|
meleeDodge += firstData;
|
|
rangeDodge += firstData;
|
|
break;
|
|
case AdditionalTypes.DodgeAndDefencePercent.DodgeDecreased:
|
|
meleeDodge -= firstData;
|
|
rangeDodge -= firstData;
|
|
break;
|
|
case AdditionalTypes.DodgeAndDefencePercent.DodgingMeleeIncreased:
|
|
meleeDodge += firstData;
|
|
break;
|
|
case AdditionalTypes.DodgeAndDefencePercent.DodgingMeleeDecreased:
|
|
meleeDodge -= firstData;
|
|
break;
|
|
case AdditionalTypes.DodgeAndDefencePercent.DodgingRangedIncreased:
|
|
rangeDodge += firstData;
|
|
break;
|
|
case AdditionalTypes.DodgeAndDefencePercent.DodgingRangedDecreased:
|
|
rangeDodge -= firstData;
|
|
break;
|
|
}
|
|
}
|
|
|
|
foreach (BCardDTO bCard in resistanceBCards)
|
|
{
|
|
int firstData = bCard.FirstDataValue(playerLevel);
|
|
|
|
switch ((AdditionalTypes.ElementResistance)bCard.SubType)
|
|
{
|
|
case AdditionalTypes.ElementResistance.AllIncreased:
|
|
fireResistance += firstData;
|
|
waterResistance += firstData;
|
|
lightResistance += firstData;
|
|
shadowResistance += firstData;
|
|
break;
|
|
case AdditionalTypes.ElementResistance.AllDecreased:
|
|
fireResistance -= firstData;
|
|
waterResistance -= firstData;
|
|
lightResistance -= firstData;
|
|
shadowResistance -= firstData;
|
|
break;
|
|
case AdditionalTypes.ElementResistance.FireIncreased:
|
|
fireResistance += firstData;
|
|
break;
|
|
case AdditionalTypes.ElementResistance.FireDecreased:
|
|
fireResistance -= firstData;
|
|
break;
|
|
case AdditionalTypes.ElementResistance.WaterIncreased:
|
|
waterResistance += firstData;
|
|
break;
|
|
case AdditionalTypes.ElementResistance.WaterDecreased:
|
|
waterResistance -= firstData;
|
|
break;
|
|
case AdditionalTypes.ElementResistance.LightIncreased:
|
|
lightResistance += firstData;
|
|
break;
|
|
case AdditionalTypes.ElementResistance.LightDecreased:
|
|
lightResistance -= firstData;
|
|
break;
|
|
case AdditionalTypes.ElementResistance.DarkIncreased:
|
|
shadowResistance += firstData;
|
|
break;
|
|
case AdditionalTypes.ElementResistance.DarkDecreased:
|
|
shadowResistance -= firstData;
|
|
break;
|
|
}
|
|
}
|
|
|
|
fireResistance += _mateEntity.Owner?.Family?.UpgradeValues?.GetOrDefault(FamilyUpgradeType.FIRE_RESISTANCE) ?? 0;
|
|
waterResistance += _mateEntity.Owner?.Family?.UpgradeValues?.GetOrDefault(FamilyUpgradeType.WATER_RESISTANCE) ?? 0;
|
|
lightResistance += _mateEntity.Owner?.Family?.UpgradeValues?.GetOrDefault(FamilyUpgradeType.LIGHT_RESISTANCE) ?? 0;
|
|
shadowResistance += _mateEntity.Owner?.Family?.UpgradeValues?.GetOrDefault(FamilyUpgradeType.DARK_RESISTANCE) ?? 0;
|
|
|
|
_stats[Statistics.MIN_DAMAGE] = minDamage;
|
|
_stats[Statistics.MAX_DAMAGE] = maxDamage;
|
|
_stats[Statistics.HITRATE] = hitRate;
|
|
_stats[Statistics.CRITICAL_CHANCE] = criticalChance;
|
|
_stats[Statistics.CRITICAL_DAMAGE] = criticalDamage;
|
|
_stats[Statistics.MELEE_DEFENSE] = meleeDefense;
|
|
_stats[Statistics.RANGE_DEFENSE] = rangeDefense;
|
|
_stats[Statistics.MAGIC_DEFENSE] = magicDefense;
|
|
_stats[Statistics.MELEE_DODGE] = meleeDodge;
|
|
_stats[Statistics.RANGE_DODGE] = rangeDodge;
|
|
_stats[Statistics.FIRE_RESISTANCE] = fireResistance;
|
|
_stats[Statistics.WATER_RESISTANCE] = waterResistance;
|
|
_stats[Statistics.LIGHT_RESISTANCE] = lightResistance;
|
|
_stats[Statistics.SHADOW_RESISTANCE] = shadowResistance;
|
|
}
|
|
} |