BindKey Process System

Started by PSL, Mar 11, 2024, 12:57 PM

Previous topic - Next topic

PSL

When the player consistently presses a bound key, the script continues to execute the key's code. How is this done, see the code below.
The code has been tested and is accurate, although you can customize the code to suit your server.
class PlayerClass //Create two items here, one to store buttons pressed by the player and the other to keep repeating the timer
{
    keytimer=null;
    keytable=null;
}
function onScriptLoad()
{
    state<-array(100,null);
    //Here are the keys on the test keyboard
    Key_I<-BindKey(true,0x49,0,0);
    Key_J<-BindKey(true,0x4A,0,0);
    Key_K<-BindKey(true,0x4B,0,0);
    Key_L<-BindKey(true,0x4C,0,0);
}
function onPlayerJoin(player)
{
    state[player.ID]=PlayerClass(player.Name);
}
function onPlayerPart(player,reason)
{
if(state[player.ID].keytimer!=null) //When the player exits, delete these two things
{
state[player.ID].keytimer.Delete();
state[player.ID].keytimer=null;
state[player.ID].keytable.clear();
state[player.ID].keytable=null;
}
    state[player.ID]=null;
}
function onKeyDown(player,key)
{
    //When you press the key, the corresponding text will be displayed
    if(key==Key_I) Message("Key: I");
    if(key==Key_J) Message("Key: J");
    if(key==Key_K) Message("Key: K");
    if(key==Key_L) Message("Key: L");
    AddKeyTable(player.ID,key); //Saves the key that the player presses
}
function onKeyUp(player,key)
{
    RemoveKeyTable(player.ID,key); //Delete the key saved by the player
}
function AddKeyTable(i,key)
{
    local plr=FindPlayer(i);
    if(plr)
    {
        if(state[plr.ID].keytable==null) state[plr.ID].keytable={}; //The first time the key is pressed, the table is created

        if(state[plr.ID].keytable.rawin(key))
        {
        }
        else state[plr.ID].keytable.rawset(key,key); //If the key is not in the table, add it

        if(state[plr.ID].keytimer==null) //If the repetition timer is not created, create it
        {
            state[plr.ID].keytimer=NewTimer("onKeyProcess",10,0,plr.ID);
        }
    }
}

function RemoveKeyTable(i,key) //Here is the delete key function
{
    local plr=FindPlayer(i);
    if(plr)
    {
        if(state[plr.ID].keytable!=null)
        {
if(state[plr.ID].keytable.rawin(key)) //If the key exists in the player's table
{
state[plr.ID].keytable.rawdelete(key); //Delete it
if(state[plr.ID].keytable.len()==0)
{
state[plr.ID].keytable=null; //If there are no keys in the table, delete the table
if(state[plr.ID].keytimer!=null) //Also delete timer
{
state[plr.ID].keytimer.Delete();
state[plr.ID].keytimer=null;
}
                }
            }
        }
    }
}
function onKeyProcess(i)
{
    local plr=FindPlayer(i);
    if(plr)
    {
        if(state[plr.ID].keytable!=null)
        {
            if(state[plr.ID].keytable.len()>0)
            {
                local nokey=0;
                for(local i=0;i<state[plr.ID].keytable.len()+1000;i++) //Create a loop to get the keys in the player's store table
                {
                    if(state[plr.ID].keytable.rawin(i))
                    {
                        local key=state[plr.ID].keytable.rawget(i);
                        nokey=0;
                        onKeyDown(plr,key); //Execute this key
                    }
                    else nokey+=1;

                    if(nokey>=10) break; //The 10 here is the number you set when you create the number of binding keys
                }
      }
        }
    }
}

PSL

If you don't want I and J to trigger loop execution, you can do so.
function onKeyDown(player,key) //Now only KL can trigger the loop execution
{
    if(key==Key_I)
{
Message("Key: I");
}
    if(key==Key_J)
{
Message("Key: J");
}
    if(key==Key_K)
{
Message("Key: K");
AddKeyTable(player.ID,key);
}
    if(key==Key_L)
{
Message("Key: L");
AddKeyTable(player.ID,key);
}
}

PSL

#2
I've optimized the script to make it easier to add methods, use only one timer, and be more efficient. Adapt the following code to your server.
function onScriptLoad()
{
    PlayerKeys<-{};
    ProcessKey<-{};
    ProcessKeyTime<-100; //This number sets the speed of the code
    ProcessKeyTimer<-null;
}
function onPlayerPart(player,reason)
{
    DeleteAllPlayerKeyToTable(player.ID);
}
function onKeyDown(player,key)
{
    AddPlayerKeyToTable(player.ID,key);
}
function onKeyUp(player,key)
{
    DeletePlayerKeyToTable(player.ID,key);
}

//Functions
function AddKeyToTable(key)
{
    ProcessKey.rawset(key,key);
}
function DeleteKeyToTable(key)
{
    if(ProcessKey.rawin(key)) ProcessKey.rawdelete(key);
}
function AddPlayerKeyToTable(i,key)
{
    local plr=FindPlayer(i);
    if(plr)
    {
        if(ProcessKey.rawin(key))
        {
            if(PlayerKeys.rawin(plr.ID))
            {
                local arr=PlayerKeys.rawget(plr.ID),find=false;
                for(i=0;i<arr.len();i++)
                {
                    if(arr[i]==key)
                    {
                        find=true;
                        break;
                    }
                }
                if(find==false) arr.append(key);
            }
            else
            {
                local arr=[];
                arr.append(key);
                PlayerKeys.rawset(plr.ID,arr);
            }
            CreateProcessKeyTimer();
        }
    }
}
function DeletePlayerKeyToTable(i,key)
{
    local plr=FindPlayer(i);
    if(plr)
    {
        if(ProcessKey.rawin(key))
        {
            if(PlayerKeys.rawin(plr.ID))
            {
                local arr=PlayerKeys.rawget(plr.ID);
                for(local i=0;i<arr.len();i++)
                {
                    if(arr[i]==key)
                    {
                        arr.remove(i);
                        break;
                    }
                }
                if(arr.len()==0) PlayerKeys.rawdelete(plr.ID);
            }
            if(PlayerKeys.len()==0) DeleteProcessKeyTimer();
        }
    }
}
function DeleteAllPlayerKeyToTable(i)
{
    local plr=FindPlayer(i);
    if(plr)
    {
        if(PlayerKeys.rawin(plr.ID)) PlayerKeys.rawdelete(plr.ID);
    }
}
function CreateProcessKeyTimer()
{
    if(ProcessKeyTimer==null) ProcessKeyTimer=NewTimer("onServerKeyProcess",ProcessKeyTime,0);
}
function DeleteProcessKeyTimer()
{
    if(ProcessKeyTimer!=null) ProcessKeyTimer.Delete();
    ProcessKeyTimer=null;
}
function onServerKeyProcess()
{
    for(local i=0;i<100;i++)
    {
        local plr=FindPlayer(i);
        if(plr)
        {
            if(PlayerKeys.rawin(plr.ID))
            {
                local arr=PlayerKeys.rawget(plr.ID);
                for(local i=0;i<arr.len();i++) onKeyDown(plr,arr[i]);
            }
        }
    }
}

test code: A simple fly code, I key up, K key down. The above code must be installed first.
function onScriptLoad()
{
    Key_J<-BindKey(true,0x4A,0,0);
    Key_L<-BindKey(true,0x4C,0,0);
    Key_I<-BindKey(true,0x49,0,0);
    Key_K<-BindKey(true,0x4B,0,0);
   
    AddKeyToTable(Key_I); //Adds the binding key to the table that is looped
    AddKeyToTable(Key_K);

    ProcessKeyTime=10;
}
function onKeyDown(player,key)
{
    if(key==Key_I) player.Pos.z+=1;
    if(key==Key_K) player.Pos.z-=1;
    if(key==Key_J) MessagePlayer("[#FFFF00]Key: J",player);
    if(key==Key_L) MessagePlayer("[#FFFF00]Key: L",player);
}

Mohamed Boubekri

#3
Setting the time during a key press is a very useful feature to prevent occasional hacking or delays in some scripts.
good job.
| What now ? | Not yet ! |
Morrocan:- [ 🇲🇦 ].

PSL

I updated the function to set the number of repetitions, Make adding code easier.
AddKeyToTable(Key_K,10); //When K is pressed, it is automatically executed 10 times.
Create nut to scripts folder gift, name is keyprocess.nut.

//by: https://forum.vc-mp.org/index.php?topic=9397.0
//Function
/*
AddKeyToTable(key); //Set a key to repeat
AddKeyToTable(key,processtimes); //Set the key to repeat and set the number of repetitions
DeleteKeyToTable(key); //Delete the duplicate function of the key
SetKeyExecTime(time); //Set the interval for automatic execution
*/

function LoadKeyProcess()
{
ProcessKey<-{}; //Records repeatable keys
ProcessKeyTime<-10; //Execution interval milliseconds
ProcessKeyTimer<-null; //Execute key timer

PlayerKeys<-{}; //Record the keys pressed by the player

ProcessKeyExecTimes<-{}; //Records the number of key executions
PlayerKeyExecTimes<-array(100,null); //Record the number of times a player executes each key
}

function AddKeyToTable(key,processtimes=null)
{
ProcessKey.rawset(key,key);
if(processtimes!=null) ProcessKeyExecTimes.rawset(key,processtimes);
}

function DeleteKeyToTable(key)
{
if(ProcessKey.rawin(key)) ProcessKey.rawdelete(key);
if(ProcessKeyExecTimes.rawin(key)) ProcessKeyExecTimes.rawdelete(key);
}

function SetKeyExecTime(times)
{
if(times<0) times=1;
ProcessKeyTime=times;
}

function AddPlayerKeyToTable(i,key)
{
local plr=FindPlayer(i);
if(plr)
{
if(ProcessKey.rawin(key))
{
if(PlayerKeys.rawin(plr.ID))
{
local arr=PlayerKeys.rawget(plr.ID),find=false;
for(i=0;i<arr.len();i++)
{
if(arr[i]==key)
{
find=true;
break;
}
}
if(find==false) arr.append(key);
}
else
{
local arr=[];
arr.append(key);
PlayerKeys.rawset(plr.ID,arr);
}

if(ProcessKeyExecTimes.rawin(key))
{
if(PlayerKeyExecTimes[plr.ID]==null) PlayerKeyExecTimes[plr.ID]={};
if(PlayerKeyExecTimes[plr.ID].rawin(key))
{
local times=PlayerKeyExecTimes[plr.ID].rawget(key);
times-=1;
PlayerKeyExecTimes[plr.ID].rawset(key,times);
}
else
{
local keytimes=ProcessKeyExecTimes.rawget(key);
PlayerKeyExecTimes[plr.ID].rawset(key,keytimes);
}
}
CreateProcessKeyTimer();
}
}
}

function DeletePlayerKeyToTable(i,key)
{
local plr=FindPlayer(i);
if(plr)
{
if(ProcessKey.rawin(key))
{
if(PlayerKeys.rawin(plr.ID))
{
local arr=PlayerKeys.rawget(plr.ID);
for(local i=0;i<arr.len();i++)
{
if(arr[i]==key)
{
arr.remove(i);
break;
}
}
if(arr.len()==0) PlayerKeys.rawdelete(plr.ID);
}
if(ProcessKeyExecTimes.rawin(key))
{
if(PlayerKeyExecTimes[plr.ID]!=null)
{
if(PlayerKeyExecTimes[plr.ID].rawin(key))
{
PlayerKeyExecTimes[plr.ID].rawdelete(key);
if(PlayerKeyExecTimes[plr.ID].len()==0) PlayerKeyExecTimes[plr.ID]=null;
}
}
}
if(PlayerKeys.len()==0) DeleteProcessKeyTimer();
}
}
}

function DeleteAllPlayerKeyToTable(i)
{
local plr=FindPlayer(i);
if(plr)
{
if(PlayerKeys.rawin(plr.ID)) PlayerKeys.rawdelete(plr.ID);
if(PlayerKeyExecTimes[plr.ID]!=null) PlayerKeyExecTimes[plr.ID]=null;
}
}

function CreateProcessKeyTimer()
{
if(ProcessKeyTimer==null) ProcessKeyTimer=NewTimer("onServerKeyProcess",ProcessKeyTime,0);
}

function DeleteProcessKeyTimer()
{
if(ProcessKeyTimer!=null) ProcessKeyTimer.Delete();
ProcessKeyTimer=null;
}

function onServerKeyProcess()
{
for(local i=0;i<100;i++)
{
local plr=FindPlayer(i);
if(plr)
{
if(PlayerKeys.rawin(plr.ID))
{
local arr=PlayerKeys.rawget(plr.ID);
for(local i=0;i<arr.len();i++)
{
local find=false;
if(ProcessKeyExecTimes.rawin(arr[i]))
{
if(PlayerKeyExecTimes[plr.ID]!=null)
{
if(PlayerKeyExecTimes[plr.ID].rawin(arr[i]))
{
local keytimes=PlayerKeyExecTimes[plr.ID].rawget(arr[i]);
if(keytimes<0) find=true;
}
}
}
if(find==false) onKeyDown(plr,arr[i]);
}
}
}
}
}

LoadKeyProcess();

Add in main.nut
function onScriptLoad()
{
dofile("scripts/keyprocess.nut");
}
function onPlayerPart(player,reason)
{
DeleteAllPlayerKeyToTable(player.ID);
}
function onKeyDown(player,key)
{
AddPlayerKeyToTable(player.ID,key);
}
function onKeyUp(player,key)
{
DeletePlayerKeyToTable(player.ID,key);
}

Very simple way to add. You can customize the key Settings according to the previous code.