add wesnoth.interface.get_items

returns all items on a locations, this allows is to
remove quite a bit of code in the dropping.lua file
of world conquest since that can now just use items.lua
instead
This commit is contained in:
gfgtdf 2020-08-26 14:39:23 +02:00
parent 13034131bd
commit 2a5ba5ace7
4 changed files with 57 additions and 148 deletions

View File

@ -51,11 +51,13 @@ end
-- place an artifact with id @a index on the map at position @a x, y.
-- can be used from the bug console as `lua wc2_artifacts.place_item(30,20,1)`
function artifacts.place_item(x, y, index)
wc2_dropping.add_item(x, y, {
wc2_atrifact_id = index,
wesnoth.wml_actions.item {
x = x,
y = y,
image = artifacts.get_artifact(index).icon,
z_order = 20,
})
wml.tag.variables { wc2_atrifact_id = index },
}
end
-- give te item with id @a index to unit @a unit, set @a visualize=true, to show the item pickup animation.
@ -120,7 +122,7 @@ end
on_event("wc2_drop_pickup", function(ec)
local item = wc2_dropping.current_item
local unit = wesnoth.get_unit(ec.x1, ec.y1)
if not item.wc2_atrifact_id then
if not item.variables.wc2_atrifact_id then
return
end
@ -135,7 +137,7 @@ on_event("wc2_drop_pickup", function(ec)
end
local index = item.wc2_atrifact_id
local index = item.variables.wc2_atrifact_id
local filter = artifacts.get_artifact(index).filter
if filter and not unit:matches(filter) then
if is_human then
@ -195,8 +197,8 @@ end)
-- returns true if there is an item in the map at the given position,
-- used to determine whether to show the artifact info menu at that position.
function artifacts.is_item_at(x,y)
for i,item in ipairs(wc2_dropping.get_entries_at_readonly(x,y)) do
if item.wc2_atrifact_id then
for i,item in ipairs(wesnoth.interface.get_items(x,y)) do
if item.variables.wc2_atrifact_id then
return true
end
end
@ -208,9 +210,9 @@ end
function wesnoth.wml_actions.wc2_show_item_info(cfg)
local x = cfg.x
local y = cfg.y
for i,item in ipairs(wc2_dropping.get_entries_at_readonly(x,y)) do
if item.wc2_atrifact_id then
local artifact_info = artifacts.get_artifact(item.wc2_atrifact_id)
for i,item in ipairs(wesnoth.interface.get_items(x,y)) do
if item.variables.wc2_atrifact_id then
local artifact_info = artifacts.get_artifact(item.variables.wc2_atrifact_id)
wesnoth.wml_actions.message {
scroll = false,
image = artifact_info.icon,

View File

@ -43,11 +43,13 @@ function bonus.place_item(x, y, image)
image = image or "scenery/lighthouse.png"
end
wc2_dropping.add_item(x, y, {
wc2_is_bonus = true,
wesnoth.wml_actions.item {
x = x,
y = y,
image = image,
z_order = 10,
})
wml.tag.variables { wc2_is_bonus = true },
}
end
function bonus.remove_current_item(ec)
@ -85,7 +87,7 @@ on_event("wc2_drop_pickup", function(ec)
local item = wc2_dropping.current_item
local side_num = wesnoth.current.side
if not item.wc2_is_bonus then
if not item.variables.wc2_is_bonus then
return
end

View File

@ -6,151 +6,27 @@ local on_event = wesnoth.require("on_event")
local dropping = {}
dropping.field_data = {}
dropping.loc_to_index = function(x,y)
return (y - 1) * 1000 + x
end
dropping.index_to_loc = function(index)
local y_m1 = math.floor(index / 1000)
return index - y_m1 * 1000, y_m1 + 1
end
dropping.decorate_imagename = function(id)
return "wc2_item_" .. id
end
dropping.place_image = function(x, y, cfg)
wesnoth.add_tile_overlay(x, y, {
image = cfg.image,
team_name = cfg.team_name,
visible_in_fog = cfg.visible_in_fog,
redraw = cfg.redraw,
name = dropping.decorate_imagename(cfg.id),
z_order = cfg.z_order
})
end
-- this can be used to remove item but not to add items.
dropping.get_entries_at_readonly = function(x,y)
return dropping.field_data[dropping.loc_to_index(x,y)] or {}
end
dropping.get_entries_at_readwrite = function(x,y)
local index = dropping.loc_to_index(x,y)
dropping.field_data[index] = dropping.field_data[index] or {}
return dropping.field_data[index]
end
dropping.remove_empty_lists = function()
local to_delete = {}
for k,v in pairs(dropping.field_data) do
if #v == 0 then
to_delete[k] = true
end
end
for k,v in pairs(to_delete) do
dropping.field_data[k] = nil
end
end
dropping.add_item = function(x, y, cfg)
table.insert(dropping.get_entries_at_readwrite(x,y), cfg)
cfg.id = dropping.next_id
dropping.next_id = dropping.next_id + 1
dropping.place_image(x, y, cfg)
end
dropping.remove_item = function(x, y, id)
local entries = dropping.get_entries_at_readwrite(x,y)
for i,v in ipairs(entries) do
if v.id == id then
wesnoth.remove_tile_overlay(x, y, dropping.decorate_imagename(id))
table.remove(entries, i)
break
end
end
end
dropping.remove_all_items = function(filter)
for k,v in pairs(dropping.field_data) do
local start = #v
local x, y = dropping.index_to_loc(k)
for i = start, 1, -1 do
if filter(v[i], x, y) then
wesnoth.remove_tile_overlay(x, y, dropping.decorate_imagename(v[i].id))
table.remove(v, i)
end
end
end
end
dropping.remove_current_item = function()
local v = dropping.current_item
local ec = wesnoth.current.event_context
wesnoth.remove_tile_overlay(ec.x1, ec.y1, dropping.decorate_imagename(v.id))
wesnoth.interface.remove_item(ec.x1, ec.y1, dropping.current_item.name)
dropping.item_taken = true
end
wesnoth.persistent_tags.wc2_dropping.write = function(add)
local res = {
next_id = dropping.next_id,
}
for i,v in pairs(dropping.field_data) do
local x,y = dropping.index_to_loc(i)
for i2,v2 in ipairs(v) do
table.insert(res, wml.tag.item {
x = x,
y = y,
wml.tag.data (v2)
})
end
end
add(res)
end
-- read might not be called if there is no [dropped_items] tag found
wesnoth.persistent_tags.wc2_dropping.read = function(cfg)
for item in wml.child_range(cfg, "item") do
local hex_list = dropping.get_entries_at_readwrite(item.x, item.y)
table.insert(hex_list, (wml.get_child(item, "data")))
end
dropping.next_id = cfg.next_id or 0
dropping.remove_empty_lists()
end
on_event("moveto", function(event_context)
local x = event_context.x1
local y = event_context.y1
local entries = dropping.get_entries_at_readonly(x,y)
local i = 1
while i <= #entries do
local v = entries[i]
dropping.current_item = v
local items = wesnoth.interface.get_items(x, y)
for i, item in ipairs(items) do
dropping.current_item = item
dropping.item_taken = nil
wesnoth.fire_event("wc2_drop_pickup", x, y)
if dropping.item_taken then
table.remove(entries, i)
wesnoth.remove_tile_overlay(x, y, dropping.decorate_imagename(v.id))
wesnoth.allow_undo(false)
else
i = i + 1
wesnoth.interface.remove_item(x,y, item.name)
end
dropping.current_item = nil
dropping.item_taken = nil
end
end)
on_event("preload", function()
dropping.next_id = dropping.next_id or 0
for k,v in pairs(dropping.field_data) do
local x,y = dropping.index_to_loc(k)
for i, cfg in ipairs(v) do
dropping.place_image(x, y, cfg)
end
end
end)
return dropping

View File

@ -2,7 +2,14 @@ local wml_actions = wesnoth.wml_actions
local scenario_items = (wesnoth.require "location_set").create()
local next_item_name = 0
local function add_overlay(x, y, cfg)
if not cfg.name then
cfg.name = "item_" .. tostring(next_item_name)
next_item_name = next_item_name + 1
end
wesnoth.interface.add_hex_overlay(x, y, cfg)
local items = scenario_items:get(x, y)
if not items then
@ -20,6 +27,7 @@ local function add_overlay(x, y, cfg)
redraw = cfg.redraw,
name = cfg.name,
z_order = cfg.z_order,
wml.tag.variables(wml.get_child(cfg, "variables") or {}),
})
end
@ -40,6 +48,28 @@ function wesnoth.interface.remove_item(x, y, name)
end
end
function wesnoth.interface.get_items(x, y)
local res = {}
local items = scenario_items:get(x, y) or {}
for i = 1,#items do
local cfg = items[i]
-- make a copy, since modifying these values (except variabels) wouldn't work anyways.
table.insert( res, {
x = cfg.x, y = cfg.y,
image = cfg.image,
halo = cfg.halo,
team_name = cfg.team_name,
filter_team = cfg.filter_team,
visible_in_fog = cfg.visible_in_fog,
redraw = cfg.redraw,
name = cfg.name,
z_order = cfg.z_order,
variables = wml.get_child(cfg, "variables"),
})
end
return res
end
function wesnoth.persistent_tags.item.write(add)
for x,y,v in scenario_items:iter() do
for i,w in ipairs(v) do
@ -53,6 +83,7 @@ function wesnoth.persistent_tags.next_item_name.write(add)
end
function wesnoth.persistent_tags.item.read(cfg)
if not cfg.name then cfg.name = "" end
add_overlay(cfg.x, cfg.y, cfg)
end
@ -60,13 +91,11 @@ function wesnoth.persistent_tags.next_item_name.read(cfg)
next_item_name = cfg.next_item_name or next_item_name
end
-- returns the 'name' of an item, this can be used as an id to remove the iten later.
function wml_actions.item(cfg)
local locs = wesnoth.get_locations(cfg)
cfg = wml.parsed(cfg)
if not cfg.name then
cfg.name = "item_" .. tostring(next_item_name)
next_item_name = next_item_name + 1
end
if not cfg.image and not cfg.halo then
wml.error "[item] missing required image= and halo= attributes."
end