Skip to content

Commit

Permalink
First pass of map earthquake effects
Browse files Browse the repository at this point in the history
  • Loading branch information
ethanmoffat committed Jan 27, 2021
1 parent 23745f1 commit 6b70cb4
Show file tree
Hide file tree
Showing 21 changed files with 167 additions and 63 deletions.
2 changes: 2 additions & 0 deletions EOLib/Domain/Notifiers/IEffectNotifier.cs
Expand Up @@ -8,6 +8,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);
}

[AutoMappedType]
Expand All @@ -16,5 +17,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) { }
}
}
1 change: 1 addition & 0 deletions EOLib/EOLib.csproj
Expand Up @@ -254,6 +254,7 @@
<Compile Include="PacketHandlers\Chat\GroupChatHandler.cs" />
<Compile Include="PacketHandlers\DoorOpenHandler.cs" />
<Compile Include="PacketHandlers\Effects\EffectPotionHandler.cs" />
<Compile Include="PacketHandlers\Effects\MapQuakeHandler.cs" />
<Compile Include="PacketHandlers\EndPlayerWarpHandler.cs" />
<Compile Include="PacketHandlers\ItemPickupHandler.cs" />
<Compile Include="PacketHandlers\MainPlayerWalkHandler.cs" />
Expand Down
40 changes: 40 additions & 0 deletions EOLib/PacketHandlers/Effects/MapQuakeHandler.cs
@@ -0,0 +1,40 @@
using AutomaticTypeMapper;
using EOLib.Domain.Login;
using EOLib.Domain.Notifiers;
using EOLib.Net;
using EOLib.Net.Handlers;
using System.Collections.Generic;

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

public override PacketFamily Family => PacketFamily.Effect;
public override PacketAction Action => PacketAction.Use;

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

public override bool HandlePacket(IPacket packet)
{
const int EffectQuake = 1;

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

var strength = packet.ReadChar();

foreach (var notifier in _effectNotifiers)
notifier.NotifyEarthquake(strength);

return true;
}
}
}
Expand Up @@ -180,6 +180,12 @@ public void NotifyTargetOtherSpellCast(short sourcePlayerID, short targetPlayerI
}
}

public void NotifyEarthquake(byte strength)
{
var mapRenderer = _hudControlProvider.GetComponent<IMapRenderer>(HudControlIdentifier.MapRenderer);
mapRenderer.StartEarthquake(strength);
}

private void ShowWaterSplashiesIfNeeded(CharacterActionState action, ICharacter character, ICharacterRenderer characterRenderer)
{
var rp = character.RenderProperties;
Expand Down
2 changes: 2 additions & 0 deletions EndlessClient/Rendering/Map/IMapRenderer.cs
Expand Up @@ -5,5 +5,7 @@ namespace EndlessClient.Rendering.Map
public interface IMapRenderer : IGameComponent
{
void StartMapTransition();

void StartEarthquake(byte strength);
}
}
109 changes: 79 additions & 30 deletions EndlessClient/Rendering/Map/MapRenderer.cs
Expand Up @@ -34,6 +34,7 @@ public class MapRenderer : DrawableGameComponent, IMapRenderer
private readonly IConfigurationProvider _configurationProvider;
private readonly IMouseCursorRenderer _mouseCursorRenderer;
private readonly IRenderOffsetCalculator _renderOffsetCalculator;
private readonly Random _random;

private RenderTarget2D _mapBaseTarget, _mapObjectTarget;
private SpriteBatch _sb;
Expand Down Expand Up @@ -77,6 +78,7 @@ private bool MouseOver
_configurationProvider = configurationProvider;
_mouseCursorRenderer = mouseCursorRenderer;
_renderOffsetCalculator = renderOffsetCalculator;
_random = new Random();
}

public override void Initialize()
Expand Down Expand Up @@ -113,6 +115,8 @@ public override void Update(GameTime gameTime)

if (MouseOver)
_mouseCursorRenderer.Update(gameTime);

UpdateQuakeState();
}

_lastMapChecksum = _currentMapProvider.CurrentMap.Properties.ChecksumInt;
Expand All @@ -137,18 +141,57 @@ public void StartMapTransition()
_mapTransitionState = new MapTransitionState(DateTime.Now, 1);
}

private void DrawToSpriteBatch(SpriteBatch spriteBatch, GameTime gameTime)
public void StartEarthquake(byte strength)
{
spriteBatch.Begin();
_hasQuake = true;
_quakeMagnitude = strength;
_quakeState = _quakeTick = 0;
_quakeOffset = 0;
_quakeOffsetTarget = 16 + 3 * _random.Next(2, _quakeMagnitude * 2);
}

spriteBatch.Draw(_mapBaseTarget, GetGroundLayerDrawPosition(), Color.White);
DrawBaseLayers(spriteBatch);
// when quake:
// 1. determine offset target (random from on magnitude/2 -> magnitude)
// 2. update every 8 ticks toward target
// 3. when target reached, determine new target (random based on magnitude)
// 4. flip direction
// 5. keep going until specific number of frames has elapsed

_mouseCursorRenderer.Draw(spriteBatch, gameTime);
private bool _hasQuake;
private int _quakeMagnitude;

spriteBatch.Draw(_mapObjectTarget, Vector2.Zero, Color.White);
private int _quakeState;
private int _quakeTick;

spriteBatch.End();
private float _quakeOffset;
private float _quakeOffsetTarget;

private void UpdateQuakeState()
{
if (!_hasQuake)
return;

_quakeOffset += _quakeOffsetTarget / 4f;
_quakeTick++;

if (Math.Abs(_quakeOffset) > Math.Abs(_quakeOffsetTarget))
{
_quakeState++;
_quakeTick = 0;

var flip = -_quakeOffsetTarget / Math.Abs(_quakeOffsetTarget);
_quakeOffset = _quakeOffsetTarget - 1;
_quakeOffsetTarget = 16 + 3 * _random.Next(0, (int)(_quakeMagnitude * 1.5));
_quakeOffsetTarget *= flip;
}

if (_quakeState > 10 + _quakeMagnitude*2)
{
_hasQuake = false;
_quakeState = _quakeTick = 0;
_quakeOffset = 0;
_quakeOffsetTarget = 0;
}
}

private void DrawGroundLayerToRenderTarget()
Expand Down Expand Up @@ -182,25 +225,6 @@ private void DrawGroundLayerToRenderTarget()
GraphicsDevice.SetRenderTarget(null);
}

private void DrawBaseLayers(SpriteBatch spriteBatch)
{
var renderBounds = _mapRenderDistanceCalculator.CalculateRenderBounds(_characterProvider.MainCharacter, _currentMapProvider.CurrentMap);

for (var row = renderBounds.FirstRow; row <= renderBounds.LastRow; row++)
{
for (var col = renderBounds.FirstCol; col <= renderBounds.LastCol; ++col)
{
var alpha = GetAlphaForCoordinates(col, row, _characterProvider.MainCharacter);

foreach (var renderer in _mapEntityRendererProvider.BaseRenderers)
{
if (renderer.CanRender(row, col))
renderer.RenderElementAt(spriteBatch, row, col, alpha);
}
}
}
}

private void DrawMapToRenderTarget()
{
var immutableCharacter = _characterProvider.MainCharacter;
Expand Down Expand Up @@ -255,12 +279,37 @@ private void DrawMapToRenderTarget()
GraphicsDevice.SetRenderTarget(null);
}

private static bool CharacterIsAtPosition(ICharacterRenderProperties renderProperties, int row, int col)
private void DrawToSpriteBatch(SpriteBatch spriteBatch, GameTime gameTime)
{
spriteBatch.Begin();

spriteBatch.Draw(_mapBaseTarget, GetGroundLayerDrawPosition() + new Vector2(_quakeOffset, 0), Color.White);
DrawBaseLayers(spriteBatch);

_mouseCursorRenderer.Draw(spriteBatch, new Vector2(_quakeOffset, 0));

spriteBatch.Draw(_mapObjectTarget, new Vector2(_quakeOffset, 0), Color.White);

spriteBatch.End();
}

private void DrawBaseLayers(SpriteBatch spriteBatch)
{
if (renderProperties.IsActing(CharacterActionState.Walking))
return row == renderProperties.GetDestinationY() && col == renderProperties.GetDestinationX();
var renderBounds = _mapRenderDistanceCalculator.CalculateRenderBounds(_characterProvider.MainCharacter, _currentMapProvider.CurrentMap);

return row == renderProperties.MapY && col == renderProperties.MapX;
for (var row = renderBounds.FirstRow; row <= renderBounds.LastRow; row++)
{
for (var col = renderBounds.FirstCol; col <= renderBounds.LastCol; ++col)
{
var alpha = GetAlphaForCoordinates(col, row, _characterProvider.MainCharacter);

foreach (var renderer in _mapEntityRendererProvider.BaseRenderers)
{
if (renderer.CanRender(row, col))
renderer.RenderElementAt(spriteBatch, row, col, alpha, new Vector2(_quakeOffset, 0));
}
}
}
}

private Vector2 GetGroundLayerDrawPosition()
Expand Down
Expand Up @@ -63,7 +63,7 @@ public virtual bool CanRender(int row, int col)

protected abstract bool ElementExistsAt(int row, int col);

public virtual void RenderElementAt(SpriteBatch spriteBatch, int row, int col, int alpha)
public virtual void RenderElementAt(SpriteBatch spriteBatch, int row, int col, int alpha, Vector2 additionalOffset = default)
{
if ((DateTime.Now - _lastFrameTime).TotalMilliseconds > 500)
{
Expand Down
Expand Up @@ -45,7 +45,7 @@ protected override bool ElementExistsAt(int row, int col)
CurrentMap.GFX[MapLayer.GroundTile][row, col] > 0;
}

public override void RenderElementAt(SpriteBatch spriteBatch, int row, int col, int alpha)
public override void RenderElementAt(SpriteBatch spriteBatch, int row, int col, int alpha, Vector2 additionalOffset = default)
{
base.RenderElementAt(spriteBatch, row, col, alpha);

Expand All @@ -69,7 +69,7 @@ public override void RenderElementAt(SpriteBatch spriteBatch, int row, int col,
var src = tileTexture.Width > TILE_FRAME_WIDTH
? new Rectangle?(new Rectangle((tileTexture.Width / 4) * _frameIndex, 0, tileTexture.Width / 4, tileTexture.Height))
: null;
spriteBatch.Draw(tileTexture, pos, src, Color.FromNonPremultiplied(255, 255, 255, alpha));
spriteBatch.Draw(tileTexture, pos + additionalOffset, src, Color.FromNonPremultiplied(255, 255, 255, alpha));
}

protected IMapFile CurrentMap => _currentMapProvider.CurrentMap;
Expand Down
@@ -1,5 +1,6 @@
using System;
using EndlessClient.Rendering.Map;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace EndlessClient.Rendering.MapEntityRenderers
Expand All @@ -12,6 +13,6 @@ public interface IMapEntityRenderer

bool CanRender(int row, int col);

void RenderElementAt(SpriteBatch spriteBatch, int row, int col, int alpha);
void RenderElementAt(SpriteBatch spriteBatch, int row, int col, int alpha, Vector2 additionalPixelOffset = default);
}
}
Expand Up @@ -3,6 +3,7 @@
using EndlessClient.Rendering.Chat;
using EndlessClient.Rendering.Map;
using EOLib.Domain.Character;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace EndlessClient.Rendering.MapEntityRenderers
Expand Down Expand Up @@ -36,7 +37,7 @@ protected override bool ElementExistsAt(int row, int col)
col == _characterProvider.MainCharacter.RenderProperties.MapX;
}

public override void RenderElementAt(SpriteBatch spriteBatch, int row, int col, int alpha)
public override void RenderElementAt(SpriteBatch spriteBatch, int row, int col, int alpha, Vector2 additionalOffset = default)
{
if (_characterRendererProvider.MainCharacterRenderer == null)
return;
Expand Down
Expand Up @@ -32,7 +32,7 @@ protected override bool ElementExistsAt(int row, int col)
return _currentMapStateProvider.MapItems.Any(item => item.X == col && item.Y == row);
}

public override void RenderElementAt(SpriteBatch spriteBatch, int row, int col, int alpha)
public override void RenderElementAt(SpriteBatch spriteBatch, int row, int col, int alpha, Vector2 additionalOffset = default)
{
var items = _currentMapStateProvider.MapItems.Where(item => item.X == col && item.Y == row);

Expand All @@ -44,7 +44,7 @@ public override void RenderElementAt(SpriteBatch spriteBatch, int row, int col,

spriteBatch.Draw(itemTexture,
new Vector2(itemPos.X - (int) Math.Round(itemTexture.Width/2.0),
itemPos.Y - (int) Math.Round(itemTexture.Height/2.0)),
itemPos.Y - (int) Math.Round(itemTexture.Height/2.0)) + additionalOffset,
Color.FromNonPremultiplied(255, 255, 255, alpha));
}
}
Expand Down
Expand Up @@ -39,15 +39,15 @@ protected override bool ElementExistsAt(int row, int col)
_currentMapStateProvider.VisibleSpikeTraps.Contains(new MapCoordinate(col, row)));
}

public override void RenderElementAt(SpriteBatch spriteBatch, int row, int col, int alpha)
public override void RenderElementAt(SpriteBatch spriteBatch, int row, int col, int alpha, Vector2 additionalOffset = default)
{
int gfxNum = MapFile.GFX[MapLayer.Objects][row, col];
var gfx = _nativeGraphicsManager.TextureFromResource(GFXTypes.MapObjects, gfxNum, true);

var pos = GetDrawCoordinatesFromGridUnits(col, row);
pos -= new Vector2(gfx.Width / 2, gfx.Height - 32);

spriteBatch.Draw(gfx, pos, Color.FromNonPremultiplied(255, 255, 255, alpha));
spriteBatch.Draw(gfx, pos + additionalOffset, Color.FromNonPremultiplied(255, 255, 255, alpha));
}

private IMapFile MapFile => _currentMapProvider.CurrentMap;
Expand Down
Expand Up @@ -4,6 +4,7 @@
using EndlessClient.Rendering.Map;
using EndlessClient.Rendering.NPC;
using EOLib.Domain.Character;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace EndlessClient.Rendering.MapEntityRenderers
Expand Down Expand Up @@ -33,7 +34,7 @@ protected override bool ElementExistsAt(int row, int col)
.Count(n => n.NPC.X == col && n.NPC.Y == row) > 0;
}

public override void RenderElementAt(SpriteBatch spriteBatch, int row, int col, int alpha)
public override void RenderElementAt(SpriteBatch spriteBatch, int row, int col, int alpha, Vector2 additionalOffset = default)
{
var indicesToRender = _npcRendererProvider.NPCRenderers.Values
.Where(n => n.NPC.X == col && n.NPC.Y == row)
Expand Down
Expand Up @@ -32,13 +32,13 @@ protected override bool ElementExistsAt(int row, int col)
return CurrentMap.GFX[MapLayer.OverlayTile][row, col] > 0;
}

public override void RenderElementAt(SpriteBatch spriteBatch, int row, int col, int alpha)
public override void RenderElementAt(SpriteBatch spriteBatch, int row, int col, int alpha, Vector2 additionalOffset = default)
{
int gfxNum = CurrentMap.GFX[MapLayer.OverlayTile][row, col];
var gfx = _nativeGraphicsManager.TextureFromResource(GFXTypes.MapTiles, gfxNum, true);

var pos = GetDrawCoordinatesFromGridUnits(col, row);
spriteBatch.Draw(gfx, pos, Color.FromNonPremultiplied(255, 255, 255, alpha));
spriteBatch.Draw(gfx, pos + additionalOffset, Color.FromNonPremultiplied(255, 255, 255, alpha));
}

private IMapFile CurrentMap => _currentMapProvider.CurrentMap;
Expand Down
Expand Up @@ -4,6 +4,7 @@
using EndlessClient.Rendering.Chat;
using EndlessClient.Rendering.Map;
using EOLib.Domain.Character;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace EndlessClient.Rendering.MapEntityRenderers
Expand Down Expand Up @@ -37,7 +38,7 @@ protected override bool ElementExistsAt(int row, int col)
.Any(c => c.MapY == row && c.MapX == col);
}

public override void RenderElementAt(SpriteBatch spriteBatch, int row, int col, int alpha)
public override void RenderElementAt(SpriteBatch spriteBatch, int row, int col, int alpha, Vector2 additionalOffset = default)
{
var idsToRender = _characterStateCache.OtherCharacters.Keys.Where(
key => _characterStateCache.OtherCharacters[key].RenderProperties.MapX == col &&
Expand Down

0 comments on commit 6b70cb4

Please sign in to comment.