minetest / minetest

Minetest is an open source voxel game-creation platform with easy modding and game creation
https://www.minetest.net/
Other
10.64k stars 2.01k forks source link

Expose drop key to `get_player_control()` #13954

Open Zughy opened 11 months ago

Zughy commented 11 months ago

Problem

I'm creating an API where people can choose which key is the key assigned to a specific action. It could be Z, AUX1, Q, whatever, but they can't really choose Q (the drop key) because I have no way to check when it's pressed

Solutions

Expose drop key to get_player_control() and get_player_control_bits()

Alternatives

Global callback for when items are dropped, but why split key checks into two different functions?

Additional context

It'd be interesting to discuss further exposures such as inventory and camera change

erlehmann commented 11 months ago

I'm creating an API where people can choose which key is the key assigned to a specific action

I am interested. Show and tell? A link to the repo would be enough to satisfy my curiosity.

Global callback for when items are dropped, but why split key checks into two different functions?

IIRC in some games, Items are dropped by players for other reasons than keypresses:

I guess some mods might also have other triggers for that kind of thing, but I do not know any.

Therefore, if a game/mod developer wants to detect when an item is dropped in a mod, doing it via keypresses is probably not the best idea. Exposing that keypress might encourage it though, providing a loaded footgun (an obvious, but wrong solution).

Zughy commented 11 months ago

Show and tell?

It's just on my PC for now and it's not what you think: it's a weapons API and I want modders to customise the reload key

if a game/mod developer wants to detect when an item is dropped in a mod, doing it via keypresses is probably not the best idea

In my case it works, as I just want to prevent the drop when people press the drop key to reload the weapon. I would simply check for get_player_control() to contain weapons_lib.RELOAD_KEY

erlehmann commented 11 months ago

I just want to prevent the drop when people press the drop key to reload the weapon.

I guess this would prevent dropping items at all. Is this not otherwise possible right now, e.g. through the item definition?

dax-er commented 11 months ago

IIRC there is an on_drop field in item definition. example code for the weapon tool definition:

on_drop = function(itemstack, dropper, pointed_thing)

    if weapons_lib.RELOAD_KEY == 'Q' -- or however you format that

        -- do reload things

    else

        minetest.item_drop(itemstack, dropper, pointed_thing)

end
Zughy commented 11 months ago

@CallMeDax if you change key, your code won't work. Control_bits espose the action, not the default key

dax-er commented 11 months ago

I might be misunderstanding but whatever triggers the drop action should call the callback function. It doesn't have to be 'Q', it could be anything else. weapons_lib.RELOAD_KEY could contain the action (e.g. "drop") to make this more clear (if it doesn't already). The if function is just to check whether the drop key should trigger it at all (per your mod's code: if the reload key is set to "zoom" in your mod then it shouldn't reload if I press "drop").

MisterE123 commented 10 months ago

IIRC there is an on_drop field in item definition. example code for the weapon tool definition:

on_drop = function(itemstack, dropper, pointed_thing)

    if weapons_lib.RELOAD_KEY == 'Q' -- or however you format that

        -- do reload things

    else

        minetest.item_drop(itemstack, dropper, pointed_thing)

end

This code just doesn't make sense to me... specifically what if weapons_lib.RELOAD_KEY == 'Q' aims to achieve.

MisterE123 commented 10 months ago

You can hack together a workaround though,

local old_drop = minetest.item_drop
function minetest.item_drop(itemstack, dropper, pos) -- supposed to return leftover item
   if weapons_lib.should_player_be_able_to_drop_item(dropper:get_player_name()) == false then -- an example ... here, you use your mod's api to check if the player should be able to drop the item, or do whatever you want
      return itemstack -- return the original itemstack to keep
   else
      return old_drop(itemstack, dropper, pos) -- do the old thing
   end
end
dax-er commented 10 months ago

IIRC there is an on_drop field in item definition. example code for the weapon tool definition:

on_drop = function(itemstack, dropper, pointed_thing)

    if weapons_lib.RELOAD_KEY == 'Q' -- or however you format that

        -- do reload things

    else

        minetest.item_drop(itemstack, dropper, pointed_thing)

end

This code just doesn't make sense to me... specifically what if weapons_lib.RELOAD_KEY == 'Q' aims to achieve.

the if is to check whether drop should trigger the reload as @Zughy has explained. for example if it was set to zoom then I wouldn't want to reload on drop but zoom instead. I was not clear when I used q, I should have used drop instead. the on_drop should be added to the weapon definition so it gets called when the player presses the drop key.

sfan5 commented 9 months ago

FWIW same problem as mentioned here exists: https://github.com/minetest/minetest/issues/14136#issuecomment-1865057527

Zughy commented 9 months ago

@sfan5 what does it change between spotting AUX (by default E) and spotting Q? Since the engine already does the former

sfan5 commented 9 months ago

Nothing, this also affects E/AUX. Just for the sake of latency key handling is 100% better done on the client.

I guess it could still be exposed as an imperfect solution is better than none.

Zughy commented 9 months ago

I'm 100% for the imperfect solution, at least it gives modders a chance to implement what they need (although not 100% responsive) instead of waiting potentially for years. I've been using E in my mods for a long time and nobody has really noticed the input lag. Same for a game like Fantasy Brawl, where Sneak and Z are used (you can try it on the AES server)