steed/stead/stead.lua

2955 lines
54 KiB
Lua
Raw Normal View History

2009-09-24 20:31:39 +03:00
stead = {
2011-07-17 14:13:28 +03:00
version = "1.4.5",
api_version = "1.1.6", -- last version before 1.2.0
table = table,
2010-07-26 09:55:56 +03:00
delim = ',',
2010-11-01 14:35:08 +02:00
scene_delim = "^^",
string = string,
math = math,
2011-04-26 17:20:23 +03:00
ticks = get_ticks,
mouse_pos = mouse_pos,
2011-04-27 10:02:54 +03:00
menu_toggle = menu_toggle,
2011-07-17 14:49:11 +03:00
next = next,
2009-09-25 09:20:40 +03:00
io = io,
2010-06-05 12:56:55 +03:00
os = os,
2011-04-17 15:31:29 +03:00
readdir = readdir,
call_top = 0,
2011-07-17 14:13:28 +03:00
call_ctx = { txt = nil, self = nil },
2010-06-22 09:13:43 +03:00
-- functions = {}, -- code blocks
2010-01-21 10:17:05 +02:00
timer = function()
if type(timer) == 'table' and type(timer.callback) == 'function' then
return timer:callback();
end
return
end,
2010-01-23 18:02:22 +02:00
input = function(event, ...)
if type(input) ~= 'table' then
return
end
if event == 'kbd' then
if type(input.key) == 'function' then
2011-02-23 12:11:27 +02:00
return input:key(...); -- pressed, event
2010-01-23 18:02:22 +02:00
end
elseif event == 'mouse' then
if type(input.click) == 'function' then
2011-02-23 12:11:27 +02:00
return input:click(...); -- pressed, x, y, mb
2010-01-21 10:49:00 +02:00
end
end
2010-01-21 10:17:05 +02:00
return
end,
2010-06-25 15:53:17 +03:00
modules_ini = {},
module_init = function(f, ...)
if type(f) ~= 'function' then
error ("Wrong parameter to mod_init.", 2);
end
stead.table.insert(stead.modules_ini, f);
f();
end
2009-09-24 20:31:39 +03:00
}
2009-09-24 19:54:22 +03:00
instead = stead;
2010-06-25 15:53:17 +03:00
module_init = stead.module_init;
2010-01-14 16:26:19 +02:00
function stead.getcmd(str)
local a = {}
local n = 1
local cmd;
2010-11-05 07:57:43 +02:00
local i,k = stead.string.find(str, '[a-zA-Z0-9_]+');
2010-01-14 16:26:19 +02:00
if not i or not k then
cmd = str;
else
cmd = stead.string.sub(str, i, k);
end
2010-06-06 14:09:17 +03:00
stead.cmd = cmd
2010-01-14 16:26:19 +02:00
if cmd == 'load' or cmd == 'save' then
2011-07-25 22:47:05 +03:00
a[1] = stead.strip(stead.string.sub(str, k + 1));
2010-06-06 14:09:17 +03:00
stead.args = a;
2010-01-14 16:26:19 +02:00
return cmd, a
end
while i do
k = k + 1;
i,k = stead.string.find(str,'[^,]+', k);
if not i then
break
end
2011-07-25 22:47:05 +03:00
a[n] = stead.strip(stead.string.sub(str, i, k));
2010-01-14 16:26:19 +02:00
n = n + 1;
end
2010-06-06 14:09:17 +03:00
stead.args = a;
2010-01-14 16:26:19 +02:00
return cmd, a
end
2010-07-11 16:26:47 +03:00
stead.tostring = function(v)
if isCode(v) then
v = stead.string.format("code %q", stead.functions[v].code);
elseif type(v) == 'string' then
v = stead.string.format("%q", v);
elseif v == nil or type(v) == 'boolean' or type(v) == 'number' then
v = tostring(v);
2010-07-12 22:17:11 +03:00
elseif type(v) == 'table' and type(deref(v)) == 'string' then
v = deref(v);
2010-07-11 16:26:47 +03:00
else
v = nil
end
return v
end
2011-07-17 14:13:28 +03:00
stead.cctx = function()
return stead.call_ctx[stead.call_top];
2009-10-27 17:07:42 +02:00
end
2011-07-17 14:16:37 +03:00
stead.callpush = function(v, ...)
stead.call_top = stead.call_top + 1;
2011-07-17 14:13:28 +03:00
stead.call_ctx[stead.call_top] = { txt = nil, self = v, action = false };
2011-02-23 12:11:27 +02:00
args = {...};
arg1 = args[1]
arg2 = args[2]
arg3 = args[3]
arg4 = args[4]
arg5 = args[5]
arg6 = args[6]
arg7 = args[7]
arg8 = args[8]
arg9 = args[9]
2010-06-25 16:35:42 +03:00
-- dirty but clean and fast :)
2010-06-22 14:04:12 +03:00
self = v
2009-10-23 15:39:21 +03:00
end
2011-07-17 14:16:37 +03:00
stead.clearargs = function()
2010-06-28 07:48:57 +03:00
arg1 = nil
arg2 = nil
arg3 = nil
arg4 = nil
arg5 = nil
arg6 = nil
arg7 = nil
arg8 = nil
arg9 = nil
self = nil
2009-10-23 15:39:21 +03:00
end
2011-07-17 14:16:37 +03:00
stead.callpop = function()
2011-07-17 14:13:28 +03:00
stead.call_ctx[stead.call_top] = nil;
2010-07-17 16:27:53 +03:00
stead.call_top = stead.call_top - 1;
if stead.call_top < 0 then
error ("callpush/callpop mismatch")
end
2011-07-14 15:21:02 +03:00
stead.clearargs()
2010-07-17 16:27:53 +03:00
end
function pclr()
2011-07-17 14:13:28 +03:00
stead.cctx().txt = nil
2009-10-23 13:46:48 +03:00
end
2010-06-25 12:31:54 +03:00
stead.pclr = pclr
2009-10-23 13:46:48 +03:00
function pget()
2011-07-17 14:13:28 +03:00
return stead.cctx().txt;
2009-10-23 13:46:48 +03:00
end
2010-06-22 09:34:45 +03:00
stead.pget = pget
2011-07-17 14:16:37 +03:00
2009-10-23 13:46:48 +03:00
function p(...)
2010-05-19 20:31:39 +03:00
local i
2011-02-23 12:11:27 +02:00
local a = {...}
for i = 1, stead.table.maxn(a) do
2011-07-17 14:13:28 +03:00
stead.cctx().txt = stead.par('', stead.cctx().txt, tostring(a[i]));
2010-05-19 20:31:39 +03:00
end
2011-07-17 14:13:28 +03:00
stead.cctx().txt = stead.cat(stead.cctx().txt, ' ');
2010-03-20 07:10:12 +02:00
end
2010-06-22 09:34:45 +03:00
stead.p = p
2010-03-20 07:10:12 +02:00
function pr(...)
2009-10-23 13:46:48 +03:00
local i
2011-02-23 12:11:27 +02:00
local a = {...}
for i = 1, stead.table.maxn(a) do
2011-07-17 14:13:28 +03:00
stead.cctx().txt = stead.par('', stead.cctx().txt, tostring(a[i]));
2009-10-23 13:46:48 +03:00
end
end
2010-06-22 09:34:45 +03:00
stead.pr = pr
2009-10-23 13:46:48 +03:00
function pn(...)
2011-02-23 12:11:27 +02:00
p(...);
2011-07-17 14:13:28 +03:00
stead.cctx().txt = stead.par('', stead.cctx().txt,'^');
2009-10-23 13:46:48 +03:00
end
2010-06-22 09:34:45 +03:00
stead.pn = pn
2009-09-24 19:54:22 +03:00
-- merge strings with "space" as separator
2009-02-21 12:52:44 +02:00
function par(space,...)
local i, res
2011-02-23 12:11:27 +02:00
local a = {...};
for i = 1, stead.table.maxn(a) do
if type(a[i]) == 'string' then
2009-02-21 12:52:44 +02:00
if res == nil then
res = ""
else
res = res..space;
end
2011-02-23 12:11:27 +02:00
res = res..a[i];
2009-02-21 12:52:44 +02:00
end
end
return res;
end
2010-06-16 22:31:15 +03:00
stead.par = par
2009-02-21 12:52:44 +02:00
-- add to not nill string any string
function cat(v,...)
local i, res
if not v then
return nil
end
res = v;
2011-02-23 12:11:27 +02:00
local a = {...}
for i = 1, stead.table.maxn(a) do
if type(a[i]) == 'string' then
res = res..a[i];
2009-02-21 12:52:44 +02:00
end
end
return res;
end
2010-06-16 22:31:15 +03:00
stead.cat = cat;
2009-02-21 12:52:44 +02:00
2010-01-25 16:53:33 +02:00
function txtnb(v)
if type(v) ~= 'string' then return nil; end
return iface:nb(v);
end
function img(v)
2009-10-26 17:00:11 +02:00
if type(v) ~= 'string' then return nil; end;
return iface:img(v);
end
2010-10-30 15:54:41 +03:00
function imgl(v)
if type(v) ~= 'string' then return nil; end;
return iface:imgl(v);
end
function imgr(v)
if type(v) ~= 'string' then return nil; end;
return iface:imgr(v);
end
function txtem(v)
2009-10-26 17:00:11 +02:00
if type(v) ~= 'string' then return nil; end;
return iface:em(v)
end
2010-10-08 11:32:41 +03:00
function txtst(v)
if type(v) ~= 'string' then return nil; end;
return iface:st(v)
end
function txtr(v)
2009-10-26 17:00:11 +02:00
if type(v) ~= 'string' then return nil; end;
return iface:right(v)
end
function txtl(v)
2009-10-26 17:00:11 +02:00
if type(v) ~= 'string' then return nil; end;
return iface:left(v)
end
function txtc(v)
2009-10-26 17:00:11 +02:00
if type(v) ~= 'string' then return nil; end;
return iface:center(v)
end
2010-11-08 10:20:37 +02:00
function txttab(v,a)
return iface:tab(v, a)
2010-11-01 15:52:42 +02:00
end
2010-10-31 17:06:54 +02:00
function txtj(v)
if type(v) ~= 'string' then return nil; end;
return iface:just(v)
end
function txtb(v)
2009-10-26 17:00:11 +02:00
if type(v) ~= 'string' then return nil; end;
return iface:bold(v)
end
2009-02-21 12:52:44 +02:00
2009-09-10 21:24:31 +03:00
function txtu(v)
2009-10-26 17:00:11 +02:00
if type(v) ~= 'string' then return nil; end;
2009-09-10 21:24:31 +03:00
return iface:under(v)
end
2010-01-17 10:27:15 +02:00
function txtnm(n, v)
2010-01-17 10:13:00 +02:00
if type(v) ~= 'string' or not tonumber(n) then return nil; end
return iface:enum(n, v);
end
2010-09-02 11:03:06 +03:00
function txttop(v)
if type(v) ~= 'string' then return nil; end;
return iface:top(v)
end
function txtbottom(v)
if type(v) ~= 'string' then return nil; end;
return iface:bottom(v)
end
function txtmiddle(v)
if type(v) ~= 'string' then return nil; end;
return iface:middle(v)
end
2010-06-16 22:31:15 +03:00
fmt = function(...)
2009-02-21 12:52:44 +02:00
local i, res
2011-02-23 12:11:27 +02:00
local a = {...};
2011-02-23 13:02:19 +02:00
2011-02-23 12:11:27 +02:00
for i=1,stead.table.maxn(a) do
if type(a[i]) == 'string' then
local s = stead.string.gsub(a[i],'[\t ]+',' ');
s = stead.string.gsub(s, '[\n]+', ' ');
2010-11-04 14:46:25 +02:00
s = stead.string.gsub(s, '\\?[\\^]', { ['^'] = '\n', ['\\^'] = '^', ['\\\\'] = '\\'} );
2010-10-30 15:54:41 +03:00
res = stead.par('', res, s);
2009-02-21 12:52:44 +02:00
end
end
return res
end
2010-06-16 22:31:15 +03:00
stead.fmt = fmt
2009-08-26 08:25:53 +03:00
-- integer lists
2011-07-25 21:00:08 +03:00
local inext = function(t, k)
2009-08-26 08:25:53 +03:00
local v
2011-07-17 14:49:11 +03:00
k, v = stead.next(t, k);
2009-08-26 08:25:53 +03:00
while k and not tonumber(k) do
2011-07-17 14:49:11 +03:00
k, v = stead.next(t, k);
2009-08-26 08:25:53 +03:00
end
if not tonumber(k) then
return nil
end
return k, v
end
2011-07-25 21:00:08 +03:00
local ilist = function(s, var)
return inext, s, nil;
2009-08-26 08:25:53 +03:00
end
2011-07-25 21:00:08 +03:00
local ordered_i = function(t)
2009-08-26 08:25:53 +03:00
local ordered = {};
local i,v, max;
max = 0;
2011-07-25 21:00:08 +03:00
for i,v in ilist(t) do
stead.table.insert(ordered, i);
2009-08-26 08:25:53 +03:00
max = max + 1;
end
stead.table.sort(ordered);
2009-08-26 08:25:53 +03:00
ordered.i = 1;
ordered.max = max;
return ordered;
end
2011-07-25 21:00:08 +03:00
local onext = function(t, k)
2009-08-26 08:25:53 +03:00
local v
if not k then
2011-07-25 21:00:08 +03:00
k = ordered_i(t);
2009-08-26 08:25:53 +03:00
end
if k.i > k.max then
return nil
end
v = k[k.i]
k.i = k.i + 1
return k, t[v], v;
end
function opairs(s, var)
2011-07-25 21:00:08 +03:00
return onext, s, nil;
2009-08-26 08:25:53 +03:00
end
2009-02-21 12:52:44 +02:00
function isPlayer(v)
2009-09-22 07:27:49 +03:00
return (type(v) == 'table') and (v.player_type)
2009-02-21 12:52:44 +02:00
end
function isRoom(v)
2009-09-22 07:27:49 +03:00
return (type(v) == 'table') and (v.location_type)
2009-02-21 12:52:44 +02:00
end
function isPhrase(v)
2009-09-22 07:27:49 +03:00
return (type(v) == 'table') and (v.phrase_type)
2009-02-21 12:52:44 +02:00
end
function isDialog(v)
2009-09-22 07:27:49 +03:00
return (type(v) == 'table') and (v.dialog_type)
2009-02-21 12:52:44 +02:00
end
function isDisabled(v)
2009-09-22 07:27:49 +03:00
return (type(v) == 'table') and (v._disabled)
2009-02-21 12:52:44 +02:00
end
function isRemoved(v)
2009-09-22 07:27:49 +03:00
return (type(v) == 'table') and (v._disabled == -1)
2009-02-21 12:52:44 +02:00
end
function isObject(v)
2009-09-22 07:27:49 +03:00
return (type(v) == 'table') and (v.object_type)
2009-02-21 12:52:44 +02:00
end
2010-09-16 12:09:02 +03:00
function isXaction(v)
return (type(v) == 'table') and (v.xaction_type)
end
2009-02-21 12:52:44 +02:00
function obj_xref(self,str)
function xrefrep(str)
2010-10-30 15:54:41 +03:00
local s = stead.string.gsub(str,'[\001\002]','');
2009-08-26 08:25:53 +03:00
return xref(s, self);
2009-02-21 12:52:44 +02:00
end
if not str then
return
end
if not isObject(self) then
return str;
end
2010-11-04 14:46:25 +02:00
local s = stead.string.gsub(str, '\\?[\\{}]',
2011-03-24 12:43:52 +02:00
{ ['{'] = '\001', ['}'] = '\002', [ '\\{' ] = '{', [ '\\}' ] = '}' }):gsub('\001([^\002]+)\002', xrefrep):gsub('[\001\002]', { ['\001'] = '{', ['\002'] = '}' });
2009-02-21 12:52:44 +02:00
return s;
end
function obj_look(self)
2009-08-26 08:25:53 +03:00
local i, vv, o
2009-02-21 12:52:44 +02:00
if isDisabled(self) then
return
end
2011-07-27 13:21:20 +03:00
local v = stead.call(self,'dsc');
2009-02-21 12:52:44 +02:00
if game.hinting then
2010-01-17 20:00:44 +02:00
v = self:xref(v);
2009-02-21 12:52:44 +02:00
elseif v then
v = stead.string.gsub(v, '[{}]','');
2009-02-21 12:52:44 +02:00
end
2009-08-26 08:25:53 +03:00
for i,o in opairs(self.obj) do
o = ref(o);
if isObject(o) then
vv = obj_look(o);
2010-06-16 22:31:15 +03:00
v = stead.par(' ',v, vv);
2009-08-26 08:25:53 +03:00
end
2009-02-21 12:52:44 +02:00
end
return v;
end
function obj_remove(self)
self._disabled = -1;
2009-08-26 08:25:53 +03:00
return self
2009-02-21 12:52:44 +02:00
end
function obj_disable(self)
self._disabled = true;
2009-08-26 08:25:53 +03:00
return self
2009-02-21 12:52:44 +02:00
end
function obj_enable(self)
self._disabled = false;
2009-08-26 08:25:53 +03:00
return self
2009-02-21 12:52:44 +02:00
end
2010-07-11 13:35:47 +03:00
function obj_disabled(self)
return (self._disabled == true);
end
function obj_enable_all(s)
if not isObject(s) then
return
end
2010-07-07 15:41:48 +03:00
objs(s):enable_all();
end
function obj_disable_all(s)
if not isObject(s) then
return
end
2010-07-07 15:41:48 +03:00
objs(s):disable_all();
end
2009-02-21 12:52:44 +02:00
function obj_save(self, name, h, need)
local dsc;
if need then
2010-07-03 15:38:27 +03:00
print ("Warning: object "..name.." can not be saved!");
return
2009-02-21 12:52:44 +02:00
end
savemembers(h, self, name, need);
end
function obj_str(self)
2009-08-26 08:25:53 +03:00
local i, v, vv, o;
2009-09-17 20:38:27 +03:00
if not isObject(self) then
2009-02-21 12:52:44 +02:00
return
end
if isDisabled(self) then
return
end
2009-08-26 08:25:53 +03:00
for i,o in opairs(self.obj) do
o = ref(o);
2009-09-17 19:32:30 +03:00
if o~= nil and not isDisabled(o) then -- isObject is better, but compat layer must be ok
2011-07-27 13:21:20 +03:00
vv = stead.call(o, 'nam');
2009-08-26 08:25:53 +03:00
vv = xref(vv, o);
2010-06-16 22:31:15 +03:00
v = stead.par(',', v, vv, obj_str(o));
2009-02-21 12:52:44 +02:00
end
end
return v;
end
function obj(v)
if v.nam == nil then
if isRoom(v) then
if isDialog(v) then
error ("No dialog name in constructor.", 3);
end
error ("No room name in constructor.", 3);
end
error ("No object name in constructor.", 2);
2009-02-21 12:52:44 +02:00
end
2010-01-17 20:00:44 +02:00
v.object_type = true;
if v.xref == nil then
v.xref = obj_xref;
end
2009-02-21 12:52:44 +02:00
if v.look == nil then
v.look = obj_look;
end
if v.enable == nil then
v.enable = obj_enable;
end
if v.disable == nil then
v.disable = obj_disable;
end
2010-07-11 13:35:47 +03:00
if v.disabled == nil then
v.disabled = obj_disabled;
end
if v.enable_all == nil then
v.enable_all = obj_enable_all;
end
if v.disable_all == nil then
v.disable_all = obj_disable_all;
end
2009-02-21 12:52:44 +02:00
if v.remove == nil then
v.remove = obj_remove;
end
if v.obj == nil then
v.obj = {};
end
if v.srch == nil then
v.srch = obj_search;
end
if v.str == nil then
v.str = obj_str;
end
v.obj = list(v.obj);
if v.save == nil then
v.save = obj_save;
end
return v
end
2010-07-27 10:17:11 +03:00
function ref(n, nofunc) -- ref object by name
2009-02-21 12:52:44 +02:00
if type(n) == 'string' then
2010-09-16 12:09:02 +03:00
if type(_G[n]) == 'table' then -- fastest path
return _G[n];
end
2010-09-21 14:11:35 +03:00
local f = loadstring('return '..n);
2009-02-21 12:52:44 +02:00
if f then
2010-07-27 10:17:11 +03:00
return ref(f(), nofunc);
2009-02-21 12:52:44 +02:00
end
return nil;
end
if type(n) == 'table' then
return n;
end
2010-07-27 10:17:11 +03:00
if type(n) == 'function' and not nofunc then
2010-07-24 20:34:41 +03:00
local r,v = pcall(n);
if not r then
return nil
end
return ref(v);
2009-02-21 12:52:44 +02:00
end
return nil
end
2009-08-26 08:25:53 +03:00
function deref(n)
if type(n) == 'string' then
return n
end
if type(n) == 'table' and type(n.key_name) == 'string' then
return n.key_name
end
2009-10-15 19:16:13 +03:00
return n
2009-08-26 08:25:53 +03:00
end
function list_check(self, name)
2009-08-26 08:25:53 +03:00
local i, v, ii;
for i,v,ii in opairs(self) do
local o = ref(v);
if not o then -- isObject(o) then -- compat
error ("No object: "..tostring(v))
2009-02-21 12:52:44 +02:00
return false
end
2010-06-30 10:27:36 +03:00
if deref(v) then
2009-08-26 08:25:53 +03:00
self[ii] = deref(v);
2009-02-21 12:52:44 +02:00
end
end
return true;
end
function list_str(self)
2009-08-26 08:25:53 +03:00
local i, v, vv, o;
for i,o in opairs(self) do
o = ref(o);
if o~= nil and not isDisabled(o) then
2011-07-27 13:21:20 +03:00
vv = stead.call(o, 'nam');
2009-08-26 08:25:53 +03:00
vv = xref(vv, o);
2010-06-16 22:31:15 +03:00
v = stead.par(',', v, vv);
2009-02-21 12:52:44 +02:00
end
end
return v;
end
2009-08-26 08:25:53 +03:00
function list_add(self, name, pos)
local nam
nam = deref(name);
2009-09-07 12:03:03 +03:00
if self:look(nam) then
2009-02-21 12:52:44 +02:00
return nil
end
self.__modified__ = true;
2009-08-26 08:25:53 +03:00
if tonumber(pos) then
stead.table.insert(self, tonumber(pos), nam);
2009-08-26 08:25:53 +03:00
self[tonumber(pos)] = nam; -- for spare lists
else
stead.table.insert(self, nam);
2009-08-26 08:25:53 +03:00
end
return true
end
function list_set(self, name, pos)
local nam
local i = tonumber(pos);
if not i then
return nil
end
nam = deref(name);
self.__modified__ = true;
2009-08-26 08:25:53 +03:00
self[i] = nam; -- for spare lists
2009-02-21 12:52:44 +02:00
return true
end
function list_find(self, name)
2009-08-26 08:25:53 +03:00
local n, v, ii
for n,v,ii in opairs(self) do
2010-07-27 10:17:11 +03:00
if ref(v) == ref(name, true) then -- do not call func while search
2009-08-26 08:25:53 +03:00
return ii;
2009-02-21 12:52:44 +02:00
end
end
return nil
end
2010-07-07 15:41:48 +03:00
function list_disable_all(s)
local k,v
for k,v in opairs(s) do
local o = ref(v);
if isObject(o) then
o:disable()
end
end
end
function list_enable_all(s)
local k,v
for k,v in opairs(s) do
local o = ref(v);
if isObject(o) then
o:enable()
end
end
end
2009-02-21 12:52:44 +02:00
function list_save(self, name, h, need)
if self.__modifyed__ or self.__modified__ then -- compat
2009-02-21 12:52:44 +02:00
h:write(name.." = list({});\n");
need = true;
end
savemembers(h, self, name, need);
end
2010-06-22 16:19:39 +03:00
function list_name(self, name, dis)
2009-08-26 08:25:53 +03:00
local n, o, ii
for n,o,ii in opairs(self) do
o = ref(o);
if isObject(o) then
2011-07-27 13:21:20 +03:00
local nam = stead.call(o,'nam') ;
2010-06-22 16:19:39 +03:00
if ( not isDisabled(o) or dis ) and name == tostring(nam) then
2009-08-26 08:25:53 +03:00
return ii;
end
2009-02-21 12:52:44 +02:00
end
end
return nil
end
2010-06-14 11:10:59 +03:00
function list_id(self, id, dis)
2009-08-26 08:25:53 +03:00
local n,o,ii
for n,o,ii in opairs(self) do
o = ref(o);
2010-06-14 11:10:59 +03:00
if dis or not isDisabled(o) then
if isObject(o) and id == o.id then
return ii;
end
2009-02-21 12:52:44 +02:00
end
end
end
2010-06-14 11:10:59 +03:00
function list_search(self, n, dis)
2009-02-21 12:52:44 +02:00
local i;
2009-09-07 12:03:03 +03:00
i = self:look(n);
2009-02-21 12:52:44 +02:00
if not i then
2010-06-22 16:19:39 +03:00
i = self:name(n, dis);
2009-02-21 12:52:44 +02:00
end
if not i and tonumber(n) then
2010-06-14 11:10:59 +03:00
i = self:byid(tonumber(n), dis);
2009-02-21 12:52:44 +02:00
if not i then
return nil
end
end
2010-06-14 11:10:59 +03:00
if not dis and isDisabled(ref(self[i])) then
2009-02-21 12:52:44 +02:00
return nil;
end
return self[i], i;
end
function list_zap(self)
local n,o,ii
for n,o,ii in opairs(self) do
self[ii] = nil;
end
self.__modified__ = true
return self
end
function list_concat(self, other, pos)
local n,o,ii
for n,o,ii in opairs(other) do
o = ref(o);
if pos == nil then
self:add(deref(o));
else
self:add(deref(o), pos);
pos = pos + 1;
end
end
end
2009-02-21 12:52:44 +02:00
function list_del(self, name)
local v,n
2009-09-07 11:15:58 +03:00
v, n = self:srch(name);
2009-02-21 12:52:44 +02:00
if n == nil then
return nil;
end
self.__modified__ = true
v = stead.table.remove(self, n);
2009-08-26 08:25:53 +03:00
if not v then
v = self[n];
self[n] = nil -- for spare lists
end
return v
2009-02-21 12:52:44 +02:00
end
2010-07-07 16:33:46 +03:00
function list_purge(self, name)
local v,n
v, n = self:srch(name, true);
if n == nil then
return nil;
end
self.__modified__ = true
v = stead.table.remove(self, n);
if not v then
v = self[n];
self[n] = nil -- for spare lists
end
return v
end
2010-07-08 07:40:14 +03:00
function list_replace(self, name, name2)
2010-07-08 07:46:03 +03:00
local o, ii
o, ii = self:srch(name);
2010-07-08 07:40:14 +03:00
if ii then
self:set(name2, ii);
else
self:add(name2);
end
return ii;
end
2009-02-21 12:52:44 +02:00
function list(v)
2009-09-22 07:27:49 +03:00
v.list_type = true;
2009-02-21 12:52:44 +02:00
v.add = list_add;
2009-08-26 08:25:53 +03:00
v.set = list_set;
2009-09-05 08:23:51 +03:00
v.cat = list_concat;
v.zap = list_zap;
2009-02-21 12:52:44 +02:00
v.del = list_del;
2010-07-07 16:33:46 +03:00
v.purge = list_purge;
2010-07-08 07:40:14 +03:00
v.replace = list_replace;
2009-02-21 12:52:44 +02:00
v.look = list_find;
v.name = list_name;
v.byid = list_id;
v.srch = list_search;
v.str = list_str;
v.check = list_check;
v.save = list_save;
2010-07-07 15:41:48 +03:00
v.enable_all = list_enable_all;
v.disable_all = list_disable_all;
2009-02-21 12:52:44 +02:00
return v;
end
2009-09-22 07:27:49 +03:00
function isList(v)
return (type(v) == 'table') and (v.list_type == true)
end
2009-02-21 12:52:44 +02:00
function call(v, n, ...)
if type(v) ~= 'table' then
error ("Call on non table object:"..n, 2);
2009-02-21 12:52:44 +02:00
end
if v[n] == nil then
return nil,nil;
end
if type(v[n]) == 'string' then
return v[n];
2010-06-21 22:58:44 +03:00
end
2009-02-21 12:52:44 +02:00
if type(v[n]) == 'function' then
2011-07-14 15:21:02 +03:00
stead.callpush(v, ...)
2011-02-23 12:11:27 +02:00
local a,b = v[n](v, ...);
2010-06-22 12:52:40 +03:00
-- boolean, nil
if type(a) == 'boolean' and b == nil then
b, a = a, stead.pget()
2010-07-09 20:25:58 +03:00
if a == nil then
2011-07-17 14:13:28 +03:00
if stead.cctx().action then
2010-07-09 20:25:58 +03:00
a = true
else
a = b
b = nil
end
2010-06-22 12:52:40 +03:00
end
2010-06-22 12:00:29 +03:00
elseif a == nil and b == nil then
2010-06-22 09:34:45 +03:00
a = stead.pget()
b = nil
2009-10-23 13:46:48 +03:00
end
2011-07-17 14:13:28 +03:00
if a == nil and b == nil and stead.cctx().action then
2010-07-04 18:43:39 +03:00
a = true
end
2011-07-14 15:21:02 +03:00
stead.callpop()
2009-10-23 13:46:48 +03:00
return a,b
2009-02-21 12:52:44 +02:00
end
2010-03-16 09:32:09 +02:00
if type(v[n]) == 'boolean' then
return v[n]
end
error ("Method not string nor function:"..tostring(n), 2);
2009-02-21 12:52:44 +02:00
end
2011-07-27 13:21:20 +03:00
stead.call = call
2009-02-21 12:52:44 +02:00
2009-10-15 08:36:22 +03:00
function call_bool(v, n, ...)
if type(v) ~= 'table' then
error ("Call bool on non table object:"..n, 2);
2009-10-15 08:36:22 +03:00
end
if v[n] == nil then
return nil
end
if v[n] == false then
return false;
end
if type(v[n]) == 'function' then
2011-07-14 15:21:02 +03:00
stead.callpush(v, ...)
2011-02-23 12:11:27 +02:00
local r,v = v[n](v, ...);
2011-07-14 15:21:02 +03:00
stead.callpop();
2010-07-10 09:39:29 +03:00
return r,v;
2009-10-15 08:36:22 +03:00
end
return true; -- not nil
end
2011-07-27 13:21:20 +03:00
stead.call_bool = call_bool
2009-10-15 08:36:22 +03:00
2010-11-03 09:50:33 +02:00
function call_value(v, n, ...)
if type(v) ~= 'table' then
error ("Call value on non table object:"..n, 2);
end
if v[n] == nil then
return nil
end
if type(v[n]) ~= 'function' then
return v[n];
end
2011-07-14 15:21:02 +03:00
stead.callpush(v, ...)
2011-02-23 12:11:27 +02:00
local r,v = v[n](v, ...);
2011-07-14 15:21:02 +03:00
stead.callpop();
2010-11-03 09:50:33 +02:00
return r,v;
end
2011-07-27 13:21:20 +03:00
stead.call_value = call_value
2010-11-03 09:50:33 +02:00
2009-02-21 12:52:44 +02:00
function room_scene(self)
local v;
2011-07-27 13:21:20 +03:00
v = iface:title(stead.call(self,'nam'));
v = stead.par('^^', v, stead.call(self,'dsc')); --obj_look(self));
2010-06-16 22:31:15 +03:00
return stead.cat(v,' ');
2009-02-21 12:52:44 +02:00
end
function room_look(self)
2009-08-26 08:25:53 +03:00
local i, vv, o;
for i,o in opairs(self.obj) do
o = ref(o);
if isObject(o) then
2010-06-16 22:31:15 +03:00
vv = stead.par(' ',vv, o:look());
2009-08-26 08:25:53 +03:00
end
2009-02-21 12:52:44 +02:00
end
2010-06-16 22:31:15 +03:00
return stead.cat(vv,' ');
2009-02-21 12:52:44 +02:00
end
2010-06-14 11:10:59 +03:00
function obj_search(v, n, dis)
2009-02-21 12:52:44 +02:00
local i;
local o;
2010-06-14 11:10:59 +03:00
if not dis and isDisabled(v) then
2009-02-21 12:52:44 +02:00
return
end
2010-06-14 11:10:59 +03:00
o = v.obj:srch(n, dis);
2009-02-21 12:52:44 +02:00
if o then
return o, v;
end
2009-08-26 08:25:53 +03:00
for i,o in opairs(v.obj) do
o = ref(o);
if isObject(o) then
2010-06-14 11:10:59 +03:00
local r,rr = obj_search(o, n, dis);
2009-08-26 08:25:53 +03:00
if r then
return r, rr;
end
2009-02-21 12:52:44 +02:00
end
end
return;
end
function room_save(self, name, h, need)
local dsc;
if need then
2010-07-03 15:38:27 +03:00
print ("Warning: room "..name.." can not be saved!");
return
end
savemembers(h, self, name, need);
end
2009-02-21 12:52:44 +02:00
function room(v) --constructor
-- if v.nam == nil then
-- error ("No room name in constructor.", 2);
-- end
2009-02-21 12:52:44 +02:00
if v.scene == nil then
v.scene = room_scene;
end
if v.look == nil then
v.look = room_look;
end
if v.save == nil then
v.save = room_save;
end
2009-02-21 12:52:44 +02:00
v.location_type = true;
if v.way == nil then
v.way = { };
end
v.way = list(v.way);
v = obj(v);
return v;
end
function dialog_enter(self)
if not dialog_rescan(self) then
return nil, false
end
return nil, true
end
function dialog_scene(self)
2009-08-26 08:25:53 +03:00
local v
2011-07-27 13:21:20 +03:00
v = iface:title(stead.call(self,'nam'));
v = stead.par('^^', v, stead.call(self, 'dsc')); --obj_look(self));
2010-01-17 20:00:44 +02:00
return v;
2009-02-21 12:52:44 +02:00
end
function dialog_look(self)
2009-08-26 08:25:53 +03:00
local i,n,v,ph
n = 1
for i,ph in opairs(self.obj) do
ph = ref(ph);
if isPhrase(ph) and not isDisabled(ph) then
2010-06-16 22:31:15 +03:00
v = stead.par('^', v, txtnm(n, ph:look()));
2009-02-21 12:52:44 +02:00
n = n + 1
end
end
return v;
end
function dialog_rescan(self)
2009-08-26 08:25:53 +03:00
local i,k,ph
2009-02-21 12:52:44 +02:00
k = 1
2009-08-26 08:25:53 +03:00
for i,ph in opairs(self.obj) do
ph = ref(ph);
2009-02-21 12:52:44 +02:00
if isPhrase(ph) and not isDisabled(ph) then
ph.nam = tostring(k);
k = k + 1;
end
end
if k == 1 then
return false
end
return true
end
2010-10-30 15:54:41 +03:00
function dialog_empty(self)
return not dialog_rescan(self);
end
2009-02-21 12:52:44 +02:00
function dialog_phrase(self, num)
if not tonumber(num) then
2009-10-27 17:02:53 +02:00
if isPhrase(ref(num)) then
return ref(num);
end
2009-02-21 12:52:44 +02:00
return nil
end
return ref(self.obj[tonumber(num)]);
end
2010-07-23 14:31:52 +03:00
function phrase_seen(s, enb, ...)
local i, ph
2011-02-23 12:11:27 +02:00
local a = {...}
if stead.table.maxn(a) == 0 then
stead.table.insert(a, self);
2010-07-23 14:31:52 +03:00
end
2011-02-23 12:11:27 +02:00
for i=1,stead.table.maxn(a) do
ph = dialog_phrase(s, a[i]);
2010-07-23 14:31:52 +03:00
local r = not isPhrase(ph) or isRemoved(ph) or ph:disabled();
if not enb then r = not r end
if r then return false end
end
return true
end
function dialog_pseen(s, ...)
2011-02-23 12:11:27 +02:00
return phrase_seen(s, true, ...);
2010-07-23 14:31:52 +03:00
end
function dialog_punseen(s, ...)
2011-02-23 12:11:27 +02:00
return phrase_seen(s, false, ...);
2010-07-23 14:31:52 +03:00
end
2009-10-27 17:02:53 +02:00
function ponoff(s, on, ...)
2009-02-21 12:52:44 +02:00
local i, ph
2011-02-23 12:11:27 +02:00
local a = {...}
if stead.table.maxn(a) == 0 then
stead.table.insert(a, self);
2009-10-27 17:02:53 +02:00
end
2011-02-23 12:11:27 +02:00
for i=1,stead.table.maxn(a) do
ph = dialog_phrase(s, a[i]);
2009-08-26 08:25:53 +03:00
if isPhrase(ph) and not isRemoved(ph) then
2009-10-27 17:02:53 +02:00
if on then
2009-08-26 08:25:53 +03:00
ph:enable();
else
ph:disable();
2009-02-21 12:52:44 +02:00
end
end
end
end
2009-10-27 17:02:53 +02:00
function dialog_prem(s, ...)
2009-02-21 12:52:44 +02:00
local i, ph
2011-02-23 12:11:27 +02:00
local a = {...}
if stead.table.maxn(a) == 0 then
stead.table.insert(a, self);
2009-10-27 17:02:53 +02:00
end
2011-02-23 12:11:27 +02:00
for i=1,stead.table.maxn(a) do
ph = dialog_phrase(s, a[i]);
2009-08-26 08:25:53 +03:00
if isPhrase(ph) then
2009-02-21 12:52:44 +02:00
ph:remove();
end
end
end
function dialog_pon(self,...)
2011-02-23 12:11:27 +02:00
return ponoff(self, true, ...);
2009-02-21 12:52:44 +02:00
end
function dialog_poff(self,...)
2011-02-23 12:11:27 +02:00
return ponoff(self, false, ...);
2009-02-21 12:52:44 +02:00
end
function dlg(v) --constructor
v.dialog_type = true;
2009-10-14 18:52:29 +03:00
if v.ini == nil then
v.ini = dialog_enter;
end
2009-02-21 12:52:44 +02:00
if v.enter == nil then
v.enter = dialog_enter;
end
if v.look == nil then
v.look = dialog_look;
end
if v.scene == nil then
v.scene = dialog_scene;
end
if v.pon == nil then
v.pon = dialog_pon;
end
if v.poff == nil then
v.poff = dialog_poff;
end
if v.prem == nil then
v.prem = dialog_prem;
end
2010-07-23 14:31:52 +03:00
if v.pseen == nil then
v.pseen = dialog_pseen;
end
if v.punseen == nil then
v.punseen = dialog_punseen;
end
2010-10-30 15:54:41 +03:00
if v.empty == nil then
v.empty = dialog_empty;
end
2009-02-21 12:52:44 +02:00
v = room(v);
return v;
end
function phrase_action(self)
local ph = self;
2010-07-11 09:08:52 +03:00
local r, ret;
2009-02-21 12:52:44 +02:00
if isDisabled(ph) then
return nil, false
end
-- here it is
ph:disable(); -- /* disable it!!! */
2011-07-27 13:21:20 +03:00
local last = stead.call(ph, 'ans');
2010-07-11 13:20:04 +03:00
2009-02-21 12:52:44 +02:00
if type(ph.do_act) == 'string' then
2010-09-21 14:11:35 +03:00
local f = loadstring(ph.do_act);
2009-02-21 12:52:44 +02:00
if f ~= nil then
ret = f();
else
error ("Error while eval phrase action.");
2009-02-21 12:52:44 +02:00
end
elseif type(ph.do_act) == 'function' then
2010-07-11 09:08:52 +03:00
ret = ph.do_act(self);
2009-02-21 12:52:44 +02:00
end
2010-07-11 13:20:04 +03:00
if ret == nil then ret = stead.pget(); end
if last == true or ret == true then
r = true;
end
2009-02-21 12:52:44 +02:00
if isDialog(here()) and not dialog_rescan(here()) then
2010-07-12 10:50:13 +03:00
ret = stead.par(' ', ret, stead.back());
2009-02-21 12:52:44 +02:00
end
2010-06-16 22:31:15 +03:00
ret = stead.par("^^", last, ret);
if ret == nil then
return r -- hack?
end
return ret
2009-02-21 12:52:44 +02:00
end
function phrase_save(self, name, h, need)
2009-09-18 16:52:27 +03:00
if need then
local m = " = phr("
2009-09-18 16:52:27 +03:00
if isDisabled(self) then
m = " = _phr("
2009-09-18 16:52:27 +03:00
end
2010-07-11 16:26:47 +03:00
h:write(stead.string.format("%s%s%s,%s,%s);\n",
name, m,
stead.tostring(self.dsc),
stead.tostring(self.ans),
stead.tostring(self.do_act)));
2009-09-18 16:52:27 +03:00
end
savemembers(h, self, name, false);
2009-02-21 12:52:44 +02:00
end
2010-01-17 19:52:52 +02:00
function phrase_look(self, n)
if isDisabled(self) then
return
end
2011-07-27 13:21:20 +03:00
local v = stead.call(self, 'dsc');
2010-01-17 19:52:52 +02:00
if type(v) ~= 'string' then return; end
if game.hinting then
2010-01-17 20:00:44 +02:00
return self:xref('{'..v..'}');
2010-01-17 19:52:52 +02:00
end
return v;
end
2009-02-21 12:52:44 +02:00
function phrase(o) --constructor
local ret = o;
2010-01-17 19:52:52 +02:00
ret.look = phrase_look;
2009-02-21 12:52:44 +02:00
ret.nam = ''; -- for start
ret.phrase_type = true;
ret.act = phrase_action;
ret.save = phrase_save;
ret = obj(ret);
return ret;
end
function _phr(ask, answ, act)
local p = phrase ( { dsc = ask, ans = answ, do_act = act });
p:disable();
return p;
end
function phr(ask, answ, act)
local p = phrase ( { dsc = ask, ans = answ, do_act = act });
2009-08-26 08:25:53 +03:00
-- p:enable();
2009-02-21 12:52:44 +02:00
return p;
end
function player_inv(self)
2010-06-16 22:31:15 +03:00
return iface:inv(stead.cat(self:str()));
2009-02-21 12:52:44 +02:00
end
function player_ways(self)
2010-06-16 22:31:15 +03:00
return iface:ways(stead.cat(ref(self.where).way:str()));
2009-02-21 12:52:44 +02:00
end
function player_objs(self)
2010-06-16 22:31:15 +03:00
return iface:objs(stead.cat(ref(self.where):str()));
2009-02-21 12:52:44 +02:00
end
function player_look(self)
return ref(self.where):scene();
end
function obj_tag(self, id)
local k,v
if isDisabled(self) then
return id
end
2009-08-26 08:25:53 +03:00
for k,v in opairs(self.obj) do
v = ref(v);
if isObject(v) and not isDisabled(v) then
2009-02-21 12:52:44 +02:00
id = id + 1;
2009-08-26 08:25:53 +03:00
v.id = id;
id = obj_tag(v, id);
2009-02-21 12:52:44 +02:00
end
end
return id;
end
function player_tagall(self)
2009-08-26 08:25:53 +03:00
local id, k, v;
id = 0;
2009-09-19 15:07:39 +03:00
2009-02-21 12:52:44 +02:00
id = obj_tag(here(), id);
2009-09-17 19:32:30 +03:00
id = obj_tag(me(), id);
2009-09-19 15:07:39 +03:00
2009-08-26 08:25:53 +03:00
for k,v in opairs(ways()) do
v = ref(v);
if isRoom(v) and not isDisabled(v) then
2009-02-21 12:52:44 +02:00
id = id + 1;
2009-08-26 08:25:53 +03:00
v.id = id;
2009-02-21 12:52:44 +02:00
end
end
end
function player_action(self, what, ...)
local v,r,obj
obj = ref(self.where):srch(what);
if not obj then
2011-07-27 13:21:20 +03:00
return stead.call(ref(game), 'action', what, ...); --player_do(self, what, ...);
2009-02-21 12:52:44 +02:00
end
2011-02-23 12:11:27 +02:00
v, r = player_take(self, what, ...);
2009-02-21 12:52:44 +02:00
if not v then
2011-07-27 13:21:20 +03:00
v, r = stead.call(ref(obj), 'act', ...);
if not v and r ~= true then
2011-07-27 13:21:20 +03:00
v, r = stead.call(ref(game), 'act', obj, ...);
2009-02-21 12:52:44 +02:00
end
end
return v, r;
2009-02-21 12:52:44 +02:00
end
2010-06-25 12:31:54 +03:00
function player_take(self, what, ...)
2009-02-21 12:52:44 +02:00
local v,r,obj,w
obj,w = ref(self.where):srch(what);
if not obj then
return nil, false;
end
2011-07-27 13:21:20 +03:00
v,r = stead.call(ref(obj), 'tak', ...);
2009-02-21 12:52:44 +02:00
if v and r ~= false then
2009-09-04 09:26:50 +03:00
take(obj, w);
2009-02-21 12:52:44 +02:00
end
return v;
end
2010-06-25 12:31:54 +03:00
function player_use(self, what, onwhat, ...)
2009-02-21 12:52:44 +02:00
local obj, obj2, v, vv, r;
2010-01-24 17:17:44 +02:00
local scene_use_mode = false
2010-07-15 13:20:49 +03:00
2010-01-24 17:17:44 +02:00
obj = self:srch(what); -- in inv?
if not obj then -- no
obj = ref(self.where):srch(what); -- in scene?
if not obj then -- no!
2009-10-15 10:06:45 +03:00
return game.err, false;
2009-10-15 08:36:22 +03:00
end
2010-01-24 17:17:44 +02:00
scene_use_mode = true -- scene_use_mode!
end
2010-01-24 17:17:44 +02:00
if onwhat == nil then -- only one?
2009-10-15 11:54:20 +03:00
if scene_use_mode then
2011-02-23 12:11:27 +02:00
return self:action(what, ...); -- call act
2009-10-15 10:06:45 +03:00
else
2011-07-27 13:21:20 +03:00
v, r = stead.call(ref(obj),'inv', ...); -- call inv
2009-10-15 10:06:45 +03:00
end
if not v and r ~= true then
2011-07-27 13:21:20 +03:00
v, r = stead.call(game, 'inv', obj, ...);
2009-02-21 12:52:44 +02:00
end
return v, r;
2009-02-21 12:52:44 +02:00
end
2010-01-24 17:17:44 +02:00
obj2 = ref(self.where):srch(onwhat); -- in scene?
2009-02-21 12:52:44 +02:00
if not obj2 then
2010-01-24 17:17:44 +02:00
obj2 = self:srch(onwhat); -- in inv?
2009-02-21 12:52:44 +02:00
end
if not obj2 or obj2 == obj then
2009-08-26 08:25:53 +03:00
return game.err, false;
2009-02-21 12:52:44 +02:00
end
2010-01-24 17:17:44 +02:00
if not scene_use_mode or isSceneUse(ref(obj)) then
2011-07-27 13:21:20 +03:00
v, r = stead.call(ref(obj), 'use', obj2, ...);
2009-10-15 11:54:20 +03:00
if r ~= false then
2011-07-27 13:21:20 +03:00
vv = stead.call(ref(obj2), 'used', obj, ...);
2009-10-15 11:54:20 +03:00
end
2009-02-21 12:52:44 +02:00
end
if not v and not vv then
2011-07-27 13:21:20 +03:00
v, r = stead.call(game, 'use', obj, obj2, ...);
2009-02-21 12:52:44 +02:00
end
2010-06-16 22:31:15 +03:00
return stead.par(' ', v, vv);
2009-02-21 12:52:44 +02:00
end
function player_back(self)
local where = ref(self.where);
if where == nil then
return nil,false
end
return go(self, where.__from__, true);
end
function go(self, where, back)
2009-08-26 08:25:53 +03:00
local was = self.where;
2009-02-21 12:52:44 +02:00
local need_scene = false;
2010-06-07 09:42:01 +03:00
local ret
if not stead.in_goto_call then
ret = function(rc) stead.in_goto_call = false return nil end
else
ret = function(rc) return rc end
end
stead.in_goto_call = true
2009-02-21 12:52:44 +02:00
if where == nil then
2010-06-07 09:42:01 +03:00
return nil,ret(false)
2009-02-21 12:52:44 +02:00
end
if not isRoom(ref(where)) then
error ("Trying to go nowhere: "..where, 2);
2009-02-21 12:52:44 +02:00
end
if not isRoom(ref(self.where)) then
error ("Trying to go from nowhere: "..self.where, 2);
2009-02-21 12:52:44 +02:00
end
2010-06-06 13:58:23 +03:00
2010-06-06 14:15:52 +03:00
if stead.in_entered_call or stead.in_onexit_call then
error ("Do not use goto from onexit/entered action! Use exit/enter action instead:" .. self.where, 2);
2010-06-06 13:58:23 +03:00
end
2009-02-21 12:52:44 +02:00
local v, r;
2009-09-27 21:06:55 +03:00
if not isVroom(ref(where)) and not stead.in_exit_call then
stead.in_exit_call = true -- to break recurse
2011-07-27 13:21:20 +03:00
v,r = stead.call(ref(self.where), 'exit', where);
2009-09-27 21:06:55 +03:00
stead.in_exit_call = nil
2009-02-21 12:52:44 +02:00
if r == false then
2010-06-07 09:42:01 +03:00
return v, ret(r)
2009-02-21 12:52:44 +02:00
end
2009-09-27 20:59:22 +03:00
end
2009-08-26 08:25:53 +03:00
2009-02-21 12:52:44 +02:00
local res = v;
2010-06-07 10:59:17 +03:00
2009-02-21 12:52:44 +02:00
v = nil;
if not back or not isDialog(ref(self.where)) or isDialog(ref(where)) then
2011-07-27 13:21:20 +03:00
v, r = stead.call(ref(where), 'enter', self.where);
2009-02-21 12:52:44 +02:00
if r == false then
2010-06-07 09:42:01 +03:00
return v, ret(r)
2009-02-21 12:52:44 +02:00
end
need_scene = true;
2009-08-26 08:25:53 +03:00
if ref(was) ~= ref(self.where) then -- jump !!!
where = deref(self.where);
need_scene = false;
end
2009-02-21 12:52:44 +02:00
end
2010-06-16 22:31:15 +03:00
res = stead.par('^^',res,v);
2010-06-07 10:59:17 +03:00
2009-02-21 12:52:44 +02:00
if not back then
2009-08-26 08:25:53 +03:00
ref(where).__from__ = deref(self.where);
2010-06-06 11:18:59 +03:00
end
self.where = deref(where);
2010-06-06 13:58:23 +03:00
2010-06-07 10:59:17 +03:00
ret();
2010-06-23 13:35:53 +03:00
PLAYER_MOVED = true
2010-06-07 10:59:17 +03:00
if need_scene then -- or isForcedsc(ref(where)) then -- i'am not sure...
2010-06-16 22:31:15 +03:00
return stead.par('^^',res,ref(where):scene());
2010-06-07 10:59:17 +03:00
end
return res;
end
2010-07-11 21:48:47 +03:00
function player_goto(self, where, ...)
2011-02-23 12:11:27 +02:00
local v, r = go(self, where, ...);
2010-06-07 09:42:01 +03:00
return v, r;
2009-02-21 12:52:44 +02:00
end
2010-07-11 20:59:45 +03:00
2009-02-21 12:52:44 +02:00
function player_go(self, where)
local w = ref(self.where).way:srch(where);
if not w then
return nil,false
end
2010-06-07 09:42:01 +03:00
local v, r = go(self, w, false);
return v, r;
2009-02-21 12:52:44 +02:00
end
function player_save(self, name, h)
2010-02-10 12:50:57 +02:00
h:write(tostring(name)..".where = '"..deref(self.where).."';\n");
2009-02-21 12:52:44 +02:00
savemembers(h, self, name, false);
end
function player(v)
if v.nam == nil then
error ("No player name in constructor.", 2);
2009-02-21 12:52:44 +02:00
end
if v.where == nil then
v.where = 'main';
end
if v.tag == nil then
v.tag = player_tagall;
end
if v.goto == nil then
v.goto = player_goto;
end
if v.go == nil then
v.go = player_go;
end
if v.ways == nil then
v.ways = player_ways;
end
if v.back == nil then
v.back = player_back;
end
if v.look == nil then
v.look = player_look;
end
if v.inv == nil then
v.inv = player_inv;
end
if v.use == nil then
v.use = player_use;
end
if v.action == nil then
v.action = player_action;
end
if v.save == nil then
v.save = player_save;
end
if v.objs == nil then
v.objs = player_objs;
end
v.player_type = true;
2009-09-17 20:38:27 +03:00
return obj(v);
2009-02-21 12:52:44 +02:00
end
function game_life(self)
2009-09-20 21:27:02 +03:00
local i,o
local av,v
2009-11-01 20:41:14 +02:00
stead.in_life_call = true;
stead.lifes_off = list {}; -- lifes to off
2010-07-15 16:42:26 +03:00
stead.PLAYER_MOVED = PLAYER_MOVED
2009-09-21 07:32:18 +03:00
for i,o in opairs(self.lifes) do
2009-09-20 21:27:02 +03:00
local vv
local pre
o = ref(o);
2009-09-21 07:32:18 +03:00
if not isDisabled(o) then
2010-06-23 15:02:04 +03:00
PLAYER_MOVED = false
2011-07-27 13:21:20 +03:00
vv,pre = stead.call(o, 'life');
2010-06-23 15:02:04 +03:00
if pre or (PLAYER_MOVED and pre ~= false) then
2010-06-16 22:31:15 +03:00
av = stead.par(' ', av, vv);
2010-06-23 14:35:50 +03:00
else
v = stead.par(' ',v, vv);
2009-09-21 07:32:18 +03:00
end
2009-02-21 12:52:44 +02:00
end
2010-06-23 15:02:04 +03:00
end
2010-07-15 16:42:26 +03:00
if not PLAYER_MOVED then PLAYER_MOVED = stead.PLAYER_MOVED end
stead.PLAYER_MOVED = nil
2009-11-01 20:41:14 +02:00
stead.in_life_call = false;
for i,o in ipairs(stead.lifes_off) do
lifeoff(o);
2009-02-21 12:52:44 +02:00
end
2009-11-01 20:41:14 +02:00
stead.lifes_off = nil;
2009-09-20 21:27:02 +03:00
return v, av;
2009-02-21 12:52:44 +02:00
end
2010-07-15 16:42:26 +03:00
function player_moved()
return PLAYER_MOVED or stead.PLAYER_MOVED
end
function check_list(k, v, p)
if v.check == nil or not v:check(stead.string.format("%s[%q]", p, k)) then
error ("error in list: "..stead.object..'.'..k);
2009-08-26 08:25:53 +03:00
end
end
2009-02-21 12:52:44 +02:00
function check_room(k, v)
if v.obj == nil then
error("no obj in room:"..k);
end
if v.way == nil then
error("no way in room:"..k);
end
end
2009-08-26 08:25:53 +03:00
function check_player(k, v)
2009-09-07 20:30:37 +03:00
v.where = deref(v.where);
2009-08-26 08:25:53 +03:00
end
2009-09-22 07:27:49 +03:00
function check_object(k, v)
if not v.nam then
error ("No name in "..k);
end
if isRoom(v) then
check_room(k, v);
end
if isPlayer(v) then
check_player(k, v);
end
for_each(v, k, check_list, isList, deref(v))
2009-09-22 07:27:49 +03:00
end
function for_everything(f, ...)
local is_ok = function(s)
return true
end
2011-02-23 12:11:27 +02:00
for_each(_G, '_G', f, is_ok, ...)
2009-09-22 07:27:49 +03:00
end
2010-06-30 11:15:01 +03:00
function do_ini(self, load)
2009-08-26 08:25:53 +03:00
local v='',vv
2010-01-21 16:23:40 +02:00
local function call_key(k, o)
o.key_name = k;
2009-09-22 07:27:49 +03:00
end
2010-06-22 21:43:10 +03:00
local function call_codekey(k, o)
stead.functions[o].key_name = k;
end
local function call_ini(k, o, ...)
2011-07-27 13:21:20 +03:00
v = stead.par('', v, stead.call(o, 'ini', ...));
2009-02-21 12:52:44 +02:00
end
math.randomseed(os.time(os.date("*t")))
rnd(1); rnd(2); rnd(3); -- Lua bug?
2009-09-22 07:27:49 +03:00
2009-09-07 20:30:37 +03:00
game.pl = deref(game.pl);
game.where = deref(game.where);
2010-06-30 11:15:01 +03:00
if not load then
for_each_object(call_key);
for_each_codeblock(call_codekey);
for_each_object(check_object);
call_key("game", game);
for_each(game, "game", check_list, isList, deref(game))
end
for_each_object(call_ini, load);
2009-02-21 12:52:44 +02:00
me():tag();
if not self.showlast then
self._lastdisp = nil;
end
2010-07-15 09:59:57 +03:00
stead.initialized = true
2010-06-16 22:31:15 +03:00
return stead.par('',v, self._lastdisp); --stead.par('^^',v);
2009-02-21 12:52:44 +02:00
end
2011-04-14 19:13:52 +03:00
stead.do_ini = do_ini
2009-02-21 12:52:44 +02:00
function game_ini(self)
local v,vv
2011-04-14 19:13:52 +03:00
v = stead.do_ini(self);
2011-07-27 13:21:20 +03:00
vv = iface:title(stead.call(self,'nam'));
vv = stead.par('^^', vv, stead.call(self,'dsc'));
2011-04-14 14:15:55 +03:00
if type(init) == 'function' then
init();
2010-06-05 18:02:10 +03:00
end
2010-06-05 20:59:34 +03:00
-- if type(hooks) == 'function' then
-- hooks();
-- end
2010-06-16 22:31:15 +03:00
return stead.par("^^", vv, v);
2009-02-21 12:52:44 +02:00
end
2011-04-14 19:13:52 +03:00
function game_start(s)
if type(start) == 'function' then
start() -- start function
end
end
2009-02-21 12:52:44 +02:00
function game(v)
if v.nam == nil then
error ("No game name in constructor.", 2);
2009-02-21 12:52:44 +02:00
end
if v.pl == nil then
v.pl = 'player';
end
if v.ini == nil then
v.ini = game_ini;
end
2011-04-14 19:13:52 +03:00
if v.start == nil then
v.start = game_start
end
2009-02-21 12:52:44 +02:00
if v.save == nil then
v.save = game_save;
end
if v.load == nil then
v.load = game_load;
end
if v.life == nil then
v.life = game_life;
end
if v.step == nil then
v.step = game_step;
end
if v.lifes == nil then
v.lifes = {};
end
v.lifes = list(v.lifes);
v._time = 0;
v._running = true;
v.game_type = true;
return v;
end
2010-07-05 17:15:14 +03:00
function live(v)
2010-07-05 22:29:03 +03:00
return ref(game.lifes:srch(v));
2010-07-05 17:15:14 +03:00
end
2009-11-13 13:28:52 +02:00
function isEnableSave()
2009-11-14 20:10:10 +02:00
if game.enable_save == nil or get_autosave() then
2009-11-13 13:28:52 +02:00
return true
end
2011-07-27 13:21:20 +03:00
return stead.call_bool(game, 'enable_save');
2009-11-13 13:28:52 +02:00
end
2009-09-22 07:27:49 +03:00
2010-08-31 19:14:52 +03:00
function isEnableAutosave()
if game.enable_autosave == nil then
return true
end
2011-07-27 13:21:20 +03:00
return stead.call_bool(game, 'enable_autosave');
2010-08-31 19:14:52 +03:00
end
2009-09-22 07:27:49 +03:00
function for_each(o, n, f, fv, ...)
2011-07-25 21:00:08 +03:00
local call_list = {}
2009-02-21 12:52:44 +02:00
local k,v
2009-09-22 07:27:49 +03:00
if type(o) ~= 'table' then
return
2009-02-21 12:52:44 +02:00
end
stead.object = n;
2011-07-25 21:00:08 +03:00
2009-09-22 07:27:49 +03:00
for k,v in pairs(o) do
2010-06-22 21:43:10 +03:00
if fv(v) then
2011-07-25 21:00:08 +03:00
stead.table.insert(call_list, { k = k, v = v });
2009-02-21 12:52:44 +02:00
end
end
2011-07-25 21:00:08 +03:00
for k, v in ipairs(call_list) do
f(v.k, v.v, ...);
end
2009-02-21 12:52:44 +02:00
end
2010-06-25 12:31:54 +03:00
function isCode(s)
return type(s) == 'function' and type(stead.functions[s]) == 'table'
end
2010-06-22 21:43:10 +03:00
function for_each_codeblock(f,...)
2011-02-23 12:11:27 +02:00
for_each(_G, '_G', f, isCode, ...)
2010-06-22 21:43:10 +03:00
end
2009-09-22 07:27:49 +03:00
function for_each_object(f,...)
2011-02-23 12:11:27 +02:00
for_each(_G, '_G', f, isObject, ...)
2009-09-22 07:27:49 +03:00
end
2009-02-21 12:52:44 +02:00
function for_each_player(f,...)
2011-02-23 12:11:27 +02:00
for_each(_G, '_G', f, isPlayer, ...)
2009-02-21 12:52:44 +02:00
end
2009-09-22 07:27:49 +03:00
function for_each_room(f,...)
2011-02-23 12:11:27 +02:00
for_each(_G, '_G', f, isRoom, ...)
2009-09-22 07:27:49 +03:00
end
function for_each_list(f,...)
2011-02-23 12:11:27 +02:00
for_each(_G, '_G', f, isList, ...)
2009-09-22 07:27:49 +03:00
end
2009-02-21 12:52:44 +02:00
function clearvar (v)
2009-09-22 07:27:49 +03:00
local k,o
for k,o in pairs(v) do
if type(o) == 'table' and o.__visited__ ~= nil then
o.__visited__ = nil
2010-07-15 21:31:23 +03:00
o.auto_saved = nil
2009-09-22 07:27:49 +03:00
clearvar(o)
end
2009-02-21 12:52:44 +02:00
end
end
function savemembers(h, self, name, need)
local k,v
for k,v in pairs(self) do
local need2
if k ~= "__visited__" then
need2 = false
2010-01-31 08:10:11 +02:00
if isForSave(k, v, self) then
2009-02-21 12:52:44 +02:00
need2 = true;
end
2010-07-15 15:54:32 +03:00
2009-02-21 12:52:44 +02:00
if type(k) == 'string' then
2010-06-20 17:05:49 +03:00
savevar(h, v, name..'['..stead.string.format("%q",k)..']', need or need2);
2010-06-22 09:13:43 +03:00
elseif type(k) ~= 'function' then
2009-02-21 12:52:44 +02:00
savevar(h, v, name.."["..k.."]", need or need2)
end
end
end
end
function savevar (h, v, n, need)
local r,f
2010-07-15 15:54:32 +03:00
2010-06-22 09:13:43 +03:00
if v == nil or type(v) == "userdata" or
type(v) == "function" then
2010-06-25 12:31:54 +03:00
if isCode(v) and need then
2010-06-22 21:43:10 +03:00
if type(stead.functions[v].key_name) == 'string'
and stead.functions[v].key_name ~= n then
h:write(stead.string.format("%s=%s\n", n, stead.functions[v].key_name))
else
h:write(stead.string.format("%s=code %q\n", n, stead.functions[v].code))
end
2010-06-22 09:13:43 +03:00
end
-- if need then
-- error ("Variable "..n.." can not be saved!");
-- end
2009-02-21 12:52:44 +02:00
return
end
-- if stead.string.find(n, '_') == 1 or stead.string.match(n,'^%u') then
2009-08-26 08:25:53 +03:00
-- need = true;
-- end
2009-02-21 12:52:44 +02:00
if type(v) == "string" then
if not need then
return
end
h:write(stead.string.format("%s=%q\n",n,v))
2009-02-21 12:52:44 +02:00
return;
end
if type(v) == "table" then
2010-06-22 21:43:10 +03:00
if v == _G then return end
if type(v.key_name) == 'string' and v.key_name ~= n then -- just xref
2010-07-19 22:49:27 +03:00
if v.auto_allocated and not v.auto_saved then
2010-07-20 07:26:10 +03:00
v:save(v.key_name, h, false, true); -- here todo
2010-07-15 15:54:32 +03:00
end
if need then
2010-07-20 10:24:48 +03:00
if ref(v.key_name) == nil then
v.key_name = 'null'
end
2010-06-20 17:05:49 +03:00
h:write(stead.string.format("%s = %s\n", n, v.key_name));
end
return
end
2009-02-21 12:52:44 +02:00
if v.__visited__ ~= nil then
return
end
2009-09-22 07:27:49 +03:00
v.__visited__ = n;
2009-02-21 12:52:44 +02:00
if type(v.save) == 'function' then
v:save(n, h, need);
return;
end
2009-02-21 12:52:44 +02:00
if need then
h:write(n.." = {};\n");
end
2010-06-22 21:43:10 +03:00
2009-02-21 12:52:44 +02:00
savemembers(h, v, n, need);
return;
end
if not need then
return
end
h:write(n, " = ",tostring(v))
h:write("\n")
end
function gamefile(file, forget)
2010-07-17 16:27:53 +03:00
stead.clearargs()
if forget then
2011-03-30 10:28:26 +03:00
stead.stop_music();
stead.stop_sound();
2010-07-22 13:39:48 +03:00
timer:stop();
2010-09-01 13:34:14 +03:00
if type(variables) == 'table' then
local k,v
for k,v in ipairs(variables) do
_G[v] = nil
end
variables = nil
end
2010-07-22 13:39:48 +03:00
init = function() -- null init function
end
2011-04-14 19:13:52 +03:00
start = function() -- null start function
end
2010-07-22 13:39:48 +03:00
for_each_object(function(k, o) -- destroy all objects
if o.system_type then
return
end
_G[k] = nil
end);
game._scripts = { }
2010-07-15 09:59:57 +03:00
game.lifes:zap()
game.scriptsforget = true
-- anything else?
stead:init();
end
2010-07-14 11:31:44 +03:00
dofile(file);
game:ini();
2010-07-14 17:22:32 +03:00
if #game._scripts == 0 or file ~= game._scripts[#game._scripts] then
if #game._scripts ~= 0 or file ~= 'main.lua' then
stead.table.insert(game._scripts, file);
end
2010-07-14 11:31:44 +03:00
end
2010-07-15 09:59:57 +03:00
if forget then
2011-04-14 19:20:44 +03:00
game:start()
2011-04-14 20:38:39 +03:00
stead.started = true
2010-07-15 09:59:57 +03:00
return goto(here());
end
2010-07-14 11:31:44 +03:00
end
2009-02-21 12:52:44 +02:00
2010-07-15 09:59:57 +03:00
stead.gamefile = gamefile
2010-07-14 11:31:44 +03:00
function do_savegame(s, h)
2010-06-22 21:44:30 +03:00
local function save_object(key, value, h)
savevar(h, value, key, false);
return true;
end
local function save_var(key, value, h)
savevar(h, value, key, isForSave(key, value, _G))
end
2010-07-15 09:59:57 +03:00
local forget = game.scriptsforget
2010-07-14 17:22:32 +03:00
local i,v
for i,v in ipairs(s._scripts) do
2010-07-15 09:59:57 +03:00
h:write(stead.string.format("stead.gamefile(%q,%s)\n",
v, tostring(forget)))
forget = nil
2010-07-14 11:31:44 +03:00
end
save_object('allocator', allocator, h); -- always first!
for_each_object(save_object, h);
save_object('game', self, h);
for_everything(save_var, h);
-- save_object('_G', _G, h);
clearvar(_G);
end
function game_save(self, name, file)
local h;
2009-11-13 13:28:52 +02:00
2009-02-21 12:52:44 +02:00
if file ~= nil then
2009-09-07 20:30:37 +03:00
file:write(name..".pl = '"..deref(self.pl).."'\n");
2009-02-21 12:52:44 +02:00
savemembers(file, self, name, false);
return nil, true
end
2009-11-14 22:20:44 +02:00
if not isEnableSave() then
return nil, false
end
2009-02-21 12:52:44 +02:00
if name == nil then
return nil, false
end
2009-09-25 09:20:40 +03:00
h = stead.io.open(name,"w");
2009-02-21 12:52:44 +02:00
if not h then
return nil, false
end
2011-07-27 13:21:20 +03:00
local n = stead.call(here(),'nam');
2010-01-19 09:19:14 +02:00
if type(n) == 'string' and n ~= "" then
2010-03-14 21:10:07 +02:00
h:write("-- $Name: "..n:gsub("\n","\\n").."$\n");
2010-01-19 09:19:14 +02:00
end
2010-07-14 11:31:44 +03:00
do_savegame(self, h);
2009-02-21 12:52:44 +02:00
h:flush();
h:close();
2009-11-14 20:23:11 +02:00
game.autosave = false; -- we have only one try for autosave
2009-02-21 12:52:44 +02:00
return nil;
end
function game_load(self, name)
2009-11-13 14:04:46 +02:00
if name == nil then
2009-02-21 12:52:44 +02:00
return nil, false
end
local f, err = loadfile(name);
if f then
local i,r = f();
if r then
return nil, false
end
2011-04-14 19:13:52 +03:00
i, r = stead.do_ini(self, true);
if not stead.started then
game:start()
stead.started = true
end
return i, r
2009-02-21 12:52:44 +02:00
end
return nil, false
end
function game_step(self)
self._time = self._time + 1;
2009-09-13 15:40:02 +03:00
return self:life(self);
2009-02-21 12:52:44 +02:00
end
game = game {
2010-07-02 14:43:33 +03:00
codepage = "UTF-8",
2010-01-17 19:57:38 +02:00
nam = "INSTEAD -- Simple Text Adventure interpreter v"..stead.version.." '2009-2010 by Peter Kosyh",
2009-02-21 12:52:44 +02:00
dsc = [[
Commands:^
look(or just enter), act <on what> (or just what), use <what> [on what], go <where>,^
back, inv, way, obj, quit, save <fname>, load <fname>.]],
pl ='pl',
showlast = true,
2010-07-14 17:22:32 +03:00
_scripts = {};
2009-02-21 12:52:44 +02:00
};
2011-07-27 12:50:17 +03:00
stead.strip = function(s)
2009-02-21 12:52:44 +02:00
local s = tostring(s);
s = stead.string.gsub(s, '^[ \t]*', '');
s = stead.string.gsub(s, '[ \t]*$', '');
2009-02-21 12:52:44 +02:00
return s;
end
2009-10-15 08:36:22 +03:00
function isForcedsc(v)
local r,g
2011-07-27 13:21:20 +03:00
r = stead.call_bool(v, 'forcedsc');
2009-10-15 08:36:22 +03:00
if r then
return true
end
2011-07-27 13:21:20 +03:00
g = stead.call_bool(game, 'forcedsc', v);
2009-10-15 08:36:22 +03:00
return g and r ~= false
end
2009-10-15 11:54:20 +03:00
function isSceneUse(v)
local o,g
2011-07-27 13:21:20 +03:00
o = stead.call_bool(v, 'scene_use');
2009-10-15 11:54:20 +03:00
if o then
return true
end
2011-07-27 13:21:20 +03:00
g = stead.call_bool(game, 'scene_use', v);
2009-10-15 11:54:20 +03:00
return g and o ~= false
end
2009-02-21 12:52:44 +02:00
iface = {
img = function(self, str)
return '';
end,
2010-01-25 16:53:33 +02:00
nb = function(self, str)
return str;
end,
2009-08-26 08:25:53 +03:00
em = function(self, str)
return str;
end,
right = function(self, str)
return str;
end,
left = function(self, str)
return str;
end,
center = function(self, str)
return str;
end,
2010-10-31 17:06:54 +02:00
just = function(self, str)
return str;
end,
2010-09-02 11:03:06 +03:00
top = function(self, str)
return str;
end,
bottom = function(self, str)
return str;
end,
middle = function(self, str)
return str;
end,
2010-11-08 10:20:37 +02:00
tab = function(self, str, al)
2010-11-01 15:52:42 +02:00
return '';
end;
bold = function(self, str)
return str;
end,
2009-09-10 21:24:31 +03:00
under = function(self, str)
return str;
end,
2010-10-08 11:32:41 +03:00
st = function(self, str)
return str;
end,
2010-01-17 10:13:00 +02:00
enum = function(self, n, str)
return n..' - '..str;
end,
2009-02-21 12:52:44 +02:00
xref = function(self, str, obj)
local o = ref(here():srch(obj));
if not o then
o = ref(ways():srch(obj));
end
if not o then
2009-09-18 08:09:46 +03:00
o = ref(me():srch(obj));
2009-02-21 12:52:44 +02:00
end
if not o or not o.id then
return str;
end
2010-06-16 22:31:15 +03:00
return stead.cat(str,"("..tostring(o.id)..")");
2009-02-21 12:52:44 +02:00
end,
title = function(self, str)
return "["..str.."]";
end,
objs = function(self, str)
return str;
end,
ways = function(self, str)
return str;
end,
inv = function(self, str)
return str;
end,
text = function(self, str)
if str then
print(str);
end
end,
2010-01-17 20:13:40 +02:00
fmt = function(self, cmd, st, moved, r, av, objs, pv) -- st -- changed state (main win), move -- loc changed
local l
if st and not moved then
2010-06-23 16:02:36 +03:00
if cmd ~= 'look' then
av = txtem(av);
pv = txtem(pv);
r = txtem(r);
if isForcedsc(here()) then
l = me():look();
end
end
end
2010-11-01 14:35:08 +02:00
vv = stead.fmt(stead.cat(stead.par(stead.scene_delim, l, r, av, objs, pv), '^'));
return vv
end,
2009-02-21 12:52:44 +02:00
cmd = function(self, inp)
2010-01-15 07:36:18 +02:00
local r, v;
2010-01-14 16:26:19 +02:00
v = false
2010-06-24 12:33:59 +03:00
stead.state = false; -- changed state (main screen)
2009-08-26 08:25:53 +03:00
local a = { };
2010-01-14 16:26:19 +02:00
local cmd;
2010-11-04 10:20:40 +02:00
RAW_TEXT = nil
2010-06-23 13:35:53 +03:00
PLAYER_MOVED = nil
2011-03-30 10:28:26 +03:00
stead.set_sound(); -- empty sound
cmd,a = stead.getcmd(inp);
2010-06-23 16:02:36 +03:00
if cmd == '' then cmd = 'look' end
-- me():tag();
local oldloc = here();
2010-06-23 16:02:36 +03:00
if cmd == 'look' then
2010-06-24 12:58:06 +03:00
stead.state = true
2009-02-21 12:52:44 +02:00
r,v = me():look();
elseif cmd == 'obj' then
r,v = me():objs();
elseif cmd == 'inv' then
r,v = me():inv();
elseif cmd == 'way' then
r,v = me():ways();
elseif cmd == 'ls' then
2010-06-16 22:31:15 +03:00
r = stead.par('^^', me():objs(), me():inv(), me():ways());
2009-02-21 12:52:44 +02:00
v = nil;
elseif cmd == 'go' then
2010-06-24 12:33:59 +03:00
stead.state = true
2009-02-21 12:52:44 +02:00
r,v = me():go(unpack(a));
elseif cmd == 'back' then
2010-06-24 12:33:59 +03:00
stead.state = true
2009-02-21 12:52:44 +02:00
r,v = me():go(from());
elseif cmd == 'act' then
2010-06-24 12:33:59 +03:00
stead.state = true
2009-02-21 12:52:44 +02:00
r,v = me():action(unpack(a));
elseif cmd == 'use' then
2010-06-24 12:33:59 +03:00
stead.state = true
2009-02-21 12:52:44 +02:00
r,v = me():use(unpack(a));
elseif cmd == 'save' then
r, v = game:save(unpack(a));
elseif cmd == 'load' then
r, v = game:load(unpack(a));
if v ~= false and game.showlast then
return r;
end
2011-04-14 22:29:07 +03:00
elseif cmd == 'wait' then -- nothing todo in game, skip tick
2010-06-25 12:31:54 +03:00
v = nil;
2011-04-14 22:29:07 +03:00
r = true;
2010-06-25 12:31:54 +03:00
stead.state = true
2011-04-14 22:29:07 +03:00
elseif cmd == 'nop' then -- inv only
2010-01-26 09:38:37 +02:00
v = true;
r = nil;
2010-06-24 12:33:59 +03:00
stead.state = true
2009-02-21 12:52:44 +02:00
else
2010-06-24 12:33:59 +03:00
stead.state = true
2010-01-14 16:26:19 +02:00
r,v = me():action(cmd, unpack(a));
2009-02-21 12:52:44 +02:00
end
2009-09-22 07:27:49 +03:00
-- here r is action result, v - ret code value
2010-06-24 12:33:59 +03:00
-- state -- game state changed
if stead.state and r == nil and v == true then -- we do nothing
2011-04-14 22:29:07 +03:00
return nil, true; -- menu
end
2011-04-23 10:57:13 +03:00
if stead.state and r == nil and v == nil and stead.api_version >= "1.3.5" then -- new goto
2011-04-14 22:29:07 +03:00
return nil, nil -- really nothing
end
2011-04-14 22:29:07 +03:00
2010-06-06 13:58:23 +03:00
if RAW_TEXT then
v = false
end
if v == false then
2010-06-16 22:31:15 +03:00
return stead.cat(r, '\n'), false;
end
2010-06-23 13:35:53 +03:00
2009-09-22 14:13:58 +03:00
ACTION_TEXT = r; -- here, life methods can redefine this
local av, pv -- av -- active lifes, pv -- background
2010-01-15 07:36:18 +02:00
local vv
2010-06-24 12:33:59 +03:00
if stead.state then
2009-09-20 21:27:02 +03:00
pv,av = game:step();
me():tag();
vv = here():look();
2009-02-21 12:52:44 +02:00
end
2010-06-24 12:33:59 +03:00
vv = self:fmt(cmd, stead.state, (oldloc ~= here()) or PLAYER_MOVED,
2010-06-23 13:35:53 +03:00
ACTION_TEXT, av, vv, pv);
2010-06-24 12:33:59 +03:00
if stead.state then
2009-02-21 12:52:44 +02:00
game._lastdisp = vv
end
2009-08-26 08:25:53 +03:00
if vv == nil then -- nil is error
return ''
end
2011-04-14 22:29:07 +03:00
return vv, true; -- action is here
2009-02-21 12:52:44 +02:00
end,
shell = function(self)
local inp, i, k, cmd, a, n;
me():tag();
while game._running do
2009-09-25 09:20:40 +03:00
inp = stead.io.read("*l");
2009-02-21 12:52:44 +02:00
if inp == 'quit' then
break;
end
self:text(self:cmd(inp));
end
end
};
function me()
return ref(game.pl);
end
2009-09-04 09:26:50 +03:00
function where(s)
2010-07-21 13:30:42 +03:00
if not isObject(ref(s)) then error("Wrong parameter to where.", 2); end
2009-09-08 20:51:24 +03:00
if isPlayer(ref(s)) then
return ref(ref(s).where);
end
2009-09-08 20:27:58 +03:00
return ref(ref(s).__where__);
2009-08-26 08:25:53 +03:00
end
2009-02-21 12:52:44 +02:00
function here()
2009-09-08 20:27:58 +03:00
return ref(me().where);
2009-02-21 12:52:44 +02:00
end
2009-10-16 16:10:05 +03:00
function from(w)
if w == nil then
w = here();
else
w = ref(w);
end
return ref(w.__from__);
2009-02-21 12:52:44 +02:00
end
function time()
return game._time;
end
2010-06-23 16:02:36 +03:00
stead.time = time
2009-02-21 12:52:44 +02:00
function inv()
return me().obj;
end
2009-08-26 08:25:53 +03:00
function objs(w)
if not w then
2009-09-04 09:26:50 +03:00
return here().obj;
2009-08-26 08:25:53 +03:00
else
2009-09-04 09:26:50 +03:00
return ref(w).obj;
2009-08-26 08:25:53 +03:00
end
2009-02-21 12:52:44 +02:00
end
2009-08-26 08:25:53 +03:00
function ways(w)
if not w then
2009-09-04 09:26:50 +03:00
return here().way;
2009-08-26 08:25:53 +03:00
else
2009-09-04 09:26:50 +03:00
return ref(w).way;
2009-08-26 08:25:53 +03:00
end
2009-02-21 12:52:44 +02:00
end
2010-06-24 12:33:59 +03:00
function xref(str, obj, ...)
2009-10-26 17:00:11 +02:00
if type(str) ~= 'string' then return nil; end;
2011-02-23 12:11:27 +02:00
return iface:xref(str, obj, ...);
2009-02-21 12:52:44 +02:00
end
2010-07-23 14:31:52 +03:00
function pseen(...)
if not isDialog(here()) then
return
end
2011-02-23 12:11:27 +02:00
return here():pseen(...);
2010-07-23 14:31:52 +03:00
end
function punseen(...)
if not isDialog(here()) then
return
end
2011-02-23 12:11:27 +02:00
return here():punseen(...);
2010-07-23 14:31:52 +03:00
end
2009-02-21 12:52:44 +02:00
function pon(...)
if not isDialog(here()) then
return
end
2011-02-23 12:11:27 +02:00
here():pon(...);
2009-02-21 12:52:44 +02:00
end
function poff(...)
if not isDialog(here()) then
return
end
2011-02-23 12:11:27 +02:00
here():poff(...);
2009-02-21 12:52:44 +02:00
end
function prem(...)
if not isDialog(here()) then
return
end
2011-02-23 12:11:27 +02:00
here():prem(...);
2009-02-21 12:52:44 +02:00
end
function lifeon(what)
game.lifes:add(what);
end
function lifeoff(what)
2009-11-01 20:41:14 +02:00
if stead.in_life_call then
stead.lifes_off:add(what);
return
end
2009-02-21 12:52:44 +02:00
game.lifes:del(what);
end
2010-07-13 09:42:08 +03:00
function allocator_save(s, name, h, need, auto)
if s.auto_allocated and not auto then
return
end
2009-10-19 11:59:01 +03:00
if need then
2010-11-06 14:32:43 +02:00
if s.auto_allocated then -- in current realization always false
2010-07-19 22:41:40 +03:00
local m = stead.string.format("allocator:new(%s, %s)\n",
stead.tostring(s.constructor),
stead.tostring(s.constructor));
h:write(m);
else
2010-11-06 14:32:43 +02:00
local m = stead.string.format(" = allocator:get(%s, %s)\n",
2010-07-19 22:41:40 +03:00
stead.tostring(name),
stead.tostring(s.constructor));
h:write(name..m);
2010-11-06 14:32:43 +02:00
if stead.api_version >= "1.3.0" then
m = stead.string.format("check_object(%s, %s)\n",
stead.tostring(name),
name);
h:write(m);
end
2010-07-19 22:41:40 +03:00
end
2009-10-19 11:59:01 +03:00
end
savemembers(h, s, name, false);
2010-07-19 21:28:29 +03:00
if s.auto_allocated then
s.auto_saved = true
end
2009-10-19 11:59:01 +03:00
end
function new(str)
if type(str) ~= 'string' then
error("Non string constructor in new.", 2);
2009-10-19 11:59:01 +03:00
end
2010-11-06 14:32:43 +02:00
return allocator:new(str);
2009-10-19 11:59:01 +03:00
end
function delete(v)
allocator:delete(v);
end
2009-02-21 12:52:44 +02:00
function vobj_save(self, name, h, need)
2010-06-30 07:46:24 +03:00
local dsc = self.dsc;
local w = deref(self.where);
2009-02-21 12:52:44 +02:00
if need then
2010-07-11 17:26:13 +03:00
h:write(stead.string.format("%s = vobj(%s, %s, %s, %s);\n",
name,
stead.tostring(self.key),
stead.tostring(self.nam),
stead.tostring(dsc),
stead.tostring(w)));
2010-06-30 07:46:24 +03:00
2009-02-21 12:52:44 +02:00
end
savemembers(h, self, name,false);
end
function vobj_act(self, ...)
2009-08-26 08:25:53 +03:00
local o, r = here():srch(self); -- self.nam
if ref(o) and ref(o).where then
return goto(ref(o).where);
end
2011-07-27 13:21:20 +03:00
return stead.call(ref(r),'act', self.key, ...);
2009-02-21 12:52:44 +02:00
end
function vobj_used(self, ...)
local o, r = here():srch(self.nam);
2011-07-27 13:21:20 +03:00
return stead.call(ref(r),'used', self.key, ...);
2009-02-21 12:52:44 +02:00
end
2009-08-26 08:25:53 +03:00
function vobj(key, name, dsc, w)
2009-02-21 12:52:44 +02:00
if not tonumber(key) then
error ("vobj key must be number!", 2);
2009-02-21 12:52:44 +02:00
end
2009-08-26 08:25:53 +03:00
return obj{ key = key, nam = name, dsc = dsc, where = deref(w), act = vobj_act, used = vobj_used, save = vobj_save, obj = list({}) };
end
function vway(name, dsc, w)
2009-02-21 12:52:44 +02:00
-- o.object_type = true;
2009-08-26 08:25:53 +03:00
return obj{ key = -1, nam = name, dsc = dsc, act = vobj_act, where = deref(w), used = vobj_used, save = vobj_save, obj = list({}), };
end
function vroom_save(self, name, h, need)
if need then
h:write(name.." = vroom('"..self.nam.."','"..deref(self.where).."');\n");
end
savemembers(h, self, name,false);
2009-02-21 12:52:44 +02:00
end
2009-08-26 08:25:53 +03:00
function vroom_enter(self, ...)
2010-07-12 10:50:13 +03:00
return stead.goto(self.where);
2009-08-26 08:25:53 +03:00
end
2009-09-27 20:59:22 +03:00
function isVroom(v)
return (type(v) == 'table') and (v.vroom_type)
end
2009-08-26 08:25:53 +03:00
function vroom(name, w)
2010-07-15 13:53:59 +03:00
if w == nil then
error("Wrong parameter to vroom.", 2);
end
2009-09-27 20:59:22 +03:00
return room { vroom_type = true, nam = name, where = deref(w), enter = vroom_enter, save = vroom_save, };
2009-08-26 08:25:53 +03:00
end
2009-02-21 12:52:44 +02:00
function goto(what)
2009-08-26 08:25:53 +03:00
local v,r=me():goto(what);
2009-02-21 12:52:44 +02:00
me():tag();
2009-08-26 08:25:53 +03:00
return v,r;
2009-02-21 12:52:44 +02:00
end
2010-07-12 10:50:13 +03:00
stead.goto = goto;
2010-07-11 20:59:45 +03:00
2009-02-21 12:52:44 +02:00
function back()
return me():back();
end
2010-07-12 10:50:13 +03:00
stead.back = back;
2010-07-11 20:59:45 +03:00
2009-02-21 12:52:44 +02:00
function rnd(m)
2011-07-14 15:21:02 +03:00
if not m then
return math.random();
end
2009-02-21 12:52:44 +02:00
return math.random(m);
end
function taken(obj)
if isObject(ref(obj)) and ref(obj)._taken then
return true
end
return false;
end
2009-09-04 09:26:50 +03:00
function remove(obj, from)
local o,w
if from then
o,w = ref(from):srch(obj);
2009-08-26 08:25:53 +03:00
else
2009-09-04 09:26:50 +03:00
o,w = here():srch(obj);
2009-08-26 08:25:53 +03:00
end
2009-02-21 12:52:44 +02:00
if w then
ref(w).obj:del(obj);
end
2009-08-26 08:25:53 +03:00
o = ref(o);
if not isObject(o) then
o = ref(obj);
end
2010-07-08 10:06:04 +03:00
if isObject(o) then
o.__where__ = nil;
end
2009-09-04 09:26:50 +03:00
return o
end
2010-07-07 16:33:46 +03:00
function purge(obj, from)
local o,w
if from then
o,w = ref(from):srch(obj, true);
else
o,w = here():srch(obj, true);
end
if w then
ref(w).obj:purge(obj);
end
o = ref(o);
if not isObject(o) then
o = ref(obj);
end
2010-07-08 10:06:04 +03:00
if isObject(o) then
o.__where__ = nil;
end
2010-07-07 16:33:46 +03:00
return o
end
2010-06-12 12:30:24 +03:00
function taketo(obj, wh, pos)
2009-09-04 09:26:50 +03:00
local o = remove(obj, wh);
2009-08-26 08:25:53 +03:00
if not isObject(o) then
error ("Trying to take wrong object.", 2);
2009-08-26 08:25:53 +03:00
end
2010-06-12 12:30:24 +03:00
inv():add(obj, pos);
2009-08-26 08:25:53 +03:00
o._taken = true
2010-07-06 16:41:24 +03:00
wh = deref(me())
if type(wh) == 'string' then
o.__where__ = wh;
end
2009-08-26 08:25:53 +03:00
return o
2009-02-21 12:52:44 +02:00
end
2010-06-12 12:30:24 +03:00
function take(obj, wh)
return taketo(obj, wh);
end
function takef(obj, wh)
return taketo(obj, wh, 1);
end
2009-09-04 09:26:50 +03:00
function putto(obj, w, pos)
2009-10-23 12:37:37 +03:00
local wh
2009-08-26 08:25:53 +03:00
local o = ref(obj);
if not isObject(o) then
error ("Trying to put wrong object.", 2);
2009-08-26 08:25:53 +03:00
end
if not w then
2009-10-23 12:37:37 +03:00
wh = deref(here());
w = here();
2009-08-26 08:25:53 +03:00
else
2009-10-23 12:37:37 +03:00
wh = deref(w);
w = ref(w);
end
w.obj:add(obj, pos);
if type(wh) == 'string' then
o.__where__ = wh;
2009-08-26 08:25:53 +03:00
end
return o;
end
2009-09-04 09:26:50 +03:00
function put(obj, w)
return putto(obj, w);
end
function putf(obj, w)
return putto(obj, w, 1);
end
2010-07-08 07:40:14 +03:00
place = put
placef = putf
placeto = putto
function replace(obj, obj2, from)
local o,w,i
2010-07-08 10:06:04 +03:00
if not isObject(ref(obj2)) then
error ("Wrong parameter to replace.", 2);
end
2010-07-08 07:40:14 +03:00
if from then
o,w = ref(from):srch(obj);
else
o,w = here():srch(obj);
end
if w then
ref(w).obj:replace(o, obj2);
ref(obj2).__where__ = deref(w);
else
place(obj2, from);
end
o = ref(o);
if not isObject(o) then
o = ref(obj);
end
2010-07-08 10:06:04 +03:00
if isObject(o) then
o.__where__ = nil;
end
2010-07-08 07:40:14 +03:00
return o;
end
2009-08-26 08:25:53 +03:00
function drop(obj, w)
local o = put(obj, w);
2009-09-04 09:26:50 +03:00
if not isObject(o) then
error ("Trying to drop wrong object.", 2);
2009-08-26 08:25:53 +03:00
end
2009-09-07 11:15:58 +03:00
inv():del(obj);
2009-08-26 08:25:53 +03:00
o._taken = false
return o;
end
function dropf(obj)
2009-09-04 09:26:50 +03:00
local o = putf(obj);
2009-08-26 08:25:53 +03:00
if not isObject(o) then
error ("Trying to dropf wrong object.", 2);
2009-08-26 08:25:53 +03:00
end
2009-09-20 10:15:39 +03:00
inv():del(obj);
2009-08-26 08:25:53 +03:00
o._taken = false
return o;
2009-02-21 12:52:44 +02:00
end
2009-08-27 07:38:56 +03:00
function seen(obj, wh)
if not wh then
wh = here();
else
2010-01-17 20:20:20 +02:00
wh = ref(wh);
2009-08-27 07:38:56 +03:00
end
local o,w = wh:srch(obj);
2009-08-26 08:25:53 +03:00
o = ref(o);
if isObject(o) then
return o,w
2009-02-21 12:52:44 +02:00
end
2009-08-26 08:25:53 +03:00
return nil
2009-02-21 12:52:44 +02:00
end
2010-06-14 11:10:59 +03:00
function exist(obj, wh)
if not wh then
wh = here();
else
wh = ref(wh);
end
local o,w = wh:srch(obj, true);
o = ref(o);
if isObject(o) then
return o,w
end
return nil
end
2009-02-21 12:52:44 +02:00
function have(obj)
2009-09-20 10:15:39 +03:00
local o = inv():srch(obj);
2009-08-26 08:25:53 +03:00
o = ref(o);
if isObject(o) then
2009-08-26 08:25:53 +03:00
return o
2009-02-21 12:52:44 +02:00
end
2009-08-26 08:25:53 +03:00
return nil
2009-02-21 12:52:44 +02:00
end
2009-08-26 08:25:53 +03:00
function moveto(obj, there, from, pos)
2009-09-04 09:26:50 +03:00
remove(obj, from);
putto(obj, there, pos);
2009-08-26 08:25:53 +03:00
return ref(obj);
end
function move(obj, there, from)
return moveto(obj, there, from);
end
function movef(obj, there, from)
return moveto(obj, there, from, 1);
2009-02-21 12:52:44 +02:00
end
function get_picture()
2011-07-27 13:21:20 +03:00
local s = stead.call(here(),'pic');
2009-08-26 08:25:53 +03:00
if not s then
2011-07-27 13:21:20 +03:00
s = stead.call(game, 'pic');
2009-08-26 08:25:53 +03:00
end
2009-02-21 12:52:44 +02:00
return s;
end
function get_title()
2011-07-27 13:21:20 +03:00
local s = stead.call(here(),'nam');
2009-02-21 12:52:44 +02:00
return s;
end
2009-08-26 08:25:53 +03:00
2009-02-21 12:52:44 +02:00
function get_music()
2009-11-12 11:07:17 +02:00
return game._music, game._music_loop;
2009-02-21 12:52:44 +02:00
end
2009-08-26 08:25:53 +03:00
function get_music_loop()
return game._music_loop;
end
function save_music(s)
2011-04-27 12:28:58 +03:00
if s == nil then
s = self
end
2009-08-26 08:25:53 +03:00
s.__old_music__ = get_music();
s.__old_loop__ = get_music_loop();
end
function restore_music(s)
2011-04-27 12:28:58 +03:00
if s == nil then
s = self
end
2009-08-26 08:25:53 +03:00
set_music(s.__old_music__, s.__old_loop__);
end
function dec_music_loop()
if game._music_loop == 0 then
return 0
end
game._music_loop = game._music_loop - 1;
if game._music_loop == 0 then
game._music_loop = -1;
end
return game._music_loop;
end
function set_music(s, count)
2009-02-21 12:52:44 +02:00
game._music = s;
2009-08-26 08:25:53 +03:00
if not tonumber(count) then
game._music_loop = 0;
else
game._music_loop = tonumber(count);
end
2009-02-21 12:52:44 +02:00
end
2011-03-30 10:28:26 +03:00
stead.set_music = set_music
2009-02-21 12:52:44 +02:00
2009-11-01 09:06:14 +02:00
function stop_music()
set_music(nil, -1);
end
2011-03-30 10:28:26 +03:00
stead.stop_music = stop_music
2009-11-01 09:06:14 +02:00
2009-11-01 13:05:36 +02:00
function is_music()
return game._music ~= nil and game._music_loop ~= -1
end
2009-11-12 11:07:17 +02:00
if is_sound == nil then
function is_sound()
return false -- sdl-instead export own function
end
end
2011-04-15 10:23:46 +03:00
stead.is_sound = is_sound
2009-11-12 11:07:17 +02:00
2010-06-05 12:56:55 +03:00
if get_savepath == nil then
function get_savepath()
return "./"
end
end
2009-11-14 20:10:10 +02:00
function autosave(slot)
game.autosave = true;
game.autosave_slot = slot;
end
function get_autosave()
return game.autosave, game.autosave_slot
end
2009-10-04 18:53:44 +03:00
function get_sound()
2009-11-12 11:07:17 +02:00
return game._sound, game._sound_channel, game._sound_loop;
2009-10-04 18:53:44 +03:00
end
2011-03-30 10:28:26 +03:00
stead.get_sound = get_sound
2009-10-04 18:53:44 +03:00
function get_sound_chan()
return game._sound_channel
end
2011-03-30 10:28:26 +03:00
stead.get_sound_chan = get_sound_chan
2009-11-11 22:16:26 +02:00
function get_sound_loop()
return game._sound_loop
end
2011-03-30 10:28:26 +03:00
stead.get_sound_loop = get_sound_loop
2009-11-11 22:16:26 +02:00
2011-03-29 13:12:17 +03:00
function stop_sound(chan)
if not tonumber(chan) then
set_sound('@');
return
end
set_sound('@'..tostring(chan));
end
2011-03-30 10:28:26 +03:00
stead.stop_sound = stop_sound
2011-03-29 13:12:17 +03:00
function add_sound(s, chan, loop)
if type(s) ~= 'string' then
return
end
if type(game._sound) == 'string' then
if tonumber(chan) then
s = s..'@'..tostring(chan);
end
if tonumber(loop) then
s = s..','..tostring(loop)
end
set_sound(game._sound..';'..s, get_sound_chan(), get_sound_loop());
else
set_sound(s, chan, loop);
end
end
2011-03-30 10:28:26 +03:00
stead.add_sound = add_sound
2011-03-29 13:12:17 +03:00
2009-11-11 22:16:26 +02:00
function set_sound(s, chan, loop)
game._sound = s;
if not tonumber(loop) then
game._sound_loop = 1;
else
game._sound_loop = tonumber(loop);
end
if not tonumber(chan) then
game._sound_channel = -1;
else
game._sound_channel = tonumber(chan);
end
2009-10-04 18:53:44 +03:00
end
2011-03-30 10:28:26 +03:00
stead.set_sound = set_sound
2009-10-04 18:53:44 +03:00
2009-08-26 08:25:53 +03:00
function change_pl(p)
local o = ref(p);
if type(deref(p)) ~= 'string' or not o then
error ("Wrong player name in change_pl...", 2);
2009-08-26 08:25:53 +03:00
end
game.pl = deref(p);
2009-08-26 08:25:53 +03:00
return goto(o.where);
end
2009-02-21 12:52:44 +02:00
function disabled(o)
return isDisabled(ref(o))
end
2010-06-14 11:10:59 +03:00
function disable(o)
o = ref(o)
if isObject(o) then
o:disable()
end
return o
end
function enable(o)
o = ref(o)
if isObject(o) then
o:enable()
end
return o
end
function disable_all(o)
o = ref(o)
2010-07-07 15:41:48 +03:00
if isObject(o) or isList(o) then
2010-06-14 11:10:59 +03:00
o:disable_all()
end
return o
end
function enable_all(o)
o = ref(o)
2010-07-07 15:41:48 +03:00
if isObject(o) or isList(o) then
2010-06-14 11:10:59 +03:00
o:enable_all()
end
return o
end
2010-01-31 08:10:11 +02:00
function isForSave(k, v, s) -- k - key, v - value, s -- parent table
2010-06-22 09:13:43 +03:00
if type(k) == 'function' then
return false
end
if type(v) == 'function' or type(v) == 'userdata' then
return false
end
return stead.string.find(k, '_') == 1 or stead.string.match(k,'^%u')
2009-09-03 13:34:53 +03:00
end
2010-06-05 18:02:10 +03:00
2010-06-05 20:59:34 +03:00
function inherit(o, f)
return function(...)
2011-02-23 12:11:27 +02:00
return f(o(...))
2010-06-05 20:59:34 +03:00
end
end
2010-06-23 15:09:33 +03:00
stead.inherit = inherit
2010-06-05 20:59:34 +03:00
function hook(o, f)
return function(...)
2010-06-19 19:43:27 +03:00
local ff
2010-06-19 17:59:57 +03:00
if type(o) ~= 'function' then
2010-06-19 19:43:27 +03:00
ff = function(s)
2010-06-19 17:59:57 +03:00
return o;
end
2010-06-19 19:43:27 +03:00
else
ff = o
2010-06-16 08:05:23 +03:00
end
2011-02-23 12:11:27 +02:00
return f(ff, ...)
2010-06-05 20:59:34 +03:00
end
end
2010-06-23 15:09:33 +03:00
stead.hook = hook
2010-06-05 20:59:34 +03:00
2010-06-27 09:04:10 +03:00
function nameof(v)
if isObject(v) then
2011-07-27 13:21:20 +03:00
local r = stead.call(v, 'nam');
2010-06-27 09:04:10 +03:00
return r
end
end
function stead_version(v)
2010-06-11 12:12:19 +03:00
if not tostring(v) then
return
end
if stead.version < v then
2010-11-03 12:21:55 +02:00
error ([[The game requires instead engine of version ]] ..v.. [[ or higher.
http://instead.googlecode.com]], 2)
2010-06-11 12:12:19 +03:00
end
stead.api_version = v
2010-06-16 13:09:41 +03:00
if v >= "1.2.0" then
require ("goto")
2010-06-22 14:04:12 +03:00
require ("vars")
require ("object")
2010-06-16 13:09:41 +03:00
end
2010-06-11 12:12:19 +03:00
end
instead_version = stead_version
2010-06-21 22:33:38 +03:00
function code(v)
2010-09-21 14:11:35 +03:00
local f = loadstring(v)
2010-06-21 22:33:38 +03:00
if not f then
error ("Wrong script: "..tostring(v), 2);
end
2010-06-22 09:34:45 +03:00
stead.functions[f] = { f = f, code = v };
2010-06-21 22:33:38 +03:00
return f;
end
2010-06-23 15:13:12 +03:00
stead.code = code
2010-07-22 13:39:48 +03:00
2010-06-05 18:02:10 +03:00
--- here the game begins
2010-07-06 11:14:42 +03:00
stead.objects = function(s)
2010-07-18 07:39:39 +03:00
null = obj {
nam = 'null';
}
2010-07-22 13:39:48 +03:00
input = obj { -- input object
system_type = true,
nam = 'input',
--[[ key = function(s, down, key)
return
end, ]]
--[[ click = function(s, down, mb, x, y, [ px, py ] )
return
end ]]
};
timer = obj { -- timer calls stead.timer callback
nam = 'timer',
ini = function(s)
if tonumber(s._timer) ~= nil and type(set_timer) == 'function' then
set_timer(s._timer);
end
end,
get = function(s)
if tonumber(s._timer) == nil then
return 0
end
return tonumber(s._timer);
end,
stop = function(s)
return s:set(0);
end,
del = function(s)
return s:set(0);
end,
set = function(s, v)
s._timer = tonumber(v);
if type(set_timer) ~= 'function' then
return false
end
set_timer(v)
return true
end,
--[[ callback = function(s)
end, ]]
};
2010-07-06 11:14:42 +03:00
allocator = obj {
nam = 'allocator',
get = function(s, n, c)
2010-11-06 14:32:43 +02:00
if isObject(ref(n)) and stead.api_version >= "1.3.0" then -- static?
return ref(n);
end
2010-07-06 11:14:42 +03:00
local v = ref(c);
if not v then
error ("Null object in allocator: "..tostring(c));
end
v.key_name = n;
v.save = allocator_save;
v.constructor = c;
return v
end,
delete = function(s, w)
w = ref(w);
if type(w.key_name) ~= 'string' then
return
end
local f = loadstring(w.key_name..'= nil;');
if f then
f();
end
end,
2010-07-19 22:41:40 +03:00
new = function(s, n, key)
2010-07-06 11:14:42 +03:00
local v = ref(n);
if type(v) ~= 'table' or type(n) ~= 'string' then
error ("Error in new.", 2);
end
v.save = allocator_save;
v.constructor = n;
2010-07-19 22:41:40 +03:00
if key then
s.objects[key] = v
v.key_name = stead.string.format('allocator["objects"][%s]', stead.tostring(key));
else
stead.table.insert(s.objects, v);
v.key_name = 'allocator["objects"]['..stead.table.maxn(s.objects)..']';
end
2010-11-06 14:32:43 +02:00
if stead.api_version >= "1.3.0" then
check_object(v.key_name, v)
end
2010-07-06 11:14:42 +03:00
return v
end,
objects = {
save = function(self, name, h, need)
savemembers(h, self, name, true);
end,
},
};
2010-06-22 09:13:43 +03:00
pl = player {
nam = "Incognito",
where = 'main',
obj = { }
};
main = room {
nam = 'main',
dsc = 'No main room defined.',
2010-07-06 11:14:42 +03:00
};
end
stead.init = function(s)
2010-07-15 09:59:57 +03:00
stead.initialized = false
2011-04-14 19:13:52 +03:00
stead.started = false
2010-07-06 11:14:42 +03:00
stead:objects();
2010-06-22 09:13:43 +03:00
s.functions = {} -- code blocks
2010-06-25 15:53:17 +03:00
local k,v
for k,v in ipairs(s.modules_ini) do
v();
end
2010-06-22 09:13:43 +03:00
end
stead:init();
2010-07-06 11:14:42 +03:00
-- vim:ts=4