Jump to content

How to make custom dynamic keybinds


Recommended Posts

This is an informational post on how to create a system for creating your own keybinds to run arbitrary LUA.

It is dynamic in that you are able to edit the files and reload them while the game is running.

I also disable Strict.

Strict is used for mainly debugging and it enforces that any global variable must be declared before use, or it will throw a violation error.

I don't like Strict, and so I kill it.

 

Everything from here on is what I did for my stuff, so change what you will to fit your needs.

Like the names of functions that you'll be calling.

I am vain, and so pretty much all of my stuff has the cz_ prefix.

I'd suggest changing it for the cz_reload() concommand to something you can easily remember.

 

File structure layout:
 

Spoiler

Klei/DoNotStarveTogether/customcommands.lua

Klei/DST_Scripts/customcommands.lua

Klei/DST_Scripts/custom_keybinds.lua

 

I reused customcommands.lua in the DST_Scripts folder for portability in that it could be used in the main folder, but for how it's setup here this is how it should be setup without needing to edit anything.

The two keybinds in there are examples on things to do, and to check for.

It binds 'R' to do the yawn emote should you have the sleep set, and it binds 'Z' to drop your current cursor-held item at your player's feet.
 

File contents:

Spoiler

File Klei/DoNotStarveTogether/customcommands.lua:


cz_customcommands_path = "../../DST_Scripts/"
print("Reloading customcommands.lua")
TheSim:GetPersistentString(cz_customcommands_path.."customcommands.lua",
    function(success, output)
        if(success==true)
        then
            xpcall(loadstring(output), debug.traceback)
            print("Reloaded customcommands.lua")
        end
    end
)

Klei/DST_Scripts/customcommands.lua:


local OldStrict = getmetatable(_G)
local NoStrict = {}
setmetatable(_G, NoStrict)

cz_customcommands_path = cz_customcommands_path or "./DST_Scripts/"
function cz_reload_custom(filename)
    print("Reloading "..filename..".lua")
    TheSim:GetPersistentString(cz_customcommands_path..filename..".lua",
        function(success, output)
            if(success==true)
            then
                local filefn = loadstring(output)
                if(filefn)
                then
                    local success = xpcall(
                        filefn,
                        function(errormsg)
                            print("LUA Error:", errormsg)
                        end
                    )
                    if(success)
                    then
                        print("Reloaded "..filename..".lua")
                    end
                end
            end
        end
    )
end
function cz_reload()
    cz_reload_custom("customcommands")
end
-- Put your custom functions here, or create another file.
-- Keybinds then will have access to anything here.
cz_reload_custom("custom_keybinds")

File Klei/DST_Scripts/custom_keybinds.lua:


function cz_hotkey_checker()
    local curScreen = TheFrontEnd:GetActiveScreen()
    if(curScreen and curScreen.name=="HUD")
    then
        return false
    end
    return true
end

if(cz_hotkey_r)
then
    TheInput.onkeyup:RemoveHandler(cz_hotkey_r)
    cz_hotkey_r = nil
end
cz_hotkey_r = TheInput:AddKeyUpHandler(
    KEY_R,
    function()
        if cz_hotkey_checker()
        then
            return
        end
        if TheNet:GetIsServer() and not TheNet:IsDedicated()
        then
            return
        end
        TheNet:SendSlashCmdToServer("yawn", true)
    end
)


if(cz_hotkey_z)
then
    TheInput.onkeyup:RemoveHandler(cz_hotkey_z)
    cz_hotkey_z = nil
end
cz_hotkey_z = TheInput:AddKeyUpHandler(
    KEY_Z,
    function()
        if cz_hotkey_checker()
        then
            return
        end
        if(ThePlayer and ThePlayer.replica and ThePlayer.replica.inventory)
        then
            local item = ThePlayer.replica.inventory:GetActiveItem()
            if(item~=nil)
            then
                local x,y,z = ThePlayer.Transform:GetWorldPosition()
                SendRPCToServer(RPC.LeftClick, ACTIONS.DROP.code, x, z, nil, nil, nil, nil, nil)
            end
        end
    end
)

 

 

Note that the functions you have access to are from the core system's functionality and so you don't need to prefix 'GLOBAL.' to anything here.

Likewise you do not have direct access to the Mod API, and so creating a prefab postinit dynamically like this will take a higher level of knowledge of how a prefab hook is done etc.

 

 

Here's a freebie.

How to setup a repeating timer:
 

Spoiler

 

Editing Klei/DST_Scripts/customcommands.lua:


function cz_reload()
    cz_reload_custom("customcommands")
end
cz_reload_custom("custom_runloops")
cz_reload_custom("custom_keybinds")

File Klei/DST_Scripts/custom_runloops.lua:


if(cz__ongameframe~=nil)
then
    cz__ongameframe:Cancel()
    cz__ongameframe = nil
end
cz__ongameframe =
    scheduler:ExecutePeriodic(
        0.0,
        function()
            if ThePlayer
            then
                -- Do something
            end
        end
    )
if(cz__on10fps~=nil)
then
    cz__on10fps:Cancel()
    cz__on10fps = nil
end
cz__on10fps =
    scheduler:ExecutePeriodic(
        0.1,
        function()
            if ThePlayer
            then
                -- Do something
            end
        end
    )

 

 

I used double underscores to denote hot variables- variables that are very caustic should they be touched without care.

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

Please be aware that the content of this thread may be outdated and no longer applicable.

×
  • Create New...