Skip to content
Snippets Groups Projects
Commit a581ee6a authored by dg's avatar dg
Browse files

key binder

git-svn-id: http://svn.net-core.org/repos/t-engine4@236 51575b47-30f0-44d4-a5cc-537603b46e54
parent 53a085ed
No related branches found
No related tags found
No related merge requests found
......@@ -2,13 +2,13 @@ defineAction{
default = { "uni:i", },
type = "SHOW_INVENTORY",
group = "inventory",
name = "shows inventory",
name = "Show inventory",
}
defineAction{
default = { "uni:e", },
type = "SHOW_EQUIPMENT",
group = "inventory",
name = "shows equipment",
name = "Show equipment",
}
defineAction{
......@@ -28,18 +28,18 @@ defineAction{
default = { "uni:w", },
type = "WEAR_ITEM",
group = "inventory",
name = "wield/wear items",
name = "Wield/wear items",
}
defineAction{
default = { "uni:t", },
type = "TAKEOFF_ITEM",
group = "inventory",
name = "takeoff items",
name = "Takeoff items",
}
defineAction{
default = { "uni:u", },
type = "USE_ITEM",
group = "inventory",
name = "use items",
name = "Use items",
}
......@@ -121,18 +121,21 @@ function _M:drawHBorder(s, x, y, h)
end
end
function _M:drawSelectionList(s, x, y, hskip, list, sel, prop, scroll, max)
function _M:drawSelectionList(s, x, y, hskip, list, sel, prop, scroll, max, color, selcolor)
selcolor = selcolor or {0,255,255}
color = color or {255,255,255}
scroll = scroll or 1
max = max or 99999
for i = scroll, math.min(#list, scroll + max - 1) do
v = list[i]
if prop then v = tostring(v[prop])
if prop and type(v[prop]) == "string" then v = tostring(v[prop])
elseif prop and type(v[prop]) == "function" then v = tostring(v[prop](v))
else v = tostring(v) end
if sel == i then
s:drawColorString(self.font, v, x, y + (i-scroll) * hskip, 0, 255, 255)
s:drawColorString(self.font, v, x, y + (i-scroll) * hskip, selcolor[1], selcolor[2], selcolor[3])
else
s:drawColorString(self.font, v, x, y + (i-scroll) * hskip)
s:drawColorString(self.font, v, x, y + (i-scroll) * hskip, color[1], color[2], color[3])
end
end
end
......@@ -8,13 +8,16 @@ module(..., package.seeall, class.inherit(engine.KeyCommand))
_M.binds_def = {}
_M.binds_remap = {}
_M.binds_loaded = {}
_M.bind_order = 1
function _M:defineAction(t)
assert(t.default, "no keybind default")
assert(t.name, "no keybind name")
t.desc = t.desc or t.name
t.order = _M.bind_order
_M.binds_def[t.type] = t
_M.bind_order = _M.bind_order + 1
end
--- Loads a list of keybind definitions
......@@ -51,11 +54,51 @@ function _M:loadRemap(file)
end
end
--- Saves a keybinds remap
function _M:saveRemap(file)
local restore = false
if not file then
restore = fs.getWritePath()
fs.setWritePath(engine.homepath)
file = "keybinds.cfg"
end
local f = fs.open(file, "w")
for virtual, keys in pairs(_M.binds_remap) do
if keys[1] and not keys[2] then
f:write(("%s = {%q,nil}\n"):format(virtual, keys[1]))
elseif not keys[1] and keys[2] then
f:write(("%s = {nil,%q}\n"):format(virtual, keys[2]))
elseif keys[1] and keys[2] then
f:write(("%s = {%q,%q}\n"):format(virtual, keys[1], keys[2]))
elseif not keys[1] and not keys[2] then
f:write(("%s = {nil,nil}\n"):format(virtual))
end
end
f:close()
if restore then
fs.setWritePath(restore)
end
end
--- Returns the binding table for the given type
function _M:getBindTable(type)
return _M.binds_remap[type.type] or type.default
end
function _M:init()
engine.KeyCommand.init(self)
self.virtuals = {}
self.binds = {}
self:bindKeys()
end
--- Binds all virtuals to keys, either defaults or remapped ones
function _M:bindKeys()
self.binds = {}
-- Bind defaults
for type, t in pairs(_M.binds_def) do
for i, ks in ipairs(_M.binds_remap[type] or t.default) do
......@@ -70,7 +113,7 @@ end
function _M:receiveKey(sym, ctrl, shift, alt, meta, unicode)
local ks, us = self:makeKeyString(sym, ctrl, shift, alt, meta, unicode)
print("[BIND]", sym, ctrl, shift, alt, meta, unicode, " :=: ", ks, us, " ?=? ", self.binds[ks], us and self.binds[us])
-- print("[BIND]", sym, ctrl, shift, alt, meta, unicode, " :=: ", ks, us, " ?=? ", self.binds[ks], us and self.binds[us])
if self.binds[ks] and self.virtuals[self.binds[ks]] then
self.virtuals[self.binds[ks]](sym, ctrl, shift, alt, meta, unicode)
return
......
require "engine.class"
require "engine.Dialog"
module(..., package.seeall, class.inherit(engine.Dialog))
function _M:init(actions)
self:generateList(actions)
engine.Dialog.init(self, "Game Menu", 300, #self.list * 30 + 20)
self.sel = 1
self.scroll = 1
self.max = math.floor((self.ih - 5) / self.font_h) - 1
self:keyCommands({
__TEXTINPUT = function(c)
if c:find("^[a-z]$") then
self.sel = util.bound(1 + string.byte(c) - string.byte('a'), 1, #self.list)
self:use()
end
end,
},{
MOVE_UP = function() self.sel = util.boundWrap(self.sel - 1, 1, #self.list) self.scroll = util.scroll(self.sel, self.scroll, self.max) self.changed = true end,
MOVE_DOWN = function() self.sel = util.boundWrap(self.sel + 1, 1, #self.list) self.scroll = util.scroll(self.sel, self.scroll, self.max) self.changed = true end,
ACCEPT = function() self:use() end,
EXIT = function() game:unregisterDialog(self) end,
})
self:mouseZones{
{ x=2, y=5, w=350, h=self.font_h*self.max, fct=function(button, x, y, xrel, yrel, tx, ty)
self.sel = util.bound(self.scroll + math.floor(ty / self.font_h), 1, #self.list)
if button == "left" then self:use()
elseif button == "right" then
end
end },
}
end
function _M:use()
self.list[self.sel].fct()
end
function _M:generateList(actions)
local default_actions = {
resume = { "Resume", function() game:unregisterDialog(self) end },
keybinds = { "Key Bindings", function()
game:unregisterDialog(self)
local menu = require("engine.dialogs.KeyBinder").new(game.normal_key)
game:registerDialog(menu)
end },
save = { "Save Game", function() game:saveGame() end },
quit = { "Save and Exit", function() game:onQuit() end },
}
-- Makes up the list
local list = {}
local i = 0
for _, act in ipairs(actions) do
if type(act) == "string" then
local a = default_actions[act]
list[#list+1] = { name=string.char(string.byte('a') + i)..") "..a[1], fct=a[2] }
i = i + 1
else
local a = act
list[#list+1] = { name=string.char(string.byte('a') + i)..") "..a[1], fct=a[2] }
i = i + 1
end
end
self.list = list
end
function _M:drawDialog(s)
self:drawSelectionList(s, 2, 5, self.font_h, self.list, self.sel, "name", self.scroll, self.max)
end
require "engine.class"
require "engine.Dialog"
local KeyBind = require "engine.KeyBind"
module(..., package.seeall, class.inherit(engine.Dialog))
function _M:init(key_source)
engine.Dialog.init(self, "Key bindings", 600, game.h / 1.2)
self:generateList(key_source)
self.key_source = key_source
self.selcol = 1
self.sel = 1
self.scroll = 1
self.max = math.floor((self.ih - 5) / self.font_h) - 1
self:keyCommands({
},{
MOVE_UP = function() self.sel = util.boundWrap(self.sel - 1, 1, #self.list) self.scroll = util.scroll(self.sel, self.scroll, self.max) self.changed = true end,
MOVE_DOWN = function() self.sel = util.boundWrap(self.sel + 1, 1, #self.list) self.scroll = util.scroll(self.sel, self.scroll, self.max) self.changed = true end,
MOVE_LEFT = function() self.selcol = util.boundWrap(self.selcol - 1, 1, 2) self.changed = true end,
MOVE_RIGHT = function() self.selcol = util.boundWrap(self.selcol + 1, 1, 2) self.changed = true end,
ACCEPT = function() self:use() end,
EXIT = function()
game:unregisterDialog(self)
self.key_source:bindKeys()
KeyBind:saveRemap()
end,
})
self:mouseZones{
{ x=2, y=5, w=350, h=self.font_h*self.max, fct=function(button, x, y, xrel, yrel, tx, ty)
self.sel = util.bound(self.scroll + math.floor(ty / self.font_h), 1, #self.list)
if button == "left" then self:use()
elseif button == "right" then
end
end },
}
end
function _M:use()
local t = self.list[self.sel]
--
-- Make a dialog to ask for the key
--
local title = "Press a key (or escape) for: "..t.name
local font = self.font
local w, h = font:size(title)
local d = engine.Dialog.new(title, w + 8, h + 25, nil, nil, nil, font)
d:keyCommands{__DEFAULT=function(sym, ctrl, shift, alt, meta, unicode)
-- Modifier keys are not treated
if sym == KeyBind._LCTRL or sym == KeyBind._RCTRL or
sym == KeyBind._LSHIFT or sym == KeyBind._RSHIFT or
sym == KeyBind._LALT or sym == KeyBind._RALT or
sym == KeyBind._LMETA or sym == KeyBind._RMETA then
return
end
if sym == KeyBind._BACKSPACE then
t["bind"..self.selcol] = nil
KeyBind.binds_remap[t.type] = KeyBind.binds_remap[t.type] or t.k.default
KeyBind.binds_remap[t.type][self.selcol] = nil
elseif sym ~= KeyBind._ESCAPE then
local ks = KeyBind:makeKeyString(sym, ctrl, shift, alt, meta, unicode)
print("Binding", t.name, "to", ks)
t["bind"..self.selcol] = ks
KeyBind.binds_remap[t.type] = KeyBind.binds_remap[t.type] or t.k.default
KeyBind.binds_remap[t.type][self.selcol] = ks
end
game:unregisterDialog(d)
end}
d.drawDialog = function(self, s)
s:drawColorStringCentered(self.font, self.selcol == 1 and "Bind key" or "Bind alternate key", 2, 2, self.iw - 2, self.ih - 2)
end
game:registerDialog(d)
end
function _M:formatKeyString(ks)
if not ks then return "--" end
if ks:find("^uni:") then
return ks:sub(5)
else
local i, j, sym, ctrl, shift, alt, meta = ks:find("^sym:([0-9]+):([a-z]+):([a-z]+):([a-z]+):([a-z]+)$")
if not i then return "--" end
ctrl = ctrl == "true" and true or false
shift = shift == "true" and true or false
alt = alt == "true" and true or false
meta = meta == "true" and true or false
sym = tonumber(sym) or sym
sym = KeyBind.sym_to_name[sym] or sym
sym = sym:gsub("^_", "")
if ctrl then sym = "[ctrl]+"..sym end
if shift then sym = "[shift]+"..sym end
if alt then sym = "[alt]+"..sym end
if meta then sym = "[meta]+"..sym end
return sym
end
end
function _M:generateList(key_source)
local l = {}
for virtual, t in pairs(KeyBind.binds_def) do
if key_source.virtuals[virtual] then
l[#l+1] = t
end
end
table.sort(l, function(a,b)
if a.group ~= b.group then
return a.group < b.group
else
return a.order < b.order
end
end)
-- Makes up the list
local list = {}
local i = 0
for _, k in ipairs(l) do
local binds = KeyBind:getBindTable(k)
list[#list+1] = {
k = k,
name = k.name,
type = k.type,
bind1 = binds[1],
bind2 = binds[2],
b1 = function(v) return self:formatKeyString(v.bind1) end,
b2 = function(v) return self:formatKeyString(v.bind2) end,
}
i = i + 1
end
self.list = list
end
function _M:drawDialog(s)
local col = {155,155,0}
local selcol = {255,255,0}
self:drawSelectionList(s, 2, 5, self.font_h, self.list, self.sel, "name", self.scroll, self.max)
self:drawSelectionList(s, 200, 5, self.font_h, self.list, self.sel, "b1", self.scroll, self.max, col, self.selcol == 1 and selcol or col)
self:drawSelectionList(s, 400, 5, self.font_h, self.list, self.sel, "b2", self.scroll, self.max, col, self.selcol == 2 and selcol or col)
end
......@@ -453,6 +453,11 @@ function _M:setupCommands()
self.gfxmode = util.boundWrap(self.gfxmode + 1, 1, 3)
self:setupDisplayMode()
end,
EXIT = function()
local menu = require("engine.dialogs.GameMenu").new{"resume", "keybinds", "save", "quit"}
self:registerDialog(menu)
end,
}
--[[
self.key:addCommands
......
local Talents = require("engine.interface.ActorTalents")
newEntity{
define_as = "BASE_NPC_VERMIN",
type = "nuisance", subtype = "vermins",
define_as = "BASE_NPC_WORM",
type = "vermin", subtype = "worms",
display = "w", color=colors.WHITE,
can_multiply = 2,
body = { INVEN = 10 },
......@@ -14,7 +14,7 @@ newEntity{
combat_armor = 1, combat_def = 1,
}
newEntity{ base = "BASE_NPC_VERMIN",
newEntity{ base = "BASE_NPC_WORM",
name = "white worm mass", color=colors.WHITE,
level_range = {1, 15}, exp_worth = 1,
rarity = 4,
......@@ -24,7 +24,7 @@ newEntity{ base = "BASE_NPC_VERMIN",
talents = resolvers.talents{ [Talents.T_CRAWL_POISON]=1 },
}
newEntity{ base = "BASE_NPC_VERMIN",
newEntity{ base = "BASE_NPC_WORM",
name = "green worm mass", color=colors.GREEN,
level_range = {2, 15}, exp_worth = 1,
rarity = 5,
......
......@@ -1344,6 +1344,12 @@ static int lua_fs_set_write_dir(lua_State *L)
return 0;
}
static int lua_fs_get_write_dir(lua_State *L)
{
lua_pushstring(L, PHYSFS_getWriteDir());
return 1;
}
static int lua_fs_get_home_path(lua_State *L)
{
lua_pushstring(L, TENGINE_HOME_PATH);
......@@ -1371,6 +1377,7 @@ static const struct luaL_reg fslib[] =
{"delete", lua_fs_delete},
{"list", lua_fs_list},
{"setWritePath", lua_fs_set_write_dir},
{"getWritePath", lua_fs_get_write_dir},
{"getPathSeparator", lua_fs_get_path_separator},
{"getRealPath", lua_fs_get_real_path},
{"getUserPath", lua_fs_get_user_path},
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment