Skip to content

Commit

Permalink
Properly implement CHEST_CLOSE and DOOR_CLOSE packets (#406)
Browse files Browse the repository at this point in the history
* Remove JammedDoor tilespec type (not officially defined)
* Implement locked/broken chest/door server packets (CHEST_CLOSE and DOOR_CLOSE)
  • Loading branch information
ethanmoffat committed Jan 29, 2025
1 parent 0f8a279 commit 59c9911
Show file tree
Hide file tree
Showing 16 changed files with 179 additions and 12 deletions.
2 changes: 1 addition & 1 deletion EOLib.IO/EOLib.IO.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AutomaticTypeMapper" Version="1.4.1" />
<PackageReference Include="Moffat.EndlessOnline.SDK" Version="1.0.0" />
<PackageReference Include="Moffat.EndlessOnline.SDK" Version="1.0.1" />
<PackageReference Include="System.Memory" Version="4.5.5" />
</ItemGroup>
<ItemGroup>
Expand Down
1 change: 0 additions & 1 deletion EOLib.IO/Map/TileSpec.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ public enum TileSpec : byte
ChairDownRight = 5,
ChairUpLeft = 6,
ChairAll = 7,
JammedDoor = 8,
Chest = 9,
BankVault = 16,
NPCBoundary = 17,
Expand Down
2 changes: 1 addition & 1 deletion EOLib.Localization/EOLib.Localization.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="AutomaticTypeMapper" Version="1.4.1" />
<PackageReference Include="Moffat.EndlessOnline.SDK" Version="1.0.0" />
<PackageReference Include="Moffat.EndlessOnline.SDK" Version="1.0.1" />
</ItemGroup>
</Project>
4 changes: 2 additions & 2 deletions EOLib.Localization/EOResourceID.cs
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,8 @@ public enum EOResourceID
DIALOG_TRANSFER_NOT_ENOUGH_WEIGHT = 108,
STATUS_LABEL_TRADE_OTHER_PLAYER_CHANGED_OFFER = 109,
//STATUS_LABEL_CHEST_YOU_OPENED = 110, //duplicate of 92?
//chest seems broken - not sure when this is used
//door seems broken - not sure when this is used
STATUS_LABEL_THE_CHEST_SEEMS_BROKEN = 111,
STATUS_LABEL_THE_DOOR_SEEMS_BROKEN = 112,
STATUS_LABEL_THE_CHEST_IS_LOCKED_EXCLAMATION = 113,
STATUS_LABEL_THE_DOOR_IS_LOCKED_EXCLAMATION = 114,
STATUS_LABEL_DRAG_AND_DROP_ITEMS = 115,
Expand Down
3 changes: 1 addition & 2 deletions EOLib/Domain/Character/WalkValidationActions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,6 @@ private bool IsTileSpecWalkable(TileSpec tileSpec)
case TileSpec.ChairDownRight:
case TileSpec.ChairUpLeft:
case TileSpec.ChairAll:
case TileSpec.JammedDoor:
case TileSpec.Chest:
case TileSpec.BankVault:
case TileSpec.MapEdge:
Expand Down Expand Up @@ -149,7 +148,7 @@ private bool IsTileSpecWalkable(TileSpec tileSpec)
default:
// These values were tested with the Vanilla 0.28 client
// TileSpec 10, 12, and 31 are walkable while other unknown values are not
return (int)tileSpec == 10 || (int)tileSpec == 12 || (int)tileSpec == 31;
return (int)tileSpec == 8 || (int)tileSpec == 10 || (int)tileSpec == 12 || (int)tileSpec == 31;
}
}

Expand Down
4 changes: 3 additions & 1 deletion EOLib/Domain/Notifiers/IChestEventNotifier.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using EOLib.IO.Map;
using AutomaticTypeMapper;
using EOLib.IO.Map;

namespace EOLib.Domain.Notifiers
{
Expand All @@ -9,6 +10,7 @@ public interface IChestEventNotifier
void NotifyChestBroken();
}

[AutoMappedType]
public class NoOpChestEventNotifier : IChestEventNotifier
{
public void NotifyChestLocked(ChestKey key) { }
Expand Down
16 changes: 16 additions & 0 deletions EOLib/Domain/Notifiers/IDoorEventNotifier.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using AutomaticTypeMapper;
using EOLib.IO.Map;

namespace EOLib.Domain.Notifiers
{
public interface IDoorEventNotifier
{
void NotifyDoorLocked(ChestKey key);
}

[AutoMappedType]
public class NoOpDoorEventNotifier : IDoorEventNotifier
{
public void NotifyDoorLocked(ChestKey key) { }
}
}
2 changes: 1 addition & 1 deletion EOLib/EOLib.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
<ItemGroup>
<PackageReference Include="Amadevus.RecordGenerator" Version="0.6.0" />
<PackageReference Include="AutomaticTypeMapper" Version="1.4.1" />
<PackageReference Include="Moffat.EndlessOnline.SDK" Version="1.0.0" />
<PackageReference Include="Moffat.EndlessOnline.SDK" Version="1.0.1" />
<PackageReference Include="Optional" Version="4.0.0" />
</ItemGroup>
</Project>
5 changes: 5 additions & 0 deletions EOLib/PacketHandlers/Chest/ChestCloseHandler.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using AutomaticTypeMapper;
using EOLib.Domain.Login;
using EOLib.Domain.Notifiers;
using EOLib.IO.Map;
Expand All @@ -8,6 +9,10 @@

namespace EOLib.PacketHandlers.Chest
{
/// <summary>
/// Sent when a chest is locked or broken (key invalid)
/// </summary>
[AutoMappedType]
public class ChestCloseHandler : InGameOnlyPacketHandler<ChestCloseServerPacket>
{
private readonly IEnumerable<IChestEventNotifier> _chestEventNotifiers;
Expand Down
39 changes: 39 additions & 0 deletions EOLib/PacketHandlers/Door/DoorCloseHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using System.Collections.Generic;
using AutomaticTypeMapper;
using EOLib.Domain.Login;
using EOLib.Domain.Notifiers;
using EOLib.IO.Map;
using EOLib.Net.Handlers;
using Moffat.EndlessOnline.SDK.Protocol.Net;
using Moffat.EndlessOnline.SDK.Protocol.Net.Server;

namespace EOLib.PacketHandlers.Door
{
/// <summary>
/// Sent when a door is locked
/// </summary>
[AutoMappedType]
public class DoorCloseHandler : InGameOnlyPacketHandler<DoorCloseServerPacket>
{
private readonly IEnumerable<IDoorEventNotifier> _doorEventNotifiers;

public override PacketFamily Family => PacketFamily.Door;

public override PacketAction Action => PacketAction.Close;

public DoorCloseHandler(IPlayerInfoProvider playerInfoProvider,
IEnumerable<IDoorEventNotifier> doorEventNotifiers)
: base(playerInfoProvider)
{
_doorEventNotifiers = doorEventNotifiers;
}

public override bool HandlePacket(DoorCloseServerPacket packet)
{
foreach (var notifier in _doorEventNotifiers)
notifier.NotifyDoorLocked((ChestKey)packet.Key);

return true;
}
}
}
2 changes: 1 addition & 1 deletion EndlessClient/EndlessClient.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
<PackageReference Include="Amadevus.RecordGenerator" Version="0.6.0" />
<PackageReference Include="EndlessClient.Binaries" Version="$(EndlessClientBinariesPackageVersion)" />
<PackageReference Include="managed-midi" Version="1.10.1" />
<PackageReference Include="Moffat.EndlessOnline.SDK" Version="1.0.0" />
<PackageReference Include="Moffat.EndlessOnline.SDK" Version="1.0.1" />
<PackageReference Include="Monogame.Content.Builder.Task" Version="3.8.2.1105" />
<PackageReference Include="MonoGame.Extended.Content.Pipeline" Version="3.8.0" />
<PackageReference Include="MonoGame.Extended.Input" Version="3.8.0" />
Expand Down
2 changes: 1 addition & 1 deletion EndlessClient/Rendering/Map/MiniMapRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ protected override void OnDrawControl(GameTime gameTime)
case TileSpec.ChairDownRight:
case TileSpec.ChairUpLeft:
case TileSpec.Chest:
case TileSpec.JammedDoor:
case (TileSpec)8:
// Unknown TileSpecs 10-15 have been confirmed in the vanilla client to show a Blue ! on the minimap
case (TileSpec)10:
case (TileSpec)11:
Expand Down
1 change: 0 additions & 1 deletion EndlessClient/Rendering/MouseCursorRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,6 @@ private void UpdateCursorIndexForTileSpec(TileSpec tileSpec)
switch (tileSpec)
{
case TileSpec.Wall:
case TileSpec.JammedDoor:
case TileSpec.MapEdge:
case TileSpec.FakeWall:
case TileSpec.VultTypo:
Expand Down
58 changes: 58 additions & 0 deletions EndlessClient/Subscribers/ChestEventSubscriber.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
using AutomaticTypeMapper;
using EndlessClient.Audio;
using EndlessClient.Dialogs;
using EndlessClient.Dialogs.Factories;
using EndlessClient.HUD;
using EOLib.Domain.Map;
using EOLib.Domain.Notifiers;
using EOLib.IO.Map;
using EOLib.Localization;

namespace EndlessClient.Subscribers
{
[AutoMappedType]
public class ChestEventSubscriber : IChestEventNotifier
{
private readonly IEOMessageBoxFactory _messageBoxFactory;
private readonly IActiveDialogRepository _activeDialogRepository;
private readonly ISfxPlayer _sfxPlayer;
private readonly IUnlockChestValidator _unlockChestValidator;
private readonly IStatusLabelSetter _statusLabelSetter;

public ChestEventSubscriber(IEOMessageBoxFactory messageBoxFactory,
IActiveDialogRepository activeDialogRepository,
IUnlockChestValidator unlockChestValidator,
IStatusLabelSetter statusLabelSetter,
ISfxPlayer sfxPlayer)
{
_messageBoxFactory = messageBoxFactory;
_activeDialogRepository = activeDialogRepository;
_unlockChestValidator = unlockChestValidator;
_statusLabelSetter = statusLabelSetter;
_sfxPlayer = sfxPlayer;
}

public void NotifyChestBroken()
{
_activeDialogRepository.ChestDialog.MatchSome(x => x.Close());

var dlg = _messageBoxFactory.CreateMessageBox(DialogResourceID.CHEST_BROKEN);
dlg.ShowDialog();

_statusLabelSetter.SetStatusLabel(EOResourceID.STATUS_LABEL_TYPE_WARNING, EOResourceID.STATUS_LABEL_THE_CHEST_SEEMS_BROKEN);
}

public void NotifyChestLocked(ChestKey key)
{
_activeDialogRepository.ChestDialog.MatchSome(x => x.Close());

var dlg = _messageBoxFactory.CreateMessageBox(DialogResourceID.CHEST_LOCKED);
dlg.ShowDialog();

var requiredKey = _unlockChestValidator.GetRequiredKeyName(key);
_statusLabelSetter.SetStatusLabel(EOResourceID.STATUS_LABEL_TYPE_WARNING, EOResourceID.STATUS_LABEL_THE_CHEST_IS_LOCKED_EXCLAMATION, requiredKey.Match(x => $" - {x}", () => string.Empty));

_sfxPlayer.PlaySfx(SoundEffectID.DoorOrChestLocked);
}
}
}
39 changes: 39 additions & 0 deletions EndlessClient/Subscribers/DoorEventSubscriber.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using AutomaticTypeMapper;
using EndlessClient.Audio;
using EndlessClient.Dialogs.Factories;
using EndlessClient.HUD;
using EOLib.Domain.Notifiers;
using EOLib.IO.Map;
using EOLib.Localization;

namespace EndlessClient.Subscribers
{
[AutoMappedType]
public class DoorEventSubscriber : IDoorEventNotifier
{
private readonly IEOMessageBoxFactory _messageBoxFactory;
private readonly ISfxPlayer _sfxPlayer;
private readonly IStatusLabelSetter _statusLabelSetter;

public DoorEventSubscriber(IEOMessageBoxFactory messageBoxFactory,
IStatusLabelSetter statusLabelSetter,
ISfxPlayer sfxPlayer)
{
_messageBoxFactory = messageBoxFactory;
_statusLabelSetter = statusLabelSetter;
_sfxPlayer = sfxPlayer;
}

public void NotifyDoorLocked(ChestKey key)
{
var dlg = _messageBoxFactory.CreateMessageBox(DialogResourceID.DOOR_LOCKED);
dlg.ShowDialog();

_statusLabelSetter.SetStatusLabel(EOResourceID.STATUS_LABEL_TYPE_WARNING,
EOResourceID.STATUS_LABEL_THE_DOOR_IS_LOCKED_EXCLAMATION,
$" - {key}");

_sfxPlayer.PlaySfx(SoundEffectID.DoorOrChestLocked);
}
}
}
11 changes: 11 additions & 0 deletions EndlessClient/Subscribers/IChestEventSubscriber.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using EOLib.IO.Map;

namespace EndlessClient.Subscribers
{
public interface IChestEventSubscriber
{
void NotifyChestBroken();

void NotifyChestLocked(ChestKey key);
}
}

0 comments on commit 59c9911

Please sign in to comment.