Angband.oook.cz
Angband.oook.cz
AboutVariantsLadderForumCompetitionComicScreenshotsFunniesLinks

Go Back   Angband Forums > Angband > Development

Reply
 
Thread Tools Display Modes
Old December 17, 2016, 08:17   #1
Derakon
Prophet
 
Derakon's Avatar
 
Join Date: Dec 2009
Posts: 8,020
Derakon is on a distinguished road
Easier keymaps

Okay, I guess I'm at least exploring the feasibility of this.

The goal is that, when the player selects an item from their inventory, one of the options (alongside drop, throw, use, etc.) is "Set Hotkey". When selected, the player is prompted for a key to bind to the item, and a keymap is created that uses the item (as per its default interaction) when pressed.

Doing this properly requires two things: first, the basic UI, and second, the ability to select an item based on its name rather than the slot it is in or the inscription it has. The UI in principle should be straightforward, I think; there's already UI for creating keymaps, so this would just be an alternate approach to the same. As for selecting items based on name, I think what needs to happen is that we create a "control code" that can be intercepted whenever the player is prompted for a menu selection, and which lets them type in a string which is matched against the items in the menu. For example, if the control code character is @, then typing "@Phase" and hitting Enter should select Phase Door scrolls, assuming that the entered string is not ambiguous. If it is ambiguous, simplest thing to do is just to error out.

Once this works, the next step is to also allow it for spellbooks. I'm honestly not entirely sure what the best way to go about doing that is. We currently have two different commands for interacting with spellbook contents. We could add a third command; that feels kind of clunky though. We could make it so holding Shift while selecting a spell becomes the "create hotkey" for spells, but that's hacky. Opinions?
Derakon is offline   Reply With Quote
Old December 17, 2016, 14:02   #2
t4nk
Adept
 
Join Date: May 2016
Posts: 249
t4nk is on a distinguished road
Doing it with keymaps will be a mess. Consider implemening ui-hotkey.c instead, unrelated to keymaps. Briefly:

1) ui-knowledge.c has do_cmd_inven(), do_cmd_equip() and do_cmd_quiver() ('i', 'e' and '|' commands)
2) it calls context_menu_object() in ui-context.c, which displays menu where you want to insert the "Hotkey" entry
3) ui-hotkey.c could have something like:
Code:
struct hotkey {
    struct keypress key;

    int tval;
    int sval;

    int cmd; /* USE_INVEN, USE_EQUIP, USE_QUIVER */

    char *substr;    /* selecting using substrings */
    int target;      /* for aiming ammo/spells */
    int spell_index; /* if that's a spell */

    /* something else? */
};
4) context_menu_object() already has the object (so it has tval and sval). It should ask the user necessary questions (based on what kind of object that is) and create the hotkey. E.g., you can determine that an object is a book by calling obj_can_cast_from() (obj-util.c); spell_index can be obtained by calling textui_get_spell_from_book() (ui-spell.c). Also see do_cmd_use() in cmd-obj.c; most items are easy to handle. The context menu doesn't have working command (USE_INVEN/EQUIP), but do_cmd_inven/equip() do.

5) A reasonable place to check if a key is a hotkey is in textui_process_command (ui-game.c). Line 291 looks like a decent place to me.
Code:
if (do_hotkey(event)) {
    return;
}
6) Hotkey code eventually does something along the lines of:
Code:
struct hotkey *hk = hotkey_find(event);

if (hk != NULL) {  
    if (hk->spell_index != -1) {
        cmdq_push(CMD_CAST);
        cmd_set_arg_choice(cmdq_peek(), "spell", hk->spell_index);
        
        if (hk->target != 0) {
            int dir = /* see textui_get_aim_dir() (ui-input.c) */
            cmd_set_arg_target(cmdq_peek(), "target", dir);
        }
    } else {
        struct object *obj = NULL;
        
        if (hk->substr != NULL) {
           obj = /* find by substring */;
        } else {
           obj = /* find by tval/sval */
        }

        if (obj == NULL) {
             /* scroll got burned or something */
             return;
        }

        if (do_cmd_useable(obj)) {
             /* do_cmd_useable() is a fictional function;
                see do_cmd_use() (cmd-obj.c) */
        } else if (hk->cmd == USE_INVEN && obj_can_wear(obj)) {
             /* and so on */
        }
    }
}
Stuff like that... cmd-core.c, cmd-obj.c and obj-util.c have necessary functions/examples.

edit: typos.

Last edited by t4nk; December 17, 2016 at 15:02.
t4nk is offline   Reply With Quote
Old December 17, 2016, 14:56   #3
fph
Knight
 
Join Date: Apr 2009
Location: Berlin / Italy
Posts: 564
fph is on a distinguished road
I think this would be a great improvement to the game!

Have you considered making your UI "verb-object" rather than "object-verb"? I mean, press the "create hotkey" key -> prompt for key to bind -> prompt to select an object -> if object is a spellbook, further prompt to select a spell in it.

This change would also solve another problem, which is: for actions that need a target (spells and projectiles), you probably want to have two or three hotkeyable variants: "cast spell, prompt me for target", "cast spell to the closest target", "cast spell to the already-set target".
__________________
Dive fast, die young, leave a high-CHA corpse.
--
You read a scroll labeled 'lol gtfo' of Teleport Level.
fph is offline   Reply With Quote
Old December 17, 2016, 16:44   #4
Derakon
Prophet
 
Derakon's Avatar
 
Join Date: Dec 2009
Posts: 8,020
Derakon is on a distinguished road
Thanks for the pointers in the code! It would have taken me probably a couple of hours to reconstruct that, so you've saved me much time.

Quote:
Doing it with keymaps will be a mess. Consider implemening ui-hotkey.c instead, unrelated to keymaps.
Why do you say that? Ultimately the purpose of this system is to change the meaning of one of the keys, and keymaps would seem to be exactly the right way to do this. What benefit does a dedicated hotkey system have, and how would it interact with keymaps?

Quote:
Originally Posted by fph
Have you considered making your UI "verb-object" rather than "object-verb"? I mean, press the "create hotkey" key -> prompt for key to bind -> prompt to select an object -> if object is a spellbook, further prompt to select a spell in it.

This change would also solve another problem, which is: for actions that need a target (spells and projectiles), you probably want to have two or three hotkeyable variants: "cast spell, prompt me for target", "cast spell to the closest target", "cast spell to the already-set target".
It sounds like you're suggesting a "recorder" system where you can input keymaps while playing the game. I definitely think this is a good idea for the more complicated keymaps where you want to integrate targeting, but it's also simply a different project. My goal is to create a discoverable way to simplify input for players who are inexperienced with the game. In order to be discoverable, it shouldn't require new commands, which is why I mentioned specifically that the "Add Hotkey" option should show up when the player selects an item from their inventory.

That said, I'd love to see someone add such a recorder.
Derakon is offline   Reply With Quote
Old December 17, 2016, 19:21   #5
t4nk
Adept
 
Join Date: May 2016
Posts: 249
t4nk is on a distinguished road
Quote:
Originally Posted by Derakon View Post
Why do you say that? Ultimately the purpose of this system is to change the meaning of one of the keys, and keymaps would seem to be exactly the right way to do this. What benefit does a dedicated hotkey system have, and how would it interact with keymaps
Keymaps are just one half of what you talked about; another one is inscriptions. You'll need to determine what command the item works with ('i', 'm', 't', etc - for both keysets); the substring stuff will require adding an inscription (where else are you going to store the substring? and it will be a pretty long one, to distinguish between, e.g., "a Dagger (1d4) (+0, +0)" and "a Dagger (1d4) (+0, +1)"; after getting the item by substring you'll need to manupulate game's command queue to actually use it anyway; are you going to keep track of which items already have inscriptions? (for example, a book in inventory has "@m1", a book in home has "@m2", a book on the floor has "@m3" - what kind of inscription should be added to a uninscribed book number four?
Note that inscriptions are just a quick hack, a workaround for problems with inventory reordering. See for yourself: inscriptions are handled in get_tag() (ui-object.c) and in menu code (ui-menu.c, get_cursor_key():478).

Anyway, do what you want. You asked for opinions: that was my opinion.
t4nk is offline   Reply With Quote
Old December 17, 2016, 21:12   #6
Derakon
Prophet
 
Derakon's Avatar
 
Join Date: Dec 2009
Posts: 8,020
Derakon is on a distinguished road
I see, thanks for the explanation. I wasn't trying to challenge your statement, just understand it.

I'm not planning to automatically add inscriptions to items; rather the plan is to add the ability to address a specific item in a keymap without needing the item to be inscribed.

As for determining the command to use, if you look at the menu that comes up when you select an item from your inventory (hit 'i', scroll to an item, hit enter), the second item in the menu after 'I'nspect is always the default use command for the item. So the game clearly knows what the most appropriate action for an item is; I'll just piggyback on that logic.
Derakon is offline   Reply With Quote
Old December 18, 2016, 01:09   #7
takkaria
Veteran
 
takkaria's Avatar
 
Join Date: Apr 2007
Posts: 1,827
Donated: $40
takkaria is on a distinguished road
Quote:
Originally Posted by t4nk View Post
Doing it with keymaps will be a mess. Consider implemening ui-hotkey.c instead, unrelated to keymaps. Briefly:
I think this looks pretty sound, and is the kind of implementation I was imagining would be possible with the command system that Angband now has, and was part of the motivation for introducing the command system in the first place. For clarification, the command system is where the game has an internal representation of commands that is not just simply keypresses.

Storing the information about what a key is meant to do using the kind of structure t4nk proposes here ('struct hotkey') is just better, I think, than encoding the information into a string. Part of it is aesthetic, but part of it is that you're representing a command in a form you can do useful things with. For example, you can write "Quaff a potion of Cure Light Wounds" instead of "q@Cure Light\n". You could also have a terminal that lists hotkeys and their actions and greys them out if you run out of that item, because it can tell in advance whether the relevant item is present or not. It's also keyset-agnostic, so you can make hotkeys that do the right thing regardless of any key remappings the player might have done.
__________________
"Physician, heal thyself."
takkaria is offline   Reply With Quote
Old December 18, 2016, 16:50   #8
Derakon
Prophet
 
Derakon's Avatar
 
Join Date: Dec 2009
Posts: 8,020
Derakon is on a distinguished road
Well, working on this is on hold as my desktop appears to have a corrupt disk and can't boot. Joy...
Derakon is offline   Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Is it easier to find the Rings of Power now? Bilbo Vanilla 7 June 30, 2010 04:21
Feature Req: Easier Hotkeying Napsterbater Vanilla 0 October 7, 2009 00:12
Make choosing wielded equipment easier Taha Vanilla 4 August 8, 2009 10:17
How To: Make permanent walls purple for easier vault clearing Zero Vanilla 4 August 6, 2008 22:13
Easier autoinscribe ekolis Vanilla 1 July 13, 2007 21:58


All times are GMT +1. The time now is 02:49.


Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2017, vBulletin Solutions, Inc.