added inventory events

This commit is contained in:
MasterGordon 2022-12-20 22:59:09 +01:00
parent c2fd66a8f0
commit 0320bbc6a6
12 changed files with 140 additions and 50 deletions

View File

@ -81,3 +81,6 @@ resharper_suggest_var_or_type_simple_types_highlighting = hint
resharper_web_config_module_not_resolved_highlighting = warning resharper_web_config_module_not_resolved_highlighting = warning
resharper_web_config_type_not_resolved_highlighting = warning resharper_web_config_type_not_resolved_highlighting = warning
resharper_web_config_wrong_module_highlighting = warning resharper_web_config_wrong_module_highlighting = warning
# ignore RCS1102
dotnet_diagnostic.RCS1102.severity = none

2
Mine2d/.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,2 @@
{
}

View File

@ -1,3 +1,4 @@
using System.Reflection;
using Mine2d.engine.system; using Mine2d.engine.system;
using Mine2d.engine.system.annotations; using Mine2d.engine.system.annotations;
using Mine2d.game.core.extensions; using Mine2d.game.core.extensions;
@ -23,7 +24,7 @@ public class EventPublisher
{ {
var types = this.GetType().Assembly var types = this.GetType().Assembly
.GetTypesSafe() .GetTypesSafe()
.Where(t => t.Namespace != null && t.Namespace.StartsWith("Mine2d.game.frontend.events", StringComparison.Ordinal)); .Where(t => t.Namespace?.StartsWith("Mine2d.game.frontend.events", StringComparison.Ordinal) == true);
foreach (var type in types) foreach (var type in types)
{ {
var methods = type.GetMethods() var methods = type.GetMethods()
@ -57,7 +58,7 @@ public class EventPublisher
foreach (var (_, value) in this.eventListeners) foreach (var (_, value) in this.eventListeners)
{ {
value.Sort((a, b) => a.Priority.CompareTo(b.Priority)); value.Sort((a, b) => b.Priority.CompareTo(a.Priority));
} }
} }
@ -75,11 +76,11 @@ public class EventPublisher
public void Publish(EventType eventType, SDL_Event e) public void Publish(EventType eventType, SDL_Event e)
{ {
if (this.eventListeners.ContainsKey(eventType)) if (this.eventListeners.TryGetValue(eventType, out var value))
{ {
try try
{ {
foreach (var action in this.eventListeners[eventType]) foreach (var action in value)
{ {
if (action.Del.Method.GetParameters().Length == 0) if (action.Del.Method.GetParameters().Length == 0)
{ {
@ -91,9 +92,8 @@ public class EventPublisher
} }
} }
} }
catch (CancelEventException) catch (TargetInvocationException ex) when (ex.InnerException is CancelEventException)
{ {
} }
} }
} }
@ -101,7 +101,8 @@ public class EventPublisher
public class CancelEventException : Exception public class CancelEventException : Exception
{ {
public CancelEventException(string message) : base(message) [System.Diagnostics.DebuggerHidden]
public CancelEventException() : base("Event cancelled")
{ {
} }
} }

View File

@ -10,4 +10,10 @@ public class EventListenerAttribute : Attribute
{ {
this.Type = type; this.Type = type;
} }
public EventListenerAttribute(EventType type, EventPriority priority)
{
this.Type = type;
this.Priority = priority;
}
} }

View File

@ -1,3 +1,4 @@
using Mine2d.engine;
using Mine2d.engine.system; using Mine2d.engine.system;
using Mine2d.engine.system.annotations; using Mine2d.engine.system.annotations;
using Mine2d.game.state; using Mine2d.game.state;
@ -40,17 +41,42 @@ public class InventoryInput
} }
} }
[EventListener(EventType.KeyDown)] [EventListener(EventType.KeyDown, EventPriority.Highest)]
public static void OnKeyDownOpenInventory(SDL_Event e) public static void OnKeyDownOpenInventory(SDL_Event e)
{ {
var frontendGameState = Context.Get().FrontendGameState; var frontendGameState = Context.Get().FrontendGameState;
if(e.key.keysym.sym == SDL_Keycode.SDLK_TAB) if(e.key.keysym.sym == SDL_Keycode.SDLK_TAB)
{ {
if(frontendGameState.OpenInventory != Inventory.Player) { if(frontendGameState.OpenInventory != InventoryKind.Player) {
frontendGameState.OpenInventory = Inventory.Player; frontendGameState.OpenInventory = InventoryKind.Player;
} else { } else {
frontendGameState.OpenInventory = Inventory.None; frontendGameState.OpenInventory = InventoryKind.None;
} }
}
if(frontendGameState.OpenInventory != InventoryKind.None)
{
throw new CancelEventException();
}
}
[EventListener(EventType.KeyUp, EventPriority.Highest)]
public static void OnKeyUpOpenInventory(SDL_Event e)
{
var frontendGameState = Context.Get().FrontendGameState;
if(frontendGameState.OpenInventory != InventoryKind.None)
{
throw new CancelEventException();
}
}
[EventListener(EventType.MouseButtonDown, EventPriority.Highest)]
public static void OnMouseButtonDownOpenInventory(SDL_Event e)
{
var frontendGameState = Context.Get().FrontendGameState;
Context.Get().InventoryRegistry.GetInventory(frontendGameState.OpenInventory)?.OnClick(e);
if(frontendGameState.OpenInventory != InventoryKind.None)
{
throw new CancelEventException();
} }
} }
} }

View File

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Mine2d.engine;
namespace Mine2d.game.frontend.inventory;
public class Inventory : IRenderer
{
public virtual void Render() { }
public virtual void OnKeyDown(SDL_Event e) { }
public virtual void OnClick(SDL_Event e) { }
}

View File

@ -8,15 +8,17 @@ namespace Mine2d.game.frontend.inventory;
public class InventoryRegistry public class InventoryRegistry
{ {
private readonly Dictionary<Inventory, IInventoryRenderer> inventoryRenderers = new(); private readonly Dictionary<InventoryKind, Inventory> inventoryRenderers = new();
public InventoryRegistry() public InventoryRegistry()
{ {
this.inventoryRenderers.Add(Inventory.Player, new PlayerInventoryRenderer()); this.inventoryRenderers.Add(InventoryKind.Player, new PlayerInventoryRenderer());
} }
public IInventoryRenderer GetRenderer(Inventory inventory) public Inventory GetInventory(InventoryKind inventory)
{ {
if(!this.inventoryRenderers.ContainsKey(inventory))
return null;
return this.inventoryRenderers[inventory]; return this.inventoryRenderers[inventory];
} }
} }

View File

@ -1,11 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Mine2d.engine;
namespace Mine2d.game.frontend.inventory;
public interface IInventoryRenderer : IRenderer
{
}

View File

@ -1,12 +1,15 @@
using System.Diagnostics;
using Mine2d.game.core; using Mine2d.game.core;
namespace Mine2d.game.frontend.inventory namespace Mine2d.game.frontend.inventory
{ {
public class PlayerInventoryRenderer : IInventoryRenderer
public class PlayerInventoryRenderer : Inventory
{ {
private IntPtr texture = IntPtr.Zero; private IntPtr texture = IntPtr.Zero;
private int x, y;
public void Render() public override void Render()
{ {
var ctx = Context.Get(); var ctx = Context.Get();
if (this.texture == IntPtr.Zero) if (this.texture == IntPtr.Zero)
@ -19,9 +22,9 @@ namespace Mine2d.game.frontend.inventory
height *= uiScale; height *= uiScale;
var extraSlotsWidth = InventoryConstants.ExtraSlotsWidth * uiScale; var extraSlotsWidth = InventoryConstants.ExtraSlotsWidth * uiScale;
var (windowWidth, windowHeight) = (ctx.FrontendGameState.WindowWidth, ctx.FrontendGameState.WindowHeight); var (windowWidth, windowHeight) = (ctx.FrontendGameState.WindowWidth, ctx.FrontendGameState.WindowHeight);
var x = (windowWidth - (width - extraSlotsWidth)) / 2; this.x = (windowWidth - (width - extraSlotsWidth)) / 2;
var y = (windowHeight - height) / 2; this.y = (windowHeight - height) / 2;
ctx.Renderer.DrawTexture(this.texture, x, y, width, height); ctx.Renderer.DrawTexture(this.texture, this.x, this.y, width, height);
var player = PlayerEntity.GetSelf(); var player = PlayerEntity.GetSelf();
var inventory = player.Inventory.Inventory; var inventory = player.Inventory.Inventory;
@ -38,20 +41,21 @@ namespace Mine2d.game.frontend.inventory
var itemTexture = stack.GetTexture(); var itemTexture = stack.GetTexture();
ctx.Renderer.DrawTexture( ctx.Renderer.DrawTexture(
itemTexture, itemTexture,
((4 + (i * 22)) * uiScale) + x, ((4 + (i * 21)) * uiScale) + this.x,
(4 * uiScale) + y, (4 * uiScale) + this.y,
16 * uiScale, 16 * uiScale,
16 * uiScale 16 * uiScale
); );
ctx.Renderer.DrawText( ctx.Renderer.DrawText(
"" + stack.Count, "" + stack.Count,
((4 + (i * 22)) * uiScale) + x, ((4 + (i * 21)) * uiScale) + this.x,
(14 * uiScale) + y (14 * uiScale) + this.y
); );
if (cursorPosition.X >= ((4 + (i * 22)) * uiScale) + x if (player.Inventory.cursor == null &&
&& cursorPosition.X <= ((4 + (i * 22)) * uiScale) + x + (16 * uiScale) cursorPosition.X >= ((4 + (i * 21)) * uiScale) + this.x
&& cursorPosition.Y >= (4 * uiScale) + y && cursorPosition.X <= ((4 + (i * 21)) * uiScale) + this.x + (16 * uiScale)
&& cursorPosition.Y <= (4 * uiScale) + y + (16 * uiScale) && cursorPosition.Y >= (4 * uiScale) + this.y
&& cursorPosition.Y <= (4 * uiScale) + this.y + (16 * uiScale)
) )
{ {
Context.Get().FrontendGameState.Tooltip = stack.GetName(); Context.Get().FrontendGameState.Tooltip = stack.GetName();
@ -68,25 +72,62 @@ namespace Mine2d.game.frontend.inventory
var itemTexture = stack.GetTexture(); var itemTexture = stack.GetTexture();
ctx.Renderer.DrawTexture( ctx.Renderer.DrawTexture(
itemTexture, itemTexture,
((4 + ((i % 9) * 22)) * uiScale) + x, ((4 + ((i % 9) * 21)) * uiScale) + this.x,
((4 + 21 + ((i / 9) * 22)) * uiScale) + y, ((4 + 21 + ((i / 9) * 21)) * uiScale) + this.y,
16 * uiScale, 16 * uiScale,
16 * uiScale 16 * uiScale
); );
ctx.Renderer.DrawText( ctx.Renderer.DrawText(
"" + stack.Count, "" + stack.Count,
((4 + ((i % 9) * 22)) * uiScale) + x, ((4 + ((i % 9) * 21)) * uiScale) + this.x,
((14 + 21 + ((i / 9) * 22)) * uiScale) + y ((14 + 21 + ((i / 9) * 21)) * uiScale) + this.y
); );
if (cursorPosition.X >= ((4 + ((i % 9) * 22)) * uiScale) + x if (player.Inventory.cursor == null &&
&& cursorPosition.X <= ((4 + ((i % 9) * 22)) * uiScale) + x + (16 * uiScale) cursorPosition.X >= ((4 + ((i % 9) * 21)) * uiScale) + this.x
&& cursorPosition.Y >= ((4 + 21 + ((i / 9) * 22)) * uiScale) + y && cursorPosition.X <= ((4 + ((i % 9) * 21)) * uiScale) + this.x + (16 * uiScale)
&& cursorPosition.Y <= ((4 + 21 + ((i / 9) * 22)) * uiScale) + y + (16 * uiScale) && cursorPosition.Y >= ((4 + 21 + ((i / 9) * 21)) * uiScale) + this.y
&& cursorPosition.Y <= ((4 + 21 + ((i / 9) * 21)) * uiScale) + this.y + (16 * uiScale)
) )
{ {
Context.Get().FrontendGameState.Tooltip = stack.GetName(); Context.Get().FrontendGameState.Tooltip = stack.GetName();
} }
} }
} }
public override void OnClick(SDL_Event e)
{
var cursorPosition = Context.Get().FrontendGameState.CursorPosition;
// is hotbar
if (cursorPosition.X >= this.x + (4 * Context.Get().FrontendGameState.Settings.UiScale)
&& cursorPosition.X <= this.x + (4 * Context.Get().FrontendGameState.Settings.UiScale) + (21 * 9 * Context.Get().FrontendGameState.Settings.UiScale)
&& cursorPosition.Y >= this.y + (4 * Context.Get().FrontendGameState.Settings.UiScale)
&& cursorPosition.Y <= this.y + (4 * Context.Get().FrontendGameState.Settings.UiScale) + (21 * Context.Get().FrontendGameState.Settings.UiScale)
)
{
var player = PlayerEntity.GetSelf();
var hotbar = player.Inventory.Hotbar;
var index = (int)((cursorPosition.X - (this.x + (4 * Context.Get().FrontendGameState.Settings.UiScale))) / (21 * Context.Get().FrontendGameState.Settings.UiScale));
if (e.button.button == SDL_BUTTON_LEFT)
{
player.Inventory.SwapWithCursor(index, hotbar);
}
}
// is inventory
if (cursorPosition.X >= this.x + (4 * Context.Get().FrontendGameState.Settings.UiScale)
&& cursorPosition.X <= this.x + (4 * Context.Get().FrontendGameState.Settings.UiScale) + (21 * 9 * Context.Get().FrontendGameState.Settings.UiScale)
&& cursorPosition.Y >= this.y + (4 * Context.Get().FrontendGameState.Settings.UiScale) + (21 * Context.Get().FrontendGameState.Settings.UiScale)
&& cursorPosition.Y <= this.y + (4 * Context.Get().FrontendGameState.Settings.UiScale) + (21 * 5 * Context.Get().FrontendGameState.Settings.UiScale)
)
{
var player = PlayerEntity.GetSelf();
var inventory = player.Inventory.Inventory;
var index = (int)((cursorPosition.X - (this.x + (4 * Context.Get().FrontendGameState.Settings.UiScale))) / (21 * Context.Get().FrontendGameState.Settings.UiScale))
+ ((int)((cursorPosition.Y - (this.y + (4 * Context.Get().FrontendGameState.Settings.UiScale) + (21 * Context.Get().FrontendGameState.Settings.UiScale))) / (21 * Context.Get().FrontendGameState.Settings.UiScale)) * 9);
if (e.button.button == SDL_BUTTON_LEFT)
{
player.Inventory.SwapWithCursor(index, inventory);
}
}
}
} }
} }

View File

@ -8,11 +8,11 @@ namespace Mine2d.game.frontend.renderer
public void Render() { public void Render() {
var ctx = Context.Get(); var ctx = Context.Get();
var inventory = ctx.FrontendGameState.OpenInventory; var inventory = ctx.FrontendGameState.OpenInventory;
if(inventory == Inventory.None) return; if(inventory == InventoryKind.None) return;
ctx.Renderer.SetColor(0, 0, 0, 200); ctx.Renderer.SetColor(0, 0, 0, 200);
ctx.Renderer.SetDrawBlendMode(SDL_BlendMode.SDL_BLENDMODE_BLEND); ctx.Renderer.SetDrawBlendMode(SDL_BlendMode.SDL_BLENDMODE_BLEND);
ctx.Renderer.DrawRect(0, 0, ctx.FrontendGameState.WindowWidth, ctx.FrontendGameState.WindowHeight); ctx.Renderer.DrawRect(0, 0, ctx.FrontendGameState.WindowWidth, ctx.FrontendGameState.WindowHeight);
var inventoryRenderer = ctx.InventoryRegistry.GetRenderer(inventory); var inventoryRenderer = ctx.InventoryRegistry.GetInventory(inventory);
inventoryRenderer.Render(); inventoryRenderer.Render();
} }
} }

View File

@ -2,7 +2,7 @@ using Mine2d.game.core;
namespace Mine2d.game.state; namespace Mine2d.game.state;
public enum Inventory { public enum InventoryKind {
None, None,
Player Player
} }
@ -20,7 +20,7 @@ public class FrontendGameState
public string PlayerName { get; set; } = "Player"; public string PlayerName { get; set; } = "Player";
public int HotbarIndex { get; set; } public int HotbarIndex { get; set; }
public string Tooltip { get; set; } = "Test"; public string Tooltip { get; set; } = "Test";
public Inventory OpenInventory { get; set; } = Inventory.None; public InventoryKind OpenInventory { get; set; } = InventoryKind.None;
} }
public class Settings public class Settings

View File

@ -7,6 +7,7 @@ public class PlayerInventory
{ {
public ItemStack[] Hotbar { get; set; } = new ItemStack[9]; public ItemStack[] Hotbar { get; set; } = new ItemStack[9];
public ItemStack[] Inventory { get; set; } = new ItemStack[5 * 9]; public ItemStack[] Inventory { get; set; } = new ItemStack[5 * 9];
public ItemStack cursor { get; set; }
public bool PickupItemStack(ItemStack itemStack) public bool PickupItemStack(ItemStack itemStack)
{ {
@ -30,4 +31,9 @@ public class PlayerInventory
} }
return true; return true;
} }
public void SwapWithCursor(int slot, ItemStack[] inventory)
{
(inventory[slot], this.cursor) = (this.cursor, inventory[slot]);
}
} }