Skip to content

Commit

Permalink
Implement Arena handling
Browse files Browse the repository at this point in the history
- All packets implemented
- Client-side arena block timer implemented
- SFX names added
- Unknown chat icon name added
- Missing resource IDs added
  • Loading branch information
ethanmoffat committed Apr 6, 2024
1 parent 23d6661 commit 739ecf0
Show file tree
Hide file tree
Showing 13 changed files with 446 additions and 7 deletions.
15 changes: 15 additions & 0 deletions EOLib.Localization/EOResourceID.cs
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,21 @@ public enum EOResourceID
SPELL_ONLY_WORKS_ON_GROUP = 304,
STATUS_LABEL_THE_NPC_DROPPED = 305,

YOU_HAVE_BEEN_FROZEN = 306,

REBOOT_SERVER_REBOOTING = 307,
REBOOT_SEQUENCE_STARTED = 308,

//ARENA_EVENT_ABORTED_LAST_OPPONENT_DC = 309, // not used
ARENA_ROUND_DELAYED_STILL_PLAYERS = 310,
ARENA_WON_EVENT = 311,
ARENA_PLAYERS_LAUNCHED = 312,
ARENA_WAS_ELIMINATED_BY = 313,
ARENA_KILLED = 314,
ARENA_PLAYERS = 315,
ARENA_DO_NOT_BLOCK_LINE = 316,
ARENA_PLEASE_MOVE_FROM_PLACE = 317,

WEDDING_PLEASE_ENTER_NAME = 318,
WEDDING_IS_ASKING_YOU_TO_MARRY = 319,
WEDDING_REGISTRATION_SERVICE = 320,
Expand Down
2 changes: 1 addition & 1 deletion EOLib/Domain/Chat/ChatIcon.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public enum ChatIcon
DotDotDotDot,
GSymbol,
Skeleton,
WhatTheFuck,
Trophy,
Information,
QuestMessage
}
Expand Down
27 changes: 27 additions & 0 deletions EOLib/Domain/Notifiers/IArenaNotifier.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using AutomaticTypeMapper;

namespace EOLib.Domain.Notifiers
{
public interface IArenaNotifier
{
void NotifyArenaBusy();

void NotifyArenaStart(int players);

void NotifyArenaKill(int killCount, string killer, string victim);

void NotifyArenaWin(string winner);
}

[AutoMappedType]
public class NoOpArenaNotifer : IArenaNotifier
{
public void NotifyArenaBusy() { }

public void NotifyArenaStart(int players) { }

public void NotifyArenaKill(int killCount, string killer, string victim) { }

public void NotifyArenaWin(string winner) { }
}
}
8 changes: 7 additions & 1 deletion EOLib/Domain/Notifiers/IChatEventNotifier.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ public enum ChatEventType
AdminChat,
AdminAnnounce,
Group,
Server,
}

public interface IChatEventNotifier
Expand All @@ -18,6 +17,9 @@ public interface IChatEventNotifier
void NotifyPrivateMessageRecipientNotFound(string recipientName);

void NotifyPlayerMutedByAdmin(string adminName);

void NotifyServerMessage(string serverMessage);
void NotifyServerPing(int timeInMS);
}

[AutoMappedType]
Expand All @@ -28,5 +30,9 @@ public void NotifyChatReceived(ChatEventType eventType) { }
public void NotifyPrivateMessageRecipientNotFound(string recipientName) { }

public void NotifyPlayerMutedByAdmin(string adminName) { }

public void NotifyServerMessage(string serverMessage) { }

public void NotifyServerPing(int timeInMS) { }
}
}
48 changes: 48 additions & 0 deletions EOLib/PacketHandlers/Arena/ArenaAcceptHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
using AutomaticTypeMapper;
using EOLib.Domain.Login;
using EOLib.Domain.Notifiers;
using EOLib.Net;
using EOLib.Net.Handlers;
using System.Collections.Generic;

namespace EOLib.PacketHandlers.Arena
{
/// <summary>
/// Arena win message
/// </summary>
[AutoMappedType]
public class ArenaAcceptHandler : InGameOnlyPacketHandler
{
private readonly IEnumerable<IArenaNotifier> _arenaNotifiers;

public override PacketFamily Family => PacketFamily.Arena;

public override PacketAction Action => PacketAction.Accept;

public ArenaAcceptHandler(IPlayerInfoProvider playerInfoProvider,
IEnumerable<IArenaNotifier> arenaNotifiers)
: base(playerInfoProvider)
{
_arenaNotifiers = arenaNotifiers;
}

public override bool HandlePacket(IPacket packet)
{
var winnerName = packet.ReadBreakString();

var killsCount = packet.ReadInt();
packet.ReadByte();

var killerName = packet.ReadBreakString();
var victimName = packet.ReadBreakString();

foreach (var notifier in _arenaNotifiers)
{
notifier.NotifyArenaKill(killsCount, killerName, victimName);
notifier.NotifyArenaWin(winnerName);
}

return true;
}
}
}
42 changes: 42 additions & 0 deletions EOLib/PacketHandlers/Arena/ArenaDropHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using AutomaticTypeMapper;
using EOLib.Domain.Login;
using EOLib.Domain.Notifiers;
using EOLib.Net;
using EOLib.Net.Handlers;
using System.Collections.Generic;

namespace EOLib.PacketHandlers.Arena
{
/// <summary>
/// "Arena is blocked" message
/// </summary>
[AutoMappedType]
public class ArenaDropHandler : InGameOnlyPacketHandler
{
private readonly IEnumerable<IArenaNotifier> _arenaNotifiers;

public override PacketFamily Family => PacketFamily.Arena;

public override PacketAction Action => PacketAction.Drop;

public ArenaDropHandler(IPlayerInfoProvider playerInfoProvider,
IEnumerable<IArenaNotifier> arenaNotifiers)
: base(playerInfoProvider)
{
_arenaNotifiers = arenaNotifiers;
}

public override bool HandlePacket(IPacket packet)
{
if (packet.ReadEndString().Length < 1)
return false;

foreach (var notifier in _arenaNotifiers)
{
notifier.NotifyArenaBusy();
}

return true;
}
}
}
76 changes: 76 additions & 0 deletions EOLib/PacketHandlers/Arena/ArenaSpecHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
using AutomaticTypeMapper;
using EOLib.Domain.Character;
using EOLib.Domain.Login;
using EOLib.Domain.Map;
using EOLib.Domain.Notifiers;
using EOLib.Net;
using EOLib.Net.Handlers;
using System.Collections.Generic;

namespace EOLib.PacketHandlers.Arena
{
/// <summary>
/// Arena kill message
/// </summary>
[AutoMappedType]
public class ArenaSpecHandler : InGameOnlyPacketHandler
{
private readonly ICharacterRepository _characterRepository;
private readonly ICurrentMapStateRepository _currentMapStateRepository;
private readonly IEnumerable<IArenaNotifier> _arenaNotifiers;

public override PacketFamily Family => PacketFamily.Arena;

public override PacketAction Action => PacketAction.Spec;

public ArenaSpecHandler(IPlayerInfoProvider playerInfoProvider,
ICharacterRepository characterRepository,
ICurrentMapStateRepository currentMapStateRepository,
IEnumerable<IArenaNotifier> arenaNotifiers)
: base(playerInfoProvider)
{
_characterRepository = characterRepository;
_currentMapStateRepository = currentMapStateRepository;
_arenaNotifiers = arenaNotifiers;
}

public override bool HandlePacket(IPacket packet)
{
var playerId = packet.ReadShort();
packet.ReadByte();

var playerDirection = (EODirection)packet.ReadChar();
packet.ReadByte();

if (playerId == _characterRepository.MainCharacter.ID)
{
var rp = _characterRepository.MainCharacter.RenderProperties.WithDirection(playerDirection);
_characterRepository.MainCharacter = _characterRepository.MainCharacter.WithRenderProperties(rp);
}
else if (_currentMapStateRepository.Characters.ContainsKey(playerId))
{
var character = _currentMapStateRepository.Characters[playerId];
var rp = character.RenderProperties.WithDirection(playerDirection);
var newCharacter = character.WithRenderProperties(rp);
_currentMapStateRepository.Characters.Update(character, newCharacter);
}
else if (playerId > 0)
{
_currentMapStateRepository.UnknownPlayerIDs.Add(playerId);
}

var killsCount = packet.ReadInt();
packet.ReadByte();

var killerName = packet.ReadBreakString();
var victimName = packet.ReadBreakString();

foreach (var notifier in _arenaNotifiers)
{
notifier.NotifyArenaKill(killsCount, killerName, victimName);
}

return true;
}
}
}
41 changes: 41 additions & 0 deletions EOLib/PacketHandlers/Arena/ArenaUseHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
using AutomaticTypeMapper;
using EOLib.Domain.Login;
using EOLib.Domain.Notifiers;
using EOLib.Net;
using EOLib.Net.Handlers;
using System.Collections.Generic;

namespace EOLib.PacketHandlers.Arena
{
/// <summary>
/// Arena start message
/// </summary>
[AutoMappedType]
public class ArenaUseHandler : InGameOnlyPacketHandler
{
private readonly IEnumerable<IArenaNotifier> _arenaNotifiers;

public override PacketFamily Family => PacketFamily.Arena;

public override PacketAction Action => PacketAction.Use;

public ArenaUseHandler(IPlayerInfoProvider playerInfoProvider,
IEnumerable<IArenaNotifier> arenaNotifiers)
: base(playerInfoProvider)
{
_arenaNotifiers = arenaNotifiers;
}

public override bool HandlePacket(IPacket packet)
{
var playersCount = packet.ReadChar();

foreach (var notifier in _arenaNotifiers)
{
notifier.NotifyArenaStart(playersCount);
}

return true;
}
}
}
1 change: 1 addition & 0 deletions EndlessClient/Audio/SoundEffectID.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ public enum SoundEffectID
Guitar3,
Thunder,
MapEvacTimer,
ArenaTickSound = MapEvacTimer,
ArenaWin = 52,
Gun,
UltimaBlastSpell,
Expand Down
15 changes: 12 additions & 3 deletions EndlessClient/HUD/Controls/HudControlsFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ public class HudControlsFactory : IHudControlsFactory
private readonly IPathFinder _pathFinder;
private readonly ICharacterActions _characterActions;
private readonly IWalkValidationActions _walkValidationActions;
private readonly IChatBubbleActions _chatBubbleActions;
private readonly IPacketSendService _packetSendService;
private readonly IUserInputTimeProvider _userInputTimeProvider;
private readonly ISpellSlotDataRepository _spellSlotDataRepository;
Expand All @@ -70,7 +71,7 @@ public class HudControlsFactory : IHudControlsFactory
private readonly IFixedTimeStepRepository _fixedTimeStepRepository;
private readonly IClickDispatcherFactory _clickDispatcherFactory;
private readonly IMetadataProvider<WeaponMetadata> _weaponMetadataProvider;

private readonly ILocalizedStringFinder _localizedStringFinder;
private IChatController _chatController;
private IMainButtonController _mainButtonController;

Expand All @@ -95,6 +96,7 @@ public HudControlsFactory(IHudButtonController hudButtonController,
IPathFinder pathFinder,
ICharacterActions characterActions,
IWalkValidationActions walkValidationActions,
IChatBubbleActions chatBubbleActions,
IPacketSendService packetSendService,
IUserInputTimeProvider userInputTimeProvider,
ISpellSlotDataRepository spellSlotDataRepository,
Expand All @@ -103,7 +105,8 @@ public HudControlsFactory(IHudButtonController hudButtonController,
INewsProvider newsProvider,
IFixedTimeStepRepository fixedTimeStepRepository,
IClickDispatcherFactory clickDispatcherFactory,
IMetadataProvider<WeaponMetadata> weaponMetadataProvider)
IMetadataProvider<WeaponMetadata> weaponMetadataProvider,
ILocalizedStringFinder localizedStringFinder)
{
_hudButtonController = hudButtonController;
_hudPanelFactory = hudPanelFactory;
Expand All @@ -126,6 +129,7 @@ public HudControlsFactory(IHudButtonController hudButtonController,
_pathFinder = pathFinder;
_characterActions = characterActions;
_walkValidationActions = walkValidationActions;
_chatBubbleActions = chatBubbleActions;
_packetSendService = packetSendService;
_userInputTimeProvider = userInputTimeProvider;
_spellSlotDataRepository = spellSlotDataRepository;
Expand All @@ -135,6 +139,7 @@ public HudControlsFactory(IHudButtonController hudButtonController,
_fixedTimeStepRepository = fixedTimeStepRepository;
_clickDispatcherFactory = clickDispatcherFactory;
_weaponMetadataProvider = weaponMetadataProvider;
_localizedStringFinder = localizedStringFinder;
}

public void InjectChatController(IChatController chatController,
Expand Down Expand Up @@ -580,7 +585,11 @@ private INPCAnimator CreateNPCAnimator()

private IPeriodicEmoteHandler CreatePeriodicEmoteHandler(ICharacterAnimator characterAnimator)
{
return new PeriodicEmoteHandler(_endlessGameProvider, _characterActions, _userInputTimeProvider, _characterRepository, characterAnimator, _statusLabelSetter, _mainButtonController);
return new PeriodicEmoteHandler(
_endlessGameProvider, _characterActions, _chatBubbleActions,
_userInputTimeProvider, _characterRepository, characterAnimator,
_statusLabelSetter, _mainButtonController, _localizedStringFinder,
_sfxPlayer);
}

private PreviousUserInputTracker CreatePreviousUserInputTracker()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ public void StartWalking(Option<MapCoordinate> targetCoordinate)
if (!_hudControlProvider.IsInGame)
return;

_hudControlProvider.GetComponent<IPeriodicEmoteHandler>(HudControlIdentifier.PeriodicEmoteHandler).CancelArenaBlockTimer();

CancelSpellPrep();
Animator.StartMainCharacterWalkAnimation(targetCoordinate, () =>
{
Expand Down
Loading

0 comments on commit 739ecf0

Please sign in to comment.