Initial commit: AetherBags + KamiToolKit for FC Gitea
Debug Build and Test / Build against Latest Dalamud (push) Has been cancelled
Debug Build and Test / Build against Staging Dalamud (push) Has been cancelled

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-02-08 14:46:31 -05:00
commit 8db4ce6094
375 changed files with 34124 additions and 0 deletions
+216
View File
@@ -0,0 +1,216 @@
using System.Linq;
using System.Numerics;
using FFXIVClientStructs.FFXIV.Component.GUI;
using KamiToolKit.Classes;
using KamiToolKit.Enums;
using KamiToolKit.Timelines;
namespace KamiToolKit.Nodes;
public unsafe class IconExtras : ResNode {
public readonly AlternateCooldownNode AlternateCooldownNode;
public readonly AntsNode AntsNode;
public readonly ImageNode ChargeCountImageNode;
public readonly ImageNode ClickFlashImageNode;
public readonly CooldownNode CooldownNode;
public readonly ImageNode HoveredBorderImageNode;
public readonly TextNode QuantityTextNode;
public readonly TextNode ResourceCostTextNode;
public readonly ImageNode TimelineImageNode;
public IconExtras() {
TimelineImageNode = new SimpleImageNode {
NodeId = 19,
Size = new Vector2(40.0f, 40.0f),
Position = new Vector2(4.0f, 4.0f),
NodeFlags = NodeFlags.Enabled | NodeFlags.EmitsEvents,
WrapMode = WrapMode.Tile,
ImageNodeFlags = ImageNodeFlags.AutoFit,
};
TimelineImageNode.AttachNode(this);
CooldownNode = new CooldownNode {
NodeId = 16,
Size = new Vector2(48.0f, 48.0f),
NodeFlags = NodeFlags.Enabled | NodeFlags.EmitsEvents,
};
CooldownNode.AttachNode(this);
AlternateCooldownNode = new AlternateCooldownNode {
NodeId = 14,
Size = new Vector2(44.0f, 48.0f),
Position = new Vector2(2.0f, 0.0f),
NodeFlags = NodeFlags.Enabled | NodeFlags.EmitsEvents,
};
AlternateCooldownNode.AttachNode(this);
AntsNode = new AntsNode {
NodeId = 12,
Size = new Vector2(48.0f, 48.0f),
NodeFlags = NodeFlags.Enabled | NodeFlags.EmitsEvents,
};
AntsNode.AttachNode(this);
HoveredBorderImageNode = new ImageNode {
NodeId = 11,
Size = new Vector2(72.0f, 72.0f),
Position = new Vector2(-12.0f, -12.0f),
NodeFlags = NodeFlags.Visible | NodeFlags.Enabled | NodeFlags.EmitsEvents,
PartId = 16,
WrapMode = WrapMode.Tile,
};
IconNodeTextureHelper.LoadIconAFrameTexture(HoveredBorderImageNode);
HoveredBorderImageNode.AttachNode(this);
ChargeCountImageNode = new ImageNode {
NodeId = 10,
Size = new Vector2(20.0f, 20.0f),
Position = new Vector2(28.0f, 28.0f),
NodeFlags = NodeFlags.Enabled | NodeFlags.EmitsEvents,
WrapMode = WrapMode.Tile,
};
foreach (var yIndex in Enumerable.Range(0, 2))
foreach (var xIndex in Enumerable.Range(0, 5)) {
var coordinate = new Vector2(xIndex * 20.0f, yIndex * 20.0f);
ChargeCountImageNode.AddPart(new Part {
TexturePath = "ui/uld/IconA_ChargeIcon.tex",
TextureCoordinates = coordinate,
Size = new Vector2(20.0f, 20.0f),
Id = (uint)(xIndex + yIndex),
});
}
ChargeCountImageNode.AttachNode(this);
QuantityTextNode = new TextNode {
NodeId = 9,
Size = new Vector2(40.0f, 12.0f),
Position = new Vector2(4.0f, 34.0f),
NodeFlags = NodeFlags.Enabled | NodeFlags.EmitsEvents,
Color = ColorHelper.GetColor(50),
TextOutlineColor = ColorHelper.GetColor(51),
AlignmentType = AlignmentType.Right,
};
QuantityTextNode.AttachNode(this);
// Also cooldown time text for non-globals
ResourceCostTextNode = new TextNode {
NodeId = 8,
Size = new Vector2(48.0f, 12.0f),
Position = new Vector2(3.0f, 37.0f),
NodeFlags = NodeFlags.Enabled | NodeFlags.EmitsEvents,
Color = ColorHelper.GetColor(50),
TextOutlineColor = ColorHelper.GetColor(51),
AlignmentType = AlignmentType.Left,
};
ResourceCostTextNode.AttachNode(this);
ClickFlashImageNode = new ImageNode {
NodeId = 7,
Size = new Vector2(64, 64),
Position = new Vector2(-8.0f, -8.0f),
Origin = new Vector2(32.0f, 32.0f),
NodeFlags = NodeFlags.Enabled | NodeFlags.EmitsEvents,
WrapMode = WrapMode.Tile,
PartId = 17,
};
IconNodeTextureHelper.LoadIconAFrameTexture(ClickFlashImageNode);
ClickFlashImageNode.AttachNode(this);
BuildTimelines();
}
private void BuildTimelines() {
TimelineImageNode.AddTimeline(new TimelineBuilder()
.BeginFrameSet(10, 19)
.AddFrame(10, alpha: 0, multiplyColor: new Vector3(100.0f), addColor: new Vector3(255.0f))
.AddFrame(12, alpha: 63, multiplyColor: new Vector3(100.0f), addColor: new Vector3(255.0f))
.EndFrameSet()
.BeginFrameSet(20, 29)
.AddFrame(20, alpha: 63, multiplyColor: new Vector3(100.0f), addColor: new Vector3(255.0f))
.EndFrameSet()
.BeginFrameSet(40, 49)
.AddFrame(40, alpha: 63, multiplyColor: new Vector3(100.0f), addColor: new Vector3(255.0f))
.EndFrameSet()
.BeginFrameSet(50, 59)
.AddFrame(50, alpha: 63, multiplyColor: new Vector3(100.0f), addColor: new Vector3(255.0f))
.AddFrame(52, alpha: 0, multiplyColor: new Vector3(100.0f), addColor: new Vector3(255.0f))
.EndFrameSet()
.Build());
CooldownNode.AddTimeline(new TimelineBuilder()
.BeginFrameSet(1, 165)
.AddLabel(1, 19, AtkTimelineJumpBehavior.PlayOnce, 0)
.AddLabel(11, 20, AtkTimelineJumpBehavior.PlayOnce, 0)
.AddLabel(21, 21, AtkTimelineJumpBehavior.PlayOnce, 0)
.AddLabel(31, 22, AtkTimelineJumpBehavior.PlayOnce, 0)
.AddLabel(41, 101, AtkTimelineJumpBehavior.PlayOnce, 0)
.AddLabel(51, 102, AtkTimelineJumpBehavior.PlayOnce, 0)
.AddLabelPair(61, 142, 24)
.AddLabelPair(143, 165, 25)
.EndFrameSet()
.AddFrameSetWithFrame(1, 9, 1, multiplyColor: new Vector3(100.0f), addColor: new Vector3(0.0f))
.BeginFrameSet(10, 19)
.AddFrame(10, multiplyColor: new Vector3(100.0f), addColor: new Vector3(0.0f))
.AddFrame(12, multiplyColor: new Vector3(100.0f), addColor: new Vector3(16.0f))
.EndFrameSet()
.AddFrameSetWithFrame(20, 29, 20, multiplyColor: new Vector3(100.0f), addColor: new Vector3(16.0f))
.AddFrameSetWithFrame(30, 39, 30, multiplyColor: new Vector3(100.0f), addColor: new Vector3(0.0f))
.AddFrameSetWithFrame(40, 49, 40, multiplyColor: new Vector3(100.0f), addColor: new Vector3(16.0f))
.BeginFrameSet(50, 59)
.AddFrame(50, multiplyColor: new Vector3(100.0f), addColor: new Vector3(16.0f))
.AddFrame(52, multiplyColor: new Vector3(100.0f), addColor: new Vector3(0.0f))
.EndFrameSet()
.Build());
AlternateCooldownNode.AddTimeline(new TimelineBuilder()
.BeginFrameSet(1, 205)
.AddLabel(1, 17, AtkTimelineJumpBehavior.PlayOnce, 0)
.AddLabel(11, 101, AtkTimelineJumpBehavior.Start, 0)
.AddLabel(92, 0, AtkTimelineJumpBehavior.PlayOnce, 0)
.AddLabel(93, 102, AtkTimelineJumpBehavior.Start, 0)
.AddLabel(174, 0, AtkTimelineJumpBehavior.PlayOnce, 0)
.AddLabel(175, 103, AtkTimelineJumpBehavior.Start, 0)
.AddLabel(205, 0, AtkTimelineJumpBehavior.LoopForever, 103)
.EndFrameSet()
.Build());
AntsNode.AddTimeline(new TimelineBuilder()
.BeginFrameSet(1, 9)
.AddLabel(1, 0, AtkTimelineJumpBehavior.PlayOnce, 0)
.AddLabel(2, 26, AtkTimelineJumpBehavior.Start, 0)
.AddLabel(9, 0, AtkTimelineJumpBehavior.LoopForever, 26)
.EndFrameSet()
.Build());
HoveredBorderImageNode.AddTimeline(new TimelineBuilder()
.BeginFrameSet(10, 19)
.AddFrame(10, alpha: 0, multiplyColor: new Vector3(100.0f), addColor: new Vector3(0.0f))
.AddFrame(12, alpha: 255, multiplyColor: new Vector3(100.0f), addColor: new Vector3(0.0f))
.EndFrameSet()
.BeginFrameSet(20, 29)
.AddFrame(20, alpha: 255, multiplyColor: new Vector3(100.0f), addColor: new Vector3(0.0f))
.EndFrameSet()
.BeginFrameSet(40, 49)
.AddFrame(40, alpha: 255, multiplyColor: new Vector3(100.0f), addColor: new Vector3(0.0f))
.EndFrameSet()
.BeginFrameSet(50, 59)
.AddFrame(50, alpha: 255, multiplyColor: new Vector3(100.0f), addColor: new Vector3(0.0f))
.AddFrame(52, alpha: 0, multiplyColor: new Vector3(100.0f), addColor: new Vector3(0.0f))
.EndFrameSet()
.Build());
ClickFlashImageNode.AddTimeline(new TimelineBuilder()
.BeginFrameSet(20, 29)
.AddFrame(20, alpha: 255, scale: new Vector2(0.1f))
.AddFrame(29, alpha: 0, scale: new Vector2(1.0f))
.EndFrameSet()
.Build());
}
}