1
0
Fork 0
mirror of https://gitlab.com/Oreolek/duel.git synced 2024-04-25 05:39:43 +03:00
duel/proxymenu.lua

237 lines
4.5 KiB
Lua
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

require "fmt"
stead.proxy_prefix = '   '
local function proxy_wrap(nam, fwd)
if not fwd then fwd = nam end
return function(s, ...)
local t
local o = _(s.ref)
local act = s.acts or { }
local par = { ... }
act = act[nam] or nam
if nam == 'use' then
local oo = par[1]
if oo:type 'proxy' then
oo = _(oo.ref)
par[1] = oo
end
end
local r, v = std.call(std.game, 'before_'..act, o, std.unpack(par))
t = std.par(std.scene_delim, t or false, r)
if v == false then
return t or r, true
end
if nam == 'use' then
r, v = std.call(par[1], s.acts.used or 'used', o)
t = std.par(std.scene_delim, t or false, r)
if v == true then
oo['__nr_used'] = (oo['__nr_used'] or 0) + 1
return t or r, true
end
end
r, v = std.call(o, act, std.unpack(par))
t = std.par(std.scene_delim, t or false, r)
if type(v) == 'boolean' then
o['__nr_'..act] = (o['__nr_'..act] or 0) + 1
end
if r ~= nil and v == false then -- deny
return t or r, true
end
if v then
r, v = std.call(std.game, 'after_'..act, o, std.unpack(par))
t = std.par(std.scene_delim, t or false, r)
else -- game action
r, v = std.call(game, act, o, std.unpack(par))
t = std.par(std.scene_delim, t or false, r)
end
return t or r, true
end
end
std.proxy_obj = std.class ({
__proxy_type = true;
new = function(s, v)
if type(v) ~= 'table' then
std.err ("Wrong argument to std.proxy_obj: "..std.tostr(v), 2)
end
if not v.ref then
std.err ("Wrong argument to std.proxy_obj (no ref attr): "..std.tostr(v), 2)
end
if v.use_mode then
v.__menu_type = false
end
v = std.obj (v)
return v
end;
disp = function(s)
local o = _(s.ref)
local d = std.dispof(o)
if type(d) ~= 'string' then
return d
end
if have(o) then
return stead.proxy_prefix..fmt.em(d)
end
return stead.proxy_prefix..d
end;
act = proxy_wrap ('act');
inv = proxy_wrap ('inv');
use = proxy_wrap ('use');
menu = proxy_wrap ('menu');
tak = proxy_wrap ('tak');
}, std.menu)
local function fill_obj(v, s)
if not v:visible() then
return nil, false -- do not do it recurse
end
if not v:type 'menu' and not std.is_system(v) then -- usual objects
-- add to proxy
local o = {
ref = std.nameof(v),
use_mode = s.use_mode,
sources = s.sources,
acts = s.acts,
}
s.obj:add(new(proxy_obj, o))
end
if v:closed() then
return nil, false -- do not do it recurse
end
end
std.proxy_menu = std.class ({
__proxy_menu_type = true;
new = function(s, v)
if type(v) ~= 'table' then
std.err ("Wrong argument to std.proxy_obj: "..std.tostr(v), 2)
end
if v.disp then
v.title = v.disp
v.disp = nil
end
return std.menu(v)
end;
disp = function(s)
local d
if s.title then
d = std.call(s, 'title')
else
d = std.dispof(s)
end
-- s:fill()
if not s:closed() then
return fmt.u(fmt.b(fmt.nb(d)))
else
return fmt.b(fmt.nb(d))
end
end;
menu = function(s) -- open/close
if not s:closed() then
s:close()
else
std.me().obj:for_each(function (v)
if v:type 'proxy_menu' and v ~= s then
v:close()
end
end)
s:open()
end
return false
end;
fill = function(s) -- fill prox
s:for_each(function(v)
delete(v) -- delete obj
end)
s.obj:zap()
-- by default -- all obj
local src = s.sources or { scene = true }
if src.inv then
me():inventory():for_each(function(v)
fill_obj(v, s)
end)
end
if src.scene then
std.here():for_each(function(v)
return fill_obj(v, s)
end)
end
if src.ways then
std.here().way:for_each(function(v)
fill_obj(v, s)
end)
end
end;
}, std.menu)
std.menu_player = std.class ({
__menu_player_type = true;
new = function(self, v)
if type(v) ~= 'table' then
std.err ("Wrong argument to std.menu_player: "..std.tostr(v), 2)
end
if not v.nam then
v.nam = 'menu_player'
end
if not v.room then
v.room = 'main'
end
v.invent = std.list {}
return std.player(v)
end;
inventory = function(s)
return s.invent
end;
}, std.player)
function proxy_obj(v)
local vv = {
ref = v.ref;
use_mode = v.use_mode;
sources = v.sources;
acts = v.acts;
}
return std.proxy_obj(vv)
end
function proxy_menu(v)
local vv = {
nam = v.nam;
disp = v.disp;
use_mode = v.use_mode;
sources = v.sources;
acts = v.acts;
}
return std.proxy_menu(vv):close()
end
std.mod_init(function() -- declarations
declare 'proxy_obj' (proxy_obj)
declare 'proxy_menu' (proxy_menu)
end)
std.mod_step(function(state)
if not state then
return
end
me().obj:for_each(function(v)
if v:type 'proxy_menu' then
v:fill()
end
end)
end)