Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
8af7814
fix: possible null reference
AcipenserSturio Dec 8, 2024
be81a7d
feat: support text for neutral zzclass
AcipenserSturio Dec 10, 2024
1631e7f
refactor: book menu
AcipenserSturio Dec 10, 2024
71119a7
fix: improve handling of menu-tab switching
AcipenserSturio Dec 10, 2024
278ad8e
feat: deck pixie text & minor fixes
AcipenserSturio Dec 10, 2024
642592b
feat: deck stats on card hover
AcipenserSturio Dec 11, 2024
930961c
fix: deck list mode switch button position
AcipenserSturio Dec 11, 2024
7692985
fix: stats for blank buttons
AcipenserSturio Dec 12, 2024
0089601
feat: card tooltips
AcipenserSturio Dec 12, 2024
ee19acf
feat: card dragging
AcipenserSturio Dec 12, 2024
e541342
refactor: drag card
AcipenserSturio Dec 12, 2024
e32c251
refactor: deck: clean up Update
AcipenserSturio Dec 15, 2024
77bf2b8
refactor: ScrDeck by child entity
AcipenserSturio Dec 16, 2024
9ad4232
refactor: rename card entities to slots
AcipenserSturio Dec 16, 2024
60805ea
fix: create spell slots
AcipenserSturio Dec 16, 2024
0c848b6
fix: give all buttons a size
AcipenserSturio Dec 16, 2024
3b566ff
fix: button and summary offsets
AcipenserSturio Dec 16, 2024
c413ded
fix: tab and pixie offset
AcipenserSturio Dec 16, 2024
59f6fc9
fix: summary
AcipenserSturio Dec 17, 2024
efffe13
fix: basic dragging
AcipenserSturio Dec 17, 2024
a2e7771
fix: restrict dragging on slot type
AcipenserSturio Dec 17, 2024
ec3d206
fix: assign indices to slots
AcipenserSturio Dec 17, 2024
34746dd
feat: add drop
AcipenserSturio Dec 17, 2024
cfd1707
fix: deck slot control flow
AcipenserSturio Dec 17, 2024
daa33ab
feat: apply dragged card to slot
AcipenserSturio Dec 17, 2024
3788c09
refactor: move click handlers to each slot
AcipenserSturio Dec 17, 2024
5c54f13
feat: add mousewheel decklist scrolling
AcipenserSturio Dec 17, 2024
92167ba
fix: temporarily undo the grid mode slider bug
AcipenserSturio Dec 17, 2024
1446e99
feat: drag and drop deck slots
AcipenserSturio Dec 18, 2024
152feb0
fix: update list slot markers when swapping
AcipenserSturio Dec 18, 2024
8356810
refactor: deck slots
AcipenserSturio Dec 18, 2024
0992450
fix: spell slot unsetting
AcipenserSturio Dec 18, 2024
0377709
fix: reduce visual updates on drop card
AcipenserSturio Dec 18, 2024
9751899
feat: spell assignment
AcipenserSturio Dec 18, 2024
963fb55
feat: throw notif on incompatible spell slots
AcipenserSturio Dec 18, 2024
5ef3fc7
feat: check spell for skills compatibility
AcipenserSturio Dec 18, 2024
b636307
fix: code style
AcipenserSturio Dec 18, 2024
b3e133e
feat: dummy uiscript
AcipenserSturio Dec 19, 2024
8652f3a
feat: implement IfIsWizform
AcipenserSturio Dec 19, 2024
c7bca66
feat: implement ModifyWizform
AcipenserSturio Dec 19, 2024
590a74f
feat: add interaction sounds
AcipenserSturio Dec 23, 2024
ee172d2
fix: golden carrots make a chime
AcipenserSturio Dec 23, 2024
ba72a2f
fix: max mana spell summary is hyphen
AcipenserSturio Dec 23, 2024
97f5181
fix: golden carrot behaviour
AcipenserSturio Dec 23, 2024
5840ecb
fix: avoid overlapping notifications
AcipenserSturio Dec 23, 2024
add494e
fix: fairy count summary positioning
AcipenserSturio Dec 23, 2024
3ffa23b
fix: deck system disposal
AcipenserSturio Dec 23, 2024
ecafdd8
refactor: create list slot
AcipenserSturio Dec 23, 2024
26c31a6
refactor: remove buttonId from component
AcipenserSturio Dec 23, 2024
9843e93
feat: fairy spells on list slot hover
AcipenserSturio Dec 24, 2024
37f7aed
refactor: slot summary setting
AcipenserSturio Dec 24, 2024
e508033
feat: only allow fairy changes in london
AcipenserSturio Dec 24, 2024
ef28f0e
fix: correct deck slot tooltips
AcipenserSturio Dec 24, 2024
e6c2e8f
feat: spell slot tooltips
AcipenserSturio Dec 24, 2024
ee8100b
fix: accessing dead top buttons
AcipenserSturio Dec 24, 2024
48e9bac
fix: remove unused UIDs
AcipenserSturio Dec 24, 2024
5ccd023
feat: update drag overlay tile
AcipenserSturio Dec 24, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions zzio/InventoryCard.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace zzio;

Expand Down Expand Up @@ -155,6 +156,26 @@ public IEnumerator<ZZClass> GetEnumerator()
if (class2 != ZZClass.None) yield return class2;
}
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();

public bool IsCompatible(zzio.db.SpellRow spell)
{
var zzclasses = Enum.GetValues<ZZClass>().Where(s => s != ZZClass.None);
List<ZZClass> skills = [class0, class1, class2];
List<ZZClass> reqs = [spell.PriceA, spell.PriceB, spell.PriceC];

var neutralsNeeded = 0;
foreach (var zzclass in zzclasses)
{
var skillHad = skills.Where(s => s == zzclass).Count();
var skillNeeded = reqs.Where(s => s == zzclass).Count();
var skillDeficit = skillNeeded - skillHad;
if (skillDeficit > 0)
neutralsNeeded += skillDeficit;
}
if (skills.Where(s => s == ZZClass.Neutral).Count() - neutralsNeeded < 0)
return false;
return true;
}
}

public enum ZZPermSpellStatus
Expand Down
4 changes: 2 additions & 2 deletions zzre.core/math/WorldCollider.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System.IO;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using zzio.rwbs;
Expand Down Expand Up @@ -94,7 +94,7 @@ public static WorldCollider Create(RWWorld world)
sectorType = RWPlaneSectionType.XPlane,
leftValue = float.PositiveInfinity,
rightValue = float.PositiveInfinity,
children = [rootAtomic, new RWString()]
children = [rootAtomic!, new RWString()]
};

var splits = new CollisionSplit[splitCount];
Expand Down
1 change: 1 addition & 0 deletions zzre/game/Game.cs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ protected void LoadScene(string sceneName)
clearColor = (scene.misc.clearColor.ToFColor() with { a = 1f }).ToVeldrid();

ecsWorld.Publish(new messages.SceneLoaded(scene, GetTag<Savegame>()));
ui.World.Publish(new messages.SceneLoaded(scene, GetTag<Savegame>()));
}

private void DisposeUnusedAssets(in messages.SceneLoaded _)
Expand Down
1 change: 1 addition & 0 deletions zzre/game/UI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ public UI(ITagContainer diContainer)
new systems.ui.Tooltip(this),
new systems.ui.CorrectRenderOrder(this),
new systems.ui.Fade(this),
new systems.ui.UIScript(this),

new systems.Reaper(this),
new systems.ParentReaper(this));
Expand Down
1 change: 1 addition & 0 deletions zzre/game/Zanzarah.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public interface IZanzarahContainer
event Action<MouseButton, Vector2> OnMouseDown;
event Action<MouseButton, Vector2> OnMouseUp;
event Action<Vector2> OnMouseMove;
event Action<float> OnScroll;
}

public class Zanzarah : ITagContainer
Expand Down
5 changes: 5 additions & 0 deletions zzre/game/components/ui/DraggedCard.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
using zzio;

namespace zzre.game.components.ui;

public record struct DraggedCard(InventoryCard card);
3 changes: 0 additions & 3 deletions zzre/game/components/ui/ScrBookMenu.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
using System.Collections.Generic;
using zzio.db;

namespace zzre.game.components.ui;

public struct ScrBookMenu
{
public Inventory Inventory;
public FairyRow[] Fairies;
public Dictionary<components.ui.ElementId, FairyRow> FairyButtons;
public DefaultEcs.Entity Sidebar;
public DefaultEcs.Entity Crosshair;
}
27 changes: 19 additions & 8 deletions zzre/game/components/ui/ScrDeck.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
namespace zzre.game.components.ui;
using zzio;

namespace zzre.game.components.ui;

public struct ScrDeck
{
Expand All @@ -14,14 +16,23 @@ public enum Tab
public Tab ActiveTab;
public bool IsGridMode;
public int Scroll;
public Inventory Inventory;
public DefaultEcs.Entity SummaryBackground;
public DefaultEcs.Entity SpellBackground;

public DefaultEcs.Entity[] TabButtons;
public DefaultEcs.Entity ListSlider;
public DefaultEcs.Entity FairyHoverSummary;
public DefaultEcs.Entity[] ListTabs;
public DefaultEcs.Entity[] ListButtons;
public DefaultEcs.Entity[] ListUsedMarkers;
public DefaultEcs.Entity[] ListSummaries;
public DefaultEcs.Entity[] DeckSlotParents;

public DefaultEcs.Entity[] DeckSlots;
public DefaultEcs.Entity[] ListSlots;

public DefaultEcs.Entity LastHovered;
public DefaultEcs.Entity StatsTitle;
public DefaultEcs.Entity StatsDescriptions;
public DefaultEcs.Entity StatsLights;
public DefaultEcs.Entity StatsLevel;

public int VacatedDeckSlot;
public InventoryCard? DraggedCard;
public DefaultEcs.Entity DraggedCardImage;
public DefaultEcs.Entity DraggedOverlay;
}
18 changes: 18 additions & 0 deletions zzre/game/components/ui/Slot.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using zzio;

namespace zzre.game.components.ui;

public record struct Slot
{
public enum Type { None, DeckSlot, ListSlot, SpellSlot }
public Type type;
public int index;
public InventoryCard? card;
public DefaultEcs.Entity button;
public DefaultEcs.Entity usedMarker; // ListSlot only
public DefaultEcs.Entity[] spellImages; // ListSlot only
public bool showSpells; // ListSlot only
public DefaultEcs.Entity summary;
public DefaultEcs.Entity req; // SpellSlot only
public DefaultEcs.Entity[] spellSlots; // DeckSlot only
};
3 changes: 3 additions & 0 deletions zzre/game/components/ui/SlotButton.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
namespace zzre.game.components.ui;

public record struct SlotButton;
6 changes: 6 additions & 0 deletions zzre/game/components/ui/UIScript.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace zzre.game.components.ui;

public record struct UIScript(
DefaultEcs.Entity DeckSlotEntity,
bool ItemConsumed
);
6 changes: 6 additions & 0 deletions zzre/game/messages/ui/ExecuteUIScript.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace zzre.game.messages.ui;

public readonly record struct ExecuteUIScript(
zzio.InventoryItem Item,
DefaultEcs.Entity DeckSlotEntity
);
6 changes: 6 additions & 0 deletions zzre/game/messages/ui/UIScriptFinished.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace zzre.game.messages.ui;

public readonly record struct UIScriptFinished(
DefaultEcs.Entity DeckSlotEntity,
bool ItemConsumed
);
25 changes: 20 additions & 5 deletions zzre/game/systems/player/OpenMenuKeys.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@ public class OpenMenuKeys : ISystem<float>
private readonly IZanzarahContainer zzContainer;
private readonly PlayerControls playerControls;
private readonly UI ui;
private readonly Zanzarah zanzarah;

public OpenMenuKeys(ITagContainer diContainer)
{
ui = diContainer.GetTag<UI>();
zanzarah = diContainer.GetTag<Zanzarah>();
playerControls = diContainer.GetTag<PlayerControls>();
zzContainer = diContainer.GetTag<IZanzarahContainer>();
zzContainer.OnKeyDown += HandleKeyDown;
Expand All @@ -34,15 +36,28 @@ public void Dispose()

private void HandleKeyDown(KeyCode code)
{
var inventory = zanzarah.CurrentGame!.PlayerEntity.Get<Inventory>();
if (!IsEnabled || playerControls.IsLocked)
return;
switch (code)
{
case MenuKey: ui.Publish<messages.ui.OpenDeck>(); break;
case RuneMenuKey: ui.Publish<messages.ui.OpenRuneMenu>(); break;
case BookMenuKey: ui.Publish<messages.ui.OpenBookMenu>(); break;
case MapMenuKey: ui.Publish<messages.ui.OpenMapMenu>(); break;
case DeckMenuKey: ui.Publish<messages.ui.OpenDeck>(); break;
case RuneMenuKey:
if (inventory.Contains(StdItemId.RuneFairyGarden))
ui.Publish<messages.ui.OpenRuneMenu>();
break;
case BookMenuKey:
if (inventory.Contains(StdItemId.FairyBook))
ui.Publish<messages.ui.OpenBookMenu>();
break;
case MapMenuKey:
if (inventory.Contains(StdItemId.MapFairyGarden))
ui.Publish<messages.ui.OpenMapMenu>();
break;
case MenuKey:
case DeckMenuKey:
if (inventory.Contains(StdItemId.FairyBag))
ui.Publish<messages.ui.OpenDeck>();
break;
}
}

Expand Down
16 changes: 14 additions & 2 deletions zzre/game/systems/ui/BaseScreen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,15 @@ protected enum BlockFlags
private readonly IDisposable removedSubscription;
protected readonly IZanzarahContainer zzContainer;
protected readonly Zanzarah zanzarah;
protected Inventory inventory => zanzarah.CurrentGame!.PlayerEntity.Get<Inventory>();
protected readonly UI ui;
protected readonly DefaultEcs.World uiWorld;// necessary as Dialog UI is owned by the game and not by the UI.
// Probably worth some cleanup but this would mean merging
// Game and UI world which I did not decided to be a good idea
protected readonly UIBuilder preload;
protected event Action<DefaultEcs.Entity, components.ui.ElementId>? OnElementDown;
protected event Action<DefaultEcs.Entity, components.ui.ElementId>? OnElementUp;
protected event Action? OnRightClick;

protected Vector2 ScreenCenter => ui.LogicalScreen.Center;

Expand Down Expand Up @@ -62,6 +64,7 @@ protected virtual void HandleAdded(in DefaultEcs.Entity entity, in TComponent _)
zzContainer.OnMouseDown += HandleMouseDown;
zzContainer.OnMouseUp += HandleMouseUp;
zzContainer.OnKeyDown += HandleKeyDown;
zzContainer.OnScroll += HandleScroll;

if (zanzarah.CurrentGame != null && blockFlags.HasFlag(BlockFlags.DisableGameUpdate))
zanzarah.CurrentGame.IsUpdateEnabled = false;
Expand All @@ -76,6 +79,7 @@ protected virtual void HandleRemoved(in DefaultEcs.Entity entity, in TComponent
zzContainer.OnMouseDown -= HandleMouseDown;
zzContainer.OnMouseUp -= HandleMouseUp;
zzContainer.OnKeyDown -= HandleKeyDown;
zzContainer.OnScroll -= HandleScroll;

if (zanzarah.CurrentGame != null && blockFlags.HasFlag(BlockFlags.DisableGameUpdate))
zanzarah.CurrentGame.IsUpdateEnabled = true;
Expand All @@ -89,6 +93,12 @@ protected virtual void HandleRemoved(in DefaultEcs.Entity entity, in TComponent
private void HandleMouseUp(MouseButton button, Vector2 pos) => HandleMouse(button, pos, isDown: false);
private void HandleMouse(MouseButton button, Vector2 pos, bool isDown)
{
if (button == MouseButton.Right)
{
if (isDown)
OnRightClick?.Invoke();
return;
}
if (button != MouseButton.Left)
return;

Expand All @@ -105,10 +115,12 @@ private void HandleMouse(MouseButton button, Vector2 pos, bool isDown)
protected virtual void HandleKeyDown(KeyCode key)
{
}

protected virtual void HandleScroll(float scrollAmount)
{
}
protected abstract void HandleOpen(in TMessage message);

[Update]
protected virtual void Update(float timeElapsed, in DefaultEcs.Entity entity, ref TComponent component) { }

}
}
75 changes: 67 additions & 8 deletions zzre/game/systems/ui/InGameScreen.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
using System.Numerics;
using System.Collections.Generic;
using System.Numerics;
using System.Linq;
using zzio;
using KeyCode = Silk.NET.SDL.KeyCode;

namespace zzre.game.systems.ui;

Expand All @@ -14,13 +17,13 @@ public static class InGameScreen
public static readonly components.ui.ElementId IDOpenMap = new(1004);
public static readonly components.ui.ElementId IDSaveGame = new(1005);

private record struct TabInfo(components.ui.ElementId Id, int PosX, int TileI, UID TooltipUID, StdItemId Item);
private static readonly TabInfo[] Tabs =
private record struct TabInfo(components.ui.ElementId Id, int PosX, int TileI, UID TooltipUID, KeyCode Key, StdItemId Item);
private static readonly List<TabInfo> Tabs =
[
new(IDOpenDeck, PosX: 553, TileI: 21, TooltipUID: new(0x6659B4A1), StdItemId.FairyBag),
new(IDOpenRunes, PosX: 427, TileI: 12, TooltipUID: new(0x6636B4A1), StdItemId.RuneFairyGarden),
new(IDOpenFairybook, PosX: 469, TileI: 15, TooltipUID: new(0x8D1BBCA1), StdItemId.FairyBook),
new(IDOpenMap, PosX: 511, TileI: 18, TooltipUID: new(0xC51E6991), StdItemId.MapFairyGarden)
new(IDOpenDeck, PosX: 553, TileI: 21, TooltipUID: new(0x6659B4A1), KeyCode.KF5, StdItemId.FairyBag),
new(IDOpenRunes, PosX: 427, TileI: 12, TooltipUID: new(0x6636B4A1), KeyCode.KF2, StdItemId.RuneFairyGarden),
new(IDOpenFairybook, PosX: 469, TileI: 15, TooltipUID: new(0x8D1BBCA1), KeyCode.KF3, StdItemId.FairyBook),
new(IDOpenMap, PosX: 511, TileI: 18, TooltipUID: new(0xC51E6991), KeyCode.KF4, StdItemId.MapFairyGarden)
];

public static void CreateTopButtons(UIBuilder preload, in DefaultEcs.Entity parent, Inventory inventory, components.ui.ElementId curTab)
Expand All @@ -35,7 +38,7 @@ public static void CreateTopButtons(UIBuilder preload, in DefaultEcs.Entity pare

preload.CreateButton(parent)
.With(IDSaveGame)
.With(Mid + new Vector2(384, 3))
.With(Mid + new Vector2(385, 3))
.With(new components.ui.ButtonTiles(26, 27))
.With(UIPreloadAsset.Btn002)
.WithTooltip(0x7113B8A1)
Expand All @@ -60,4 +63,60 @@ public static void CreateTopButtons(UIBuilder preload, in DefaultEcs.Entity pare
}
}
}

public static void HandleNavClick(components.ui.ElementId id, Zanzarah zanzarah, DefaultEcs.Entity uiEntity, components.ui.ElementId curTab)
{
var tab = Tabs.FirstOrDefault(tab => tab.Id == id);
if (tab.Id == curTab)
{
// Ignore current tab
return;
}
if (tab != default)
TryOpenTab(tab, zanzarah, uiEntity, curTab);
if (id == IDClose)
uiEntity.Dispose();
}

public static void HandleNavKeyDown(KeyCode key, Zanzarah zanzarah, DefaultEcs.Entity uiEntity, components.ui.ElementId curTab)
{
var tab = Tabs.FirstOrDefault(tab => tab.Key == key);
if (tab.Id == curTab)
{
// Exit current tab
uiEntity.Dispose();
return;
}
if (tab != default)
TryOpenTab(tab, zanzarah, uiEntity, curTab);
if (key == KeyCode.KReturn || key == KeyCode.KEscape)
uiEntity.Dispose();
}

private static void TryOpenTab(TabInfo tab, Zanzarah zanzarah, DefaultEcs.Entity uiEntity, components.ui.ElementId curTab)
{
var inventory = zanzarah.CurrentGame!.PlayerEntity.Get<Inventory>();
if (!inventory.Contains(tab.Item)) return;
switch (tab.Key)
{
case KeyCode.KF2:
uiEntity.Dispose();
zanzarah.UI.Publish<messages.ui.OpenRuneMenu>();
break;
case KeyCode.KF3:
uiEntity.Dispose();
zanzarah.UI.Publish<messages.ui.OpenBookMenu>();
break;
case KeyCode.KF4:
uiEntity.Dispose();
zanzarah.UI.Publish<messages.ui.OpenMapMenu>();
break;
case KeyCode.KF5:
uiEntity.Dispose();
zanzarah.UI.Publish<messages.ui.OpenDeck>();
break;
default:
break;
}
}
}
Loading