//
// CharacterInitResponder.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.Core.Packets;
using NosSmooth.Game.Data.Info;
using NosSmooth.Game.Data.Social;
using NosSmooth.Game.Events.Characters;
using NosSmooth.Game.Events.Core;
using NosSmooth.Packets.Packets.Server.Players;
using Remora.Results;
namespace NosSmooth.Game.PacketHandlers.Characters;
///
/// Responds to CInfoPacket by creating the character.
///
public class CharacterInitResponder : IPacketResponder, IPacketResponder, IPacketResponder
{
private readonly Game _game;
private readonly EventDispatcher _eventDispatcher;
///
/// Initializes a new instance of the class.
///
/// The nostale game.
/// The event dispatcher.
public CharacterInitResponder(Game game, EventDispatcher eventDispatcher)
{
_game = game;
_eventDispatcher = eventDispatcher;
}
///
public async Task Respond(PacketEventArgs packetArgs, CancellationToken ct = default)
{
var oldCharacter = _game.Character;
var character = oldCharacter;
var packet = packetArgs.Packet;
await _game.EnsureCharacterCreatedAsync(false, ct).ConfigureAwait(false);
if (character is not null)
{
_game.Character = character = character with
{
Id = packet.CharacterId,
AuthorityType = packet.Authority,
Sex = packet.Sex,
HairStyle = packet.HairStyle,
HairColor = packet.HairColor,
Class = packet.Class,
Icon = packet.Icon,
Compliment = packet.Compliment,
Morph = (character.Morph ?? new Morph(packet.MorphVNum, packet.MorphUpgrade)) with
{
VNum = packet.MorphVNum, Upgrade = packet.MorphUpgrade
},
ArenaWinner = packet.ArenaWinner,
Invisible = packet.IsInvisible,
Family = new Family(packet.FamilyId, packet.FamilyName, packet.FamilyLevel)
};
}
_game.SetSemaphore.Release();
if (character is not null && character != oldCharacter)
{
return await _eventDispatcher.DispatchEvent(new ReceivedCharacterDataEvent(oldCharacter, character), ct);
}
return Result.FromSuccess();
}
///
public async Task Respond(PacketEventArgs packetArgs, CancellationToken ct = default)
{
var packet = packetArgs.Packet;
await _game.EnsureCharacterCreatedAsync(false, ct).ConfigureAwait(false);
var oldCharacter = _game.Character;
var character = oldCharacter;
if (character is not null)
{
_game.Character = character = character with
{
SkillCp = packet.SkillCp,
Reputation = packet.Reputation,
Level = new Level(packet.Level, packet.LevelXp, packet.XpLoad),
JobLevel = new Level(packet.JobLevel, packet.JobLevelXp, packet.JobXpLoad),
HeroLevel = new Level(packet.HeroLevel, packet.HeroXp, packet.HeroXpLoad)
};
}
_game.SetSemaphore.Release();
if (character is not null && character != oldCharacter)
{
return await _eventDispatcher.DispatchEvent(new ReceivedCharacterDataEvent(oldCharacter, character), ct);
}
return Result.FromSuccess();
}
///
public async Task Respond(PacketEventArgs packetArgs, CancellationToken ct = default)
{
var packet = packetArgs.Packet;
var oldCharacter = _game.Character;
var character = oldCharacter;
if (character is null || character.Id != packetArgs.Packet.EntityId)
{ // Not the current character.
return Result.FromSuccess();
}
await _game.SetSemaphore.WaitAsync(ct);
character = character with
{
Morph = new Morph
(
packet.MorphVNum,
packet.MorphUpgrade,
packet.MorphDesign,
packet.MorphBonus,
packet.MorphSkin
),
Size = packet.Size
};
_game.SetSemaphore.Release();
if (oldCharacter != character)
{
return await _eventDispatcher.DispatchEvent(new ReceivedCharacterDataEvent(oldCharacter, character), ct);
}
return Result.FromSuccess();
}
}