1-- add this: reuire "dbg" 2-- in your project 3-- for debug tools 4require "input" 5 6local function _xref_escape(n) 7 local delim = ':' 8 if stead.api_atleast(1, 2, 2) then 9 delim = stead.delim; 10 end 11 if xact then 12 n = n:gsub("\\?[\\"..delim.."]", { [delim] = "\\"..delim } ) 13 end 14 return n 15end 16 17local function ordered_n(t) 18 local ordered = {}; 19 local max = 0 20 for i, v in stead.pairs(t) do 21 local o = { k = i; v = v }; 22 stead.table.insert(ordered, o); 23 max = max + 1; 24 end 25 stead.table.sort(ordered, function(a, b) 26 if isObject(a.v) and not isObject(b.v) then 27 return true 28 end 29 if not isObject(a.v) and isObject(b.v) then 30 return false 31 end 32 if isObject(a.v) and isObject(b.v) then 33 local n = stead.call(a.v, 'nam'); 34 local m = stead.call(b.v, 'nam'); 35 if stead.type(n) ~= 'string' and stead.type(m) ~= 'string' then 36 return false 37 end 38 if stead.type(n) ~= 'string' then 39 return true 40 end 41 if stead.type(m) ~= 'string' then 42 return false 43 end 44 if n == m then 45 local o1, o2 46 o1 = stead.deref(a.v) 47 o2 = stead.deref(b.v) 48 if stead.type(o1) == 'string' and stead.type(o2) == 'string' then 49 return o1 < o2 50 end 51 end 52 return n < m; 53 end 54 return false 55 end) 56 ordered.i = 1; 57 ordered.max = max; 58 return ordered; 59end 60 61local function snext(t, k) 62 local v 63 if not k then 64 k = ordered_n(t); 65 end 66 if k.i > k.max then 67 return nil 68 end 69 v = k[k.i] 70 k.i = k.i + 1 71 return k, v.v, v.k; 72end 73 74local function spairs(s, var) 75 return snext, s, nil; 76end 77 78function dbg_disp_obj() 79 local v = obj { 80 nam = 'disp', 81 act = true, 82 dsc = function(s) 83 local r = s._txt 84 s._txt = nil; 85 return r 86 end; 87 save = function(self, name, h, need) 88 if need then 89 h:write(stead.string.format("%s = dbg_disp_obj();\n", name)); 90 end 91 stead.savemembers(h, self, name, false); 92 end 93 } 94 return v; 95end 96 97dbg_dump_obj = function(w) 98 w = stead.ref(w) 99 100 if stead.type(w) ~= 'table' then 101 seen('disp')._txt = '^^No such object.'; 102 return true 103 end 104 local n 105 local rc = '' 106 for i, o in stead.pairs(w) do 107 local t = stead.tostring(o); 108 if t == i then 109 t = stead.tostr(o); 110 end 111 if t then 112 if rc ~='' then rc = rc..'^' end 113 local n = ''; 114 if isObject(o) then 115 n = stead.call(o, 'nam'); 116 if stead.type(n) ~= 'string' then n = '' else n = ' : '..n; end 117 end 118 rc = stead.cat(rc, stead.par(' ', stead.tostr(i)..' : '..t..n)); 119 end 120 end 121 seen('disp')._txt = stead.cat('^^', rc) 122 return true; 123end 124 125dbg_dump_globals = function() 126 local rc='' 127 if stead.type(variables) ~= 'table' then 128 return 129 end 130 for i, o in stead.ipairs(variables) do 131 local v = stead.rawget(_G, o); 132 local t = stead.tostring(v); 133 if t then 134 if rc ~='' then rc = rc..'^' end 135 rc = stead.cat(rc, stead.par(' ', stead.tostr(o)..' : '..t)); 136 end 137 end 138 seen('disp')._txt = stead.cat('^^', rc) 139 return true; 140end 141 142dbg_here = function() 143 return debug_tool._here 144end 145 146dbg_list_objects = function() 147 local dis = function(o) 148 if isDisabled(o) then 149 return ", disabled" 150 end 151 return '' 152 end 153 local rc = stead.par(' ', 'Room:'..stead.tostr(stead.deref(dbg_here())), 154 'Nam:'..stead.tostr(stead.call(dbg_here(),'nam'))); 155 for i, o in stead.opairs(objs(dbg_here())) do 156 rc = rc..'^'; 157 o = stead.ref(o) 158 rc = stead.cat(rc, stead.par(' ', 'Id: '..stead.tostr(o.id)..', '.. 159 stead.tostr(stead.deref(o))..': '..stead.tostr(stead.call(o, 'nam'))..dis(o))); 160 end 161-- seen('disp')._txt = rc 162 return rc 163end 164 165dbg_list_inv = function() 166 local rc = '' 167 local dis = function(o) 168 if isDisabled(o) then 169 return ", disabled" 170 end 171 return '' 172 end 173 174 local tak = function(o) 175 if taken(o) then 176 return ", taken" 177 end 178 return '' 179 end 180 181 for i, o in stead.opairs(inv()) do 182 if rc ~='' then rc = rc..'^' end 183 o = stead.ref(o) 184 rc = stead.cat(rc, stead.par(' ', 'Id: '..stead.tostr(o.id)..', '.. 185 stead.tostr(stead.deref(o))..': '..stead.tostr(stead.call(o, 'nam'))..dis(o)..tak(o))); 186 end 187 if rc == '' then return end 188-- seen('disp')._txt = rc 189 return rc 190end 191 192dbg_execute_cmd = room { 193 nam = "Execute Lua code", 194 debug = true, 195 pic = true, 196 system_type = true, 197 forcedsc = true, 198 dsc = "Enter Lua code here to exec.", 199 inp_enter = function(s) 200 if stead.type(s.obj[1]._txt) == 'string' then 201 local f = stead.eval(s.obj[1]._txt); 202 if f then 203 seen('disp')._txt = stead.cat('^^', f()); 204 return true 205 end 206 seen('disp')._txt = "^^Error in exec."; 207 return true 208 end 209 return stead.back(); 210 end, 211 obj = { inp('inp', '{Enter cmd}: ', 'return "Hello World!"'), 212 obj { nam = 'Back', dsc = '^{Back}', act = code [[ stead.back() ]] }, 213 dbg_disp_obj(), 214 }, 215 exit = function(s) 216 s.obj[1]:state(false) 217 end; 218} 219 220dbg_dump_object = room { 221 nam = "Dump object", 222 debug = true, 223 pic = true, 224 system_type = true, 225 forcedsc = true, 226 dsc = "Enter object name here to dump.", 227 inp_enter = function(s) 228 local w = s.obj[1]._txt 229 if stead.type(w) == 'string' then 230 if not stead.ref(w) then w = objs(dbg_here()):srch(w); end 231 return dbg_dump_obj(w); 232 end 233 return stead.back(); 234 end, 235 obj = { inp('inp', '{Enter object}: ', 'main'), 236 obj{nam = 'Here', dsc = '^{Dump here}', act = code[[ return dbg_dump_obj(dbg_here())]]}, 237 obj{nam = 'Player',dsc = '^{Dump player}', act = code[[ return dbg_dump_obj(stead.me())]]}, 238 obj{nam = 'Lifes', dsc = '^{Dump lifes}', act = code[[ return dbg_dump_obj(debug_tool.lifes)]]}, 239 obj{nam = 'Ways', dsc = '^{Dump ways}', act = code[[ return dbg_dump_obj(ways(dbg_here()))]]}, 240 obj{nam = 'Globals', dsc = '^{Dump globals}', act = code [[return dbg_dump_globals()]] }, 241 obj{nam = 'Back', dsc = '^{Back}', act = code [[ return stead.back() ]] }, 242 dbg_disp_obj() }, 243 exit = function(s) 244 s.obj[1]:state(false) 245 end; 246} 247 248dbg_choose_location = dlg { 249 debug = true, 250 pic = true, 251 system_type = true, 252 forcedsc = true, 253 nam = 'Go to', 254 dsc = 'Select location.', 255 gen = function(s) 256 objs(s):zap(); 257 for k, v, kk in spairs(_G) do 258 if isRoom(v) and not v.debug then 259 local n = stead.tostr(stead.call(v, 'nam')); 260 local o = kk; 261 if stead.type(o) == 'string' then 262 n = n..' : '..o; 263 n = _xref_escape(n); 264 put(phr(n, true, [[timer:set(debug_tool._timer); game.lifes:cat(debug_tool.lifes); return stead.walk(]]..o..[[)]]), s); 265 end 266 end 267 end 268 put (phr('Back',true, 'return stead.back()'), s) 269 end 270} 271 272dbg_choose_object = dlg { 273 debug = true, 274 pic = true, 275 system_type = true, 276 forcedsc = true, 277 nam = 'Get object', 278 dsc = 'Select object to get.', 279 gen = function(s) 280 objs(s):zap(); 281 for k, v, kk in spairs(_G) do 282 if isObject(v) and not isPhrase(v) and not isRoom(v) and not isPlayer(v) and not v.debug and not have(v) and not isStatus(v) then 283 local n = stead.tostr(stead.call(v, 'nam')); 284 local o = kk; 285 if stead.type(o) == 'string' then 286 n = n..' : '..o; 287 n = _xref_escape(n); 288 put(phr(n, true, o..':enable(); return take('..o..')'), s); 289 end 290 end 291 end 292 put (phr('Back',true, 'return stead.back()'), s) 293 end 294} 295 296dbg_drop_object = dlg { 297 debug = true, 298 pic = true, 299 forcedsc = true, 300 system_type = true, 301 nam = 'Drop object', 302 dsc = 'Select object to drop.', 303 gen = function(s) 304 objs(s):zap(); 305 for k, v in stead.ipairs(inv()) do 306 v = stead.ref(v); 307 if not v.debug then 308 local n = stead.tostr(stead.call(v, 'nam')); 309 local o = stead.deref(v); 310 if stead.type(o) == 'string' then 311 n = n..' : '..o; 312 n = _xref_escape(n); 313 put (phr(n, true, o..':enable(); drop('..o..','..stead.deref(dbg_here())..')'), s) 314 end 315 end 316 end 317 put (phr('Back', true, 'return stead.back()'), s) 318 end 319} 320 321function dbg_exit() 322 local r 323 if not stead.api_atleast(1, 2, 0) then 324 r = stead.call(dbg_here(), 'dsc'); 325 end 326 game.lifes:cat(debug_tool.lifes); 327 timer:set(debug_tool._timer); 328 return stead.par ('^^', stead.back(), r); 329end 330 331debug_dlg = dlg { 332 debug = true, 333 pic = true, 334 system_type = true, 335 forcedsc = true, 336 nam = 'Debug Tool', 337 dsc = 'Select tool.', 338 obj = { 339 phr('Go to location...', true, [[pon(); dbg_choose_location:gen(); return stead.walk('dbg_choose_location')]]), 340 phr('Get object...', true, [[pon(); dbg_choose_object:gen(); return stead.walk('dbg_choose_object')]]), 341 phr('Put object...', true, [[pon(); dbg_drop_object:gen(); return stead.walk('dbg_drop_object')]]), 342 phr('Current scene...', true, [[pon(); return dbg_list_objects();]]), 343 phr('Inventory...', true, [[pon(); return dbg_list_inv();]]), 344 phr('Dump object...', true, [[pon(); return stead.walk(dbg_dump_object);]]), 345 phr('Exec Lua string...', true, [[pon(); return stead.walk('dbg_execute_cmd')]]), 346 phr('Exit',true , [[pon(); return dbg_exit()]]), 347 }, 348}; 349 350debug_tool = menu { 351 debug = true, 352 system_type = true, 353 forcedsc = true, 354 nam = txtb('debug'), 355 lifes = list {}, 356 inv = function(s) 357 if stead.here().debug then 358 return nil, true --nothing todo 359 end 360 debug_dlg.__from__ = stead.here(); 361 s._timer = timer:get(); 362 timer:stop(); 363 s.lifes:zap(); 364 s.lifes:cat(game.lifes); 365 game.lifes:zap(); 366 s._here = stead.here(); 367 stead.me().where = 'debug_dlg'; -- force to go 368 return stead.walk(self.where); 369 end, 370}; 371 372game.action = stead.hook(game.action, 373function (f, s, cmd, ...) 374 if cmd == 'use_debug' then 375 return debug_tool:inv() 376 elseif cmd == 'exit_debug' then 377 stead.me().where = 'debug_dlg'; 378 dbg_execute_cmd.obj[1]:state(false) 379 dbg_dump_object.obj[1]:state(false) 380 return dbg_exit() 381 end 382 return f(s, cmd, ...) 383end) 384 385stead.module_init(function() 386 input.key = stead.hook(input.key, 387 function(f, s, down, key, ...) 388 if down and key == 'f7' then 389 if stead.here().debug then 390 return 'exit_debug' 391 else 392 return 'use_debug' 393 end 394 end 395 396 return f(s, down, key, ...) 397 end) 398 putf('debug_tool', stead.me()); 399end) 400 401 402-- vim:ts=4 403