Skip to content

Commit

Permalink
Merge pull request #97 from ethanmoffat/sitting
Browse files Browse the repository at this point in the history
Implement chair/floor sitting
- Add handling for walking to a chair, F11 toggling of sit, and clicking to stand
- Update offsets to work for sitting in chairs/floor
- Fix crash bug when receiving PM
  • Loading branch information
ethanmoffat committed Jan 29, 2021
2 parents d4fde4d + b0d4b12 commit f587db2
Show file tree
Hide file tree
Showing 21 changed files with 401 additions and 28 deletions.
20 changes: 20 additions & 0 deletions EOLib/Domain/Character/CharacterActions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,24 @@ public void Attack()

_packetSendService.SendPacket(packet);
}

public void ToggleSit()
{
var renderProperties = _characterProvider.MainCharacter.RenderProperties;
var sitAction = renderProperties.SitState == SitState.Standing
? SitAction.Sit
: SitAction.Stand;

var packetFamily = renderProperties.SitState == SitState.Chair
? PacketFamily.Chair
: PacketFamily.Sit;

var packet = new PacketBuilder(packetFamily, PacketAction.Request)
.AddChar((byte)sitAction)
.Build();

_packetSendService.SendPacket(packet);
}
}

public interface ICharacterActions
Expand All @@ -62,5 +80,7 @@ public interface ICharacterActions
void Walk();

void Attack();

void ToggleSit();
}
}
8 changes: 8 additions & 0 deletions EOLib/Domain/Character/SitAction.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace EOLib.Domain.Character
{
public enum SitAction
{
Sit = 1,
Stand = 2
}
}
6 changes: 4 additions & 2 deletions EOLib/Domain/Character/WalkValidationActions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@ public bool CanMoveToDestinationCoordinates()
if (_currentMapStateProvider.MapWarpState == WarpState.WarpStarted)
return false;

var mainCharacter = _characterProvider.MainCharacter;
var renderProperties = mainCharacter.RenderProperties;
var renderProperties = _characterProvider.MainCharacter.RenderProperties;
var destX = renderProperties.GetDestinationX();
var destY = renderProperties.GetDestinationY();

Expand All @@ -43,6 +42,9 @@ public bool CanMoveToCoordinates(int gridX, int gridY)
{
var mainCharacter = _characterProvider.MainCharacter;

if (mainCharacter.RenderProperties.SitState != SitState.Standing)
return false;

var cellState = _mapCellStateProvider.GetCellStateAt(gridX, gridY);

if (cellState.Character.HasValue) //todo: walk through players after certain elapsed time
Expand Down
3 changes: 3 additions & 0 deletions EOLib/EOLib.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@
<Compile Include="Domain\Character\CharacterStat.cs" />
<Compile Include="Domain\Character\CharacterStats.cs" />
<Compile Include="Domain\Character\ExperienceTableProvider.cs" />
<Compile Include="Domain\Character\SitAction.cs" />
<Compile Include="Domain\Character\StatTrainingActions.cs" />
<Compile Include="Domain\Character\TrainType.cs" />
<Compile Include="Domain\Character\WalkValidationActions.cs" />
Expand Down Expand Up @@ -257,9 +258,11 @@
<Compile Include="PacketHandlers\Effects\MapQuakeHandler.cs" />
<Compile Include="PacketHandlers\EndPlayerWarpHandler.cs" />
<Compile Include="PacketHandlers\ItemPickupHandler.cs" />
<Compile Include="PacketHandlers\PlayerSitHandler.cs" />
<Compile Include="PacketHandlers\MainPlayerWalkHandler.cs" />
<Compile Include="PacketHandlers\Effects\MapHpDrainHandler.cs" />
<Compile Include="PacketHandlers\NPCTakeDamageHandler.cs" />
<Compile Include="PacketHandlers\PlayerStandHandler.cs" />
<Compile Include="PacketHandlers\PlayerTargetOtherSpellHandler.cs" />
<Compile Include="PacketHandlers\PlayerSelfTargetSpellHandler.cs" />
<Compile Include="PacketHandlers\Effects\PlayerSpikeDamageHandler.cs" />
Expand Down
19 changes: 12 additions & 7 deletions EOLib/PacketHandlers/Chat/PrivateMessageHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,20 @@ protected override void PostChat(string name, string message)
var localData = new ChatData(name, message, ChatIcon.Note, ChatColor.PM);
var pmData = new ChatData(name, message, ChatIcon.Note);

var whichPMTab = _chatRepository.PMTarget1.Equals(name, StringComparison.InvariantCultureIgnoreCase)
? ChatTab.Private1
: _chatRepository.PMTarget2.Equals(name, StringComparison.InvariantCultureIgnoreCase)
? ChatTab.Private2
: ChatTab.Local;
ChatTab whichPmTab;

if (_chatRepository.PMTarget1 == null && _chatRepository.PMTarget2 == null)
whichPmTab = ChatTab.Local;
else
whichPmTab = _chatRepository.PMTarget1.Equals(name, StringComparison.InvariantCultureIgnoreCase)
? ChatTab.Private1
: _chatRepository.PMTarget2.Equals(name, StringComparison.InvariantCultureIgnoreCase)
? ChatTab.Private2
: ChatTab.Local;

_chatRepository.AllChat[ChatTab.Local].Add(localData);
if (whichPMTab != ChatTab.Local)
_chatRepository.AllChat[whichPMTab].Add(pmData);
if (whichPmTab != ChatTab.Local)
_chatRepository.AllChat[whichPmTab].Add(pmData);
}
}
}
86 changes: 86 additions & 0 deletions EOLib/PacketHandlers/PlayerSitHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
using AutomaticTypeMapper;
using EOLib.Domain.Character;
using EOLib.Domain.Login;
using EOLib.Domain.Map;
using EOLib.Net;
using EOLib.Net.Handlers;
using System.Linq;

namespace EOLib.PacketHandlers
{
public abstract class PlayerSitHandler : InGameOnlyPacketHandler
{
private readonly ICharacterRepository _characterRepository;
private readonly ICurrentMapStateRepository _currentMapStateRepository;

public override PacketAction Action => PacketAction.Player;

public PlayerSitHandler(IPlayerInfoProvider playerInfoProvider,
ICharacterRepository characterRepository,
ICurrentMapStateRepository currentMapStateRepository)
: base(playerInfoProvider)
{
_characterRepository = characterRepository;
_currentMapStateRepository = currentMapStateRepository;
}

public override bool HandlePacket(IPacket packet)
{
var playerId = packet.ReadShort();
var x = packet.ReadChar();
var y = packet.ReadChar();
var direction = (EODirection)packet.ReadChar();

var sitState = Family == PacketFamily.Sit ? SitState.Floor : SitState.Chair;

if (packet.ReadChar() != 0)
return false;

if (playerId == _characterRepository.MainCharacter.ID)
{
var renderProperties = _characterRepository.MainCharacter.RenderProperties;
var updatedRenderProperties = renderProperties.WithSitState(sitState)
.WithMapX(x)
.WithMapY(y)
.WithDirection(direction);
_characterRepository.MainCharacter = _characterRepository.MainCharacter.WithRenderProperties(updatedRenderProperties);
}
else
{
var oldCharacter = _currentMapStateRepository.Characters.Single(c => c.ID == playerId);
var renderProperties = oldCharacter.RenderProperties.WithSitState(sitState)
.WithMapX(x)
.WithMapY(y)
.WithDirection(direction);
var newCharacter = oldCharacter.WithRenderProperties(renderProperties);

_currentMapStateRepository.Characters.Remove(oldCharacter);
_currentMapStateRepository.Characters.Add(newCharacter);
}

return true;
}
}

[AutoMappedType]
public class PlayerSitFloorHandler : PlayerSitHandler
{
public override PacketFamily Family => PacketFamily.Sit;

public PlayerSitFloorHandler(IPlayerInfoProvider playerInfoProvider,
ICharacterRepository characterRepository,
ICurrentMapStateRepository currentMapStateRepository)
: base(playerInfoProvider, characterRepository, currentMapStateRepository) { }
}

[AutoMappedType]
public class PlayerSitChairHandler : PlayerSitHandler
{
public override PacketFamily Family => PacketFamily.Chair;

public PlayerSitChairHandler(IPlayerInfoProvider playerInfoProvider,
ICharacterRepository characterRepository,
ICurrentMapStateRepository currentMapStateRepository)
: base(playerInfoProvider, characterRepository, currentMapStateRepository) { }
}
}
89 changes: 89 additions & 0 deletions EOLib/PacketHandlers/PlayerStandHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
using AutomaticTypeMapper;
using EOLib.Domain.Character;
using EOLib.Domain.Login;
using EOLib.Domain.Map;
using EOLib.Net;
using EOLib.Net.Handlers;
using System.Linq;

namespace EOLib.PacketHandlers
{
public abstract class PlayerStandHandler : InGameOnlyPacketHandler
{
private readonly ICharacterRepository _characterRepository;
private readonly ICurrentMapStateRepository _currentMapStateRepository;

public override PacketFamily Family => PacketFamily.Sit;

public PlayerStandHandler(IPlayerInfoProvider playerInfoProvider,
ICharacterRepository characterRepository,
ICurrentMapStateRepository currentMapStateRepository)
: base(playerInfoProvider)
{
_characterRepository = characterRepository;
_currentMapStateRepository = currentMapStateRepository;
}

public override bool HandlePacket(IPacket packet)
{
var playerId = packet.ReadShort();
var x = packet.ReadChar();
var y = packet.ReadChar();

if (playerId == _characterRepository.MainCharacter.ID)
{
var renderProperties = _characterRepository.MainCharacter.RenderProperties;
var updatedRenderProperties = renderProperties.WithSitState(SitState.Standing)
.WithMapX(x)
.WithMapY(y);
_characterRepository.MainCharacter = _characterRepository.MainCharacter.WithRenderProperties(updatedRenderProperties);
}
else
{
var oldCharacter = _currentMapStateRepository.Characters.Single(c => c.ID == playerId);
var renderProperties = oldCharacter.RenderProperties.WithSitState(SitState.Standing)
.WithMapX(x)
.WithMapY(y);
var newCharacter = oldCharacter.WithRenderProperties(renderProperties);

_currentMapStateRepository.Characters.Remove(oldCharacter);
_currentMapStateRepository.Characters.Add(newCharacter);
}

return true;
}
}

[AutoMappedType]
public class OtherPlayerStandHandler : PlayerStandHandler
{
public override PacketAction Action => PacketAction.Remove;

public OtherPlayerStandHandler(IPlayerInfoProvider playerInfoProvider,
ICharacterRepository characterRepository,
ICurrentMapStateRepository currentMapStateRepository)
: base(playerInfoProvider, characterRepository, currentMapStateRepository) { }
}

[AutoMappedType]
public class MainPlayerStandHandler : PlayerStandHandler
{
public override PacketAction Action => PacketAction.Close;

public MainPlayerStandHandler(IPlayerInfoProvider playerInfoProvider,
ICharacterRepository characterRepository,
ICurrentMapStateRepository currentMapStateRepository)
: base(playerInfoProvider, characterRepository, currentMapStateRepository) { }
}

[AutoMappedType]
public class MainPlayerStandFromChairHandler : MainPlayerStandHandler
{
public override PacketFamily Family => PacketFamily.Chair;

public MainPlayerStandFromChairHandler(IPlayerInfoProvider playerInfoProvider,
ICharacterRepository characterRepository,
ICurrentMapStateRepository currentMapStateRepository)
: base(playerInfoProvider, characterRepository, currentMapStateRepository) { }
}
}
8 changes: 4 additions & 4 deletions EndlessClient/Controllers/ArrowKeyController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,21 @@ public class ArrowKeyController : IArrowKeyController
private readonly ICharacterAnimationActions _characterAnimationActions;
private readonly ICharacterActions _characterActions;
private readonly ICharacterProvider _characterProvider;
private readonly IWalkErrorHandler _walkErrorHandler;
private readonly IUnwalkableTileActions _unwalkableTileActions;
private readonly ISpikeTrapActions _spikeTrapActions;

public ArrowKeyController(IWalkValidationActions walkValidationActions,
ICharacterAnimationActions characterAnimationActions,
ICharacterActions characterActions,
ICharacterProvider characterProvider,
IWalkErrorHandler walkErrorHandler,
IUnwalkableTileActions walkErrorHandler,
ISpikeTrapActions spikeTrapActions)
{
_walkValidationActions = walkValidationActions;
_characterAnimationActions = characterAnimationActions;
_characterActions = characterActions;
_characterProvider = characterProvider;
_walkErrorHandler = walkErrorHandler;
_unwalkableTileActions = walkErrorHandler;
_spikeTrapActions = spikeTrapActions;
}

Expand Down Expand Up @@ -107,7 +107,7 @@ private void AttemptToStartWalking()
{
if (!_walkValidationActions.CanMoveToDestinationCoordinates())
{
_walkErrorHandler.HandleWalkError();
_unwalkableTileActions.HandleUnwalkableTile();
}
else
{
Expand Down
14 changes: 13 additions & 1 deletion EndlessClient/Controllers/FunctionKeyController.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using AutomaticTypeMapper;
using EOLib.Domain.Character;
using EOLib.Domain.Map;

namespace EndlessClient.Controllers
Expand All @@ -7,10 +8,19 @@ namespace EndlessClient.Controllers
public class FunctionKeyController : IFunctionKeyController
{
private readonly IMapActions _mapActions;
private readonly ICharacterActions _characterActions;

public FunctionKeyController(IMapActions mapActions)
public FunctionKeyController(IMapActions mapActions,
ICharacterActions characterActions)
{
_mapActions = mapActions;
_characterActions = characterActions;
}

public bool Sit()
{
_characterActions.ToggleSit();
return true;
}

public bool RefreshMapState()
Expand All @@ -22,6 +32,8 @@ public bool RefreshMapState()

public interface IFunctionKeyController
{
bool Sit();

bool RefreshMapState();
}
}

0 comments on commit f587db2

Please sign in to comment.