[ZScript] Replacing functionality for weapon select

Ask about ACS, DECORATE, ZScript, or any other scripting questions here!

Moderator: GZDoom Developers

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.

Please bear in mind that the people helping you do not automatically know how much you know. You may be asked to upload your project file to look at. Don't be afraid to ask questions about what things mean, but also please be patient with the people trying to help you. (And helpers, please be patient with the person you're trying to help!)
Post Reply
User avatar
Virathas
Posts: 254
Joined: Thu Aug 10, 2017 9:38 am

[ZScript] Replacing functionality for weapon select

Post by Virathas »

Hey

Topic probably too ambiguous, but:

TL;DR: Is it possible to intercept the weapon select (via slot) command and perform a different function?

Long Story:

I have a main player class, that can select slot 0-9 and then use a spell to set a spell for that slot.

This player can morph into various other forms (monsters) and while in this form, I would like to have a spell be cast when that slot is selected, to reduce the amount of hotkeys. Is it possible to do so?
User avatar
m8f
 
 
Posts: 1461
Joined: Fri Dec 29, 2017 4:15 am
Preferred Pronouns: He/Him
Location: Siberia (UTC+7)
Contact:

Re: [ZScript] Replacing functionality for weapon select

Post by m8f »

Totally doable. First, you need an EventHandler that overrides InputProcess. Then in that function you check InputEvent to be a slot key press event:

Code: Select all

  bool inputProcess(InputEvent event)
  {
    if (event.type != InputEvent.Type_KeyDown) return false;

    int key = event.keyScan;
    for (int i = 0; i <= 11; ++i)
    {
      if (isKeyForCommand(key, string.format("slot %d", i)))
      {
        // i is your slot here
        return true;
      }
    }
    return false;
  }
where isKeyForCommand is

Code: Select all

  private static
  bool isKeyForCommand(int key, string command)
  {
    int key1;
    int key2;
    [key1, key2] = bindings.getKeysForCommand(command);
    return (key == key1 || key == key2);
  }
Remember to return true in inputProcess when you want to "eat" the key, and false when you want to ignore the key (for example, movement keys).
Note that inputProcess is UI-scoped, and to do something gameplay-related you will need to throw an event with EventHandler.SendNetworkEvent and catch it with EventHandler's void NetworkProcess (ConsoleEvent e) function, which you override too.

If you want a complete example, here is a mod that catches slot keys and some other keys to call its own functions.
User avatar
Virathas
Posts: 254
Joined: Thu Aug 10, 2017 9:38 am

Re: [ZScript] Replacing functionality for weapon select

Post by Virathas »

Thanks a ton!

I will check this mod then (Need to be careful, not to cause MP desyncs)
User avatar
Player701
 
 
Posts: 1710
Joined: Wed May 13, 2009 3:15 am
Graphics Processor: nVidia with Vulkan support
Contact:

Re: [ZScript] Replacing functionality for weapon select

Post by Player701 »

BTW, recent versions of GZDoom allow binding more than two keys to a single command by normal means (i.e. the menu), so there's now a new method available to retrieve all bindings:

Code: Select all

native void GetAllKeysForCommand(out array<int> list, String cmd);
It's quite unlikely that someone assigns more than 2 (let alone 1) key to a slot command though, but I tend to prefer a "better safe than sorry" approach in scenarios like this one.
User avatar
m8f
 
 
Posts: 1461
Joined: Fri Dec 29, 2017 4:15 am
Preferred Pronouns: He/Him
Location: Siberia (UTC+7)
Contact:

Re: [ZScript] Replacing functionality for weapon select

Post by m8f »

Oh, I missed that! Player701, thanks!

In this case, isKeyForCommand will look like this:

Code: Select all

  private static
  bool isKeyForCommand(int key, string command)
  {
    Array<int> keys;
    bindings.getAllKeysForCommand(keys, command);
    uint nKeys = keys.size();
    for (uint i = 0; i < nKeys; ++i)
    {
      if (keys[i] == key) return true;
    }
    return false;
  }
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
Posts: 49232
Joined: Sat Jul 19, 2003 10:19 am
Location: Germany

Re: [ZScript] Replacing functionality for weapon select

Post by Graf Zahl »

Player701 wrote:BTW, recent versions of GZDoom allow binding more than two keys to a single command by normal means (i.e. the menu), so there's now a new method available to retrieve all bindings:

Code: Select all

native void GetAllKeysForCommand(out array<int> list, String cmd);
It's quite unlikely that someone assigns more than 2 (let alone 1) key to a slot command though, but I tend to prefer a "better safe than sorry" approach in scenarios like this one.

The binding worked always like this - the system binds commands to keys, not keys to commands, so you can bind the same command to an infinite number of keys.
The problem with the old menu code was that it was mostly a lazy port of Blood's keybind menu. Blood, like all other Build games, binds keys to commands so it only has 2 slots per command. ZDoom's menu replicated that in its menu display despite the underlying system not having the limitation.
User avatar
Nash
 
 
Posts: 17499
Joined: Mon Oct 27, 2003 12:07 am
Location: Kuala Lumpur, Malaysia
Contact:

Re: [ZScript] Replacing functionality for weapon select

Post by Nash »

m8f - does your solution handle changing weapons with the mousewheel or a non-keyboard input (like a gamepad - I have shoulder buttons bounded to weapnext/prev)?
User avatar
m8f
 
 
Posts: 1461
Joined: Fri Dec 29, 2017 4:15 am
Preferred Pronouns: He/Him
Location: Siberia (UTC+7)
Contact:

Re: [ZScript] Replacing functionality for weapon select

Post by m8f »

It works with mousewheel. Cannot check on a gamepad because I don't have one.
Post Reply

Return to “Scripting”