This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
MonsTheLord's profile picture

Countdown Timer For A Spawner

Started by MonsTheLord, 11 September 2013 - 07:31 AM
MonsTheLord #1
Posted 11 September 2013 - 09:31 AM
I am trying to make a countdown for a redstone button to put a countdown on mob spawning, but im am pretty noob to all of this :<

i want to do exactly this:

Button is pressed and redstone signal goes to computer
computer starts a countdown (of 5 minutes) and displays the countdown on the screen next to it
while this countdown is active i would like an active redstone pulse from another side.
when the countdown hits zero the screen will say "Press button to start spawner"
The redstone pulse will then turn off until button is pressed again.

If anyone can help me this would be much appreciated :>
Lyqyd #2
Posted 11 September 2013 - 12:30 PM
Split into new topic.

Well, the simplest version of this would basically just check the redstone input on the side of the button, then output a redstone signal on another side and use sleeps or timer events to deal with the timer display. You should start with the redstone API page in the wiki and check out the sleep page and term API page for drawing to the screen.
MonsTheLord #3
Posted 11 September 2013 - 07:48 PM
post link = here
You need to use os.pullEvent()
I just threw this together, dunno if it works.

local mon = peripheral.wrap("back")
local count = 45

function hold()
  sleep(1)
  return
end

function redPulse()
  os.pullEvent("redstone")
  return
end

function count()
  local current = count
  while true do
	mon.clear()
	mon.setCursorPos(1,1)
	mon.write('Next train arrives in '..current..' seconds')
	current = current - 1
	if current < 0 then
	  mon.clear()
	  mon.setCursorPos(1,1)
	  mon.write('Next train is arriving...')
	end
	local e = parallel.waitForAny(hold, redPulse)
	if e == 2 then
	  break
	end
  end
end

while true do
  count()
end
found this in another thread and i edited on it since it seems to almost fit the same function i needed for my countdown timer…
there were a lot of errors to begin with but so far i have:

local mon = peripheral.wrap("right")
local x,y = mon.getSize()
local count = 300

function hold()
  sleep(1)
  return
end

function redPulse()
  os.pullEvent("redstone")
  return
end

function count()
  local current = count
  while true do
		mon.clear()
		mon.setCursorPos( x / 2 - 26 / 2 + (26 % 2 == 0 and 0 or 1), 1)
		mon.write("Mobs will stop spawning in")
		mon.setCursorPos( x / 2 - 10 / 2 + (10 % 2 == 0 and 0 or 1), 2)
		mon.write(current "seconds")
		current = current - 1
		if current < 0 then
		  redstone.setOutput(back, false)
		  mon.clear()
		  mon.setCursorPos( screen_width / 2 - 21 / 2 + (21 % 2 == 0 and 0 or 1), 1)
		  mon.write("Mobs have been paused")
		end
		local e = parallel.waitForAny(hold, redPulse)
		if e == 2 then
		  break
		end
  end
end

while true do
  count()
end
my problems are that

		mon.write("current seconds")
"current" didnt place to the number of seconds

also line 23

		current = current - 1
i have an error on attempt to perform arithmetic __sub on function and number
ikke009 #4
Posted 11 September 2013 - 09:29 PM
Great work so far.
Your first problem is that in:
mon.write("current seconds")
current is actually a string, or a word, instead of a variable. To fix this simply put current out of the string like this:
mon.write(current .. "seconds")

Why the "current = current-1" thing isn't working.. No clue sorry :S
Lyqyd #5
Posted 11 September 2013 - 11:29 PM
function count()
local current = count

That's what's causing the error. A variable only holds one thing at a time.
MonsTheLord #6
Posted 12 September 2013 - 04:33 AM
Great work so far.
Your first problem is that in:
mon.write("current seconds")
current is actually a string, or a word, instead of a variable. To fix this simply put current out of the string like this:
mon.write(current .. "seconds")

Why the "current = current-1" thing isn't working.. No clue sorry :S
Ok thanks i fixed that above but that is still affected by the next problem:
function count()
local current = count

That's what's causing the error. A variable only holds one thing at a time.
im still not sure how to fix this any suggestions :/
albrat #7
Posted 12 September 2013 - 08:17 AM
the local current = count is basically assigning current to the function itself. (bad way of writing the program with a function and a varible using the same name.)

Change local count = 300 (at the start of the program) to "counter = 300"

then change the local current = count to "local current = counter"
This will avoid any possible mis-translation of the counter and count (varible and function) by Lua. (also note I changed the counter varible into a global varible by removing local from it's declaration)


I would also say that you really do not need to assign the origional "counter" value as all you are doing is later passing a unchanged value to the program. (wastes memory)…

I suggest you scrap the local count = 300 and just write in the first line of the function "local current = 300" instead. as it is exactly the same but you only assign 300 to current and not to count and current.

function count()
  local current = 300
  ... code stuffs
end
MonsTheLord #8
Posted 12 September 2013 - 08:52 AM

local mon = peripheral.wrap("right")
local x,y = mon.getSize()

function hold()
  sleep(1)
  return
end

function redPulse()
  os.pullEvent("redstone")
  return
end

function count()
  local current = 300
  while true do
		mon.clear()
		mon.setCursorPos( x / 2 - 26 / 2 + (26 % 2 == 0 and 0 or 1), 1)
		mon.write("Mobs will stop spawning in")
		mon.setCursorPos( x / 2 - 10 / 2 + (10 % 2 == 0 and 0 or 1), 2)
		mon.write(current "seconds")
		current = current - 1
		if current < 0 then
		  redstone.setOutput(back, true)
		  mon.clear()
		  mon.setCursorPos( screen_width / 2 - 21 / 2 + (21 % 2 == 0 and 0 or 1), 1)
		  mon.write("Mobs have been paused")
		end
		local e = parallel.waitForAny(hold, redPulse)
		if e == 2 then
		  break
		end
  end
end

while true do
  count()
end
another problem :<

		mon.write(current "seconds")
i cant get current to replace to be the 1-2 digit number it is suppose to be :<
i get "attempt to call number" error
CoderPuppy #9
Posted 12 September 2013 - 09:12 AM
Lua lets you call functions without parentheses is you're only passing one argument. Thus it thinks you want to call current (which is a number) passing in "seconds". Which would result in an attempt to call number. What you want to do is concatenate current and "seconds", so you should use the '..' operator.
MonsTheLord #10
Posted 12 September 2013 - 09:34 AM
Lua lets you call functions without parentheses is you're only passing one argument. Thus it thinks you want to call current (which is a number) passing in "seconds". Which would result in an attempt to call number. What you want to do is concatenate current and "seconds", so you should use the '..' operator.
so how would i put that? i tried a few times on my own but got nil and errors
CoderPuppy #11
Posted 12 September 2013 - 10:25 AM
Could you post the code you tried?

Edit: That line should work if it is:

mon.write(current .. "seconds")
MonsTheLord #12
Posted 12 September 2013 - 07:16 PM
Could you post the code you tried?

Edit: That line should work if it is:

mon.write(current .. "seconds")
ok so far so good this is what i have now


local mon = peripheral.wrap("right")
local x,y = mon.getSize()

function hold()
  sleep(1)
  return
end

function redPulse()
  os.pullEvent("redstone")
  return
end

function count()
  local current = 300
  while true do
		mon.clear()
		mon.setCursorPos( x / 2 - 26 / 2 + (26 % 2 == 0 and 0 or 1), 1)
		mon.write("Mobs will stop spawning in")
		mon.setCursorPos( x / 2 - 10 / 2 + (10 % 2 == 0 and 0 or 1), 2)
		mon.write(current .. " seconds")
		current = (current - 1)
		if current < 0 then
		  redstone.setOutput(back, true)
		  mon.clear()
		  mon.setCursorPos( screen_width / 2 - 21 / 2 + (21 % 2 == 0 and 0 or 1), 1)
		  mon.write("Mobs have been paused")
		end
		local e = parallel.waitForAny(hold, redPulse)
		if e == 2 then
		  break
		end
  end
end

while true do
  count()
end
here are the next problems:
i once the timer gets to zero it says
startup:40: Expected string, bolean

also this bit of code didnt seem to take place

if current < 0 then
		  redstone.setOutput(back, true)
		  mon.clear()
		  mon.setCursorPos( screen_width / 2 - 21 / 2 + (21 % 2 == 0 and 0 or 1), 1)
		  mon.write("Mobs have been paused")
immibis #13
Posted 13 September 2013 - 03:48 AM
Which line is 40?
MonsTheLord #14
Posted 13 September 2013 - 09:32 AM
Which line is 40?
thats the problem :< only has 38 lines.. so its something to do with its startup >.> hence why i am lost
BigTwisty #15
Posted 13 September 2013 - 10:57 AM
What if we just created a whole bunch of timer events at timer start? That would reduce error over time from events not being processed at exactly the moment they rise if some other application is taking time.


local timers = {}
term.clear()
term.setCursorPos(1,1)
print("Spawner Timer Delux")
print("----------------------------")
print("Press button for teh mobz...")

local function output(text)
  term.setCursorPos(1,3)
  term.clearLine()
  term.write(text)
end

local function begin(seconds)
  timers = {}
  for i=0,seconds - 1 do
	timers[os.startTimer(seconds-i)] = i
  end
  redstone.setOutput("back", true)
  output("Spawner on for next "..tostring(seconds).." seconds...")
end

while true do
  event, p1, p2 = os.pullEvent()
  if event == "timer" then
	if timers[p1] == 0 then
	  output("Press button for teh mobz...")
	  redstone.setOutput("back", false)
	else if timers[p1] then
	  output("Spawner on for next "..tostring(timers[p1]).." seconds...")
	end
  end
  if event == "redstone" and redstone.getInput("back") then
	begin(300)
  end
end