FAForever Forums
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Login
    1. Home
    2. illumination
    3. Best
    I
    Offline
    • Profile
    • Following 0
    • Followers 0
    • Topics 4
    • Posts 12
    • Groups 0

    Posts

    Recent Best Controversial
    • Patch for hotkey modding tutorial

      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.

      posted in Modding & Tools
      I
      illumination
    • 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 like

      local 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 that

      Prefs.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.

      posted in Modding & Tools uimod
      I
      illumination
    • 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

      posted in Modding & Tools
      I
      illumination