-- nef version 2 20211221 function _freeciv_state_dump() local script = "" -- toggle comment on next line for lang. support in Npp etc.. .. [[ local sc = {n=0;ul="unit_lost"} for s, n in function(sc)return find.signal_callback (sc.ul,0), sc.n +1 end, sc, nil do sc[n] = s; sc.n = n; signal.remove (sc.ul,s ) end local f = (function() for p in players_iterate () do for i, itr in ipairs {p.cities_iterate, p.units_iterate} do for uc in itr(p) do if uc.tile then local id, T = 0 repeat T = find.unit_type (id); id = id +1 if T and T:can_exist_at_tile(uc.tile) then return {p = p, t = uc.tile, T = T} end until not T end end end end end) () local ne = setmetatable ( {find.nonexistent ()}, {__index = function (t, a) -- upvalue: f local unit = assert( f and edit.create_unit (f.p, f.t, f.T, 0, nil, -1), "No suitable player to restore Nonexistent") edit.unit_kill (unit, "used", f.p); t[a] = unit; return t[a] end} ) local index = function (t, a) t[a] = {}; return t[a] end; local t = setmetatable ( {_ENV}, { __call = function (t, im, ...) local m = t[im] for i, a in ipairs ({...}) do m = setmetatable (t[a],m) end return m end; __index = index; } ) for n, s in ipairs(sc) do signal.connect(sc.ul,s) end local sc = setmetatable({},{__index = index;} ) -- ]] .."\n" -- *******end of the vars script prologue********* local TT -- forward local ri = {_ENV} local t1 = setmetatable ( { [ri[1]] = 1; n = 1; rollback = function (t1) t1.t2 = {}; getmetatable(t1).__index = t1.t2; t1.r = t1.n end; commit = function (t1, ri) for tbl, inx in pairs (t1.t2) do t1[tbl] = inx; ri[inx] = tbl end; t1.n = t1.r end; newset = function (t1, da) if not t1[da] then t1.r = t1.r +1; t1.t2[da] = t1.r end return t1[da] end; getmeta = function (da) da = getmetatable(da); return type (da) == "table" and da end; } , { __call = function (t1, da) local d, x = da, {} repeat d = t1.getmeta(d) if d then d = rawget(d, "_fc_keep") else return {} end local T = type(d); if T ~= "table" then if (TT [T](d)).text then break else return {} end else if x[d] then break else x[d]=true end end until false local s, dx = {} while da do -- beware side effect in newset dx = not t1[da] and t1.getmeta (da) table.insert (s, 1, t1:newset(da)); da = dx end; return {text = "t("..table.concat(s, ", ")..")"} end; -- __call } ) local function get_text(da) if not da:find ("[%c\x80-\xFF]") then return ("%q"):format(da) end -- else local s= {}; for i = 1, #da do s[i] = da:byte (i) end return "string.char("..table.concat(s, ", ")..")" end local NE = setmetatable ( {[find.nonexistent ()] = 1;n=1}, {__index = function (t, a) t.n = t.n + 1; t[a] = t.n; return t.n end;} ) local p2 = {Unit = "nil, "; City = "nil, ";} local n_list ={direction = true;} local no_text = function (da) return {} end local text_ok = function (da) return {text= ("%q"):format(da)} end TT = setmetatable ( { -- table first boolean = text_ok; number = text_ok; -- number = function (da) return {text= ("%s"):format(da)} end; -- number = function (da) return {text= da} end; thread = no_text; ["function"] = no_text; ["nil"] = no_text; table = t1; -- see __call in t1 metatable userdata = function (da) -- upvalues: p2, NE, n_list local Type = tolua.type (da); local l_ud = Type:lower() local rule, name, id = da.rule_name, da.name, da.id return { text = Type == "Nonexistent" and "ne["..NE[da].."]" or find [l_ud] and (rule or name or id) and "find."..l_ud.."(".. ( rule and ("%q"):format(da:rule_name()) or ( name and n_list [l_ud] and ("%q"):format(name)) or --[[id and]] (p2[Type] or "")..(math.floor(id)) )..")" } end; string = function (da) return { text = get_text(da), us = da:find ("^_[%w_]*$") } end; }, { -- now metatable __call = function (tt, da) return tt [type(da)] (da) end; } ) -- TT [] for inx, tbl in ipairs (ri) do for ca, cd in next, tbl, nil do t1:rollback() local a, d = TT (ca), TT (cd) if a.text and (inx > 1 or not a.us) and d.text then t1:commit (ri); script = script.. "rawset(t["..inx.."], "..a.text..", "..d.text.."); \n" end end -- in next end -- in ipairs for s_id, ss in (function (s, s_id) s_id = s_id + 1 local ss = find.signal (s_id) return ss and s_id, ss end), nil, -1 do for c_id, cf in (function (ss, c_id) c_id = c_id + 1 local cf = find.signal_callback (ss, c_id) return cf and c_id, cf end), ss, -1 do script = script..(("sc[%s][%s] = "..get_text(cf).."; \n"):format(s_id, c_id)) end; -- for c_id, cf end -- for s_id, ss return script.."if type(_fc_restore)=='function' then _fc_restore(t,ne,sc) end\n" end