Shroud is Slow

Discussion of Lua and LuaWML support, development, and ideas.

Moderator: Forum Moderators

Post Reply
SoftSilkLionMilk
Posts: 3
Joined: December 7th, 2022, 2:13 am

Shroud is Slow

Post by SoftSilkLionMilk »

My scenario starts off by generating 2700 hexes. This takes less than a minute.
Every turn, I move 2700 hexes and generate 180. This takes a few seconds.

But when I try to individually move 2700 tiles worth of shroud, it takes more than a minute. Why???

It would be awesome if this was fixed. Also, there might be a workaround where I modify the shroud once... can anybody point me to a mod with some advanced shroud manipulation? Thanks.
User avatar
Pentarctagon
Project Manager
Posts: 5496
Joined: March 22nd, 2009, 10:50 pm
Location: Earth (occasionally)

Re: Shroud is Slow

Post by Pentarctagon »

Moved to WML Workshop.

What is your current code? Both [remove_shroud] and [place_shroud] accept a filter for applying the shroud change to multiple tiles at once.
99 little bugs in the code, 99 little bugs
take one down, patch it around
-2,147,483,648 little bugs in the code
SoftSilkLionMilk
Posts: 3
Joined: December 7th, 2022, 2:13 am

Re: Shroud is Slow

Post by SoftSilkLionMilk »

So I could pick up the whole shroud map and move it at once. I'm not really sure how.

Code: Select all

function SSLM.fun.set_shroud(x, y, shroud) --too slow
    if shroud then
        --wml.fire("place_shroud", {side="1,2,3,4,5,6,7,8,9", x = x, y = y})
    else
        --wml.fire("remove_shroud", {side="1,2,3,4,5,6,7,8,9", x = x, y = y})
    end
    --[[local leaders = wesnoth.units.find_on_map({canrecruit = "yes"})
    for i,l in ipairs(leaders) do
        if shroud then
            --wesnoth.interface.add_chat_message(l.side)
            wesnoth.sides.place_shroud(l.side, {{x, y}})
        else
            --wesnoth.sides.remove_shroud(l.side, {{x, y}})
        end
    end--]]
end
function SSLM.fun.shift_tile(x, y, dir, all)
	local h = wesnoth.current.map.get(x, y)
	local p = wesnoth.current.map.get_direction({h.x, h.y}, dir)
	--local shroud = wesnoth.sides.is_shrouded(2,{x,y})
	wesnoth.current.map[{p.x, p.y}] = h.terrain
	wesnoth.current.map.set_owner(p.x, p.y, wesnoth.current.map.get_owner(x, y))
--	wesnoth.current.map[{x, y}] = "Qxua"
	if all then
		local units = wesnoth.units.find_on_map({x = x, y = y})
		for i,u in ipairs(units) do
			local vx, vy = wesnoth.paths.find_vacant_hex(p.x, p.y, u)
			if (p.x == vx) and (p.y == vy) then
				wesnoth.units.extract(u)
				wesnoth.units.to_map(u, p.x, p.y)
	--			wesnoth.interface.add_chat_message("Unit extracted. placing a")
	--			wesnoth.interface.add_chat_message(u.type)
			end
		end
		if shroud then
			SSLM.fun.set_shroud(p.x, p.y, true)
		else
			SSLM.fun.set_shroud(p.x, p.y, false)
		end
	end
end

function SSLM.fun.shift_row(x, y, dir, len, ray, all)
	local rx, ry = x, y
	for i=1,len do
		SSLM.fun.shift_tile(rx, ry, dir, all)
		local p = wesnoth.current.map.get_direction({rx, ry}, ray)
		rx, ry = p.x, p.y
	end
end

function SSLM.fun.shift_triangle(x, y, dir, len, ray, wid, rad, all)
	local v = wesnoth.current.map.get_direction({x, y}, rad, wid-1)
	local r = len
	for i=1,len do
		SSLM.fun.shift_row(v.x, v.y, dir, r, ray, all)
		v = wesnoth.current.map.get_direction({v.x, v.y}, rad, -1)
		r = r - 1
	end
end
User avatar
Pentarctagon
Project Manager
Posts: 5496
Joined: March 22nd, 2009, 10:50 pm
Location: Earth (occasionally)

Re: Shroud is Slow

Post by Pentarctagon »

You should be able to use coordinate ranges (ie: x=1-12).
99 little bugs in the code, 99 little bugs
take one down, patch it around
-2,147,483,648 little bugs in the code
User avatar
Celtic_Minstrel
Developer
Posts: 2158
Joined: August 3rd, 2012, 11:26 pm
Location: Canada
Contact:

Re: Shroud is Slow

Post by Celtic_Minstrel »

(Note: This post is made with respect to 1.17.x. I am not sure to what degree it works in 1.16.x; most of the pieces are there but there may be some missing pieces or major bugs.)

It looks like you're changing the shroud one tile at a time. I think it might make more sense to replace it in a single batch. You can get and set the shroud as a bit string using wesnoth.sides[1].shroud_data (which for some reason seemed to be missing from the documentation; I've corrected the oversight). For manipulating the bit string, you can either split it by lines and manipulate it as an array of strings, or parse it into a location set and iterate over it to produce a new set.

Here's an example of how you might shift the shroud 1 tile in the x direction using this approach:

Code: Select all

local location_set = wesnoth.require "location_set"
local shroud = location_set.of_shroud_data(wesnoth.sides[1].shroud_data)
local new_shroud = location_set.create()
for x, y in shroud:iter() do
	new_shroud:insert(x + 1, y)
end
wesnoth.sides[1].shroud_data = new_shroud:to_shroud_data()
Author of The Black Cross of Aleron campaign and Default++ era.
Former maintainer of Steelhive.
Post Reply