local callback_off = false; -- Remember all, delete all, rebuild all as it was -- (well, at least with a similarity we can achieve for now) function rebuild_all() local units, cities, tn, cn = {}, {}, {}, {} local cqrr local restore_unit -- Don't cascade if callback_off then return false else callback_off = true end restore_unit = function(i) if "table" == type(units[i]) then local trr = units[i][8] units[i][5] = cities[units[i][5]] if trr then units[i][8] = restore_unit(trr) end -- hm, unpack() is missing in Freeciv Lua??? units[i] = edit.create_unit_full (units[i][1], units[i][2], units[i][3], units[i][4], units[i][5], units[i][6], units[i][7], units[i][8]) end return units[i] end -- Destroy a city on tile ct from tile t, set cqrr that can do it -- pc is city owner, p is a player at war local function destroy_city(p, pc, t, ct) local ut = cqrr local i = 0 local u local pu = pc local sz = ct:city().size repeat if u and u:exists() then --Unsuitable conqueror u:kill("editor") end if ut then u = edit.create_unit(p, t, cqrr, 0, nil, -1) end if not u then -- Find a conqueror that can exist here. -- We have no way to know if a unit can conquer a city, so try and see while true do ut = find.unit_type(i) if not ut then -- can't conquer from here by anything! return false end i = i + 1 end else u:move(ct, 3--[[just a random cost]]) end until u and u.tile == ct u:kill("editor") cqrr = ut if ct:city().size >= sz then -- Bad player p! return nil end while ct:city() do u = edit.create_unit(pu, t, cqrr, 0, nil, -1) u:move(ct, 3--[[just a random cost]]) u:kill("editor") if pu == p then pu = pc else pu = p end end return true end -- Fix what we can for p in players_iterate() do local i = 1 for c in p:cities_iterate() do table.insert(cities, {p, c.tile, c.name--[[, c.size, c.buildings??]]}) cn[c] = #cities end for u in p:units_iterate() do table.insert(units, {p, u.tile, u.utype, 0--[[u.veteran]], cn[u:get_homecity()], -1--[[u.moves_left]], -1--[[u.hp]]}) tn[u] = {#units, 0} end for u in p:units_iterate() do local t = u:transporter() if t then local ttn = tn[t] units[i][8] = ttn[1] ttn[2] = ttn[2] + 1 end i = i+1 end end -- Ensure we have a barbarian player that will be at war with everybody for t in whole_map_iterate() do if not t:city() and t:num_units() == 0 then t:unleash_barbarians() break end end -- Now, clear the map. -- Remove units. Try no to sink anything, just delete it for p in players_iterate() do -- Recursively delete transported units while p:num_units() > 0 do for u in p:units_iterate() do if not tn[u] or tn[u][2] == 0 then local t = u:transporter() if t and tn[t] then tn[t][2] = tn[t][2] - 1 end u:kill("editor") end end end end -- Remove the cities. -- We don't have the method, so just act so that they disappear -- Well, some cities can't be destroyed that simple, forget it for p in players_iterate() do local paw for c in p:cities_iterate() do local ct = c.tile if not paw then -- Find a player at war for pw in players_iterate() do if pw ~= p then for at in ct:square_iterate(1) do if at ~= ct then if destroy_city(pw, p, at, ct) then paw = pw break --square_iterate end end end if paw then break --players_iterate /inner/ end end end --players_iterate /inner/ else for at in ct:square_iterate(1) do if at ~= ct then if destroy_city(paw, p, at, ct) then break --square_iterate end end end end --if end --cities_iterate end --players_iterate -- Now, rebuild what we have cleaned... or something for i = 1, #cities do local xc = cities[i][2]:city() if xc then cities[i] = xc else cities[i] = edit.create_city(cities[i][1], cities[i][2], cities[i][3]) end end for i = 1, #units do -- Recursively generate transports before cargo restore_unit(i) end callback_off = false return false end