2121using ImGuiNET ;
2222using Dalamud . Game . ClientState . Statuses ;
2323using FFXIVClientStructs . FFXIV . Client . Game ;
24+ using Lumina . Excel . GeneratedSheets ;
25+ using static MOAction . MOActionAddressResolver ;
2426
2527namespace MOAction
2628{
@@ -49,6 +51,9 @@ public delegate bool OnRequestActionDetour(long param_1, uint param_2, ulong par
4951 private Hook < OnRequestActionDetour > requestActionHook ;
5052 private Hook < OnSetUiMouseoverEntityId > uiMoEntityIdHook ;
5153
54+ public unsafe delegate RecastTimer * GetGroupTimerDelegate ( void * @this , int cooldownGroup ) ;
55+ private readonly GetGroupTimerDelegate getGroupTimer ;
56+
5257 public List < MoActionStack > Stacks { get ; set ; }
5358 private DalamudPluginInterface pluginInterface ;
5459 private IEnumerable < Lumina . Excel . GeneratedSheets . Action > RawActions ;
@@ -67,7 +72,9 @@ public delegate bool OnRequestActionDetour(long param_1, uint param_2, ulong par
6772 public bool IsGuiMOEnabled = false ;
6873 public bool IsFieldMOEnabled = false ;
6974
70- private IntPtr thing ;
75+ private IntPtr AnimLock ;
76+
77+ private bool IsLocked => Marshal . ReadInt32 ( AnimLock ) != 0 ;
7178
7279 public DataManager dataManager ;
7380 public TargetManager targetManager ;
@@ -86,6 +93,8 @@ public MOAction(SigScanner scanner, ClientState clientstate,
8693 {
8794 clientstate . Login += LoadClientModules ;
8895 clientstate . Logout += ClearClientModules ;
96+ if ( clientstate . IsLoggedIn )
97+ LoadClientModules ( null , null ) ;
8998
9099 fieldMOLocation = scanner . GetStaticAddressFromSig ( "E8 ?? ?? ?? ?? 83 BF ?? ?? ?? ?? ?? 0F 84 ?? ?? ?? ?? 48 8D 4C 24 ??" , 0x283 ) ;
91100 focusTargLocation = scanner . GetStaticAddressFromSig ( "48 8B 0D ?? ?? ?? ?? 48 89 5C 24 ?? BB ?? ?? ?? ?? 48 89 7C 24 ??" , 0 ) ;
@@ -108,7 +117,8 @@ public MOAction(SigScanner scanner, ClientState clientstate,
108117
109118 RALDelegate = Marshal . GetDelegateForFunctionPointer < RequestActionLocationDelegate > ( Address . RequestActionLocation ) ;
110119 PostRequestResolver = Marshal . GetDelegateForFunctionPointer < PostRequest > ( Address . PostRequest ) ;
111- thing = scanner . Module . BaseAddress + 0x1d8e490 ;
120+ getGroupTimer = Marshal . GetDelegateForFunctionPointer < GetGroupTimerDelegate > ( Address . GetGroupTimer ) ;
121+ //thing = scanner.Module.BaseAddress + 0x1d8e490;
112122
113123 Stacks = new ( ) ;
114124
@@ -120,6 +130,7 @@ public MOAction(SigScanner scanner, ClientState clientstate,
120130 requestActionHook = new Hook < OnRequestActionDetour > ( Address . RequestAction , new OnRequestActionDetour ( HandleRequestAction ) ) ;
121131 uiMoEntityIdHook = new Hook < OnSetUiMouseoverEntityId > ( Address . SetUiMouseoverEntityId , new OnSetUiMouseoverEntityId ( HandleUiMoEntityId ) ) ;
122132 PlaceholderResolver = Marshal . GetDelegateForFunctionPointer < ResolvePlaceholderActor > ( Address . ResolvePlaceholderText ) ;
133+ AnimLock = Address . AnimLock ;
123134 //MagicUiObject = IntPtr.Zero;
124135
125136 enabledActions = new ( ) ;
@@ -163,6 +174,11 @@ public void Dispose()
163174 //reqlochook.Dispose();
164175 }
165176
177+ public unsafe RecastTimer * GetGroupRecastTimer ( int group )
178+ {
179+ return group < 1 ? null : getGroupTimer ( AM , group - 1 ) ;
180+ }
181+
166182 private void HandleUiMoEntityId ( long param1 , long param2 )
167183 {
168184 //Log.Information("UI MO: {0}", param2);
@@ -176,25 +192,36 @@ private bool ReqLocDetour(IntPtr actionMgr, uint type, uint id, uint targetId, r
176192 return reqlochook . Original ( actionMgr , type , id , targetId , ref location , zero ) ;
177193 }
178194
179- private bool HandleRequestAction ( long param_1 , uint param_2 , ulong param_3 , long param_4 ,
195+ private unsafe bool HandleRequestAction ( long param_1 , uint actionType , ulong actionID , long param_4 ,
180196 uint param_5 , uint param_6 , int param_7 )
181197 {
182- var ( action , target ) = GetActionTarget ( ( uint ) param_3 , param_2 ) ;
198+ if ( actionType != 1 ) return requestActionHook . Original ( param_1 , actionType , actionID , param_4 , param_5 , param_6 , param_7 ) ;
199+ var ( action , target ) = GetActionTarget ( ( uint ) actionID , actionType ) ;
183200 void EnqueueGroundTarget ( )
184201 {
185202 IntPtr self = ( IntPtr ) param_1 ;
186-
187203 Marshal . WriteInt32 ( self + 128 , ( int ) param_6 ) ;
188204 Marshal . WriteInt32 ( self + 132 , ( int ) param_7 ) ;
189205 Marshal . WriteByte ( self + 104 , 1 ) ;
190- Marshal . WriteInt32 ( self + 108 , ( int ) param_2 ) ;
206+ Marshal . WriteInt32 ( self + 108 , ( int ) actionType ) ;
191207 Marshal . WriteInt32 ( self + 112 , ( int ) action . RowId ) ;
192208 Marshal . WriteInt64 ( self + 120 , param_4 ) ;
193209 }
210+ void DequeueGroundTarget ( )
211+ {
212+ IntPtr self = ( IntPtr ) param_1 ;
213+
214+ Marshal . WriteInt32 ( self + 128 , 0 ) ;
215+ Marshal . WriteInt32 ( self + 132 , 0 ) ;
216+ Marshal . WriteByte ( self + 104 , 0 ) ;
217+ Marshal . WriteInt32 ( self + 108 , 0 ) ;
218+ Marshal . WriteInt32 ( self + 112 , 0 ) ;
219+ Marshal . WriteInt64 ( self + 120 , 0 ) ;
220+ }
194221
195- if ( action == null ) return requestActionHook . Original ( param_1 , param_2 , param_3 , param_4 , param_5 , param_6 , param_7 ) ;
222+ if ( action == null ) return requestActionHook . Original ( param_1 , actionType , actionID , param_4 , param_5 , param_6 , param_7 ) ;
196223 if ( action . Name == "Earthly Star" && clientState . LocalPlayer . StatusList . Any ( x => x . StatusId == 1248 || x . StatusId == 1224 ) )
197- return requestActionHook . Original ( param_1 , param_2 , param_3 , param_4 , param_5 , param_6 , param_7 ) ;
224+ return requestActionHook . Original ( param_1 , actionType , actionID , param_4 , param_5 , param_6 , param_7 ) ;
198225 // Ground target "at my cursor"
199226 if ( action != null && target == null )
200227 {
@@ -204,40 +231,43 @@ void EnqueueGroundTarget()
204231 {
205232 var playerpos = clientState . LocalPlayer . Position ;
206233 var distance = Vector3 . Distance ( playerpos , pos ) ;
207- if ( distance > action . Range + 1 )
234+ if ( distance > action . Range )
208235 {
209- pos = GetClampedGroundCoords ( playerpos , pos , action . Range + 1 ) ;
236+ pos = GetClampedGroundCoords ( playerpos , pos , action . Range ) ;
210237 }
211238
212239 }
213- EnqueueGroundTarget ( ) ;
214- bool returnval = RALDelegate ( ( IntPtr ) param_1 , param_2 , action . RowId , ( uint ) param_4 , ref pos , 0 ) ;
215- return returnval ;
240+ if ( IsLocked ) EnqueueGroundTarget ( ) ;
241+ //if (!AM->IsRecastTimerActive((ActionType)param_2, action.RowId)) return RALDelegate((IntPtr)param_1, param_2, action.RowId, (uint)param_4, ref pos, 0);
242+ return RALDelegate ( ( IntPtr ) param_1 , actionType , action . RowId , ( uint ) param_4 , ref pos , 0 ) ;
243+ //DequeueGroundTarget();
244+ //return false;
216245
217246 }
218247
219248 if ( action != null && target != null )
220249 {
221250 // ground target at non-mouse
222- if ( action . CastType == 7 ) {
251+ if ( action . TargetArea ) {
223252
224253 var targpos = target . Position ;
225254 if ( Configuration . OtherGroundClamp )
226255 {
227256 var playerpos = clientState . LocalPlayer . Position ;
228257 var distance = Vector3 . Distance ( playerpos , targpos ) ;
229- if ( distance > action . Range + 1 )
258+ if ( distance > action . Range )
230259 {
231- targpos = GetClampedGroundCoords ( playerpos , targpos , action . Range + 1 ) ;
260+ targpos = GetClampedGroundCoords ( playerpos , targpos , action . Range ) ;
232261 }
233262 }
234- EnqueueGroundTarget ( ) ;
235- bool returnval = RALDelegate ( ( IntPtr ) param_1 , param_2 , action . RowId , ( uint ) param_4 , ref targpos , 0 ) ;
263+ if ( IsLocked )
264+ EnqueueGroundTarget ( ) ;
265+ bool returnval = RALDelegate ( ( IntPtr ) param_1 , actionType , action . RowId , ( uint ) param_4 , ref targpos , 0 ) ;
236266 return returnval ;
237267 }
238- return requestActionHook . Original ( param_1 , param_2 , action . RowId , target . ObjectId , param_5 , param_6 , param_7 ) ;
268+ return requestActionHook . Original ( param_1 , actionType , action . RowId , target . ObjectId , param_5 , param_6 , param_7 ) ;
239269 }
240- return requestActionHook . Original ( param_1 , param_2 , param_3 , param_4 , param_5 , param_6 , param_7 ) ;
270+ return requestActionHook . Original ( param_1 , actionType , actionID , param_4 , param_5 , param_6 , param_7 ) ;
241271 }
242272
243273 private Vector3 GetClampedGroundCoords ( Vector3 self , Vector3 dest , int range )
@@ -276,7 +306,7 @@ private Vector3 GetClampedGroundCoords(Vector3 self, Vector3 dest, int range)
276306 {
277307 if ( CanUseAction ( entry , ActionType ) )
278308 {
279- if ( ! entry . Action . CanTargetFriendly && ! entry . Action . CanTargetHostile ) return ( entry . Action , clientState . LocalPlayer ) ;
309+ if ( ! entry . Action . CanTargetFriendly && ! entry . Action . CanTargetHostile && ! entry . Action . CanTargetParty && ! entry . Action . CanTargetDead ) return ( entry . Action , clientState . LocalPlayer ) ;
280310 return ( entry . Action , entry . Target . getPtr ( ) ) ;
281311 }
282312 }
@@ -292,11 +322,26 @@ private Vector3 GetClampedGroundCoords(Vector3 self, Vector3 dest, int range)
292322 return ( null , null ) ;
293323 }
294324
295- private bool CanUseAction ( StackEntry targ , uint ActionType )
325+ private unsafe int AvailableCharges ( Lumina . Excel . GeneratedSheets . Action action )
326+ {
327+ RecastTimer * timer ;
328+ if ( action . CooldownGroup == 58 )
329+ timer = GetGroupRecastTimer ( action . AdditionalCooldownGroup ) ;
330+ else
331+ timer = GetGroupRecastTimer ( action . CooldownGroup ) ;
332+ if ( action . MaxCharges == 0 ) return timer ->IsActive ^ 1 ;
333+ return ( int ) ( ( action . MaxCharges + 1 ) * ( timer ->Elapsed / timer ->Total ) ) ;
334+ }
335+
336+ private unsafe bool CanUseAction ( StackEntry targ , uint actionType )
296337 {
297338 if ( targ . Target == null || targ . Action == null ) return false ;
298-
339+ var y = AM ->GetActionStatus ( ( ActionType ) actionType , targ . Action . RowId , targ . Target . GetTargetActorId ( ) ) ;
340+ if ( AM ->GetActionStatus ( ( ActionType ) actionType , AM ->GetAdjustedActionId ( targ . Action . RowId ) , targ . Target . GetTargetActorId ( ) ) != 0 )
341+ return false ;
299342 var action = targ . Action ;
343+ var action2 = AM ->GetAdjustedActionId ( action . RowId ) ;
344+ action = RawActions . First ( x => x . RowId == action2 ) ;
300345 var target = targ . Target . GetTargetActorId ( ) ;
301346
302347 // ground target "at my mouse cursor"
@@ -310,9 +355,21 @@ private bool CanUseAction(StackEntry targ, uint ActionType)
310355 //var a = clientState.Actors[i];
311356 if ( a != null && a . ObjectId == target )
312357 {
358+
313359 unsafe
314360 {
315- if ( AM ->IsRecastTimerActive ( ( ActionType ) ActionType , action . RowId ) ) return false ;
361+ if ( action . ActionCategory . Value . RowId == ( uint ) ActionType . Ability && action . MaxCharges == 0 )
362+ {
363+ if ( AM ->IsRecastTimerActive ( ( ActionType ) actionType , action . RowId ) )
364+ {
365+ return false ;
366+ }
367+ }
368+ else if ( action . MaxCharges > 0 || ( action . CooldownGroup != 0 && action . AdditionalCooldownGroup != 0 ) )
369+ {
370+ if ( AvailableCharges ( action ) == 0 ) return false ;
371+
372+ }
316373 }
317374 if ( Configuration . RangeCheck )
318375 {
0 commit comments