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

Why Does The Red Cable Go On?!

Started by campicus, 08 November 2013 - 07:48 AM
campicus #1
Posted 08 November 2013 - 08:48 AM
When this code boots up after a restart, all the cables should be ON, only the red goes on though. After I touch something on the screen, they all turn on. I have no idea what is happening here

Spoiler

local rsSide = "top" --"bundled cable side"
local sCount = 10 --"how long the spawner will stay on"
local mon = peripheral.wrap("back")

local spawn = {
creeper = {status = "off", color = colors.green, yPos = 2,},
witch = {status = "off", color = colors.red, yPos = 3,},
skeleton = {status = "off", color = colors.white, yPos = 4,},
blaze = {status = "off", color = colors.orange, yPos = 5,},
pigmen = {status = "off", color = colors.yellow, yPos = 6,},
slime = {status = "off", color = colors.lime, yPos = 7,},
chicken = {status = "off", color = colors.pink, yPos = 8,},
zombie = {status = "off", color = colors.purple, yPos = 9,},
cow = {status = "off", color = colors.brown, yPos = 10,},
sheep = {status = "off", color = colors.lightGray, yPos = 11,},
wither = {status = "off", color = colors.black, yPos = 12,},
spider = {status = "off", color = colors.magenta, yPos = 13,},
}

local function text(curX,curY,textCol,backCol,scale,string)
  scale = tonumber(scale)
  mon.setTextScale(scale)
  mon.setBackgroundColor(backCol)
  mon.setTextColor(textCol)
  mon.setCursorPos(curX,curY)
  mon.write(string)
  mon.setBackgroundColor(colors.black)
  mon.setTextColor(colors.white)
end

local function header() --"monitor display"
  mon.clear()
  text(1,1,colors.blue,colors.white,0.5,"Camp's Spawner v0.3                         ")
  for mob, data in pairs(spawn) do
    if data.yPos == 12 then
      text(3,data.yPos,colors.gray,colors.black,1," "..mob..": ")
    else
      text(3,data.yPos,data.color,colors.black,1," "..mob..": ")
    end
    if data.status == "on " then
      text(16,data.yPos,colors.white,colors.green,1,data.status)
    elseif data.status == "off" then
      text(16,data.yPos,colors.black,colors.red,1,data.status)
    end
    text(21,data.yPos,colors.white,colors.black,1,"|")
    if data.yPos == 3 then
      text(23,3,colors.white,colors.black,1,"  \/\\  ")
    elseif data.yPos == 4 then
      text(23,4,colors.black,colors.white,1,"  "..sCount.."  ")
    elseif data.yPos == 5 then
      text(23,5,colors.white,colors.black,1,"  \\\/  ")
    end
    text(23,12,colors.black,colors.green,1,"All On")
    text(23,13,colors.black,colors.red,1,"AllOff")
  end
end

local function toggleSpawn() --"turns spawners on/off depending on their status"
  for mob,data in pairs(spawn) do
    if (data.status == "on ") and colors.test(rs.getBundledOutput(rsSide), data.color) then
      rs.setBundledOutput(rsSide, rs.getBundledOutput(rsSide)-data.color)
    elseif (data.status == "off") and (not colors.test(rs.getBundledOutput(rsSide), data.color)) then
      rs.setBundledOutput(rsSide, rs.getBundledOutput(rsSide)+data.color)
    end
  end
end

local function checkClick() --"touchscreen functionality"
  event, side, xClick, yClick = os.pullEvent("monitor_touch")
  for mob,data in pairs(spawn) do
    if yClick == data.yPos and (xClick >= 16 and xClick <= 19) then
      if data.status == "off" then
        data.status = "on "
      else
        data.status = "off"
      end
    end
  end
  if yClick == 3 and (xClick >= 23 and xClick <= 29) then
    if sCount < 500 then
      sCount = sCount + 10
    end
  elseif yClick == 5 and (xClick >= 23 and xClick <= 29) then
    if sCount > 10 then
      sCount = sCount - 10
    end
  end
  if yClick == 12 and (xClick >= 23 and xClick <= 29) then
    for mob,data in pairs(spawn) do
      data.status = "on "
    end
  end
  if yClick == 13 and (xClick >= 23 and xClick <= 29) then
    for mob,data in pairs(spawn) do
      data.status = "off"
    end
  end
end

local function spawner()
  header()
  toggleSpawn()
  checkClick()
end

while true do
  spawner()
end
Bomb Bloke #2
Posted 08 November 2013 - 04:15 PM
Your current toggle-spawn function:

local function toggleSpawn() --"turns spawners on/off depending on their status"
  for mob,data in pairs(spawn) do
    if (data.status == "on ") and colors.test(rs.getBundledOutput(rsSide), data.color) then             -- If this colour should be on, and IS on, then...
      rs.setBundledOutput(rsSide, rs.getBundledOutput(rsSide)-data.color)                               -- remove it from the cable, turning it off.
    elseif (data.status == "off") and (not colors.test(rs.getBundledOutput(rsSide), data.color)) then   -- otherwise, if it should be off, and IS off...
      rs.setBundledOutput(rsSide, rs.getBundledOutput(rsSide)+data.color)                               -- then turn it on.
    end
  end
end

See the problem? If a colour is enabled in the cable and is supposed to be, or isn't and shouldn't, then you don't want to perform any action at all.

If you want all the cables to be on when the program starts, then your starting table shouldn't be filled with "off"s.
Edited on 08 November 2013 - 03:15 PM
theoriginalbit #3
Posted 08 November 2013 - 09:41 PM
Also you should be avoiding using + and - with ComputerCraft colours. You can get unexpected results, instead you should use colors.combine and colors.subtract

Here is an example output/reason why… Lets assume we want to add white to a cable, that already has white

local current = colors.white
print(current + colors.white)
the output of this will be 2, which is colours.orange, meaning that this now has an unexpected result, however, now if we use combine

local current = colors.white
print(colors.combine(current, colors.white))
the output for this will be 1, which is white, meaning no unexpected result.

Knowing this knowledge we can actually refine your toggle spawn function down

local function toggleSpawn()
  for mob,data in pairs(spawn) do
	local func = data.status == "on " and colors.subtract or colors.combine --# make a variable for which function we want to call based on the status   [condition] and [if-true] or [if-false]
	rs.setBundledOutput(rsSide, func(rs.getBundledOutput(rsSide), data.color) --# set the output to what the new output should be
  end
end
Edited on 08 November 2013 - 08:42 PM
campicus #4
Posted 08 November 2013 - 09:44 PM
If you supply spawners with a redstone signal they will turn off, so "off" actually means that the redpower should be on, so that the spawners are off. I will try colors.combine :)/>

EDIT:
Tried combine and subtract and it made no difference

local function toggleSpawn() --"turns spawners on/off depending on their status"
  for mob,data in pairs(spawn) do
	if active and (data.status == "on ") and colors.test(rs.getBundledOutput(rsSide), data.color) then
	  rs.setBundledOutput(rsSide, colors.subtract(rs.getBundledOutput(rsSide),data.color))
	elseif (data.status == "off") and (not colors.test(rs.getBundledOutput(rsSide), data.color)) then
	  rs.setBundledOutput(rsSide, colors.combine(rs.getBundledOutput(rsSide),data.color))
	end
  end
end

EDIT:
I changed the cable from red to gray and it still turned on… weird
Also, changed the status in the table to "on " for all of them, this resulted in all the wires having no rs signal (as it should)

LAST EDIT:
I fixed the problem by manually setting all the colors on when the program launches and not calling toggleSpawn() until the prgram gets a touch_screen event
Edited on 08 November 2013 - 09:07 PM