From c8bcfd67bd133d2c3ce303c1ffd27dac3ead05b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franti=C5=A1ek=20Boh=C3=A1=C4=8Dek?= Date: Sat, 7 Jan 2023 10:31:56 +0100 Subject: [PATCH] feat(game): add mates processing --- .../Data/Entities/GroundItem.cs | 2 +- Core/NosSmooth.Game/Data/Entities/IPet.cs | 14 - Core/NosSmooth.Game/Data/Entities/Partner.cs | 12 - Core/NosSmooth.Game/Data/Entities/Pet.cs | 12 - .../Data/Items/PartnerEquipment.cs | 15 + Core/NosSmooth.Game/Data/Mates/Mate.cs | 29 ++ Core/NosSmooth.Game/Data/Mates/Mates.cs | 94 +++++ Core/NosSmooth.Game/Data/Mates/Partner.cs | 47 +++ .../NosSmooth.Game/Data/Mates/PartnerSkill.cs | 18 + Core/NosSmooth.Game/Data/Mates/PartnerSp.cs | 18 + .../NosSmooth.Game/Data/Mates/PartyPartner.cs | 25 ++ Core/NosSmooth.Game/Data/Mates/PartyPet.cs | 25 ++ Core/NosSmooth.Game/Data/Mates/Pet.cs | 46 +++ .../Data/Stats/MateArmorStats.cs | 17 + .../Data/Stats/MateAttackStats.cs | 17 + Core/NosSmooth.Game/Data/Stats/Resistance.cs | 15 + .../Events/Mates/MateStatEvent.cs | 13 + .../Mates/MatesPartyInitializedEvent.cs | 12 + .../Events/Mates/PartnerInitializedEvent.cs | 12 + .../Mates/PartnerSkillsReceivedEvent.cs | 13 + .../Events/Mates/PetInitializedEvent.cs | 12 + .../Events/Mates/PetSkillReceivedEvent.cs | 13 + .../Extensions/LivingEntityExtensions.cs | 25 ++ .../Extensions/ServiceCollectionExtensions.cs | 3 + Core/NosSmooth.Game/Game.cs | 35 ++ Core/NosSmooth.Game/GameSemaphoreType.cs | 7 +- .../Relations/MatesInitResponder.cs | 367 ++++++++++++++++++ .../Skills/MatesSkillResponder.cs | 145 +++++++ .../Skills/PlayerSkillResponder.cs | 4 +- .../Client/Battle/UsePetSkillPacket.cs | 37 ++ .../Server/Entities/EffectsSubPacket.cs | 2 +- .../Server/Mates/ScNEquipmentSubPacket.cs | 6 +- .../Server/Mates/ScNPacket.cs | 2 +- .../Server/Mates/ScNSkillSubPacket.cs | 2 +- .../InventoryInitializedResponder.cs | 52 +++ 35 files changed, 1120 insertions(+), 48 deletions(-) delete mode 100644 Core/NosSmooth.Game/Data/Entities/IPet.cs delete mode 100644 Core/NosSmooth.Game/Data/Entities/Partner.cs delete mode 100644 Core/NosSmooth.Game/Data/Entities/Pet.cs create mode 100644 Core/NosSmooth.Game/Data/Items/PartnerEquipment.cs create mode 100644 Core/NosSmooth.Game/Data/Mates/Mate.cs create mode 100644 Core/NosSmooth.Game/Data/Mates/Mates.cs create mode 100644 Core/NosSmooth.Game/Data/Mates/Partner.cs create mode 100644 Core/NosSmooth.Game/Data/Mates/PartnerSkill.cs create mode 100644 Core/NosSmooth.Game/Data/Mates/PartnerSp.cs create mode 100644 Core/NosSmooth.Game/Data/Mates/PartyPartner.cs create mode 100644 Core/NosSmooth.Game/Data/Mates/PartyPet.cs create mode 100644 Core/NosSmooth.Game/Data/Mates/Pet.cs create mode 100644 Core/NosSmooth.Game/Data/Stats/MateArmorStats.cs create mode 100644 Core/NosSmooth.Game/Data/Stats/MateAttackStats.cs create mode 100644 Core/NosSmooth.Game/Data/Stats/Resistance.cs create mode 100644 Core/NosSmooth.Game/Events/Mates/MateStatEvent.cs create mode 100644 Core/NosSmooth.Game/Events/Mates/MatesPartyInitializedEvent.cs create mode 100644 Core/NosSmooth.Game/Events/Mates/PartnerInitializedEvent.cs create mode 100644 Core/NosSmooth.Game/Events/Mates/PartnerSkillsReceivedEvent.cs create mode 100644 Core/NosSmooth.Game/Events/Mates/PetInitializedEvent.cs create mode 100644 Core/NosSmooth.Game/Events/Mates/PetSkillReceivedEvent.cs create mode 100644 Core/NosSmooth.Game/Extensions/LivingEntityExtensions.cs create mode 100644 Core/NosSmooth.Game/PacketHandlers/Relations/MatesInitResponder.cs create mode 100644 Core/NosSmooth.Game/PacketHandlers/Skills/MatesSkillResponder.cs create mode 100644 Packets/NosSmooth.Packets/Client/Battle/UsePetSkillPacket.cs create mode 100644 Samples/FileClient/Responders/InventoryInitializedResponder.cs diff --git a/Core/NosSmooth.Game/Data/Entities/GroundItem.cs b/Core/NosSmooth.Game/Data/Entities/GroundItem.cs index 6036926..17954c8 100644 --- a/Core/NosSmooth.Game/Data/Entities/GroundItem.cs +++ b/Core/NosSmooth.Game/Data/Entities/GroundItem.cs @@ -18,7 +18,7 @@ public class GroundItem : IEntity /// /// Gets or sets the id of the owner, if any. /// - public long? OwnerId { get; set; } + public long? OwnerId { get; internal set; } /// /// Gets or sets the amount of the item on the ground. diff --git a/Core/NosSmooth.Game/Data/Entities/IPet.cs b/Core/NosSmooth.Game/Data/Entities/IPet.cs deleted file mode 100644 index 0a0b0bc..0000000 --- a/Core/NosSmooth.Game/Data/Entities/IPet.cs +++ /dev/null @@ -1,14 +0,0 @@ -// -// IPet.cs -// -// Copyright (c) František Boháček. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace NosSmooth.Game.Data.Entities; - -/// -/// Represents base type for a pet or a partner. -/// -public interface IPet -{ -} \ No newline at end of file diff --git a/Core/NosSmooth.Game/Data/Entities/Partner.cs b/Core/NosSmooth.Game/Data/Entities/Partner.cs deleted file mode 100644 index d9a8202..0000000 --- a/Core/NosSmooth.Game/Data/Entities/Partner.cs +++ /dev/null @@ -1,12 +0,0 @@ -// -// Partner.cs -// -// Copyright (c) František Boháček. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace NosSmooth.Game.Data.Entities; - -/// -/// Represents Partner of the Character. -/// -public record Partner() : IPet; \ No newline at end of file diff --git a/Core/NosSmooth.Game/Data/Entities/Pet.cs b/Core/NosSmooth.Game/Data/Entities/Pet.cs deleted file mode 100644 index 2f9c157..0000000 --- a/Core/NosSmooth.Game/Data/Entities/Pet.cs +++ /dev/null @@ -1,12 +0,0 @@ -// -// Pet.cs -// -// Copyright (c) František Boháček. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace NosSmooth.Game.Data.Entities; - -/// -/// Represents pet of the character. -/// -public record Pet() : IPet; \ No newline at end of file diff --git a/Core/NosSmooth.Game/Data/Items/PartnerEquipment.cs b/Core/NosSmooth.Game/Data/Items/PartnerEquipment.cs new file mode 100644 index 0000000..a17b407 --- /dev/null +++ b/Core/NosSmooth.Game/Data/Items/PartnerEquipment.cs @@ -0,0 +1,15 @@ +// +// PartnerEquipment.cs +// +// Copyright (c) František Boháček. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace NosSmooth.Game.Data.Items; + +public record PartnerEquipment +( + UpgradeableItem? Weapon, + UpgradeableItem? Armor, + UpgradeableItem? Gauntlet, + UpgradeableItem? Boots +); \ No newline at end of file diff --git a/Core/NosSmooth.Game/Data/Mates/Mate.cs b/Core/NosSmooth.Game/Data/Mates/Mate.cs new file mode 100644 index 0000000..0f6928a --- /dev/null +++ b/Core/NosSmooth.Game/Data/Mates/Mate.cs @@ -0,0 +1,29 @@ +// +// Mate.cs +// +// Copyright (c) František Boháček. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using NosSmooth.Game.Data.Info; +using NosSmooth.Game.Data.Stats; +using NosSmooth.Packets.Enums; +using NosSmooth.PacketSerializer.Abstractions.Common; + +namespace NosSmooth.Game.Data.Mates; + +public record Mate +( + long MateId, + long NpcVNum, + long TransportId, + Level Level, + short Loyalty, + MateAttackStats Attack, + MateArmorStats Armor, + Element Element, + Resistance Resistance, + Health Hp, + Health Mp, + string Name, + bool IsSummonable +); \ No newline at end of file diff --git a/Core/NosSmooth.Game/Data/Mates/Mates.cs b/Core/NosSmooth.Game/Data/Mates/Mates.cs new file mode 100644 index 0000000..794b2be --- /dev/null +++ b/Core/NosSmooth.Game/Data/Mates/Mates.cs @@ -0,0 +1,94 @@ +// +// Mates.cs +// +// Copyright (c) František Boháček. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System.Collections; +using System.Collections.Concurrent; +using NosSmooth.Game.Data.Characters; + +namespace NosSmooth.Game.Data.Mates; + +/// +/// Game mates state. +/// +public class Mates : IEnumerable +{ + private ConcurrentDictionary _partners; + private ConcurrentDictionary _pets; + + /// + /// Initializes a new instance of the class. + /// + public Mates() + { + _partners = new ConcurrentDictionary(); + _pets = new ConcurrentDictionary(); + } + + /// + /// Gets all of the partners belonging to the character. + /// + public IEnumerable Partners => _partners.Values; + + /// + /// Gets all of the pets belonging to the character. + /// + public IEnumerable Pets => _pets.Values; + + /// + /// Gets the current skill of pet, if there is any. + /// + public Skill? PetSkill { get; internal set; } + + /// + /// Get sthe current skills of partner(' sp). + /// + public IReadOnlyList? PartnerSkills { get; internal set; } + + /// + /// Gets the current pet of the client. + /// + public PartyPet? CurrentPet { get; internal set; } + + /// + /// Gets the current partner of the client. + /// + public PartyPartner? CurrentPartner { get; internal set; } + + /// + public IEnumerator GetEnumerator() + => _partners.Values.Cast().Concat(_pets.Values.Cast()).GetEnumerator(); + + /// + IEnumerator IEnumerable.GetEnumerator() + => GetEnumerator(); + + /// + /// Sets pet of the given id. + /// + /// The pet. + internal void SetPet(Pet pet) + { + _pets[pet.MateId] = pet; + } + + /// + /// Sets partner of the given id. + /// + /// The partner. + internal void SetPartner(Partner partner) + { + _partners[partner.MateId] = partner; + } + + /// + /// Clears partners and pets. + /// + internal void Clear() + { + _partners.Clear(); + _pets.Clear(); + } +} \ No newline at end of file diff --git a/Core/NosSmooth.Game/Data/Mates/Partner.cs b/Core/NosSmooth.Game/Data/Mates/Partner.cs new file mode 100644 index 0000000..aacdb4d --- /dev/null +++ b/Core/NosSmooth.Game/Data/Mates/Partner.cs @@ -0,0 +1,47 @@ +// +// Partner.cs +// +// Copyright (c) František Boháček. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using NosSmooth.Game.Data.Info; +using NosSmooth.Game.Data.Items; +using NosSmooth.Game.Data.Stats; +using NosSmooth.Packets.Enums; + +namespace NosSmooth.Game.Data.Mates; + +public record Partner +( + long MateId, + long NpcVNum, + long TransportId, + Level Level, + short Loyalty, + MateAttackStats Attack, + MateArmorStats Armor, + PartnerEquipment Equipment, + Element Element, + Resistance Resistance, + Health Hp, + Health Mp, + string Name, + int? MorphVNum, + bool IsSummonable, + PartnerSp? Sp +) : Mate +( + MateId, + NpcVNum, + TransportId, + Level, + Loyalty, + Attack, + Armor, + Element, + Resistance, + Hp, + Mp, + Name, + IsSummonable +); \ No newline at end of file diff --git a/Core/NosSmooth.Game/Data/Mates/PartnerSkill.cs b/Core/NosSmooth.Game/Data/Mates/PartnerSkill.cs new file mode 100644 index 0000000..491a777 --- /dev/null +++ b/Core/NosSmooth.Game/Data/Mates/PartnerSkill.cs @@ -0,0 +1,18 @@ +// +// PartnerSkill.cs +// +// Copyright (c) František Boháček. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using NosSmooth.Data.Abstractions.Infos; +using NosSmooth.Game.Data.Characters; +using NosSmooth.Packets.Enums.Mates; + +namespace NosSmooth.Game.Data.Mates; + +public record PartnerSkill +( + int SkillVNum, + PartnerSkillRank? Rank, + ISkillInfo? Info +) : Skill(SkillVNum, null, Info); \ No newline at end of file diff --git a/Core/NosSmooth.Game/Data/Mates/PartnerSp.cs b/Core/NosSmooth.Game/Data/Mates/PartnerSp.cs new file mode 100644 index 0000000..20cf157 --- /dev/null +++ b/Core/NosSmooth.Game/Data/Mates/PartnerSp.cs @@ -0,0 +1,18 @@ +// +// PartnerSp.cs +// +// Copyright (c) František Boháček. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using NosSmooth.Game.Data.Characters; + +namespace NosSmooth.Game.Data.Mates; + +public record PartnerSp +( + long VNum, + byte? AgilityPercentage, + PartnerSkill? Skill1, + PartnerSkill? Skill2, + PartnerSkill? Skill3 +); \ No newline at end of file diff --git a/Core/NosSmooth.Game/Data/Mates/PartyPartner.cs b/Core/NosSmooth.Game/Data/Mates/PartyPartner.cs new file mode 100644 index 0000000..a2f7b10 --- /dev/null +++ b/Core/NosSmooth.Game/Data/Mates/PartyPartner.cs @@ -0,0 +1,25 @@ +// +// PartyPartner.cs +// +// Copyright (c) František Boháček. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using NosSmooth.Game.Data.Info; + +namespace NosSmooth.Game.Data.Mates; + +public record PartyPartner +( + Partner Partner +) +{ + /// + /// Gets the hp of the partner. + /// + public Health? Hp { get; internal set; } + + /// + /// Gets the mp of the partner. + /// + public Health? Mp { get; internal set; } +} \ No newline at end of file diff --git a/Core/NosSmooth.Game/Data/Mates/PartyPet.cs b/Core/NosSmooth.Game/Data/Mates/PartyPet.cs new file mode 100644 index 0000000..fd11c78 --- /dev/null +++ b/Core/NosSmooth.Game/Data/Mates/PartyPet.cs @@ -0,0 +1,25 @@ +// +// PartyPet.cs +// +// Copyright (c) František Boháček. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using NosSmooth.Game.Data.Info; + +namespace NosSmooth.Game.Data.Mates; + +public record PartyPet +( + Pet Pet +) +{ + /// + /// Gets the hp of the partner. + /// + public Health? Hp { get; internal set; } + + /// + /// Gets the mp of the partner. + /// + public Health? Mp { get; internal set; } +} \ No newline at end of file diff --git a/Core/NosSmooth.Game/Data/Mates/Pet.cs b/Core/NosSmooth.Game/Data/Mates/Pet.cs new file mode 100644 index 0000000..f00475a --- /dev/null +++ b/Core/NosSmooth.Game/Data/Mates/Pet.cs @@ -0,0 +1,46 @@ +// +// Pet.cs +// +// Copyright (c) František Boháček. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using NosSmooth.Game.Data.Info; +using NosSmooth.Game.Data.Items; +using NosSmooth.Game.Data.Stats; +using NosSmooth.Packets.Enums; +using NosSmooth.PacketSerializer.Abstractions.Common; + +namespace NosSmooth.Game.Data.Mates; + +public record Pet +( + long MateId, + long NpcVNum, + long TransportId, + Level Level, + short Loyalty, + MateAttackStats Attack, + MateArmorStats Armor, + Element Element, + Resistance Resistance, + Health Hp, + Health Mp, + string Name, + bool IsSummonable, + bool CanPickUp +) : Mate +( + MateId, + NpcVNum, + TransportId, + Level, + Loyalty, + Attack, + Armor, + Element, + Resistance, + Hp, + Mp, + Name, + IsSummonable +); \ No newline at end of file diff --git a/Core/NosSmooth.Game/Data/Stats/MateArmorStats.cs b/Core/NosSmooth.Game/Data/Stats/MateArmorStats.cs new file mode 100644 index 0000000..fd1127f --- /dev/null +++ b/Core/NosSmooth.Game/Data/Stats/MateArmorStats.cs @@ -0,0 +1,17 @@ +// +// MateArmorStats.cs +// +// Copyright (c) František Boháček. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace NosSmooth.Game.Data.Stats; + +public record MateArmorStats +( + short DefenceUpgrade, + int MeleeDefence, + int MeleeDefenceDodge, + int RangeDefence, + int RangeDodgeRate, + int MagicalDefence +); \ No newline at end of file diff --git a/Core/NosSmooth.Game/Data/Stats/MateAttackStats.cs b/Core/NosSmooth.Game/Data/Stats/MateAttackStats.cs new file mode 100644 index 0000000..672c230 --- /dev/null +++ b/Core/NosSmooth.Game/Data/Stats/MateAttackStats.cs @@ -0,0 +1,17 @@ +// +// MateAttackStats.cs +// +// Copyright (c) František Boháček. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace NosSmooth.Game.Data.Stats; + +public record MateAttackStats +( + short AttackUpgrade, + int MinimumAttack, + int MaximumAttack, + int Precision, + int CriticalChance, + int CriticalRate +); \ No newline at end of file diff --git a/Core/NosSmooth.Game/Data/Stats/Resistance.cs b/Core/NosSmooth.Game/Data/Stats/Resistance.cs new file mode 100644 index 0000000..7386e14 --- /dev/null +++ b/Core/NosSmooth.Game/Data/Stats/Resistance.cs @@ -0,0 +1,15 @@ +// +// Resistance.cs +// +// Copyright (c) František Boháček. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace NosSmooth.Game.Data.Stats; + +public record Resistance +( + short FireResistance, + short WaterResistance, + short LightResistance, + short DarkResistance +); \ No newline at end of file diff --git a/Core/NosSmooth.Game/Events/Mates/MateStatEvent.cs b/Core/NosSmooth.Game/Events/Mates/MateStatEvent.cs new file mode 100644 index 0000000..acf3182 --- /dev/null +++ b/Core/NosSmooth.Game/Events/Mates/MateStatEvent.cs @@ -0,0 +1,13 @@ +// +// MateStatEvent.cs +// +// Copyright (c) František Boháček. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using NosSmooth.Game.Data.Info; +using NosSmooth.Game.Data.Mates; +using NosSmooth.Game.Data.Social; + +namespace NosSmooth.Game.Events.Mates; + +public record MateStatEvent(Mate Mate, Health Hp, Health Mp) : IGameEvent; \ No newline at end of file diff --git a/Core/NosSmooth.Game/Events/Mates/MatesPartyInitializedEvent.cs b/Core/NosSmooth.Game/Events/Mates/MatesPartyInitializedEvent.cs new file mode 100644 index 0000000..1b36cde --- /dev/null +++ b/Core/NosSmooth.Game/Events/Mates/MatesPartyInitializedEvent.cs @@ -0,0 +1,12 @@ +// +// MatesPartyInitializedEvent.cs +// +// Copyright (c) František Boháček. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using NosSmooth.Game.Data.Mates; +using NosSmooth.Game.Data.Social; + +namespace NosSmooth.Game.Events.Mates; + +public record MatesPartyInitializedEvent(Pet? Pet, Partner? Partner) : IGameEvent; \ No newline at end of file diff --git a/Core/NosSmooth.Game/Events/Mates/PartnerInitializedEvent.cs b/Core/NosSmooth.Game/Events/Mates/PartnerInitializedEvent.cs new file mode 100644 index 0000000..4bddce5 --- /dev/null +++ b/Core/NosSmooth.Game/Events/Mates/PartnerInitializedEvent.cs @@ -0,0 +1,12 @@ +// +// PartnerInitializedEvent.cs +// +// Copyright (c) František Boháček. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using NosSmooth.Game.Data.Mates; +using NosSmooth.Game.Data.Social; + +namespace NosSmooth.Game.Events.Mates; + +public record PartnerInitializedEvent(Partner Partner) : IGameEvent; \ No newline at end of file diff --git a/Core/NosSmooth.Game/Events/Mates/PartnerSkillsReceivedEvent.cs b/Core/NosSmooth.Game/Events/Mates/PartnerSkillsReceivedEvent.cs new file mode 100644 index 0000000..1c4648a --- /dev/null +++ b/Core/NosSmooth.Game/Events/Mates/PartnerSkillsReceivedEvent.cs @@ -0,0 +1,13 @@ +// +// PartnerSkillsReceivedEvent.cs +// +// Copyright (c) František Boháček. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using NosSmooth.Game.Data.Characters; +using NosSmooth.Game.Data.Mates; +using NosSmooth.Game.Data.Social; + +namespace NosSmooth.Game.Events.Mates; + +public record PartnerSkillsReceivedEvent(Partner? Partner, IReadOnlyList Skills) : IGameEvent; \ No newline at end of file diff --git a/Core/NosSmooth.Game/Events/Mates/PetInitializedEvent.cs b/Core/NosSmooth.Game/Events/Mates/PetInitializedEvent.cs new file mode 100644 index 0000000..175bf1b --- /dev/null +++ b/Core/NosSmooth.Game/Events/Mates/PetInitializedEvent.cs @@ -0,0 +1,12 @@ +// +// PetInitializedEvent.cs +// +// Copyright (c) František Boháček. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using NosSmooth.Game.Data.Mates; +using NosSmooth.Game.Data.Social; + +namespace NosSmooth.Game.Events.Mates; + +public record PetInitializedEvent(Pet Pet) : IGameEvent; \ No newline at end of file diff --git a/Core/NosSmooth.Game/Events/Mates/PetSkillReceivedEvent.cs b/Core/NosSmooth.Game/Events/Mates/PetSkillReceivedEvent.cs new file mode 100644 index 0000000..4b5c112 --- /dev/null +++ b/Core/NosSmooth.Game/Events/Mates/PetSkillReceivedEvent.cs @@ -0,0 +1,13 @@ +// +// PetSkillReceivedEvent.cs +// +// Copyright (c) František Boháček. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using NosSmooth.Game.Data.Characters; +using NosSmooth.Game.Data.Mates; +using NosSmooth.Game.Data.Social; + +namespace NosSmooth.Game.Events.Mates; + +public record PetSkillReceivedEvent(Pet? Pet, Skill? PetSkill) : IGameEvent; \ No newline at end of file diff --git a/Core/NosSmooth.Game/Extensions/LivingEntityExtensions.cs b/Core/NosSmooth.Game/Extensions/LivingEntityExtensions.cs new file mode 100644 index 0000000..ce246f4 --- /dev/null +++ b/Core/NosSmooth.Game/Extensions/LivingEntityExtensions.cs @@ -0,0 +1,25 @@ +// +// LivingEntityExtensions.cs +// +// Copyright (c) František Boháček. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using NosSmooth.Game.Data.Entities; + +namespace NosSmooth.Game.Extensions; + +/// +/// An extension methods for . +/// +public static class LivingEntityExtensions +{ + /// + /// Checks whether the entity is alive. + /// + /// The entity to check. + /// Whether the entity is alive. + public static bool IsAlive(ILivingEntity entity) + { + return entity.Hp is null || entity.Hp.Amount != 0 || entity.Hp.Percentage != 0; + } +} \ No newline at end of file diff --git a/Core/NosSmooth.Game/Extensions/ServiceCollectionExtensions.cs b/Core/NosSmooth.Game/Extensions/ServiceCollectionExtensions.cs index a71fc86..e2884c8 100644 --- a/Core/NosSmooth.Game/Extensions/ServiceCollectionExtensions.cs +++ b/Core/NosSmooth.Game/Extensions/ServiceCollectionExtensions.cs @@ -15,6 +15,7 @@ using NosSmooth.Game.PacketHandlers.Entities; using NosSmooth.Game.PacketHandlers.Inventory; using NosSmooth.Game.PacketHandlers.Map; using NosSmooth.Game.PacketHandlers.Relations; +using NosSmooth.Game.PacketHandlers.Skills; using NosSmooth.Game.PacketHandlers.Specialists; namespace NosSmooth.Game.Extensions; @@ -40,11 +41,13 @@ public static class ServiceCollectionExtensions serviceCollection .AddPacketResponder() .AddPacketResponder() + .AddPacketResponder() .AddPacketResponder() .AddPacketResponder() .AddPacketResponder() .AddPacketResponder() .AddPacketResponder() + .AddPacketResponder() .AddPacketResponder() .AddPacketResponder() .AddPacketResponder() diff --git a/Core/NosSmooth.Game/Game.cs b/Core/NosSmooth.Game/Game.cs index 53be409..6e6f7d6 100644 --- a/Core/NosSmooth.Game/Game.cs +++ b/Core/NosSmooth.Game/Game.cs @@ -6,10 +6,12 @@ using Microsoft.Extensions.Options; using NosSmooth.Core.Stateful; +using NosSmooth.Game.Data; using NosSmooth.Game.Data.Characters; using NosSmooth.Game.Data.Chat; using NosSmooth.Game.Data.Inventory; using NosSmooth.Game.Data.Maps; +using NosSmooth.Game.Data.Mates; using NosSmooth.Game.Data.Raids; using NosSmooth.Game.Data.Social; @@ -43,6 +45,11 @@ public class Game : IStatefulEntity /// public Character? Character { get; internal set; } + /// + /// Gets the mates of the current character. + /// + public Mates? Mates { get; internal set; } + /// /// Gets or sets the inventory of the character. /// @@ -88,6 +95,34 @@ public class Game : IStatefulEntity /// public Raid? CurrentRaid { get; internal set; } + /// + /// Creates the mates if they are null, or updates the current mates. + /// + /// The function for creating the mates. + /// The function for updating the mates. + /// Whether to release the semaphore used for changing the mates. + /// The cancellation token for cancelling the operation. + /// The updated mates. + internal async Task CreateOrUpdateMatesAsync + ( + Func create, + Func update, + bool releaseSemaphore = true, + CancellationToken ct = default + ) + { + return await CreateOrUpdateAsync + ( + GameSemaphoreType.Mates, + () => Mates, + s => Mates = s, + create, + update, + releaseSemaphore, + ct + ); + } + /// /// Creates the skills if they are null, or updates the current skills. /// diff --git a/Core/NosSmooth.Game/GameSemaphoreType.cs b/Core/NosSmooth.Game/GameSemaphoreType.cs index 0cb141f..2c0277f 100644 --- a/Core/NosSmooth.Game/GameSemaphoreType.cs +++ b/Core/NosSmooth.Game/GameSemaphoreType.cs @@ -49,5 +49,10 @@ public enum GameSemaphoreType /// /// The semaphore for raid. /// - Raid + Raid, + + /// + /// The semaphore for mates. + /// + Mates } \ No newline at end of file diff --git a/Core/NosSmooth.Game/PacketHandlers/Relations/MatesInitResponder.cs b/Core/NosSmooth.Game/PacketHandlers/Relations/MatesInitResponder.cs new file mode 100644 index 0000000..512f938 --- /dev/null +++ b/Core/NosSmooth.Game/PacketHandlers/Relations/MatesInitResponder.cs @@ -0,0 +1,367 @@ +// +// MatesInitResponder.cs +// +// Copyright (c) František Boháček. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using Microsoft.Extensions.Logging; +using NosSmooth.Core.Extensions; +using NosSmooth.Core.Packets; +using NosSmooth.Data.Abstractions; +using NosSmooth.Game.Data.Characters; +using NosSmooth.Game.Data.Info; +using NosSmooth.Game.Data.Items; +using NosSmooth.Game.Data.Mates; +using NosSmooth.Game.Data.Social; +using NosSmooth.Game.Data.Stats; +using NosSmooth.Game.Events.Core; +using NosSmooth.Game.Events.Mates; +using NosSmooth.Packets.Enums.Entities; +using NosSmooth.Packets.Enums.Mates; +using NosSmooth.Packets.Server.Groups; +using NosSmooth.Packets.Server.Mates; +using NosSmooth.Packets.Server.Miniland; +using Remora.Results; + +namespace NosSmooth.Game.PacketHandlers.Relations; + +/// +/// A mates initialization responder. +/// +public class MatesInitResponder : IPacketResponder, IPacketResponder, + IPacketResponder, IPacketResponder, IPacketResponder +{ + private readonly Game _game; + private readonly IInfoService _infoService; + private readonly EventDispatcher _eventDispatcher; + private readonly ILogger _logger; + + /// + /// Initializes a new instance of the class. + /// + /// The game. + /// The info service. + /// The event dispatcher. + /// The logger. + public MatesInitResponder + ( + Game game, + IInfoService infoService, + EventDispatcher eventDispatcher, + ILogger logger + ) + { + _game = game; + _infoService = infoService; + _eventDispatcher = eventDispatcher; + _logger = logger; + } + + /// + public async Task Respond(PacketEventArgs packetArgs, CancellationToken ct = default) + { + var packet = packetArgs.Packet; + var pet = new Pet + ( + packet.PetId, + packet.NpcVNum, + packet.TransportId, + new Level(packet.Level, packet.Experience, packet.LevelExperience), + packet.Loyalty, + new MateAttackStats + ( + packet.AttackUpgrade, + packet.MinimumAttack, + packet.MaximumAttack, + packet.Concentrate, + packet.CriticalChance, + packet.CriticalRate + ), + new MateArmorStats + ( + packet.DefenceUpgrade, + packet.MeleeDefence, + packet.MeleeDefenceDodge, + packet.RangeDefence, + packet.RangeDodgeRate, + packet.MagicalDefence + ), + packet.Element, + new Resistance + ( + packet.ResistanceSubPacket.FireResistance, + packet.ResistanceSubPacket.WaterResistance, + packet.ResistanceSubPacket.LightResistance, + packet.ResistanceSubPacket.DarkResistance + ), + new Health { Amount = packet.Hp, Maximum = packet.HpMax }, + new Health { Amount = packet.Mp, Maximum = packet.MpMax }, + packet.Name, + packet.IsSummonable, + packet.CanPickUp + ); + + await _game.CreateOrUpdateMatesAsync + ( + () => + { + var mates = new Mates(); + mates.SetPet(pet); + return mates; + }, + mates => + { + mates.SetPet(pet); + return mates; + }, + ct: ct + ); + + return await _eventDispatcher.DispatchEvent + ( + new PetInitializedEvent(pet), + ct + ); + } + + /// + public async Task Respond(PacketEventArgs packetArgs, CancellationToken ct = default) + { + var packet = packetArgs.Packet; + var partner = new Partner + ( + packet.PartnerId, + packet.NpcVNum, + packet.TransportId, + new Level(packet.Level, packet.Experience, packet.LevelExperience), + packet.Loyalty, + new MateAttackStats + ( + packet.AttackUpgrade, + packet.MinimumAttack, + packet.MaximumAttack, + packet.Precision, + packet.CriticalChance, + packet.CriticalRate + ), + new MateArmorStats + ( + packet.DefenceUpgrade, + packet.MeleeDefence, + packet.MeleeDefenceDodge, + packet.RangeDefence, + packet.RangeDodgeRate, + packet.MagicalDefence + ), + new PartnerEquipment + ( + await CreatePartnerItem(packet.WeaponSubPacket, ct), + await CreatePartnerItem(packet.ArmorSubPacket, ct), + await CreatePartnerItem(packet.GauntletSubPacket, ct), + await CreatePartnerItem(packet.BootsSubPacket, ct) + ), + packet.Element, + new Resistance + ( + packet.ResistanceSubPacket.FireResistance, + packet.ResistanceSubPacket.WaterResistance, + packet.ResistanceSubPacket.LightResistance, + packet.ResistanceSubPacket.DarkResistance + ), + new Health { Amount = packet.Hp, Maximum = packet.HpMax }, + new Health { Amount = packet.Mp, Maximum = packet.MpMax }, + packet.Name, + packet.MorphVNum, + packet.IsSummonable, +#pragma warning disable SA1118 + packet.SpSubPacket?.ItemVNum is not null + ? new PartnerSp + ( + packet.SpSubPacket.ItemVNum.Value, + packet.SpSubPacket.AgilityPercentage, + await CreateSkill(packet.Skill1SubPacket, ct), + await CreateSkill(packet.Skill2SubPacket, ct), + await CreateSkill(packet.Skill3SubPacket, ct) + ) + : null +#pragma warning restore SA1118 + ); + + await _game.CreateOrUpdateMatesAsync + ( + () => + { + var mates = new Mates(); + mates.SetPartner(partner); + return mates; + }, + mates => + { + mates.SetPartner(partner); + return mates; + }, + ct: ct + ); + + return await _eventDispatcher.DispatchEvent + ( + new PartnerInitializedEvent(partner), + ct + ); + } + + /// + public async Task Respond(PacketEventArgs packetArgs, CancellationToken ct = default) + { + var packet = packetArgs.Packet; + var partner = packet.PinitSubPackets?.FirstOrDefault(x => x.MateSubPacket?.MateType == MateType.Partner); + var pet = packet.PinitSubPackets?.FirstOrDefault(x => x.MateSubPacket?.MateType == MateType.Pet); + + Partner? gamePartner = null; + Pet? gamePet = null; + + await _game.CreateOrUpdateMatesAsync + ( + () => null, + m => + { + if (partner is not null) + { + gamePartner = _game.Mates?.Partners.FirstOrDefault(x => x.MateId == partner.EntityId); + if (gamePartner is not null && gamePartner != m.CurrentPartner?.Partner) + { + m.CurrentPartner = new PartyPartner(gamePartner); + } + } + + if (pet is not null) + { + gamePet = _game.Mates?.Pets.FirstOrDefault(x => x.MateId == pet.EntityId); + if (gamePet is not null && gamePet != m.CurrentPet?.Pet) + { + m.CurrentPet = new PartyPet(gamePet); + } + } + + return m; + }, + ct: ct + ); + + return await _eventDispatcher.DispatchEvent + ( + new MatesPartyInitializedEvent(gamePet, gamePartner), + ct + ); + } + + /// + public async Task Respond(PacketEventArgs packetArgs, CancellationToken ct = default) + { + var packet = packetArgs.Packet; + if (packet.EntityType != EntityType.Npc || packet.MateType is null) + { + return Result.FromSuccess(); + } + + Mate? mate = null; + var hp = new Health { Amount = packet.Hp, Percentage = packet.HpPercentage }; + var mp = new Health { Amount = packet.Mp, Percentage = packet.MpPercentage }; + + await _game.CreateOrUpdateMatesAsync + ( + () => null, + m => + { + if (packet.MateType is MateType.Pet && m.CurrentPet is not null) + { + mate = m.CurrentPet.Pet; + m.CurrentPet.Hp = hp; + m.CurrentPet.Mp = mp; + } + else if (packet.MateType is MateType.Partner && m.CurrentPartner is not null) + { + mate = m.CurrentPartner.Partner; + m.CurrentPartner.Hp = hp; + m.CurrentPartner.Mp = mp; + } + + return m; + }, + ct: ct + ); + + if (mate is not null) + { + return await _eventDispatcher.DispatchEvent(new MateStatEvent(mate, hp, mp), ct); + } + + return Result.FromSuccess(); + } + + /// + public async Task Respond(PacketEventArgs packetArgs, CancellationToken ct = default) + { + await _game.CreateOrUpdateMatesAsync + ( + () => null, + m => + { + m.Clear(); + return m; + }, + ct: ct + ); + + return Result.FromSuccess(); + } + + private async Task CreatePartnerItem(ScNEquipmentSubPacket? packet, CancellationToken ct) + { + if (packet is null || packet.ItemVNum is null) + { + return null; + } + + var itemInfoResult = await _infoService.GetItemInfoAsync(packet.ItemVNum.Value, ct); + if (!itemInfoResult.IsDefined(out var itemInfo)) + { + _logger.LogWarning + ( + "Could not obtain an item info for vnum {vnum}: {error}", + packet.ItemVNum.Value, + itemInfoResult.ToFullString() + ); + } + + return new UpgradeableItem + ( + packet.ItemVNum.Value, + itemInfo, + packet.ItemUpgrade, + packet.ItemRare, + 0 + ); + } + + private async Task CreateSkill(ScNSkillSubPacket? packet, CancellationToken ct) + { + if (packet is null || packet.SkillVNum is null) + { + return null; + } + + var skillInfoResult = await _infoService.GetSkillInfoAsync(packet.SkillVNum.Value, ct); + if (!skillInfoResult.IsDefined(out var skillInfo)) + { + _logger.LogWarning + ( + "Could not obtain a skill info for vnum {vnum}: {error}", + packet.SkillVNum.Value, + skillInfoResult.ToFullString() + ); + } + + return new PartnerSkill(packet.SkillVNum.Value, packet.Rank, skillInfo); + } +} \ No newline at end of file diff --git a/Core/NosSmooth.Game/PacketHandlers/Skills/MatesSkillResponder.cs b/Core/NosSmooth.Game/PacketHandlers/Skills/MatesSkillResponder.cs new file mode 100644 index 0000000..9ea2003 --- /dev/null +++ b/Core/NosSmooth.Game/PacketHandlers/Skills/MatesSkillResponder.cs @@ -0,0 +1,145 @@ +// +// MatesSkillResponder.cs +// +// Copyright (c) František Boháček. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using Microsoft.Extensions.Logging; +using NosSmooth.Core.Extensions; +using NosSmooth.Core.Packets; +using NosSmooth.Data.Abstractions; +using NosSmooth.Game.Data.Characters; +using NosSmooth.Game.Data.Mates; +using NosSmooth.Game.Events.Core; +using NosSmooth.Game.Events.Mates; +using NosSmooth.Packets.Server.Skills; +using Remora.Results; + +namespace NosSmooth.Game.PacketHandlers.Skills; + +/// +/// Responds to petski and pski packets. +/// +public class MatesSkillResponder : IPacketResponder, IPacketResponder +{ + private readonly Game _game; + private readonly EventDispatcher _eventDispatcher; + private readonly IInfoService _infoService; + private readonly ILogger _logger; + + /// + /// Initializes a new instance of the class. + /// + /// The game. + /// The event dispatcher. + /// The info service. + /// The logger. + public MatesSkillResponder + ( + Game game, + EventDispatcher eventDispatcher, + IInfoService infoService, + ILogger logger + ) + { + _game = game; + _eventDispatcher = eventDispatcher; + _infoService = infoService; + _logger = logger; + } + + /// + public async Task Respond(PacketEventArgs packetArgs, CancellationToken ct = default) + { + var packet = packetArgs.Packet; + Skill? skill = null; + if (packet.SkillVNum is not null) + { + var skillInfoResult = await _infoService.GetSkillInfoAsync(packet.SkillVNum.Value, ct); + if (!skillInfoResult.IsDefined(out var skillInfo)) + { + _logger.LogWarning + ( + "Could not obtain skill info for vnum {vnum}: {error}", + packet.SkillVNum.Value, + skillInfoResult.ToFullString() + ); + } + + skill = new Skill(packet.SkillVNum.Value, null, skillInfo); + } + + var mates = await _game.CreateOrUpdateMatesAsync + ( + () => new Mates + { + PetSkill = skill + }, + m => + { + m.PetSkill = skill; + return m; + }, + ct: ct + ); + + return await _eventDispatcher.DispatchEvent + ( + new PetSkillReceivedEvent(mates?.CurrentPet?.Pet, skill), + ct + ); + } + + /// + public async Task Respond(PacketEventArgs packetArgs, CancellationToken ct = default) + { + var packet = packetArgs.Packet; + var skills = new List(); + + foreach (var skillVNum in packet.SkillVNums) + { + if (skillVNum is null) + { + continue; + } + + var skillInfoResult = await _infoService.GetSkillInfoAsync(skillVNum.Value, ct); + if (!skillInfoResult.IsDefined(out var skillInfo)) + { + _logger.LogWarning + ( + "Could not obtain skill info for vnum {vnum}: {error}", + skillVNum, + skillInfoResult.ToFullString() + ); + } + + skills.Add(new Skill(skillVNum.Value, null, skillInfo)); + } + + if (skills.Count == 0) + { + skills = null; + } + + var mates = await _game.CreateOrUpdateMatesAsync + ( + () => new Mates + { + PartnerSkills = skills + }, + m => + { + m.PartnerSkills = skills; + return m; + }, + ct: ct + ); + + return await _eventDispatcher.DispatchEvent + ( + new PartnerSkillsReceivedEvent(mates?.CurrentPartner?.Partner, skills ?? Array.Empty().ToList()), + ct + ); + } +} \ No newline at end of file diff --git a/Core/NosSmooth.Game/PacketHandlers/Skills/PlayerSkillResponder.cs b/Core/NosSmooth.Game/PacketHandlers/Skills/PlayerSkillResponder.cs index 9f4883b..a7738b3 100644 --- a/Core/NosSmooth.Game/PacketHandlers/Skills/PlayerSkillResponder.cs +++ b/Core/NosSmooth.Game/PacketHandlers/Skills/PlayerSkillResponder.cs @@ -14,7 +14,7 @@ using NosSmooth.Game.Events.Core; using NosSmooth.Packets.Server.Skills; using Remora.Results; -namespace NosSmooth.Game.PacketHandlers.Characters; +namespace NosSmooth.Game.PacketHandlers.Skills; /// /// Responds to SkiPacket to add skill to the character. @@ -94,7 +94,7 @@ public class PlayerSkillResponder : IPacketResponder otherSkillsFromCharacter.Add(await CreateSkill(newSkill, default)); } - skills = new Skills(primarySkill, secondarySkill, otherSkillsFromCharacter); + skills = new Data.Characters.Skills(primarySkill, secondarySkill, otherSkillsFromCharacter); await _game.CreateOrUpdateSkillsAsync ( diff --git a/Packets/NosSmooth.Packets/Client/Battle/UsePetSkillPacket.cs b/Packets/NosSmooth.Packets/Client/Battle/UsePetSkillPacket.cs new file mode 100644 index 0000000..c94134f --- /dev/null +++ b/Packets/NosSmooth.Packets/Client/Battle/UsePetSkillPacket.cs @@ -0,0 +1,37 @@ +// +// UsePetSkillPacket.cs +// +// Copyright (c) František Boháček. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using NosSmooth.Packets.Enums.Entities; +using NosSmooth.PacketSerializer.Abstractions.Attributes; + +namespace NosSmooth.Packets.Client.Battle; + +/// +/// Sent to use a pet skill. +/// +/// The pet skill id. +/// The target entity type. +/// The target id. +/// Unknown, seems to always be 1. +/// Unknown, 6 for Otter. +/// Unknown, 9 for Otter. +[PacketHeader("u_pet", PacketSource.Client)] +[GenerateSerializer(true)] +public record UsePetSkillPacket +( + [PacketIndex(0)] + long MateTransportId, + [PacketIndex(1)] + EntityType TargetEntityType, + [PacketIndex(2)] + long TargetId, + [PacketIndex(3)] + byte Unknown, + [PacketIndex(4)] + byte Unknown1, + [PacketIndex(5)] + byte Unknown2 +) : IPacket; \ No newline at end of file diff --git a/Packets/NosSmooth.Packets/Server/Entities/EffectsSubPacket.cs b/Packets/NosSmooth.Packets/Server/Entities/EffectsSubPacket.cs index 84ad65d..63462f6 100644 --- a/Packets/NosSmooth.Packets/Server/Entities/EffectsSubPacket.cs +++ b/Packets/NosSmooth.Packets/Server/Entities/EffectsSubPacket.cs @@ -18,7 +18,7 @@ namespace NosSmooth.Packets.Server.Entities; public record EffectsSubPacket ( [PacketIndex(0)] - long CardId, + short CardId, [PacketIndex(1, IsOptional = true)] short? Level ) : IPacket; \ No newline at end of file diff --git a/Packets/NosSmooth.Packets/Server/Mates/ScNEquipmentSubPacket.cs b/Packets/NosSmooth.Packets/Server/Mates/ScNEquipmentSubPacket.cs index 971d87c..ab6cea0 100644 --- a/Packets/NosSmooth.Packets/Server/Mates/ScNEquipmentSubPacket.cs +++ b/Packets/NosSmooth.Packets/Server/Mates/ScNEquipmentSubPacket.cs @@ -21,9 +21,9 @@ namespace NosSmooth.Packets.Server.Mates; public record ScNEquipmentSubPacket ( [PacketIndex(0)] - long? ItemVNum, + int? ItemVNum, [PacketIndex(1, IsOptional = true)] - long? ItemRare, + sbyte? ItemRare, [PacketIndex(2, IsOptional = true)] - long? ItemUpgrade + byte? ItemUpgrade ) : IPacket; \ No newline at end of file diff --git a/Packets/NosSmooth.Packets/Server/Mates/ScNPacket.cs b/Packets/NosSmooth.Packets/Server/Mates/ScNPacket.cs index 9c3208f..8a2e15b 100644 --- a/Packets/NosSmooth.Packets/Server/Mates/ScNPacket.cs +++ b/Packets/NosSmooth.Packets/Server/Mates/ScNPacket.cs @@ -75,7 +75,7 @@ public record ScNPacket [PacketIndex(6, InnerSeparator = '.')] ScNEquipmentSubPacket? WeaponSubPacket, [PacketIndex(7, InnerSeparator = '.')] - ScNEquipmentSubPacket? ArmodSubPacket, + ScNEquipmentSubPacket? ArmorSubPacket, [PacketIndex(8, InnerSeparator = '.')] ScNEquipmentSubPacket? GauntletSubPacket, [PacketIndex(9, InnerSeparator = '.')] diff --git a/Packets/NosSmooth.Packets/Server/Mates/ScNSkillSubPacket.cs b/Packets/NosSmooth.Packets/Server/Mates/ScNSkillSubPacket.cs index 624c0ce..fbf3132 100644 --- a/Packets/NosSmooth.Packets/Server/Mates/ScNSkillSubPacket.cs +++ b/Packets/NosSmooth.Packets/Server/Mates/ScNSkillSubPacket.cs @@ -21,7 +21,7 @@ namespace NosSmooth.Packets.Server.Mates; public record ScNSkillSubPacket ( [PacketIndex(0)] - long? SkillVNum, + int? SkillVNum, [PacketIndex(1, IsOptional = true)] PartnerSkillRank? Rank ) : IPacket; \ No newline at end of file diff --git a/Samples/FileClient/Responders/InventoryInitializedResponder.cs b/Samples/FileClient/Responders/InventoryInitializedResponder.cs new file mode 100644 index 0000000..4def438 --- /dev/null +++ b/Samples/FileClient/Responders/InventoryInitializedResponder.cs @@ -0,0 +1,52 @@ +// +// InventoryInitializedResponder.cs +// +// Copyright (c) František Boháček. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using NosSmooth.Data.Abstractions.Enums; +using NosSmooth.Data.Abstractions.Language; +using NosSmooth.Game.Data.Items; +using NosSmooth.Game.Events.Core; +using NosSmooth.Game.Events.Inventory; +using NosSmooth.Game.Extensions; +using Remora.Results; + +namespace FileClient.Responders; + +/// +public class InventoryInitializedResponder : IGameResponder +{ + private readonly ILanguageService _languageService; + + /// + /// Initializes a new instance of the class. + /// + /// The langauge service. + public InventoryInitializedResponder(ILanguageService languageService) + { + _languageService = languageService; + + } + + /// + public async Task Respond(InventoryInitializedEvent gameEvent, CancellationToken ct = default) + { + foreach (var bag in gameEvent.Inventory) + { + foreach (var slot in bag) + { + var item = slot.Item; + if (item?.Info is not null && bag.Type != item.Info.BagType) + { + var translatedResult = await _languageService.GetTranslationAsync(item.Info.Name, Language.Cz, ct); + var entity = translatedResult.Entity; + + Console.WriteLine(entity + $", {item.ItemVNum} is: {bag.Type}, should be: {item.Info.BagType.Convert()}"); + } + } + } + + return Result.FromSuccess(); + } +} \ No newline at end of file -- 2.49.0