server-master/srcs/WingsAPI.Game/EntityStatistics/MateStatisticsComponent.cs
2026-02-10 18:21:30 +01:00

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;
}
}