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

237 lines
4.5 KiB
Lua
Raw Permalink Normal View History

2017-03-05 19:34:59 +02:00
require "fmt"
stead.proxy_prefix = '   '
local function proxy_wrap(nam, fwd)
if not fwd then fwd = nam end
return function(s, ...)
local t
2017-03-05 19:34:59 +02:00
local o = _(s.ref)
local act = s.acts or { }
2019-03-23 18:32:05 +02:00
local par = { ... }
act = act[nam] or nam
2019-03-23 18:32:05 +02:00
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))
2017-03-05 19:34:59 +02:00
t = std.par(std.scene_delim, t or false, r)
if v == false then
return t or r, true
end
if nam == 'use' then
2019-03-23 18:32:05 +02:00
r, v = std.call(par[1], s.acts.used or 'used', o)
2017-03-05 19:34:59 +02:00
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
2019-03-23 18:32:05 +02:00
r, v = std.call(o, act, std.unpack(par))
2017-03-05 19:34:59 +02:00
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
2019-03-23 18:32:05 +02:00
r, v = std.call(std.game, 'after_'..act, o, std.unpack(par))
2017-03-05 19:34:59 +02:00
t = std.par(std.scene_delim, t or false, r)
2019-03-23 18:32:05 +02:00
else -- game action
r, v = std.call(game, act, o, std.unpack(par))
2017-03-05 19:34:59 +02:00
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)
2019-03-23 18:32:05 +02:00
local d = std.dispof(o)
if type(d) ~= 'string' then
return d
end
2017-03-05 19:34:59 +02:00
if have(o) then
2019-03-23 18:32:05 +02:00
return stead.proxy_prefix..fmt.em(d)
2017-03-05 19:34:59 +02:00
end
2019-03-23 18:32:05 +02:00
return stead.proxy_prefix..d
2017-03-05 19:34:59 +02:00
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
2019-03-23 18:32:05 +02:00
if not v.nam then
v.nam = 'menu_player'
end
2017-03-05 19:34:59 +02:00
if not v.room then
v.room = 'main'
end
v.invent = std.list {}
return std.player(v)
2017-03-05 19:34:59 +02:00
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
2017-03-05 19:34:59 +02:00
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
2017-03-05 19:34:59 +02:00
std.mod_init(function() -- declarations
declare 'proxy_obj' (proxy_obj)
declare 'proxy_menu' (proxy_menu)
2017-03-05 19:34:59 +02:00
end)
2019-03-23 18:32:05 +02:00
std.mod_step(function(state)
if not state then
return
end
2017-03-05 19:34:59 +02:00
me().obj:for_each(function(v)
if v:type 'proxy_menu' then
v:fill()
end
end)
end)