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.
Difference between revisions of "User:Selune"
From ATITD6
Jump to navigationJump to searchLine 227: | Line 227: | ||
lsSleep(per_read_delay_time); | lsSleep(per_read_delay_time); | ||
end | end | ||
+ | end | ||
+ | </pre> | ||
+ | |||
+ | Fixed Crematory Macro: | ||
+ | <pre> | ||
+ | -- 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 | end | ||
</pre> | </pre> |
Revision as of 01:03, 2 January 2013
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