To implement your own keyboard command, or override an existing one implemented by the engine, use a hook like so:

hook(hook.KEYPRESS, function(key) 
        if key ~= strbyte('T') then
                return
        end

        local throw_tester = function(item)
                return item.flags[FLAG_ON_THROW] ~= nil
        end

        local ret, item = get_item("Throw which item?", "You have nothing to throw.",
                                   USE_INVEN | USE_FLOOR, throw_tester, 'T')
        if not ret then
                return true
        end
        local object = get_object(item)

        local max_range = object.flags[FLAG_RANGE] or 12
        local dir
        ret, dir = get_aim_dir({max_range = max_range})

        if not ret then
                return true
        end

        local func = get_function_registry_from_flag(object.flags, FLAG_ON_THROW)
        if not func(object, dir) then
                energy_use = get_player_energy(SPEED_FIRE)

                item_increase(item, -1)
                item_describe(item)
                item_optimize(item)
        end

        return true
end)

This example command, which implements throwing grenades and setting other explosives in E-Team, will allow the player to use shift-T to throw any object on the floor beneath him or in his inventory, as long as it has the ON_THROW flag. The maximum range the player can throw the object is 12 unless the object has the RANGE flag set.

If the player successfully chooses an item and a target, the hook then calls the function assumed to be stored in that ON_THROW flag, giving it arguments of the object and the target (for use in a later project call, for example). When throwing, the player uses energy as appropriate for his FIRE speed.

Note that returning nothing means the key was not handled, returning true tells the engine the key was handled.

Chatter

RavenRed: Nice, Neil. This will allow for a lof of customisation. Where does this hook get put? Anywhere where it gets loaded?

NeilStevens: Anywhere in scripts/ should do, dependent of course only on it needing anything it uses to be already loaded.

DarkGod: Actually no, the loading order only matters for things done in the global scope. If you do something like:

test.a = 5

make_new_shiny_test(test.a)

Then yes test.a needs to be defined before the second line. However if you do:

hook(hook.GAME_START, function()
  make_new_shiny_test(test.a)
end)

test.a = 5

It will work because the parsing checks syntax validity, but not symbols and such, as lua is completly dynamic.

Module Developers Discussion/Module Writing How-To Guides/How to write your own command (last edited 2006-12-04 09:27:16 by DarkGod)