SHOW:
|
|
- or go back to the newest paste.
| 1 | -- Cloned | |
| 2 | -- Misc Useful Functions | |
| 3 | -- Required by most other programs | |
| 4 | -- <[email protected]> | |
| 5 | ||
| 6 | ------------------------------------------- | |
| 7 | -- |¯¯] || |¯¯] \\// /\ |¯\ [¯¯] -- | |
| 8 | -- | ] ||_ | ] >< | | | / ][ -- | |
| 9 | -- || |__] |__] //\\ |||| || [__] -- | |
| 10 | ------------------------------------------- | |
| 11 | ||
| 12 | local log_file = "log.txt" | |
| 13 | local options_file = "flex_options.cfg" | |
| 14 | ||
| 15 | - | local modem_channel = 6464 |
| 15 | + | |
| 16 | local modem_channel = 6969 | |
| 17 | local name_color | |
| 18 | if term.isColor() then | |
| 19 | name_color = "yellow" | |
| 20 | - | name_color = "lightGray" |
| 20 | + | |
| 21 | name_color = "pink" | |
| 22 | end --if/else | |
| 23 | ||
| 24 | ||
| 25 | function getPeripheral(name) | |
| 26 | local x,sides | |
| 27 | sides = { "top", "bottom", "left",
| |
| 28 | "right", "front", "back" } | |
| 29 | local periph = {}
| |
| 30 | for x=1,#sides do | |
| 31 | if peripheral.getType(sides[x]) == name then | |
| 32 | periph[#periph+1] = sides[x] | |
| 33 | end --if | |
| 34 | end --for | |
| 35 | return periph | |
| 36 | end --function | |
| 37 | ||
| 38 | ||
| 39 | local modem | |
| 40 | local hasModem = false | |
| 41 | local x = getPeripheral("modem")
| |
| 42 | if #x > 0 then | |
| 43 | hasModem = true | |
| 44 | modem = peripheral.wrap(x[1]) | |
| 45 | modem.open(modem_channel) | |
| 46 | end --if | |
| 47 | ||
| 48 | function modemOff() | |
| 49 | local x = getPeripheral("modem")
| |
| 50 | if #x > 0 then | |
| 51 | modem.close(modem_channel) | |
| 52 | end --if | |
| 53 | end --function | |
| 54 | ||
| 55 | ||
| 56 | local file | |
| 57 | if not fs.exists(log_file) then | |
| 58 | file = fs.open(log_file,"w") | |
| 59 | file.close() | |
| 60 | end --if | |
| 61 | ||
| 62 | ||
| 63 | ||
| 64 | function optionsExport() | |
| 65 | if fs.exists(options_file) then | |
| 66 | fs.delete(options_file) | |
| 67 | end | |
| 68 | local file | |
| 69 | while file == nil do | |
| 70 | file = fs.open(options_file,"w") | |
| 71 | end | |
| 72 | file.writeLine("# Flex API Options File #\n")
| |
| 73 | file.writeLine("modem_channel="
| |
| 74 | ..tostring(modem_channel)) | |
| 75 | file.writeLine("name_color="..name_color.."\n")
| |
| 76 | file.close() | |
| 77 | return true | |
| 78 | end --function | |
| 79 | ||
| 80 | ||
| 81 | function optionsImport() | |
| 82 | if not fs.exists(options_file) then | |
| 83 | return false | |
| 84 | end | |
| 85 | local file | |
| 86 | while file == nil do | |
| 87 | file = fs.open(options_file, "r") | |
| 88 | end | |
| 89 | ||
| 90 | local x = file.readLine() | |
| 91 | while x ~= nil do | |
| 92 | if string.find(x,"modem_channel")==1 then | |
| 93 | modem_channel = tonumber(string.sub(x,15)) | |
| 94 | elseif string.find(x,"name_color")==1 then | |
| 95 | name_color = string.sub(x,12) | |
| 96 | end --if/else | |
| 97 | x = file.readLine() | |
| 98 | end --while | |
| 99 | ||
| 100 | file.close() | |
| 101 | return true | |
| 102 | end --function | |
| 103 | ||
| 104 | ||
| 105 | if not optionsImport() then | |
| 106 | optionsExport() | |
| 107 | end --if | |
| 108 | ||
| 109 | ||
| 110 | ||
| 111 | --==============================-- | |
| 112 | ||
| 113 | ||
| 114 | -- Inventory Condense | |
| 115 | function condense(n) | |
| 116 | if n == nil then n = 1 end | |
| 117 | n = math.floor(n) | |
| 118 | if n < 1 or n > 16 then | |
| 119 | n = 1 | |
| 120 | end --if | |
| 121 | ||
| 122 | local x,y,slot | |
| 123 | slot = turtle.getSelectedSlot() | |
| 124 | for x=n+1,16 do | |
| 125 | if turtle.getItemCount(x) > 0 then | |
| 126 | ||
| 127 | for y=n,x-1 do | |
| 128 | if turtle.getItemCount(y) == 0 or | |
| 129 | turtle.getItemDetail(x)["name"] == | |
| 130 | turtle.getItemDetail(y)["name"] and | |
| 131 | turtle.getItemSpace(y) > 0 then | |
| 132 | turtle.select(x) | |
| 133 | turtle.transferTo(y) | |
| 134 | end --if | |
| 135 | if turtle.getItemCount(x) == 0 then | |
| 136 | break | |
| 137 | end --if | |
| 138 | end --for | |
| 139 | ||
| 140 | end --if | |
| 141 | end --for | |
| 142 | turtle.select(slot) | |
| 143 | end --function | |
| 144 | ||
| 145 | ||
| 146 | -- Round n to p decimal places | |
| 147 | function round(n,p) | |
| 148 | if p == nil then p = 0 end | |
| 149 | n = n*math.pow(10,p) | |
| 150 | local m = n - math.floor(n) | |
| 151 | if m < 0.5 then | |
| 152 | return math.floor(n) / math.pow(10,p) | |
| 153 | else | |
| 154 | return math.ceil(n) / math.pow(10,p) | |
| 155 | end --if/else | |
| 156 | end --function | |
| 157 | ||
| 158 | ||
| 159 | -- Number to String | |
| 160 | -- Optionally a max length if not an integer | |
| 161 | function tostr(num,len) | |
| 162 | num = tostring(num) | |
| 163 | local sci = "" | |
| 164 | ||
| 165 | local e = string.find(num,"e") | |
| 166 | if e ~= nil then | |
| 167 | -- Separate exponent from number | |
| 168 | sci = string.sub(num,e,-1) | |
| 169 | num = string.sub(num,1,e-1) | |
| 170 | end --if | |
| 171 | ||
| 172 | if string.find(num,"%.") ~= nil then | |
| 173 | -- Remove extra zeroes from decimal | |
| 174 | while string.sub(num,string.len(num)) == "0" do | |
| 175 | num = string.sub(num,1,string.len(num)-1).."" | |
| 176 | end --while | |
| 177 | end --if | |
| 178 | ||
| 179 | if string.sub(num,-1) == "." then | |
| 180 | -- If all trailing zeroes are gone, erase decimal point | |
| 181 | num = string.sub(num,1,-2).."" | |
| 182 | end --if | |
| 183 | ||
| 184 | if len == nil then | |
| 185 | -- If no max length specified | |
| 186 | return num..sci.."" | |
| 187 | end --if | |
| 188 | ||
| 189 | while string.len(num) + string.len(sci) > len do | |
| 190 | -- If too long, cut off a decimal digit | |
| 191 | num = string.sub(num,1,-2).."" | |
| 192 | end --while | |
| 193 | ||
| 194 | return num..sci.."" | |
| 195 | ||
| 196 | end --function | |
| 197 | ||
| 198 | ||
| 199 | -- Evaluate Expression | |
| 200 | function eval(expression) | |
| 201 | local solution, err = loadstring( | |
| 202 | "return "..expression) | |
| 203 | if err then error(err,2) end | |
| 204 | local sol = pcall(solution) | |
| 205 | if not sol then | |
| 206 | error("Invalid Expression",2)
| |
| 207 | end | |
| 208 | return solution() | |
| 209 | end --function | |
| 210 | ||
| 211 | ||
| 212 | -- Press any Key | |
| 213 | function getKey() | |
| 214 | local event, key_code = os.pullEvent("key")
| |
| 215 | return key_code | |
| 216 | end --function | |
| 217 | function keyPress() return getKey() end | |
| 218 | ||
| 219 | ||
| 220 | ||
| 221 | ||
| 222 | ------------------------------- | |
| 223 | -- [¯¯] |¯¯] \\// [¯¯] -- | |
| 224 | -- || | ] >< || -- | |
| 225 | -- || |__] //\\ || -- | |
| 226 | ------------------------------- | |
| 227 | -- /¯] /¯\ || /¯\ |¯\ -- | |
| 228 | -- | [ | O | ||_ | O | | / -- | |
| 229 | -- \_] \_/ |__] \_/ | \ -- | |
| 230 | ------------------------------- | |
| 231 | ||
| 232 | hexchars = "0123456789ABCDEF" | |
| 233 | ||
| 234 | -- Start with named value, get hex char | |
| 235 | function getHex(x) | |
| 236 | if x == nil then | |
| 237 | error("Number expected, got nil", 2)
| |
| 238 | end | |
| 239 | x = round(math.log(x)/math.log(2)) | |
| 240 | if x < 0 or x > 15 then | |
| 241 | error("Invalid color number", 2)
| |
| 242 | end --if | |
| 243 | return string.sub(hexchars,x+1,x+1) | |
| 244 | end --function | |
| 245 | ||
| 246 | -- Start with hex char, get named value | |
| 247 | function getVal(x) | |
| 248 | local z = string.find(hexchars,x) | |
| 249 | if z == nil then return nil end | |
| 250 | return math.pow(2,z-1) | |
| 251 | end --function | |
| 252 | ||
| 253 | local send_depth, print_depth = 0, 0 | |
| 254 | ||
| 255 | ||
| 256 | ||
| 257 | ------------------------------- | |
| 258 | -- Multicolor Print Function -- | |
| 259 | ------------------------------- | |
| 260 | ||
| 261 | function printColors(message,textColor) | |
| 262 | local x,y,z,t,skip,margin | |
| 263 | local xmax,ymax = term.getSize() | |
| 264 | local oldColor = term.getTextColor() | |
| 265 | if textColor == nil then | |
| 266 | textColor = oldColor | |
| 267 | else | |
| 268 | ||
| 269 | end --if | |
| 270 | ||
| 271 | margin = "" | |
| 272 | for x=1,print_depth do | |
| 273 | margin = margin.." " | |
| 274 | end --for | |
| 275 | ||
| 276 | if type(message) == "table" then | |
| 277 | if print_depth == 0 then | |
| 278 | printColors("#0{")
| |
| 279 | end --if | |
| 280 | print_depth = print_depth + 1 | |
| 281 | ||
| 282 | for x,y in pairs(message) do | |
| 283 | if type(y) == "table" then | |
| 284 | printColors(margin.." "..tostring(x).." #0= {",textColor)
| |
| 285 | printColors(y,textColor) | |
| 286 | else | |
| 287 | printColors(margin.." "..tostring(x).." #0= #".. | |
| 288 | getHex(textColor)..tostring(y),textColor) | |
| 289 | end --if/else | |
| 290 | end --for | |
| 291 | ||
| 292 | print_depth = print_depth - 1 | |
| 293 | printColors(margin.."#0}") | |
| 294 | return | |
| 295 | ||
| 296 | end --if | |
| 297 | ||
| 298 | if type(textColor) == "number" then | |
| 299 | message = "#"..getHex(textColor) | |
| 300 | ..tostring(message) | |
| 301 | end --if | |
| 302 | ||
| 303 | for t=1,string.len(message) do | |
| 304 | ||
| 305 | skip = false | |
| 306 | while string.sub(message,t,t) == "#" and | |
| 307 | not skip do | |
| 308 | ||
| 309 | -- Found legit "#" | |
| 310 | if string.sub(message,t+1,t+1) == "#" then | |
| 311 | message = string.sub(message,1,t).. | |
| 312 | string.sub(message,t+2).."" | |
| 313 | skip = true | |
| 314 | ||
| 315 | else | |
| 316 | textColor = getVal(string.sub(message,t+1,t+1)) | |
| 317 | ||
| 318 | if textColor == nil then | |
| 319 | textColor = colors.white | |
| 320 | end --if | |
| 321 | ||
| 322 | -- This bit clears out # escapes | |
| 323 | if t == 1 then | |
| 324 | message = string.sub(message,3).."" | |
| 325 | elseif t < string.len(message) then | |
| 326 | message = string.sub(message,1,t-1).. | |
| 327 | string.sub(message,t+2).."" | |
| 328 | elseif t == string.len(message) then | |
| 329 | message = string.sub(message,1,t-1).."" | |
| 330 | end --if/else | |
| 331 | ||
| 332 | end --if | |
| 333 | ||
| 334 | if t > string.len(message) then | |
| 335 | break | |
| 336 | end --if | |
| 337 | ||
| 338 | end --while (is escape char) | |
| 339 | ||
| 340 | if t > string.len(message) then | |
| 341 | break | |
| 342 | end --if | |
| 343 | ||
| 344 | -- Actually Print Character | |
| 345 | x,y = term.getCursorPos() | |
| 346 | term.setTextColor(textColor) | |
| 347 | ||
| 348 | if textColor == colors.gray then | |
| 349 | --term.setBackgroundColor(colors.lightGray) | |
| 350 | ||
| 351 | elseif textColor == colors.black then | |
| 352 | term.setBackgroundColor(colors.lightGray) | |
| 353 | ||
| 354 | end --if/else | |
| 355 | term.write(string.sub(message,t,t)) | |
| 356 | term.setBackgroundColor(colors.black) | |
| 357 | ||
| 358 | if t >= string.len(message) then | |
| 359 | break | |
| 360 | end --if | |
| 361 | ||
| 362 | -- Loop Around to Next Row | |
| 363 | xmax,ymax = term.getSize() | |
| 364 | if string.sub(message,t,t) == "\n" or x >= xmax then | |
| 365 | x = 1 | |
| 366 | if y < ymax-1 then | |
| 367 | y = y + 1 | |
| 368 | else | |
| 369 | print("")
| |
| 370 | end --if/else | |
| 371 | else | |
| 372 | x = x + 1 | |
| 373 | end --if/else | |
| 374 | term.setCursorPos(x,y) | |
| 375 | ||
| 376 | end --for | |
| 377 | ||
| 378 | term.setTextColor(oldColor) | |
| 379 | print("")
| |
| 380 | ||
| 381 | end --function | |
| 382 | ||
| 383 | ||
| 384 | ||
| 385 | ------------------------------ | |
| 386 | -- Print/Broadcast Function -- | |
| 387 | ------------------------------ | |
| 388 | ||
| 389 | function send(message,textColor) | |
| 390 | local x,y,z,id,nameColor | |
| 391 | local oldColor = term.getTextColor() | |
| 392 | ||
| 393 | local margin = "" | |
| 394 | for x=1,send_depth do | |
| 395 | margin = margin.." " | |
| 396 | end --for | |
| 397 | ||
| 398 | if type(message) == "table" then | |
| 399 | if send_depth == 0 then | |
| 400 | send("#0{")
| |
| 401 | end --if | |
| 402 | send_depth = send_depth + 1 | |
| 403 | ||
| 404 | for x,y in pairs(message) do | |
| 405 | if type(y) == "table" then | |
| 406 | send(margin.." "..tostring(x).." #0= {",textColor)
| |
| 407 | send(y,textColor) | |
| 408 | else | |
| 409 | send(margin.." "..tostring(x).." #0= #" | |
| 410 | ..getHex(textColor)..tostring(y),textColor) | |
| 411 | end --if/else | |
| 412 | end --for | |
| 413 | ||
| 414 | send_depth = send_depth - 1 | |
| 415 | send(margin.."#0}") | |
| 416 | return | |
| 417 | ||
| 418 | end --if | |
| 419 | ||
| 420 | ||
| 421 | if message == nil then | |
| 422 | message = "nil" | |
| 423 | end --if | |
| 424 | ||
| 425 | message = tostring(message) | |
| 426 | if textColor == nil then | |
| 427 | textColor = colors.white | |
| 428 | end --if | |
| 429 | nameColor = eval("colors."..name_color)
| |
| 430 | ||
| 431 | printColors(message) | |
| 432 | ||
| 433 | file = fs.open(log_file,"a") | |
| 434 | file.writeLine(message) | |
| 435 | file.close() | |
| 436 | ||
| 437 | if hasModem then | |
| 438 | id = "#"..getHex(nameColor).. | |
| 439 | tostring(os.getComputerID()).."#0" | |
| 440 | ||
| 441 | if os.getComputerLabel() ~= nil then | |
| 442 | id = id.."|#"..getHex(nameColor).. | |
| 443 | os.getComputerLabel().."#0" | |
| 444 | end --if | |
| 445 | ||
| 446 | id = id..": #"..getHex(textColor).. | |
| 447 | message.."" | |
| 448 | ||
| 449 | modem.transmit(modem_channel, | |
| 450 | modem_channel+1,id) | |
| 451 | sleep(0.1) | |
| 452 | end --if (hasModem) | |
| 453 | ||
| 454 | term.setTextColor(oldColor) | |
| 455 | sleep(0.02) | |
| 456 | end --function (print/broadcast) | |
| 457 | ||
| 458 | ||
| 459 | --================================-- | |
| 460 | ||
| 461 | ||
| 462 | args = {...}
| |
| 463 | ||
| 464 | if args[1]=="color" or args[1]=="colors" then | |
| 465 | z = "" | |
| 466 | for x=0,15 do | |
| 467 | y = string.sub(hexchars,x+1,x+1).."" | |
| 468 | z = z.."#"..y..y.."#0 " | |
| 469 | end --for | |
| 470 | printColors(z) | |
| 471 | return | |
| 472 | ||
| 473 | elseif args[1] == "edit" then | |
| 474 | shell.run("edit "..options_file)
| |
| 475 | optionsImport() | |
| 476 | ||
| 477 | end --if/else | |
| 478 | ||
| 479 | ||
| 480 | ||
| 481 | ------------------------------------------- | |
| 482 | -- /¯¯] |¯¯] [¯¯] |¯\ /\ [¯¯] /\ -- | |
| 483 | --| [¯| | ] || | | | | || | | -- | |
| 484 | -- \__| |__] || |_/ |||| || |||| -- | |
| 485 | ------------------------------------------- | |
| 486 | ||
| 487 | ||
| 488 | function getBlock(dir) | |
| 489 | dir = dir or "fwd" | |
| 490 | local block,meta | |
| 491 | ||
| 492 | if dir=="fwd" then | |
| 493 | block,meta = turtle.inspect() | |
| 494 | elseif dir=="up" then | |
| 495 | block,meta = turtle.inspectUp() | |
| 496 | elseif dir=="down" then | |
| 497 | block,meta = turtle.inspectDown() | |
| 498 | end | |
| 499 | ||
| 500 | if block then | |
| 501 | block = meta["name"] | |
| 502 | meta = meta["metadata"] | |
| 503 | return block,meta | |
| 504 | else | |
| 505 | return "minecraft:air",nil | |
| 506 | end --if | |
| 507 | ||
| 508 | end --function | |
| 509 | ||
| 510 | function getBlockUp() | |
| 511 | return getBlock("up")
| |
| 512 | end | |
| 513 | ||
| 514 | function getBlockDown() | |
| 515 | return getBlock("down")
| |
| 516 | end | |
| 517 | ||
| 518 | ||
| 519 | function isBlock(key,dir) | |
| 520 | if type(key) == "string" then | |
| 521 | key = { key }
| |
| 522 | end --if | |
| 523 | if type(key) ~= "table" then | |
| 524 | error("Expected string or table, got "
| |
| 525 | ..type(key), 2) | |
| 526 | return false | |
| 527 | end --if | |
| 528 | ||
| 529 | local block = getBlock(dir) | |
| 530 | local x | |
| 531 | for x=1,#key do | |
| 532 | ||
| 533 | if string.find(key[x],":") ~= nil then | |
| 534 | if block == key[x] then | |
| 535 | return true | |
| 536 | end --if | |
| 537 | ||
| 538 | else | |
| 539 | if string.find(block,key[x]) ~= nil then | |
| 540 | return true | |
| 541 | end --if | |
| 542 | ||
| 543 | end --if/else | |
| 544 | end --for | |
| 545 | ||
| 546 | return false | |
| 547 | end --function | |
| 548 | ||
| 549 | function isBlockUp(key) | |
| 550 | return isBlock(key, "up") | |
| 551 | end | |
| 552 | ||
| 553 | function isBlockDown(key) | |
| 554 | return isBlock(key, "down") | |
| 555 | end | |
| 556 | ||
| 557 | ||
| 558 | ||
| 559 | local fluid = { "air", "water", "lava",
| |
| 560 | "acid", "blood", "poison" } | |
| 561 | ||
| 562 | function isFluid(dir) | |
| 563 | return isBlock(fluid, "fwd") | |
| 564 | end | |
| 565 | ||
| 566 | function isFluidUp() | |
| 567 | return isBlock(fluid, "up") | |
| 568 | end | |
| 569 | ||
| 570 | function isFluidDown() | |
| 571 | return isBlock(fluid, "down") | |
| 572 | end | |
| 573 | ||
| 574 | ||
| 575 | ||
| 576 | function isItem(key,slot) | |
| 577 | if key == nil then return false end | |
| 578 | ||
| 579 | local slot_old = turtle.getSelectedSlot() | |
| 580 | if type(slot) ~= "number" then | |
| 581 | slot = slot_old | |
| 582 | end --if | |
| 583 | ||
| 584 | if type(key) == "table" then | |
| 585 | local x | |
| 586 | for x=1,#key do | |
| 587 | if isItem(key[x],slot) then | |
| 588 | return true | |
| 589 | end --if | |
| 590 | end --for | |
| 591 | return false | |
| 592 | end --if | |
| 593 | ||
| 594 | if turtle.getItemCount(slot) == 0 then | |
| 595 | return false | |
| 596 | end --if | |
| 597 | ||
| 598 | local name = turtle.getItemDetail(slot)["name"] | |
| 599 | ||
| 600 | return ( string.find(name,key) ~= nil ) | |
| 601 | end --function | |
| 602 | ||
| 603 | ||
| 604 |