1+ using System ;
2+ using System . Linq ;
3+ using System . Numerics ;
4+ using FFXIVClientStructs . FFXIV . Component . GUI ;
5+ using KamiToolKit . Classes . TimelineBuilding ;
6+ using KamiToolKit . Nodes ;
7+ using KamiToolKit . Nodes . Image ;
8+
9+ namespace MiniCactpotSolver ;
10+
11+ public class GameGrid : ResNode {
12+
13+ private readonly IconImageNode [ ] buttonImages ;
14+ private readonly ImageNode [ ] laneImages ;
15+
16+ public GameGrid ( ) {
17+ var gameGridOffset = new Vector2 ( 28.0f , 44.0f ) ;
18+ var buttonsOffset = gameGridOffset + new Vector2 ( 32.0f , 32.0f ) ;
19+
20+ uint selectedIcon = Service . Config . CustomIconId ;
21+
22+ AddTimeline ( new TimelineBuilder ( )
23+ . BeginFrameSet ( 1 , 130 )
24+ . AddLabel ( 1 , 200 , AtkTimelineJumpBehavior . Start , 0 )
25+ . AddLabel ( 120 , 0 , AtkTimelineJumpBehavior . LoopForever , 200 )
26+ . AddLabel ( 121 , 201 , AtkTimelineJumpBehavior . Start , 0 )
27+ . EndFrameSet ( )
28+ . Build ( ) ) ;
29+
30+ buttonImages = new IconImageNode [ 9 ] ;
31+
32+ foreach ( var yIndex in Enumerable . Range ( 0 , 3 ) )
33+ foreach ( var xIndex in Enumerable . Range ( 0 , 3 ) ) {
34+ var imageNode = new IconImageNode {
35+ Position = new Vector2 ( 54.0f * xIndex , 54.0f * yIndex - 1.0f ) + buttonsOffset ,
36+ Size = new Vector2 ( 54.0f , 54.0f ) ,
37+ Origin = new Vector2 ( 27.0f , 27.0f ) ,
38+ Scale = new Vector2 ( 0.8f , 0.8f ) ,
39+ IsVisible = true ,
40+ IconId = selectedIcon ,
41+ Color = Service . Config . ButtonColor ,
42+ } ;
43+
44+ imageNode . AddTimeline ( new TimelineBuilder ( )
45+ . BeginFrameSet ( 1 , 120 )
46+ . AddFrame ( 1 , scale : new Vector2 ( 0.8f , 0.8f ) , rotation : 0.0f )
47+ . AddFrame ( 60 , scale : new Vector2 ( 0.7f , 0.7f ) , rotation : MathF . PI )
48+ . AddFrame ( 120 , scale : new Vector2 ( 0.8f , 0.8f ) , rotation : 2.0f * MathF . PI )
49+ . EndFrameSet ( )
50+ . BeginFrameSet ( 121 , 130 )
51+ . AddFrame ( 121 , scale : new Vector2 ( 0.8f , 0.8f ) , rotation : 0.0f )
52+ . EndFrameSet ( )
53+ . Build ( ) ) ;
54+
55+ buttonImages [ xIndex + yIndex * 3 ] = imageNode ;
56+
57+ Service . NativeController . AttachNode ( imageNode , this ) ;
58+ }
59+
60+ laneImages = new ImageNode [ 8 ] ;
61+
62+ laneImages [ 0 ] = new IconImageNode {
63+ Position = new Vector2 ( 0.0f , 40.0f ) + gameGridOffset ,
64+ Size = new Vector2 ( 34.0f , 34.0f ) ,
65+ Origin = new Vector2 ( 17.0f , 17.0f ) ,
66+ Color = Service . Config . LaneColor ,
67+ IsVisible = true ,
68+ IconId = 60934 ,
69+ } ;
70+
71+ AddLaneNodeTimeline ( laneImages [ 0 ] , MathF . PI / 2.0f ) ;
72+ Service . NativeController . AttachNode ( laneImages [ 0 ] , this ) ;
73+
74+ laneImages [ 1 ] = new IconImageNode {
75+ Position = new Vector2 ( 0.0f , 94.0f ) + gameGridOffset ,
76+ Size = new Vector2 ( 34.0f , 34.0f ) ,
77+ Origin = new Vector2 ( 17.0f , 17.0f ) ,
78+ Color = Service . Config . LaneColor ,
79+ IsVisible = true ,
80+ IconId = 60934 ,
81+ } ;
82+
83+ AddLaneNodeTimeline ( laneImages [ 1 ] , MathF . PI / 2.0f ) ;
84+ Service . NativeController . AttachNode ( laneImages [ 1 ] , this ) ;
85+
86+ laneImages [ 2 ] = new IconImageNode {
87+ Position = new Vector2 ( 0.0f , 148.0f ) + gameGridOffset ,
88+ Size = new Vector2 ( 34.0f , 34.0f ) ,
89+ Origin = new Vector2 ( 17.0f , 17.0f ) ,
90+ Color = Service . Config . LaneColor ,
91+ IsVisible = true ,
92+ IconId = 60934 ,
93+ } ;
94+
95+ AddLaneNodeTimeline ( laneImages [ 2 ] , MathF . PI / 2.0f ) ;
96+ Service . NativeController . AttachNode ( laneImages [ 2 ] , this ) ;
97+
98+ laneImages [ 3 ] = new IconImageNode {
99+ Position = new Vector2 ( 42.0f , 0.0f ) + gameGridOffset ,
100+ Size = new Vector2 ( 34.0f , 34.0f ) ,
101+ Origin = new Vector2 ( 17.0f , 17.0f ) ,
102+ Color = Service . Config . LaneColor ,
103+ IsVisible = true ,
104+ IconId = 60934 ,
105+ } ;
106+
107+ AddLaneNodeTimeline ( laneImages [ 3 ] , MathF . PI ) ;
108+ Service . NativeController . AttachNode ( laneImages [ 3 ] , this ) ;
109+
110+ laneImages [ 4 ] = new IconImageNode {
111+ Position = new Vector2 ( 96.0f , 0.0f ) + gameGridOffset ,
112+ Size = new Vector2 ( 34.0f , 34.0f ) ,
113+ Origin = new Vector2 ( 17.0f , 17.0f ) ,
114+ Color = Service . Config . LaneColor ,
115+ IsVisible = true ,
116+ IconId = 60934 ,
117+ } ;
118+
119+ AddLaneNodeTimeline ( laneImages [ 4 ] , MathF . PI ) ;
120+ Service . NativeController . AttachNode ( laneImages [ 4 ] , this ) ;
121+
122+ laneImages [ 5 ] = new IconImageNode {
123+ Position = new Vector2 ( 150.0f , 0.0f ) + gameGridOffset ,
124+ Size = new Vector2 ( 34.0f , 34.0f ) ,
125+ Origin = new Vector2 ( 17.0f , 17.0f ) ,
126+ Color = Service . Config . LaneColor ,
127+ IsVisible = true ,
128+ IconId = 60934 ,
129+ } ;
130+
131+ AddLaneNodeTimeline ( laneImages [ 5 ] , MathF . PI ) ;
132+ Service . NativeController . AttachNode ( laneImages [ 5 ] , this ) ;
133+
134+ laneImages [ 6 ] = new IconImageNode {
135+ Position = new Vector2 ( 0.0f , 0.0f ) + gameGridOffset ,
136+ Size = new Vector2 ( 34.0f , 34.0f ) ,
137+ Origin = new Vector2 ( 17.0f , 17.0f ) ,
138+ Color = Service . Config . LaneColor ,
139+ IsVisible = true ,
140+ IconId = 60934 ,
141+ } ;
142+
143+ AddLaneNodeTimeline ( laneImages [ 6 ] , MathF . PI * 3.0f / 4.0f ) ;
144+ Service . NativeController . AttachNode ( laneImages [ 6 ] , this ) ;
145+
146+ laneImages [ 7 ] = new IconImageNode {
147+ Position = new Vector2 ( 190.0f , 0.0f ) + gameGridOffset ,
148+ Size = new Vector2 ( 34.0f , 34.0f ) ,
149+ Origin = new Vector2 ( 17.0f , 17.0f ) ,
150+ Color = Service . Config . LaneColor ,
151+ IsVisible = true ,
152+ IconId = 60934 ,
153+ } ;
154+
155+ AddLaneNodeTimeline ( laneImages [ 7 ] , MathF . PI + MathF . PI / 4.0f ) ;
156+ Service . NativeController . AttachNode ( laneImages [ 7 ] , this ) ;
157+
158+ Timeline ? . StartAnimation ( Service . Config . EnableAnimations ? 200 : 201 ) ;
159+ }
160+
161+ protected override void Dispose ( bool disposing ) {
162+ if ( disposing ) {
163+ foreach ( var node in buttonImages ) {
164+ node . Dispose ( ) ;
165+ }
166+
167+ foreach ( var lane in laneImages ) {
168+ lane . Dispose ( ) ;
169+ }
170+
171+ base . Dispose ( disposing ) ;
172+ }
173+ }
174+
175+ public void SetActiveButtons ( params int [ ] ? indexes ) {
176+ #if DEBUG
177+ return ;
178+ #endif
179+
180+ foreach ( var image in buttonImages ) {
181+ image . IsVisible = false ;
182+ }
183+
184+ if ( indexes is null ) return ;
185+
186+ foreach ( var index in indexes ) {
187+ buttonImages [ index ] . IsVisible = true ;
188+ }
189+ }
190+
191+ public void SetActiveLanes ( params int [ ] ? indexes ) {
192+ #if DEBUG
193+ return ;
194+ #endif
195+
196+ foreach ( var lane in laneImages ) {
197+ lane . IsVisible = false ;
198+ }
199+
200+ if ( indexes is null ) return ;
201+
202+ foreach ( var index in indexes ) {
203+ laneImages [ index ] . IsVisible = true ;
204+ }
205+ }
206+
207+ private void AddLaneNodeTimeline ( ImageNode imageNode , float rotation ) {
208+ imageNode . AddTimeline ( new TimelineBuilder ( )
209+ . BeginFrameSet ( 1 , 120 )
210+ . AddFrame ( 1 , scale : new Vector2 ( 1.4f , 1.4f ) , rotation : rotation )
211+ . AddFrame ( 60 , scale : new Vector2 ( 1.0f , 1.0f ) , rotation : rotation )
212+ . AddFrame ( 120 , scale : new Vector2 ( 1.4f , 1.4f ) , rotation : rotation )
213+ . EndFrameSet ( )
214+ . BeginFrameSet ( 121 , 130 )
215+ . AddFrame ( 121 , scale : new Vector2 ( 1.0f , 1.0f ) , rotation : rotation )
216+ . EndFrameSet ( )
217+ . Build ( ) ) ;
218+ }
219+
220+ public void UpdateIcons ( uint icon ) {
221+ foreach ( var image in buttonImages ) {
222+ image . IconId = icon ;
223+ }
224+ }
225+
226+ public void UpdateButtonColors ( Vector4 color ) {
227+ foreach ( var image in buttonImages ) {
228+ image . Color = color ;
229+ }
230+ }
231+
232+ public void UpdateLaneColors ( Vector4 color ) {
233+ foreach ( var image in laneImages ) {
234+ image . Color = color ;
235+ }
236+ }
237+ }
0 commit comments