ZScript and the Keyboard

Ask about ACS, DECORATE, ZScript, or any other scripting questions here!
Forum rules
Before asking on how to use a ZDoom feature, read the ZDoom wiki first. If you still don't understand how to use a feature, then ask here.

ZScript and the Keyboard

Postby Exosphere » Fri Jun 08, 2018 3:48 pm

So I have a few scripts planned that would act as abilities for the player that aren't tied to any items, but I am confused as to how exactly I would execute them. I know that when in ACS, I would do this in the KEYCONF file:

Code: Select allExpand view
addkeysection "Other Keybindings" [modname]

addmenukey "Toggle Ability" ab
defaultbind "ab" f
alias ab "pukename script_Ability"


But I am not sure if I could just replace the ZScript names where the ACS names are. So is there method to do the same but with ZScript? Let me know if you need more clarification with my question.
User avatar
Exosphere
 
Joined: 11 Jun 2017
Location: New England, US

Re: ZScript and the Keyboard

Postby gwHero » Fri Jun 08, 2018 4:33 pm

In ZScript, you can catch the keys in an eventhandler with InputProcess(); acting upon this event can be done with NetworkProcess().

Example code:
Code: Select allExpand view
class MKeyEvents : EventHandler
{   
   override bool InputProcess (InputEvent e)
   {
      if (e.Type == InputEvent.Type_KeyDown)
         SendNetworkEvent("MYKEYPRESS", e.KeyScan);         
      return false;
   }

   override void NetworkProcess(ConsoleEvent e)
   {               
      if (e.Name == "MYKEYPRESS")   
      {
         int key1, key2;
         [key1, key2] = Bindings.GetKeysForCommand("ab");
         if ((key1 && key1 == e.Args[0]) || (key2 && key2 == e.Args[0]))
         {
            // do your stuff, like calling your zscript function
         }
      }
   }
}



In the keyconf, you can replace the pukename by "" like so:
Code: Select allExpand view
addkeysection "Other Keybindings" [modname]
addmenukey "Toggle Ability" ab
defaultbind "ab" f
alias ab ""


Edit: eventhandler class itself needs to be defined in map or gameinfo definition in mapinfo lump.
User avatar
gwHero
Be your own Siddhartha
 
Joined: 08 May 2017
Location: The Netherlands

Re: ZScript and the Keyboard

Postby Exosphere » Sat Jun 09, 2018 1:45 pm

gwHero wrote:In ZScript, you can catch the keys in an eventhandler with InputProcess(); acting upon this event can be done with NetworkProcess().

Example code:
Code: Select allExpand view
class MKeyEvents : EventHandler
{   
   override bool InputProcess (InputEvent e)
   {
      if (e.Type == InputEvent.Type_KeyDown)
         SendNetworkEvent("MYKEYPRESS", e.KeyScan);         
      return false;
   }

   override void NetworkProcess(ConsoleEvent e)
   {               
      if (e.Name == "MYKEYPRESS")   
      {
         int key1, key2;
         [key1, key2] = Bindings.GetKeysForCommand("ab");
         if ((key1 && key1 == e.Args[0]) || (key2 && key2 == e.Args[0]))
         {
            // do your stuff, like calling your zscript function
         }
      }
   }
}



In the keyconf, you can replace the pukename by "" like so:
Code: Select allExpand view
addkeysection "Other Keybindings" [modname]
addmenukey "Toggle Ability" ab
defaultbind "ab" f
alias ab ""


Edit: eventhandler class itself needs to be defined in map or gameinfo definition in mapinfo lump.


Awesome, this will definitely be helpful in regards to the EventHandler. However, I do have a few more questions.

1. I know this will sound silly and simple question, but what is the method to writing a script that isn't an object? I am still somewhat new to ZScript, with most of my experience being mostly writing weapons. For example, say I want to write a script that push the player forward; using the event handler you mentioned, would the actual script that pushes the player forward be:
Code: Select allExpand view
class longjump
{
Thrust(30, 45);
}

If this isn't the correct way (which I have a feeling it isn't), what is the proper way to write a script like my example? Is it like writing a function mentioned in the wiki?

2. Do I still need to use KEYCONF file if I am using the EventHandler you wrote above to handle ZScript keyboard input?
User avatar
Exosphere
 
Joined: 11 Jun 2017
Location: New England, US

Re: ZScript and the Keyboard

Postby gwHero » Sat Jun 09, 2018 4:03 pm

Exosphere wrote:1. I know this will sound silly and simple question, but what is the method to writing a script that isn't an object? I am still somewhat new to ZScript, with most of my experience being mostly writing weapons. For example, say I want to write a script that push the player forward; using the event handler you mentioned, would the actual script that pushes the player forward be:
Code: Select allExpand view
class longjump
{
Thrust(30, 45);
}


If this isn't the correct way (which I have a feeling it isn't), what is the proper way to write a script like my example? Is it like writing a function mentioned in the wiki?


You will always need classes in ZScript; a class will have to have methods or functions where you put the code that really does something.
But indeed, a class does not have to be instantiated as an object. You can just create static methods in a class so you can use it as a library with functions you can call just wherever you want.
So taken your example, it could be something like:
Code: Select allExpand view
class longjump
{
   play static void ThrustMe()
   {
       Actor mo = players[consoleplayer].mo;
       mo.Thrust(30, 45);
   }
}


Some notes:
- the Thust you used is a method of the Actor class; if you want to use it to the player, you can retrieve the actor object of the player like in my example.
- notice the keyword 'play' that I added: this is necessary for static functions in such a class to be able to obtain the method that is used here.

Now in the beginning, if you just start with ZScript, it may all be a bit overwhelming. However, there is more and more info about ZScript in the forums and on the wiki, and I would advise also to download a lot of recent mods and tc's from the forum; a lot of the newer mods use ZScript and they are a good reference to learn from them.

Exosphere wrote:2. Do I still need to use KEYCONF file if I am using the EventHandler you wrote above to handle ZScript keyboard input?

Yes, if you want to do it in a proper way; notice that I use Bindings.GetKeysForCommand("ab"); if you do it this way the player will still be able to define his own key for your command.
However, it is indeed also possible to do it without the keyconf; if you wish you could check hardcoded the pressed keycode. More info about events is on the wiki: https://zdoom.org/wiki/Events_and_handlers

Edit: for your convenience, here is an example for checking directly if 'G' was pressed without a keyconf:
Code: Select allExpand view
class MEvents : EventHandler
{
   override bool InputProcess (InputEvent e)
   {
      if (e.Type == InputEvent.Type_KeyDown)
         SendNetworkEvent("KEYPRESS", e.KeyScan);         
      return false;
   }
   
   override void NetworkProcess(ConsoleEvent e)
   {   
      if (e.Name == "KEYPRESS" && e.Args[0] == 34)   //G pressed
         console.printf("you pressed 'G'");      
   }
}
User avatar
gwHero
Be your own Siddhartha
 
Joined: 08 May 2017
Location: The Netherlands

Re: ZScript and the Keyboard

Postby Exosphere » Sat Jun 23, 2018 10:44 pm

So I have been tinkering with the keyboard and event handlers and made some minor success. The action that I want to happen happens (thrusting the player forward), but it now happens with every key press, and setting it with KEYCONF does nothing to make it use only the specified button. Anyone have any suggestions on how to make it happen with only a specific button press set in the keyboard options? Here is the code:
Code: Select allExpand view
class LongJumpManager : EventHandler
{
    override bool InputProcess(InputEvent e)
    {
        if (e.Type == InputEvent.Type_KeyDown) //I know that the problem lies here, since the action is activating every time I press any button
        { SendNetworkEvent("longjump_use", e.KeyScan); }
       
        return false;
    }
   
    override void NetworkProcess(ConsoleEvent e)
    {
        if (e.Name == "longjump_use")
        {
            let plr = players[e.Player].mo;
            //plr.Thrust(30, 45); Fixed, and changed to Vel3DFromAngle
        }
    }
}


Also, do you (or anyone else) have any ideas on how I would make the player do a long-jump-like (ala the Long Jump Module from Half-Life and Mario's Long Jump from most, if not all, 3D Super Mario games) action in ZScript? I was able to achieve what I wanted with ACS, but since I am working with ZScript, ThrustThing and ThrustThingZ are unavailable to me and I am unsure how to proceed. SOLVED
User avatar
Exosphere
 
Joined: 11 Jun 2017
Location: New England, US

Re: ZScript and the Keyboard

Postby phantombeta » Thu Jan 24, 2019 5:11 am

While this is a necrobump of sorts, someone else on the ZDoom Discord was trying to use this code, so this really needs to be said.
Don't use this! There's a "netevent" console command specifically made for this sort of thing!

This is correct way to do this:
KEYCONF:
Code: Select allExpand view
addkeysection "Other Keybindings" [modname]

addmenukey "Toggle Ability" ab
defaultbind "ab" f
alias ab "netevent \"longjump_use\""

ZScript:
Code: Select allExpand view
class LongJumpManager : EventHandler
{
    override void NetworkProcess(ConsoleEvent e)
    {
        if (e.Name == "longjump_use")
        {
            let plr = players[e.Player].mo;
            //plr.Thrust(30, 45); Fixed, and changed to Vel3DFromAngle
        }
    }
}
User avatar
phantombeta
In the meadow of sinful thoughts, every flower's a perfect one
 
Joined: 02 May 2013
Location: The United Soviet Socialist Dictatorship of Hueland
Discord: phantombeta#2461
Twitch ID: phantombeta_


Return to Scripting

Who is online

Users browsing this forum: No registered users and 2 guests