The Wiki for Tale 5 is in read-only mode and is available for archival and reference purposes only. Please visit the current Tale 11 Wiki in the meantime.

If you have any issues with this Wiki, please post in #wiki-editing on Discord or contact Brad in-game.

User:Kasiya/flax

From ATITD5
Jump to navigationJump to search

flax.lua


-- Edit these first 2 to adjust how much is planted in a pass
-- May need to adjust walk_time in flax_common.inc if you move too slowly to keep up
-- grids tested: 2x2, 3x3, 5x5, 6x6 (probably need 3+ dex and 600ms walk time)
grid_w = 5;
grid_h = 5;

loadfile("luaScripts/flax_common.inc")();
loadfile("luaScripts/screen_reader_common.inc")();
loadfile("luaScripts/ui_utils.inc")();

-- Just testing spiral algorithm, ignore this...
function spiraltest()
	-- for spiral
	local dxi=1;
	local dt_max=grid_w;
	local dt=grid_w;
	local dx={1, 0, -1, 0};
	local dy={0, -1, 0, 1};
	local num_at_this_length = 3;
	
	-- Plant and pin
	for y=1, grid_h do
		for x=1, grid_w do
			lsPrintln('doing ' .. x .. ',' .. y);

			-- move to next position
			if not ((x == grid_w) and (y == grid_h)) then
				lsPrintln('walking dx=' .. dx[dxi] .. ' dy=' .. dy[dxi]);
				dt = dt - 1;
				if dt == 1 then
					dxi = dxi + 1;
					num_at_this_length = num_at_this_length - 1;
					if num_at_this_length == 0 then
						dt_max = dt_max - 1;
						num_at_this_length = 2;
					end
					if dxi == 5 then
						dxi = 1;
					end
					dt = dt_max;
				end
			else
				lsPrintln('skipping walking, on last leg');
			end
		end
	end
end

function doit()
	-- num_loops = promptNumber("How many " .. grid_w .. "x" .. grid_h .. " passes ?", 5);
	promptFlaxNumbers(1);

	askForWindow("Make sure the plant flax window is pinned and you are in F8F8 cam zoomed in.  You may need to F12 at low resolutions or hide your chat window (if it starts planting and fails to move downward, it probably clicked on your chat window).  Will plant grid NE of current location.  'Plant all crops where you stand' must be ON.  'Right click pins/unpins a menu' must be ON.");
	
	initGlobals();
	
	local went_to_seeds = 0; -- Don't loop if we lost one, it'll mess us up!
	srReadScreen();
	local xyPlantFlax = srFindImage(imgFlax1);
	if not xyPlantFlax then
		xyPlantFlax = srFindImage(imgFlax2);
		if not xyPlantFlax then
			error 'Could not find plant window';
		end
	end
	xyPlantFlax[0] = xyPlantFlax[0] + 5;
	local xyCenter = getCenterPos();
	local xyFlaxMenu = {};
	xyFlaxMenu[0] = xyCenter[0] - 43;
	xyFlaxMenu[1] = xyCenter[1] + 0;
	
	for loop_count=1, num_loops do
		
		-- for spiral
		local dxi=1;
		local dt_max=grid_w;
		local dt=grid_w;
		local dx={1, 0, -1, 0};
		local dy={0, -1, 0, 1};
		local num_at_this_length = 3;
		local x_pos = 0;
		local y_pos = 0;
		
		-- Plant and pin
		for y=1, grid_h do
			for x=1, grid_w do
				lsPrintln('doing ' .. x .. ',' .. y .. ' of ' .. grid_w .. ',' .. grid_h);
	
				statusScreen("(" .. loop_count .. "/" .. num_loops .. ") Planting " .. x .. ", " .. y);
	
				-- Plant
				lsPrintln('planting ' .. xyPlantFlax[0] .. ',' .. xyPlantFlax[1]);
				setWaitSpot(xyFlaxMenu[0], xyFlaxMenu[1]);
				srClickMouseNoMove(xyPlantFlax[0], xyPlantFlax[1], 0);
				srSetMousePos(xyFlaxMenu[0], xyFlaxMenu[1]);
				waitForChange();
				-- lsSleep(delay_time);
				
				-- Bring up menu
				lsPrintln('menu ' .. xyFlaxMenu[0] .. ',' .. xyFlaxMenu[1]);
				setWaitSpot(xyFlaxMenu[0]+5, xyFlaxMenu[1]);
				srClickMouse(xyFlaxMenu[0], xyFlaxMenu[1], 0);
				waitForChange();
				-- lsSleep(delay_time);
				
				-- Check for window size
				checkWindowSize(xyFlaxMenu[0], xyFlaxMenu[1]);
				
				-- Pin
				lsPrintln('pin ' .. (xyFlaxMenu[0]+5) .. ',' .. xyFlaxMenu[1]);
				srClickMouseNoMove(xyFlaxMenu[0]+5, xyFlaxMenu[1]+0, 1);
				-- lsSleep(delay_time);
				
				-- Move window
				local pp = pinnedPos(x, y);
				lsPrintln('move ' .. (xyFlaxMenu[0]+5) .. ',' .. xyFlaxMenu[1] .. ' to ' .. pp[0] .. ',' .. pp[1]);
				drag(xyFlaxMenu[0] + 5, xyFlaxMenu[1],
					pp[0], pp[1], 0);
				-- lsSleep(delay_time);

				-- move to next position
				if not ((x == grid_w) and (y == grid_h)) then
					lsPrintln('walking dx=' .. dx[dxi] .. ' dy=' .. dy[dxi]);
					x_pos = x_pos + dx[dxi];
					y_pos = y_pos + dy[dxi];
					srClickMouseNoMove(xyCenter[0] + walk_px_x*dx[dxi], xyCenter[1] + walk_px_y*dy[dxi], 0);
					lsSleep(walk_time);
					dt = dt - 1;
					if dt == 1 then
						dxi = dxi + 1;
						num_at_this_length = num_at_this_length - 1;
						if num_at_this_length == 0 then
							dt_max = dt_max - 1;
							num_at_this_length = 2;
						end
						if dxi == 5 then
							dxi = 1;
						end
						dt = dt_max;
					end
				else
					lsPrintln('skipping walking, on last leg');
				end
			end
			checkBreak();
		end

		statusScreen("(" .. loop_count .. "/" .. num_loops .. ") Refocusing windows...");
		
		-- Bring windows to front
		for y=grid_h, 1, -1 do
			for x=grid_w, 1, -1 do 
				local rp = refreshPosUp(x, y);
				srClickMouseNoMove(rp[0], rp[1], 0);
				lsSleep(refocus_click_time);
			end
		end
		lsSleep(refocus_time); -- Wait for last window to bring to the foreground before clicking again
		
		local did_harvest=false;
		local water_step = 0;
		while not did_harvest do
			-- Monitor for Weed This/etc
			water_step = water_step + 1;
			for y=1, grid_h do
				for x=1, grid_w do 
					statusScreen("(" .. loop_count .. "/" .. num_loops .. ") Weeding/Harvest step " .. water_step);
					local pp = pinnedPos(x, y);
					local rp = refreshPosDown(x, y);
					local seeds_retry=3;
					while 1 do
						srClickMouseNoMove(rp[0], rp[1], 0);
						lsSleep(screen_refresh_time);
						srReadScreen();
						local weed = srFindImageInRange(imgWeed, pp[0], pp[1] - 50, 120, 100);
						if weed then
							srClickMouseNoMove(weed[0] + 5, weed[1], 0);
							break;
						end
						local weed = srFindImageInRange(imgWeedAndWater, pp[0], pp[1] - 50, 120, 100);
						if weed then
							srClickMouseNoMove(weed[0] + 5, weed[1], 0);
							break;
						end
						local harvest = srFindImageInRange(imgHarvest, pp[0], pp[1] - 50, 110, 100);
						if harvest then
							srClickMouseNoMove(harvest[0] + 5, harvest[1], 0);
							srClickMouseNoMove(pp[0], pp[1], 1); -- unpin
							did_harvest = true;
							break;
						end
						local seeds = srFindImageInRange(imgSeeds, pp[0], pp[1] - 50, 120, 100);
						if seeds then
							seeds_retry = seeds_retry - 1;
							if (seeds_retry == 0) then
								if nil then -- Don't do this, it causes us to walk out of range of the rest!
									lsPrintln('Went to seed, grabbing the seeds and ignoring.');
									srClickMouseNoMove(seeds[0] + 5, seeds[1], 0);
								end
								srSetMousePos(pp[0]+5, pp[1]+37);
								lsSleep(100);
								srClickMouseNoMove(pp[0]+5, pp[1]+37, 0); -- Utility
								lsSleep(100);
								srReadScreen();
								local rip = srFindImage("FlaxRipOut.png");
								if rip then
									srClickMouseNoMove(rip[0] + 5, rip[1] + 2, 0); -- Rip out
								else
									error 'Flax went to seed, but failed to find rip out option';
								end
								lsSleep(100);
							
								srClickMouseNoMove(pp[0]-3, pp[1], 1); -- unpin
								went_to_seeds = 1;
								did_harvest = true;
								break;
							end
						end
						checkBreak();
					end
				end
			end
				
			-- Bring windows to front
			if not did_harvest then
				statusScreen("(" .. loop_count .. "/" .. num_loops .. ") Refocusing windows...");
				for y=grid_h, 1, -1 do
					for x=grid_w, 1, -1 do 
						local rp = refreshPosUp(x, y);
						srClickMouseNoMove(rp[0], rp[1], 0);
						lsSleep(refocus_click_time);
					end
				end
				lsSleep(refocus_time); -- Wait for last window to bring to the foreground before clicking again
			end
		end
		
		lsSleep(2500); -- Wait for last flax bed to disappear before accidentally clicking on it!
		statusScreen("(" .. loop_count .. "/" .. num_loops .. ") Walking...");

		if went_to_seeds == 0 then	
			-- Walk back
			for x=1, x_pos do
				srClickMouseNoMove(xyCenter[0] + walk_px_x*-1, xyCenter[1], 0);
				lsSleep(walk_time);
			end
			for x=1, -y_pos do
				srClickMouseNoMove(xyCenter[0], xyCenter[1] + walk_px_y, 0);
				lsSleep(walk_time);
			end
		end
		
		if went_to_seeds and not loop_count == num_loops then
			error 'Some of the plants went to seeds, stopping loop'
		end
	end
	
	lsPlaySound("Complete.wav");
end

flax_seeds.lua


-- This script has not yet been updated to use the new UI utilties
-- See flax.lua instead

-- Edit these first 3 to adjust how much is planted in a pass and how many passes
-- May need to adjust walk_time in flax_common.inc if you move too slowly to keep up
-- grids tested up to 7x7, can probably do more
grid_w = 5;
grid_h = 5;

harvest_seeds_time = 1300;

loadfile("luaScripts/flax_common.inc")();
loadfile("luaScripts/screen_reader_common.inc")();
loadfile("luaScripts/ui_utils.inc")();

-- Harvest seeds
function doit()
	--num_loops = promptNumber("How many " .. grid_w .. "x" .. grid_h .. " passes ?", 5);
	promptFlaxNumbers(false);
	askForWindow("Make sure the plant flax window is pinned and you are in F8F8 cam zoomed in.  You may need to F12 at low resolutions or hide your chat window (if it starts planting and fails to move downward, it probably clicked on your chat window).  Will plant grid NE of current location.  'Plant all crops where you stand' must be ON.  'Right click pins/unpins a menu' must be ON.");
	initGlobals();
	srReadScreen();
	local xyPlantFlax = srFindImage(imgFlax1);
	if not xyPlantFlax then
		xyPlantFlax = srFindImage(imgFlax2);
		if not xyPlantFlax then
			error 'Could not find plant window';
		end
	end
	xyPlantFlax[0] = xyPlantFlax[0] + 5;
	local xyCenter = getCenterPos();
	local xyFlaxMenu = {};
	xyFlaxMenu[0] = xyCenter[0] - 43;
	xyFlaxMenu[1] = xyCenter[1] + 0;
	
	-- for spiral
	local dxi=1;
	local dt_max=grid_w;
	local dt=grid_w;
	local dx={1, 0, -1, 0};
	local dy={0, -1, 0, 1};
	local num_at_this_length = 3;
	local x_pos = 0;
	local y_pos = 0;
	
	-- Plant and pin
	for y=1, grid_h do
		for x=1, grid_w do
			lsPrintln('doing ' .. x .. ',' .. y);
			
			statusScreen("Planting...");

			-- Plant
			lsPrintln('planting ' .. xyPlantFlax[0] .. ',' .. xyPlantFlax[1]);
			setWaitSpot(xyFlaxMenu[0], xyFlaxMenu[1]);
			srClickMouseNoMove(xyPlantFlax[0], xyPlantFlax[1], 0);
			srSetMousePos(xyFlaxMenu[0], xyFlaxMenu[1]);
			waitForChange();
			-- lsSleep(delay_time);
			
			-- Bring up menu
			lsPrintln('menu ' .. xyFlaxMenu[0] .. ',' .. xyFlaxMenu[1]);
			setWaitSpot(xyFlaxMenu[0]+5, xyFlaxMenu[1]);
			srClickMouse(xyFlaxMenu[0], xyFlaxMenu[1], 0);
			waitForChange();
			-- lsSleep(delay_time);
			
			-- Pin
			lsPrintln('pin ' .. (xyFlaxMenu[0]+5) .. ',' .. xyFlaxMenu[1]);
			srClickMouseNoMove(xyFlaxMenu[0]+5, xyFlaxMenu[1]+0, 1);
			-- lsSleep(delay_time);
			
			-- Check for window size
			checkWindowSize(xyFlaxMenu[0], xyFlaxMenu[1]);
			
			-- Move window
			local pp = pinnedPos(x, y);
			lsPrintln('move ' .. (xyFlaxMenu[0]+5) .. ',' .. xyFlaxMenu[1] .. ' to ' .. pp[0] .. ',' .. pp[1]);
			drag(xyFlaxMenu[0] + 5, xyFlaxMenu[1],
				pp[0], pp[1], 0);
			-- lsSleep(delay_time);

			-- move to next position
			if not ((x == grid_w) and (y == grid_h)) then
				lsPrintln('walking dx=' .. dx[dxi] .. ' dy=' .. dy[dxi]);
				x_pos = x_pos + dx[dxi];
				y_pos = y_pos + dy[dxi];
				srClickMouseNoMove(xyCenter[0] + walk_px_x*dx[dxi], xyCenter[1] + walk_px_y*dy[dxi], 0);
				lsSleep(walk_time);
				dt = dt - 1;
				if dt == 1 then
					dxi = dxi + 1;
					num_at_this_length = num_at_this_length - 1;
					if num_at_this_length == 0 then
						dt_max = dt_max - 1;
						num_at_this_length = 2;
					end
					if dxi == 5 then
						dxi = 1;
					end
					dt = dt_max;
				end
			else
				lsPrintln('skipping walking, on last leg');
			end
		end
		if (lsShiftHeld() and lsControlHeld()) then
			error 'broke out of loop from Shift+Ctrl';
		end
	end
	
	for loop_count=1, num_loops do
		
		statusScreen("(" .. loop_count .. "/" .. num_loops .. ") Refocusing");
		-- Bring windows to front
		for y=grid_h, 1, -1 do
			for x=grid_w, 1, -1 do 
				local rp = refreshPosUp(x, y);
				srClickMouseNoMove(rp[0], rp[1], 0);
				lsSleep(refocus_click_time);
			end
		end
		lsSleep(refocus_time); -- Wait for last window to bring to the foreground before continuing
	
		-- And harvest
		for y=1, grid_h do
			for x=1, grid_w do 

				statusScreen("(" .. loop_count .. "/" .. num_loops .. ") Harvesting " .. x .. ", " .. y);
				
				local pp = pinnedPos(x, y);
				local rp = refreshPosDown(x, y);
				while 1 do
					srClickMouseNoMove(rp[0], rp[1], 0);
					lsSleep(screen_refresh_time);
					srReadScreen();
					local seeds = srFindImageInRange(imgSeeds, pp[0], pp[1] - 50, 160, 100);
					if seeds then
						srClickMouseNoMove(seeds[0] + 5, seeds[1], 0);
						lsSleep(harvest_seeds_time);
						break;
					end
					checkBreak();
				end
			end
		end
	end

	statusScreen("Refocusing");
	-- Bring windows to front
	for y=grid_h, 1, -1 do
		for x=grid_w, 1, -1 do 
			local rp = refreshPosUp(x, y);
			srClickMouseNoMove(rp[0], rp[1], 0);
			lsSleep(refocus_click_time);
		end
	end
	lsSleep(refocus_time); -- Wait for last window to bring to the foreground before continuing
	
	-- and clean up!
	for y=1, grid_h do
		for x=1, grid_w do 
			local rp = refreshPosDown(x, y);
			srClickMouseNoMove(rp[0], rp[1], 1); -- unpin
			lsSleep(refocus_click_time);
			checkBreak();
		end
	end

	lsPlaySound("Complete.wav");
end

flax_common.inc

-- Also using these for other planting automation

xyWindowSize = srGetWindowSize();
imgFlax1 = "FlaxOldEgypt.png";
imgFlax2 = "FlaxNileGreen.png";
imgHarvest = "HarvestThisFlax.png";
imgWeedAndWater = "WeedAndWater.png";
imgWeed = "WeedThisFlaxBed.png";
imgSeeds = "HarvestSeeds.png";
imgHarvestThese = "HarvestThese.png";
imgWeedThese = "WeedThese.png";

delay_time = 100;
screen_refresh_time = 110;
walk_px_y = 340;
walk_px_x = 380;
walk_y_drift = 18;
walk_x_drift = 14;
walk_time = 570;
refocus_time = 500;
refocus_click_time = 100;

function initGlobals()
	pixel_scale = xyWindowSize[0] / 1720; -- Macro written with 1720 pixel wide window
	lsPrintln("pixel_scale " .. pixel_scale);

	walk_px_y = math.floor(walk_px_y * pixel_scale);
	walk_px_x = math.floor(walk_px_x * pixel_scale);
	if (lsScreenX < 1280) then
		-- Have to click way off center in order to not move at high resoltuions
		walk_y_drift = math.floor(walk_y_drift * pixel_scale);
		walk_x_drift = math.floor(walk_x_drift * pixel_scale);
	else
		-- Very little drift at these resolutions, clicking dead center barely moves
		walk_y_drift = 1;
		walk_x_drift = 1;
	end
end

-- The flax bed window
-- T4, guilded?: window_w = 166;
-- T4, guilded?: window_h = 116;
window_w = 174;
window_h = 100;
refresh_down_y_offs = 4;
refresh_up_y_offs = 0;

-- adjust if "plant all guild owned" option is enabled
window_check_done_once = false;
function checkWindowSize(x, y)
	if not window_check_done_once then
		srReadScreen();
		window_check_done_once = true;
		local pos = srFindImageInRange("UseableBy.png", x-5, y-50, 150, 100)
		if pos then
			window_w = 166;
			window_h = 116;
		end
	end
end

-- position to drag window to
function pinnedPos(x, y)
	local ret = {};
	ret[0] = xyWindowSize[0] - 25*(x-1) - (window_w - 5);
	ret[1] = (y-1)*14 + (window_h/2) + 2;
	lsPrintln("pinnedPos(" .. x .. "," .. y .. ")=" .. ret[0] .. "," .. ret[1]);
	return ret;
end

function refreshPosUp(x, y)
	local ret = pinnedPos(x, y);
	ret[0] = ret[0] + (window_w - 15);
	ret[1] = ret[1] - (window_h/2 - 4); -- - (window_h - 66) + refresh_up_y_offs; -- 50 for flax;
	lsPrintln("refreshPosUp(" .. x .. "," .. y .. ")=" .. ret[0] .. "," .. ret[1]);
	return ret;
end

function refreshPosDown(x, y)
	local ret = pinnedPos(x, y);
	ret[0] = ret[0] - 2;
	ret[1] = ret[1] + (window_h / 2) - refresh_down_y_offs;
	lsPrintln("refreshPosDown(" .. x .. "," .. y .. ")=" .. ret[0] .. "," .. ret[1]);
	return ret;
end

function getCenterPos()
	local ret = {};
	ret[0] = xyWindowSize[0] / 2 - walk_x_drift;
	ret[1] = xyWindowSize[1] / 2 + walk_y_drift;
	return ret;
end

function setWaitSpot(x0, y0)
	setWaitSpot_x = x0;
	setWaitSpot_y = y0;
	setWaitSpot_px = srReadPixel(x0, y0);
end

function waitForChange()
	local c=0;
	while srReadPixel(setWaitSpot_x, setWaitSpot_y) == setWaitSpot_px do
		lsSleep(1);
		c = c+1;
		if (lsShiftHeld() and lsControlHeld()) then
			error 'broke out of loop from Shift+Ctrl';
		end
	end
	lsPrintln('Waited ' .. c .. 'ms for pixel to change.');
end

function drag(x0, y0, x1, y1)
	srSetMousePos(x0, y0);
	setWaitSpot(x1, y1);
	srMouseDown(x0, y0, 0);
	-- lsSleep(15);
	srSetMousePos(x1, y1);
	-- lsSleep(50);
	waitForChange();
	srMouseUp(x0, y0, 0);
	-- lsSleep(50);
end

function promptFlaxNumbers(is_plant)
	scale = 1.0;
	
	local z = 0;
	local is_done = nil;
	local value = nil;
	-- Edit box and text display
	while not is_done do
		-- Put these everywhere to make sure we don't lock up with no easy way to escape!
		checkBreak("disallow pause");
		
		lsPrint(10, 10, z, scale, scale, 0xFFFFFFff, "Choose passes and grid size");
		
		-- lsEditBox needs a key to uniquely name this edit box
		--   let's just use the prompt!
		-- lsEditBox returns two different things (a state and a value)
		local y = 40;
		lsPrint(5, y, z, scale, scale, 0xFFFFFFff, "Passes:");
		is_done, num_loops = lsEditBox("passes",
			100, y, z, 50, 30, scale, scale,
			0x000000ff, 5);
		if not tonumber(num_loops) then
			is_done = nil;
			lsPrint(10, y+18, z+10, 0.7, 0.7, 0xFF2020ff, "MUST BE A NUMBER");
			num_loops = 1;
		end
		y = y + 32;

		lsPrint(5, y, z, scale, scale, 0xFFFFFFff, "Grid size:");
		is_done, grid_w = lsEditBox("grid",
			100, y, z, 50, 30, scale, scale,
			0x000000ff, grid_w);
		if not tonumber(grid_w) then
			is_done = nil;
			lsPrint(10, y+18, z+10, 0.7, 0.7, 0xFF2020ff, "MUST BE A NUMBER");
			grid_w = 1;
			grid_h = 1;
		end
		grid_w = tonumber(grid_w);
		grid_h = grid_w;
		y = y + 32;

		if lsButtonText(170, y-32, z, 100, 0xFFFFFFff, "OK") then
			is_done = 1;
		end

		if is_plant then
			lsPrintWrapped(10, y, z+10, lsScreenX - 20, 0.7, 0.7, 0xD0D0D0ff, "This will plant and harvest a " .. grid_w .. "x" .. grid_w .. " grid of Flax " .. num_loops .. " times, requiring " .. (grid_w * grid_w * num_loops) .. " seeds, doing " .. (grid_w*grid_w*num_loops) .. " flax harvests.");
		else
			lsPrintWrapped(10, y, z+10, lsScreenX - 20, 0.7, 0.7, 0xD0D0D0ff, "This will plant a " .. grid_w .. "x" .. grid_w .. " grid of Flax " .. num_loops .. " times, requiring " .. (grid_w * grid_w) .. " seeds, yielding " .. (grid_w * grid_w * num_loops) .. " seeds.");
		end

		if is_done and (not num_loops or not grid_w) then
			error 'Canceled';
		end
		
		if lsButtonText(lsScreenX - 110, lsScreenY - 30, z, 100, 0xFFFFFFff, "End script") then
			error "Clicked End Script button";
		end
	
		
		lsDoFrame();
		lsSleep(10); -- Sleep just so we don't eat up all the CPU for no reason
	end
end