move set_variable.rand's logic to helper.rand
This commit is contained in:
parent
34d78f2a2a
commit
1d8d843a80
2 changed files with 85 additions and 75 deletions
|
@ -380,10 +380,82 @@ function helper.shallow_parsed(cfg)
|
|||
end
|
||||
|
||||
function helper.rand (possible_values)
|
||||
wml_actions.set_variable({ name = "LUA_rand", rand = possible_values })
|
||||
local result = wesnoth.get_variable("LUA_rand")
|
||||
wesnoth.set_variable("LUA_rand")
|
||||
return result
|
||||
assert(type(possible_values) == "table" or type(possible_values) == "string", string.format("helper.rand expects a string or table as parameter, got %s instead", type(possible_values)))
|
||||
|
||||
local items = {}
|
||||
local num_choices = 0
|
||||
|
||||
if type(possible_values) == "string" then
|
||||
-- split on commas
|
||||
for word in possible_values:gmatch("[^,]+") do
|
||||
-- does the word contain two dots? If yes, that's a range
|
||||
local dots_start, dots_end = word:find("%.%.")
|
||||
if dots_start then
|
||||
-- split on the dots if so and cast as numbers
|
||||
local low = tonumber(word:sub(1, dots_start-1))
|
||||
local high = tonumber(word:sub(dots_end+1))
|
||||
-- perhaps someone passed a string as part of the range, intercept the issue
|
||||
if not (low and high) then
|
||||
wesnoth.message("Malformed range: " .. possible_values)
|
||||
table.insert(items, word)
|
||||
num_choices = num_choices + 1
|
||||
else
|
||||
if low > high then
|
||||
-- low is greater than high, swap them
|
||||
low, high = high, low
|
||||
end
|
||||
|
||||
-- if both ends represent the same number, then just use that number
|
||||
if low == high then
|
||||
table.insert(items, low)
|
||||
num_choices = num_choices + 1
|
||||
else
|
||||
-- insert a table representing the range
|
||||
table.insert(items, {low, high})
|
||||
-- how many items does the range contain? Increase difference by 1 because we include both ends
|
||||
num_choices = num_choices + (high - low) + 1
|
||||
end
|
||||
end
|
||||
else
|
||||
-- handle as a string
|
||||
table.insert(items, word)
|
||||
num_choices = num_choices + 1
|
||||
end
|
||||
end
|
||||
else
|
||||
num_choices = #possible_values
|
||||
items = possible_values
|
||||
-- We need to parse ranges separately anyway
|
||||
for i, val in ipairs(possible_values) do
|
||||
if type(val) == "table" then
|
||||
assert(#val == 2 and type(val[1]) == "number" and type(val[2]) == "number", "Malformed range for helper.rand")
|
||||
if val[1] > val[2] then
|
||||
val = {val[2], val[1]}
|
||||
end
|
||||
num_choices = num_choices + (val[2] - val[1])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local idx = wesnoth.random(1, num_choices)
|
||||
|
||||
for i, item in ipairs(items) do
|
||||
if type(item) == "table" then -- that's a range
|
||||
local elems = item[2] - item[1] + 1 -- amount of elements in the range, both ends included
|
||||
if elems >= idx then
|
||||
return item[1] + elems - idx
|
||||
else
|
||||
idx = idx - elems
|
||||
end
|
||||
else -- that's a single element
|
||||
idx = idx - 1
|
||||
if idx == 0 then
|
||||
return item
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
function helper.deprecate(msg, f)
|
||||
|
|
|
@ -38,7 +38,7 @@ function wml_actions.sync_variable(cfg)
|
|||
local variable_type = string.sub(name, string.len(name)) == "]" and "indexed" or ( wesnoth.get_variable(name .. ".length") > 0 and "array" or "attribute")
|
||||
local variable_info = { name = name, type = variable_type }
|
||||
table.insert(res, { "variable", variable_info })
|
||||
if variable_type == "indexed" then
|
||||
if variable_type == "indexed" then
|
||||
table.insert(variable_info, { "value", wesnoth.get_variable(name) } )
|
||||
elseif variable_type == "array" then
|
||||
for i = 1, wesnoth.get_variable(name .. ".length") do
|
||||
|
@ -53,7 +53,7 @@ function wml_actions.sync_variable(cfg)
|
|||
)
|
||||
for variable in helper.child_range(result, "variable") do
|
||||
local name = variable.name
|
||||
|
||||
|
||||
if variable.type == "indexed" then
|
||||
wesnoth.set_variable(name, variable[1][2])
|
||||
elseif variable.type == "array" then
|
||||
|
@ -269,7 +269,7 @@ end
|
|||
-- This is mainly for use in unit test macros, but maybe it can be useful elsewhere too
|
||||
function wml_actions.test_condition(cfg)
|
||||
local logger = cfg.logger or "warning"
|
||||
|
||||
|
||||
-- This function returns true if it managed to explain the failure
|
||||
local function explain(current_cfg, expect)
|
||||
for i,t in ipairs(current_cfg) do
|
||||
|
@ -313,7 +313,7 @@ function wml_actions.test_condition(cfg)
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- Use not twice here to convert nil to false
|
||||
explain(cfg, not not cfg.result)
|
||||
end
|
||||
|
@ -398,7 +398,7 @@ function wml_actions.store_unit(cfg)
|
|||
--cache the needed units here, since the filter might reference the to-be-cleared variable(s)
|
||||
local units = wesnoth.get_units(filter)
|
||||
local recall_units = wesnoth.get_recall_units(filter)
|
||||
|
||||
|
||||
local writer = utils.vwriter.init(cfg, "unit")
|
||||
|
||||
for i,u in ipairs(units) do
|
||||
|
@ -687,7 +687,7 @@ end
|
|||
|
||||
-- This is the port of the old [modify_ai] into lua. It is different from wesnoth.modify_ai in that it uses a standard side filter.
|
||||
-- I don't know why these functions were made to behave differently, but this seems to be the more powerful and useful one according
|
||||
-- to mattsc's comments
|
||||
-- to mattsc's comments
|
||||
function wml_actions.modify_ai(cfg)
|
||||
wesnoth.modify_ai_wml(cfg)
|
||||
end
|
||||
|
@ -764,7 +764,7 @@ end
|
|||
function wml_actions.put_to_recall_list(cfg)
|
||||
local units = wesnoth.get_units(cfg)
|
||||
|
||||
for i, unit in ipairs(units) do
|
||||
for i, unit in ipairs(units) do
|
||||
if cfg.heal then
|
||||
unit.hitpoints = unit.max_hitpoints
|
||||
unit.moves = unit.max_moves
|
||||
|
@ -990,7 +990,7 @@ wml_actions.unstore_unit = function(cfg)
|
|||
if unit_cfg.gender == "female" then
|
||||
text = cfg.female_text or cfg.text
|
||||
else
|
||||
text = cfg.male_text or cfg.text
|
||||
text = cfg.male_text or cfg.text
|
||||
end
|
||||
local color = cfg.color
|
||||
if color == nil and cfg.red and cfg.blue and cfg.green then
|
||||
|
@ -1138,69 +1138,7 @@ function wml_actions.set_variable(cfg)
|
|||
end
|
||||
|
||||
if cfg.rand then
|
||||
local random_string = tostring(cfg.rand)
|
||||
local num_choices = 0
|
||||
local items = {}
|
||||
|
||||
-- split on commas
|
||||
for word in random_string:gmatch("[^,]+") do
|
||||
-- does the word contain two dots? If yes, that's a range
|
||||
local dots_start, dots_end = word:find("%.%.")
|
||||
if dots_start then
|
||||
-- split on the dots if so and cast as numbers
|
||||
local low = tonumber(word:sub(1, dots_start-1))
|
||||
local high = tonumber(word:sub(dots_end+1))
|
||||
-- perhaps someone passed a string as part of the range, intercept the issue
|
||||
if not (low and high) then
|
||||
wesnoth.message("<WML>","Malformed range: rand " .. cfg.rand)
|
||||
table.insert(items, word)
|
||||
num_choices = num_choices + 1
|
||||
else
|
||||
if low > high then
|
||||
-- low is greater than high, swap them
|
||||
low, high = high, low
|
||||
end
|
||||
|
||||
-- if both ends represent the same number, then just use that number
|
||||
if low == high then
|
||||
table.insert(items, low)
|
||||
num_choices = num_choices + 1
|
||||
else
|
||||
-- insert a table representing the range
|
||||
table.insert(items, {low, high})
|
||||
-- how many items does the range contain? Increase difference by 1 because we include both ends
|
||||
num_choices = num_choices + (high - low) + 1
|
||||
end
|
||||
end
|
||||
else
|
||||
-- handle as a string
|
||||
table.insert(items, word)
|
||||
num_choices = num_choices + 1
|
||||
end
|
||||
end
|
||||
|
||||
local idx = wesnoth.random(1, num_choices)
|
||||
local done = false
|
||||
|
||||
for i, item in ipairs(items) do
|
||||
if type(item) == "table" then -- that's a range
|
||||
local elems = item[2] - item[1] + 1 -- amount of elements in the range, both ends included
|
||||
if elems >= idx then
|
||||
wesnoth.set_variable(name, item[1] + elems - idx)
|
||||
done = true
|
||||
break
|
||||
else
|
||||
idx = idx - elems
|
||||
end
|
||||
else -- that's a single element
|
||||
idx = idx - 1
|
||||
if idx == 0 then
|
||||
wesnoth.set_variable(name, item)
|
||||
done = true
|
||||
end
|
||||
end
|
||||
if done then break end
|
||||
end
|
||||
wesnoth.set_variable(name, helper.rand(tostring(cfg.rand)))
|
||||
end
|
||||
|
||||
local join_child = helper.get_child(cfg, "join")
|
||||
|
|
Loading…
Add table
Reference in a new issue