Skip to content

Commit

Permalink
Add check for clicks based on the bounds of the graphic associated wi…
Browse files Browse the repository at this point in the history
…th a map sign
  • Loading branch information
ethanmoffat committed Apr 10, 2022
1 parent 6c05472 commit b0e6f14
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 9 deletions.
6 changes: 3 additions & 3 deletions EndlessClient/Controllers/MapInteractionController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ public MapInteractionController(IMapActions mapActions,
_activeDialogProvider = activeDialogProvider;
}

public void LeftClick(IMapCellState cellState, IMouseCursorRenderer mouseRenderer)
public void LeftClick(IMapCellState cellState, Option<IMouseCursorRenderer> mouseRenderer)
{
if (!InventoryPanel.NoItemsDragging() || _activeDialogProvider.ActiveDialogs.Any(x => x.HasValue))
return;
Expand Down Expand Up @@ -128,7 +128,7 @@ public void LeftClick(IMapCellState cellState, IMouseCursorRenderer mouseRendere
}
else if (cellState.InBounds && !cellState.Character.HasValue && !cellState.NPC.HasValue)
{
mouseRenderer.AnimateClick();
mouseRenderer.MatchSome(r => r.AnimateClick());
_hudControlProvider.GetComponent<ICharacterAnimator>(HudControlIdentifier.CharacterAnimator)
.StartMainCharacterWalkAnimation(Option.Some(cellState.Coordinate));
}
Expand Down Expand Up @@ -229,7 +229,7 @@ private bool CharacterIsCloseEnough(MapCoordinate coordinate)

public interface IMapInteractionController
{
void LeftClick(IMapCellState cellState, IMouseCursorRenderer mouseRenderer);
void LeftClick(IMapCellState cellState, Option<IMouseCursorRenderer> mouseRenderer);

void RightClick(IMapCellState cellState);
}
Expand Down
52 changes: 50 additions & 2 deletions EndlessClient/Rendering/Map/DynamicMapObjectUpdater.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
using AutomaticTypeMapper;
using EndlessClient.Controllers;
using EndlessClient.Input;
using EOLib.Domain.Character;
using EOLib.Domain.Map;
using EOLib.IO.Map;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using Optional;
using System;
using System.Collections.Generic;
using System.Linq;
Expand All @@ -21,14 +26,25 @@ private class DoorTimePair

private readonly ICharacterProvider _characterProvider;
private readonly ICurrentMapStateRepository _currentMapStateRepository;
private readonly IUserInputProvider _userInputProvider;
private readonly ICurrentMapProvider _currentMapProvider;
private readonly IMapObjectBoundsCalculator _mapObjectBoundsCalculator;
private readonly IMapInteractionController _mapInteractionController;
private readonly List<DoorTimePair> _cachedDoorState;

public DynamicMapObjectUpdater(ICharacterProvider characterProvider,
ICurrentMapStateRepository currentMapStateRepository)
ICurrentMapStateRepository currentMapStateRepository,
IUserInputProvider userInputProvider,
ICurrentMapProvider currentMapProvider,
IMapObjectBoundsCalculator mapObjectBoundsCalculator,
IMapInteractionController mapInteractionController)
{
_characterProvider = characterProvider;
_currentMapStateRepository = currentMapStateRepository;

_userInputProvider = userInputProvider;
_currentMapProvider = currentMapProvider;
_mapObjectBoundsCalculator = mapObjectBoundsCalculator;
_mapInteractionController = mapInteractionController;
_cachedDoorState = new List<DoorTimePair>();
}

Expand All @@ -39,6 +55,8 @@ public void UpdateMapObjects(GameTime gameTime)
CloseExpiredDoors(now);

RemoveStaleSpikeTraps();

CheckForObjectClicks();
}

private void OpenNewDoors(DateTime now)
Expand Down Expand Up @@ -75,6 +93,36 @@ private void RemoveStaleSpikeTraps()

_currentMapStateRepository.VisibleSpikeTraps.RemoveWhere(staleTraps.Contains);
}

private void CheckForObjectClicks()
{
var mouseClicked = _userInputProvider.PreviousMouseState.LeftButton == ButtonState.Pressed &&
_userInputProvider.CurrentMouseState.LeftButton == ButtonState.Released;

if (mouseClicked)
{
foreach (var sign in _currentMapProvider.CurrentMap.Signs)
{
var gfx = _currentMapProvider.CurrentMap.GFX[MapLayer.Objects][sign.Y, sign.X];
if (gfx > 0)
{
var bounds = _mapObjectBoundsCalculator.GetMapObjectBounds(sign.X, sign.Y, gfx);
if (bounds.Contains(_userInputProvider.CurrentMouseState.Position))
{
var cellState = new MapCellState
{
Sign = Option.Some<ISign>(new Sign(sign)),
Coordinate = new MapCoordinate(sign.X, sign.Y)
};
_mapInteractionController.LeftClick(cellState, Option.None<IMouseCursorRenderer>());
break;
}
}
}

// todo: check for board object clicks
}
}
}

public interface IDynamicMapObjectUpdater
Expand Down
45 changes: 45 additions & 0 deletions EndlessClient/Rendering/Map/MapObjectBoundsCalculator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using AutomaticTypeMapper;
using EndlessClient.Rendering.MapEntityRenderers;
using EOLib.Domain.Character;
using EOLib.Graphics;
using Microsoft.Xna.Framework;
using System.Linq;

namespace EndlessClient.Rendering.Map
{
[AutoMappedType]
public class MapObjectBoundsCalculator : IMapObjectBoundsCalculator
{
private readonly INativeGraphicsManager _nativeGraphicsManager;
private readonly ICharacterProvider _characterProvider;
private readonly IRenderOffsetCalculator _renderOffsetCalculator;
private readonly MapObjectLayerRenderer _objectRenderer;

public MapObjectBoundsCalculator(INativeGraphicsManager nativeGraphicsManager,
ICharacterProvider characterProvider,
IRenderOffsetCalculator renderOffsetCalculator,
IMapEntityRendererProvider mapEntityRendererProvider)
{
_nativeGraphicsManager = nativeGraphicsManager;
_characterProvider = characterProvider;
_renderOffsetCalculator = renderOffsetCalculator;

_objectRenderer = mapEntityRendererProvider.MapEntityRenderers.OfType<MapObjectLayerRenderer>().Single();
}

public Rectangle GetMapObjectBounds(int gridX, int gridY, int gfxNum)
{
var gfx = _nativeGraphicsManager.TextureFromResource(GFXTypes.MapObjects, gfxNum, transparent: true);
var drawPosition = _objectRenderer.GetDrawCoordinatesFromGridUnits(gridX, gridY);
// see: MapObjectLayerRenderer
// todo: more centralized way of representing this
drawPosition -= new Vector2(gfx.Width / 2, gfx.Height - 32);
return gfx.Bounds.WithPosition(drawPosition);
}
}

public interface IMapObjectBoundsCalculator
{
Rectangle GetMapObjectBounds(int gridX, int gridY, int gfxNum);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ public virtual void RenderElementAt(SpriteBatch spriteBatch, int row, int col, i
}
}

protected virtual Vector2 GetDrawCoordinatesFromGridUnits(int gridX, int gridY)
// todo: this shouldn't be public, move to another service that's responsible for calculating the offsets for map entities
public virtual Vector2 GetDrawCoordinatesFromGridUnits(int gridX, int gridY)
{
const int ViewportWidthFactor = 320; // 640 * (1/2)
const int ViewportHeightFactor = 144; // 480 * (3/10)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public GroundLayerRenderer(INativeGraphicsManager nativeGraphicsManager,
_currentMapProvider = currentMapProvider;
}

protected override Vector2 GetDrawCoordinatesFromGridUnits(int gridX, int gridY)
public override Vector2 GetDrawCoordinatesFromGridUnits(int gridX, int gridY)
{
// the height is used to offset the 0 point of the grid, which is 32 units per tile in the height of the map
var height = CurrentMap.Properties.Height;
Expand Down Expand Up @@ -97,7 +97,7 @@ protected override bool ElementExistsAt(int row, int col)
return tileExists && _nativeGraphicsManager.TextureFromResource(GFXTypes.MapTiles, tileId, true).Width > TILE_FRAME_WIDTH;
}

protected override Vector2 GetDrawCoordinatesFromGridUnits(int gridX, int gridY)
public override Vector2 GetDrawCoordinatesFromGridUnits(int gridX, int gridY)
{
var offsetX = _renderOffsetCalculator.CalculateOffsetX(_characterProvider.MainCharacter.RenderProperties) - 288;
var offsetY = _renderOffsetCalculator.CalculateOffsetY(_characterProvider.MainCharacter.RenderProperties) - 144;
Expand Down
2 changes: 1 addition & 1 deletion EndlessClient/Rendering/MouseCursorRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ private void CheckForClicks(IMapCellState cellState)
if (currentMouseState.LeftButton == ButtonState.Released &&
previousMouseState.LeftButton == ButtonState.Pressed)
{
_mapInteractionController.LeftClick(cellState, this);
_mapInteractionController.LeftClick(cellState, Option.Some<IMouseCursorRenderer>(this));
}
}

Expand Down

0 comments on commit b0e6f14

Please sign in to comment.