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

856 lines
No EOL
29 KiB
C#

// WingsEmu
//
// Developed by NosWings Team
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using PhoenixLib.Events;
using WingsAPI.Data.Character;
using WingsAPI.Data.Miniland;
using WingsEmu.Core.Generics;
using WingsEmu.DTOs.Account;
using WingsEmu.DTOs.Bonus;
using WingsEmu.DTOs.Buffs;
using WingsEmu.DTOs.Inventory;
using WingsEmu.DTOs.Mates;
using WingsEmu.DTOs.Quests;
using WingsEmu.DTOs.Quicklist;
using WingsEmu.DTOs.Skills;
using WingsEmu.DTOs.Titles;
using WingsEmu.Game._enum;
using WingsEmu.Game.Algorithm;
using WingsEmu.Game.Battle;
using WingsEmu.Game.Battle.Managers;
using WingsEmu.Game.Buffs;
using WingsEmu.Game.Cheats;
using WingsEmu.Game.Entities;
using WingsEmu.Game.EntityStatistics;
using WingsEmu.Game.Exchange;
using WingsEmu.Game.Extensions;
using WingsEmu.Game.Families;
using WingsEmu.Game.Groups;
using WingsEmu.Game.Helpers.Damages;
using WingsEmu.Game.Inventory;
using WingsEmu.Game.Mails;
using WingsEmu.Game.Managers;
using WingsEmu.Game.Managers.StaticData;
using WingsEmu.Game.Maps;
using WingsEmu.Game.Mates;
using WingsEmu.Game.Networking;
using WingsEmu.Game.Portals;
using WingsEmu.Game.Quests;
using WingsEmu.Game.Quicklist;
using WingsEmu.Game.Raids;
using WingsEmu.Game.RainbowBattle;
using WingsEmu.Game.Relations;
using WingsEmu.Game.RespawnReturn;
using WingsEmu.Game.Revival;
using WingsEmu.Game.Shops;
using WingsEmu.Game.Skills;
using WingsEmu.Game.SnackFood;
using WingsEmu.Game.Specialists;
using WingsEmu.Game.TimeSpaces;
using WingsEmu.Game.Triggers;
using WingsEmu.Packets.Enums;
using WingsEmu.Packets.Enums.Character;
namespace WingsEmu.Game.Characters;
public partial class PlayerEntity : IPlayerEntity
{
private readonly IBattleEntityAlgorithmService _algorithm;
private readonly ICharacterAlgorithm _characterAlgorithm;
private readonly IAsyncEventPipeline _eventPipeline;
private readonly IFamilyManager _familyManager;
private readonly IFoodSnackComponentFactory _foodSnackComponentFactory;
private readonly IMapManager _mapManager;
private readonly IPortalFactory _portalFactory;
private readonly IRandomGenerator _randomGenerator;
public PlayerEntity(CharacterDTO characterDto, IFamilyManager familyManager, IRandomGenerator randomGenerator, IMapManager mapManager, ICharacterAlgorithm characterAlgorithm,
IFoodSnackComponentFactory foodSnackComponentFactory, IAsyncEventPipeline eventPipeline, IBattleEntityAlgorithmService algorithm, IPortalFactory portalFactory, IItemsManager itemsManager)
{
Id = (int)characterDto.Id;
Hp = characterDto.Hp;
Mp = characterDto.Mp;
Level = characterDto.Level;
Faction = characterDto.Faction;
AccountId = characterDto.AccountId;
Act4Dead = characterDto.Act4Dead;
Act4Kill = characterDto.Act4Kill;
Act4Points = characterDto.Act4Points;
ArenaWinner = characterDto.ArenaWinner;
Biography = characterDto.Biography;
BuffBlocked = characterDto.BuffBlocked;
Class = characterDto.Class;
Compliment = characterDto.Compliment;
Dignity = characterDto.Dignity;
EmoticonsBlocked = characterDto.EmoticonsBlocked;
ExchangeBlocked = characterDto.ExchangeBlocked;
FamilyRequestBlocked = characterDto.FamilyRequestBlocked;
FriendRequestBlocked = characterDto.FriendRequestBlocked;
Gender = characterDto.Gender;
Gold = characterDto.Gold;
GroupRequestBlocked = characterDto.GroupRequestBlocked;
HairColor = characterDto.HairColor;
HairStyle = characterDto.HairStyle;
HeroChatBlocked = characterDto.HeroChatBlocked;
HeroLevel = characterDto.HeroLevel;
HeroXp = characterDto.HeroXp;
HpBlocked = characterDto.HpBlocked;
IsPetAutoRelive = characterDto.IsPetAutoRelive;
IsPartnerAutoRelive = characterDto.IsPartnerAutoRelive;
JobLevel = characterDto.JobLevel;
JobLevelXp = characterDto.JobLevelXp;
LevelXp = characterDto.LevelXp;
MapId = characterDto.MapId;
MapX = characterDto.MapX;
MapY = characterDto.MapY;
MasterPoints = characterDto.MasterPoints;
MasterTicket = characterDto.MasterTicket;
MaxPetCount = characterDto.MaxPetCount;
MaxPartnerCount = characterDto.MaxPartnerCount;
MinilandInviteBlocked = characterDto.MinilandInviteBlocked;
MinilandMessage = characterDto.MinilandMessage;
MinilandPoint = characterDto.MinilandPoint;
MinilandState = characterDto.MinilandState;
MouseAimLock = characterDto.MouseAimLock;
Name = characterDto.Name;
QuickGetUp = characterDto.QuickGetUp;
HideHat = characterDto.HideHat;
UiBlocked = characterDto.UiBlocked;
Reput = characterDto.Reput;
Slot = characterDto.Slot;
SpPointsBonus = characterDto.SpPointsBonus;
SpPointsBasic = characterDto.SpPointsBasic;
TalentLose = characterDto.TalentLose;
TalentSurrender = characterDto.TalentSurrender;
TalentWin = characterDto.TalentWin;
WhisperBlocked = characterDto.WhisperBlocked;
PartnerInventory = characterDto.PartnerInventory;
NosMates = characterDto.NosMates;
PartnerWarehouse = characterDto.PartnerWarehouse;
Bonus = characterDto.Bonus;
StaticBuffs = characterDto.StaticBuffs;
Quicklist = characterDto.Quicklist;
LearnedSkills = characterDto.LearnedSkills;
Titles = characterDto.Titles;
CompletedScripts = characterDto.CompletedScripts;
CompletedQuests = characterDto.CompletedQuests;
CompletedPeriodicQuests = characterDto.CompletedPeriodicQuests;
ActiveQuests = characterDto.ActiveQuests;
CompletedTimeSpaces = characterDto.CompletedTimeSpaces;
MinilandObjects = characterDto.MinilandObjects;
Inventory = characterDto.Inventory;
EquippedStuffs = characterDto.EquippedStuffs;
LifetimeStats = characterDto.LifetimeStats;
RaidRestrictionDto = characterDto.RaidRestrictionDto;
RainbowBattleLeaverBusterDto = characterDto.RainbowBattleLeaverBusterDto;
_familyManager = familyManager;
_randomGenerator = randomGenerator;
_mapManager = mapManager;
_characterAlgorithm = characterAlgorithm;
_foodSnackComponentFactory = foodSnackComponentFactory;
_eventPipeline = eventPipeline;
_algorithm = algorithm;
_portalFactory = portalFactory;
_raidComponent = new RaidComponent();
TimeSpaceComponent = new TimeSpaceComponent();
_familyComponent = new FamilyComponent(_familyManager);
_inventory = new InventoryComponent(this, itemsManager);
_exchange = new ExchangeComponent();
_characterRevivalComponent = new CharacterRevivalComponent();
_groupComponent = new GroupComponent();
_relationComponent = new RelationComponent();
_eventTriggerContainer = new EventTriggerContainer(_eventPipeline);
BCardComponent = new BCardComponent(_randomGenerator);
_questContainer = new BasicQuestContainer();
BuffComponent = new BuffComponent();
_eqOptions = new EquipmentOptionContainer();
_comboSkillComponent = new ComboSkillComponent();
_bubbleComponent = new BubbleComponent();
_partnerInventory = new PartnerInventoryComponent(this);
_castingComponent = new CastingComponent();
_skillCooldownComponent = new SkillCooldownComponent();
_chargeComponent = new ChargeComponent();
_angelElementBuffComponent = new AngelElementBuffComponent();
_endBuffDamageComponent = new EndBuffDamageComponent();
_scoutComponent = new ScoutComponent();
QuicklistComponent = new QuicklistComponent();
_foodSnackComponent = _foodSnackComponentFactory.CreateFoodSnackComponent();
HomeComponent = new HomeComponent(characterDto.ReturnPoint);
MateComponent = new MateComponent();
WildKeeperComponent = new WildKeeperComponent();
SkillComponent = new SkillComponent();
CheatComponent = new CheatComponent();
SpecialistComponent = new SpecialistStatsComponent(this);
StatisticsComponent = new PlayerStatisticsComponent(this);
ChargeComponent = new ChargeComponent();
ShopComponent = new ShopComponent();
MailNoteComponent = new MailNoteComponent();
RainbowBattleComponent = new RainbowBattleComponent();
RefreshCharacterStats();
Killer = null;
SpCooldownEnd = null;
LastWalk = new LastWalk
{
MapId = null
};
LastDefence = DateTime.MinValue;
LastItemUpgrade = DateTime.MinValue;
LastHealth = DateTime.MinValue;
LastSkillUse = DateTime.MinValue;
LastEffect = DateTime.MinValue;
LastDayNight = DateTime.MinValue;
Bubble = DateTime.MinValue;
ItemsToRemove = DateTime.UtcNow;
LastPulseTick = DateTime.UtcNow;
LastAdministrationBazaarRefresh = DateTime.UtcNow;
LastBuySearchBazaarRefresh = DateTime.UtcNow;
LastListItemBazaar = DateTime.UtcNow;
Session = null;
Skills = new List<IBattleEntitySkill>();
}
public DateTime LastDivinePotion { get; set; }
public DateTime? GrowthShield { get; set; }
public int AdditionalHp { get; set; }
public int AdditionalMp { get; set; }
public int Hp { get; set; }
public int MaxHp { get; set; }
public int Mp { get; set; }
public int MaxMp { get; set; }
public bool TriggerAmbush { get; set; }
public DateTime LastMapChange { get; set; }
public DateTime? LastSkillCombo { get; set; }
public AuthorityType Authority { get; set; }
public int CurrentMinigame { get; set; }
public byte Level { get; set; }
public byte Direction { get; set; } = 2;
public int DamagesMinimum
{
get => GetDamagesMinimum(true);
set { }
}
public int DamagesMaximum
{
get => GetDamagesMaximum(true);
set { }
}
public int SecondDamageMinimum => GetDamagesMinimum(false);
public int SecondDamageMaximum => GetDamagesMaximum(false);
public int HitRate => GetHitRate(true);
public int HitCriticalChance => GetCriticalChance(true);
public int HitCriticalDamage => GetCriticalDamage(true);
public int SecondHitRate => GetHitRate(false);
public int SecondHitCriticalChance => GetCriticalChance(false);
public int SecondHitCriticalDamage => GetCriticalDamage(false);
public int MeleeDefence => this.GetDefence(_meleeDefense, StatisticType.DEFENSE_MELEE);
public int RangedDefence => this.GetDefence(_rangedDefense, StatisticType.DEFENSE_RANGED);
public int MagicDefence => this.GetDefence(_magicDefense, StatisticType.DEFENSE_MAGIC);
public int MeleeDodge => this.GetDodge(_meleeDodge, StatisticType.DODGE_MELEE);
public int RangedDodge => this.GetDodge(_rangedDodge, StatisticType.DODGE_RANGED);
public byte Element
{
get
{
if (Fairy == null || Fairy.GameItem.Element == (byte)ElementType.All)
{
return 0;
}
return (byte)Fairy?.GameItem.Element;
}
set { }
}
public int ElementRate
{
get => this.GetElement(false);
set { }
}
public int SpecialistElementRate => this.GetElement(true);
public int FireResistance
{
get => this.GetResistance(StatisticType.FIRE);
set { }
}
public int WaterResistance
{
get => this.GetResistance(StatisticType.WATER);
set { }
}
public int LightResistance
{
get => this.GetResistance(StatisticType.LIGHT);
set { }
}
public int DarkResistance
{
get => this.GetResistance(StatisticType.DARK);
set { }
}
public DateTime GameStartDate { get; set; }
public bool HasShopOpened { get; set; }
public bool Invisible => this.IsInvisible();
public bool IsCustomSpeed { get; set; }
public bool IsShopping { get; set; }
public bool IsSitting { get; set; }
public bool IsOnVehicle { get; set; }
public bool IsMorphed { get; set; }
public (VisualType, long) LastEntity { get; set; }
public DateTime? RandomMapTeleport { get; set; }
public DateTime LastMove { get; set; }
public DateTime LastPutItem { get; set; }
public DateTime LastSentNote { get; set; }
public DateTime? CheckWeedingBuff { get; set; }
public DateTime LastPvPAttack { get; set; }
public DateTime LastRainbowArrowEffect { get; set; }
public DateTime LastRainbowEffects { get; set; }
public LastWalk LastWalk { get; set; }
public int LastNRunId { get; set; }
public int LastPulse { get; set; }
public DateTime LastPulseTick { get; set; }
public DateTime LastDefence { get; set; }
public DateTime LastItemUpgrade { get; set; }
public DateTime LastDeath { get; set; }
public DateTime LastEffect { get; set; }
public DateTime LastEffectMinigame { get; set; }
public DateTime LastHealth { get; set; }
public DateTime LastPortal { get; set; }
public DateTime LastPotion { get; set; }
public DateTime LastSnack { get; set; }
public DateTime LastFood { get; set; }
public DateTime LastSkillUse { get; set; }
public DateTime LastSpeedChange { get; set; }
public DateTime LastTransform { get; set; }
public DateTime LastDayNight { get; set; }
public DateTime? SpCooldownEnd { get; set; }
public DateTime Bubble { get; set; }
public DateTime SpyOutStart { get; set; }
public DateTime ItemsToRemove { get; set; }
public DateTime BonusesToRemove { get; set; }
public IMapInstance MapInstance => _mapManager.GetMapInstance(MapInstanceId);
public Guid MapInstanceId { get; set; }
public IMapInstance Miniland { get; set; }
public int Morph { get; set; }
public int MorphUpgrade { get; set; }
public int MorphUpgrade2 { get; set; }
public int? LastMinilandProducedItem { get; set; }
public bool IsGettingLosingReputation { get; set; }
public byte DeathsOnAct4 { get; set; }
public long ArenaKills { get; set; }
public long ArenaDeaths { get; set; }
public TimeSpan? MuteRemainingTime { get; set; }
public DateTime LastMuteTick { get; set; }
public DateTime LastSitting { get; set; }
public DateTime? LastChatMuteMessage { get; set; }
public DateTime LastInventorySort { get; set; }
public DateTime? ArenaImmunity { get; set; }
public Position Position
{
get => new(PositionX, PositionY);
set
{
Position pos = value;
PositionX = pos.X;
PositionY = pos.Y;
}
}
public short PositionX { get; set; }
public short PositionY { get; set; }
public FactionType Faction { get; private set; }
public IClientSession Session { get; private set; }
public byte Size { get; set; } = 10;
public List<IBattleEntitySkill> Skills { get; set; }
public IChargeComponent ChargeComponent { get; }
public ThreadSafeHashSet<Guid> AggroedEntities { get; } = new();
public ConcurrentDictionary<int, CharacterSkill> CharacterSkills { get; } = new();
public ConcurrentDictionary<int, CharacterSkill> SkillsSp { get; set; }
public byte Speed
{
get => _speed;
set
{
LastSpeedChange = DateTime.UtcNow;
_speed = value > 59 ? (byte)59 : value;
}
}
public IBattleEntity Killer { get; set; }
public void AddStaticBonus(CharacterStaticBonusDto bonus) => Bonus.Add(bonus);
public void AddStaticBonuses(IEnumerable<CharacterStaticBonusDto> bonuses) => Bonus.AddRange(bonuses);
public IReadOnlyList<CharacterStaticBonusDto> GetStaticBonuses() => Bonus;
public CharacterStaticBonusDto GetStaticBonus(Predicate<CharacterStaticBonusDto> predicate)
{
return Bonus.FirstOrDefault(x => predicate(x));
}
public ConcurrentDictionary<long, int> HitsByMonsters { get; } = new();
public bool UseSp { get; set; }
public byte VehicleSpeed { get; set; }
public byte VehicleMapSpeed { get; set; }
public int WareHouseSize { get; set; }
public DateTime LastBuySearchBazaarRefresh { get; set; }
public DateTime LastBuyBazaarRefresh { get; set; }
public DateTime LastListItemBazaar { get; set; }
public DateTime LastAdministrationBazaarRefresh { get; set; }
public DateTime LastMonsterCaught { get; set; }
public bool IsSeal { get; set; }
public bool IsRemovingSpecialistPoints { get; set; }
public VisualType Type => VisualType.Player;
public int Id { get; }
public long AccountId { get; set; }
public int Act4Dead { get; set; }
public int Act4Kill { get; set; }
public int Act4Points { get; set; }
public int ArenaWinner { get; set; }
public string Biography { get; set; }
public bool BuffBlocked { get; set; }
public bool ShowRaidDeathInfo { get; set; }
public ClassType Class { get; set; }
public short Compliment { get; set; }
public float Dignity { get; set; }
public bool EmoticonsBlocked { get; set; }
public bool ExchangeBlocked { get; set; }
public bool FamilyRequestBlocked { get; set; }
public bool FriendRequestBlocked { get; set; }
public GenderType Gender { get; set; }
public long Gold { get; set; }
public bool GroupRequestBlocked { get; set; }
public HairColorType HairColor { get; set; }
public HairStyleType HairStyle { get; set; }
public bool HeroChatBlocked { get; set; }
public byte HeroLevel { get; set; }
public long HeroXp { get; set; }
public bool HpBlocked { get; set; }
public bool IsPetAutoRelive { get; set; }
public bool IsPartnerAutoRelive { get; set; }
public byte JobLevel { get; set; }
public long JobLevelXp { get; set; }
public long LevelXp { get; set; }
public int MapId { get; set; }
public short MapX { get; set; }
public short MapY { get; set; }
public int MasterPoints { get; set; }
public int MasterTicket { get; set; }
public byte MaxPetCount { get; set; }
public byte MaxPartnerCount { get; set; }
public bool MinilandInviteBlocked { get; set; }
public string MinilandMessage { get; set; }
public short MinilandPoint { get; set; }
public MinilandState MinilandState { get; set; }
public bool MouseAimLock { get; set; }
public string Name { get; set; }
public bool QuickGetUp { get; set; }
public bool HideHat { get; set; }
public bool UiBlocked { get; set; }
public long Reput { get; set; }
public byte Slot { get; set; }
public int SpPointsBonus { get; set; }
public int SpPointsBasic { get; set; }
public int TalentLose { get; set; }
public int TalentSurrender { get; set; }
public int TalentWin { get; set; }
public bool WhisperBlocked { get; set; }
public List<CharacterPartnerInventoryItemDto> PartnerInventory { get; set; }
public List<MateDTO> NosMates { get; set; }
public HashSet<long> CompletedTimeSpaces { get; set; }
public List<PartnerWarehouseItemDto> PartnerWarehouse { get; set; }
public List<CharacterStaticBonusDto> Bonus { get; set; }
public List<CharacterStaticBuffDto> StaticBuffs { get; set; }
public List<CharacterQuicklistEntryDto> Quicklist { get; set; }
public List<CharacterSkillDTO> LearnedSkills { get; set; }
public List<CharacterTitleDto> Titles { get; set; }
public List<CompletedScriptsDto> CompletedScripts { get; set; }
public List<CharacterQuestDto> CompletedQuests { get; set; }
public List<CharacterQuestDto> CompletedPeriodicQuests { get; set; }
public List<CharacterQuestDto> ActiveQuests { get; set; }
public List<CharacterMinilandObjectDto> MinilandObjects { get; set; }
public List<CharacterInventoryItemDto> Inventory { get; set; }
public List<CharacterInventoryItemDto> EquippedStuffs { get; set; }
public CharacterLifetimeStatsDto LifetimeStats { get; set; }
public CharacterRaidRestrictionDto RaidRestrictionDto { get; set; }
public RainbowBattleLeaverBusterDto RainbowBattleLeaverBusterDto { get; set; }
public bool HasBuff(BuffVnums buffVnum) => BuffComponent.HasBuff((short)buffVnum);
public void SetFaction(FactionType faction)
{
Faction = faction;
}
public void AddEvent(string trigger, IAsyncEvent notification, bool removeOnTrigger = false)
{
_eventTriggerContainer.AddEvent(trigger, notification, removeOnTrigger);
}
public async Task TriggerEvents(string key) => await _eventTriggerContainer.TriggerEvents(key);
public async Task EmitEventAsync<T>(T eventArgs) where T : IBattleEntityEvent
{
if (eventArgs.Entity != this)
{
throw new ArgumentException("An event should be emitted only from the event sender");
}
await _eventPipeline.ProcessEventAsync(eventArgs);
}
public void EmitEvent<T>(T eventArgs) where T : IBattleEntityEvent
{
EmitEventAsync(eventArgs).ConfigureAwait(false).GetAwaiter().GetResult();
}
public bool HasCompletedQuest(int questId) => _questContainer.HasCompletedQuest(questId);
public void RemoveCompletedQuest(int questId) => _questContainer.RemoveCompletedQuest(questId);
public void RemoveCompletedScript(int scriptId, int scriptIndex) => _questContainer.RemoveCompletedScript(scriptId, scriptIndex);
public void RemoveAllCompletedScripts() => _questContainer.RemoveAllCompletedScripts();
public void ClearCompletedPeriodicQuests() => _questContainer.ClearCompletedPeriodicQuests();
public IHomeComponent HomeComponent { get; }
public ICheatComponent CheatComponent { get; }
protected bool Equals(IPlayerEntity other) => Id == other.Id && Type == other.Type;
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj))
{
return false;
}
if (ReferenceEquals(this, obj))
{
return true;
}
return obj.GetType() == GetType() && Equals((IPlayerEntity)obj);
}
public override int GetHashCode()
{
unchecked
{
return Id.GetHashCode() * 397 ^ Type.GetHashCode();
}
}
#region Methods
private int GetDamagesMinimum(bool isMainWeapon)
{
return Class switch
{
ClassType.Swordman => this.GetDamage(isMainWeapon ? _meleeDamageMin : _rangedDamageMin, true, isMainWeapon ? StatisticType.ATTACK_MELEE : StatisticType.ATTACK_RANGED, isMainWeapon),
ClassType.Wrestler => this.GetDamage(isMainWeapon ? _meleeDamageMax : _rangedDamageMax, true, isMainWeapon ? StatisticType.ATTACK_MELEE : StatisticType.ATTACK_RANGED, isMainWeapon),
ClassType.Adventurer => this.GetDamage(isMainWeapon ? _meleeDamageMin : _rangedDamageMin, true, isMainWeapon ? StatisticType.ATTACK_MELEE : StatisticType.ATTACK_RANGED, isMainWeapon),
ClassType.Archer => this.GetDamage(isMainWeapon ? _rangedDamageMin : _meleeDamageMin, true, isMainWeapon ? StatisticType.ATTACK_RANGED : StatisticType.ATTACK_MELEE, isMainWeapon),
ClassType.Magician => this.GetDamage(isMainWeapon ? _magicDamageMin : _rangedDamageMin, true, isMainWeapon ? StatisticType.ATTACK_MAGIC : StatisticType.ATTACK_RANGED, isMainWeapon)
};
}
private int GetHitRate(bool isMainWeapon)
{
int hitRate = 0;
if (Class == ClassType.Magician && isMainWeapon)
{
return this.GetHitRate(0, true, StatisticType.HITRATE_MAGIC);
}
if (isMainWeapon)
{
switch (Class)
{
case ClassType.Swordman:
case ClassType.Wrestler:
case ClassType.Adventurer:
hitRate = this.GetHitRate(_meleeHitRate, true, StatisticType.HITRATE_MELEE);
break;
case ClassType.Archer:
hitRate = this.GetHitRate(_rangedHitRate, true, StatisticType.HITRATE_RANGED);
break;
}
}
else
{
switch (Class)
{
case ClassType.Wrestler:
case ClassType.Archer:
case ClassType.Adventurer:
hitRate = this.GetHitRate(_meleeHitRate, false, StatisticType.HITRATE_MELEE);
break;
case ClassType.Magician:
case ClassType.Swordman:
hitRate = this.GetHitRate(_rangedHitRate, false, StatisticType.HITRATE_RANGED);
break;
}
}
return hitRate;
}
private int GetCriticalChance(bool isMainWeapon)
{
if (Class == ClassType.Magician && isMainWeapon)
{
return 0;
}
return this.GetCriticalChance(_criticalChance, isMainWeapon);
}
private int GetCriticalDamage(bool isMainWeapon)
{
if (Class == ClassType.Magician && isMainWeapon)
{
return 0;
}
return this.GetCriticalDamage(_criticalDamage, isMainWeapon);
}
private int GetDamagesMaximum(bool isMainWeapon)
{
return Class switch
{
ClassType.Swordman =>
this.GetDamage(isMainWeapon ? _meleeDamageMax : _rangedDamageMax, false, isMainWeapon ? StatisticType.ATTACK_MELEE : StatisticType.ATTACK_RANGED, isMainWeapon),
ClassType.Wrestler =>
this.GetDamage(isMainWeapon ? _meleeDamageMax : _rangedDamageMax, false, isMainWeapon ? StatisticType.ATTACK_MELEE : StatisticType.ATTACK_RANGED, isMainWeapon),
ClassType.Adventurer =>
this.GetDamage(isMainWeapon ? _meleeDamageMax : _rangedDamageMax, false, isMainWeapon ? StatisticType.ATTACK_MELEE : StatisticType.ATTACK_RANGED, isMainWeapon),
ClassType.Archer =>
this.GetDamage(isMainWeapon ? _rangedDamageMax : _meleeDamageMax, false, isMainWeapon ? StatisticType.ATTACK_RANGED : StatisticType.ATTACK_MELEE, isMainWeapon),
ClassType.Magician =>
this.GetDamage(isMainWeapon ? _magicDamageMax : _rangedDamageMax, false, isMainWeapon ? StatisticType.ATTACK_MAGIC : StatisticType.ATTACK_RANGED, isMainWeapon)
};
}
public bool IsCraftingItem { get; set; }
public bool IsBankOpen { get; set; }
public DateTime LastUnfreezedPlayer { get; set; }
public DateTime LastSpPacketSent { get; set; }
public DateTime LastSpRemovingProcess { get; set; }
public DateTime LastSpPointProcess { get; set; }
public DateTime LastAttack { get; set; }
public bool InitialScpPacketSent { get; set; }
public IQuicklistComponent QuicklistComponent { get; }
public ISpecialistStatsComponent SpecialistComponent { get; }
public IPlayerStatisticsComponent StatisticsComponent { get; }
public IRainbowBattleComponent RainbowBattleComponent { get; }
public int GetCp()
{
int cpMax = (Class > 0 ? 40 : 0) + JobLevel * 2;
int cpUsed = 0;
foreach (CharacterSkill skill in CharacterSkills.Values)
{
if (skill == null)
{
continue;
}
if (skill.Skill.IsPassiveSkill())
{
continue;
}
cpUsed += skill.Skill.CPCost;
}
return cpMax - cpUsed;
}
public int GetDignityIco()
{
int icoDignity = 1;
if (Dignity <= -100)
{
icoDignity = 2;
}
if (Dignity <= -200)
{
icoDignity = 3;
}
if (Dignity <= -400)
{
icoDignity = 4;
}
if (Dignity <= -600)
{
icoDignity = 5;
}
if (Dignity <= -800)
{
icoDignity = 6;
}
return icoDignity;
}
public List<IPortalEntity> GetExtraPortal()
{
if (MapInstance == null || Miniland == null)
{
return new List<IPortalEntity>();
}
return MapInstance.GenerateMinilandEntryPortals(Miniland, _portalFactory);
}
[Obsolete("Move to constructor")]
public void SetSession(IClientSession clientSession)
{
Session = clientSession;
}
public int HealthHpLoad()
{
if (IsSitting)
{
return _characterAlgorithm.GetRegenHp(this, Class, true);
}
return LastDefence.AddSeconds(4) <= DateTime.UtcNow ? _characterAlgorithm.GetRegenHp(this, Class, false) : 0;
}
public int HealthMpLoad()
{
if (IsSitting)
{
return _characterAlgorithm.GetRegenMp(this, Class, true);
}
return LastDefence.AddSeconds(4) <= DateTime.UtcNow ? _characterAlgorithm.GetRegenMp(this, Class, false) : 0;
}
#endregion
}