@@ -21,6 +21,11 @@ local COL_YELLOW <const> = Color("yellow")
2121--- | "scenes"
2222--- | "clipsets"
2323
24+ --- @alias ActionHistorySortMode
25+ --- | 0 Timestamp
26+ --- | 1 Type
27+ --- | 2 Label
28+
2429--- @class YimActionsFavorites
2530--- @field anims table<string , AnimData>
2631--- @field scenarios table<string , ScenarioData>
@@ -35,12 +40,14 @@ local COL_YELLOW <const> = Color("yellow")
3540--- @class YimActions
3641--- @field protected m_initialized boolean
3742--- @field private m_file_names { favorites : " saved_actions.json" , commands : " action_commands.json" }
38- --- @field Favorites YimActionsFavorites
39- --- @field Commands table<string , ActionCommandData>
40- --- @field CurrentlyPlaying table<handle , Action>
41- --- @field LastPlayed Action[]
42- --- @field CompanionManager CompanionManager
43- --- @field SceneManager SceneManager
43+ --- @field private SceneManager SceneManager
44+ --- @field public Favorites YimActionsFavorites
45+ --- @field public Commands table<string , ActionCommandData>
46+ --- @field public DrawNewCommandWindow boolean
47+ --- @field public CurrentlyPlaying table<handle , Action>
48+ --- @field public LastPlayed { count : integer , sort_mode : ActionHistorySortMode , data : array< { action : Action , timestamp : seconds , type : eActionType , fmt : string } > }
49+ --- @field private m_history_lookup set<string>
50+ --- @field public CompanionManager CompanionManager
4451local YimActions = {}
4552YimActions .__index = YimActions
4653
@@ -50,16 +57,22 @@ function YimActions:init()
5057 return self
5158 end
5259
53- self .CompanionManager = CompanionManager .new ()
54- self .SceneManager = SceneManager .new ()
55- self .CurrentlyPlaying = {}
56- self .LastPlayed = {}
57- self .Commands = {}
58- self .m_file_names = {
60+ self .DrawNewCommandWindow = false
61+ self .CompanionManager = CompanionManager .new ()
62+ self .SceneManager = SceneManager .new ()
63+ self .CurrentlyPlaying = {}
64+ self .m_history_lookup = {}
65+ self .LastPlayed = {
66+ data = {},
67+ count = 0 ,
68+ sort_mode = 0 ,
69+ }
70+ self .Commands = {}
71+ self .m_file_names = {
5972 favorites = " saved_actions.json" ,
6073 commands = " action_commands.json" ,
6174 }
62- self .Favorites = {
75+ self .Favorites = {
6376 anims = {},
6477 scenarios = {},
6578 scenes = {},
@@ -85,30 +98,86 @@ function YimActions:GetPed(ped)
8598 return ped or LocalPlayer :GetHandle ()
8699end
87100
101+ --- @private
88102--- @param ped ? integer
89- function YimActions :AddActionToRecents (ped )
90- ped = self :GetPed (ped )
91- local current = self . CurrentlyPlaying [ ped ]
103+ function YimActions :UpdatePlayHistory (ped )
104+ local current = self . CurrentlyPlaying [ self :GetPed (ped )]
105+ if ( not current ) then return end
92106
93- if (not current ) then
107+ local label = current .data .label
108+ local lookupArray = self .m_history_lookup
109+ if (lookupArray [label ]) then return end
110+
111+ local type = current .action_type
112+ local fmt = _F (" [%s] %s" , current :TypeAsString (), label )
113+ local epoch = DateTime :Now ():Epoch ()
114+ table.insert (self .LastPlayed .data , {
115+ action = current ,
116+ timestamp = epoch ,
117+ type = type ,
118+ fmt = fmt ,
119+ })
120+
121+ lookupArray [label ] = true
122+ self .LastPlayed .count = # self .LastPlayed .data
123+ self :SortPlayHistory ()
124+ end
125+
126+ --- @param index integer
127+ function YimActions :RemoveFromHistory (index )
128+ local data = self .LastPlayed .data
129+ local count = # data
130+ if (count == 0 ) then return end
131+
132+ if (count == 1 ) then
133+ self .LastPlayed .data = {}
134+ self .m_history_lookup = {}
135+ self .LastPlayed .count = 0
94136 return
95137 end
96138
97- if (# self .LastPlayed == 0 ) then
98- table.insert (self .LastPlayed , current )
99- else
100- local exists = false
101- for _ , action in ipairs (self .LastPlayed ) do
102- if action .data .label == current .data .label then
103- exists = true
104- break
105- end
106- end
139+ --- @type { action : Action , timestamp : seconds , type : eActionType , fmt : string }?
140+ local entry = table.remove (data , index )
141+ if (entry ) then
142+ self .m_history_lookup [entry .action .data .label ] = nil
143+ end
144+ self .LastPlayed .count = math.max (0 , count - 1 )
145+ end
146+
147+ function YimActions :ClearPlayHistory ()
148+ local count = self .LastPlayed .count
149+ if (count == 0 ) then
150+ return
151+ end
107152
108- if not exists then
109- table.insert (self .LastPlayed , current )
153+ local lastPlayed = self .LastPlayed .data
154+ ThreadManager :Run (function ()
155+ for i = count , 1 , - 1 do
156+ table.remove (lastPlayed , i )
157+ yield (5 )
110158 end
159+ self .LastPlayed .count = 0
160+ self .m_history_lookup = {}
161+ end )
162+ end
163+
164+ --- @param mode ActionHistorySortMode ?
165+ function YimActions :SortPlayHistory (mode )
166+ if (mode and mode == self .LastPlayed .sort_mode ) then
167+ return
111168 end
169+
170+ mode = mode or self .LastPlayed .sort_mode
171+ table.sort (self .LastPlayed .data , function (a , b )
172+ if (mode == 0 ) then
173+ return a .timestamp > b .timestamp
174+ elseif (mode == 1 ) then
175+ return a .type < b .type
176+ end
177+
178+ return a .action .data .label < b .action .data .label
179+ end )
180+ self .LastPlayed .sort_mode = mode
112181end
113182
114183--- @return boolean
@@ -215,7 +284,7 @@ function YimActions:PlayAnim(animData, targetPed)
215284 false
216285 )
217286
218- self :AddActionToRecents (targetPed )
287+ self :UpdatePlayHistory (targetPed )
219288
220289 if (not GVars .features .yim_actions .disable_props ) then
221290 if (animData .props and # animData .props > 0 ) then
@@ -321,7 +390,7 @@ function YimActions:Play(action, ped)
321390 self :PlaySyncedScene (action .data )
322391 end
323392
324- self :AddActionToRecents (ped )
393+ self :UpdatePlayHistory (ped )
325394
326395 if (Backend .debug_mode ) then
327396 self .Debugger :Update (ped )
@@ -496,34 +565,45 @@ end
496565--- @param action_type eActionType
497566function YimActions :AddToFavorites (category , name , data , action_type )
498567 if (self :DoesFavoriteExist (category , name )) then
499- Notifier :ShowError (
500- " Samurai's Scripts" ,
501- " This action is already saved as a favorite!"
502- )
568+ Notifier :ShowError (" YimActions" , " This action is already saved as a favorite!" )
569+ return
570+ end
571+
572+ --- @type table<string , ActionData> ?
573+ local cat = self .Favorites [category ]
574+ if (type (cat ) ~= " table" ) then
575+ Notifier :ShowError (" YimActions" , " Unknown action category!" )
503576 return
504577 end
505578
506579 data [" type" ] = action_type
507- self . Favorites [ category ] [name ] = data
580+ cat [name ] = data
508581 self :ParseFavorites ()
509582end
510583
511584--- @param category ActionCategory
512585--- @param name string
513586function YimActions :RemoveFromFavorites (category , name )
514- self .Favorites [category ][name ] = nil
587+ --- @type table<string , ActionData> ?
588+ local cat = self .Favorites [category ]
589+ if (type (cat ) ~= " table" ) then
590+ return
591+ end
592+
593+ cat [name ] = nil
515594 self :ParseFavorites ()
516595end
517596
518597function YimActions :ReadSavedCommands ()
519598 --- @type table<string , ActionCommandData> ?
520599 local data = Serializer :ReadFromFile (self .m_file_names .commands )
521600 if (type (data ) ~= " table" ) then
522- self : ParseCommands ( )
601+ Serializer : WriteToFile ( self . m_file_names . commands , {} )
523602 return
524603 end
525604
526605 self .Commands = data
606+ self :ParseCommands ()
527607end
528608
529609function YimActions :RegisterCommands ()
@@ -616,10 +696,10 @@ function YimActions:RemoveCommandAction(action_label)
616696end
617697
618698--- @param action_type eActionType
619- --- @param id string
699+ --- @param str_id string
620700--- @return Action ?
621- function YimActions :FindActionByStrID (action_type , id )
622- --- @type AnimData | ScenarioData ?
701+ function YimActions :FindActionByStrID (action_type , str_id )
702+ --- @type array< AnimData| ScenarioData> ?
623703 local lookup_array = Switch (action_type ) {
624704 [Enums .eActionType .ANIM ] = t_AnimList ,
625705 [Enums .eActionType .SCENARIO ] = t_PedScenarios ,
@@ -631,7 +711,7 @@ function YimActions:FindActionByStrID(action_type, id)
631711 end
632712
633713 for _ , data in ipairs (lookup_array ) do
634- if (data .label == id ) then
714+ if (data .label == str_id ) then
635715 return Action .new (data , action_type )
636716 end
637717 end
0 commit comments