The Wiki for Tale 8 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.

Difference between revisions of "User:Augir/Foliage"

From A Wiki in the Desert
Jump to navigation Jump to search
(Replaced content with "http://www.atitd.org/wiki/tale3/Guides/Foliage")
Line 1: Line 1:
 
http://www.atitd.org/wiki/tale3/Guides/Foliage
 
http://www.atitd.org/wiki/tale3/Guides/Foliage
 
-- crematory.lua v1.2 by Tallow
 
--
 
-- Runs one or more crematories. Automatically discovers button
 
-- configuration on its own and loads/unloads materials.
 
--
 
 
dofile("common.inc");
 
 
askText = singleLine([[
 
  Crematory v1.2 (by Tallow) --
 
  Automatically runs one or more crematories.
 
]]);
 
 
wmText = "Tap Ctrl on Crematories to open and pin.\nTap Alt to open, pin and stash.";
 
 
OPP = 0;
 
SAME_UP = 1;
 
SAME_DOWN = 2;
 
 
tolerance = 6500;
 
tickTime = 500;
 
maxWait = 1000;
 
longWait = 500;
 
shortWait = 30;
 
 
colOffsets = {
 
  {15, 22}, --{35-40-3, 204-182}
 
  {51, 22}, --{71-40-3, 204-182}
 
  {87, 22}, --{107-40-3, 204-182}
 
  {123, 22},--{143-40-3, 204-182}
 
  {159, 22},--{179-40-3, 204-182}
 
  {195, 22},--{215-40-3, 204-182}
 
  {231, 22} --{251-40-3, 204-182}
 
};
 
 
colWidth = 36-35+6;
 
colHeight = 323-204;
 
colMiddle = 57;
 
 
buttonOffsets = {
 
  {32, 151}, --{49-40, 333-182}
 
  {72, 151}, --{89-40, 333-182}
 
  {112, 151},--{129-40, 333-182}
 
  {152, 151},--{169-40, 333-182}
 
  {192, 151} --{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;
 
    local iter = 0;
 
    srReadScreen();
 
    while closeEmptyAndErrorWindows() ~= 0 and iter < 10 do
 
      lsSleep(100);
 
      checkBreak();
 
      srReadScreen();
 
      iter = iter + 1;
 
    end
 
    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
 
    current.origin[1] = vLime[0];
 
    current.origin[2] = 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].origin[2] = windows[i].origin[2] - 7;
 
    end
 
  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 allFound = true;
 
  cremWins = findAllText("This is a Crematory", nil, REGION);
 
  for i = 1, #cremWins do
 
      safeClick(cremWins[i].x + 5, cremWins[i].y + 5);
 
  end
 
  for i = 1, #cremWins do
 
      if not findText("Fire the Crematory", cremWins[i]) then
 
        allFound = false;
 
      end
 
  end
 
  return allFound;
 
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);
 
    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);
 
      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 wins = findAllText("This is a Crematory", nil, REGION);
 
  for i, win in ipairs(wins) do
 
    local t = findText("Take...", win);
 
    if t then
 
      clickText(findText("Take...", win));
 
      t = waitForText("Everything");
 
      clickText(t);
 
      waitForNoText("Everything");
 
      safeClick(wins[i].x + 25, wins[i].y + 5);
 
    end
 
  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()
 
  cremWins = findAllText("This is a Crematory", nil, REGION);
 
  lsPrintln("loading");
 
  loads = {};
 
  if load_flax then
 
      table.insert(loads, "Flax");
 
  end
 
  if load_papyrus then
 
      table.insert(loads, "Papyrus");
 
  end
 
  if load_limestone then
 
      table.insert(loads, "Limestone");
 
  end
 
  if load_leeks then
 
      table.insert(loads, "Leeks");
 
  end
 
  table.insert(loads, "Wood");
 
  for i=1, #cremWins do
 
      cremWin = cremWins[i]
 
      for i, v in ipairs(loads) do
 
        clickText(findText("Load the Crematory...", cremWin));
 
        local t = waitForText("Wood", nil, nil, nil, REGION);
 
        t = waitForText(v, nil, nil, t);
 
        clickText(t);
 
        t = waitForText("Load how much", nil, nil, nil, REGION);
 
        safeClick(t.x + t.width/2, t.bottom - 50);
 
        waitForNoText("Load how much");
 
      end
 
  end
 
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
 

Revision as of 02:13, 12 July 2018