Skip to content

Commit

Permalink
Fix bug where other players would not finish casting a spell targeted…
Browse files Browse the repository at this point in the history
… at NPCs
  • Loading branch information
ethanmoffat committed Sep 14, 2022
1 parent 5c0603d commit 6a4a127
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 17 deletions.
4 changes: 4 additions & 0 deletions EOLib/Domain/Notifiers/IOtherCharacterAnimationNotifier.cs
Expand Up @@ -12,6 +12,8 @@ public interface IOtherCharacterAnimationNotifier

void NotifyStartSpellCast(short playerId, short spellId);

void NotifyTargetNpcSpellCast(short playerId);

void NotifySelfSpellCast(short playerId, short spellId, int spellHp, byte percentHealth);

void NotifyTargetOtherSpellCast(short sourcePlayerID, short targetPlayerID, short spellId, int recoveredHP, byte targetPercentHealth);
Expand All @@ -28,6 +30,8 @@ public class NoOpOtherCharacterAnimationNotifier : IOtherCharacterAnimationNotif

public void NotifyStartSpellCast(short playerId, short spellId) { }

public void NotifyTargetNpcSpellCast(short playerId) { }

public void NotifySelfSpellCast(short playerId, short spellId, int spellHp, byte percentHealth) { }

public void NotifyTargetOtherSpellCast(short sourcePlayerID, short targetPlayerID, short spellId, int recoveredHP, byte targetPercentHealth) { }
Expand Down
30 changes: 20 additions & 10 deletions EOLib/PacketHandlers/NPCLeaveMapHandler.cs
Expand Up @@ -19,6 +19,7 @@ public class NPCLeaveMapHandler : InGameOnlyPacketHandler
private readonly ICharacterSessionRepository _characterSessionRepository;
private readonly IEnumerable<INPCActionNotifier> _npcActionNotifiers;
private readonly IEnumerable<IMainCharacterEventNotifier> _mainCharacterEventNotifiers;
private readonly IEnumerable<IOtherCharacterAnimationNotifier> _otherCharacterAnimationNotifiers;

public override PacketFamily Family => PacketFamily.NPC;

Expand All @@ -29,33 +30,35 @@ public class NPCLeaveMapHandler : InGameOnlyPacketHandler
ICharacterRepository characterRepository,
ICharacterSessionRepository characterSessionRepository,
IEnumerable<INPCActionNotifier> npcActionNotifiers,
IEnumerable<IMainCharacterEventNotifier> mainCharacterEventNotifiers)
IEnumerable<IMainCharacterEventNotifier> mainCharacterEventNotifiers,
IEnumerable<IOtherCharacterAnimationNotifier> otherCharacterAnimationNotifiers)
: base(playerInfoProvider)
{
_currentMapStateRepository = currentMapStateRepository;
_characterRepository = characterRepository;
_characterSessionRepository = characterSessionRepository;
_npcActionNotifiers = npcActionNotifiers;
_mainCharacterEventNotifiers = mainCharacterEventNotifiers;
_otherCharacterAnimationNotifiers = otherCharacterAnimationNotifiers;
}

public override bool HandlePacket(IPacket packet)
{
var spellID = packet.Family
var spellId = packet.Family
.SomeWhen(f => f == PacketFamily.Cast)
.Map(f => packet.ReadShort());

var playerID = packet.ReadShort(); //player that is protecting the item
var fromPlayerId = packet.ReadShort(); //player that is protecting the item
var playerDirection = (EODirection)packet.ReadChar();
if (playerID > 0)
UpdatePlayerDirection(playerID, playerDirection);
if (fromPlayerId > 0)
UpdatePlayerDirection(fromPlayerId, playerDirection);

var deadNPCIndex = packet.ReadShort();

//packet is removing the NPC from view due to out of range of character
if (packet.ReadPosition == packet.Length)
{
RemoveNPCFromView(deadNPCIndex, playerID, spellID, damage: Option.None<int>(), showDeathAnimation: false);
RemoveNPCFromView(deadNPCIndex, fromPlayerId, spellId, damage: Option.None<int>(), showDeathAnimation: false);
return true;
}

Expand All @@ -66,7 +69,7 @@ public override bool HandlePacket(IPacket packet)
var droppedAmount = packet.ReadInt();

var damageDoneToNPC = packet.ReadThree();
RemoveNPCFromView(deadNPCIndex, playerID, spellID, Option.Some(damageDoneToNPC), showDeathAnimation: true);
RemoveNPCFromView(deadNPCIndex, fromPlayerId, spellId, Option.Some(damageDoneToNPC), showDeathAnimation: true);

if (packet.Family == PacketFamily.Cast)
{
Expand All @@ -90,7 +93,13 @@ public override bool HandlePacket(IPacket packet)
}

if (droppedItemID > 0)
ShowDroppedItem(playerID, droppedItemUID, droppedItemID, x, y, droppedAmount);
ShowDroppedItem(fromPlayerId, droppedItemUID, droppedItemID, x, y, droppedAmount);

spellId.MatchSome(_ =>
{
foreach (var notifier in _otherCharacterAnimationNotifiers)
notifier.NotifyTargetNpcSpellCast(fromPlayerId);
});

return true;
}
Expand Down Expand Up @@ -164,8 +173,9 @@ public class NPCDieFromSpellCastHandler : NPCLeaveMapHandler
ICharacterRepository characterRepository,
ICharacterSessionRepository characterSessionRepository,
IEnumerable<INPCActionNotifier> npcAnimationNotifiers,
IEnumerable<IMainCharacterEventNotifier> mainCharacterEventNotifiers)
IEnumerable<IMainCharacterEventNotifier> mainCharacterEventNotifiers,
IEnumerable<IOtherCharacterAnimationNotifier> otherCharacterAnimationNotifiers)
: base(playerInfoProvider, currentMapStateRepository, characterRepository, characterSessionRepository,
npcAnimationNotifiers, mainCharacterEventNotifiers) { }
npcAnimationNotifiers, mainCharacterEventNotifiers, otherCharacterAnimationNotifiers) { }
}
}
21 changes: 16 additions & 5 deletions EOLib/PacketHandlers/NPCTakeDamageHandler.cs
Expand Up @@ -17,18 +17,21 @@ public abstract class NPCTakeDamageHandler : InGameOnlyPacketHandler
private readonly ICharacterRepository _characterRepository;
private readonly ICurrentMapStateRepository _currentMapStateRepository;
private readonly IEnumerable<INPCActionNotifier> _npcNotifiers;
private readonly IEnumerable<IOtherCharacterAnimationNotifier> _otherCharacterAnimationNotifiers;

public override PacketAction Action => PacketAction.Reply;

public NPCTakeDamageHandler(IPlayerInfoProvider playerInfoProvider,
ICharacterRepository characterRepository,
ICurrentMapStateRepository currentMapStateRepository,
IEnumerable<INPCActionNotifier> npcNotifiers)
IEnumerable<INPCActionNotifier> npcNotifiers,
IEnumerable<IOtherCharacterAnimationNotifier> otherCharacterAnimationNotifiers)
: base(playerInfoProvider)
{
_characterRepository = characterRepository;
_currentMapStateRepository = currentMapStateRepository;
_npcNotifiers = npcNotifiers;
_otherCharacterAnimationNotifiers = otherCharacterAnimationNotifiers;
}

public override bool HandlePacket(IPacket packet)
Expand Down Expand Up @@ -89,6 +92,12 @@ public override bool HandlePacket(IPacket packet)
return true;
}

spellId.MatchSome(_ =>
{
foreach (var notifier in _otherCharacterAnimationNotifiers)
notifier.NotifyTargetNpcSpellCast(fromPlayerId);
});

return true;
}
}
Expand All @@ -101,8 +110,9 @@ public class NPCTakeWeaponDamageHandler : NPCTakeDamageHandler
public NPCTakeWeaponDamageHandler(IPlayerInfoProvider playerInfoProvider,
ICharacterRepository characterRepository,
ICurrentMapStateRepository currentMapStateRepository,
IEnumerable<INPCActionNotifier> npcNotifiers)
: base(playerInfoProvider, characterRepository, currentMapStateRepository, npcNotifiers) { }
IEnumerable<INPCActionNotifier> npcNotifiers,
IEnumerable<IOtherCharacterAnimationNotifier> otherCharacterAnimationNotifiers)
: base(playerInfoProvider, characterRepository, currentMapStateRepository, npcNotifiers, otherCharacterAnimationNotifiers) { }
}

[AutoMappedType]
Expand All @@ -113,7 +123,8 @@ public class NPCTakeSpellDamageHandler : NPCTakeDamageHandler
public NPCTakeSpellDamageHandler(IPlayerInfoProvider playerInfoProvider,
ICharacterRepository characterRepository,
ICurrentMapStateRepository currentMapStateRepository,
IEnumerable<INPCActionNotifier> npcNotifiers)
: base(playerInfoProvider, characterRepository, currentMapStateRepository, npcNotifiers) { }
IEnumerable<INPCActionNotifier> npcNotifiers,
IEnumerable<IOtherCharacterAnimationNotifier> otherCharacterAnimationNotifiers)
: base(playerInfoProvider, characterRepository, currentMapStateRepository, npcNotifiers, otherCharacterAnimationNotifiers) { }
}
}
6 changes: 4 additions & 2 deletions EOLib/PacketHandlers/PlayerLevelUpHandler.cs
Expand Up @@ -23,9 +23,10 @@ public class PlayerLevelUpHandler : NPCLeaveMapHandler
ICharacterSessionRepository characterSessionRepository,
IEnumerable<INPCActionNotifier> npcAnimationNotifiers,
IEnumerable<IMainCharacterEventNotifier> mainCharacterEventNotifiers,
IEnumerable<IOtherCharacterAnimationNotifier> otherCharacterAnimationNotifiers,
IEnumerable<IEmoteNotifier> emoteNotifiers)
: base(playerInfoProvider, currentMapStateRepository, characterRepository, characterSessionRepository,
npcAnimationNotifiers, mainCharacterEventNotifiers)
npcAnimationNotifiers, mainCharacterEventNotifiers, otherCharacterAnimationNotifiers)
{
_emoteNotifiers = emoteNotifiers;
}
Expand Down Expand Up @@ -71,8 +72,9 @@ public class PlayerLevelUpFromSpellCastHandler : PlayerLevelUpHandler
ICharacterSessionRepository characterSessionRepository,
IEnumerable<INPCActionNotifier> npcAnimationNotifiers,
IEnumerable<IMainCharacterEventNotifier> mainCharacterEventNotifiers,
IEnumerable<IOtherCharacterAnimationNotifier> otherCharacterAnimationNotifiers,
IEnumerable<IEmoteNotifier> emoteNotifiers)
: base(playerInfoProvider, currentMapStateRepository, characterRepository, characterSessionRepository,
npcAnimationNotifiers, mainCharacterEventNotifiers, emoteNotifiers) { }
npcAnimationNotifiers, mainCharacterEventNotifiers, otherCharacterAnimationNotifiers, emoteNotifiers) { }
}
}
11 changes: 11 additions & 0 deletions EndlessClient/Rendering/Character/CharacterAnimationActions.cs
Expand Up @@ -178,6 +178,17 @@ public void NotifyStartSpellCast(short playerId, short spellId)
_characterRendererProvider.CharacterRenderers[playerId].ShoutSpellPrep(shoutName.ToLower());
}

public void NotifyTargetNpcSpellCast(short playerId)
{
// Main player starts its spell cast animation immediately when targeting NPC
// Other players need to wait for packet to be received and do it here
// this is some spaghetti...
if (_characterRendererProvider.CharacterRenderers.ContainsKey(playerId))
{
Animator.StartOtherCharacterSpellCast(playerId);
}
}

public void NotifySelfSpellCast(short playerId, short spellId, int spellHp, byte percentHealth)
{
var spellGraphic = _pubFileProvider.ESFFile[spellId].Graphic;
Expand Down
2 changes: 2 additions & 0 deletions EndlessClient/Rendering/NPC/NPCActions.cs
Expand Up @@ -134,6 +134,8 @@ private void ShoutSpellCast(int playerId)
{
if (r.Character.ID == playerId)
r.ShoutSpellCast();
else if (_characterRendererRepository.CharacterRenderers.ContainsKey(playerId))
_characterRendererRepository.CharacterRenderers[playerId].ShoutSpellCast();
},
none: () =>
{
Expand Down

0 comments on commit 6a4a127

Please sign in to comment.