-
Notifications
You must be signed in to change notification settings - Fork 16
/
NPCEntityRenderer.cs
62 lines (53 loc) · 2.56 KB
/
NPCEntityRenderer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
using EndlessClient.Rendering.Map;
using EndlessClient.Rendering.NPC;
using EOLib.Domain.Character;
using EOLib.Domain.Extensions;
using EOLib.Domain.NPC;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Linq;
namespace EndlessClient.Rendering.MapEntityRenderers
{
public class NPCEntityRenderer : BaseMapEntityRenderer
{
private readonly INPCRendererProvider _npcRendererProvider;
public NPCEntityRenderer(ICharacterProvider characterProvider,
IRenderOffsetCalculator renderOffsetCalculator,
INPCRendererProvider npcRendererProvider)
: base(characterProvider, renderOffsetCalculator)
{
_npcRendererProvider = npcRendererProvider;
}
public override MapRenderLayer RenderLayer => MapRenderLayer.Npc;
protected override int RenderDistance => 16;
protected override bool ElementExistsAt(int row, int col)
{
// Render NPCs as part of a row/col one higher than they actually are
// This fixes weird layer render order bugs (without modifying the underlying data structures)
// This is a total hack because I'm not using a depth buffer for map rendering
return _npcRendererProvider.NPCRenderers.Values
.Count(n => IsNpcAt(n.NPC, row + 1, col + 1)) > 0;
}
public override void RenderElementAt(SpriteBatch spriteBatch, int row, int col, int alpha, Vector2 additionalOffset = default)
{
var indicesToRender = _npcRendererProvider.NPCRenderers.Values
.Where(n => IsNpcAt(n.NPC, row + 1, col + 1))
.Select(n => n.NPC.Index);
foreach (var index in indicesToRender)
{
if (!_npcRendererProvider.NPCRenderers.ContainsKey(index) ||
_npcRendererProvider.NPCRenderers[index] == null)
throw new InvalidOperationException(
$"NPC renderer for ID {index} is null or missing! Did you call MapRenderer.Update() before calling MapRenderer.Draw()?");
var renderer = _npcRendererProvider.NPCRenderers[index];
renderer.DrawToSpriteBatch(spriteBatch);
}
}
private static bool IsNpcAt(EOLib.Domain.NPC.NPC npc, int row, int col)
{
return (npc.IsActing(NPCActionState.Walking) && npc.GetDestinationX() == col && npc.GetDestinationY() == row) ||
(npc.X == col && npc.Y == row);
}
}
}