Kaikaku

tWaitFor

Apr 9th, 2021 (edited)
675
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 33.35 KB | None | 0 0
  1. --{program="tWaitFor",version="1.00",date="2021-04-11"}
  2. ---------------------------------------
  3. -- tWaitFor           by Kaikaku
  4. -- 2021-04-16, v1.00   improved blnSilenced
  5. -- 2021-04-11, v0.99   added to rs 'any' and 'change'
  6. --                     and to in 'all' and 'any'
  7. -- 2021-04-10, v0.98   initial
  8. ---------------------------------------
  9.  
  10. ---------------------------------------
  11. ---- DESCRIPTION ----------------------
  12. ---------------------------------------
  13. -- Makes a turtle or computer wait
  14. --   for one of several specified
  15. --   events. Returns the number of the
  16. --   event.accuracy
  17. -- Last argument (if n%3=1) will be
  18. --   used in shell.run(last_argument).
  19. -- Runs only when called with parameters.
  20. --
  21. -- Hints:
  22. -- rs: values need to change to speci-
  23. --     fied value to trigger
  24. -- rn: all specified modem frequencies
  25. --     will be used
  26. -- in: inventory needs to change for
  27. --     slots beeing checked
  28. -- al: if time is at the beginning
  29. --     already within the specified
  30. --     interval, event will trigger
  31. --     after a short delay.
  32.  
  33.  
  34. ---------------------------------------
  35. ---- ASSUMPTIONS ----------------------
  36. ---------------------------------------
  37. -- Turtle or computer
  38. -- If there is no modem attached the
  39. --   program will ask for providing/
  40. --   placing one.
  41.  
  42. -- Improvement ideas:
  43. --   rs: extend to analog
  44. --   in: make checking for changes similar like rs
  45. --   rn: add broadcast
  46.  
  47.  
  48. ---------------------------------------
  49. ---- VARIABLES: template --------------
  50. ---------------------------------------
  51. local cVersion  ="v1.00"              
  52. local cPrgName  ="tWaitFor"          
  53. local blnAskForParameters =true      
  54. local blnDebugPrint       =false--true--
  55. local blnSilenced         =false--true--
  56. local blnTurtle                      
  57. local baseColor=colors.blue          
  58.  
  59.  
  60. ---------------------------------------
  61. ---- VARIABLES: specific --------------
  62. ---------------------------------------
  63. local modem -- set later in code
  64. local slotFuel=16
  65. local shellDotRun="" -- keeps the parameter for shell.run if there is one
  66. local initalRedstone={front=false, back=false, top=false, bottom=false, right=false, left=false}
  67.  
  68.  
  69. ---------------------------------------
  70. ---- Early UI functions ---------------
  71. ---------------------------------------
  72. local function swapColors()
  73. local backColor=term.getBackgroundColor()
  74. local textColor=term.getTextColor()
  75.  
  76. term.setBackgroundColor(textColor)
  77. term.setTextColor(backColor)
  78. end
  79.  
  80. local function printUI(strInput)
  81. if strInput==ni then strInput="" end
  82.  
  83.   if strInput=="header" then
  84.     term.write("—ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ") swapColors() print("”") swapColors()  
  85.   elseif strInput=="line" then
  86.      term.write("ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ") swapColors() print("‘") swapColors()
  87.   elseif strInput=="footer" then
  88.     term.write("ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŽ") print()
  89.   else
  90.     term.write("•")
  91.     strInput=strInput.."                                     "
  92.     term.write(string.sub(strInput,1,37))
  93.     swapColors() print("•") swapColors()
  94.   end
  95. end
  96.  
  97. local function pprintUI(strInput)                    
  98.   -- parameterized printUI that can be silinced blnSilenced
  99.   if not blnSilenced then printUI(strInput) end
  100. end
  101.  
  102. local function coloredTextAt(inputText,outputRow,outputCol,textColor,backColor)
  103. -- writes and colors text to coordinates
  104. local oldRow, oldCol = term.getCursorPos()
  105. local oldTextColor=term.getTextColor()
  106. local oldBackColor=term.getBackgroundColor()
  107. if textColor==nil then textColor=term.getTextColor() end
  108. if backColor==nil then backColor=term.getBackgroundColor() end
  109.  
  110.   term.setTextColor(textColor)
  111.   term.setBackgroundColor(backColor)
  112.   term.setCursorPos(outputRow,outputCol)
  113.   term.write(inputText)
  114.   term.setCursorPos(oldRow, oldCol)
  115.   term.setTextColor(oldTextColor)
  116.   term.setBackgroundColor(oldBackColor)
  117. end
  118.  
  119. local function pcoloredTextAt(inputText,outputRow,outputCol,textColor,backColor)
  120.   -- parameterized coloredTextAt that can be silinced blnSilenced
  121.   if not blnSilenced then coloredTextAt(inputText,outputRow,outputCol,textColor,backColor)  end
  122. end
  123.  
  124. local function ptermwrit(str)      
  125. -- parameterized term.write that can be silinced blnSilenced
  126.   if not blnSilenced then term.write(str) end -- TO DO: probably needs attention because of .. / ,
  127. end
  128.  
  129. local function pprint(str)  
  130. -- parameterized print that can be silinced blnSilenced
  131.   if not blnSilenced then print(str) end
  132. end
  133.  
  134. local function debugPrint(str)
  135.  if blnDebugPrint then print(str) end
  136. end
  137.  
  138. local function debugSleep(num)
  139.  if num==nil then num=0 end
  140.  if blnDebugPrint then sleep(num) end
  141. end
  142.  
  143.  
  144. local function checkFuel()
  145.   local tmp=turtle.getFuelLevel()
  146.   return tmp
  147. end
  148.  
  149. local function checkTurtle(blnOnlyIdentify)
  150. if blnOnlyIdentify==nil then blnOnlyIdentify=false end
  151. -- turtle?
  152.   local turtleOk, turtleVal = pcall(checkFuel)
  153.   if not turtleOk then
  154.     blnTurtle=false
  155.     if not blnOnlyIdentify then
  156.       if not blnSilenced then term.clear() term.setCursorPos(1,1) end
  157.       printUI("header")
  158.       printUI(""..cPrgName..", "..cVersion..", by Kaikaku")
  159.       printUI("line")
  160.       printUI("This is a turtle program.")
  161.       printUI("  Please, execute it with a turtle!")
  162.       printUI("footer")
  163.    
  164.       coloredTextAt(cPrgName,2,2,baseColor)
  165.       error()
  166.     end
  167.   else
  168.     blnTurtle=true
  169.   end
  170. end
  171.  
  172. local function sleepDots(sec, duration)                
  173. if sec==nil then sec=10 end
  174. if sec<1 then return end
  175. if duration==nil then duration=1 end -- shorten durtation for more dots
  176.  
  177.   for i=1,sec-1 do
  178.     sleep(1*duration)
  179.     term.write(".")
  180.   end
  181.  
  182.   sleep(1*duration)
  183.   print(".")
  184. end
  185.  
  186. local function getFirstEmptySlot(startAt)                
  187. if startAt==nil then startAt=1 end
  188. if startAt>16 or startAt<1 then return nil end
  189.  
  190.   for i=startAt,16,1 do
  191.     if turtle.getItemCount(i)==0 then return i end  
  192.   end
  193.   for i=1,startAt,1 do
  194.     if turtle.getItemCount(i)==0 then return i end  
  195.   end
  196.   return nil
  197. end
  198.  
  199. local function identifyTool(toolSide)              
  200. -- returns name of tool at side toolSide
  201. -- returns no_tool if there is none
  202. -- requires at least one empty slot for tool check (throws error)
  203. if toolSide==nil then toolSide="right" end
  204. if toolSide~="right" and toolSide~="r" then toolSide="left" end
  205. local slotNumber = getFirstEmptySlot()
  206. local slotSelected=turtle.getSelectedSlot()
  207. local toolName="no_tool"
  208.  
  209.   if slotNumber==nil then error("Couldn't find empty slot to check tool on side '"..toolSide.."'!") end
  210.   turtle.select(slotNumber)
  211.   -- step 1: get name
  212.   if toolSide=="right" or toolSide=="r" then
  213.     turtle.equipRight()
  214.   else
  215.     turtle.equipLeft()  
  216.   end
  217.   -- step 2: get name
  218.   local data = turtle.getItemDetail()
  219.   if data~=nil then toolName=data.name end
  220.   -- step 3: re-equipget name
  221.   if toolSide=="right" or toolSide=="r" then
  222.     turtle.equipRight()
  223.   else
  224.     turtle.equipLeft()  
  225.   end
  226.   turtle.select(slotSelected)
  227.   return toolName
  228. end
  229.  
  230. local function findModem()          
  231.   for _, p in pairs( rs.getSides() ) do
  232.     if peripheral.isPresent(p) and peripheral.getType(p) == "modem" then return true,p end
  233.   end
  234.   return false,nil
  235. end
  236.  
  237. local function ensureModem()                
  238. -- Equips modem from slotFuel either right or left, depending which solt is free.
  239. -- Throws an error if both sides are already taken.
  240. -- Return modem side
  241. local modemExists, modemSide = findModem()
  242.  
  243.   if not blnTurtle then
  244.     while not modemExists do
  245.       print("No modem found, attach a modem to computer!")
  246.       sleepDots(3)
  247.       modemExists, modemSide = findModem()
  248.     end
  249.    
  250.   else -- isTurtle
  251.   local slotSelected=turtle.getSelectedSlot()
  252.     while not modemExists do
  253.       turtle.select(slotFuel)
  254.       print("Turtle has no modem, put one wireless modem in slot "..slotFuel.."!")
  255.       sleepDots(3)
  256.       if turtle.getItemCount()== 1 then
  257.         -- check right side
  258.         if identifyTool("right")=="no_tool" then
  259.           turtle.equipRight()
  260.         elseif identifyTool("left")=="no_tool" then
  261.           turtle.equipLeft()
  262.         else
  263.           error("Couldn't find empty tool slot to equip modem! Please, manually remove one tool. E.g., in lua editor with 'turtle.equipLeft()'")
  264.         end
  265.       end  
  266.       modemExists, modemSide = findModem()
  267.     end
  268.     turtle.select(slotSelected)
  269.   end
  270.   return modemSide
  271. end
  272.  
  273.  
  274. ---------------------------------------
  275. ---- tArgs ----------------------------
  276. ---------------------------------------
  277. local tArgs = {...}  
  278. --term.clear() term.setCursorPos(1,1)
  279.  
  280. -- pre-checks
  281. -- count
  282. if #tArgs==1 or #tArgs%3==2 then
  283.   error(cPrgName.." incorrect number of parameteres. Either 0 (for info screen), a multiple of 3 or a (multiple of 3)+1.")  
  284. end
  285.  
  286. -- extract shell.run
  287. if #tArgs%3==1 then
  288.   -- there is a command for shell.run
  289.   shellDotRun=tArgs[#tArgs]
  290.  
  291.   -- check for silenced
  292.   if string.sub(shellDotRun,1,8)=="silenced" or string.sub(shellDotRun,1,8)=="silence" then
  293.     blnSilenced=true
  294.     shellDotRun=string.sub(shellDotRun,9)
  295.     -- no need for info print, as it would be silenced anyways :)
  296.   end
  297.  
  298.   tArgs[#tArgs]=nil --..(tArgs[1] or "").. TO DO
  299.   if shellDotRun~="" then
  300.     debugPrint("Info: Extrated parameter("..(#tArgs+1)..")='"..shellDotRun.."' to be used in shell.run().")
  301.     debugSleep(2)
  302.   end
  303. end
  304.  
  305. -- header (after silenced check)
  306. if #tArgs~=0 then
  307.   blnAskForParameters=false
  308.   if not blnSilenced then term.clear() term.setCursorPos(1,1) end
  309.   pprintUI("header")
  310.   pprintUI(""..cPrgName..", "..cVersion..", by Kaikaku. Enjoy!")
  311.   pprintUI("line")
  312.   pcoloredTextAt(cPrgName,2,2,baseColor)
  313.   pprint("Starting...")
  314. end
  315.  
  316. -- correct formats
  317. for i=1,#tArgs,3 do
  318.   pprint("i="..i..":"..tArgs[i])
  319.   if tArgs[i]~="rs" and tArgs[i]~="redstone" and tArgs[i]~="rn" and tArgs[i]~="rednet" and tArgs[i]~="ti" and tArgs[i]~="timer" and tArgs[i]~="al" and tArgs[i]~="alarm" and tArgs[i]~="in" and tArgs[i]~="inventory" then
  320.     error("Invalid paramter("..i..")='"..tArgs[i].."'. Only the following parameters are allowed at each beginning of a 3-tupel: rs, redstone, rn, rednet, ti, timer, al, alarm, in, inventory!")
  321.   end  
  322.  
  323.   -- rs
  324.   if tArgs[i]=="rs" or tArgs[i]=="redstone" then
  325.     -- use abbreviation
  326.     tArgs[i]="rs"
  327.     -- check second
  328.     if tArgs[i+1]~="front" and tArgs[i+1]~="back" and tArgs[i+1]~="top" and tArgs[i+1]~="bottom" and tArgs[i+1]~="left" and tArgs[i+1]~="right" and tArgs[i+1]~="any" then
  329.       error("Invalid paramter("..(i+1)..")='"..tArgs[i+1].."'. Only the following expressions are allowed as first parameter after rs/redstone: front, back, top, bottom, left, right, any!")
  330.     end
  331.     -- check third
  332.     if tArgs[i+2]~="true" and tArgs[i+2]~="false" and tArgs[i+2]~= "change" then
  333.       error("Invalid paramter("..(i+2)..")='"..tArgs[i+2].."'. Only the following expressions are allowed as second parameter after rs/redstone: true, false, change!")
  334.     else
  335.       -- transform into boolean
  336.       if tArgs[i+2]=="true" then tArgs[i+2]=true elseif tArgs[i+2]=="false" then tArgs[i+2]=false end  
  337.     end
  338.     -- get current rs status
  339.     initalRedstone['front']=rs.getInput("front")
  340.     initalRedstone['back']=rs.getInput("back")
  341.     initalRedstone['top']=rs.getInput("top")
  342.     initalRedstone['bottom']=rs.getInput("bottom")
  343.     initalRedstone['left']=rs.getInput("left")
  344.     initalRedstone['right']=rs.getInput("right")
  345.   end
  346.  
  347.   -- ti
  348.   if tArgs[i]=="ti" or tArgs[i]=="timer" then
  349.     -- use abbreviation
  350.     tArgs[i]="ti"
  351.     -- check second
  352.     if tArgs[i+1]~="sec" and tArgs[i+1]~="min" and tArgs[i+1]~="tick" and tArgs[i+1]~="ticks" then
  353.       error("Invalid paramter("..(i+1)..")='"..tArgs[i+1].."'. Only the following expressions are allowed as first parameter after ti/timer: sec, min, tick!(s)")
  354.     end
  355.     if tArgs[i+1]=="ticks" then tArgs[i+1]="tick" end
  356.     -- check third
  357.     tArgs[i+2]=tonumber(tArgs[i+2])
  358.     if tArgs[i+2]==nil then
  359.       error("Invalid paramter("..(i+2)..")='"..tArgs[i+2].."'. Only number expressions are allowed as second parameter after ti/timer!")
  360.     else
  361.       -- transform to sec
  362.       if tArgs[i+1]=="min" then tArgs[i+2]=tArgs[i+2]*60 end
  363.       if tArgs[i+1]=="tick" then tArgs[i+2]=tArgs[i+2]/20 end
  364.     end
  365.     -- start timer
  366.     tArgs[i+1] = os.startTimer(tArgs[i+2])
  367.   end
  368.  
  369.   -- al
  370.   if tArgs[i]=="al" or tArgs[i]=="alarm" then
  371.     -- use abbreviation
  372.     tArgs[i]="al"
  373.     -- check second
  374.     tArgs[i+1]=tonumber(tArgs[i+1])
  375.     if tArgs[i+1]==nil then
  376.       error("Invalid paramter("..(i+1)..")='"..tArgs[i+1].."'. Only number expressions are allowed as first parameter after al/alarm!")
  377.     elseif tArgs[i+1]<0 or tArgs[i+1]>=24 then
  378.       error("Invalid paramter("..(i+1)..")='"..tArgs[i+1].."'. Only numbers [0.0, 24.0) are allowed as first parameter after al/alarm!")
  379.     end
  380.     -- check third
  381.     tArgs[i+2]=tonumber(tArgs[i+2])
  382.     if tArgs[i+2]==nil then
  383.       error("Invalid paramter("..(i+2)..")='"..tArgs[i+2].."'. Only number expressions are allowed as second parameter after al/alarm!")
  384.     elseif tArgs[i+2]<0 or tArgs[i+2]>=24 then
  385.       error("Invalid paramter("..(i+2)..")='"..tArgs[i+2].."'. Only numbers [0.0, 24.0) are allowed as second parameter after al/alarm!")
  386.     end
  387.     -- prepare alarm(s)
  388.     -- check if already in interval
  389.     if os.time()>=tArgs[i+1] and os.time()<=tArgs[i+2] then
  390.       -- already time for the alarm, set-up immediate alarm
  391.       tArgs[i+2]=os.setAlarm(os.time() + 0.05) -- hm, not sure if 0.05 is the best value
  392.     end
  393.     -- set regular alarm
  394.     tArgs[i+1]=os.setAlarm(tArgs[i+1])
  395.   end    
  396.  
  397.   -- in
  398.   if tArgs[i]=="in" or tArgs[i]=="inventory" then
  399.     -- turtle?
  400.     checkTurtle(true)
  401.     if not blnTurtle then
  402.       error("Invalid paramter("..(i)..")='"..tArgs[i].."'. Only turtles may wait for inventory events!")
  403.     end
  404.     -- use abbreviation
  405.     tArgs[i]="in"
  406.     -- check second
  407.     if tArgs[i+1]~="all" and tArgs[i+1]~="any" then
  408.       tArgs[i+1]=tonumber(tArgs[i+1])
  409.       if tArgs[i+1]==nil then
  410.         error("Invalid paramter("..(i+1)..")='"..tArgs[i+1].."'. Only slot numbers 1-16 (or 'all'/'any') are allowed as first parameter after in/inventory!")
  411.       end
  412.       tArgs[i+1]=math.floor(tArgs[i+1])
  413.       if tArgs[i+1]<1 or tArgs[i+1]>16 then
  414.         error("Invalid paramter("..(i+1)..")='"..tArgs[i+1].."'. Only slot numbers 1-16 (or 'all'/'any') are allowed as first parameter after in/inventory!")
  415.       end
  416.     end
  417.     -- check third
  418.     --   string length
  419.     local tmpLen = string.len(tArgs[i+2])
  420.     if tmpLen<2 or tmpLen>3 then
  421.       error("Invalid paramter("..(i+2)..")='"..tArgs[i+2].."'. Only 2 or 3 character expressions are allowed as second parameter after in/inventory! (e.g. '>10', '=1', '<20')")
  422.     end
  423.     --    right prefix
  424.     local tmpComp =  string.sub(tArgs[i+2], 1, 1)
  425.     if tmpComp~="<" and tmpComp~="=" and tmpComp~=">" then
  426.       error("Invalid paramter("..(i+2)..")='"..tArgs[i+2].."'. First character of second parameter after in/inventory must be '>', '=' or '<'!")
  427.     end
  428.     --    no impssible
  429.     if tArgs[i+2]=="<0" or tArgs[i+2]==">64" then
  430.       error("Invalid paramter("..(i+2)..")='"..tArgs[i+2].."'. '<0' and '>64' don't make sense for the second parameter after in/inventory!")
  431.     end
  432.     --    numbers
  433.     tArgs[i+2]=string.sub(tArgs[i+2].." ", 2, 3)
  434.     tArgs[i+2]=tonumber(tArgs[i+2])
  435.     if tArgs[i+2]==nil then
  436.       error("Invalid paramter("..(i+2)..")='"..tArgs[i+2].."'. Second + third character of second parameter after in/inventory must be digits! (e.g. '>10', '=1', '<20')")
  437.     end
  438.     --    nubers of right interval
  439.     tArgs[i+2]=math.floor(tArgs[i+2])
  440.     if tArgs[i+2]<0 or tArgs[i+2]>64  then
  441.       error("Invalid paramter("..(i+2)..")='"..tArgs[i+2].."'. Second + third character of second parameter after in/inventory must be 0-64!")
  442.     end    
  443.     -- remember tmpComp
  444.     tArgs[i]="in"..tmpComp
  445.   end
  446.  
  447.    
  448.   -- rn
  449.   if tArgs[i]=="rn" or tArgs[i]=="rednet" then
  450.     -- turtle?
  451.     checkTurtle(true)
  452.     -- modem?
  453.     if modem==nil then modem = peripheral.wrap(ensureModem()) end
  454.     -- use abbreviation
  455.     tArgs[i]="rn"  
  456.  
  457.     -- check second
  458.     tArgs[i+1]=tonumber(tArgs[i+1])
  459.     if tArgs[i+1]==nil then
  460.       error("Invalid paramter("..(i+1)..")='"..tArgs[i+1].."'. Only numbers (0-65535) can be used as first parameter for channel numbers after rn/rednet!")
  461.     end
  462.     tArgs[i+1]=math.floor(tArgs[i+1])
  463.     if tArgs[i+1]<0 or tArgs[i+1]>65535 then
  464.       error("Invalid paramter("..(i+1)..")='"..tArgs[i+1].."'. Only numbers (0-65535) can be used as first parameter for channel numbers after rn/rednet!")
  465.     end
  466.     modem.open(tArgs[i+1])
  467.   end
  468. end
  469.  
  470.  
  471. ---------------------------------------
  472. -- basic functions for turtle control -
  473. ---------------------------------------
  474.  
  475. local function waitKey(strText)
  476.   local event, scancode
  477.   term.write(strText)
  478.   event, scancode = os.pullEvent("key")
  479.   print()
  480. end
  481.  
  482. local function askForInputText(textt)
  483.   local at=""
  484.   -- check prompting texts
  485.   if textt==nil then textt="Enter text:" end
  486.  
  487.   -- ask for input
  488.   term.write(textt)
  489.   at=read()
  490.   return at
  491. end
  492.  
  493. local function askForNumber(askText, minValue, maxValue)
  494. -- gets entered data, ensures it's a number and returns it
  495. -- keeps asking if entry is not a number
  496. -- adapts to min and max values
  497. -- allways writes in screen line 13 (last for turtles)
  498. -- calls askForInputText
  499. local blnReask=true
  500. local returnNumber=nil
  501. if minValue==nil then minValur=1 end
  502. if maxValue==nil then maxValue=100 end
  503. if askText==nil then askText="Key in number and press Enter: " end
  504.   while blnReask do
  505.    term.setCursorPos(1,13)
  506.     returnNumber=askForInputText(askText)
  507.     if returnNumber==nil then
  508.       blnReask=true
  509.     else  
  510.       returnNumber=tonumber(returnNumber)
  511.       if returnNumber==nil then
  512.         blnReask=true
  513.       else
  514.         returnNumber=math.floor(returnNumber)
  515.         if returnNumber>maxValue then returnNumber=maxValue end
  516.         if returnNumber<minValue then returnNumber=minValue end
  517.         blnReask=false
  518.       end
  519.     end
  520.   end
  521.   return returnNumber
  522. end
  523.  
  524. local function pressKeyNoSpecials(askText)
  525. -- excludes ctrl / alt / shifts
  526. -- catches windows
  527. -- retruns the key number (if needed at all)
  528. local tmpEvent, tmpKey
  529. if askText==nil then askText="Press key to START! (stop w/ ctrl+t)   " end
  530.   tmpKey=341
  531.   while tmpKey>=340 and tmpKey<=346 do -- ctrls, alts, shifts
  532.     term.write(askText) tmpEvent, tmpKey = os.pullEvent("key")
  533.     if tmpKey==nil then tmpKey=341 end -- win
  534.   end
  535.   return tmpKey
  536. end
  537.  
  538.  
  539. ------------------------------------------------------------------------------
  540. -- main: description ---------------------------------------------------------
  541. ------------------------------------------------------------------------------
  542.  
  543. if blnAskForParameters then
  544. term.clear() term.setCursorPos(1,1)
  545. local iPage=0
  546. local iPageMax=11                                    
  547. local event, key, isHeld  
  548. local blnLoop=true                              
  549.  
  550. term.clear() term.setCursorPos(1,1) iPage=iPage+1
  551. printUI("header")
  552. printUI(""..cPrgName..", "..cVersion..", by Kaikaku ("..iPage.."/"..iPageMax..")")
  553. printUI("line")
  554. --       1234567890123456789012345678901234567
  555. printUI("This program makes a turtle or ")
  556. printUI("  computer wait for a specified")
  557. printUI("  event.")
  558. printUI("You can specify as many events as you")
  559. printUI("  like, the first that occurs ends")
  560. printUI("  the program and the event number is")
  561. printUI("  returned. I.e. if the second event")
  562. printUI("  triggers '2' is returned.")
  563. printUI("footer")
  564.  
  565. coloredTextAt(cPrgName,2,2,baseColor)
  566.                              
  567. pressKeyNoSpecials("Press key for next. (stop w/ ctrl+t)   ")  
  568.  
  569.  
  570.  
  571. term.clear() term.setCursorPos(1,1) iPage=iPage+1
  572. printUI("header")
  573. printUI(""..cPrgName..", "..cVersion..", by Kaikaku ("..iPage.."/"..iPageMax..")")
  574. printUI("line")
  575. --       1234567890123456789012345678901234567
  576. printUI("The following events can be used:")
  577. printUI("  ")
  578. printUI("* rs/redstone: redstone changes")
  579. printUI("* rn/rednet: rednet messages")
  580. printUI("* ti/timer: timer events")
  581. printUI("* al/alarm: alarm events")
  582. printUI("* in/inventory: inventory changes")
  583. printUI("  ")
  584. printUI("footer")
  585.  
  586. coloredTextAt(cPrgName,2,2,baseColor)
  587. coloredTextAt("rs",4,6,baseColor)
  588. coloredTextAt("rn",4,7,baseColor)
  589. coloredTextAt("ti",4,8,baseColor)
  590. coloredTextAt("al",4,9,baseColor)
  591. coloredTextAt("in",4,10,baseColor)
  592.                              
  593. pressKeyNoSpecials("Press key for next. (stop w/ ctrl+t)   ")  
  594.  
  595.  
  596. term.clear() term.setCursorPos(1,1) iPage=iPage+1
  597. printUI("header")
  598. printUI(""..cPrgName..", "..cVersion..", by Kaikaku ("..iPage.."/"..iPageMax..")")
  599. printUI("line")
  600. --       1234567890123456789012345678901234567
  601. printUI("Each event is specified with exactly ")
  602. printUI("  3 parameters. That is the number of")
  603. printUI("  paramteres must be a multiple of 3.")
  604. printUI("Option: You may provide one more")
  605. printUI("  parameter, that will be used after ")
  606. printUI("  the trigger, in an shell.run()")
  607. printUI("  command. I.e. you can start a")
  608. printUI("  program waiting for an event.")
  609. printUI("footer")
  610.  
  611. coloredTextAt(cPrgName,2,2,baseColor)
  612. coloredTextAt("3 parameters",4,5,baseColor)
  613. coloredTextAt("shell.run()",23,9,baseColor)
  614.                              
  615. pressKeyNoSpecials("Press key for next. (stop w/ ctrl+t)   ")
  616.  
  617.  
  618.  
  619. term.clear() term.setCursorPos(1,1) iPage=iPage+1
  620. printUI("header")
  621. printUI(""..cPrgName..", "..cVersion..", by Kaikaku ("..iPage.."/"..iPageMax..")")
  622. printUI("line")
  623. --       1234567890123456789012345678901234567
  624. printUI("Option: If you want to use the ")
  625. printUI("  program within another program, you")
  626. printUI("  might want to suppress the messages")
  627. printUI("  showing up.")
  628. printUI('To do so add "silenced" directly ')
  629. printUI("  before the program name to be run ")
  630. printUI("  in shell.run() respectively add it")
  631. printUI('  instead, e.g. "silenceddance".')
  632. printUI("footer")
  633.  
  634. coloredTextAt(cPrgName,2,2,baseColor)
  635. coloredTextAt("silenced",16,8,baseColor)
  636.                              
  637. pressKeyNoSpecials("Press key for next. (stop w/ ctrl+t)   ")
  638.  
  639. term.clear() term.setCursorPos(1,1) iPage=iPage+1
  640. printUI("header")
  641. printUI(""..cPrgName..", "..cVersion..", by Kaikaku ("..iPage.."/"..iPageMax..")")
  642. printUI("line")
  643. --       1234567890123456789012345678901234567
  644. printUI("Syntax for redstone changes:")
  645. printUI("  rs/redstone side true/false/change")
  646. printUI("  side: front, back, left, right,")
  647. printUI("        top, bottom, any")
  648. printUI("The event will trigger if the red-")
  649. printUI("  stone signal at this side changes")
  650. printUI("  to the specified boolean value.")
  651. printUI("Example: rs back true")
  652. printUI("footer")
  653.  
  654. coloredTextAt(cPrgName,2,2,baseColor)
  655. coloredTextAt("redstone",13,4,colors.white,baseColor)
  656. coloredTextAt("rs/redstone side true/false/change",4,5,baseColor)
  657. coloredTextAt("rs back true",11,11,baseColor)
  658.                              
  659. pressKeyNoSpecials("Press key for next. (stop w/ ctrl+t)   ")
  660.  
  661.  
  662. term.clear() term.setCursorPos(1,1) iPage=iPage+1
  663. printUI("header")
  664. printUI(""..cPrgName..", "..cVersion..", by Kaikaku ("..iPage.."/"..iPageMax..")")
  665. printUI("line")
  666. --       1234567890123456789012345678901234567
  667. printUI("Syntax for rednet messages:")
  668. printUI("  rn/rednet channel message")
  669. printUI("  channel: 0-65535")
  670. printUI('  message: "use quotes for text"')
  671. printUI("The event will trigger if the message")
  672. printUI("  is received on the channel.")
  673. printUI("  Requires a modem.")
  674. printUI('Example: rn 1 "Hello World!"')
  675. printUI("footer")
  676.  
  677. coloredTextAt(cPrgName,2,2,baseColor)
  678. coloredTextAt("rednet",13,4,colors.white,baseColor)
  679. coloredTextAt("rn/rednet channel message",4,5,baseColor)
  680. coloredTextAt('rn 1 "Hello World!"',11,11,baseColor)
  681.                              
  682. pressKeyNoSpecials("Press key for next. (stop w/ ctrl+t)   ")
  683.  
  684.  
  685. term.clear() term.setCursorPos(1,1) iPage=iPage+1
  686. printUI("header")
  687. printUI(""..cPrgName..", "..cVersion..", by Kaikaku ("..iPage.."/"..iPageMax..")")
  688. printUI("line")
  689. --       1234567890123456789012345678901234567
  690. printUI("Syntax for timer events:")
  691. printUI("  ti/timer unit number")
  692. printUI("  unit: sec/min/tick(s)")
  693. printUI("  number: waits so long")
  694. printUI("The event will trigger after the ")
  695. printUI("  spefied time expired.")
  696. printUI("  20 ticks = 1 sec")
  697. printUI("Example: ti min 2.5")
  698. printUI("footer")
  699.  
  700. coloredTextAt(cPrgName,2,2,baseColor)
  701. coloredTextAt("timer",13,4,colors.white,baseColor)
  702. coloredTextAt("ti/timer unit number",4,5,baseColor)
  703. coloredTextAt("ti min 2.5",11,11,baseColor)
  704.                              
  705. pressKeyNoSpecials("Press key for next. (stop w/ ctrl+t)   ")
  706.  
  707.  
  708. term.clear() term.setCursorPos(1,1) iPage=iPage+1
  709. printUI("header")
  710. printUI(""..cPrgName..", "..cVersion..", by Kaikaku ("..iPage.."/"..iPageMax..")")
  711. printUI("line")
  712. --       1234567890123456789012345678901234567
  713. printUI("Syntax for alarm events:")
  714. printUI("  al/alarm start end")
  715. printUI("start: MC time the event triggers,")
  716. printUI("  0.00 - 23.99 (with 12.00=noon)")
  717. printUI("end: checks at the beginning, if ")
  718. printUI("  time>start and time<end then it")
  719. printUI("  will trigger after a short delay.")
  720. printUI("Example: al 12.0 12.0")
  721. printUI("footer")
  722.  
  723. coloredTextAt(cPrgName,2,2,baseColor)
  724. coloredTextAt("alarm",13,4,colors.white,baseColor)
  725. coloredTextAt("al/alarm start end",4,5,baseColor)
  726. coloredTextAt("al 12.0 12.0",11,11,baseColor)
  727.                              
  728. pressKeyNoSpecials("Press key for next. (stop w/ ctrl+t)   ")
  729.  
  730.  
  731. term.clear() term.setCursorPos(1,1) iPage=iPage+1
  732. printUI("header")
  733. printUI(""..cPrgName..", "..cVersion..", by Kaikaku ("..iPage.."/"..iPageMax..")")
  734. printUI("line")
  735. --       1234567890123456789012345678901234567
  736. printUI("Syntax for inventory events:")
  737. printUI("  in/inventory slot >=<number")
  738. printUI("slot: turtle(!) slot 1-16 or all/any")
  739. printUI(">=<number: Is a compound parameter.")
  740. printUI("number specifies the item count 0-64")
  741. printUI("and the prefix > or = or < the con-")
  742. printUI("dition (triggers with first update).")
  743. printUI("Example: in 1 >10")
  744. printUI("footer")
  745.  
  746. coloredTextAt(cPrgName,2,2,baseColor)
  747. coloredTextAt("inventory",13,4,colors.white,baseColor)
  748. coloredTextAt("in/inventory slot >=<number",4,5,baseColor)
  749. coloredTextAt("in 1 >10",11,11,baseColor)
  750.                              
  751. pressKeyNoSpecials("Press key for next. (stop w/ ctrl+t)   ")
  752.  
  753.  
  754. term.clear() term.setCursorPos(1,1) iPage=iPage+1
  755. printUI("header")
  756. printUI(""..cPrgName..", "..cVersion..", by Kaikaku ("..iPage.."/"..iPageMax..")")
  757. printUI("line")
  758. --       1234567890123456789012345678901234567
  759. printUI("Example 1:")
  760. printUI(" ")
  761. printUI("tWaitFor rs left false ti min 10")
  762. printUI(" ")
  763. printUI("Triggers either if redstone signal")
  764. printUI("on left side changes(!) from on to ")
  765. printUI("off or after 10 minutes.")
  766. printUI(" ")
  767. printUI("footer")
  768.  
  769. coloredTextAt(cPrgName,2,2,baseColor)
  770. coloredTextAt("Example 1:",2,4,colors.white,baseColor)
  771. coloredTextAt("tWaitFor rs left false ti min 10",2,6,baseColor)
  772.                              
  773. pressKeyNoSpecials("Press key for next. (stop w/ ctrl+t)   ")
  774.  
  775.  
  776. term.clear() term.setCursorPos(1,1) iPage=iPage+1
  777. printUI("header")
  778. printUI(""..cPrgName..", "..cVersion..", by Kaikaku ("..iPage.."/"..iPageMax..")")
  779. printUI("line")
  780. --       1234567890123456789012345678901234567
  781. printUI("Example 2:")
  782. printUI(" ")
  783. printUI('tWaitFor rn 4 "let us go" "go fd 10"')
  784. printUI(" ")
  785. printUI('Triggers with message "let us go" on ')
  786. printUI('channel 4 and executes the program   ')
  787. printUI('"go fd 10", i.e. the turtle moves ')
  788. printUI("forward 10 blocks.")
  789. printUI("footer")
  790.  
  791. coloredTextAt(cPrgName,2,2,baseColor)
  792. coloredTextAt("Example 2:",2,4,colors.white,baseColor)
  793. coloredTextAt('tWaitFor rn 4 "let us go" "go fd 10"',2,6,baseColor)
  794.                                            
  795. pressKeyNoSpecials("Press key to exit.                     ")
  796.  
  797. return
  798. end
  799.  
  800.  
  801. ---------------------------------------
  802. -- additional functions               -
  803. ---------------------------------------
  804.  
  805. local function checkRedstoneInput(side, compareTo)
  806. if side==nil then side="front" end
  807. if compareTo==nil then side="change" end
  808.   -- compares current input to initalRedstone
  809.   if side~="any" then
  810.     -- one side
  811.     if rs.getInput(side)~=initalRedstone[side] then
  812.       -- change happened
  813.       pprint("Right side has changed")
  814.       if compareTo=="change" then
  815.         return true
  816.       end
  817.       if rs.getInput(side)==compareTo then
  818.         pprint("... and to the right value!")
  819.         return true
  820.       else
  821.         -- adapt initalRedstone
  822.         initalRedstone[side]=rs.getInput(side)
  823.       end
  824.     else
  825.       pprint("Other side has changed")
  826.     end
  827.   else
  828.     -- any side
  829.     if checkRedstoneInput("front", compareTo)  then return true end
  830.     if checkRedstoneInput("back", compareTo)   then return true end
  831.     if checkRedstoneInput("left", compareTo)   then return true end
  832.     if checkRedstoneInput("right", compareTo)  then return true end
  833.     if checkRedstoneInput("top", compareTo)    then return true end
  834.     if checkRedstoneInput("bottom", compareTo) then return true end
  835.   end
  836.   return false
  837. end
  838.  
  839. local function checkInventroyCount(mode, slot, number)
  840. if mode==nil then mode="in=" end
  841. if slot==nil then slot=0 end
  842. if number==nil then number=0 end
  843. local isOkay=true
  844.  
  845.   if slot=="all" then
  846.     -- all
  847.     for i=1,16 do
  848. print(i)
  849.       isOkay = isOkay and checkInventroyCount(mode, i, number)
  850.       if not isOkay then return false end
  851.     end
  852.     return true
  853.    
  854.   elseif slot=="any" then
  855.     -- any
  856.     for i=1,16 do
  857.       if checkInventroyCount(mode, i, number)  then return true end
  858.     end
  859.   else
  860.     -- slot 1-16
  861.     if mode=="in<" then
  862.       if turtle.getItemCount(slot)<number  then return true end
  863.     elseif mode=="in>" then
  864.       if turtle.getItemCount(slot)>number  then return true end
  865.     else -- "in="
  866.       if turtle.getItemCount(slot)==number then return true end
  867.     end
  868.   end
  869.  
  870.   return false
  871. end
  872.  
  873. ------------------------------------------------------------------------------
  874. -- main: program -------------------------------------------------------------
  875. ------------------------------------------------------------------------------
  876. if not blnSilenced then term.clear() term.setCursorPos(1,1) end
  877. ---- step 1: waiting for event ----                
  878. pprint("Waiting for event...")
  879.  
  880. local returnResult=""
  881.    
  882. blnLoop=true
  883. while blnLoop do
  884.  
  885.   local event, param1, param2, param3, param4, param5 = os.pullEvent()
  886.  
  887.   -- ignore a bunch of events
  888.   if event~="key" and event~="key_up" and event~="char" and event~="mouse_up" and event~="mouse_click" then
  889.  
  890.   -- post processing rednet.send
  891.   if param4~=nil then
  892.     if param4.message~=nil then param4=param4.message end
  893.   end
  894.  
  895.     -- print event data
  896.     if blnDebugPrint then
  897.       pprint(" e="..event)--(tArgs[1] or "")
  898.       if param1~=nil then pprint(" p1="..param1) end
  899.       if param2~=nil then pprint(" p2="..param2) end
  900.       if param3~=nil then pprint(" p3="..param3) end
  901.       if param4~=nil then pprint(" p4="..param4) end
  902.       if param5~=nil then pprint(" p5="..param5) end
  903.     end
  904.  
  905.     -- rs
  906.     if event == "redstone" then
  907.       -- got a redstone event
  908.       pprint( "Redstone event..." )
  909.       for i=1,#tArgs,3 do
  910.         if tArgs[i]=="rs" then
  911.           --pprint("... i("..i..") rs |"..tArgs[i+1].."|"..tArgs[i+2])
  912.           pprint("... i("..i..") rs | "..tostring(tArgs[i+1]).." | "..tostring(tArgs[i+2]))
  913.           if checkRedstoneInput(tArgs[i+1],tArgs[i+2]) then pprint("Match!") blnLoop=false returnResult=(i+2)/3 break end
  914.         end
  915.       end
  916.     end
  917.    
  918.     -- ti
  919.     if event == "timer" then
  920.       -- got a timer event
  921.       pprint( "Timer event..." )
  922.       for i=1,#tArgs,3 do
  923.         if tArgs[i]=="ti" then
  924.           pprint("... i("..i..") ti | sec | "..tostring(tArgs[i+2]))
  925.           if param1==tArgs[i+1] then pprint("Match!") blnLoop=false returnResult=(i+2)/3 break end
  926.         end
  927.       end
  928.     end
  929.    
  930.     -- al
  931.     if event == "alarm" then
  932.       -- got an alarm event
  933.       pprint( "Alarm event..." )
  934.       for i=1,#tArgs,3 do
  935.         if tArgs[i]=="al" then
  936.           pprint("... i("..i..") al | triggered @ "..os.time())
  937.           if param1==tArgs[i+1] then pprint("Match!")      blnLoop=false returnResult=(i+2)/3 break end
  938.           if param1==tArgs[i+2] then pprint("Late Match!") blnLoop=false returnResult=(i+2)/3 break end
  939.         end
  940.       end
  941.     end
  942.    
  943.     -- in
  944.     if event == "turtle_inventory" then
  945.       -- got an inventory event
  946.       pprint( "Inventory event..." )
  947.       for i=1,#tArgs,3 do
  948.         if tArgs[i]=="in=" or tArgs[i]=="in>" or tArgs[i]=="in<" then
  949.           pprint("... i("..i..") in | "..tostring(tArgs[i+1]).." | "..string.sub(tArgs[i],3,3)..tostring(tArgs[i+2]))
  950.           if checkInventroyCount(tArgs[i], tArgs[i+1], tArgs[i+2]) then pprint("Match!") blnLoop=false returnResult=(i+2)/3 break end
  951.         end
  952.       end
  953.     end
  954.        
  955.     -- rn
  956.     if event == "modem_message" then --or event == "rednet_message"then
  957.       -- got an alarm event
  958.       pprint( "Rednet event..." )
  959.       for i=1,#tArgs,3 do
  960.         if tArgs[i]=="rn" then
  961.           pprint("... i("..i..") rn | "..tostring(tArgs[i+1]).." | "..tostring(tArgs[i+2]))
  962.           if param2==tArgs[i+1] and param4==tArgs[i+2] then pprint("Match!") blnLoop=false returnResult=(i+2)/3 break end
  963.         end
  964.       end
  965.     end
  966.   end
  967. end
  968.  
  969.  
  970. ---- step 2: finishing stuff / report ----
  971. pprint("Triggered event = "..returnResult)
  972. pprint("That was eventful !")
  973. pprintUI("header")  
  974. pprintUI("Check out YouTube for more videos")
  975. pprintUI("and turtle programs by Kaikaku :)")
  976. pprintUI("footer")
  977. local tmpX, tmpY = term.getCursorPos() pcoloredTextAt("Kaikaku",9+16,tmpY-2,baseColor) -- <<-- put line in template
  978. if shellDotRun~="" then
  979.   pprint("Executing: shell.run("..shellDotRun..")")
  980.   debugSleep(2)
  981.   shell.run(shellDotRun)
  982. end
  983.  
  984. return returnResult
Add Comment
Please, Sign In to add comment