mirror of
https://github.com/wesnoth/wesnoth
synced 2025-04-27 15:01:42 +00:00

variable v does not exist... the function is not commented so I can't be sure of the intention, but the most backwards-compatible fix is to not pass argument v, so that it will be nil as before. this bug was revealed by enabling lua "strict mode"
188 lines
3.6 KiB
Lua
188 lines
3.6 KiB
Lua
local location_set = {}
|
|
|
|
local function index(x, y)
|
|
-- the 2000 bias ensure that the correct x is recovered for negative y
|
|
return x * 16384 + y + 2000
|
|
end
|
|
|
|
local invscale = 1 / 16384
|
|
local function revindex(p)
|
|
local x = math.floor(p * invscale)
|
|
return x, p - x * 16384 - 2000
|
|
end
|
|
|
|
local methods = {}
|
|
local locset_meta = { __index = methods }
|
|
|
|
function methods:empty()
|
|
return (not next(self.values))
|
|
end
|
|
|
|
function methods:size()
|
|
local sz = 0
|
|
for p,v in pairs(self.values) do
|
|
sz = sz + 1
|
|
end
|
|
return sz
|
|
end
|
|
|
|
function methods:clear()
|
|
self.values = {}
|
|
end
|
|
|
|
function methods:get(x, y)
|
|
return self.values[index(x, y)]
|
|
end
|
|
|
|
function methods:insert(x, y, v)
|
|
self.values[index(x, y)] = v or true
|
|
end
|
|
|
|
function methods:remove(x, y)
|
|
self.values[index(x, y)] = nil
|
|
end
|
|
|
|
function methods:union(s)
|
|
local values = self.values
|
|
for p,v in pairs(s.values) do
|
|
values[p] = v
|
|
end
|
|
end
|
|
|
|
function methods:union_merge(s, f)
|
|
local values = self.values
|
|
for p,v in pairs(s.values) do
|
|
local x, y = revindex(p)
|
|
values[p] = f(x, y, values[p], v)
|
|
end
|
|
end
|
|
|
|
function methods:inter(s)
|
|
local values = self.values
|
|
local nvalues = {}
|
|
for p,v in pairs(s.values) do
|
|
nvalues[p] = values[p]
|
|
end
|
|
self.values = nvalues
|
|
end
|
|
|
|
function methods:inter_merge(s, f)
|
|
local values = s.values
|
|
local nvalues = {}
|
|
for p,v in pairs(self.values) do
|
|
local x, y = revindex(p)
|
|
nvalues[p] = f(x, y, v, values[p])
|
|
end
|
|
self.values = nvalues
|
|
end
|
|
|
|
function methods:filter(f)
|
|
local nvalues = {}
|
|
for p,v in pairs(self.values) do
|
|
local x, y = revindex(p)
|
|
if f(x, y, v) then nvalues[p] = v end
|
|
end
|
|
return setmetatable({ values = nvalues }, locset_meta)
|
|
end
|
|
|
|
function methods:iter(f)
|
|
for p,v in pairs(self.values) do
|
|
local x, y = revindex(p)
|
|
f(x, y, v)
|
|
end
|
|
end
|
|
|
|
function methods:stable_iter(f)
|
|
local indices = {}
|
|
for p,v in pairs(self.values) do
|
|
table.insert(indices, p)
|
|
end
|
|
table.sort(indices)
|
|
for i,p in ipairs(indices) do
|
|
local x, y = revindex(p)
|
|
f(x, y)
|
|
end
|
|
end
|
|
|
|
function methods:of_pairs(t)
|
|
local values = self.values
|
|
|
|
for i,v in ipairs(t) do
|
|
local value_table = {}
|
|
local x_index
|
|
local y_index
|
|
if v.x and v.y then
|
|
x_index = "x"
|
|
y_index = "y"
|
|
else
|
|
x_index = 1
|
|
y_index = 2
|
|
end
|
|
for k,val in pairs(v) do
|
|
if k ~= x_index and k ~= y_index then
|
|
value_table[k] = val
|
|
end
|
|
end
|
|
if next(value_table) then
|
|
values[index(v[x_index], v[y_index])] = value_table
|
|
else
|
|
values[index(v[x_index], v[y_index])] = true
|
|
end
|
|
end
|
|
end
|
|
|
|
function methods:of_wml_var(name)
|
|
local values = self.values
|
|
for i = 0, wesnoth.get_variable(name .. ".length") - 1 do
|
|
local t = wesnoth.get_variable(string.format("%s[%d]", name, i))
|
|
local x, y = t.x, t.y
|
|
t.x, t.y = nil, nil
|
|
values[index(x, y)] = next(t) and t or true
|
|
end
|
|
end
|
|
|
|
function methods:to_pairs()
|
|
local res = {}
|
|
self:iter(function(x, y) table.insert(res, { x, y }) end)
|
|
return res
|
|
end
|
|
|
|
function methods:to_stable_pairs()
|
|
local res = {}
|
|
self:stable_iter(function(x, y) table.insert(res, { x, y }) end)
|
|
return res
|
|
end
|
|
|
|
function methods:to_wml_var(name)
|
|
local i = 0
|
|
wesnoth.set_variable(name)
|
|
self:stable_iter(function(x, y, v)
|
|
if type(v) == 'table' then
|
|
wesnoth.set_variable(string.format("%s[%d]", name, i), v)
|
|
end
|
|
wesnoth.set_variable(string.format("%s[%d].x", name, i), x)
|
|
wesnoth.set_variable(string.format("%s[%d].y", name, i), y)
|
|
i = i + 1
|
|
end)
|
|
end
|
|
|
|
function location_set.create()
|
|
local w,h,b = wesnoth.get_map_size()
|
|
assert(h + 2 * b < 9000)
|
|
return setmetatable({ values = {} }, locset_meta)
|
|
end
|
|
|
|
function location_set.of_pairs(t)
|
|
local s = location_set.create()
|
|
s:of_pairs(t)
|
|
return s
|
|
end
|
|
|
|
function location_set.of_wml_var(name)
|
|
local s = location_set.create()
|
|
s:of_wml_var(name)
|
|
return s
|
|
end
|
|
|
|
return location_set
|