The Wiki for Tale 6 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:Selune

From ATITD6
Revision as of 16:06, 3 January 2013 by Selune (talk | contribs)
Jump to navigationJump to search

Paint Reaction Template:

Cabbage | RedSand | G | -11 | 26
Cabbage | Iron | W | 27 | 27
Cabbage | Copper | W | -20 | -60
Cabbage | Potash | B | 19 | -63
Carrot | RedSand | B | 32 | -26
Carrot | Lead | W | -17 | 61
Carrot | Potash | W | -59 | 56
Carrot | Lime | G | 0 | 23
Clay | Lead | B | 32 | -16
Clay | Copper | R | 20 | -12
Clay | Sulfur | G | -55 | -41
Clay | Saltpeter | B | 54 | 35
Lead | Iron | B | 4 | 14
Lead | Copper | W | -25 | -40
Lead | Saltpeter | G | -7 | 47
Iron | Sulfur | G | -17 | 0
Iron | Saltpeter | W | -55 | 7
Copper | Sulfur | W | -25 | -12
Copper | Saltpeter | B | 42 | 4

Modified VT PaintWatch:

--
-- 
--

--Cabbage		| 129, 63, 145   | 8      | Y | bulk    | 10
--Carrot		| 225, 113, 33   | 10     | Y | bulk    | 10
--Clay			| 128, 96, 32    | 4      | Y | bulk    | 20
--DeadTongue		| 112, 64, 64    | 500    | N | normal  | 4
--ToadSkin		| 48, 96, 48     | 500    | N | normal  | 4
--EarthLight		| 128, 240, 224  | 10000  | N | normal  | 4
--RedSand		| 144, 16, 24    | 10     | Y | bulk    | 20
--Lead			| 80, 80, 96     | 50     | Y | normal  | 6
--Silver		| 16, 16, 32     | 50     | N | normal  | 6
--Iron			| 96, 48, 32     | 30     | Y | normal  | 8
--Copper		| 64, 192, 192   | 30     | Y | normal  | 8

--Sulfur      | catalyst       | 10     | Y | normal  | 1
--Potash      | catalyst       | 50     | Y | normal  | 1
--Lime        | catalyst       | 20     | Y | normal  | 1
--Saltpeter   | catalyst       | 10     | Y | normal  | 1

-- 317, 55, 71
--                 cj   ca  cl   dt   ts   el   rs   le   si   ir   co   su  po li sp
paint_colourR = { 129, 225, 129, 112, 48,  128, 145, 81,  16,  97,  64  };
paint_colourG = { 64,  113, 97,  64,  96,  240, 16,  81,  16,  48, 194  };
paint_colourB = { 145, 33,  33,  64,  48,  224, 24,  97,  32,  33, 194  };
catalyst1 = 12;

loadfile("luaScripts/screen_reader_common.inc")();
loadfile("luaScripts/ui_utils.inc")();
loadfile("luascripts/common.inc")();

button_names = {
"CabbageJ","Carrot","Clay","DeadTongue","ToadSkin","EarthLight","RedSand",
"Lead","SilverP","Iron","Copper","C:Sulfur","C:potash","C:Lime","C:Saltpeter"}; 

per_paint_delay_time = 1000;
per_read_delay_time = 600;
per_click_delay = 10;


function doit()

	local paint_sum = {0,0,0};
	local paint_count = 0;
	local bar_colour = {0,0,0};
	local expected_colour = {0,0,0};
	local diff_colour = {0,0,0};
	local new_px = 0xffffffFF;
	local px_R = nil;
	local px_G = nil;
	local px_B = nil;
	local px_A = nil;
	local m_x = 0;
	local m_y = 0;
	local update_now = 1;
	local y=0;
	local button_push = 0;

	lsSetCaptureWindow();

	askForWindow("Open the paint window. Take any paint away so to start with 'Black'.");


	srReadScreen();
	xyWindowSize = srGetWindowSize();
	local colour_panel = findAllImages("paint-black.png");
	if (#colour_panel == 0) then
		m_x, m_y = srMousePos();
	else
		m_x = colour_panel[1][0];
		m_y = colour_panel[1][1];	
	end

	local paint_buttons = findAllImages("paint-button.png");
	if (#paint_buttons == 0) then
		error "No buttons found";
	end


	while 1 do
lsSetCamera(0,0,lsScreenX*1.5,lsScreenY*1.5);
		-- Where to start putting buttons/text on the screen.
		y=0;
		
		if lsButtonText(lsScreenX - 30, lsScreenY - 80, 0, 100, 0xFFFFFFff, "Reset") then
			for i= 1, 10 do
				srClickMouseNoMove(paint_buttons[7][0]+2,paint_buttons[7][1]+2, right_click);
				lsSleep(per_click_delay);
			end
			srReadScreen();
			lsSleep(100);
			clickAllText("Take the Paint");
			lsSleep(100);
			paint_sum = {0,0,0};
			paint_count = 0;
			bar_colour = {0,0,0};
			expected_colour = {0,0,0};
			diff_colour = {0,0,0};
			new_px = 0xffffffFF;
			px_R = nil;
			px_G = nil;
			px_B = nil;
			px_A = nil;
			m_x = 0;
			m_y = 0;
			update_now = 1;
		end

		-- Create each button and set the button push.
		for i=1, #button_names do
			if lsButtonText(10, y, 0, 250, 0xFFFFFFff, button_names[i]) then
				image_name = button_names[i];
				update_now = 1;
				button_push = i;
			end
			y = y + 26;
		end
		srReadScreen();


		-- read the bar pixels
		new_px = srReadPixel(m_x, m_y);
		px_R = (math.floor(new_px/256/256/256) % 256);
		px_G = (math.floor(new_px/256/256) % 256);
		px_B = (math.floor(new_px/256) % 256);
		px_A = (new_px % 256);

		if not(update_now==0) then
		--{
			if not (button_push==0) then
			--{
				-- click the appropriate button to add paint.
				srClickMouseNoMove(paint_buttons[button_push][0]+2,paint_buttons[button_push][1]+2, right_click);
				lsSleep(per_click_delay);
			
				if(button_push < catalyst1) then
					-- add the paint estimate 
					paint_sum[1] = 	paint_sum[1] + paint_colourR[button_push];
					paint_sum[2] = 	paint_sum[2] + paint_colourG[button_push];
					paint_sum[3] = 	paint_sum[3] + paint_colourB[button_push];
					paint_count = paint_count + 1.0;
				end
			--}
			end

			-- count up all the pixels.
			lsSleep(per_paint_delay_time);
			srReadScreen();

			bar_colour[1] = #findAllImages("paint-redbarC.png");
			lsSleep(per_read_delay_time/3);
			bar_colour[2] = #findAllImages("paint-greenbarC.png");
			lsSleep(per_read_delay_time/3);
			bar_colour[3] = #findAllImages("paint-bluebarC.png");
			lsSleep(per_read_delay_time/3);
			update_now = 0;

			-- tweak/hack because we miss the first pixel
			for i=1, 3 do
				if(bar_colour[i]>0)then				
					bar_colour[i]=bar_colour[i]+1;
					bar_colour[i]=bar_colour[i]*256.0/259;
				end
			end


			
			-- New colour has been added, mix in the pot, and see if there's a difference from the expected value.
			if not (button_push==0) then
			--{				
				for i=1, 3 do
					expected_colour[i] = paint_sum[i] / paint_count;
					diff_colour[i] = math.floor(0.5+bar_colour[i]) - math.floor(0.5+expected_colour[i]);
				end

				button_push = 0;
			--}
			end
		--}
		end

		-- Display all the goodies
		lsPrintWrapped(0, y, 1, lsScreenX, 1, 1, 0xFFFFFFff,
			" Pixel   RGBA: " .. px_R .. "," .. px_G .. "," .. px_B .. "," .. px_A);
		y = y + 26;
		lsPrintWrapped(0, y, 1, lsScreenX, 1, 1, 0xFFFFFFff,
			" Bar read RGB: " .. math.floor(bar_colour[1]+0.5) .. "," .. math.floor(bar_colour[2]+0.5) .. "," .. math.floor(bar_colour[3]+0.5));
		y = y + 26;
		lsPrintWrapped(0, y, 1, lsScreenX, 1, 1, 0xFFFFFFff,
			" Expected RGB: " .. math.floor(expected_colour[1]+0.5) .. "," .. math.floor(expected_colour[2]+0.5) .. "," .. math.floor(expected_colour[3]+0.5) );
		y = y + 26;
		lsPrintWrapped(0, y, 1, lsScreenX, 1, 1, 0xFFFFFFff,
			" Reactions RGB: " .. math.floor(diff_colour[1]+0.5) .. "," .. math.floor(diff_colour[2]+0.5) .. "," .. math.floor(diff_colour[3]+0.5) );


		if lsButtonText(lsScreenX - 30, lsScreenY - 30, 0, 100, 0xFFFFFFff, "Exit") then
			error "Canceled";
		end

		lsDoFrame();
		lsSleep(per_read_delay_time);
	end
end

Fixed Crematory Macro:

-- crematory.lua v1.2 by Tallow
--
-- Runs one or more crematories. Automatically discovers button
-- configuration on its own and loads/unloads materials.
--

assert(loadfile("luaScripts/common.inc"))();

askText = singleLine([[
  Crematory v1.2 (by Tallow) --
  Automatically runs one or more crematories.
]]);

wmText = "Tap control on Crematories to open and pin.";

OPP = 0;
SAME_UP = 1;
SAME_DOWN = 2;

tolerance = 6500;
tickTime = 1000;
maxWait = 1000;
longWait = 500;
shortWait = 30;

colOffsets = {
  {35-40-3, 204-182},
  {71-40-3, 204-182},
  {107-40-3, 204-182},
  {143-40-3, 204-182},
  {179-40-3, 204-182},
  {215-40-3, 204-182},
  {251-40-3, 204-182}
};

colWidth = 36-35+6;
colHeight = 323-204;
colMiddle = 57;

buttonOffsets = {
  {49-40, 333-182},
  {89-40, 333-182},
  {129-40, 333-182},
  {169-40, 333-182},
  {209-40, 333-182}
};

buttonWidth = 78-49;
buttonHeight = 354-333;
buttonClick = 10;

limestoneOffset = 0;
leeksOffset = 16;
flaxOffset = 32;
papyrusOffset = 48;
woodOffset = 64;

load_flax = true;
load_papyrus = true;
load_leeks = true;
load_limestone = true;

currentPass = 1;
passCount = 5;

windows = nil;

-------------------------------------------------------------------------------
-- doit
-------------------------------------------------------------------------------

function doit()
  askForWindow(askText);
  windowManager("Crematory Setup", wmText);
  unpinOnExit(runCrematories);
end

-------------------------------------------------------------------------------
-------------------------------------------------------------------------------

function runCrematories()
  promptLoad();
  askForFocus();
  for i=1,passCount do
    currentPass = i;
    takeAll();
    loadAll();
    start();
    local is_done = false;
    while not is_done do
      tick();
      is_done = checkDone();
    end
    sleepWithStatus(longWait*5, updateMessage("Waiting to take"));
  end
  takeAll();
  lsPlaySound("Complete.wav");
end

-------------------------------------------------------------------------------
-- addWindow
-------------------------------------------------------------------------------

function addWindow(vPos)
  local newWindow = {
    origin = {vPos[0], vPos[1]},
    ups = {nil, nil, nil, nil, nil},
    downs = {nil, nil, nil, nil, nil},
    dirs = {OPP, OPP, OPP, OPP, OPP},
    double = {false, false, false, false, false, false, false},
    probe = 0,
    lastPos = nil;
    lastDiff = nil;
    buttonState = {true, true, true, true, true},
    sameCount = 0,
    done = false
  };
  local vFire = srFindImageInRange("crem-fire.png", newWindow.origin[1] - 31,
                                   newWindow.origin[2] - 175, 238, 175,
                                   tolerance);
  if vFire then
    newWindow.fire = {vFire[0], vFire[1]};
  else
    error "No fire button. Do you have Advanced Chemistry?"
  end
  windows[#windows + 1] = newWindow;
end

-------------------------------------------------------------------------------
-- resetWindow
-------------------------------------------------------------------------------

function resetWindow(current)
  local vLime = srFindImageInRange("crem-lime.png", current.origin[1] - 20,
                                   current.origin[2] - 20, 100, 100,
				   tolerance);
  if (not vLime) then
     error "Could not find origin again.";
  end
  if ((vLime[0] ~= current.origin[1]) or
      (vLime[1] ~= current.origin[2])) then
     error("Window moved from (" .. current.origin[1] .. ", " ..
       current.origin[2] .. ") to (" .. vLime[0] .. ", " .. vLime[1] .. ")");
  end
  local vFire = srFindImageInRange("crem-fire.png", current.origin[1] - 31,
                                   current.origin[2] - 175, 238, 175,
                                   tolerance);
  if vFire then
    current.fire = {vFire[0], vFire[1]};
  end
  if current.probe < 6 then
    current.probe = 0;
    current.ups = {nil, nil, nil, nil, nil};
    current.downs = {nil, nil, nil, nil, nil};
    current.dirs = {OPP, OPP, OPP, OPP, OPP};
    current.double = {false, false, false, false, false, false, false};
  end
  current.lastPos = nil;
  current.lastDiff = nil;
  current.buttonState = {true, true, true, true, true};
  current.sameCount = 0;
  current.done = false;
end

-------------------------------------------------------------------------------
-- start
-------------------------------------------------------------------------------

function start()
  sleepWithStatus(longWait, updateMessage("Waiting to begin"));
  srReadScreen();
  if windows then
    for i=1,#windows do
      resetWindow(windows[i]);
    end
  else
    windows = {};
    local posList = findAllImages("crem-lime.png");
    if #posList == 0 then
      error "No crematories found";
    end
    for i=1,#posList do
      addWindow(posList[i]);
    end
  end
  for i=1,#windows do
    if windows[i].fire then
      safeClick(windows[i].fire[1] + 5, windows[i].fire[2] + 5);
      lsSleep(shortWait);
    end
  end
  sleepWithStatus(longWait, updateMessage("Finding my Chi"));
  srReadScreen();
  for i=1,#windows do
    windows[i].lastPos = findPoints(windows[i]);
    if not windows[i].lastPos then
      windows[i].done = true;
    end
  end
end

-------------------------------------------------------------------------------
-- tick
-------------------------------------------------------------------------------

function tick()
  sleepWithStatus(tickTime, updateMessage("Tending Crematory"));
  srReadScreen();
  for i=1,#windows do
    tickWindow(windows[i]);
  end
  checkBreak();
end

-------------------------------------------------------------------------------
-- tickWindow
-------------------------------------------------------------------------------

function tickWindow(current)
  if not current.done then
    local points = findPoints(current);
    if points then
      probeNext(current, points);
      if current.probe > 5 then
        toggleButtons(current, points, current.buttonState);
      end
    else
      current.done = true;
    end
  end
end

-------------------------------------------------------------------------------
-- checkDone
-------------------------------------------------------------------------------

function checkDone()
  local all_done = true;
  for i=1,#windows do
    if not windows[i].done then
      local done = srFindImageInRange("crem-done.png", windows[i].origin[1] - 3,
                                      windows[i].origin[2] - 15, 40, 40,
                                      tolerance);
      if done then
        windows[i].done = true;
      else
        all_done = false;
      end
    end
  end
  return all_done;
end

-------------------------------------------------------------------------------
-- findPoints
-------------------------------------------------------------------------------

function findPoints(current)
  local result = {};
  for i=1,7 do
    local offset = {current.origin[1] + colOffsets[i][1],
                    current.origin[2] + colOffsets[i][2]};
    local point = srFindImageInRange("crem-point.png", offset[1],
                                     offset[2] - 5,
                                     colWidth, colHeight + 10, tolerance);
    if point then
      result[i] = point[1] - colOffsets[i][2] - current.origin[2] - colMiddle;
    else
      result = nil;
      break;
    end
  end
  return result;
end

-------------------------------------------------------------------------------
-- findDiffs
-------------------------------------------------------------------------------

function findDiffs(current, points)
  local result = {};
  local all_zero = true;
  for i=1,7 do
    result[i] = points[i] - current.lastPos[i];
    if result[i] ~= 0 then
      all_zero = false;
    end
  end
  if all_zero then
    result = nil;
  end
  return result;
end

-------------------------------------------------------------------------------
-- probeNext
-------------------------------------------------------------------------------

function probeNext(current, points)
  local diffs = findDiffs(current, points);
  checkSame(current, diffs);
  if diffs and current.probe < 6 then
    if current.probe > 0 then
      for i=1,7 do
        if current.lastDiffs[i] < 0 and diffs[i] > 0 then
          if current.ups[current.probe] then
            current.downs[current.probe] = i;
            current.dirs[current.probe] = SAME_UP;
          else
            current.ups[current.probe] = i;
          end
        elseif current.lastDiffs[i] > 0 and diffs[i] < 0 then
          if current.downs[current.probe] then
            current.ups[current.probe] = i;
            current.dirs[current.probe] = SAME_DOWN;
          else
            current.downs[current.probe] = i;
          end
        end
      end
      if current.ups[current.probe] and current.downs[current.probe] then
        current.double[current.ups[current.probe]] = true;
        current.double[current.downs[current.probe]] = true;
      end
    end
    current.lastPos = points;
    current.lastDiffs = diffs;
    current.probe = current.probe + 1;
    if current.probe <= 5 then
      local newProbe = not current.buttonState[current.probe];
      local clickX = current.origin[1] + buttonOffsets[current.probe][1] +
	buttonClick;
      local clickY = current.origin[2] + buttonOffsets[current.probe][2] +
	buttonClick;

      current.buttonState[current.probe] = newProbe;
      safeClick(clickX, clickY);
      lsSleep(shortWait);
    end
  end
end

-------------------------------------------------------------------------------
-- checkSame
-------------------------------------------------------------------------------

function checkSame(current, diffs)
  if diffs then
    local all_same = true;
    for i=1,#diffs do
      if diffs[i] ~= 0 then
        all_same = false;
      end
    end
    if all_same then
      current.sameCount = current.sameCount + 1;
    else
      current.sameCount = 0;
    end
    if current.sameCount > 10 then
      current.done = true;
    end
  end
end

-------------------------------------------------------------------------------
-- toggleButtons
-------------------------------------------------------------------------------

function toggleButtons(current, points, buttonState)
  local balance = getBalance(points, current.double);
  for i=1,5 do
    local up = getPointValue(points, current.double, current.ups[i],
                             balance);
    local down = getPointValue(points, current.double, current.downs[i],
                               balance);
    local goalState = ((up >= 0 and down <= 0) or
                       (up >= 0 and down >= 0 and up > down) or
                       (up <= 0 and down <= 0 and up > down));
    if current.dirs[i] == SAME_UP then
      goalState = ((up >= 0 and down >= 0) or
                   (up >= 0 and down <= 0 and up >= -down) or
                   (up <= 0 and down >= 0 and -up <= down));
    elseif current.dirs[i] == SAME_DOWN then
      goalState = ((up <= 0 and down <= 0) or
                   (up >= 0 and down <= 0 and up <= -down) or
                   (up <= 0 and down >= 0 and -up >= down));
    end
    local goalStateStr = "false";
    if goalState then
      goalStateStr = "true";
    end
    local buttonStr = "false";
    if buttonState[i] then
      buttonStr = "true";
    end
    if (goalState and not buttonState[i]) or
       (not goalState and buttonState[i]) then
      safeClick(current.origin[1] + buttonOffsets[i][1] + buttonClick,
		current.origin[2] + buttonOffsets[i][2] + buttonClick);
      lsSleep(shortWait);
      buttonState[i] = goalState;
    end
  end
end

-------------------------------------------------------------------------------
-- getBalance
-------------------------------------------------------------------------------

function getBalance(points, double)
  local above = 0;
  local below = 0;
  for i=1,#points do
    if points[i] > 0 and double[i] then
      below = below + 1;
    elseif points[i] < 0 and double[i] then
      above = above + 1;
    end
  end

  local result = 0;
  if above >= 3 then
    result = -5;
  elseif below >= 3 then
    result = 5;
  end
  return result;
end

-------------------------------------------------------------------------------
-- getPointValue
-------------------------------------------------------------------------------

function getPointValue(points, double, index, balance)
  local result = 0;
  if index then
    result = points[index];
    if not double[index] then
      result = result + balance;
    end
  end
  return result;
end

-------------------------------------------------------------------------------
-- takeAll
-------------------------------------------------------------------------------

function takeAll()
  srReadScreen();
  local updateList = findAllImages("ThisIs.png");
  for i=1,#updateList do
    safeClick(updateList[i][0], updateList[i][1]);
  end
  sleepWithStatus(longWait, updateMessage("Update Crematory Windows"));
  srReadScreen();
  local takeList = findAllImages("crem-take.png");
  for i=1,#takeList do
    safeClick(takeList[i][0] + 5, takeList[i][1] + 5);
    sleepWithStatus(shortWait*2, "Waiting for Everything");
    srReadScreen();
    local all = waitForImage("Everything.png", maxWait, "Grabbing Everything");
    if all then
      safeClick(all[0] + 5, all[1] + 5);
    end
    lsSleep(shortWait*2);
  end
end

-------------------------------------------------------------------------------
-- promptLoad
-------------------------------------------------------------------------------

function promptLoad()
  scale = 1.0;
  local z = 0;
  local is_done = nil;
  while not is_done do
    checkBreak("disallow pause");
    lsPrint(10, 10, z, scale, scale, 0xFFFFFFff, "Configure");
    local y = 60;

    lsPrint(5, y, z, scale, scale, 0xffffffff, "Passes:");
    is_done, passCount = lsEditBox("passes", 110, y, z, 50, 30, scale, scale,
                                   0x000000ff, 5);
    if not tonumber(passCount) then
      is_done = false;
      lsPrint(10, y+18, z+10, 0.7, 0.7, 0xFF2020ff, "MUST BE A NUMBER");
      passCount = 1;
    end
    y = y + 48;

    load_flax = lsCheckBox(15, y, z+10, 0xffffffff, "Dried Flax",
                           load_flax);
    y = y + 32;

    load_papyrus = lsCheckBox(15, y, z+10, 0xffffffff, "Dried Papyrus",
                              load_papyrus);
    y = y + 32;

    load_leeks = lsCheckBox(15, y, z+10, 0xffffffff, "Leeks",
                            load_leeks);
    y = y + 32;

    load_limestone = lsCheckBox(15, y, z+10, 0xffffffff, "Limestone",
                                load_limestone);
    y = y + 32;

    lsPrintWrapped(10, y, z+10, lsScreenX - 20, 0.7, 0.7, 0xd0d0d0ff,
                   "Make sure each crematory is pinned and empty.");

    if lsButtonText(10, lsScreenY - 30, z, 100, 0xFFFFFFff, "Begin") then
        is_done = 1;
    end
    if lsButtonText(lsScreenX - 110, lsScreenY - 30, z, 100, 0xFFFFFFff,
                    "End script") then
      error "Clicked End Script button";
    end
    lsDoFrame();
    lsSleep(shortWait);
  end
end

-------------------------------------------------------------------------------
-- loadAll
-------------------------------------------------------------------------------

function loadAll()
  srReadScreen();
  local posList = findAllImages("ThisIs.png");
  for i=1,#posList do
    safeClick(posList[i][0], posList[i][1]);
  end
  sleepWithStatus(longWait, updateMessage("Update Crematory Windows"));
  srReadScreen();
  posList = findAllImages("crem-fire.png");
  for i=1,#posList do
    loadSingle(posList[i], woodOffset, "Wood");
    if load_flax then
      loadSingle(posList[i], flaxOffset, "Flax");
    end
    if load_papyrus then
      loadSingle(posList[i], papyrusOffset, "Papyrus");
    end
    if load_leeks then
      loadSingle(posList[i], leeksOffset, "Leeks");
    end
    if load_limestone then
      loadSingle(posList[i], limestoneOffset, "Limestone");
    end
  end
end

-------------------------------------------------------------------------------
-- loadSingle
-------------------------------------------------------------------------------

function loadSingle(pos, offset, type)
  sleepWithStatus(200, "Waiting to load");
  safeClick(pos[0]+5, pos[1]+5+16);
  lsSleep(100);
  local limePos = waitForImage("crem-limestone.png", maxWait,
			       "Loading " .. type .. " Into Crematory");
  if limePos then
    safeClick(limePos[0] + 5, limePos[1] + 5 + offset);
    lsSleep(100);
    local maxPos = waitForImage("crem-max.png", maxWait,
				"Adding Maximum Amount");
    if maxPos then
      safeClick(maxPos[0]+5, maxPos[1]+5);
    end
  end
  lsSleep(100);
  sleepWithStatus(shortWait, "Waiting for load to complete");
end

-------------------------------------------------------------------------------
-- updateMessage
-------------------------------------------------------------------------------

function updateMessage(message)
  local result = "Pass " .. currentPass .. " / " .. passCount .. "\n";
  result = result .. message .. "\n\n";
  if message == "Tending Crematory" then
    for i=1,#windows do
      local status = "Buttons: ";
      for j=1,5 do
	if windows[i].dirs[j] == OPP then
	  status = status .. getDir("+", windows[i].ups[j]) ..
	    getDir("-", windows[i].downs[j]);
	elseif windows[i].dirs[j] == SAME_UP then
	  status = status .. getDir("+", windows[i].ups[j]) ..
	    getDir("+", windows[i].downs[j]);
	else
	  status = status .. getDir("-", windows[i].ups[j]) ..
	    getDir("-", windows[i].downs[j]);
	end
	if j ~= 5 then
	  status = status .. ", ";
	else
	  status = status .. "\n";
	end
      end
      result = result .. "\n" .. status;
    end
  end
  return result;
end

function getDir(sign, number)
  local result = "";
  if number then
    result = sign .. number
  end
  return result;
end

Forge.inc to add Treated Metal Sheeting option:

button_names = {
"Knife Blade",
"Shovel Blade",
"Nails",
"Copper Pipe",
"Lead Pipe",
"Bars",
"Sheeting",
"Straps",
"Tools",
"Wire"
};

bar_button_names = {
"Iron Bar",
"Gold Bar",
"Silver Bar"
};

sheeting_button_names = {
"Lead Sheeting",
"Gold Sheeting",
"Copper Sheeting",
"Octecs Alloy Sheeting",
"Silver Sheeting",
"Steel Sheeting",
"Gold Foil",
"Metal Blue Sheeting",
"Treated Metal Sheeting",
"Tin Sheeting",
"Moon Steel Sheeting",
"Thoths Metal Sheeting"
};

straps_button_names = {
"Water Metal Strap",
"Iron Strap",
"Aluminum Strap",
"Copper Strap"
};

tools_button_names = {
"Iron Poker",
"Steel Blade",
"Lead Chisel"
};

wire_button_names = {
"Thoths Metal Wire",
"Metal Blue Wire",
"Magnesium Wire",
"Octecs Alloy Wire",
"Silver Wire",
"Copper Wire",
"Steel Wire",
"Gold Wire"
};


----------------- MAKE PROJECTS 'SUPPORTING' FUNCTIONS -----------------

function waitMinutes(minutes)
-- Teppy Minute is 66 seconds or 66000 ms
-- Add a 3 second delay (3000 ms) in case of lag

wait_delay = 3000; -- Extra delay on top of Teppy Time, for lag purposes. Default is 3000
wait = (minutes * 66000) + wait_delay;
askForFocus(); -- Pause to allow user to focus back to ATITD (if they checked the Pause for Focus Box), before starting project.
end


function doneGUI(totalPasses)
wait = 5000;  -- Gives a 5 second delay to review the GUI stats, before quitting/returing to Main Menu.
clickAllImages("This.png"); -- Refresh the screen. Update forge window so we know how much charcoal is currently in each forge before next project

sleepWithStatus(wait, "[" .. totalPasses .. "/" .. totalPasses .. "] ALL DONE!\n----------------------------------------------\n[" .. made .. "/" .. batch*project_windows*num_loops .. "] " .. name .. " / Completed");

lsPlaySound("Complete.wav");
runForge(); -- Return to/Display Main Menu
end


function waitGUI(pass)
	--If any forge menus shows the Forge_StartFire.png - refreshWindows() function, then display the stalledMessage in the GUI. Suggests its not lit (or out of charcoal)
	if #stalled > 0 then
	stalledMessage = "\n[" .. #stalled .. "] Forges STALLED (Needs Lit)"
	else
	stalledMessage = "";
	end

sleepWithStatus(wait, "[" .. pass .. "/" .. num_loops .. "] Total Passes\n----------------------------------------------\n[" .. batch .. "] " .. name .. " per forge\n[" .. project_windows .. "] Forges working" .. stalledMessage .. "\n----------------------------------------------\n[" .. batch*project_windows .. "] " .. name .. " per pass\n----------------------------------------------\n[" .. made .. "/" .. batch*project_windows*num_loops .. "] " .. name .. " / Completed");

made = made + (batch*project_windows);
end


function refreshWindows()
	checkBreak();
	pinned_windows = clickAllImages("This.png");
	lsSleep(400);
		if pinned_windows == 0 then
		error("No pinned windows found!");
		else
		srReadScreen();
		stalled = findAllImages("Forge/Forge_StartFire.png");
			if #stalled == pinned_windows/2 then -- The /2 is because each forge has 'This' located in window twice. Can't use ThisIs.png either because idle/working forge has different words (Idle Forge shows 'This' only and Working Forge shows 'This Is'
			error("No forges are lit!");
			end
		end
end


----------------- MAKE PROJECT FUNCTIONS -----------------

function KnifeBlade()
	num_loops = promptNumber("How many passes ?", 1);
	batch = 1;
	name = "Knife Blade";
	waitMinutes(10);
		for i=1, num_loops do
			while 1 do
			refreshWindows();
			project_windows = clickAllImages("Forge/Forge_Knife_Blade.png");
				if project_windows == 0 then
				sleepWithStatus(1500, "Waiting for Project windows");
				else
				break;
				end
			end
			waitGUI(i);
		end
	doneGUI(num_loops);
end

function ShovelBlade()
	num_loops = promptNumber("How many passes ?", 1);
	batch = 1;
	name = "Shovel Blade";
	waitMinutes(5);
		for i=1, num_loops do
			while 1 do
			refreshWindows();
			project_windows = clickAllImages("Forge/Forge_Shovel_Blade.png");
				if project_windows == 0 then
				sleepWithStatus(1500, "Waiting for Project windows");
				else
				break;
				end
			end
			waitGUI(i);
		end
	doneGUI(num_loops);
end

function Nails()
	num_loops = promptNumber("How many passes ?", 1);
	batch = 12;
	name = "Nails";
	waitMinutes(1);
		for i=1, num_loops do
			while 1 do
			refreshWindows();
			project_windows = clickAllImages("Forge/Forge_Nail.png");
				if project_windows == 0 then
				sleepWithStatus(1500, "Waiting for Project windows");
				else
				break;
				end
			end
			waitGUI(i);
		end
	doneGUI(num_loops);
end

function CopperPipe()
	num_loops = promptNumber("How many passes ?", 1);
	batch = 1;
	name = "Copper Pipe";
	waitMinutes(5);
		for i=1, num_loops do
			while 1 do
			refreshWindows();
			project_windows = clickAllImages("Forge/Forge_Copper_Pipe.png");
				if project_windows == 0 then
				sleepWithStatus(1500, "Waiting for Project windows");
				else
				break;
				end
			end
			waitGUI(i);
		end
	doneGUI(num_loops);
end

function LeadPipe()
	num_loops = promptNumber("How many passes ?", 1);
	batch = 1;
	name = "Lead Pipe";
	waitMinutes(5);
		for i=1, num_loops do
			while 1 do
			refreshWindows();
			project_windows = clickAllImages("Forge/Forge_Lead_Pipe.png");
				if project_windows == 0 then
				sleepWithStatus(1500, "Waiting for Project windows");
				else
				break;
				end
			end
			waitGUI(i);
		end
	doneGUI(num_loops);
end

function IronBar()
	num_loops = promptNumber("How many passes ?", 1);
	batch = 1;
	name = "Iron Bar";
	waitMinutes(15);
		for i=1, num_loops do
			while 1 do
			refreshWindows();
			clickAllImages("Forge/Forge_Bars.png");
			lsSleep(400);
			project_windows = clickAllImages("Forge/Forge_Iron_Bar.png");
				if project_windows == 0 then
				sleepWithStatus(1100, "Waiting for Project windows");
				else
				break;
				end
			end
			waitGUI(i);
		end
	doneGUI(num_loops);
end

function GoldBar()
	num_loops = promptNumber("How many passes ?", 1);
	batch = 1;
	name = "Gold Bar";
	waitMinutes(5);
		for i=1, num_loops do
			while 1 do
			refreshWindows();
			clickAllImages("Forge/Forge_Bars.png");
			lsSleep(400);
			project_windows = clickAllImages("Forge/Forge_Gold_Bar.png");
				if project_windows == 0 then
				sleepWithStatus(1100, "Waiting for Project windows");
				else
				break;
				end
			end
			waitGUI(i);
		end
	doneGUI(num_loops);
end

function SilverBar()
	num_loops = promptNumber("How many passes ?", 1);
	batch = 1;
	name = "Silver Bar";
	waitMinutes(10);
		for i=1, num_loops do
			while 1 do
			refreshWindows();
			clickAllImages("Forge/Forge_Bars.png");
			lsSleep(400);
			project_windows = clickAllImages("Forge/Forge_Silver_Bar.png");
				if project_windows == 0 then
				sleepWithStatus(1100, "Waiting for Project windows");
				else
				break;
				end
			end
			waitGUI(i);
		end
	doneGUI(num_loops);
end

function LeadSheeting()
	num_loops = promptNumber("How many passes ?", 1);
	batch = 1;
	name = "Lead Sheeting";
	waitMinutes(10);
		for i=1, num_loops do
			while 1 do
			refreshWindows();
			clickAllImages("Forge/Forge_Sheeting.png");
			lsSleep(400);
			project_windows = clickAllImages("Forge/Forge_Lead_Sheeting.png");
				if project_windows == 0 then
				sleepWithStatus(1100, "Waiting for Project windows");
				else
				break;
				end
			end
			waitGUI(i);
		end
	doneGUI(num_loops);
end

function GoldSheeting()
	num_loops = promptNumber("How many passes ?", 1);
	batch = 4;
	name = "Gold Sheeting";
	waitMinutes(10);
		for i=1, num_loops do
			while 1 do
			refreshWindows();
			clickAllImages("Forge/Forge_Sheeting.png");
			lsSleep(400);
			project_windows = clickAllImages("Forge/Forge_Gold_Sheeting.png");
				if project_windows == 0 then
				sleepWithStatus(1100, "Waiting for Project windows");
				else
				break;
				end
			end
			waitGUI(i);
		end
	doneGUI(num_loops);
end

function CopperSheeting()
	num_loops = promptNumber("How many passes ?", 1);
	batch = 1;
	name = "Copper Sheeting";
	waitMinutes(1);
		for i=1, num_loops do
			while 1 do
			refreshWindows();
			clickAllImages("Forge/Forge_Sheeting.png");
			lsSleep(400);
			project_windows = clickAllImages("Forge/Forge_Copper_Sheeting.png");
				if project_windows == 0 then
				sleepWithStatus(1100, "Waiting for Project windows");
				else
				break;
				end
			end
			waitGUI(i);
		end
	doneGUI(num_loops);
end

function TreatedSheeting()
	num_loops = promptNumber("How many passes ?", 1);
	typeOfMetal = promptText("Enter the metal name:");
	batch = 1;
	name = "Treated Metal Sheeting";
	waitMinutes(2);
		for i=1, num_loops do
			while 1 do
				refreshWindows();
				clickAllImages("Forge/Forge_Sheeting.png");
				lsSleep(400);
				project_windows = clickAllText("Treated");
				if project_windows == 0 then
					sleepWithStatus(1100, "Waiting for Project windows");
				else
					lsSleep(400);
					local numClicked = clickAllText(typeOfMetal);
					if numClicked == 0 then
						break;
					end
				end
			end
			waitGUI(i);
		end
	doneGUI(num_loops);
end

function OctecsAlloySheeting()
	num_loops = promptNumber("How many passes ?", 1);
	batch = 8;
	name = "Octecs Alloy";
	waitMinutes(20);
		for i=1, num_loops do
			while 1 do
			refreshWindows();
			clickAllImages("Forge/Forge_Sheeting.png");
			lsSleep(400);
			project_windows = clickAllImages("Forge/Forge_Octecs_Alloy_Sheeting.png");
				if project_windows == 0 then
				sleepWithStatus(1100, "Waiting for Project windows");
				else
				break;
				end
			end
			waitGUI(i);
		end
	doneGUI(num_loops);
end

function SilverSheeting()
	num_loops = promptNumber("How many passes ?", 1);
	batch = 1;
	name = "Silver Sheeting";
	waitMinutes(2);
		for i=1, num_loops do
			while 1 do
			refreshWindows();
			clickAllImages("Forge/Forge_Sheeting.png");
			lsSleep(400);
			project_windows = clickAllImages("Forge/Forge_Silver_Sheeting.png");
				if project_windows == 0 then
				sleepWithStatus(1100, "Waiting for Project windows");
				else
				break;
				end
			end
			waitGUI(i);
		end
	doneGUI(num_loops);
end

function SteelSheeting()
	num_loops = promptNumber("How many passes ?", 1);
	batch = 6;
	name = "Steel Sheeting";
	waitMinutes(10);
		for i=1, num_loops do
			while 1 do
			refreshWindows();
			clickAllImages("Forge/Forge_Sheeting.png");
			lsSleep(400);
			project_windows = clickAllImages("Forge/Forge_Steel_Sheeting.png");
				if project_windows == 0 then
				sleepWithStatus(1100, "Waiting for Project windows");
				else
				break;
				end
			end
			waitGUI(i);
		end
	doneGUI(num_loops);
end

function GoldFoil()
	num_loops = promptNumber("How many passes ?", 1);
	batch = 4;
	name = "Gold Foil";
	waitMinutes(1);
		for i=1, num_loops do
			while 1 do
			refreshWindows();
			clickAllImages("Forge/Forge_Sheeting.png");
			lsSleep(400);
			project_windows = clickAllImages("Forge/Forge_Gold_Foil.png");
				if project_windows == 0 then
				sleepWithStatus(1100, "Waiting for Project windows");
				else
				break;
				end
			end
			waitGUI(i);
		end
	doneGUI(num_loops);
end

function MetalBlueSheeting()
	num_loops = promptNumber("How many passes ?", 1);
	batch = 1;
	name = "Metal Blue Sheeting";
	waitMinutes(15);
		for i=1, num_loops do
			while 1 do
			refreshWindows();
			clickAllImages("Forge/Forge_Sheeting.png");
			lsSleep(400);
			project_windows = clickAllImages("Forge/Forge_Metal_Blue_Sheeting.png");
				if project_windows == 0 then
				sleepWithStatus(1100, "Waiting for Project windows");
				else
				break;
				end
			end
			waitGUI(i);
		end
	doneGUI(num_loops);
end

function TinSheeting()
	num_loops = promptNumber("How many passes ?", 1);
	batch = 1;
	name = "Tin Sheeting";
	waitMinutes(5);
		for i=1, num_loops do
			while 1 do
			refreshWindows();
			clickAllImages("Forge/Forge_Sheeting.png");
			lsSleep(400);
			project_windows = clickAllImages("Forge/Forge_Tin_Sheeting.png");
				if project_windows == 0 then
				sleepWithStatus(1100, "Waiting for Project windows");
				else
				break;
				end
			end
			waitGUI(i);
		end
	doneGUI(num_loops);
end

function MoonSteelSheeting()
	num_loops = promptNumber("How many passes ?", 1);
	batch = 1;
	name = "Moon Steel Sheeting";
	waitMinutes(5);
		for i=1, num_loops do
			while 1 do
			refreshWindows();
			clickAllImages("Forge/Forge_Sheeting.png");
			lsSleep(400);
			project_windows = clickAllImages("Forge/Forge_Moon_Steel_Sheeting.png");
				if project_windows == 0 then
				sleepWithStatus(1100, "Waiting for Project windows");
				else
				break;
				end
			end
			waitGUI(i);
		end
	doneGUI(num_loops);
end

function ThothsMetalSheeting()
	num_loops = promptNumber("How many passes ?", 1);
	batch = 1;
	name = "Thoths Metal Sheeting";
	waitMinutes(10);
		for i=1, num_loops do
			while 1 do
			refreshWindows();
			clickAllImages("Forge/Forge_Sheeting.png");
			lsSleep(400);
			project_windows = clickAllImages("Forge/Forge_Thoths_Metal_Sheeting.png");
				if project_windows == 0 then
				sleepWithStatus(1100, "Waiting for Project windows");
				else
				break;
				end
			end
			waitGUI(i);
		end
	doneGUI(num_loops);
end

function WaterMetalStrap()
	num_loops = promptNumber("How many passes ?", 1);
	batch = 1;
	name = "Water Metal Strap";
	waitMinutes(1);
		for i=1, num_loops do
			while 1 do
			refreshWindows();
			clickAllImages("Forge/Forge_Straps.png");
			lsSleep(400);
			project_windows = clickAllImages("Forge/Forge_Water_Metal_Strap.png");
				if project_windows == 0 then
				sleepWithStatus(1100, "Waiting for Project windows");
				else
				break;
				end
			end
			waitGUI(i);
		end
	doneGUI(num_loops);
end

function IronStrap()
	num_loops = promptNumber("How many passes ?", 1);
	batch = 1;
	name = "Iron Strap";
	waitMinutes(3);
		for i=1, num_loops do
			while 1 do
			refreshWindows();
			clickAllImages("Forge/Forge_Straps.png");
			lsSleep(400);
			project_windows = clickAllImages("Forge/Forge_Iron_Strap.png");
				if project_windows == 0 then
				sleepWithStatus(1100, "Waiting for Project windows");
				else
				break;
				end
			end
			waitGUI(i);
		end
	doneGUI(num_loops);
end

function AluminumStrap()
	num_loops = promptNumber("How many passes ?", 1);
	batch = 1;
	name = "Aluminum Strap";
	waitMinutes(1);
		for i=1, num_loops do
			while 1 do
			refreshWindows();
			clickAllImages("Forge/Forge_Straps.png");
			lsSleep(400);
			project_windows = clickAllImages("Forge/Forge_Aluminum_Strap.png");
				if project_windows == 0 then
				sleepWithStatus(1100, "Waiting for Project windows");
				else
				break;
				end
			end
			waitGUI(i);
		end
	doneGUI(num_loops);
end
	
function CopperStrap()
	num_loops = promptNumber("How many passes ?", 1);
	batch = 1;
	name = "Copper Strap";
	waitMinutes(2);
		for i=1, num_loops do
			while 1 do
			refreshWindows();
			clickAllImages("Forge/Forge_Straps.png");
			lsSleep(400);
			project_windows = clickAllImages("Forge/Forge_Copper_Strap.png");
				if project_windows == 0 then
				sleepWithStatus(1100, "Waiting for Project windows");
				else
				break;
				end
			end
			waitGUI(i);
		end
	doneGUI(num_loops);
end

function IronPoker()
	num_loops = promptNumber("How many passes ?", 1);
	batch = 1;
	name = "Iron Poker";
	waitMinutes(20);
		for i=1, num_loops do
			while 1 do
			refreshWindows();
			clickAllImages("Forge/Forge_Tools.png");
			lsSleep(400);
			project_windows = clickAllImages("Forge/Forge_Iron_Poker.png");
				if project_windows == 0 then
				sleepWithStatus(1100, "Waiting for Project windows");
				else
				break;
				end
			end
			waitGUI(i);
		end
	doneGUI(num_loops);
end

function SteelBlade()
	num_loops = promptNumber("How many passes ?", 1);
	batch = 1;
	name = "Steel Blade";
	waitMinutes(10);
		for i=1, num_loops do
			while 1 do
			refreshWindows();
			clickAllImages("Forge/Forge_Tools.png");
			lsSleep(400);
			project_windows = clickAllImages("Forge/Forge_Steel_Blade.png");
				if project_windows == 0 then
				sleepWithStatus(1100, "Waiting for Project windows");
				else
				break;
				end
			end
			waitGUI(i);
		end
	doneGUI(num_loops);
end
	
function LeadChisel()
	num_loops = promptNumber("How many passes ?", 1);
	batch = 1;
	name = "Lead Chisel";
	waitMinutes(6);
		for i=1, num_loops do
			while 1 do
			refreshWindows();
			clickAllImages("Forge/Forge_Tools.png");
			lsSleep(400);
			project_windows = clickAllImages("Forge/Forge_Lead_Chisel.png");
				if project_windows == 0 then
				sleepWithStatus(1100, "Waiting for Project windows");
				else
				break;
				end
			end
			waitGUI(i);
		end
	doneGUI(num_loops);
end

function ThothsMetalWire()
	num_loops = promptNumber("How many passes ?", 1);
	batch = 14;
	name = "Thoths Metal Wire";
	waitMinutes(5);
		for i=1, num_loops do
			while 1 do
			refreshWindows();
			clickAllImages("Forge/Forge_Wire.png");
			lsSleep(400);
			project_windows = clickAllImages("Forge/Forge_Thoths_Metal_Wire.png");
				if project_windows == 0 then
				sleepWithStatus(1100, "Waiting for Project windows");
				else
				break;
				end
			end
			waitGUI(i);
		end
	doneGUI(num_loops);
end

function MetalBlueWire()
	num_loops = promptNumber("How many passes ?", 1);
	batch = 12;
	name = "Metal Blue Wire";
	waitMinutes(5);
		for i=1, num_loops do
			while 1 do
			refreshWindows();
			clickAllImages("Forge/Forge_Wire.png");
			lsSleep(400);
			project_windows = clickAllImages("Forge/Forge_Metal_Blue_Wire.png");
				if project_windows == 0 then
				sleepWithStatus(1100, "Waiting for Project windows");
				else
				break;
				end
			end
			waitGUI(i);
		end
	doneGUI(num_loops);
end

function MagnesiumWire()
	num_loops = promptNumber("How many passes ?", 1);
	batch = 10;
	name = "Magnesium Wire";
	waitMinutes(1);
		for i=1, num_loops do
			while 1 do
			refreshWindows();
			clickAllImages("Forge/Forge_Wire.png");
			lsSleep(400);
			project_windows = clickAllImages("Forge/Forge_Magnesium_Wire.png");
				if project_windows == 0 then
				sleepWithStatus(1100, "Waiting for Project windows");
				else
				break;
				end
			end
			waitGUI(i);
		end
	doneGUI(num_loops);
end

function OctecsAlloyWire()
	num_loops = promptNumber("How many passes ?", 1);
	batch = 16;
	name = "Octecs Alloy Wire";
	waitMinutes(10);
		for i=1, num_loops do
			while 1 do
			refreshWindows();
			clickAllImages("Forge/Forge_Wire.png");
			lsSleep(400);
			project_windows = clickAllImages("Forge/Forge_Octecs_Alloy_Wire.png");
				if project_windows == 0 then
				sleepWithStatus(1100, "Waiting for Project windows");
				else
				break;
				end
			end
			waitGUI(i);
		end
	doneGUI(num_loops);
end

function SilverWire()
	num_loops = promptNumber("How many passes ?", 1);
	batch = 5;
	name = "Silver Wire";
	waitMinutes(5);
		for i=1, num_loops do
			while 1 do
			refreshWindows();
			clickAllImages("Forge/Forge_Wire.png");
			lsSleep(400);
			project_windows = clickAllImages("Forge/Forge_Silver_Wire.png");
				if project_windows == 0 then
				sleepWithStatus(1100, "Waiting for Project windows");
				else
				break;
				end
			end
			waitGUI(i);
		end
	doneGUI(num_loops);
end

function CopperWire()
	num_loops = promptNumber("How many passes ?", 1);
	batch = 20;
	name = "Copper Wire";
	waitMinutes(5);
		for i=1, num_loops do
			while 1 do
			refreshWindows();
			clickAllImages("Forge/Forge_Wire.png");
			lsSleep(400);
			project_windows = clickAllImages("Forge/Forge_Copper_Wire.png");
				if project_windows == 0 then
				sleepWithStatus(1100, "Waiting for Project windows");
				else
				break;
				end
			end
			waitGUI(i);
		end
	doneGUI(num_loops);
end

function SteelWire()
	num_loops = promptNumber("How many passes ?", 1);
	batch = 20;
	name = "Steel Wire";
	waitMinutes(5);
		for i=1, num_loops do
			while 1 do
			refreshWindows();
			clickAllImages("Forge/Forge_Wire.png");
			lsSleep(400);
			project_windows = clickAllImages("Forge/Forge_Steel_Wire.png");
				if project_windows == 0 then
				sleepWithStatus(1100, "Waiting for Project windows");
				else
				break;
				end
			end
			waitGUI(i);
		end
	doneGUI(num_loops);
end

function GoldWire()
	num_loops = promptNumber("How many passes ?", 1);
	batch = 10;
	name = "Gold Wire";
	waitMinutes(10);
		for i=1, num_loops do
			while 1 do
			refreshWindows();
			clickAllImages("Forge/Forge_Wire.png");
			lsSleep(400);
			project_windows = clickAllImages("Forge/Forge_Gold_Wire.png");
				if project_windows == 0 then
				sleepWithStatus(1100, "Waiting for Project windows");
				else
				break;
				end
			end
			waitGUI(i);
		end
	doneGUI(num_loops);
end


function Bars()
	while 1 do
		-- Ask for which button
		local image_name = nil;
		local is_done = nil;	
		while not is_done do
			local y = nil;
			local x = nil;
			local bsize = nil;
			for i=1, #bar_button_names do
				if bar_button_names[i] == "Iron Bar" then
					x = 30;
					y = 10;
					bsize = 250;
				elseif bar_button_names[i] == "Gold Bar" then
					x = 30;
					y = 40;
					bsize = 250;
				elseif bar_button_names[i] == "Silver Bar" then
					x = 30;
					y = 70;
					bsize = 250;
				end
				if lsButtonText(x, y, 0, bsize, 0x80D080ff, bar_button_names[i]) then
					image_name = bar_button_names[i];
					is_done = 1;
				end
			end

			if lsButtonText(lsScreenX - 110, lsScreenY - 30, z, 100, 0xFFFFFFff, "End script") then
				error "Clicked End Script button";
			end
			lsDoFrame();
			lsSleep(10);
		end	
		
		if image_name == "Iron Bar" then
			IronBar();
		elseif image_name == "Gold Bar" then
			GoldBar();
		elseif image_name == "Silver Bar" then
			SilverBar();
		end
	end
end

function Sheeting()
	while 1 do
		-- Ask for which button
		local image_name = nil;
		local is_done = nil;	
		while not is_done do
			local y = nil;
			local x = nil;
			local bsize = nil;
			for i=1, #sheeting_button_names do
				if sheeting_button_names[i] == "Lead Sheeting" then
					x = 30;
					y = 10;
					bsize = 150;
				elseif sheeting_button_names[i] == "Gold Sheeting" then
					x = 30;
					y = 35;
					bsize = 150;
				elseif sheeting_button_names[i] == "Copper Sheeting" then
					x = 30;
					y = 60;
					bsize = 150;
        elseif sheeting_button_names[i] == "Treated Metal Sheeting" then
					x = 30;
					y = 285;
					bsize = 150;
				elseif sheeting_button_names[i] == "Octecs Alloy Sheeting" then
					x = 30;
					y = 85;
					bsize = 150;
				elseif sheeting_button_names[i] == "Silver Sheeting" then
					x = 30;
					y = 110;
					bsize = 150;
				elseif sheeting_button_names[i] == "Steel Sheeting" then
					x = 30;
					y = 135;
					bsize = 150;
				elseif sheeting_button_names[i] == "Gold Foil" then
					x = 30;
					y = 160;
					bsize = 150;
				elseif sheeting_button_names[i] == "Metal Blue Sheeting" then
					x = 30;
					y = 185;
					bsize = 150;
				elseif sheeting_button_names[i] == "Tin Sheeting" then
					x = 30;
					y = 210;
					bsize = 150;
				elseif sheeting_button_names[i] == "Moon Steel Sheeting" then
					x = 30;
					y = 235;
					bsize = 150;
				elseif sheeting_button_names[i] == "Thoths Metal Sheeting" then
					x = 30;
					y = 260;
					bsize = 150;
				end
				if lsButtonText(x, y, 0, 250, 0x80D080ff, sheeting_button_names[i]) then
					image_name = sheeting_button_names[i];
					is_done = 1;
				end
			end

			if lsButtonText(lsScreenX - 110, lsScreenY - 30, z, 100, 0xFFFFFFff, "End script") then
				error "Clicked End Script button";
			end
			lsDoFrame();
			lsSleep(10);
		end	
		
		if image_name == "Lead Sheeting" then
			LeadSheeting();
		elseif image_name == "Gold Sheeting" then
			GoldSheeting();
		elseif image_name == "Copper Sheeting" then
			CopperSheeting();
    elseif image_name == "Treated Metal Sheeting" then
			TreatedSheeting();
		elseif image_name == "Octecs Alloy Sheeting" then
			OctecsAlloySheeting();
		elseif image_name == "Silver Sheeting" then
			SilverSheeting();
		elseif image_name == "Steel Sheeting" then
			SteelSheeting();
		elseif image_name == "Gold Foil" then
			GoldFoil();
		elseif image_name == "Metal Blue Sheeting" then
			MetalBlueSheeting();
		elseif image_name == "Tin Sheeting" then
			TinSheeting();
		elseif image_name == "Moon Steel Sheeting" then
			MoonSteelSheeting();
		elseif image_name == "Thoths Metal Sheeting" then
			ThothsMetalSheeting();
		end
	end


end

function Straps()
	while 1 do
		-- Ask for which button
		local image_name = nil;


		local is_done = nil;	
		while not is_done do
			local y = nil;
			local x = nil;
			local bsize = nil;
			for i=1, #straps_button_names do
				if straps_button_names[i] == "Water Metal Strap" then
					x = 30;
					y = 10;
					bsize = 250;
				elseif straps_button_names[i] == "Iron Strap" then
					x = 30;
					y = 40;
					bsize = 250;
				elseif straps_button_names[i] == "Aluminum Strap" then
					x = 30;
					y = 70;
					bsize = 250;
				elseif straps_button_names[i] == "Copper Strap" then
					x = 30;
					y = 100;
					bsize = 250;
				end
				if lsButtonText(x, y, 0, bsize, 0x80D080ff, straps_button_names[i]) then
					image_name = straps_button_names[i];
					is_done = 1;
				end
			end

			if lsButtonText(lsScreenX - 110, lsScreenY - 30, z, 100, 0xFFFFFFff, "End script") then
				error "Clicked End Script button";
			end
			lsDoFrame();
			lsSleep(10);
		end	
		
		if image_name == "Water Metal Strap" then
			WaterMetalStrap();
		elseif image_name == "Iron Strap" then
			IronStrap();
		elseif image_name == "Aluminum Strap" then
			AluminumStrap();
		elseif image_name == "Copper Strap" then
			CopperStrap();
		end
	end
end

function Tools()
	while 1 do
		-- Ask for which button
		local image_name = nil;
		local is_done = nil;	
		while not is_done do
			local y = nil;
			local x = nil;
			local bsize = nil;
			for i=1, #tools_button_names do
				if tools_button_names[i] == "Iron Poker" then
					x = 30;
					y = 10;
					bsize = 250;
				elseif tools_button_names[i] == "Steel Blade" then
					x = 30;
					y = 40;
					bsize = 250;
				elseif tools_button_names[i] == "Lead Chisel" then
					x = 30;
					y = 70;
					bsize = 250;
				end
				if lsButtonText(x, y, 0, bsize, 0x80D080ff, tools_button_names[i]) then
					image_name = tools_button_names[i];
					is_done = 1;
				end
			end

			if lsButtonText(lsScreenX - 110, lsScreenY - 30, z, 100, 0xFFFFFFff, "End script") then
				error "Clicked End Script button";
			end
			lsDoFrame();
			lsSleep(10);
		end	
		
		if image_name == "Iron Poker" then
			IronPoker();
		elseif image_name == "Steel Blade" then
			SteelBlade();
		elseif image_name == "Lead Chisel" then
			LeadChisel();
		end
	end
end

function Wire()
	while 1 do
		-- Ask for which button
		local image_name = nil;
		local is_done = nil;	
		while not is_done do
			local y = nil;
			local x = nil;
			local bsize = nil;
			for i=1, #wire_button_names do
				if wire_button_names[i] == "Thoths Metal Wire" then
					x = 30;
					y = 10;
					bsize = 150;
				elseif wire_button_names[i] == "Metal Blue Wire" then
					x = 30;
					y = 35;
					bsize = 150;
				elseif wire_button_names[i] == "Magnesium Wire" then
					x = 30;
					y = 60;
					bsize = 150;
				elseif wire_button_names[i] == "Octecs Alloy Wire" then
					x = 30;
					y = 85;
					bsize = 150;
				elseif wire_button_names[i] == "Silver Wire" then
					x = 30;
					y = 110;
					bsize = 150;
				elseif wire_button_names[i] == "Copper Wire" then
					x = 30;
					y = 135;
					bsize = 150;
				elseif wire_button_names[i] == "Steel Wire" then
					x = 30;
					y = 160;
					bsize = 150;
				elseif wire_button_names[i] == "Gold Wire" then
					x = 30;
					y = 185;
					bsize = 150;
				end
				if lsButtonText(x, y, 0, 250, 0x80D080ff, wire_button_names[i]) then
					image_name = wire_button_names[i];
					is_done = 1;
				end
			end

			if lsButtonText(lsScreenX - 110, lsScreenY - 30, z, 100, 0xFFFFFFff, "End script") then
				error "Clicked End Script button";
			end
			lsDoFrame();
			lsSleep(10);
		end	
		
		if image_name == "Thoths Metal Wire" then
			ThothsMetalWire();
		elseif image_name == "Metal Blue Wire" then
			MetalBlueWire();
		elseif image_name == "Magnesium Wire" then
			MagnesiumWire();
		elseif image_name == "Octecs Alloy Wire" then
			OctecsAlloyWire();
		elseif image_name == "Silver Wire" then
			SilverWire();
		elseif image_name == "Copper Wire" then
			CopperWire();
		elseif image_name == "Steel Wire" then
			SteelWire();
		elseif image_name == "Gold Wire" then
			GoldWire();
		end
	end
end

Barley with "Skip gather water" option:


-- Edit these first 2 to adjust how much is planted in a pass
-- May need to adjust walk_time in Barley_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;
watered = {};
loop_count = 0;
skip_water = 0;

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


function promptBarleyNumbers(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, 1);
		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 Barley " .. num_loops .. " times, requiring " .. (grid_w * grid_w) .. " raw barley and ".. (grid_w * grid_w * num_loops * 4) .. "water in jugs, doing " .. (grid_w*grid_w*num_loops) .. " 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
		y = y + 50;
		skip_water = lsCheckBox(10, y, z, 0xFFFFFFff, "Skip Rain Barrel", skip_water);

		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


function doit()

  promptBarleyNumbers(1);
  askForWindow("Make sure the plant barley 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.");
  lsSleep(1000);
  delay_time = 2000;
  local x = 1;
  local y = 1;
  initGlobals();
  -- Find the plant barley button
  srReadScreen();

  local imgBarley = "barley.png";
  local xyPlantBarley = srFindImage(imgBarley);
  if not xyPlantBarley then
    error 'Could not find plant window';
  end
  xyPlantBarley[0] = xyPlantBarley[0] + 5;
  
  -- Find the Rain Barrel
  if not skip_water then
	local imgDrawWater = "draw_water.png";
	local xyDrawWater = srFindImage(imgDrawWater);
	if not xyDrawWater then
		error 'Could not find rain barrel';
	end 
	xyDrawWater[0] = xyDrawWater[0] + 5;
  end

 

  for loop_count=1, num_loops do
    local start_time = lsGetTimer();
    harvested = 0;
    -- Init watered array to 0
    for y=grid_h, 1, -1 do
      for x=grid_w, 1, -1 do 
        watered[x+((y-1)*grid_w)] = 1;
      end
    end	
	  -- Local variables
    local xyCenter = getCenterPos();
    local xyBarleyMenu = {};
    xyBarleyMenu[0] = xyCenter[0] - 43;
    xyBarleyMenu[1] = xyCenter[1] + 0;
    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;
    for y=1, grid_h do
      for x=1, grid_w do
        lsPrintln('doing ' .. x .. ',' .. y .. ' of ' .. grid_w .. ',' .. grid_h);
        statusScreen("Planting " .. x .. ", " .. y);
        
        -- Plant
        lsPrintln('planting ' .. xyPlantBarley[0] .. ',' .. xyPlantBarley[1]);
        setWaitSpot(xyBarleyMenu[0], xyBarleyMenu[1]);
        srClickMouseNoMove(xyPlantBarley[0], xyPlantBarley[1], 0);
        srSetMousePos(xyBarleyMenu[0], xyBarleyMenu[1]);
        waitForChange();
        
        -- Bring up menu
        lsPrintln('menu ' .. xyBarleyMenu[0] .. ',' .. xyBarleyMenu[1]);
        setWaitSpot(xyBarleyMenu[0]+5, xyBarleyMenu[1]);
        srClickMouse(xyBarleyMenu[0], xyBarleyMenu[1], 0);
        waitForChange();

        -- Check for window size
        window_w = 214;
        window_h = 218;

        -- Pin
        lsPrintln('pin ' .. (xyBarleyMenu[0]+5) .. ',' .. xyBarleyMenu[1]);
        srClickMouseNoMove(xyBarleyMenu[0]+5, xyBarleyMenu[1]+0, 1);

        -- Move window
        local pp = pinnedPos(x, y);
        lsPrintln('move ' .. (xyBarleyMenu[0]+5) .. ',' .. xyBarleyMenu[1] .. ' to ' .. pp[0] .. ',' .. pp[1]);
        drag(xyBarleyMenu[0] + 5, xyBarleyMenu[1], pp[0], pp[1], 0);
		
        -- Add 2 water now
        srReadScreen();
        local barleyAddButton = srFindImageInRange("BarleyAdd.png", pp[0], pp[1], 200, 100);
        local barleyWater = srFindImageInRange("barleyWater.png", pp[0], pp[1] - 50, 220, 150);
        if not barleyAddButton or not barleyWater then
          -- bugfix maybe for lag.
          lsSleep(100);
          srReadScreen();
          barleyAddButton = srFindImageInRange("BarleyAdd.png", pp[0], pp[1], 200, 100);
          barleyWater = srFindImageInRange("barleyWater.png", pp[0], pp[1] - 50, 220, 150);
        end

        srClickMouseNoMove(barleyAddButton[0]+8, barleyWater[1]);
        srClickMouseNoMove(barleyAddButton[0]+8, barleyWater[1]);
        watered[x+((y-1)*grid_w)] = watered[x+((y-1)*grid_w)] + 2;

        -- 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;
          else
            lsPrintln('skipping walking, on last leg');
          end
        end
        checkBreak();
      end
    end
  
    statusScreen("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
  
    -- Barley has been planted, pinned and refocused	
 
    while 1 do
      for y=1, grid_h do
        for x=1, grid_w do 
          local pp = pinnedPos(x, y);
          local rp = refreshPosDown(x, y);
          srClickMouse(rp[0],rp[1]);
          lsSleep(200);
          srReadScreen();
          local leftBar = srFindImageInRange("barleyBarLeft.png", pp[0], pp[1] - 50, 120, 100);
          if leftBar then
            leftBar[0] = leftBar[0] + 4;
          end
          local rightBar = srFindImageInRange("barleyBarRight.png", pp[0], pp[1] - 50, 220, 200);
          if rightBar then
            rightBar[0] = rightBar[0] + 1;
          end
          if not rightBar then
            error 'Could not find rightbar';
          end
          local barleyWater = srFindImageInRange("barleyWater.png", pp[0], pp[1] - 50, 220, 150);
          if not barleyWater then error 'Could not find water button.'; end
          local barleyAddButton = srFindImageInRange("BarleyAdd.png", pp[0], pp[1], 200, 100);
          if not barleyAddButton then error 'Could not find add button. Ended at batch '; end

          while 1 do
            if leftBar then
              waterBlue = 0;
              if rightBar then
                if barleyWater then
                  srReadScreen();
                  for i=leftBar[0],rightBar[0] do
                    pxval = srReadPixelFromBuffer(i, barleyWater[1]);
                    b = (math.floor(pxval/256) % 256);
                    if b > 220 then
                      waterBlue = waterBlue + 1;
                    end
                  end
                  waterBlue = (waterBlue/(rightBar[0]-leftBar[0])*100);
                end
              end
            end
            checkBreak();
			
            if watered[x+((y-1)*grid_w)] < 5 then
              statusScreen("Watering " .. x .. "," .. y .. "step " .. watered[x+((y-1)*grid_w)] .. ".");
              if waterBlue < 90 then
                if watered[x+((y-1)*grid_w)] == 0 then
                end
                srClickMouseNoMove(barleyAddButton[0]+8, barleyWater[1]);
                watered[x+((y-1)*grid_w)] = watered[x+((y-1)*grid_w)] + 1;
                lsSleep(100);
                break;
              end
            else
              statusScreen("Harvesting " .. x .. "," .. y .. ".");
              if waterBlue < 90 then
                srClickMouseNoMove(pp[0]+90, pp[1]+90);
                lsSleep(100);
                srClickMouseNoMove(pp[0]+180, pp[1]-25);
                if watered[x+((y-1)*grid_w)] == 5 then
                  harvested = 1;
                end
                break;
              end
            end
          end
        end
      end

      if harvested == 0 then
        statusScreen("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
      else
        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
        break;
      end
    end
    local end_time = lsGetTimer();
    statusScreen("Time taken: " .. (end_time-start_time)/1000);
    -- move X and Y every 4 batches, but skip the Y move every 20th batch
    if loop_count % 4 == 0 and loop_count % 5 == 0 then
      doCorrectiveMove('x')
    elseif loop_count % 4 == 0 then
      doCorrectiveMove('xy')
    end 
    --doStashWH(num_loops*grid_w*grid_w);
    --doRefillWater(4*numloops*grid_w*grid_w);
    doStashWH(grid_w*grid_w);
	if not skip_water then
		doRefillWater(4*grid_w*grid_w);
	end
    debug('end of batch #' .. loop_count)
  end
end

function doCorrectiveMove(move)
  statusScreen("Moving to correct for drift");
  local xyCenter = getCenterPos();
  if move == 'xy' or move == 'x' then
    srClickMouseNoMove(xyCenter[0] + walk_px_x*-1, xyCenter[1], 0);
    lsSleep(walk_time);
  end
  if move == 'xy' or move == 'y' then
    srClickMouseNoMove(xyCenter[0], xyCenter[1] + walk_px_y, 0);
    lsSleep(walk_time);
  end
end

function doStashWH(qty)
  local wh = srFindImage("stash.png");
  if wh then
    srClickMouseNoMove(wh[0]+9,wh[1]+9)
    debug('found stash, clicked it');
    lsSleep(250);

    srReadScreen();
    local insects = srFindImage("stashInsectEllipsis.png");

    local stashes = srFindImage("stashBarley.png");
    if not stashes then
      error "no barley to stash"
    end
    srClickMouseNoMove(stashes[0],stashes[1]);

    lsSleep(250);
    -- stash exactly the right amount by number so we don't lose our seed barley
    srKeyEvent(qty);
    srKeyEvent('\n');

    if insects then
      srClickMouseNoMove(wh[0]+9,wh[1]+9)
      lsSleep(250);
      srReadScreen();

      local insects = srFindImage("stashInsectEllipsis.png");
      if insects then
        srClickMouseNoMove(insects[0],insects[1]);
        lsSleep(250);

        srReadScreen();
        insects = srFindImage("stashAllTheInsects.png");
        if not insects then
          error "found insects but couldn't stash them";
        end
        srClickMouseNoMove(insects[0],insects[1]);
      end
    end
  end
end

function doRefillWater(qty)
  debug("in refill")
  local rb = srFindImage("draw_water.png");
  if rb then
    srClickMouseNoMove(rb[0]+5,rb[1]+5)
    lsSleep(250);
    srKeyEvent(qty);
    srKeyEvent('\n');
  end

end


function debug(msg)
  if 0 then
    statusScreen(msg);
    lsSleep(1000);
  end 
end