Skip to content

Commit

Permalink
Add sound effects for some map interactions
Browse files Browse the repository at this point in the history
  • Loading branch information
ethanmoffat committed May 14, 2022
1 parent 90670f8 commit e33bb5c
Show file tree
Hide file tree
Showing 11 changed files with 109 additions and 21 deletions.
5 changes: 4 additions & 1 deletion EOLib.IO/Map/MapEffect.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ public enum MapEffect : byte
Quake1 = 3,
Quake2 = 4,
Quake3 = 5,
Quake4 = 6
Quake4 = 6,

// not a recognized value for IO; used internally
Spikes = 0x7f
}
}
5 changes: 3 additions & 2 deletions EOLib/Domain/Notifiers/IEffectNotifier.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using AutomaticTypeMapper;
using EOLib.Domain.Map;
using EOLib.IO.Map;

namespace EOLib.Domain.Notifiers
{
Expand All @@ -8,7 +9,7 @@ public interface IEffectNotifier
void NotifyWarpLeaveEffect(short characterId, WarpAnimation anim);
void NotifyWarpEnterEffect(short characterId, WarpAnimation anim);
void NotifyPotionEffect(short playerId, int effectId);
void NotifyEarthquake(byte strength);
void NotifyMapEffect(MapEffect effect, byte strength = 0);
}

[AutoMappedType]
Expand All @@ -17,6 +18,6 @@ public class NoOpEffectNotifier : IEffectNotifier
public void NotifyWarpLeaveEffect(short characterId, WarpAnimation anim) { }
public void NotifyWarpEnterEffect(short characterId, WarpAnimation anim) { }
public void NotifyPotionEffect(short playerId, int effectId) { }
public void NotifyEarthquake(byte strength) { }
public void NotifyMapEffect(MapEffect effect, byte strength = 0) { }
}
}
9 changes: 8 additions & 1 deletion EOLib/PacketHandlers/Effects/MapDebuffHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using EOLib.Domain.Character;
using EOLib.Domain.Login;
using EOLib.Domain.Notifiers;
using EOLib.IO.Map;
using EOLib.Net;
using EOLib.Net.Handlers;
using System;
Expand All @@ -17,18 +18,21 @@ public class MapDebuffHandler : InGameOnlyPacketHandler

private readonly ICharacterRepository _characterRepository;
private readonly IEnumerable<IMainCharacterEventNotifier> _mainCharacterEventNotifiers;
private readonly IEnumerable<IEffectNotifier> _effectNotifiers;

public override PacketFamily Family => PacketFamily.Effect;

public override PacketAction Action => PacketAction.Spec;

public MapDebuffHandler(IPlayerInfoProvider playerInfoProvider,
ICharacterRepository characterRepository,
IEnumerable<IMainCharacterEventNotifier> mainCharacterEventNotifiers)
IEnumerable<IMainCharacterEventNotifier> mainCharacterEventNotifiers,
IEnumerable<IEffectNotifier> effectNotifiers)
: base(playerInfoProvider)
{
_characterRepository = characterRepository;
_mainCharacterEventNotifiers = mainCharacterEventNotifiers;
_effectNotifiers = effectNotifiers;
}

public override bool HandlePacket(IPacket packet)
Expand All @@ -50,6 +54,9 @@ public override bool HandlePacket(IPacket packet)
_characterRepository.MainCharacter = character.WithStats(
originalStats.WithNewStat(CharacterStat.TP, tp)
.WithNewStat(CharacterStat.MaxTP, maxTp));

foreach (var notifier in _effectNotifiers)
notifier.NotifyMapEffect(MapEffect.TPDrain);
}
break;
case EFFECT_DAMAGE_SPIKE:
Expand Down
11 changes: 9 additions & 2 deletions EOLib/PacketHandlers/Effects/MapHpDrainHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using EOLib.Domain.Extensions;
using EOLib.Domain.Login;
using EOLib.Domain.Notifiers;
using EOLib.IO.Map;
using EOLib.Net;
using EOLib.Net.Handlers;
using System;
Expand All @@ -17,6 +18,7 @@ public class MapHpDrainHandler : InGameOnlyPacketHandler
private readonly ICharacterRepository _characterRepository;
private readonly IEnumerable<IMainCharacterEventNotifier> _mainCharacterEventNotifiers;
private readonly IEnumerable<IOtherCharacterEventNotifier> _otherCharacterEventNotifiers;
private readonly IEnumerable<IEffectNotifier> _effectNotifiers;

public override PacketFamily Family => PacketFamily.Effect;

Expand All @@ -25,12 +27,14 @@ public class MapHpDrainHandler : InGameOnlyPacketHandler
public MapHpDrainHandler(IPlayerInfoProvider playerInfoProvider,
ICharacterRepository characterRepository,
IEnumerable<IMainCharacterEventNotifier> mainCharacterEventNotifiers,
IEnumerable<IOtherCharacterEventNotifier> otherCharacterEventNotifiers)
IEnumerable<IOtherCharacterEventNotifier> otherCharacterEventNotifiers,
IEnumerable<IEffectNotifier> effectNotifiers)
: base(playerInfoProvider)
{
_characterRepository = characterRepository;
_mainCharacterEventNotifiers = mainCharacterEventNotifiers;
_otherCharacterEventNotifiers = otherCharacterEventNotifiers;
_effectNotifiers = effectNotifiers;
}

public override bool HandlePacket(IPacket packet)
Expand All @@ -42,7 +46,10 @@ public override bool HandlePacket(IPacket packet)
_characterRepository.MainCharacter = _characterRepository.MainCharacter.WithDamage(damage, hp == 0);

foreach (var notifier in _mainCharacterEventNotifiers)
notifier.NotifyTakeDamage(damage, (int)Math.Round((double)hp / maxhp), isHeal: false);
notifier.NotifyTakeDamage(damage, (int)Math.Round(((double)hp / maxhp) * 100), isHeal: false);

foreach (var notifier in _effectNotifiers)
notifier.NotifyMapEffect(MapEffect.HPDrain);

while (packet.ReadPosition != packet.Length)
{
Expand Down
3 changes: 2 additions & 1 deletion EOLib/PacketHandlers/Effects/MapQuakeHandler.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using AutomaticTypeMapper;
using EOLib.Domain.Login;
using EOLib.Domain.Notifiers;
using EOLib.IO.Map;
using EOLib.Net;
using EOLib.Net.Handlers;
using System.Collections.Generic;
Expand Down Expand Up @@ -32,7 +33,7 @@ public override bool HandlePacket(IPacket packet)
var strength = packet.ReadChar();

foreach (var notifier in _effectNotifiers)
notifier.NotifyEarthquake(strength);
notifier.NotifyMapEffect(MapEffect.Quake1, strength);

return true;
}
Expand Down
19 changes: 15 additions & 4 deletions EOLib/PacketHandlers/Effects/TimedSpikeEffectHandler.cs
Original file line number Diff line number Diff line change
@@ -1,26 +1,37 @@
using AutomaticTypeMapper;
using EOLib.Domain.Login;
using EOLib.Domain.Notifiers;
using EOLib.IO.Map;
using EOLib.Net;
using EOLib.Net.Handlers;
using System.Collections.Generic;

namespace EOLib.PacketHandlers.Effects
{
[AutoMappedType]
public class TimedSpikeEffectHandler : InGameOnlyPacketHandler
{
private readonly IEnumerable<IEffectNotifier> _effectNotifiers;

public override PacketFamily Family => PacketFamily.Effect;

public override PacketAction Action => PacketAction.Report;

public TimedSpikeEffectHandler(IPlayerInfoProvider playerInfoProvider)
: base(playerInfoProvider) { }
public TimedSpikeEffectHandler(IPlayerInfoProvider playerInfoProvider,
IEnumerable<IEffectNotifier> effectNotifiers)
: base(playerInfoProvider)
{
_effectNotifiers = effectNotifiers;
}

public override bool HandlePacket(IPacket packet)
{
if ((char)packet.ReadChar() != 'S')
if ((char)packet.ReadByte() != 'S')
return false;

// todo: play sound effect for timed spikes
foreach (var notifier in _effectNotifiers)
notifier.NotifyMapEffect(MapEffect.Spikes);

return true;
}
}
Expand Down
2 changes: 1 addition & 1 deletion EndlessClient/Controllers/ArrowKeyController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ private void AttemptToStartWalking()
coordinate = new MapCoordinate(
_characterProvider.MainCharacter.RenderProperties.GetDestinationX(),
_characterProvider.MainCharacter.RenderProperties.GetDestinationY());
_spikeTrapActions.ShowSpikeTrap(coordinate);
_spikeTrapActions.ShowSpikeTrap(coordinate, isMainCharacter: true);
}
}
}
Expand Down
40 changes: 36 additions & 4 deletions EndlessClient/Rendering/Character/CharacterAnimationActions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,11 @@ public void StartWalking()
CancelSpellPrep();
Animator.StartMainCharacterWalkAnimation(Option.None<MapCoordinate>());
ShowWaterSplashiesIfNeeded(CharacterActionState.Walking, _characterRepository.MainCharacter.ID);

if (_characterRepository.MainCharacter.NoWall)
_sfxPlayer.PlaySfx(SoundEffectID.NoWallWalk);
else if (IsSteppingStone(_characterRepository.MainCharacter.RenderProperties))
_sfxPlayer.PlaySfx(SoundEffectID.JumpStone);
}

public void StartAttacking(int noteIndex = -1)
Expand Down Expand Up @@ -117,14 +122,17 @@ public void Emote(Emote whichEmote)

public void StartOtherCharacterWalkAnimation(int characterID, byte destinationX, byte destinationY, EODirection direction)
{
if (!_hudControlProvider.IsInGame)
if (!_hudControlProvider.IsInGame || !_currentMapStateProvider.Characters.ContainsKey(characterID))
return;

Animator.StartOtherCharacterWalkAnimation(characterID, destinationX, destinationY, direction);

ShowWaterSplashiesIfNeeded(CharacterActionState.Walking, characterID);
_spikeTrapActions.HideSpikeTrap(characterID);
_spikeTrapActions.ShowSpikeTrap(characterID);

if (IsSteppingStone(_currentMapStateProvider.Characters[characterID].RenderProperties))
_sfxPlayer.PlaySfx(SoundEffectID.JumpStone);
}

public void StartOtherCharacterAttackAnimation(int characterID, int noteIndex = -1)
Expand Down Expand Up @@ -223,10 +231,28 @@ public void NotifyTargetOtherSpellCast(short sourcePlayerID, short targetPlayerI
}
}

public void NotifyEarthquake(byte strength)
public void NotifyMapEffect(MapEffect effect, byte strength = 0)
{
var mapRenderer = _hudControlProvider.GetComponent<IMapRenderer>(HudControlIdentifier.MapRenderer);
mapRenderer.StartEarthquake(strength);
switch (effect)
{
case MapEffect.Quake1:
case MapEffect.Quake2:
case MapEffect.Quake3:
case MapEffect.Quake4:
var mapRenderer = _hudControlProvider.GetComponent<IMapRenderer>(HudControlIdentifier.MapRenderer);
mapRenderer.StartEarthquake(strength);
_sfxPlayer.PlaySfx(SoundEffectID.Earthquake);
break;
case MapEffect.HPDrain:
_sfxPlayer.PlaySfx(SoundEffectID.MapEffectHPDrain);
break;
case MapEffect.TPDrain:
_sfxPlayer.PlaySfx(SoundEffectID.MapEffectTPDrain);
break;
case MapEffect.Spikes:
_sfxPlayer.PlaySfx(SoundEffectID.Spikes);
break;
}
}

public void NotifyEmote(short playerId, Emote emote)
Expand Down Expand Up @@ -338,6 +364,12 @@ private bool IsInstrumentWeapon(int weaponGraphic)
.Match(some: x => Constants.InstrumentIDs.ToList().FindIndex(y => y == x.ID) >= 0, none: () => false);
}

private bool IsSteppingStone(CharacterRenderProperties renderProps)
{
return _currentMapProvider.CurrentMap.Tiles[renderProps.MapY, renderProps.MapX] == TileSpec.Jump
|| _currentMapProvider.CurrentMap.Tiles[renderProps.GetDestinationY(), renderProps.GetDestinationX()] == TileSpec.Jump;
}

private ICharacterAnimator Animator => _hudControlProvider.GetComponent<ICharacterAnimator>(HudControlIdentifier.CharacterAnimator);
}

Expand Down
15 changes: 13 additions & 2 deletions EndlessClient/Rendering/Map/DynamicMapObjectUpdater.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using AutomaticTypeMapper;
using EndlessClient.Audio;
using EndlessClient.Controllers;
using EndlessClient.Input;
using EOLib.Domain.Character;
Expand Down Expand Up @@ -30,21 +31,24 @@ private class DoorTimePair
private readonly ICurrentMapProvider _currentMapProvider;
private readonly IMapObjectBoundsCalculator _mapObjectBoundsCalculator;
private readonly IMapInteractionController _mapInteractionController;
private readonly ISfxPlayer _sfxPlayer;
private readonly List<DoorTimePair> _cachedDoorState;

public DynamicMapObjectUpdater(ICharacterProvider characterProvider,
ICurrentMapStateRepository currentMapStateRepository,
IUserInputRepository userInputRepository,
ICurrentMapProvider currentMapProvider,
IMapObjectBoundsCalculator mapObjectBoundsCalculator,
IMapInteractionController mapInteractionController)
IMapInteractionController mapInteractionController,
ISfxPlayer sfxPlayer)
{
_characterProvider = characterProvider;
_currentMapStateRepository = currentMapStateRepository;
_userInputRepository = userInputRepository;
_currentMapProvider = currentMapProvider;
_mapObjectBoundsCalculator = mapObjectBoundsCalculator;
_mapInteractionController = mapInteractionController;
_sfxPlayer = sfxPlayer;
_cachedDoorState = new List<DoorTimePair>();
}

Expand All @@ -63,7 +67,10 @@ private void OpenNewDoors(DateTime now)
{
var newDoors = _currentMapStateRepository.OpenDoors.Where(x => _cachedDoorState.All(d => d.Door != x));
foreach (var door in newDoors)
{
_cachedDoorState.Add(new DoorTimePair { Door = door, OpenTime = now });
_sfxPlayer.PlaySfx(SoundEffectID.DoorOpen);
}
}

private void CloseExpiredDoors(DateTime now)
Expand All @@ -72,7 +79,11 @@ private void CloseExpiredDoors(DateTime now)
foreach (var door in expiredDoors)
{
_cachedDoorState.Remove(door);
_currentMapStateRepository.OpenDoors.Remove(door.Door);
if (_currentMapStateRepository.OpenDoors.Contains(door.Door))
{
_currentMapStateRepository.OpenDoors.Remove(door.Door);
_sfxPlayer.PlaySfx(SoundEffectID.DoorClose);
}
}
}

Expand Down
6 changes: 6 additions & 0 deletions EndlessClient/Rendering/Map/MapChangedActions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ public void NotifyMapChanged(WarpAnimation warpAnimation, bool differentMapID)
StopAllAnimations();
ClearCharacterRenderersAndCache();
ClearNPCRenderersAndCache();
ClearOpenDoors();
ShowMapNameIfAvailable(differentMapID);
//todo: show message if map is a PK map
ShowMapTransition(differentMapID);
Expand Down Expand Up @@ -110,6 +111,11 @@ private void ClearNPCRenderersAndCache()
_npcStateCache.Reset();
}

private void ClearOpenDoors()
{
_currentMapStateRepository.OpenDoors.Clear();
}

private void ShowMapNameIfAvailable(bool differentMapID)
{
if (!differentMapID || string.IsNullOrWhiteSpace(_currentMapProvider.CurrentMap.Properties.Name))
Expand Down
15 changes: 12 additions & 3 deletions EndlessClient/Rendering/Map/SpikeTrapActions.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using AutomaticTypeMapper;
using EndlessClient.Audio;
using EOLib.Domain.Extensions;
using EOLib.Domain.Map;
using EOLib.IO.Map;
Expand All @@ -10,20 +11,28 @@ public class SpikeTrapActions : ISpikeTrapActions
{
private readonly ICurrentMapStateRepository _currentMapStateRepository;
private readonly ICurrentMapProvider _currentMapProvider;
private readonly ISfxPlayer _sfxPlayer;

public SpikeTrapActions(ICurrentMapStateRepository currentMapStateRepository,
ICurrentMapProvider currentMapProvider)
ICurrentMapProvider currentMapProvider,
ISfxPlayer sfxPlayer)
{
_currentMapStateRepository = currentMapStateRepository;
_currentMapProvider = currentMapProvider;
_sfxPlayer = sfxPlayer;
}

public void ShowSpikeTrap(MapCoordinate coordinate)
public void ShowSpikeTrap(MapCoordinate coordinate, bool isMainCharacter = false)
{
if (!_currentMapStateRepository.VisibleSpikeTraps.Contains(coordinate) &&
_currentMapProvider.CurrentMap.Tiles[coordinate.Y, coordinate.X] == TileSpec.SpikesTrap)
{
_currentMapStateRepository.VisibleSpikeTraps.Add(coordinate);

if (isMainCharacter)
{
_sfxPlayer.PlaySfx(SoundEffectID.Spikes);
}
}
}

Expand Down Expand Up @@ -57,7 +66,7 @@ public void HideSpikeTrap(int characterId)

public interface ISpikeTrapActions
{
void ShowSpikeTrap(MapCoordinate coordinate);
void ShowSpikeTrap(MapCoordinate coordinate, bool isMainCharacter = false);

void ShowSpikeTrap(int characterId);

Expand Down

0 comments on commit e33bb5c

Please sign in to comment.