Since it's another part , I'm aiming to post a new post.
What's the difference between UserKeyActions and UserKeyMap ?
1. Every time you insert something into UserKeyActions , the game will automatically update UserKeyActions table in game.prefs , but without a specific hotkey bound , what is updated is only UserKeyActions .
2. Once you distribute a hotkey for the added new action , the game will copy the default key mappings into UserKeyMap and UserDebugKeyMap , and automatically update your custom hotkey into UserKeyMap even if it's a debug hotkey , thus UserDebugKeyMap is not important in this case.
3. As a kind of overriding specification of SupCom , once UserKeyMap exists , the game will only read mappings from UserKeyMap , ignoring default key mappings , which is why if you delete some of UserKeyMap's elements , the corresponding hotkey lost in game.
4. To solve 3 , you can delete UserKeyMap entirely , which drives game to read datas from default file .
5. UserKeyActions is maybe a interface left by someone to make customing hotkeys easier . It's complex to explain , but there is a bug if you don't use this convenience :
Your own hotkeys won't be recognized until F1 pressed detecting hotkey files once again , since the command path is written else where the program had already passed through ,while the path written in UserKeyActions can be recognized automatically. (there is no place other than /lua/keymap that can be read if you don't use UserKeyActions )
Thus I think it's impossible to define custom hotkeys in /lua/keymap by table operations in gamemain.lua . The program had already passed through.
6. Defaultly , players don't have UserKeyMap or UserKeyActions in game.prefs , if you do , maybe your game had encountered a SetUserKeyAction command sometime , and you gave the custom action a hotkey .
7. It's terrible to get polluted game.prefs rid of various custom hotkey mappings from UserKeyActions and UserKeyMap by programming manner . If you have a polluted game.prefs consists of tons of esoteric hotkey mappings , delete the UserKeyMap , leaving the actions blank without hotkey , and distribute them manually again.
Best posts made by illumination
-
Patch for hotkey modding tutorial
-
The MOST detailed UI modding tutorial · hotkey aspect
[Guide for UI modders]
This is a tutorial for those who want to add their own hotkeys into game.
I don't know how the original game binds keys to various actions , but the following is a way available for modders
Firstly , we need to pay attention to this directory , for Windows , it is
-- C:\Users\User\AppData\Local\Gas Powered Games\Supreme Commander Forged Alliance --
And you will find a file named game.prefs here . Yes , 'prefs' is the suffix , thus you must tell your Windows which application you want to open it with. Mine is notepad ++
This is where SUPCOM storages its user datas .
How to access it in game ? It's a function embedded in Engine , and you can find it in
-- SupCom\mohodata\lua\user\prefs.lua --
You will see something named 'GetPreference' here.
It can be found on supcom wiki , however , only such a perfunctory statement.
'INFO: obj GetPreference(string, [default])'
What 'GetPreference' actually does is extracting datas from game.prefs . That's why you can pass 'profile' , or 'profile.profiles' to it , as the game.prefs itself contains these tables.
Secondly , we should notice that there is a thing called profile.current .
It is a number , recording how many profiles you have in game.
Emmm.....
Is it really that simple ? Of course not.
Another role it plays is pointing to the current profile , which is used by Player now. New profile would be added to the end of profile table , and its index is just equal to the total sum.
So you would see these codes .if profile.profiles[profile.current] then
As profile.current pointing to the current profile , the current profile must storaged with a index having a value of profile.current , which indicates that all the profiles are storaged in profile.profiles . You would understand the abovementioned code better if you take a look of game.prefs.
Thirdly , take a look of this line of codes.
profile.profiles[profile.current][fieldName] = data
If you do have took a look of game.prefs , you would notice the variable called 'fieldName' .
You can put whatever you want into this variable , even give it a value of 'asdjoiadjgrjsiofgjsdoigr' , though which won't be discerned by game.
I'm not talking about something magical , but if you want your custom fieldName can be recognized , you need to assume that there're really a ton of lines of fixed codes somewhere you can't reach , saying 'local x = profile.userkeyaction' , or something like that , fixed , unchangeable .
Thus if you want your codes be recognized by game , especially to put your custom hotkey into use , you must follow the specification .
The specification I found is following:
If you want to add your own hotkeys into game , there're two things you need to pay attention to.
One is action, the another is category.
Game says : There will be v.category . Then there popped out a rule for modders that if you don't have a element indexed with string 'category' in table , even if this table contains actual command , game won't recognize it.
Category is necessary , but what value it actually holds is not important. You can say:local t = { action = 'rtertghfgh' , category = 'bbhhnjnjfg' }
Just keep category ~= nil , and if there's no such a bbhhnjnjfg category , game will create a new one. You can press F1 to see this category printed out .
For action , if you don't give it a string path value like
"UI_Lua import('/mods/apimod/lib/main.lua')._print()"
The game would remind you that unknown console command not found.
e.g. The game won't find what is called rtertghfgh.
But anyway , it runs successfully .
Keep it in mind that if you don't have a action stuff while still having category , the game will crash at the beginning , because he cannot comprehend a nil value as actual path .
And if you have both two , you can put them together into one table .
Usually , we have another element called order , but this is not a thing decisive
Finally , your codes look likelocal t = { action = "dxxxx", category = 'dxddx', order = 35 }
You can add whatever you like into variable t , though they will not be discerned.
It's also legal.local t = { 12,34,45,67,89,90, action = "dxxxx", category = 'dxddx', order = 350 }
We are not finished yet.
After completing table t , we need to put t into a larger table .local s = {t}
Somewhere we can't see , game loops table s , and for each k,v in s , it loops v to know what category this v has, and what action this v refers to , and prints k as a description of the action in v .
If you directly pass t as the result , like thatPrefs.SetToCurrentProfile("UserKeyActions", t)
Things you made won't be shown in game , as the game is attempting to loop a string value. The game would get stuck .
Once everything set well , you should worry about the description shown out.
The game shows index of table t in the table s as the description for the t , which is number 1 in this case.
You can set the index as a string , but that's not convenient.
Mine solution is :local keydes = import('/lua/keymap/keydescriptions.lua').keyDescriptions keydes[1] = 'dsdsds'
Note that I said keydes[1] , not keydes['1'] , as the index is number not a string.
Lua passes table from = rightside to = leftside as referrence , so you can call keydes[1] to modify original table , which is the one game reads datas from.
Thus one gamemain.lua file does all the thing , no need for modders to put keydescriptions.lua into hook.
Eventually , the hotkeys bound to custom actions are shown in currentprofile.UserKeyMap .
Thus , even though you clear UserKeyActions , there's still referrence to the hotkey bound to the cleared one.
Theoretically , you can make use of \lua\keymap in similar way , to achieve similar function without using UserKeyActions , you can make a try. I suggest you to do these in gamemain.lua , do not put too many files into hook to mess up your mod. -
RE: Expansion Technology Pack
For example , we can display ST3sniper's toggle on a custom window , and give it custom tooltips so that it will be hard to confuse with their current mode anymore