Skip to content

Commit

Permalink
Merge pull request #166 from ethanmoffat/emotes
Browse files Browse the repository at this point in the history
Add support for rendering player emotes. Includes: beer item type handling, testing for expreward item types, rendering of face/emote graphics, afk emotes, drunk text, and level up emotes.
  • Loading branch information
ethanmoffat committed Apr 1, 2022
2 parents 2b81c32 + 80f6272 commit ba0b8da
Show file tree
Hide file tree
Showing 42 changed files with 511 additions and 356 deletions.
2 changes: 2 additions & 0 deletions EOBot/Program.cs
Expand Up @@ -136,6 +136,8 @@ public void JunkItem(short id, int amountRemoved)
var maxWeight = _characterProvider.MainCharacter.Stats[CharacterStat.MaxWeight];
ConsoleHelper.WriteMessage(ConsoleHelper.Type.JunkItem, $"{weight,3}/{maxWeight,3} - weight - {inventoryCount?.Amount ?? 0} in inventory");
}

public void MakeDrunk() { }
}

[AutoMappedType]
Expand Down
1 change: 1 addition & 0 deletions EOLib.IO/Pub/EIFRecord.cs
Expand Up @@ -40,6 +40,7 @@ public class EIFRecord : PubRecord
public int HairColor => Get<int>(PubRecordProperty.ItemHairColor);
public int Effect => Get<int>(PubRecordProperty.ItemEffect);
public int Key => Get<int>(PubRecordProperty.ItemKey);
public int BeerPotency => Get<int>(PubRecordProperty.BeerPotency);

public byte Gender => Get<byte>(PubRecordProperty.ItemGender);
public byte ScrollX => Get<byte>(PubRecordProperty.ItemScrollX);
Expand Down
2 changes: 2 additions & 0 deletions EOLib.IO/Pub/PubRecordProperty.cs
Expand Up @@ -75,6 +75,8 @@ public enum PubRecordProperty : uint
ItemEffect,
[RecordData(32, 3)]
ItemKey,
[RecordData(32, 3)]
BeerPotency,

[RecordData(35, 1)]
ItemGender,
Expand Down
1 change: 1 addition & 0 deletions EOLib.Localization/EOResourceID.cs
Expand Up @@ -231,6 +231,7 @@ public enum EOResourceID
STATUS_LABEL_ITEM_EQUIP_THIS_ITEM_REQUIRES = 411,

STATUS_LABEL_UNABLE_TO_ATTACK = 423,
STATUS_LABEL_YOU_HAVE_NO_ARROWS = 424,

STATUS_LABEL_YOUR_LOCATION_IS_AT = 427,
STATUS_LABEL_IS_ONLINE_IN_THIS_WORLD = 428,
Expand Down
14 changes: 12 additions & 2 deletions EOLib/Domain/Character/AttackValidationActions.cs
@@ -1,6 +1,9 @@
using AutomaticTypeMapper;
using EOLib.Domain.Extensions;
using EOLib.Domain.Map;
using EOLib.IO.Repositories;
using Optional.Collections;
using System.Linq;

namespace EOLib.Domain.Character
{
Expand All @@ -9,12 +12,15 @@ public class AttackValidationActions : IAttackValidationActions
{
private readonly ICharacterProvider _characterProvider;
private readonly IMapCellStateProvider _mapCellStateProvider;
private readonly IEIFFileProvider _eifFileProvider;

public AttackValidationActions(ICharacterProvider characterProvider,
IMapCellStateProvider mapCellStateProvider)
IMapCellStateProvider mapCellStateProvider,
IEIFFileProvider eifFileProvider)
{
_characterProvider = characterProvider;
_mapCellStateProvider = mapCellStateProvider;
_eifFileProvider = eifFileProvider;
}

public AttackValidationError ValidateCharacterStateBeforeAttacking()
Expand All @@ -27,6 +33,9 @@ public AttackValidationError ValidateCharacterStateBeforeAttacking()

var rp = _characterProvider.MainCharacter.RenderProperties;

if (rp.IsRangedWeapon && (rp.ShieldGraphic == 0 || !_eifFileProvider.EIFFile.Any(x => x.DollGraphic == rp.ShieldGraphic && x.SubType == IO.ItemSubType.Arrows)))
return AttackValidationError.MissingArrows;

return _mapCellStateProvider
.GetCellStateAt(rp.GetDestinationX(), rp.GetDestinationY())
.NPC.Match(
Expand All @@ -47,6 +56,7 @@ public enum AttackValidationError
OK,
Overweight,
Exhausted,
NotYourBattle
NotYourBattle,
MissingArrows
}
}
11 changes: 11 additions & 0 deletions EOLib/Domain/Character/CharacterActions.cs
Expand Up @@ -138,6 +138,15 @@ public void CastSpell(int spellId, ISpellTargetable target)

_packetSendService.SendPacket(builder.Build());
}

public void Emote(Emote whichEmote)
{
var packet = new PacketBuilder(PacketFamily.Emote, PacketAction.Report)
.AddChar((byte)whichEmote)
.Build();

_packetSendService.SendPacket(packet);
}
}

public interface ICharacterActions
Expand All @@ -153,5 +162,7 @@ public interface ICharacterActions
void PrepareCastSpell(int spellId);

void CastSpell(int spellId, ISpellTargetable target);

void Emote(Emote whichEmote);
}
}
12 changes: 12 additions & 0 deletions EOLib/Domain/Character/CharacterRenderProperties.cs
Expand Up @@ -37,6 +37,7 @@ public class CharacterRenderProperties : ICharacterRenderProperties

public bool IsHidden { get; private set; }
public bool IsDead { get; private set; }
public bool IsDrunk { get; private set; }

public bool IsRangedWeapon { get; private set; }

Expand Down Expand Up @@ -232,6 +233,13 @@ public ICharacterRenderProperties WithAlive()
return props;
}

public ICharacterRenderProperties WithIsDrunk(bool drunk)
{
var props = MakeCopy(this);
props.IsDrunk = drunk;
return props;
}

public object Clone()
{
return MakeCopy(this);
Expand Down Expand Up @@ -269,6 +277,8 @@ private static CharacterRenderProperties MakeCopy(ICharacterRenderProperties oth

IsHidden = other.IsHidden,
IsDead = other.IsDead,
IsDrunk = other.IsDrunk,

IsRangedWeapon = other.IsRangedWeapon
};
}
Expand Down Expand Up @@ -298,6 +308,7 @@ public override bool Equals(object obj)
Emote == properties.Emote &&
IsHidden == properties.IsHidden &&
IsDead == properties.IsDead &&
IsDrunk == properties.IsDrunk &&
IsRangedWeapon == properties.IsRangedWeapon;
}

Expand Down Expand Up @@ -326,6 +337,7 @@ public override int GetHashCode()
hashCode = hashCode * -1521134295 + Emote.GetHashCode();
hashCode = hashCode * -1521134295 + IsHidden.GetHashCode();
hashCode = hashCode * -1521134295 + IsDead.GetHashCode();
hashCode = hashCode * -1521134295 + IsDrunk.GetHashCode();
hashCode = hashCode * -1521134295 + IsRangedWeapon.GetHashCode();
return hashCode;
}
Expand Down
3 changes: 3 additions & 0 deletions EOLib/Domain/Character/ICharacterRenderProperties.cs
Expand Up @@ -33,6 +33,7 @@ public interface ICharacterRenderProperties : ICloneable

bool IsHidden { get; }
bool IsDead { get; }
bool IsDrunk { get; }

bool IsRangedWeapon { get; }

Expand Down Expand Up @@ -63,5 +64,7 @@ public interface ICharacterRenderProperties : ICloneable
ICharacterRenderProperties WithIsHidden(bool hidden);
ICharacterRenderProperties WithDead();
ICharacterRenderProperties WithAlive();

ICharacterRenderProperties WithIsDrunk(bool drunk);
}
}
13 changes: 9 additions & 4 deletions EOLib/Domain/Chat/ChatActions.cs
Expand Up @@ -36,14 +36,14 @@ public class ChatActions : IChatActions
_chatProcessor = chatProcessor;
}

public async Task SendChatToServer(string chat, string targetCharacter)
public string SendChatToServer(string chat, string targetCharacter)
{
var chatType = _chatTypeCalculator.CalculateChatType(chat);

if (chatType == ChatType.Command)
{
if (HandleCommand(chat))
return;
return chat;

//treat unhandled command as local chat
chatType = ChatType.Local;
Expand All @@ -59,10 +59,15 @@ public async Task SendChatToServer(string chat, string targetCharacter)

chat = _chatProcessor.RemoveFirstCharacterIfNeeded(chat, chatType, targetCharacter);

if (_characterProvider.MainCharacter.RenderProperties.IsDrunk)
chat = _chatProcessor.MakeDrunk(chat);

var chatPacket = _chatPacketBuilder.BuildChatPacket(chatType, chat, targetCharacter);
await _packetSendService.SendPacketAsync(chatPacket);
_packetSendService.SendPacket(chatPacket);

AddChatForLocalDisplay(chatType, chat, targetCharacter);

return chat;
}

/// <summary>
Expand Down Expand Up @@ -126,6 +131,6 @@ private void AddChatForLocalDisplay(ChatType chatType, string chat, string targe

public interface IChatActions
{
Task SendChatToServer(string chat, string targetCharacter);
string SendChatToServer(string chat, string targetCharacter);
}
}
30 changes: 30 additions & 0 deletions EOLib/Domain/Chat/ChatProcessor.cs
@@ -1,11 +1,15 @@
using System;
using System.Linq;
using System.Text;
using AutomaticTypeMapper;

namespace EOLib.Domain.Chat
{
[AutoMappedType]
public class ChatProcessor : IChatProcessor
{
private readonly Random _random = new Random();

public string RemoveFirstCharacterIfNeeded(string chat, ChatType chatType, string targetCharacter)
{
switch (chatType)
Expand Down Expand Up @@ -33,10 +37,36 @@ public string RemoveFirstCharacterIfNeeded(string chat, ChatType chatType, strin
throw new ArgumentOutOfRangeException(nameof(chatType));
}
}

public string MakeDrunk(string input)
{
// implementation from Phorophor::notepad (thanks Apollo)
// https://discord.com/channels/723989119503696013/785190349026492437/791376941822246953
var ret = new StringBuilder();

foreach (var c in input)
{
var repeats = _random.Next(0, 8) < 6 ? 1 : 2;
ret.Append(c, repeats);

if ((c == 'a' || c == 'e') && _random.NextDouble() / 1.0 < 0.555)
ret.Append('j');

if ((c == 'u' || c == 'o') && _random.NextDouble() / 1.0 < 0.444)
ret.Append('w');

if ((c == ' ') && _random.NextDouble() / 1.0 < 0.333)
ret.Append(" *hic*");
}

return ret.ToString();
}
}

public interface IChatProcessor
{
string RemoveFirstCharacterIfNeeded(string input, ChatType chatType, string targetCharacter);

string MakeDrunk(string input);
}
}
4 changes: 4 additions & 0 deletions EOLib/Domain/Notifiers/IEmoteNotifier.cs
Expand Up @@ -6,11 +6,15 @@ namespace EOLib.Domain.Notifiers
public interface IEmoteNotifier
{
void NotifyEmote(short playerId, Emote emote);

void MakeMainPlayerDrunk();
}

[AutoMappedType]
public class NoOpEmoteNotifier : IEmoteNotifier
{
public void NotifyEmote(short playerId, Emote emote) { }

public void MakeMainPlayerDrunk() { }
}
}
40 changes: 0 additions & 40 deletions EOLib/Net/API/Emote.cs

This file was deleted.

1 change: 0 additions & 1 deletion EOLib/Net/API/PacketAPI.cs
Expand Up @@ -22,7 +22,6 @@ public PacketAPI(EOClient client)
//each of these sets up members of the partial PacketAPI class relevant to a particular packet family
_createBankMembers();
_createChestMembers();
_createEmoteMembers();
_createInitMembers();
_createLockerMembers();
_createMessageMembers();
Expand Down
9 changes: 4 additions & 5 deletions EOLib/PacketHandlers/Items/UseItemHandler.cs
Expand Up @@ -86,10 +86,9 @@ public override bool HandlePacket(IPacket packet)
renderProps = renderProps.WithHairColor(hairColor);
break;
case ItemType.Beer:
// todo: drunk
// old logic:
// OldWorld.Instance.ActiveCharacterRenderer.MakeDrunk();
// m_game.Hud.SetStatusLabel(EOResourceID.STATUS_LABEL_TYPE_WARNING, EOResourceID.STATUS_LABEL_ITEM_USE_DRUNK);
renderProps = renderProps.WithIsDrunk(true);
foreach (var notifier in _emoteNotifiers)
notifier.MakeMainPlayerDrunk();
break;
case ItemType.EffectPotion:
var potionId = packet.ReadShort();
Expand Down Expand Up @@ -159,7 +158,7 @@ public override bool HandlePacket(IPacket packet)
.WithNewStat(CharacterStat.Armor, cureCurseArmor);

break;
case ItemType.EXPReward: // todo: EXPReward has not been tested
case ItemType.EXPReward:
var levelUpExp = packet.ReadInt();
var levelUpLevel = packet.ReadChar();
var levelUpStat = packet.ReadShort();
Expand Down
4 changes: 3 additions & 1 deletion EOLib/PacketHandlers/OtherPlayerLevelUpHandler.cs
@@ -1,4 +1,5 @@
using EOLib.Domain.Character;
using AutomaticTypeMapper;
using EOLib.Domain.Character;
using EOLib.Domain.Login;
using EOLib.Domain.Notifiers;
using EOLib.Net;
Expand All @@ -7,6 +8,7 @@

namespace EOLib.PacketHandlers
{
[AutoMappedType]
public class OtherPlayerLevelUpHandler : InGameOnlyPacketHandler
{
private readonly IEnumerable<IEmoteNotifier> _emoteNotifiers;
Expand Down

0 comments on commit ba0b8da

Please sign in to comment.