Бекап

This commit is contained in:
igor 2018-01-30 05:41:56 +03:00
parent 4ac241bc3e
commit bdc80516c0
542 changed files with 55855 additions and 16 deletions

View File

@ -0,0 +1 @@
{label = "OpenOS", reboot=true, setlabel=true, setboot=true}

Binary file not shown.

View File

@ -0,0 +1 @@
{["HoloEdit.app"]={["y"]=9,["x"]=87},["Calendar.app"]={["y"]=2,["x"]=73},["ChristmasTree.app"]={["y"]=2,["x"]=101},[".DS_Store"]={["y"]=16,["x"]=143},["RayWalk.app"]={["y"]=16,["x"]=45},["Graph.app"]={["y"]=9,["x"]=31},["InfoPanel.app"]={["y"]=9,["x"]=101},["VK.app"]={["y"]=16,["x"]=115},["Shooting.app"]={["y"]=16,["x"]=73},["Palette.app"]={["y"]=9,["x"]=129},["FlappyBird.app"]={["y"]=2,["x"]=129},["MineCode IDE.app"]={["y"]=9,["x"]=115},["Stargate.app"]={["y"]=16,["x"]=87},["PrintImage.app"]={["y"]=16,["x"]=3},["HoloClock.app"]={["y"]=9,["x"]=73},["GeoScan2.app"]={["y"]=9,["x"]=17},["Photoshop.app"]={["y"]=9,["x"]=143},["RunningString.app"]={["y"]=16,["x"]=59},["Radio.app"]={["y"]=16,["x"]=31},["GuessWord.app"]={["y"]=9,["x"]=45},["3DPrint.app"]={["y"]=2,["x"]=3},["FuckTheRain.app"]={["y"]=9,["x"]=3},["HEX.app"]={["y"]=9,["x"]=59},["ForceAdmin.app"]={["y"]=2,["x"]=143},["BufferDemo.app"]={["y"]=2,["x"]=59},["CodeDoor.app"]={["y"]=2,["x"]=115},["QuantumCube.app"]={["y"]=16,["x"]=17},["TurretControl.app"]={["y"]=16,["x"]=101},["3DTest.app"]={["y"]=2,["x"]=17},["AppMarket.app"]={["y"]=2,["x"]=31},["Weather.app"]={["y"]=16,["x"]=129},["Camera.app"]={["y"]=2,["x"]=87},["Battleship.app"]={["y"]=2,["x"]=45}}

View File

@ -0,0 +1,764 @@
local component = require("component")
local event = require("event")
local unicode = require("unicode")
local serialization = require("serialization")
local fs = require("filesystem")
local color = require("color")
local buffer = require("doubleBuffering")
local context = require("context")
local bigLetters = require("bigLetters")
local ecs = require("ECSAPI")
local printer
local gpu = component.gpu
local hologramAvailable = component.isAvailable("hologram")
------------------------------------------------------------------------------------------------------------------------
if component.isAvailable("printer3d") then
printer = component.printer3d
else
ecs.error("Этой программе требуется 3D-принтер для работы.")
return
end
------------------------------------------------------------------------------------------------------------------------
local colors = {
drawingZoneCYKA = 0xCCCCCC,
drawingZoneBackground = 0xFFFFFF,
drawingZoneStartPoint = 0x262626,
drawingZoneEndPoint = 0x555555,
drawingZoneSelection = 0xFF5555,
toolbarBackground = 0xEEEEEE,
toolbarText = 0x262626,
toolbarKeyText = 0x000000,
toolbarValueText = 0x666666,
toolbarBigLetters = 0x262626,
shapeNumbersText = 0xFFFFFF,
shapeNumbersBackground = 0xAAAAAA,
shapeNumbersActiveBackground = ecs.colors.blue,
shapeNumbersActiveText = 0xFFFFFF,
toolbarInfoBackground = 0x262626,
toolbarInfoText = 0xFFFFFF,
toolbarButtonBackground = 0xCCCCCC,
toolbarButtonText = 0x262626,
}
local xOld, yOld = gpu.getResolution()
local xSize, ySize = 160, 50
gpu.setResolution(160, 50)
buffer.flush()
local widthOfToolbar = 33
local xToolbar = xSize - widthOfToolbar + 1
local widthOfDrawingCYKA = xSize - widthOfToolbar
local currentLayer = 1
local currentShape = 1
local maxShapeCount = printer.getMaxShapeCount()
if maxShapeCount > 24 then maxShapeCount = 24 end
local currentMode = 1
local modes = {
"неактивная",
"активная"
}
local currentTexture = "planks_oak"
local currentTint = ecs.colors.orange
local useTint = false
local showLayerOnHologram = true
local pixelWidth = 6
local pixelHeight = 3
local drawingZoneWidth = pixelWidth * 16
local drawingZoneHeight = pixelHeight * 16
local xDrawingZone = math.floor(widthOfDrawingCYKA / 2 - drawingZoneWidth / 2)
local yDrawingZone = 3
local shapeColors = {}
local HUE = 0
local HUEAdder = math.floor(360 / maxShapeCount)
for i = 1, maxShapeCount do
shapeColors[i] = color.HSBToInteger(HUE, 1, 1)
HUE = HUE + HUEAdder
end
HUE, HUEAdder = nil, nil
local model = {}
------------------------------------------------------------------------------------------------------------------------
local function swap(a, b)
return b, a
end
local function correctShapeCoords(shapeNumber)
if model.shapes[shapeNumber] then
if model.shapes[shapeNumber][1] >= model.shapes[currentShape][4] then
model.shapes[shapeNumber][1], model.shapes[currentShape][4] = swap(model.shapes[currentShape][1], model.shapes[currentShape][4])
model.shapes[shapeNumber][1] = model.shapes[shapeNumber][1] - 1
model.shapes[shapeNumber][4] = model.shapes[shapeNumber][4] + 1
-- ecs.error("СУКА")
end
if model.shapes[shapeNumber][2] >= model.shapes[currentShape][5] then
model.shapes[shapeNumber][2], model.shapes[currentShape][5] = swap(model.shapes[currentShape][2], model.shapes[currentShape][5])
model.shapes[shapeNumber][2] = model.shapes[shapeNumber][2] - 1
model.shapes[shapeNumber][5] = model.shapes[shapeNumber][5] + 1
-- ecs.error("СУКА2")
end
if model.shapes[shapeNumber][3] >= model.shapes[currentShape][6] then
model.shapes[shapeNumber][3], model.shapes[currentShape][6] = swap(model.shapes[currentShape][3], model.shapes[currentShape][6])
model.shapes[shapeNumber][3] = model.shapes[shapeNumber][3] - 1
model.shapes[shapeNumber][6] = model.shapes[shapeNumber][6] + 1
-- ecs.error("СУКА3")
end
end
end
local function loadShapeParameters()
if model.shapes[currentShape] then
currentTexture = model.shapes[currentShape].texture
if model.shapes[currentShape].tint then
currentTint = model.shapes[currentShape].tint
useTint = true
else
useTint = false
end
end
end
local function fixModelArray()
model.label = model.label or "Sample label"
model.tooltip = model.tooltip or "Sample tooltip"
model.lightLevel = model.lightLevel or 0
model.emitRedstone = model.emitRedstone or false
model.buttonMode = model.buttonMode or false
model.collidable = model.collidable or {true, true}
model.shapes = model.shapes or {}
currentLayer = 1
currentShape = 1
currentMode = 1
loadShapeParameters()
end
--Объекты для тача
local obj = {}
local function newObj(class, name, ...)
obj[class] = obj[class] or {}
obj[class][name] = {...}
end
local function drawShapeNumbers(x, y)
local counter = 1
local xStart = x
for j = 1, 4 do
for i = 1, 6 do
if currentShape == counter then
newObj("ShapeNumbers", counter, buffer.button(x, y, 4, 1, shapeColors[counter], 0xFFFFFF - shapeColors[counter], tostring(counter)))
-- newObj("ShapeNumbers", counter, buffer.button(x, y, 4, 1, colors.shapeNumbersActiveBackground, colors.shapeNumbersActiveText, tostring(counter)))
else
newObj("ShapeNumbers", counter, buffer.button(x, y, 4, 1, colors.shapeNumbersBackground, colors.shapeNumbersText, tostring(counter)))
end
x = x + 5
counter = counter + 1
if counter > maxShapeCount then return end
end
x = xStart
y = y + 2
end
end
local function toolBarInfoLine(y, text)
buffer.square(xToolbar, y, widthOfToolbar, 1, colors.toolbarInfoBackground, 0xFFFFFF, " ")
buffer.text(xToolbar + 1, y, colors.toolbarInfoText, text)
end
local function centerText(y, color, text)
local x = math.floor(xToolbar + widthOfToolbar / 2 - unicode.len(text) / 2)
buffer.text(x, y, color, text)
end
local function addButton(y, back, fore, text)
newObj("ToolbarButtons", text, buffer.button(xToolbar + 2, y, widthOfToolbar - 4, 3, back, fore, text))
end
local function printKeyValue(x, y, keyColor, valueColor, key, value, limit)
local totalLength = unicode.len(key .. ": " .. value)
if totalLength > limit then
value = unicode.sub(value, 1, limit - unicode.len(key .. ": ") - 1) .. ""
end
buffer.text(x, y, keyColor, key .. ":")
buffer.text(x + unicode.len(key) + 2, y, valueColor, value)
end
local function getShapeCoords()
local coords = "элемент не создан"
if model.shapes[currentShape] then
coords = "(" .. model.shapes[currentShape][1] .. "," .. model.shapes[currentShape][2] .. "," .. model.shapes[currentShape][3] .. ");(" .. model.shapes[currentShape][4] .. "," .. model.shapes[currentShape][5] .. "," .. model.shapes[currentShape][6] .. ")"
end
return coords
end
local function fixNumber(number)
if number < 10 then number = "0" .. number end
return tostring(number)
end
local function drawToolbar()
buffer.square(xToolbar, 1, widthOfToolbar, ySize, colors.toolbarBackground, 0xFFFFFF, " ")
local x = xToolbar + 8
local y = 3
--Текущий слой
bigLetters.drawText(x, y, colors.toolbarBigLetters, fixNumber(currentLayer))
y = y + 6
centerText(y, colors.toolbarText, "Текущий слой")
--Управление элементом
y = y + 2
x = xToolbar + 2
toolBarInfoLine(y, "Управление моделью"); y = y + 2
printKeyValue(x, y, colors.toolbarKeyText, colors.toolbarValueText, "Имя", model.label, widthOfToolbar - 4); y = y + 1
printKeyValue(x, y, colors.toolbarKeyText, colors.toolbarValueText, "Описание", model.tooltip, widthOfToolbar - 4); y = y + 1
printKeyValue(x, y, colors.toolbarKeyText, colors.toolbarValueText, "Как кнопка", tostring(model.buttonMode), widthOfToolbar - 4); y = y + 1
printKeyValue(x, y, colors.toolbarKeyText, colors.toolbarValueText, "Редстоун-сигнал", tostring(model.emitRedstone), widthOfToolbar - 4); y = y + 1
printKeyValue(x, y, colors.toolbarKeyText, colors.toolbarValueText, "Коллизия", tostring(model.collidable[currentMode]), widthOfToolbar - 4); y = y + 1
printKeyValue(x, y, colors.toolbarKeyText, colors.toolbarValueText, "Уровень света", tostring(model.lightLevel), widthOfToolbar - 4); y = y + 1
y = y + 1
printKeyValue(x, y, ecs.colors.blue, colors.toolbarValueText, "Состояние", modes[currentMode], widthOfToolbar - 4); y = y + 1
y = y + 1
addButton(y, colors.toolbarButtonBackground, colors.toolbarButtonText, "Изменить параметры"); y = y + 4
addButton(y, colors.toolbarButtonBackground, colors.toolbarButtonText, "Напечатать"); y = y + 4
toolBarInfoLine(y, "Управление элементом " .. currentShape); y = y + 2
printKeyValue(x, y, colors.toolbarKeyText, colors.toolbarValueText, "Текстура", tostring(currentTexture), widthOfToolbar - 4); y = y + 1
printKeyValue(x, y, colors.toolbarKeyText, colors.toolbarValueText, "Оттенок", ecs.HEXtoString(currentTint, 6, true), widthOfToolbar - 4); y = y + 1
printKeyValue(x, y, colors.toolbarKeyText, colors.toolbarValueText, "Использовать оттенок", tostring(useTint), widthOfToolbar - 4); y = y + 1
printKeyValue(x, y, colors.toolbarKeyText, colors.toolbarValueText, "Позиция", getShapeCoords(), widthOfToolbar - 4); y = y + 2
addButton(y, colors.toolbarButtonBackground, colors.toolbarButtonText, "Изменить параметры "); y = y + 4
--Элементы
toolBarInfoLine(y, "Выбор элемента"); y = y + 2
drawShapeNumbers(x, y)
y = y + 8
end
local function drawTopMenu(selected)
obj["TopMenu"] = ecs.drawTopMenu(1, 1, xSize - widthOfToolbar, colors.toolbarBackground, selected, {"Файл", 0x262626}, {"Проектор", 0x262626}, {"О программе", 0x262626})
end
local function renderCurrentLayerOnHologram(xStart, yStart, zStart)
if showLayerOnHologram then
for i = yStart, yStart + 16 do
component.hologram.set(xStart - 1, i, zStart + (16 - currentLayer), 3)
component.hologram.set(xStart + 16, i, zStart + (16 - currentLayer), 3)
end
for i = (xStart-1), (xStart + 16) do
component.hologram.set(i, yStart - 1, zStart + (16 - currentLayer), 3)
component.hologram.set(i, yStart + 16, zStart + (16 - currentLayer), 3)
end
end
end
local function drawModelOnHologram()
if hologramAvailable then
local xStart, yStart, zStart = 16,4,16
component.hologram.clear()
for shape in pairs(model.shapes) do
if (currentMode == 2 and model.shapes[shape].state) or (currentMode == 1 and not model.shapes[shape].state) then
if model.shapes[shape] then
for x = model.shapes[shape][1], model.shapes[shape][4] - 1 do
for y = model.shapes[shape][2], model.shapes[shape][5] - 1 do
for z = model.shapes[shape][3], model.shapes[shape][6] - 1 do
--Эта хуйня для того, чтобы в разных режимах не ебало мозг
if (model.shapes[shape].state and currentMode == 2) or (not model.shapes[shape].state and currentMode == 1) then
if shape == currentShape then
component.hologram.set(xStart + x, yStart + y, zStart + 15 - z, 2)
else
component.hologram.set(xStart + x, yStart + y, zStart + 15 - z, 1)
end
end
end
end
end
end
end
end
renderCurrentLayerOnHologram(xStart, yStart, zStart)
end
end
local function printModel(count)
printer.reset()
printer.setLabel(model.label)
printer.setTooltip(model.tooltip)
printer.setCollidable(model.collidable[1], model.collidable[2])
printer.setLightLevel(model.lightLevel)
printer.setRedstoneEmitter(model.emitRedstone)
printer.setButtonMode(model.buttonMode)
for i in pairs(model.shapes) do
printer.addShape(
model.shapes[i][1],
(model.shapes[i][2]),
(model.shapes[i][3]),
model.shapes[i][4],
(model.shapes[i][5]),
(model.shapes[i][6]),
model.shapes[i].texture,
model.shapes[i].state,
model.shapes[i].tint
)
end
local success, reason = printer.commit(count)
if not success then
ecs.error("Ошибка печати: " .. reason)
end
end
local function drawPixel(x, y, width, height, color, trasparency)
buffer.square(xDrawingZone + x * pixelWidth - pixelWidth, yDrawingZone + y * pixelHeight - pixelHeight, width * pixelWidth, height * pixelHeight, color, 0xFFFFFF, " ", trasparency)
end
local function setka()
drawPixel(1, 1, 16, 16, colors.drawingZoneBackground)
local shade = colors.drawingZoneBackground - 0x111111
for j = 1, 16 do
for i = 1, 16 do
if j % 2 == 0 then
if i % 2 == 0 then
drawPixel(i, j, 1, 1, shade)
end
else
if i % 2 ~= 0 then
drawPixel(i, j, 1, 1, shade)
end
end
end
end
end
local function drawDrawingZone()
setka()
local selectionStartPoint = {}
local selectionEndPoint = {}
local trasparency = 70
for shape in pairs(model.shapes) do
--Если по состояниям все заебок
if ((model.shapes[shape].state and currentMode == 2) or (not model.shapes[shape].state and currentMode == 1)) then
selectionStartPoint.x = model.shapes[shape][1] + 1
selectionStartPoint.y = model.shapes[shape][2] + 1
selectionStartPoint.z = model.shapes[shape][3] + 1
selectionEndPoint.x = model.shapes[shape][4]
selectionEndPoint.y = model.shapes[shape][5]
selectionEndPoint.z = model.shapes[shape][6]
local yDifference = selectionEndPoint.y - selectionStartPoint.y + 1
if currentLayer >= selectionStartPoint.z and currentLayer <= selectionEndPoint.z then
if shape ~= currentShape then
local h, s, b = color.IntegerToHSB(shapeColors[shape])
s = 0.3
-- ecs.error("РИСУЮ")
drawPixel(selectionStartPoint.x, 18 - selectionStartPoint.y - yDifference, selectionEndPoint.x - selectionStartPoint.x + 1, yDifference, color.HSBToInteger(h, s, b))
-- drawPixel(selectionStartPoint.x, selectionStartPoint.z, selectionEndPoint.x - selectionStartPoint.x + 1, selectionEndPoint.z - selectionStartPoint.z + 1, shapeColors[shape], trasparency)
else
drawPixel(selectionStartPoint.x, 18 - selectionStartPoint.y - yDifference, selectionEndPoint.x - selectionStartPoint.x + 1, yDifference, shapeColors[shape])
--Точки
if selectionStartPoint.z == currentLayer then
drawPixel(selectionStartPoint.x, 17 - selectionStartPoint.y, 1, 1, colors.drawingZoneStartPoint)
end
if selectionEndPoint.z == currentLayer then
drawPixel(selectionEndPoint.x, 17 - selectionEndPoint.y, 1, 1, colors.drawingZoneEndPoint)
end
end
end
end
end
end
local function drawAll()
buffer.square(1, 2, xSize, ySize, colors.drawingZoneCYKA, 0xFFFFFF, " ")
drawDrawingZone()
drawToolbar()
buffer.draw()
drawTopMenu(0)
end
local function save(path)
fs.makeDirectory(fs.path(path) or "")
local file = io.open(path, "w")
file:write(serialization.serialize(model))
file:close()
end
local function open(path)
if fs.exists(path) then
if ecs.getFileFormat(path) == ".3dm" then
local file = io.open(path, "r")
model = serialization.unserialize(file:read("*a"))
fixModelArray()
file:close()
drawAll()
drawModelOnHologram()
else
ecs.error("Файл имеет неизвестный формат. Поддерживаются только модели в формате .3dm.")
end
else
ecs.error("Файл \"" .. path .. "\" не существует")
end
end
------------------------------------------------------------------------------------------------------------------------
model = {}
fixModelArray()
local args = {...}
if args[1] and fs.exists(args[1]) then
open(args[1])
end
drawAll()
drawModelOnHologram()
------------------------------------------------------------------------------------------------------------------------
local startPointSelected = false
local xShapeStart, yShapeStart, zShapeStart, xShapeEnd, yShapeEnd, zShapeEnd
while true do
local e = { event.pull() }
if e[1] == "touch" then
--Если кликнули в зону рисования
if ecs.clickedAtArea(e[3], e[4], xDrawingZone, yDrawingZone, xDrawingZone + drawingZoneWidth - 1, yDrawingZone + drawingZoneHeight - 1) then
if not startPointSelected then
xShapeStart = math.ceil((e[3] - xDrawingZone + 1) / pixelWidth)
yShapeStart = math.ceil((e[4] - yDrawingZone + 1) / pixelHeight)
zShapeStart = currentLayer
startPointSelected = true
model.shapes[currentShape] = nil
-- buffer.square(xDrawingZone, yDrawingZone, drawingZoneWidth, drawingZoneHeight, colors.drawingZoneBackground, 0xFFFFFF, " ")
drawPixel(xShapeStart, yShapeStart, 1, 1, colors.drawingZoneStartPoint)
buffer.draw()
else
xShapeEnd = math.ceil((e[3] - xDrawingZone + 1) / pixelWidth)
yShapeEnd = math.ceil((e[4] - yDrawingZone + 1) / pixelHeight)
zShapeEnd = currentLayer
drawPixel(xShapeEnd, yShapeEnd, 1, 1, colors.drawingZoneEndPoint)
startPointSelected = false
model.shapes[currentShape] = {
xShapeStart - 1,
17 - yShapeStart - 1,
zShapeStart - 1,
xShapeEnd,
17 - yShapeEnd,
zShapeEnd,
texture = currentTexture,
}
model.shapes[currentShape].state = nil
model.shapes[currentShape].tint = nil
if currentMode == 2 then model.shapes[currentShape].state = true end
if useTint then model.shapes[currentShape].tint = currentTint end
correctShapeCoords(currentShape)
drawAll()
drawModelOnHologram()
end
else
for key in pairs(obj.ShapeNumbers) do
if ecs.clickedAtArea(e[3], e[4], obj.ShapeNumbers[key][1], obj.ShapeNumbers[key][2], obj.ShapeNumbers[key][3], obj.ShapeNumbers[key][4]) then
currentShape = key
loadShapeParameters()
drawAll()
drawModelOnHologram()
break
end
end
for key in pairs(obj.ToolbarButtons) do
if ecs.clickedAtArea(e[3], e[4], obj.ToolbarButtons[key][1], obj.ToolbarButtons[key][2], obj.ToolbarButtons[key][3], obj.ToolbarButtons[key][4]) then
buffer.button(obj.ToolbarButtons[key][1], obj.ToolbarButtons[key][2], widthOfToolbar - 4, 3, ecs.colors.blue, 0xFFFFFF, key)
buffer.draw()
os.sleep(0.2)
if key == "Напечатать" then
local data = ecs.universalWindow("auto", "auto", 36, 0x262626, true,
{"EmptyLine"},
{"CenterText", ecs.colors.orange, "Напечатать"},
{"EmptyLine"},
{"Slider", 0xFFFFFF, ecs.colors.orange, 1, 64, 1, "", " штук"},
{"EmptyLine"},
{"Button", {ecs.colors.orange, 0xffffff, "OK"}, {0x999999, 0xffffff, "Отмена"}}
)
if data[2] == "OK" then
printModel(data[1])
end
elseif key == "Изменить параметры" then
local data = ecs.universalWindow("auto", "auto", 36, 0x262626, true,
{"EmptyLine"},
{"CenterText", ecs.colors.orange, "Параметры модели"},
{"EmptyLine"},
{"Input", 0xFFFFFF, ecs.colors.orange, model.label},
{"Input", 0xFFFFFF, ecs.colors.orange, model.tooltip},
{"Selector", 0xFFFFFF, ecs.colors.orange, "Неактивная", "Активная"},
{"EmptyLine"},
{"Switch", ecs.colors.orange, 0xffffff, 0xFFFFFF, "Как кнопка", model.buttonMode},
{"EmptyLine"},
{"Switch", ecs.colors.orange, 0xffffff, 0xFFFFFF, "Редстоун-сигнал", model.emitRedstone},
{"EmptyLine"},
{"Switch", ecs.colors.orange, 0xffffff, 0xFFFFFF, "Коллизия", model.collidable[currentMode]},
{"EmptyLine"},
{"Slider", 0xFFFFFF, ecs.colors.orange, 0, 15, model.lightLevel, "Уровень света: ", ""},
{"EmptyLine"},
{"Button", {ecs.colors.orange, 0xffffff, "OK"}, {0x999999, 0xffffff, "Отмена"}}
)
if data[8] == "OK" then
model.label = data[1] or "Sample label"
model.tooltip = data[2] or "Sample tooltip"
if data[3] == "Активная" then
currentMode = 2
else
currentMode = 1
end
model.buttonMode = data[4]
model.emitRedstone = data[5]
model.collidable[currentMode] = data[6]
model.lightLevel = data[7]
end
elseif key == "Изменить параметры " then
local data = ecs.universalWindow("auto", "auto", 36, 0x262626, true,
{"EmptyLine"},
{"CenterText", ecs.colors.orange, "Параметры элемента"},
{"EmptyLine"},
{"Input", 0xFFFFFF, ecs.colors.orange, currentTexture},
{"Color", "Оттенок", currentTint},
{"EmptyLine"},
{"Switch", ecs.colors.orange, 0xffffff, 0xFFFFFF, "Использовать оттенок", useTint},
{"EmptyLine"},
{"Button", {ecs.colors.orange, 0xffffff, "OK"}, {0x999999, 0xffffff, "Отмена"}}
)
if data[4] == "OK" then
currentTexture = data[1]
currentTint = data[2]
useTint = data[3]
if model.shapes[currentShape] then
model.shapes[currentShape].texture = currentTexture
if useTint then
model.shapes[currentShape].tint = currentTint
else
model.shapes[currentShape].tint = nil
end
end
end
end
drawAll()
drawModelOnHologram()
break
end
end
for key in pairs(obj.TopMenu) do
if ecs.clickedAtArea(e[3], e[4], obj.TopMenu[key][1], obj.TopMenu[key][2], obj.TopMenu[key][3], obj.TopMenu[key][4]) then
drawTopMenu(obj.TopMenu[key][5])
-- buffer.button(obj.TopMenu[key][1] - 1, obj.TopMenu[key][2], unicode.len(key) + 2, 1, ecs.colors.blue, 0xFFFFFF, key)
-- buffer.draw()
local action
if key == "Файл" then
action = context.menu(obj.TopMenu[key][1] - 1, obj.TopMenu[key][2] + 1, {"Новый"}, "-", {"Открыть"}, {"Сохранить"}, "-", {"Выход"})
elseif key == "Проектор" then
action = context.menu(obj.TopMenu[key][1] - 1, obj.TopMenu[key][2] + 1, {"Масштаб", not hologramAvailable}, {"Отступ проекции", not hologramAvailable}, {"Изменить палитру", not hologramAvailable}, "-", {"Включить показ слоя", not hologramAvailable}, {"Отключить показ слоя", not hologramAvailable}, "-", {"Включить вращение", not hologramAvailable}, {"Отключить вращение", not hologramAvailable})
elseif key == "О программе" then
ecs.universalWindow("auto", "auto", 36, 0x262626, true,
{"EmptyLine"},
{"CenterText", ecs.colors.orange, "3DPrint v3.0"},
{"EmptyLine"},
{"CenterText", 0xFFFFFF, "Автор:"},
{"CenterText", 0xBBBBBB, "Тимофеев Игорь"},
{"CenterText", 0xBBBBBB, "vk.com/id7799889"},
{"EmptyLine"},
{"CenterText", 0xFFFFFF, "Тестеры:"},
{"CenterText", 0xBBBBBB, "Семёнов Сeмён"},
{"CenterText", 0xBBBBBB, "vk.com/day_z_utes"},
{"CenterText", 0xBBBBBB, "Бесфамильный Яков"},
{"CenterText", 0xBBBBBB, "vk.com/mathem"},
{"CenterText", 0xBBBBBB, "Егор Палиев"},
{"CenterText", 0xBBBBBB, "vk.com/mrherobrine"},
{"EmptyLine"},
{"Button", {ecs.colors.orange, 0xffffff, "OK"}}
)
end
if action == "Сохранить" then
local data = ecs.universalWindow("auto", "auto", 30, 0x262626, true,
{"EmptyLine"},
{"CenterText", ecs.colors.orange, "Сохранить как"},
{"EmptyLine"},
{"Input", 0xFFFFFF, ecs.colors.orange, "Путь"},
{"Selector", 0xFFFFFF, ecs.colors.orange, ".3dm"},
{"EmptyLine"},
{"Button", {ecs.colors.orange, 0xffffff, "OK"}, {0x999999, 0xffffff, "Отмена"}}
)
if data[3] == "OK" then
data[1] = data[1] or "Untitled"
local filename = data[1] .. data[2]
save(filename)
end
elseif action == "Открыть" then
local data = ecs.universalWindow("auto", "auto", 30, 0x262626, true,
{"EmptyLine"},
{"CenterText", ecs.colors.orange, "Открыть"},
{"EmptyLine"},
{"Input", 0xFFFFFF, ecs.colors.orange, "Путь"},
{"EmptyLine"},
{"Button", {ecs.colors.orange, 0xffffff, "OK"}, {0x999999, 0xffffff, "Отмена"}}
)
if data[2] == "OK" then
open(data[1])
end
elseif action == "Новый" then
model = {}
fixModelArray()
drawAll()
drawModelOnHologram()
elseif action == "Выход" then
gpu.setResolution(xOld, yOld)
buffer.flush()
buffer.draw(true)
if hologramAvailable then component.hologram.clear() end
return
elseif action == "Масштаб" then
local data = ecs.universalWindow("auto", "auto", 36, 0x262626, true,
{"EmptyLine"},
{"CenterText", ecs.colors.orange, "Изменить масштаб"},
{"EmptyLine"},
{"Slider", ecs.colors.white, ecs.colors.orange, 1, 100, math.ceil(component.hologram.getScale() * 100 / 4), "", "%"},
{"EmptyLine"},
{"Button", {ecs.colors.orange, 0xffffff, "OK"}, {0x999999, 0xffffff, "Отмена"}}
)
if data[2] == "OK" then
component.hologram.setScale(data[1] * 4 / 100)
end
elseif action == "Отступ проекции" then
local translation = { component.hologram.getTranslation() }
local data = ecs.universalWindow("auto", "auto", 36, 0x262626, true,
{"EmptyLine"},
{"CenterText", ecs.colors.orange, "Отступ проекции"},
{"EmptyLine"},
{"CenterText", 0xFFFFFF, "Эти параметры позволяют проецировать"},
{"CenterText", 0xFFFFFF, "голограмму на некотором расстоянии от"},
{"CenterText", 0xFFFFFF, "проектора. Удобно, если вы хотите спрятать"},
{"CenterText", 0xFFFFFF, "проектор от чужих глаз."},
{"EmptyLine"},
{"Slider", 0xFFFFFF, ecs.colors.orange, 1, 100, translation[1] * 100, "Ось X: ", "%"},
{"Slider", 0xFFFFFF, ecs.colors.orange, 1, 100, translation[2] * 100, "Ось Y: ", "%"},
{"Slider", 0xFFFFFF, ecs.colors.orange, 1, 100, translation[3] * 100, "Ось Z: ", "%"},
{"EmptyLine"},
{"Button", {ecs.colors.orange, 0xffffff, "OK"}, {0x999999, 0xffffff, "Отмена"}}
)
if data[4] == "OK" then
component.hologram.setTranslation(data[1] / 100, data[2] / 100, data[3] / 100)
end
elseif action == "Изменить палитру" then
local data = ecs.universalWindow("auto", "auto", 36, 0x262626, true,
{"EmptyLine"},
{"CenterText", ecs.colors.orange, "Палитра проектора"},
{"EmptyLine"},
{"Color", "Цвет активного элемента", component.hologram.getPaletteColor(2)},
{"Color", "Цвет других элементов", component.hologram.getPaletteColor(1)},
{"Color", "Цвет рамки высоты", component.hologram.getPaletteColor(3)},
{"EmptyLine"},
{"Button", {ecs.colors.orange, 0xffffff, "OK"}, {0x999999, 0xffffff, "Отмена"}}
)
if data[4] == "OK" then
component.hologram.setPaletteColor(2, data[1])
component.hologram.setPaletteColor(1, data[2])
component.hologram.setPaletteColor(3, data[3])
end
elseif action == "Включить показ слоя" then
showLayerOnHologram = true
drawModelOnHologram()
elseif action == "Отключить показ слоя" then
showLayerOnHologram = false
drawModelOnHologram()
elseif action == "Включить вращение" then
component.hologram.setRotationSpeed(15, 0, 23, 0)
elseif action == "Отключить вращение" then
component.hologram.setRotationSpeed(0, 0, 0, 0)
end
drawTopMenu(0)
end
end
end
elseif e[1] == "scroll" then
if e[5] == 1 then
if currentLayer < 16 then
currentLayer = currentLayer + 1
drawAll()
drawModelOnHologram()
end
else
if currentLayer > 1 then
currentLayer = currentLayer - 1
drawAll()
drawModelOnHologram()
end
end
end
end

View File

@ -0,0 +1 @@
Это профессиональный инструмент для создания и распечатки моделей на 3D-принтере. Поддерживает все возможные функции принтера без исключения. Для работы требуется сам принтер и, по желанию, голографический проектор 2 уровня.

View File

@ -0,0 +1,539 @@
-------------------------------------------------------- Libraries --------------------------------------------------------
-- package.loaded["GUI"] = nil
-- package.loaded["doubleBuffering"] = nil
-- package.loaded["vector"] = nil
-- package.loaded["OpenComputersGL/Main"] = nil
-- package.loaded["OpenComputersGL/Materials"] = nil
-- package.loaded["OpenComputersGL/Renderer"] = nil
-- package.loaded["MeowEngine/Main"] = nil
local color = require("color")
local computer = require("computer")
local buffer = require("doubleBuffering")
local event = require("event")
local GUI = require("GUI")
local vector = require("vector")
local materials = require("OpenComputersGL/Materials")
local renderer = require("OpenComputersGL/Renderer")
local OCGL = require("OpenComputersGL/Main")
local meowEngine = require("MeowEngine/Main")
---------------------------------------------- Anus preparing ----------------------------------------------
-- /MineOS/Desktop/3DTest.app/3DTest.lua
buffer.flush()
meowEngine.intro(vector.newVector3(0, 0, 0), 20)
local mainContainer = GUI.fullScreenContainer()
local scene = meowEngine.newScene(0x1D1D1D)
scene.renderMode = OCGL.renderModes.flatShading
scene.auxiliaryMode = OCGL.auxiliaryModes.disabled
scene.camera:translate(-2.5, 8.11, -19.57)
scene.camera:rotate(math.rad(30), 0, 0)
scene:addLight(meowEngine.newLight(vector.newVector3(0, 20, 0), 1.0, 200))
---------------------------------------------- Constants ----------------------------------------------
local blockSize = 5
local rotationAngle = math.rad(5)
local translationOffset = 1
---------------------------------------------- Voxel-world system ----------------------------------------------
local world = {{{}}}
local worldMesh = scene:addObject(
meowEngine.newMesh(
vector.newVector3(0, 0, 0), { }, { },
materials.newSolidMaterial(0xFF00FF)
)
)
local function checkBlock(x, y, z)
if world[z] and world[z][y] and world[z][y][x] then
return true
end
return false
end
local function setBlock(x, y, z, value)
world[z] = world[z] or {}
world[z][y] = world[z][y] or {}
world[z][y][x] = value
end
local blockSides = {
front = 1,
left = 2,
back = 3,
right = 4,
up = 5,
down = 6
}
local function renderWorld()
worldMesh.vertices = {}
worldMesh.triangles = {}
for z in pairs(world) do
for y in pairs(world[z]) do
for x in pairs(world[z][y]) do
local firstVertexIndex = #worldMesh.vertices + 1
local xBlock, yBlock, zBlock = (x - 1) * blockSize, (y - 1) * blockSize, (z - 1) * blockSize
local material = materials.newSolidMaterial(world[z][y][x])
table.insert(worldMesh.vertices, vector.newVector3(xBlock, yBlock, zBlock))
table.insert(worldMesh.vertices, vector.newVector3(xBlock, yBlock + blockSize, zBlock))
table.insert(worldMesh.vertices, vector.newVector3(xBlock + blockSize, yBlock + blockSize, zBlock))
table.insert(worldMesh.vertices, vector.newVector3(xBlock + blockSize, yBlock, zBlock))
table.insert(worldMesh.vertices, vector.newVector3(xBlock, yBlock, zBlock + blockSize))
table.insert(worldMesh.vertices, vector.newVector3(xBlock, yBlock + blockSize, zBlock + blockSize))
table.insert(worldMesh.vertices, vector.newVector3(xBlock + blockSize, yBlock + blockSize, zBlock + blockSize))
table.insert(worldMesh.vertices, vector.newVector3(xBlock + blockSize, yBlock, zBlock + blockSize))
-- Front (1, 2)
if not checkBlock(x, y, z - 1) then
table.insert(worldMesh.triangles, OCGL.newIndexedTriangle(firstVertexIndex, firstVertexIndex + 1, firstVertexIndex + 2, material))
table.insert(worldMesh.triangles, OCGL.newIndexedTriangle(firstVertexIndex + 3, firstVertexIndex, firstVertexIndex + 2, material))
end
-- Left (3, 4)
if not checkBlock(x - 1, y, z) then
table.insert(worldMesh.triangles, OCGL.newIndexedTriangle(firstVertexIndex + 5, firstVertexIndex + 1, firstVertexIndex + 4, material))
table.insert(worldMesh.triangles, OCGL.newIndexedTriangle(firstVertexIndex + 1, firstVertexIndex, firstVertexIndex + 4, material))
end
-- Back (5, 6)
if not checkBlock(x, y, z + 1) then
table.insert(worldMesh.triangles, OCGL.newIndexedTriangle(firstVertexIndex + 6, firstVertexIndex + 5, firstVertexIndex + 7, material))
table.insert(worldMesh.triangles, OCGL.newIndexedTriangle(firstVertexIndex + 5, firstVertexIndex + 4, firstVertexIndex + 7, material))
end
-- Right (7, 8)
if not checkBlock(x + 1, y, z) then
table.insert(worldMesh.triangles, OCGL.newIndexedTriangle(firstVertexIndex + 3, firstVertexIndex + 2, firstVertexIndex + 6, material))
table.insert(worldMesh.triangles, OCGL.newIndexedTriangle(firstVertexIndex + 7, firstVertexIndex + 3, firstVertexIndex + 6, material))
end
-- Up (9, 10)
if not checkBlock(x, y + 1, z) then
table.insert(worldMesh.triangles, OCGL.newIndexedTriangle(firstVertexIndex + 1, firstVertexIndex + 5, firstVertexIndex + 6, material))
table.insert(worldMesh.triangles, OCGL.newIndexedTriangle(firstVertexIndex + 2, firstVertexIndex + 1, firstVertexIndex + 6, material))
end
-- Down (11, 12)
if not checkBlock(x, y - 1, z) then
table.insert(worldMesh.triangles, OCGL.newIndexedTriangle(firstVertexIndex + 4, firstVertexIndex, firstVertexIndex + 7, material))
table.insert(worldMesh.triangles, OCGL.newIndexedTriangle(firstVertexIndex, firstVertexIndex + 3, firstVertexIndex + 7, material))
end
end
end
end
end
-- Mode 1
local hue, hueStep = 0, 360 / 9
for z = -1, 1 do
for x = -1, 1 do
if not (x == 0 and z == 0) then
setBlock(x, 0, z, color.HSBToInteger(hue, 1, 1))
hue = hue + hueStep
end
end
end
-- -- Mode 2
-- for z = 1, 7 do
-- for x = -3, 3 do
-- setBlock(x, 0, z, 0xFFFFFF)
-- end
-- end
---------------------------------------------- Cat ----------------------------------------------
-- scene:addObject(meowEngine.newPolyCatMesh(vector.newVector3(0, 5, 0), 5))
-- scene:addObject(meowEngine.newFloatingText(vector.newVector3(0, -2, 0), 0xEEEEEE, "Тест плавающего текста"))
---------------------------------------------- Texture ----------------------------------------------
-- scene.camera:translate(0, 20, 0)
-- scene.camera:rotate(math.rad(90), 0, 0)
-- local texturedPlane = scene:addObject(meowEngine.newTexturedPlane(vector.newVector3(0, 0, 0), 20, 20, materials.newDebugTexture(16, 16, 40)))
---------------------------------------------- Wave ----------------------------------------------
-- local xCells, yCells = 4, 1
-- local plane = meowEngine.newPlane(vector.newVector3(0, 0, 0), 40, 15, xCells, yCells, materials.newSolidMaterial(0xFFFFFF))
-- plane.nextWave = function(mesh)
-- for xCell = 1, xCells do
-- for yCell = 1, yCells do
-- end
-- end
-- end
---------------------------------------------- Fractal field ----------------------------------------------
-- local function createField(vector3Position, xCellCount, yCellCount, cellSize)
-- local totalWidth, totalHeight = xCellCount * cellSize, yCellCount * cellSize
-- local halfWidth, halfHeight = totalWidth / 2, totalHeight / 2
-- xCellCount, yCellCount = xCellCount + 1, yCellCount + 1
-- local vertices, triangles = {}, {}
-- local vertexIndex = 1
-- for yCell = 1, yCellCount do
-- for xCell = 1, xCellCount do
-- table.insert(vertices, vector.newVector3(xCell * cellSize - cellSize - halfWidth, yCell * cellSize - cellSize - halfHeight, 0))
-- if xCell < xCellCount and yCell < yCellCount then
-- table.insert(triangles,
-- OCGL.newIndexedTriangle(
-- vertexIndex,
-- vertexIndex + 1,
-- vertexIndex + xCellCount
-- )
-- )
-- table.insert(triangles,
-- OCGL.newIndexedTriangle(
-- vertexIndex + 1,
-- vertexIndex + xCellCount + 1,
-- vertexIndex + xCellCount
-- )
-- )
-- end
-- vertexIndex = vertexIndex + 1
-- end
-- end
-- local mesh = meowEngine.newMesh(vector3Position, vertices, triangles,materials.newSolidMaterial(0xFF8888))
-- local function getRandomSignedInt(from, to)
-- return (math.random(0, 1) == 1 and 1 or -1) * (math.random(from, to))
-- end
-- local function getRandomDirection()
-- return getRandomSignedInt(5, 100) / 100
-- end
-- mesh.randomizeTrianglesColor = function(mesh, hueChangeSpeed, brightnessChangeSpeed, minimumBrightness)
-- mesh.hue = mesh.hue and mesh.hue + hueChangeSpeed or math.random(0, 360)
-- if mesh.hue > 359 then mesh.hue = 0 end
-- for triangleIndex = 1, #mesh.triangles do
-- mesh.triangles[triangleIndex].brightness = mesh.triangles[triangleIndex].brightness and mesh.triangles[triangleIndex].brightness + getRandomSignedInt(1, brightnessChangeSpeed) or math.random(minimumBrightness, 100)
-- if mesh.triangles[triangleIndex].brightness > 100 then
-- mesh.triangles[triangleIndex].brightness = 100
-- elseif mesh.triangles[triangleIndex].brightness < minimumBrightness then
-- mesh.triangles[triangleIndex].brightness = minimumBrightness
-- end
-- mesh.triangles[triangleIndex][4] = materials.newSolidMaterial(color.HSBToInteger(mesh.hue, 1, mesh.triangles[triangleIndex].brightness))
-- end
-- end
-- mesh.randomizeVerticesPosition = function(mesh, speed)
-- local vertexIndex = 1
-- for yCell = 1, yCellCount do
-- for xCell = 1, xCellCount do
-- if xCell > 1 and xCell < xCellCount and yCell > 1 and yCell < yCellCount then
-- mesh.vertices[vertexIndex].offset = mesh.vertices[vertexIndex].offset or {0, 0}
-- mesh.vertices[vertexIndex].direction = mesh.vertices[vertexIndex].direction or {getRandomDirection(), getRandomDirection()}
-- local newOffset = {
-- mesh.vertices[vertexIndex].direction[1] * (speed * cellSize),
-- mesh.vertices[vertexIndex].direction[1] * (speed * cellSize)
-- }
-- for i = 1, 2 do
-- if math.abs(mesh.vertices[vertexIndex].offset[i] + newOffset[i]) < cellSize / 2 then
-- mesh.vertices[vertexIndex].offset[i] = mesh.vertices[vertexIndex].offset[i] + newOffset[i]
-- mesh.vertices[vertexIndex][i] = mesh.vertices[vertexIndex][i] + newOffset[i]
-- else
-- mesh.vertices[vertexIndex].direction[i] = getRandomDirection()
-- end
-- end
-- end
-- vertexIndex = vertexIndex + 1
-- end
-- end
-- end
-- return mesh
-- end
-- local plane = createField(vector.newVector3(0, 0, 0), 8, 4, 4)
-- scene:addObject(plane)
-- plane:randomizeTrianglesColor(10, 10, 50)
-------------------------------------------------------- Controls --------------------------------------------------------
local function move(x, y, z)
local moveVector = vector.newVector3(x, y, z)
OCGL.rotateVectorRelativeToXAxis(moveVector, scene.camera.rotation[1])
OCGL.rotateVectorRelativeToYAxis(moveVector, scene.camera.rotation[2])
scene.camera:translate(moveVector[1], moveVector[2], moveVector[3])
end
local function moveLight(x, y, z)
scene.lights[mainContainer.toolbar.lightSelectComboBox.selectedItem].position[1] = scene.lights[mainContainer.toolbar.lightSelectComboBox.selectedItem].position[1] + x
scene.lights[mainContainer.toolbar.lightSelectComboBox.selectedItem].position[2] = scene.lights[mainContainer.toolbar.lightSelectComboBox.selectedItem].position[2] + y
scene.lights[mainContainer.toolbar.lightSelectComboBox.selectedItem].position[3] = scene.lights[mainContainer.toolbar.lightSelectComboBox.selectedItem].position[3] + z
end
local controls = {
-- F1
[59 ] = function() mainContainer.toolbar.hidden = not mainContainer.toolbar.hidden; mainContainer.infoTextBox.hidden = not mainContainer.infoTextBox.hidden end,
-- Arrows
[200] = function() scene.camera:rotate(-rotationAngle, 0, 0) end,
[208] = function() scene.camera:rotate(rotationAngle, 0, 0) end,
[203] = function() scene.camera:rotate(0, -rotationAngle, 0) end,
[205] = function() scene.camera:rotate(0, rotationAngle, 0) end,
[16 ] = function() scene.camera:rotate(0, 0, rotationAngle) end,
[18 ] = function() scene.camera:rotate(0, 0, -rotationAngle) end,
-- WASD
[17 ] = function() move(0, 0, translationOffset) end,
[31 ] = function() move(0, 0, -translationOffset) end,
[30 ] = function() move(-translationOffset, 0, 0) end,
[32 ] = function() move(translationOffset, 0, 0) end,
-- RSHIFT, SPACE
[42 ] = function() move(0, -translationOffset, 0) end,
[57 ] = function() move(0, translationOffset, 0) end,
-- NUM 4 6 8 5 1 3
[75 ] = function() moveLight(-translationOffset, 0, 0) end,
[77 ] = function() moveLight(translationOffset, 0, 0) end,
[72 ] = function() moveLight(0, 0, translationOffset) end,
[80 ] = function() moveLight(0, 0, -translationOffset) end,
[79 ] = function() moveLight(0, -translationOffset, 0) end,
[81 ] = function() moveLight(0, translationOffset, 0) end,
}
-------------------------------------------------------- GUI --------------------------------------------------------
local OCGLView = GUI.object(1, 1, mainContainer.width, mainContainer.height)
local function drawInvertedText(x, y, text)
local index = buffer.getIndex(x, y)
local background, foreground = buffer.rawGet(index)
buffer.rawSet(index, background, 0xFFFFFF - foreground, text)
end
local function drawCross(x, y)
drawInvertedText(x - 2, y, "")
drawInvertedText(x - 1, y, "")
drawInvertedText(x + 2, y, "")
drawInvertedText(x + 1, y, "")
drawInvertedText(x, y - 1, "")
drawInvertedText(x, y + 1, "")
end
OCGLView.draw = function(object)
mainContainer.oldClock = os.clock()
if world then renderWorld() end
scene:render()
if mainContainer.toolbar.zBufferSwitch.state then
renderer.visualizeDepthBuffer()
end
drawCross(renderer.viewport.xCenter, math.floor(renderer.viewport.yCenter / 2))
end
OCGLView.eventHandler = function(mainContainer, object, eventData)
if eventData[1] == "touch" then
local targetVector = vector.newVector3(scene.camera.position[1], scene.camera.position[2], scene.camera.position[3] + 1000)
OCGL.rotateVectorRelativeToXAxis(targetVector, scene.camera.rotation[1])
OCGL.rotateVectorRelativeToYAxis(targetVector, scene.camera.rotation[2])
local objectIndex, triangleIndex, distance = meowEngine.sceneRaycast(scene, scene.camera.position, targetVector)
if objectIndex then
local triangle = scene.objects[objectIndex].triangles[triangleIndex]
local xWorld = math.floor(((scene.objects[objectIndex].vertices[scene.objects[objectIndex].triangles[triangleIndex][1]][1] + scene.objects[objectIndex].vertices[scene.objects[objectIndex].triangles[triangleIndex][2]][1] + scene.objects[objectIndex].vertices[scene.objects[objectIndex].triangles[triangleIndex][3]][1]) / 3) / blockSize) + 1
local yWorld = math.floor(((scene.objects[objectIndex].vertices[triangle[1]][2] + scene.objects[objectIndex].vertices[triangle[2]][2] + scene.objects[objectIndex].vertices[triangle[3]][2]) / 3) / blockSize) + 1
local zWorld = math.floor(((scene.objects[objectIndex].vertices[triangle[1]][3] + scene.objects[objectIndex].vertices[triangle[2]][3] + scene.objects[objectIndex].vertices[triangle[3]][3]) / 3) / blockSize) + 1
local normalVector = vector.getSurfaceNormal(
scene.objects[objectIndex].vertices[triangle[1]],
scene.objects[objectIndex].vertices[triangle[2]],
scene.objects[objectIndex].vertices[triangle[3]]
)
if normalVector[1] > 0 and eventData[5] ~= 1 or normalVector[1] < 0 and eventData[5] == 1 then
xWorld = xWorld - 1
elseif normalVector[2] > 0 and eventData[5] ~= 1 or normalVector[2] < 0 and eventData[5] == 1 then
yWorld = yWorld - 1
elseif normalVector[3] > 0 and eventData[5] ~= 1 or normalVector[3] < 0 and eventData[5] == 1 then
zWorld = zWorld - 1
end
setBlock(xWorld, yWorld, zWorld, eventData[5] == 1 and mainContainer.toolbar.blockColorSelector.color or nil)
end
end
end
mainContainer:addChild(OCGLView)
mainContainer.infoTextBox = mainContainer:addChild(GUI.textBox(2, 4, 45, mainContainer.height, nil, 0xEEEEEE, {}, 1, 0, 0))
local lines = {
"Copyright © 2016-2017 - Developed by ECS Inc.",
"Timofeef Igor (vk.com/id7799889), Trifonov Gleb (vk.com/id88323331), Verevkin Yakov (vk.com/id60991376), Bogushevich Victoria (vk.com/id171497518)",
"All rights reserved",
}
mainContainer:addChild(GUI.textBox(1, mainContainer.height - #lines + 1, mainContainer.width, #lines, nil, 0x3C3C3C, lines, 1)):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top)
local elementY = 2
mainContainer.toolbar = mainContainer:addChild(GUI.container(mainContainer.width - 31, 1, 32, mainContainer.height))
local elementWidth = mainContainer.toolbar.width - 2
mainContainer.toolbar:addChild(GUI.panel(1, 1, mainContainer.toolbar.width, mainContainer.toolbar.height, 0x0, 0.5))
mainContainer.toolbar:addChild(GUI.label(2, elementY, elementWidth, 1, 0xEEEEEE, "Render mode")):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top); elementY = elementY + 2
mainContainer.toolbar.renderModeComboBox = mainContainer.toolbar:addChild(GUI.comboBox(2, elementY, elementWidth, 1, 0x2D2D2D, 0xAAAAAA, 0x555555, 0x888888)); elementY = elementY + mainContainer.toolbar.renderModeComboBox.height + 1
mainContainer.toolbar.renderModeComboBox:addItem("disabled")
mainContainer.toolbar.renderModeComboBox:addItem("constantShading")
mainContainer.toolbar.renderModeComboBox:addItem("flatShading")
mainContainer.toolbar.renderModeComboBox.selectedItem = scene.renderMode
mainContainer.toolbar.renderModeComboBox.onItemSelected = function()
scene.renderMode = mainContainer.toolbar.renderModeComboBox.selectedItem
end
mainContainer.toolbar.auxiliaryModeComboBox = mainContainer.toolbar:addChild(GUI.comboBox(2, elementY, elementWidth, 1, 0x2D2D2D, 0xAAAAAA, 0x555555, 0x888888)); elementY = elementY + mainContainer.toolbar.auxiliaryModeComboBox.height + 1
mainContainer.toolbar.auxiliaryModeComboBox:addItem("disabled")
mainContainer.toolbar.auxiliaryModeComboBox:addItem("wireframe")
mainContainer.toolbar.auxiliaryModeComboBox:addItem("vertices")
mainContainer.toolbar.auxiliaryModeComboBox.selectedItem = scene.auxiliaryMode
mainContainer.toolbar.auxiliaryModeComboBox.onItemSelected = function()
scene.auxiliaryMode = mainContainer.toolbar.auxiliaryModeComboBox.selectedItem
end
mainContainer.toolbar:addChild(GUI.label(2, elementY, elementWidth, 1, 0xAAAAAA, "Perspective proj:"))
mainContainer.toolbar.perspectiveSwitch = mainContainer.toolbar:addChild(GUI.switch(mainContainer.toolbar.width - 8, elementY, 8, 0x66DB80, 0x2D2D2D, 0xEEEEEE, scene.camera.projectionEnabled)); elementY = elementY + 2
mainContainer.toolbar.perspectiveSwitch.onStateChanged = function()
scene.camera.projectionEnabled = mainContainer.toolbar.perspectiveSwitch.state
end
mainContainer.toolbar:addChild(GUI.label(2, elementY, elementWidth, 1, 0xAAAAAA, "Z-buffer visualize:"))
mainContainer.toolbar.zBufferSwitch = mainContainer.toolbar:addChild(GUI.switch(mainContainer.toolbar.width - 8, elementY, 8, 0x66DB80, 0x2D2D2D, 0xEEEEEE, false)); elementY = elementY + 2
local function calculateLightComboBox()
mainContainer.toolbar.lightSelectComboBox.dropDownMenu.itemsContainer.children = {}
for i = 1, #scene.lights do
mainContainer.toolbar.lightSelectComboBox:addItem(tostring(i))
end
mainContainer.toolbar.lightSelectComboBox.selectedItem = #mainContainer.toolbar.lightSelectComboBox.dropDownMenu.itemsContainer.children
mainContainer.toolbar.lightIntensitySlider.value = scene.lights[mainContainer.toolbar.lightSelectComboBox.selectedItem].intensity * 100
mainContainer.toolbar.lightEmissionSlider.value = scene.lights[mainContainer.toolbar.lightSelectComboBox.selectedItem].emissionDistance
end
mainContainer.toolbar:addChild(GUI.label(2, elementY, elementWidth, 1, 0xEEEEEE, "Light control")):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top); elementY = elementY + 2
mainContainer.toolbar.lightSelectComboBox = mainContainer.toolbar:addChild(GUI.comboBox(2, elementY, elementWidth, 1, 0x2D2D2D, 0xAAAAAA, 0x555555, 0x888888)); elementY = elementY + mainContainer.toolbar.lightSelectComboBox.height + 1
mainContainer.toolbar.addLightButton = mainContainer.toolbar:addChild(GUI.button(2, elementY, elementWidth, 1, 0x2D2D2D, 0xAAAAAA, 0x555555, 0xAAAAAA, "Add light")); elementY = elementY + 2
mainContainer.toolbar.addLightButton.onTouch = function()
scene:addLight(meowEngine.newLight(vector.newVector3(0, 10, 0), mainContainer.toolbar.lightIntensitySlider.value / 100, mainContainer.toolbar.lightEmissionSlider.value))
calculateLightComboBox()
end
mainContainer.toolbar.removeLightButton = mainContainer.toolbar:addChild(GUI.button(2, elementY, elementWidth, 1, 0x2D2D2D, 0xAAAAAA, 0x555555, 0xAAAAAA, "Remove light")); elementY = elementY + 2
mainContainer.toolbar.removeLightButton.onTouch = function()
if #scene.lights > 1 then
table.remove(scene.lights, mainContainer.toolbar.lightSelectComboBox.selectedItem)
calculateLightComboBox()
end
end
mainContainer.toolbar.lightIntensitySlider = mainContainer.toolbar:addChild(GUI.slider(2, elementY, elementWidth, 0xCCCCCC, 0x2D2D2D, 0xEEEEEE, 0xAAAAAA, 0, 500, 100, false, "Intensity: ", "")); elementY = elementY + 3
mainContainer.toolbar.lightIntensitySlider.onValueChanged = function()
scene.lights[mainContainer.toolbar.lightSelectComboBox.selectedItem].intensity = mainContainer.toolbar.lightIntensitySlider.value / 100
end
mainContainer.toolbar.lightEmissionSlider = mainContainer.toolbar:addChild(GUI.slider(2, elementY, elementWidth, 0xCCCCCC, 0x2D2D2D, 0xEEEEEE, 0xAAAAAA, 0, scene.lights[mainContainer.toolbar.lightSelectComboBox.selectedItem].emissionDistance, scene.lights[mainContainer.toolbar.lightSelectComboBox.selectedItem].emissionDistance, false, "Distance: ", "")); elementY = elementY + 3
mainContainer.toolbar.lightEmissionSlider.onValueChanged = function()
scene.lights[mainContainer.toolbar.lightSelectComboBox.selectedItem].emissionDistance = mainContainer.toolbar.lightEmissionSlider.value
end
calculateLightComboBox()
mainContainer.toolbar.blockColorSelector = mainContainer.toolbar:addChild(GUI.colorSelector(2, elementY, elementWidth, 1, 0xEEEEEE, "Block color")); elementY = elementY + mainContainer.toolbar.blockColorSelector.height + 1
mainContainer.toolbar.backgroundColorSelector = mainContainer.toolbar:addChild(GUI.colorSelector(2, elementY, elementWidth, 1, scene.backgroundColor, "Background color")); elementY = elementY + mainContainer.toolbar.blockColorSelector.height + 1
mainContainer.toolbar.backgroundColorSelector.onTouch = function()
scene.backgroundColor = mainContainer.toolbar.backgroundColorSelector.color
end
mainContainer.toolbar:addChild(GUI.label(2, elementY, elementWidth, 1, 0xEEEEEE, "RAM monitoring")):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top); elementY = elementY + 2
mainContainer.toolbar.RAMChart = mainContainer.toolbar:addChild(GUI.chart(2, elementY, elementWidth, mainContainer.toolbar.height - elementY - 3, 0xEEEEEE, 0xAAAAAA, 0x555555, 0x66DB80, 0.35, 0.25, "s", "%", true, {})); elementY = elementY + mainContainer.toolbar.RAMChart.height + 1
mainContainer.toolbar.RAMChart.roundValues = true
-- mainContainer.toolbar.RAMChart.showXAxisValues = false
mainContainer.toolbar.RAMChart.counter = 1
mainContainer.toolbar:addChild(GUI.button(1, mainContainer.toolbar.height - 2, mainContainer.toolbar.width, 3, 0x2D2D2D, 0xEEEEEE, 0x444444, 0xEEEEEE, "Exit")).onTouch = function()
mainContainer:stopEventHandling()
end
local FPSCounter = GUI.object(2, 2, 8, 3)
FPSCounter.draw = function(FPSCounter)
renderer.renderFPSCounter(FPSCounter.x, FPSCounter.y, tostring(math.ceil(1 / (os.clock() - mainContainer.oldClock) / 10)), 0xFFFF00)
end
mainContainer:addChild(FPSCounter)
mainContainer.eventHandler = function(mainContainer, object, eventData)
if not mainContainer.toolbar.hidden then
local totalMemory = computer.totalMemory()
table.insert(mainContainer.toolbar.RAMChart.values, {mainContainer.toolbar.RAMChart.counter, math.ceil((totalMemory - computer.freeMemory()) / totalMemory * 100)})
mainContainer.toolbar.RAMChart.counter = mainContainer.toolbar.RAMChart.counter + 1
if #mainContainer.toolbar.RAMChart.values > 20 then table.remove(mainContainer.toolbar.RAMChart.values, 1) end
mainContainer.infoTextBox.lines = {
" ",
"SceneObjects: " .. #scene.objects,
" ",
"OCGLVertices: " .. #OCGL.vertices,
"OCGLTriangles: " .. #OCGL.triangles,
"OCGLLines: " .. #OCGL.lines,
"OCGLFloatingTexts: " .. #OCGL.floatingTexts,
"OCGLLights: " .. #OCGL.lights,
" ",
"CameraFOV: " .. string.format("%.2f", math.deg(scene.camera.FOV)),
"СameraPosition: " .. string.format("%.2f", scene.camera.position[1]) .. " x " .. string.format("%.2f", scene.camera.position[2]) .. " x " .. string.format("%.2f", scene.camera.position[3]),
"СameraRotation: " .. string.format("%.2f", math.deg(scene.camera.rotation[1])) .. " x " .. string.format("%.2f", math.deg(scene.camera.rotation[2])) .. " x " .. string.format("%.2f", math.deg(scene.camera.rotation[3])),
"CameraNearClippingSurface: " .. string.format("%.2f", scene.camera.nearClippingSurface),
"CameraFarClippingSurface: " .. string.format("%.2f", scene.camera.farClippingSurface),
"CameraProjectionSurface: " .. string.format("%.2f", scene.camera.projectionSurface),
"CameraPerspectiveProjection: " .. tostring(scene.camera.projectionEnabled),
" ",
"Controls:",
" ",
"Arrows - camera rotation",
"WASD/Shift/Space - camera movement",
"LMB/RMB - destroy/place block",
"NUM 8/2/4/6/1/3 - selected light movement",
"F1 - toggle GUI overlay",
}
mainContainer.infoTextBox.height = #mainContainer.infoTextBox.lines
end
if eventData[1] == "key_down" then
if controls[eventData[4]] then controls[eventData[4]]() end
elseif eventData[1] == "scroll" then
if eventData[5] == 1 then
if scene.camera.FOV < math.rad(170) then
scene.camera:setFOV(scene.camera.FOV + math.rad(5))
end
else
if scene.camera.FOV > math.rad(5) then
scene.camera:setFOV(scene.camera.FOV - math.rad(5))
end
end
end
mainContainer:draw()
buffer.draw()
end
-------------------------------------------------------- Ebat-kopat --------------------------------------------------------
mainContainer:startEventHandling(0)

View File

@ -0,0 +1 @@
Программа-демонстратор возможностей 3D-движка, созданного специально для низкопроизводительных компьютеров. В ней воплощены практически все наработки нашей команды: от отрисовки сложных трехмерных объектов и динамического освещения до текстурирования и пользовательского интерфейса на мощной GUI-библиотеке.

View File

@ -0,0 +1,246 @@
require("advancedLua")
local component = require("component")
local computer = require("computer")
local image = require("image")
local buffer = require("doubleBuffering")
local GUI = require("GUI")
local fs = require("filesystem")
local unicode = require("unicode")
local web = require("web")
local MineOSPaths = require("MineOSPaths")
local MineOSCore = require("MineOSCore")
local MineOSInterface = require("MineOSInterface")
----------------------------------------------------------------------------------------------------------------
local applicationListURL = "https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications.cfg"
local applicationList
local localization = MineOSCore.getCurrentApplicationLocalization()
local resources = MineOSCore.getCurrentApplicationResourcesDirectory()
local updateImage = image.load(resources .. "Update.pic")
local appsPerPage = 6
local mainContainer, window = MineOSInterface.addWindow(MineOSInterface.tabbedWindow(1, 1, 80, 32))
----------------------------------------------------------------------------------------------------------------
local function newApp(x, y, width, applicationListElement, hideDownloadButton)
local app = GUI.container(x, y, width, 4)
app.icon = app:addChild(GUI.image(1, 1, MineOSInterface.iconsCache.script))
if applicationListElement.icon then
app.icon.image = MineOSCore.loadImageFromString(web.request(applicationListElement.icon))
end
app.downloadButton = app:addChild(GUI.roundedButton(1, 1, 13, 1, 0x66DB80, 0xFFFFFF, 0x339240, 0xFFFFFF, localization.download))
app.downloadButton.localX = app.width - app.downloadButton.width
app.downloadButton.onTouch = function()
app.downloadButton.disabled = true
app.downloadButton.colors.disabled.background, app.downloadButton.colors.disabled.text = 0xBBBBBB, 0xFFFFFF
app.downloadButton.text = localization.downloading
mainContainer:draw()
buffer.draw()
MineOSCore.downloadApplication(applicationListElement, MineOSCore.properties.language)
app.downloadButton.text = localization.downloaded
computer.pushSignal("MineOSCore", "updateFileList")
end
app.downloadButton.hidden = hideDownloadButton
app.pathLabel = app:addChild(GUI.label(app.icon.width + 3, 1, width - app.icon.width - app.downloadButton.width - 5, 1, 0x0, fs.name(applicationListElement.path)))
app.versionLabel = app:addChild(GUI.label(app.icon.width + 3, 2, app.pathLabel.width, 1, 0x555555, localization.version .. applicationListElement.version))
if applicationListElement.about then
local lines = string.wrap({web.request(applicationListElement.about .. MineOSCore.properties.language .. ".txt")}, app.pathLabel.width)
app.aboutTextBox = app:addChild(GUI.textBox(app.icon.width + 3, 3, app.pathLabel.width, #lines, nil, 0x999999, lines, 1, 0, 0))
app.aboutTextBox.eventHandler = nil
if #lines > 2 then
app.height = #lines + 2
end
end
return app
end
local function addUpdateImage()
window.contentContainer:deleteChildren()
local cyka = window.contentContainer:addChild(GUI.image(math.floor(window.contentContainer.width / 2 - image.getWidth(updateImage) / 2), math.floor(window.contentContainer.height / 2 - image.getHeight(updateImage) / 2) - 1, updateImage))
return cyka.localY + cyka.height + 2
end
local function updateApplicationList()
local y = addUpdateImage()
window.contentContainer:addChild(GUI.label(1, y, window.contentContainer.width, 1, 0x888888, localization.checkingForUpdates)):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top)
mainContainer:draw()
buffer.draw()
applicationList = table.fromString(web.request(applicationListURL))
end
local function displayApps(fromPage, typeFilter, nameFilter, updateCheck)
window.contentContainer:deleteChildren()
local y = 2
local finalApplicationList = {}
if updateCheck then
local oldApplicationList = table.fromFile(MineOSPaths.applicationList)
for j = 1, #applicationList do
local pathFound = false
for i = 1, #oldApplicationList do
if oldApplicationList[i].path == applicationList[j].path then
if oldApplicationList[i].version < applicationList[j].version then
table.insert(finalApplicationList, applicationList[j])
end
pathFound = true
break
end
end
if not pathFound then
table.insert(finalApplicationList, applicationList[j])
end
end
if #finalApplicationList == 0 then
window.contentContainer:addChild(GUI.label(1, 1, window.contentContainer.width, window.contentContainer.height, 0x888888, localization.youHaveNewestApps)):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.center)
mainContainer:draw()
buffer.draw()
return
else
window.contentContainer:addChild(GUI.roundedButton(math.floor(window.contentContainer.width / 2 - 9), y, 18, 1, 0xBBBBBB, 0xFFFFFF, 0x999999, 0xFFFFFF, localization.updateAll)).onTouch = function()
y = addUpdateImage()
local progressBarWidth = math.floor(window.contentContainer.width * 0.65)
local progressBar = window.contentContainer:addChild(GUI.progressBar(math.floor(window.contentContainer.width / 2 - progressBarWidth / 2), y, progressBarWidth, 0x33B6FF, 0xDDDDDD, 0x0, 0, true, false))
local label = window.contentContainer:addChild(GUI.label(1, y + 1, window.contentContainer.width, 1, 0x888888, "")):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top)
for i = 1, #finalApplicationList do
progressBar.value = math.floor(i / #finalApplicationList * 100)
label.text = localization.updating .. fs.name(finalApplicationList[i].path)
mainContainer:draw()
buffer.draw()
MineOSCore.downloadApplication(finalApplicationList[i], MineOSCore.properties.language)
end
mainContainer:draw()
buffer.draw()
table.toFile(MineOSPaths.applicationList, applicationList)
computer.shutdown(true)
end
end
else
window.contentContainer.searchInputTextBox = window.contentContainer:addChild(GUI.input(math.floor(window.contentContainer.width / 2 - 10), y, 20, 1, 0xFFFFFF, 0x444444, 0xAAAAAA, 0xFFFFFF, 0x2D2D2D, "", localization.search, true))
window.contentContainer.searchInputTextBox.onInputFinished = function()
if window.contentContainer.searchInputTextBox.text then
displayApps(1, typeFilter, window.contentContainer.searchInputTextBox.text)
end
end
for i = 1, #applicationList do
if (not typeFilter or typeFilter == applicationList[i].type) and (not nameFilter or string.unicodeFind(unicode.lower(fs.name(applicationList[i].path)), unicode.lower(nameFilter))) then
table.insert(finalApplicationList, applicationList[i])
end
end
end
y = y + 2
mainContainer:draw()
buffer.draw()
local appOnPageCounter, fromAppCounter, fromApp = 1, 1, (fromPage - 1) * appsPerPage + 1
for i = 1, #finalApplicationList do
if fromAppCounter >= fromApp then
y, appOnPageCounter = y + window.contentContainer:addChild(newApp(1, y, window.contentContainer.width, finalApplicationList[i])).height + 1, appOnPageCounter + 1
mainContainer:draw()
buffer.draw()
if appOnPageCounter > appsPerPage then
break
end
end
fromAppCounter = fromAppCounter + 1
end
-- Pages buttons CYKA
local buttonWidth, text = 5, localization.page .. fromPage
local textLength = unicode.len(text)
local x = math.floor(window.contentContainer.width / 2 - (buttonWidth * 2 + textLength + 4) / 2)
window.contentContainer:addChild(GUI.roundedButton(x, y, buttonWidth, 1, 0xBBBBBB, 0xFFFFFF, 0x999999, 0xFFFFFF, "<")).onTouch = function()
if fromPage > 1 then
displayApps(fromPage - 1, typeFilter, nameFilter)
end
end
x = x + buttonWidth + 2
window.contentContainer:addChild(GUI.label(x, y, textLength, 1, 0x3C3C3C, text))
x = x + textLength + 2
window.contentContainer:addChild(GUI.roundedButton(x, y, buttonWidth, 1, 0xBBBBBB, 0xFFFFFF, 0x999999, 0xFFFFFF, ">")).onTouch = function()
displayApps(fromPage + 1, typeFilter, nameFilter)
end
mainContainer:draw()
buffer.draw()
end
window.contentContainer = window:addChild(GUI.container(3, 4, window.width - 4, window.height - 3))
window.contentContainer.eventHandler = function(mainContainer, object, eventData)
if eventData[1] == "scroll" and (eventData[5] == -1 or window.contentContainer.children[1].localY <= 1) then
for i = 1, #window.contentContainer.children do
window.contentContainer.children[i].localY = window.contentContainer.children[i].localY + eventData[5]
end
mainContainer:draw()
buffer.draw()
end
end
local tabs = {
window.tabBar:addItem(localization.applications),
window.tabBar:addItem(localization.libraries),
window.tabBar:addItem(localization.wallpapers),
window.tabBar:addItem(localization.other),
window.tabBar:addItem(localization.updates)
}
window.onResize = function(width, height)
window.contentContainer.width, window.contentContainer.height = width - 4, height - 3
window.tabBar.width = width
window.backgroundPanel.width = width
window.backgroundPanel.height = height - window.tabBar.height
tabs[window.tabBar.selectedItem].onTouch()
end
tabs[1].onTouch = function() displayApps(1, "Application") end
tabs[2].onTouch = function() displayApps(1, "Library") end
tabs[3].onTouch = function() displayApps(1, "Wallpaper") end
tabs[4].onTouch = function() displayApps(1, "Script") end
tabs[5].onTouch = function() displayApps(1, nil, nil, true) end
----------------------------------------------------------------------------------------------------------------
if select(1, ...) == "updates" then
window.tabBar.selectedItem = 5
end
updateApplicationList()
tabs[window.tabBar.selectedItem].onTouch()

View File

@ -0,0 +1 @@
Одно из главных системных приложений, позволяющее проверять наличие необходимых обновлений, а также загружать красивейшие программы, созданные специально для MineOS.

View File

@ -0,0 +1,17 @@
{
applications = "Applications",
libraries = "Libraries",
wallpapers = "Wallpapers",
other = "Other",
updates = "Updates",
checkingForUpdates = "Checking for updates",
version = "Version: ",
updateAll = "Update all",
download = "Install",
downloading = "Installing",
downloaded = "Installed",
search = "Search",
page = "Page ",
youHaveNewestApps = "You have no updates.",
updating = "Installing ",
}

View File

@ -0,0 +1,17 @@
{
applications = "Приложения",
libraries = "Библиотеки",
wallpapers = "Обои",
other = "Другое",
updates = "Обновления",
checkingForUpdates = "Проверка наличия обновлений",
version = "Версия: ",
updateAll = "Обновить все",
download = "Загрузить",
downloading = "Загрузка",
downloaded = "Установлено",
search = "Поиск",
page = "Страница ",
youHaveNewestApps = "У вас самое новое ПО",
updating = "Обновление ",
}

View File

@ -0,0 +1,339 @@
--Реквайрики
local g = require("component").gpu
local term = require("term")
local event = require("event")
local colors = {
white = 0xffffff,
orange = 0xF2B233,
magenta = 0xE57FD8,
lightBlue = 0x99B2F2,
yellow = 0xDEDE6C,
lime = 0x7FCC19,
pink = 0xF2B2CC,
gray = 0x4C4C4C,
lightGray = 0x999999,
cyan = 0x4C99B2,
purple = 0xB266E5,
blue = 0x3366CC,
brown = 0x7F664C,
green = 0x57A64E,
red = 0xCC4C4C,
black = 0x000000,
}
--Настройка экрана
local w, h = 46, 14
g.setResolution(w,h)
--Аргументы
args = {...}
--Очищаем экран
g.setBackground(colors.lightGray)
term.clear()
--Переменные для кораблей
local ships = {{3, 3, 8},
{3, 5, 6},
{11, 5, 6},
{3, 7, 4},
{9, 7, 4},
{15, 7, 4},
{3, 9, 2},
{7, 9, 2},
{11, 9, 2},
{15, 9, 2}}
local shipsE = {{0, 0, 8},
{0, 0, 6},
{0, 0, 6},
{0, 0, 4},
{0, 0, 4},
{0, 0, 4},
{0, 0, 2},
{0, 0, 2},
{0, 0, 2},
{0, 0, 2}}
--Переменные попаданий
local shots = 0
local shotsE = {{0, 0}}
local shotsE2 = 0
--Пишем заголовок
g.setBackground(colors.gray)
g.fill(1,1,w,1," ")
term.setCursor(math.floor(w/2-6),1)
g.setForeground(colors.white)
term.write("Морской Бой")
g.setBackground(colors.black)
term.setCursor(w-3,1)
term.write(" ")
--Функция определения координаты для поля
function makePixelX(x, b)
return b+math.floor((x-b)/2)*2
end
--Рисуем кораблики
function drawShips()
for i=1,10 do
g.setBackground(colors.brown)
g.fill(ships[i][1], ships[i][2], ships[i][3], 1, " ")
end
end
--Автоматически установить кораблики
function setShipsAuto(var)
local s = ships
if var ~= 25 then
s = shipsE
end
for i=1,10 do
local x, y = 0, 0
local yes = true
while yes do
x = math.random(var, var+19)
y = math.random(3, 12)
if x+s[i][3]-1 < var+20 then
for j=1,10 do
if i ~= j and (x < s[j][1]+s[j][3]+2 and x+s[i][3] > s[j][1]-2 and y > s[j][2]-2 and y < s[j][2]+2) then
x = math.random(var, var+19)
y = math.random(3, 12)
break
elseif i ~= j and (j == 10 or (i == 10 and j == 9)) then
s[i][1] = makePixelX(x, var)
s[i][2] = y
yes = false
end
end
end
end
end
if var == 25 then
ships = s
else
shipsE = s
end
end
--Рисуем поле
function drawField()
g.setBackground(0xffffff)
g.fill(25,3,20,10," ")
g.setBackground(0xDDDDDD)
if args[1] ~= "fast" then
for i=1,10 do
local delta = math.fmod(i,2)
for j=1,5 do
g.fill(23+4*j-2*delta, i+2, 2, 1, " ")
end
end
end
end
--Рисуем поле врага
function drawFieldE()
g.setBackground(0xffffff)
g.fill(3,3,20,10," ")
g.setBackground(0xDDDDDD)
if args[1] ~= "fast" then
for i=1,10 do
local delta = math.fmod(i,2)
for j=1,5 do
g.fill(1+4*j-2*delta, i+2, 2, 1, " ")
end
end
end
end
--Кнопка готово после рандома
function drawButton2()
g.setBackground(colors.pink)
term.setCursor(13, 11)
term.write(" Готово ")
end
--Кнопка рандома своих кораблей
function drawButton()
g.setBackground(colors.lime)
term.setCursor(3, 11)
term.write(" Авто ")
end
--Очищаем пустое место
function clearShipsField()
g.setBackground(colors.lightGray)
g.fill(3,3,22,10," ")
end
--Гуишечка
drawField()
drawShips()
drawButton()
g.setBackground(colors.lightGray)
g.setForeground(colors.black)
term.setCursor(3,13)
term.write("Установите корабли")
--Цикл для установки своих корабликов вручную
local ship = 0
local prevX = 0
local shipCoords = {0,0}
local setting = true
local playing = true
local button2 = false
while setting do
local event, _, x, y = event.pull()
if event == "touch" then
if x > 2 and x < 13 and y == 11 then
setShipsAuto(25)
drawField()
clearShipsField()
drawShips()
drawButton()
drawButton2()
button2 = true
elseif button2 and x > 12 and x < 24 and y == 11 then
setting = false
break
elseif x > w-4 and x < w and y == 1 then
setting = false
playing = false
break
end
elseif event == "drag" then
if ship == 0 then
for i=1,10 do
if x > ships[i][1] and x < ships[i][1]+ships[i][3] and y == ships[i][2] then
ship = i
shipCoords[1] = ships[i][1]
shipCoords[2] = ships[i][2]
break
end
end
else
ships[ship][1] = ships[ship][1] + x - prevX
ships[ship][2] = y
if ships[ship][1] > 2 and ships[ship][1]+ships[ship][3]-1 < 45 and y > 2 and y < 13 then
drawField()
clearShipsField()
drawShips()
drawButton()
end
end
prevX = x
elseif event == "drop" then
if ship > 0 then
if ships[ship][1] < 25 or ships[ship][1]+ships[ship][3]-1 > 45 or y < 3 or y > 13then
ships[ship][1] = shipCoords[1]
ships[ship][2] = shipCoords[2]
end
for i=1,10 do
if i ~= ship and (ships[ship][1] < ships[i][1]+ships[i][3]+1 and ships[ship][1]+ships[ship][3]-1 > ships[i][1]-2 and ships[ship][2] > ships[i][2]-2 and ships[ship][2] < ships[i][2]+2) then
ships[ship][1] = shipCoords[1]
ships[ship][2] = shipCoords[2]
break
end
end
ships[ship][1] = makePixelX(ships[ship][1], 25)
end
ship = 0
drawField()
clearShipsField()
drawShips()
drawButton()
for i=1,10 do
if ships[i][1] < 25 then
break
elseif i == 10 then
setting = false
break
end
end
end
end
--Следующий цикл для игры
setShipsAuto(3)
drawFieldE()
g.setBackground(colors.lightGray)
g.setForeground(colors.black)
term.setCursor(3,13)
term.write("Противник ")
term.setCursor(25,13)
term.write("Вы")
g.setBackground(colors.magenta)
g.fill(23, 3, 2, 10, " ")
while playing do
local event, _, x, y = event.pull()
if event == "touch" then
if shots < 20 and shotsE2 < 20 and x > 2 and x < 23 and y > 2 and y < 13 then
x = makePixelX(x, 3)
for i=1,10 do
if x > shipsE[i][1]-1 and x < shipsE[i][1]+shipsE[i][3] and y == shipsE[i][2] then
shots = shots + 1
g.setBackground(colors.red)
break
end
g.setBackground(colors.blue)
end
g.fill(x, y, 2, 1, " ")
local yes = true
local xE, yE = 0, 0
while yes do
xE = makePixelX(math.random(25,44), 3)
yE = math.random(3,12)
for i=1,#shotsE do
if xE == shotsE[i][1] and yE == shotsE[i][2] then
break
elseif i == #shotsE then
yes = false
break
end
end
end
table.insert(shotsE, {makePixelX(xE, 3), yE})
if args[2] ~= "notime" then
g.setBackground(colors.purple)
g.fill(23, 3, 2, 10, " ")
os.sleep(math.floor(math.random(2))-0.5)
g.setBackground(colors.magenta)
g.fill(23, 3, 2, 10, " ")
end
for i=1,10 do
if xE > ships[i][1]-1 and xE < ships[i][1]+ships[i][3] and yE == ships[i][2] then
shotsE2 = shotsE2 + 1
g.setBackground(colors.red)
break
end
g.setBackground(colors.blue)
end
g.fill(xE, yE, 2, 1, " ")
if shots == 20 or shotsE2 == 20 then
g.setBackground(colors.lightGray)
g.fill(2, 3, 43, 12, " ")
g.setBackground(colors.white)
g.fill(15, 5, 16, 3, " ")
if shots == 20 then
term.setCursor(20, 6)
term.write("Победа")
elseif shotsE2 == 20 then
term.setCursor(18, 6)
term.write("Поражение")
end
end
elseif x > w-4 and x < w and y == 1 then
playing = false
break
end
end
end
--При выходе
g.setForeground(colors.white)
g.setBackground(colors.black)
term.clear()
g.setResolution(g.maxResolution())

View File

@ -0,0 +1 @@
Популярная игра "Морской бой", написанная товарищем Nezn с форума ComputerCraft.ru. Рассчитана на одного игрока, вам предстоит захватывающее сражение с флотом противника, контролируемым ИИ на Lua.

View File

@ -0,0 +1,160 @@
local buffer = require("doubleBuffering")
local event = require("event")
local image = require("image")
local currentBackground = 0x990000
local risovatKartinku = true
local showPanel = true
local transparency = 0.25
local xWindow, yWindow = 5, 5
local fon = image.load("MineOS/Applications/BufferDemo.app/Resources/Wallpaper.pic")
buffer.flush()
local bufferWidth, bufferHeight = buffer.getResolution()
local function drawBackground()
--Заполним весь наш экран цветом фона 0x262626, цветом текста 0xFFFFFF и символом " "
if not risovatKartinku then
buffer.square(1, 1, bufferWidth, bufferHeight, currentBackground, 0xFFFFFF, " ")
else
buffer.image(1, 1, fon)
end
end
--Создаем переменные с координатами начала и размерами нашего окна
local width, height = 82, 25
-- local cykaPicture = image.load("System/OS/Icons/Steve.pic")
-- local cykaPicture2 = image.load("System/OS/Icons/Love.pic")
local function drawWindow(x, y)
--Тени
local shadowTransparency = 0.6
buffer.square(x + width, y + 1, 2, height, 0x000000, 0xFFFFFF, " ", shadowTransparency)
buffer.square(x + 2, y + height, width - 2, 1, 0x000000, 0xFFFFFF, " ", shadowTransparency)
--Создаем прозрачную часть окна, где отображается "Избранное"
buffer.square(x, y, 20, height, 0xFFFFFF, 0xFFFFFF, " ", transparency)
--Создаем непрозрачную часть окна для отображения всяких файлов и т.п.
buffer.square(x + 20, y, width - 20, height, 0xFFFFFF, 0xFFFFFF, " ")
--Создаем три более темных полоски вверху окна, имитируя объем
buffer.square(x, y, width, 1, 0xDDDDDD, 0xFFFFFF, " ")
buffer.square(x, y + 1, width, 1, 0xCCCCCC, 0xFFFFFF, " ")
buffer.square(x, y + 2, width, 1, 0xBBBBBB, 0xFFFFFF, " ")
--Рисуем заголовок нашего окошка
buffer.text(x + 30, y, 0x000000, "Тестовое окно")
--Создаем три кнопки в левом верхнем углу для закрытия, разворачивания и сворачивания окна
buffer.set(x + 1, y, 0xDDDDDD, 0xFF4940, "")
buffer.set(x + 3, y, 0xDDDDDD, 0xFFB640, "")
buffer.set(x + 5, y, 0xDDDDDD, 0x00B640, "")
--Рисуем элементы "Избранного" чисто для демонстрации
buffer.text(x + 1, y + 3, 0x000000, "Избранное")
for i = 1, 6 do buffer.text(x + 2, y + 3 + i, 0x555555, "Вариант " .. i) end
--Рисуем "Файлы" в виде желтых квадратиков. Нам без разницы, а выглядит красиво
for j = 1, 3 do
for i = 1, 5 do
local xPos, yPos = x + 22 + i*12 - 12, y + 4 + j*7 - 7
buffer.square(xPos, yPos, 8, 4, 0xFFFF80, 0xFFFFFF, " ")
buffer.text(xPos, yPos + 5, 0x262626, "Файл " .. i .. "x" .. j)
end
end
--Ну, и наконец рисуем голубой скроллбар справа
buffer.square(x + width - 1, y + 3, 1, height - 3, 0xBBBBBB, 0xFFFFFF, " ")
buffer.square(x + width - 1, y + 3, 1, 4, 0x3366CC, 0xFFFFFF, " ")
--Изображения!
-- buffer.image(x + 23, y + 6, cykaPicture)
-- buffer.image(x + 33, y + 12, cykaPicture2)
if showPanel then
xPos, yPos = x, y + height + 2
buffer.square(xPos, yPos, width, 10, 0xFFFFFF, 0xFFFFFF, " ", transparency)
--Тень
buffer.square(xPos + width, yPos + 1, 2, 10, 0x000000, 0xFFFFFF, " ", shadowTransparency)
buffer.square(xPos + 2, yPos + 10, width - 2, 1, 0x000000, 0xFFFFFF, " ", shadowTransparency)
yPos = yPos + 1
xPos = xPos + 2
buffer.text(xPos + 2, yPos, 0x262626, "Клик левой кнопкой мыши: изменить позицию окошка"); yPos = yPos + 1
buffer.text(xPos + 2, yPos, 0x262626, "Клик правой кнопкой: нарисовать еще одно такое же окошко"); yPos = yPos + 1
buffer.text(xPos + 2, yPos, 0x262626, "Колесо мыши: изменить прозрачность окна"); yPos = yPos + 2
buffer.text(xPos + 2, yPos, 0x262626, "Space: переключить фон между картинкой и статичным цветом"); yPos = yPos + 1
buffer.text(xPos + 2, yPos, 0x262626, "Shift: изменить цвет фона на рандомный"); yPos = yPos + 1
buffer.text(xPos + 2, yPos, 0x262626, "Tab: включить или отключить данную информационную панель"); yPos = yPos + 1
buffer.text(xPos + 2, yPos, 0x262626, "Enter: выйти отсудова на хер"); yPos = yPos + 1
end
end
drawBackground()
drawWindow(xWindow, yWindow)
buffer.draw()
while true do
local e = {event.pull()}
if e[1] == "touch" or e[1] == "drag" then
if e[5] == 0 then
drawBackground()
xWindow, yWindow = e[3], e[4]
drawWindow(xWindow, yWindow)
buffer.draw()
else
xWindow, yWindow = e[3], e[4]
drawWindow(xWindow, yWindow)
buffer.draw()
end
elseif e[1] == "key_down" then
if e[4] == 42 then
currentBackground = math.random(0x000000, 0xFFFFFF)
drawBackground()
drawWindow(xWindow, yWindow)
buffer.draw()
elseif e[4] == 28 then
buffer.square(1, 1, bufferWidth, bufferHeight, 0x262626, 0xFFFFFF, " ")
buffer.draw()
return
elseif e[4] == 57 then
risovatKartinku = not risovatKartinku
drawBackground()
drawWindow(xWindow, yWindow)
buffer.draw()
elseif e[4] == 15 then
showPanel = not showPanel
drawBackground()
drawWindow(xWindow, yWindow)
buffer.draw()
end
elseif e[1] == "scroll" then
if e[5] == 1 then
if transparency > 0.05 then
transparency = transparency - 0.05
drawBackground()
drawWindow(xWindow, yWindow)
buffer.draw()
end
else
if transparency < 1 then
transparency = transparency + 0.05
drawBackground()
drawWindow(xWindow, yWindow)
buffer.draw()
end
end
end
end

View File

@ -0,0 +1 @@
Программа-демонстратор возможностей нашей библиотеки двойной буферизации изображения. Вся ОС работает именно на этой библиотеке.

View File

@ -0,0 +1,379 @@
local ecs = require("ECSAPI")
local fs = require("filesystem")
local event = require("event")
local component = require("component")
local gpu = component.gpu
--Список месяцев
local months = {
"Январь",
"Февраль",
"Март",
"Апрель",
"Май",
"Июнь",
"Июль",
"Август",
"Сентябрь",
"Октябрь",
"Ноябрь",
"Декабрь",
}
--Количество дней в месяцах
local countOfDays = {
31,
28,
31,
30,
31,
30,
31,
31,
30,
31,
30,
31,
}
--Сдвиг дня недели по дате в каждом месяце
local monthDateMove = {
3,
2,
3,
2,
3,
2,
3,
3,
2,
3,
2,
3,
}
--Графика
local numbers = {
["1"] = {
{0, 1, 0},
{0, 1, 0},
{0, 1, 0},
{0, 1, 0},
{0, 1, 0},
},
["2"] = {
{1, 1, 1},
{0, 0, 1},
{1, 1, 1},
{1, 0, 0},
{1, 1, 1},
},
["3"] = {
{1, 1, 1},
{0, 0, 1},
{1, 1, 1},
{0, 0, 1},
{1, 1, 1},
},
["4"] = {
{1, 0, 1},
{1, 0, 1},
{1, 1, 1},
{0, 0, 1},
{0, 0, 1},
},
["5"] = {
{1, 1, 1},
{1, 0, 0},
{1, 1, 1},
{0, 0, 1},
{1, 1, 1},
},
["6"] = {
{1, 1, 1},
{1, 0, 0},
{1, 1, 1},
{1, 0, 1},
{1, 1, 1},
},
["7"] = {
{1, 1, 1},
{0, 0, 1},
{0, 0, 1},
{0, 0, 1},
{0, 0, 1},
},
["8"] = {
{1, 1, 1},
{1, 0, 1},
{1, 1, 1},
{1, 0, 1},
{1, 1, 1},
},
["9"] = {
{1, 1, 1},
{1, 0, 1},
{1, 1, 1},
{0, 0, 1},
{1, 1, 1},
},
["0"] = {
{1, 1, 1},
{1, 0, 1},
{1, 0, 1},
{1, 0, 1},
{1, 1, 1},
},
}
--Всякие переменные
local constants = {
xSpaceBetweenNumbers = 2,
ySpaceBetweenNumbers = 1,
xSpaceBetweenMonths = 4,
ySpaceBetweenMonths = 1,
currentYear = 2015,
currentMonth = 9,
currentDay = 26,
programYear = 2015,
programMonth = 1,
proramDay = 1,
usualDayColor = 0x262626,
weekendColor = 0x880000,
backgroundColor = 0xEEEEEE,
dayNamesColor = 0x888888,
monthsColor = 0xCC0000,
currentDayColor = 0xFFFFFF,
bigNumberColor = 0x262626,
}
local xMax, yMax = gpu.maxResolution()
--Объекты для тача
local obj = {}
local function newObj(class, name, ...)
obj[class] = obj[class] or {}
obj[class][name] = {...}
end
--Проверка года на "високосность"
local function visokosniy(year)
if year % 4 == 0 or year % 400 == 0 then return true else return false end
end
--Отрисовать месяц
local function drawMonth(x, y, firstDay, countOfDays, year, month)
local xPos, yPos = x, y + 4
local counter = 1
local startDrawing = false
local separator = string.rep(" ", constants.xSpaceBetweenNumbers)
ecs.colorText(x, y, constants.monthsColor, months[month])
ecs.colorText(x, y + 2, constants.dayNamesColor,"Пн"..separator.."Вт"..separator.."Ср"..separator.."Чт"..separator.."Пт"..separator.."Сб"..separator.."Вс")
for j = 1, 6 do
xPos = x
for i = 1, 7 do
if i < 6 then gpu.setForeground(constants.usualDayColor) else gpu.setForeground(constants.weekendColor) end
if counter == constants.currentDay and year == constants.currentYear and month == constants.currentMonth then ecs.square(xPos-1, yPos, 4, 1, constants.weekendColor); gpu.setForeground(constants.currentDayColor) else gpu.setBackground(constants.backgroundColor) end
if counter > countOfDays then break end
if i >= firstDay then startDrawing = true end
if startDrawing then gpu.set(xPos, yPos, tostring(counter)); counter = counter + 1 end
xPos = xPos + constants.xSpaceBetweenNumbers + 2
end
yPos = yPos + constants.ySpaceBetweenNumbers + 1
end
end
--Получить номер следующего дня
local function getNextDay(day)
if day < 7 then
return (day + 1)
else
return 1
end
end
--Просчитать данные о годе
local function calculateYear(year, dayOf1Jan)
local massivGoda = {}
local visokosniy = visokosniy(year)
local firstDayPosition = dayOf1Jan
--Получаем количество дней в каждом месяце
for month = 1, 12 do
--Создаем подмассив месяца в массиве года
massivGoda[month] = {}
--Если это февраль
if month == 2 then
--Если год високосный
if visokosniy then
massivGoda[month].countOfDays = 29
massivGoda[month].firstDayPosition = firstDayPosition
firstDayPosition = getNextDay(firstDayPosition)
--Если не високосный
else
massivGoda[month].countOfDays = 28
massivGoda[month].firstDayPosition = firstDayPosition
end
--Если не февраль
else
massivGoda[month].countOfDays = countOfDays[month]
massivGoda[month].firstDayPosition = firstDayPosition
for i = 1, monthDateMove[month] do
firstDayPosition = getNextDay(firstDayPosition)
end
end
end
return massivGoda
end
--Получить день недели первого января указанного года
local function polu4itDenNedeliPervogoJanvarja(year, debug)
local den = 0
local difference = math.abs(year - 1010)
local koli4estvoVisokosnih
if difference % 4 == 0 then
koli4estvoVisokosnih = difference / 4
elseif difference % 4 == 1 then
koli4estvoVisokosnih = math.floor(difference / 4)
elseif difference % 4 == 2 then
koli4estvoVisokosnih = math.floor(difference / 4)
elseif difference % 4 == 3 then
koli4estvoVisokosnih = math.floor(difference / 4) + 1
end
local sdvig = difference + koli4estvoVisokosnih
if sdvig % 7 == 0 then
den = 1
else
den = sdvig % 7 + 1
end
if debug then
print("Год: "..year)
print("Разница в годах: "..difference)
print("Кол-во високосных: "..koli4estvoVisokosnih)
print("Сдвиг по дням: "..sdvig)
print("День недели: "..den)
print(" ")
end
return den
end
--Нарисовать календарь
local function drawCalendar(xPos, yPos, year)
ecs.square(xPos, yPos, 120, 48, constants.backgroundColor)
--Получаем позицию первого января указанного года
local janFirst = polu4itDenNedeliPervogoJanvarja(year)
--Получаем массив года
local massivGoda = calculateYear(year, janFirst)
--Перебираем массив года
for i = 1, #massivGoda do
--Рисуем месяц
drawMonth(xPos, yPos, massivGoda[i].firstDayPosition, massivGoda[i].countOfDays, year, i)
--Корректируем коорды
xPos = xPos + constants.xSpaceBetweenMonths + 27
if i % 4 == 0 then xPos = 3; yPos = yPos + constants.ySpaceBetweenMonths + 15 end
end
end
local function drawSymbol(x, y, symbol)
local xPos, yPos = x, y
for j = 1, #numbers[symbol] do
xPos = x
for i = 1, #numbers[symbol][j] do
if numbers[symbol][j][i] ~= 0 then
gpu.set(xPos, yPos, " ")
end
xPos = xPos + 2
end
yPos = yPos + 1
end
end
local function drawYear(x, y, year)
year = tostring(year)
for i = 1, #year do
drawSymbol(x, y, string.sub(year, i, i))
x = x + 8
end
end
local next, prev
local function drawInfo()
local xPos, yPos = 127, 4
ecs.square(xPos, yPos, 30, 5, constants.backgroundColor)
gpu.setBackground(constants.bigNumberColor)
drawYear(xPos, yPos, constants.programYear)
yPos = yPos + 6
local name = "Следующий год"; newObj("Buttons", name, ecs.drawButton(xPos, yPos, 30, 3, name, 0xDDDDDD, 0x262626)); yPos = yPos + 4
name = "Предыдущий год"; newObj("Buttons", name, ecs.drawButton(xPos, yPos, 30, 3, name, 0xDDDDDD, 0x262626)); yPos = yPos + 4
name = "Выйти"; newObj("Buttons", name, ecs.drawButton(xPos, yPos, 30, 3, name, 0xDDDDDD, 0x262626)); yPos = yPos + 4
end
local function drawAll()
--Очищаем экран
ecs.square(1, 1, xMax, yMax, constants.backgroundColor)
--Рисуем календарик
drawCalendar(3, 2, constants.programYear)
--Рисуем парашу
drawInfo()
end
--------------------------------------------------------------------------------------------------------------------
if xMax < 150 then error("This program requires Tier 3 GPU and Tier 3 Screen.") end
--Запоминаем старое разрешение экрана
local xOld, yOld = gpu.getResolution()
--Ставим максимальное
gpu.setResolution(xMax, yMax)
--Получаем данные о текущей дате (os.date выдает неверную дату и месяц, забавно)
constants.currentDay, constants.currentMonth, constants.currentYear = ecs.getHostTime(2)
constants.programDay, constants.programMonth, constants.programYear = constants.currentDay, constants.currentMonth, constants.currentYear
--Рисуем все
drawAll()
while true do
local e = {event.pull()}
if e[1] == "touch" then
for key in pairs(obj["Buttons"]) do
if ecs.clickedAtArea(e[3], e[4], obj["Buttons"][key][1], obj["Buttons"][key][2], obj["Buttons"][key][3], obj["Buttons"][key][4]) then
ecs.drawButton(obj["Buttons"][key][1], obj["Buttons"][key][2], 30, 3, key, constants.weekendColor, constants.currentDayColor)
os.sleep(0.2)
if key == "Следующий год" then
constants.programYear = constants.programYear + 1
elseif key == "Предыдущий год" then
constants.programYear = constants.programYear - 1
elseif key == "Выйти" then
gpu.setResolution(xOld, yOld)
ecs.prepareToExit()
return
end
drawInfo()
drawCalendar(3, 2, constants.programYear)
break
end
end
end
end

View File

@ -0,0 +1 @@
Calendar - простая программа, не нуждающаяся в особом представлении. Красивый интерфейс позволяет легко узнать день недели конкретной даты любого года.

View File

@ -0,0 +1,229 @@
local component = require("component")
local ecs = require("ECSAPI")
local buffer = require("doubleBuffering")
local event = require("event")
local context = require("context")
local gpu = component.gpu
local camera
if not component.isAvailable("camera") then
ecs.error("Этой программе требуется камера из мода Computronix.")
return
else
camera = component.camera
end
local step = 0.04
local from = step * 25
local distanceLimit = 36
local widthOfImage, heightOfImage = 100, 50
local grayScale = {
0x000000,
0x111111,
0x111111,
0x222222,
0x333333,
0x333333,
0x444444,
0x555555,
0x666666,
0x777777,
0x777777,
0x888888,
0x999999,
0xaaaaaa,
0xbbbbbb,
0xbbbbbb,
0xcccccc,
0xdddddd,
0xeeeeee,
0xeeeeee,
0xffffff,
}
local rainbow = {
0x000000,
0x000040,
0x000080,
0x002480,
0x0000BF,
0x0024BF,
0x002400,
0x004900,
0x006D00,
0x009200,
0x00B600,
0x33DB00,
0x99FF00,
0xCCFF00,
0xFFDB00,
0xFFB600,
0xFF9200,
0xFF6D00,
0xFF4900,
0xFF2400,
0xFF0000,
}
local currentPalette = rainbow
local topObjects
local currentTopObject = 0
local function gui()
topObjects = ecs.drawTopMenu(1, 1, widthOfImage, 0xeeeeee, currentTopObject, {"Камера", 0x000000}, {"Сделать снимок", 0x444444}, {"Параметры рендера", 0x444444}, {"Палитра", 0x444444})
end
local function capture(x, y)
local xPos, yPos = x, y
local distance, color
local oldPixels = ecs.info("auto", "auto", " ", " Делаю снимок... ")
for y = from, -from, -step do
for x = -from, from, step do
distance = camera.distance(x, y)
if distance >= 0 then
if distance > distanceLimit then distance = distanceLimit end
color = currentPalette[(#currentPalette + 1) - math.ceil(distance / (distanceLimit / #currentPalette))]
buffer.set(xPos, yPos, color, 0x000000, " ")
buffer.set(xPos + 1, yPos, color, 0x000000, " ")
else
buffer.set(xPos, yPos, 0x000000, 0x000000, " ")
buffer.set(xPos + 1, yPos, 0x000000, 0x000000, " ")
end
percent = (x * y) / (widthOfImage * heightOfImage)
xPos = xPos + 2
end
xPos = x
yPos = yPos + 1
end
ecs.drawOldPixels(oldPixels)
end
local function drawDistanceMeter()
local width = 4
local xPos, yPos = widthOfImage - 3 - width, 3
buffer.square(xPos, yPos, width + 2, #currentPalette * 2 + 2, 0x000000, 0x000000, " ")
yPos = yPos + 1
xPos = xPos + 1
for i = #currentPalette, 1, -1 do
buffer.square(xPos, yPos, width, 2, currentPalette[i], 0x000000, " ")
yPos = yPos + 2
end
end
local xOld, yOld = gpu.getResolution()
gpu.setResolution(100, 50)
buffer.flush()
gui()
ecs.square(1, 2, widthOfImage, heightOfImage - 1, 0x000000)
buffer.square(1, 2, widthOfImage, heightOfImage - 1, 0x000000, 0x000000, " ")
capture(1, 1)
drawDistanceMeter()
buffer.draw()
gui()
while true do
local e = {event.pull()}
if e[1] == "touch" then
for key in pairs(topObjects) do
if ecs.clickedAtArea(e[3], e[4], topObjects[key][1], topObjects[key][2], topObjects[key][3], topObjects[key][4]) then
currentTopObject = topObjects[key][5]
gui()
if key == "Камера" then
local action = context.menu(topObjects[key][1] - 1, 2, {"О программе"}, {"Выход"})
if action == "О программе" then
local text = "Эта программа является тестом библиотеки двойной буферизации изображения, написана для проверки адекватности нескольких функций. Сама идея сперта у какого-то крутого парня с форума CC, однако немного доработана в GUI-плане. Такие дела."
ecs.universalWindow("auto", "auto", 36, 0xeeeeee, true, {"EmptyLine"}, {"CenterText", 0x000000, "О программе \"Камера\""}, {"EmptyLine"}, {"TextField", 9, 0xFFFFFF, 0x000000, 0xaaaaaa, ecs.colors.blue, text}, {"EmptyLine"}, {"Button", {0x999999, 0xffffff, "OK"}})
elseif action == "Выход" then
gpu.setResolution(xOld, yOld)
ecs.prepareToExit()
return
end
elseif key == "Сделать снимок" then
capture(1, 1)
drawDistanceMeter()
buffer.draw()
gui()
elseif key == "Параметры рендера" then
local action = context.menu(topObjects[key][1] - 1, 2, {"Масштаб"}, {"Дальность рейкастинга"})
if action == "Масштаб" then
local data = ecs.universalWindow("auto", "auto", 36, 0xeeeeee, true, {"EmptyLine"}, {"CenterText", 0x000000, "Изменить масштаб:"}, {"EmptyLine"}, {"Slider", 0x262626, 0x880000, 1, 100, 100, "", "%"}, {"EmptyLine"}, {"Button", {0x999999, 0xffffff, "OK"}})
local part = (0.04 - 0.01) / 100
local percent = part * data[1]
step = percent
from = step * 25
capture(1, 1)
drawDistanceMeter()
buffer.draw()
gui()
elseif action == "Дальность рейкастинга" then
local data = ecs.universalWindow("auto", "auto", 36, 0xeeeeee, true, {"EmptyLine"}, {"CenterText", 0x000000, "Изменить дальность:"}, {"EmptyLine"}, {"Slider", 0x262626, 0x880000, 10, 36, distanceLimit, "", " блоков"}, {"EmptyLine"}, {"Button", {0x999999, 0xffffff, "OK"}})
distanceLimit = data[1]
capture(1, 1)
drawDistanceMeter()
buffer.draw()
gui()
end
elseif key == "Палитра" then
local action = context.menu(topObjects[key][1] - 1, 2, {"Черно-белая"}, {"Термальная"})
if action == "Черно-белая" then
currentPalette = grayScale
capture(1, 1)
drawDistanceMeter()
buffer.draw()
gui()
elseif action == "Термальная" then
currentPalette = rainbow
capture(1, 1)
drawDistanceMeter()
buffer.draw()
gui()
end
end
currentTopObject = 0
gui()
break
end
end
end
end

View File

@ -0,0 +1 @@
Программа-рейкастер, делающая снимки местности с помощью камеры из мода Computronix. Разумеется, данный мод должен быть установлен для работы.

View File

@ -0,0 +1,148 @@
local component = require("component")
local ecs = require("ECSAPI")
local hologram
local c = 23
-----------------------------------------------------------
if not component.isAvailable("hologram") then
ecs.error("Этой программе необходим голографический проектор 2 уровня.")
return
else
hologram = component.hologram
end
-----------------------------------------------------------
local data = ecs.universalWindow("auto", "auto", 36, 0x262626, true,
{"EmptyLine"},
{"CenterText", ecs.colors.orange, "Настройки анимации"},
{"EmptyLine"},
{"Selector", 0xFFFFFF, ecs.colors.orange, "Снегопад", "Легкий снежок", "Что-то сыпется", "Без осадков"},
{"Selector", 0xFFFFFF, ecs.colors.orange, "Легкое вращение", "Быстрое вращение", "Турбина", "Дюраселл", "Без вращения"},
{"EmptyLine"},
{"CenterText", ecs.colors.orange, "Размер елочки"},
{"EmptyLine"},
{"Slider", ecs.colors.white, ecs.colors.orange, 1, 100, 50, "", ""},
{"EmptyLine"},
{"CenterText", ecs.colors.white, "Программа закрывается через"},
{"CenterText", ecs.colors.white, "CTRL + ALT + C"},
{"EmptyLine"},
{"Button", {ecs.colors.orange, 0xffffff, "OK"}, {0x999999, 0xffffff, "Отмена"}}
)
local snowMode, rotationMode, scale, buttonPress = data[1], data[2], data[3], data[4]
scale = scale * 4 / 100
if snowMode == "Снегопад" then
snowMode = 0
elseif snowMode == "Легкий снежок" then
snowMode = 0.2
elseif snowMode == "Что-то сыпется" then
snowMode = 0.5
end
if rotationMode == "Легкое вращение" then
rotationMode = 5
elseif rotationMode == "Быстрое вращение" then
rotationMode = 15
elseif rotationMode == "Турбина" then
rotationMode = 25
elseif rotationMode == "Дюраселл" then
rotationMode = 35
elseif rotationMode == "Без вращения" then
rotationMode = 0
end
if buttonPress == "Отмена" then return end
-----------------------------------------------------------
-- создаем модель елки
local tSpruce = {3, 2, 2, 2, 2, 8, 9, 10, 9, 8, 7, 6, 5, 4, 3, 4, 6, 8, 7, 6, 5, 4, 3, 6, 5, 4, 3, 2, 3, 2, 1}
-- создаем таблицу с падающими снежинками
local tSnow = {}
-- создаем палитру цветов
hologram.setPaletteColor(1, 0xFFFFFF) -- снег
hologram.setPaletteColor(2, 0x221100) -- ствол
hologram.setPaletteColor(3, 0x005522) -- хвоя
local function cricle(x0, y, z0, R, i) -- задействуем алгоритм Брезенхэма для рисования кругов
local x = R
local z = 0
local err = -R
while z <= x do
hologram.set(x + x0, y, z + z0, i)
hologram.set(z + x0, y, x + z0, i)
hologram.set(-x + x0, y, z + z0, i)
hologram.set(-z + x0, y, x + z0, i)
hologram.set(-x + x0, y, -z + z0, i)
hologram.set(-z + x0, y, -x + z0, i)
hologram.set(x + x0, y, -z + z0, i)
hologram.set(z + x0, y, -x + z0, i)
z = z + 1
if err <= 0 then
err = err + (2 * z + 1)
else
x = x - 1
err = err + (2 * (z - x) + 1)
end
end
end
local function spruce() -- рисуем ель
for i = 1, 5 do
cricle(c, i, c, tSpruce[i], 2) -- отрисовываем основание ствола
cricle(c, i, c, tSpruce[i]-1, 2)
end
for j = 5, #tSpruce do
cricle(c, j, c, tSpruce[j]-1, 3) -- отрисовываем хвою
cricle(c, j, c, tSpruce[j]-2, 3)
end
end
local function gen_snow() -- генерируем снежинку
local x, y, z = math.random(1, 46), 32, math.random(1, 46)
table.insert(tSnow,{x=x,y=y,z=z})
hologram.set(x, y, z, 1)
end
local function falling_snow() -- сдвигаем снежинки вниз
local i=1
while i<=#tSnow do
if tSnow[i].y>1 then
local x,y,z=tSnow[i].x+math.random(-1, 1), tSnow[i].y-1, tSnow[i].z+math.random(-1, 1)
if x<1 then x=1 end
if x>46 then x=46 end
if z<1 then z=1 end
if z>46 then z=46 end
c=hologram.get(x, y, z)
if c==0 or c==1 then
hologram.set(tSnow[i].x, tSnow[i].y, tSnow[i].z, 0)
tSnow[i].x, tSnow[i].y, tSnow[i].z=x,y,z
hologram.set(x, y, z, 1)
i=i+1
else
table.remove(tSnow,i)
end
else
table.remove(tSnow,i)
end
os.sleep(snowMode)
end
end
ecs.info("auto", "auto", "", "Счастливого нового года!")
hologram.clear()
hologram.setScale(scale)
hologram.setRotationSpeed(rotationMode, 0, 23, 0)
spruce()
while 1 do
gen_snow()
falling_snow()
end

View File

@ -0,0 +1 @@
Красивая новогодняя программа, написанная разработчиком Doob, сотворяющая атмосферу праздника в любом месте, где бы вы ни находились.

View File

@ -0,0 +1,276 @@
local rs
local component = require("component")
local gpu = component.gpu
local unicode = require("unicode")
local ecs = require("ECSAPI")
local sides = require("sides")
local event = require("event")
local fs = require("filesystem")
local serialization = require("serialization")
if not component.isAvailable("redstone") then
ecs.error("This program requires Redstone I/O block or Redstone Card to work.")
return
else
rs = component.redstone
end
------------------------------------------------------------------------------------------------------------
local colors = {
background = 0x202020,
borders = 0xFFDD00,
}
------------------------------------------------------------------------------------------------------------
local keyPad = {
{"1", "2", "3"},
{"4", "5", "6"},
{"7", "8", "9"},
{"*", "0", "#"},
}
local xSize, ySize
local buttons = {}
local biometry = {}
local input
local password = "12345"
local showPassword = true
local showKeyPresses = true
local nicknames = {
"IgorTimofeev"
}
local pathToConfig = "System/CodeDoor/Config.cfg"
local function saveConfig()
local file = io.open(pathToConfig, "w")
local massiv = {["password"] = password, ["nicknames"] = nicknames, ["showPassword"] = showPassword, ["showKeyPresses"] = showKeyPresses}
file:write(serialization.serialize(massiv))
file:close()
end
local function loadConfig()
if fs.exists(pathToConfig) then
local massiv = {}
local file = io.open(pathToConfig, "r")
local stroka = file:read("*a")
massiv = serialization.unserialize(stroka)
file:close()
nicknames = massiv.nicknames
password = massiv.password
showPassword = massiv.showPassword
showKeyPresses = massiv.showKeyPresses
else
fs.makeDirectory(fs.path(pathToConfig))
local data = ecs.universalWindow("auto", "auto", 30, 0xEEEEEE, true, {"EmptyLine"}, {"CenterText", 0x880000, "Добро пожаловать в программу"}, {"CenterText", 0x880000, "конфигурации кодовой двери!"}, {"EmptyLine"}, {"CenterText", 0x262626, "Введите ваш пароль:"}, {"Input", 0x262626, 0x880000, "12345"}, {"EmptyLine"}, {"Switch", 0xF2B233, 0xffffff, 0x262626, "Показывать вводимый пароль", true}, {"EmptyLine"}, {"Switch", 0x3366CC, 0xffffff, 0x262626, "Показывать нажатие клавиш", true}, {"EmptyLine"}, {"Button", {0xbbbbbb, 0xffffff, "OK"}})
if data[1] == "" or tonumber(data[1]) == nil then ecs.error("Указан неверный пароль. По умолчанию он будет 12345."); password = "12345" else password = data[1] end
showPassword = data[2]
showKeyPresses = data[3]
saveConfig()
end
end
local function drawKeyPad(x, y)
local xPos, yPos = x, y
buttons = {}
for j = 1, #keyPad do
xPos = x
for i = 1, #keyPad[j] do
ecs.drawFramedButton(xPos, yPos, 5, 3, keyPad[j][i], colors.borders)
buttons[keyPad[j][i]] = {xPos, yPos, xPos + 4, yPos + 2}
xPos = xPos + 6
end
yPos = yPos + 3
end
end
local function visualScan(x, y, timing)
local yPos = y
gpu.setBackground(colors.background)
gpu.setForeground(colors.borders)
gpu.set(x, yPos, "╞══════════╡")
yPos = yPos - 1
os.sleep(timing)
for i = 1, 3 do
gpu.set(x, yPos, "╞══════════╡")
gpu.set(x, yPos + 1, "│ │")
yPos = yPos - 1
os.sleep(timing)
end
yPos = yPos + 2
for i = 1, 3 do
gpu.set(x, yPos, "╞══════════╡")
gpu.set(x, yPos - 1, "│ │")
yPos = yPos + 1
os.sleep(timing)
end
gpu.set(x, yPos - 1, "│ │")
end
local function infoPanel(info, background, foreground, hideData)
ecs.square(1, 1, xSize, 3, background)
local text if hideData then
text = ecs.stringLimit("start", string.rep("*", unicode.len(info)), xSize - 4)
else
text = ecs.stringLimit("start", info, xSize - 4)
end
ecs.colorText(math.ceil(xSize / 2 - unicode.len(text) / 2) + 1 , 2, foreground, text)
end
local function drawAll()
local xPos, yPos = 3, 5
--Как прописывать знаки типа © § ® ™
--кейпад
gpu.setBackground(colors.background)
drawKeyPad(xPos, yPos)
--Био
xPos = xPos + 18
ecs.border(xPos, yPos, 12, 6, colors.background, colors.borders)
ecs.square(xPos + 5, yPos + 2, 2, 2, colors.borders)
gpu.setBackground(colors.background)
biometry = {xPos, yPos, xPos + 11, yPos + 5}
--Био текст
yPos = yPos + 7
xPos = xPos + 1
gpu.set(xPos + 3, yPos, "ECS®")
gpu.set(xPos + 1, yPos + 1, "Security")
gpu.set(xPos + 1, yPos + 2, "Systems™")
end
local function checkNickname(name)
for i = 1, #nicknames do
if name == nicknames[i] then
return true
end
end
return false
end
local function pressButton(x, y, name)
ecs.square(x, y, 5, 3, colors.borders)
gpu.setForeground(colors.background)
gpu.set(x + 2, y + 1, name)
os.sleep(0.2)
end
local function waitForExit()
local e2 = {event.pull(3, "touch")}
if #e2 > 0 then
if ecs.clickedAtArea(e2[3], e2[4], buttons["*"][1], buttons["*"][2], buttons["*"][3], buttons["*"][4]) then
pressButton(buttons["*"][1], buttons["*"][2], "*")
return true
end
end
return false
end
local function redstone(go)
if go then
rs.setOutput(sides.top, 15)
local goexit = waitForExit()
rs.setOutput(sides.top, 0)
rs.setOutput(sides.bottom, 0)
return goexit
else
rs.setOutput(sides.bottom, 15)
os.sleep(2)
rs.setOutput(sides.top, 0)
rs.setOutput(sides.bottom, 0)
end
return false
end
------------------------------------------------------------------------------------------------------------
ecs.prepareToExit(colors.background)
loadConfig()
local oldWidth, oldHeight = gpu.getResolution()
gpu.setResolution(34, 17)
xSize, ySize = 34, 17
drawAll()
infoPanel("Введите пароль", colors.borders, colors.background)
while true do
local e = {event.pull()}
if e[1] == "touch" then
for key in pairs(buttons) do
if ecs.clickedAtArea(e[3], e[4], buttons[key][1], buttons[key][2], buttons[key][3], buttons[key][4]) then
if showKeyPresses then
pressButton(buttons[key][1], buttons[key][2], key)
end
if key == "*" then
input = nil
infoPanel("Поле ввода очищено", colors.borders, colors.background)
elseif key == "#" then
drawAll()
if input == password then
infoPanel("Доступ разрешён!", ecs.colors.green, 0xFFFFFF)
local goexit = redstone(true)
for i = 1, #nicknames do
if nicknames[i] == e[6] then nicknames[i] = nil end
end
table.insert(nicknames, e[6])
saveConfig()
if goexit then
ecs.prepareToExit()
gpu.setResolution(oldWidth, oldHeight)
ecs.prepareToExit()
return
end
else
infoPanel("Доступ запрещён!", ecs.colors.red, 0xFFFFFF)
redstone(false)
end
infoPanel("Введите пароль", colors.borders, colors.background)
input = nil
else
input = (input or "") .. key
infoPanel(input, colors.borders, colors.background, not showPassword)
end
drawAll()
break
end
end
if ecs.clickedAtArea(e[3], e[4], biometry[1], biometry[2], biometry[3], biometry[4]) then
visualScan(biometry[1], biometry[2] + 4, 0.08)
if checkNickname(e[6]) then
infoPanel("Привет, " .. e[6], ecs.colors.green, 0xFFFFFF)
redstone(true)
else
infoPanel("В доступе отказано!", ecs.colors.red, 0xFFFFFF)
redstone(false)
end
infoPanel("Введите пароль", colors.borders, colors.background)
drawAll()
end
end
end

View File

@ -0,0 +1 @@
Программа для защиты вашего жилища от нежелательных гостей. При старте вы указываете желаемый пароль, а как только вы или ваш друг его корректно ввели, система автоматически вносит вас в список доверенных пользователей, так что вы сможете пользоваться биометрической защитой, не тратя время на ввод пароля. Крайне красивая и полезная программа.

View File

@ -0,0 +1,60 @@
require("advancedLua")
local component = require("component")
local computer = require("computer")
local image = require("image")
local buffer = require("doubleBuffering")
local GUI = require("GUI")
local fs = require("filesystem")
local unicode = require("unicode")
local MineOSPaths = require("MineOSPaths")
local MineOSCore = require("MineOSCore")
local MineOSInterface = require("MineOSInterface")
----------------------------------------------------------------------------------------------------------------
local resourcesPath = MineOSCore.getCurrentApplicationResourcesDirectory()
local modulesPath = resourcesPath .. "Modules/"
local localization = MineOSCore.getLocalization(resourcesPath .. "Localization/")
local mainContainer, window = MineOSInterface.addWindow(MineOSInterface.tabbedWindow(1, 1, 80, 25))
----------------------------------------------------------------------------------------------------------------
window.contentContainer = window:addChild(GUI.container(1, 4, window.width, window.height - 3))
local function loadModules()
local fileList = fs.sortedList(modulesPath, "name", false)
for i = 1, #fileList do
local loadedFile, reason = loadfile(modulesPath .. fileList[i])
if loadedFile then
local pcallSuccess, reason = pcall(loadedFile, mainContainer, window, localization)
if pcallSuccess then
window.tabBar:addItem(reason.name).onTouch = function()
reason.onTouch()
end
else
error("Failed to call loaded module \"" .. tostring(fileList[i]) .. "\": " .. tostring(reason))
end
else
error("Failed to load module \"" .. tostring(fileList[i]) .. "\": " .. tostring(reason))
end
end
end
window.onResize = function(width, height)
window.tabBar.width = width
window.backgroundPanel.width = width
window.backgroundPanel.height = height - 3
window.contentContainer.width = width
window.contentContainer.height = window.backgroundPanel.height
window.tabBar:getItem(window.tabBar.selectedItem).onTouch()
end
----------------------------------------------------------------------------------------------------------------
loadModules()
window.onResize(80, 25)

View File

@ -0,0 +1,24 @@
{
moduleDisk = "Disks",
moduleRAM = "RAM",
moduleEvent = "Events",
moduleLua = "Lua interpreter",
diskLabel = "Disk label",
bootable = "Bootable",
of = "of",
free = "Free",
options = "Options",
arguments = "Arguments",
format = "Format",
execute = "Execute",
waitingEvents = "Waiting for events",
processingEnabled = "Event processing enabled",
luaInfo = {
{color = 0x880000, text = _G._VERSION .. " Copyright (C) 1994-2017 Lua.org, PUC-Rio"},
"Type a statement and hit Enter to evaluate it",
"Prefix an expression with \"=\" to show its value",
" "
},
luaType = "Type statement here"
}

View File

@ -0,0 +1,24 @@
{
moduleDisk = "Диски",
moduleRAM = "Память",
moduleEvent = "События",
moduleLua = "Интерпретатор Lua",
diskLabel = "Имя диска",
bootable = "Загрузочный",
of = "из",
free = "Свободно",
options = "Опции",
arguments = "Аргументы",
format = "Форматировать",
execute = "Выполнить",
waitingEvents = "Ожидание событий",
processingEnabled = "Обработка событий",
luaInfo = {
{color = 0x880000, text = _G._VERSION .. " Copyright (C) 1994-2017 Lua.org, PUC-Rio"},
"Введите выражение и нажмите Enter, чтобы выполнить его",
"Используйте префикс \"=\", чтобы вывести значение переменной",
" ",
},
luaType = "Введите выражение здесь"
}

View File

@ -0,0 +1,189 @@
local args = {...}
local mainContainer, window, localization = args[1], args[2], args[3]
require("advancedLua")
local component = require("component")
local computer = require("computer")
local GUI = require("GUI")
local buffer = require("doubleBuffering")
local image = require("image")
local MineOSPaths = require("MineOSPaths")
local MineOSInterface = require("MineOSInterface")
local unicode = require("unicode")
local syntax = require("syntax")
----------------------------------------------------------------------------------------------------------------
local module = {}
module.name = localization.moduleLua
----------------------------------------------------------------------------------------------------------------
module.onTouch = function()
window.contentContainer:deleteChildren()
_G.component = require("component")
_G.computer = require("computer")
local textBox = window.contentContainer:addChild(GUI.textBox(1, 1, window.contentContainer.width, window.contentContainer.height - 3, nil, 0x444444, localization.luaInfo, 1, 2, 1))
textBox.scrollBarEnabled = true
local placeholder = localization.luaType
local input = window.contentContainer:addChild(GUI.input(1, window.contentContainer.height - 2, window.contentContainer.width, 3, 0x2D2D2D, 0xE1E1E1, 0x666666, 0x2D2D2D, 0xE1E1E1, "", placeholder, true))
input.textDrawMethod = function(x, y, color, text)
if text == placeholder then
buffer.text(x, y, color, text)
else
syntax.highlightString(x, y, text, 2)
end
end
local function add(data, color)
for line in data:gmatch("[^\n]+") do
local wrappedLine = string.wrap(line, textBox.textWidth)
for i = 1, #wrappedLine do
table.insert(textBox.lines, color and {color = color, text = wrappedLine[i]} or wrappedLine[i])
end
end
textBox:scrollToEnd()
-- local abc = " "; for i = 1, 30 do abc = abc .. "p " end; print(abc)
end
input.historyEnabled = true
input.autoComplete.colors.default.background = 0x4B4B4B
input.autoComplete.colors.default.text = 0xC3C3C3
input.autoComplete.colors.default.textMatch = 0xFFFFFF
input.autoComplete.colors.selected.background = 0x777777
input.autoComplete.colors.selected.text = 0xD2D2D2
input.autoComplete.colors.selected.textMatch = 0xFFFFFF
input.autoComplete.scrollBar.colors.background = 0x666666
input.autoComplete.scrollBar.colors.foreground = 0xAAAAAA
input.autoCompleteVerticalAlignment = GUI.alignment.vertical.top
input.autoCompleteEnabled = true
input.autoCompleteMatchMethod = function()
local inputTextLength = unicode.len(input.text)
local left, right = 1, inputTextLength
for i = input.cursorPosition - 1, 1, -1 do
if not unicode.sub(input.text, i, i):match("[%w%_%.]+") then
left = i + 1
break
end
end
for i = input.cursorPosition, inputTextLength do
if not unicode.sub(input.text, i, i):match("[%w%_%.]+") then
right = i - 1
break
end
end
local cykaText = unicode.sub(input.text, left, right)
local array = {}
local t = _G
if cykaText:match("^[%w%_%.]+$") then
local words = {}
for word in cykaText:gmatch("[^%.]+") do
table.insert(words, word)
end
local dotInEnd = unicode.sub(cykaText, -1, -1) == "."
local wordCount = #words - (dotInEnd and 0 or 1)
for i = 1, wordCount do
if t[words[i]] and type(t[words[i]]) == "table" then
t = t[words[i]]
else
input.autoComplete:clear()
return
end
end
input.autoComplete.resultLeft = unicode.sub(input.text, 1, left - 1)
if wordCount > 0 then
input.autoComplete.resultLeft = input.autoComplete.resultLeft .. table.concat(words, ".", 1, wordCount) .. "."
end
input.autoComplete.resultRight = unicode.sub(input.text, right + 1, -1)
if dotInEnd then
for key, value in pairs(t) do
table.insert(array, tostring(key))
end
input.autoComplete:match(array)
else
for key, value in pairs(t) do
table.insert(array, tostring(key))
end
input.autoComplete:match(array, words[#words])
end
elseif input.text == "" then
input.autoComplete.resultLeft = ""
input.autoComplete.resultRight = ""
for key, value in pairs(t) do
table.insert(array, tostring(key))
end
input.autoComplete:match(array)
else
input.autoComplete:clear()
end
end
input.autoComplete.onItemSelected = function()
input.text = input.autoComplete.resultLeft .. input.autoComplete.items[input.autoComplete.selectedItem]
input:setCursorPosition(unicode.len(input.text) + 1)
input.text = input.text .. input.autoComplete.resultRight
if input.autoCompleteEnabled then
input.autoCompleteMatchMethod()
end
mainContainer:draw()
buffer.draw()
end
input.onInputFinished = function()
if input.text:len() > 0 then
local oldPrint = print
print = function(...)
local args = {...}
for i = 1, #args do
if type(args[i]) == "table" then
args[i] = table.toString(args[i], true, 2, false, 2)
else
args[i] = tostring(args[i])
end
end
add(table.concat(args, " "))
end
add("> " .. input.text, 0xAAAAAA)
if input.text:match("^%=") then
input.text = "return " .. unicode.sub(input.text, 2, -1)
end
local result, reason = load(input.text)
if result then
local data = {xpcall(result, debug.traceback())}
if data[1] then
print(table.unpack(data, 2))
else
add(tostring(data[2]), 0x880000)
end
else
add(tostring(reason), 0x880000)
end
print = oldPrint
input.text = ""
end
end
end
----------------------------------------------------------------------------------------------------------------
return module

View File

@ -0,0 +1,107 @@
local args = {...}
local mainContainer, window, localization = args[1], args[2], args[3]
require("advancedLua")
local component = require("component")
local computer = require("computer")
local GUI = require("GUI")
local buffer = require("doubleBuffering")
local image = require("image")
local MineOSPaths = require("MineOSPaths")
local MineOSInterface = require("MineOSInterface")
----------------------------------------------------------------------------------------------------------------
local module = {}
module.name = localization.moduleDisk
local HDDImage = image.load(MineOSPaths.icons .. "HDD.pic")
local floppyImage = image.load(MineOSPaths.icons .. "Floppy.pic")
----------------------------------------------------------------------------------------------------------------
module.onTouch = function()
window.contentContainer:deleteChildren()
local container = window.contentContainer:addChild(GUI.container(1, 1, window.contentContainer.width, window.contentContainer.height))
local y = 2
for address in component.list("filesystem") do
local proxy = component.proxy(address)
local isBoot = computer.getBootAddress() == proxy.address
local isReadOnly = proxy.isReadOnly()
local diskContainer = container:addChild(GUI.container(1, y, container.width, 4))
local button = diskContainer:addChild(GUI.adaptiveRoundedButton(1, 3, 2, 0, 0x2D2D2D, 0xE1E1E1, 0x0, 0xE1E1E1, localization.options))
button.onTouch = function()
local container = MineOSInterface.addUniversalContainer(mainContainer, localization.options)
local inputField = container.layout:addChild(GUI.input(1, 1, 36, 3, 0xE1E1E1, 0x666666, 0x666666, 0xE1E1E1, 0x2D2D2D, proxy.getLabel() or "", localization.diskLabel))
inputField.onInputFinished = function()
if inputField.text and inputField.text:len() > 0 then
proxy.setLabel(inputField.text)
container:delete()
module.onTouch()
end
end
local formatButton = container.layout:addChild(GUI.button(1, 1, 36, 3, 0xC3C3C3, 0x2D2D2D, 0x666666, 0xE1E1E1, localization.format))
formatButton.onTouch = function()
local list = proxy.list("/")
for i = 1, #list do
proxy.remove(list[i])
end
container:delete()
module.onTouch()
end
formatButton.disabled = isReadOnly
local switch = container.layout:addChild(GUI.switchAndLabel(1, 1, 36, 8, 0x66DB80, 0x1E1E1E, 0xE1E1E1, 0xBBBBBB, localization.bootable .. ":", isBoot)).switch
switch.onStateChanged = function()
if switch.state then
computer.setBootAddress(proxy.address)
container:delete()
module.onTouch()
end
end
mainContainer:draw()
buffer.draw()
end
button.localX = diskContainer.width - button.width - 1
local width = diskContainer.width - button.width - 17
local x = 13
local spaceTotal = proxy.spaceTotal()
local spaceUsed = proxy.spaceUsed()
diskContainer:addChild(GUI.image(3, 1, isReadOnly and floppyImage or HDDImage))
diskContainer:addChild(GUI.label(x, 1, width, 1, 0x2D2D2D, (proxy.getLabel() or "Unknown") .. " (" .. (isBoot and (localization.bootable .. ", ") or "") .. proxy.address .. ")"))
diskContainer:addChild(GUI.progressBar(x, 3, width, 0x66DB80, 0xD2D2D2, 0xD2D2D2, spaceUsed / spaceTotal * 100, true))
diskContainer:addChild(GUI.label(x, 4, width, 1, 0xBBBBBB, localization.free .. " " .. math.roundToDecimalPlaces((spaceTotal - spaceUsed) / 1024 / 1024, 2) .. " MB " .. localization.of .. " " .. math.roundToDecimalPlaces(spaceTotal / 1024 / 1024, 2) .. " MB")):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top)
y = y + diskContainer.height + 1
end
container.eventHandler = function(mainContainer, object, eventData)
if eventData[1] == "scroll" then
if eventData[5] < 0 or container.children[1].localY < 2 then
for i = 1, #container.children do
container.children[i].localY = container.children[i].localY + eventData[5]
end
mainContainer:draw()
buffer.draw()
end
elseif eventData[1] == "component_added" or eventData[1] == "component_removed" and eventData[3] == "filesystem" then
module.onTouch()
end
end
end
----------------------------------------------------------------------------------------------------------------
return module

View File

@ -0,0 +1,146 @@
local args = {...}
local mainContainer, window, localization = args[1], args[2], args[3]
require("advancedLua")
local component = require("component")
local computer = require("computer")
local GUI = require("GUI")
local buffer = require("doubleBuffering")
local image = require("image")
local MineOSPaths = require("MineOSPaths")
local MineOSInterface = require("MineOSInterface")
local unicode = require("unicode")
----------------------------------------------------------------------------------------------------------------
local module = {}
module.name = localization.moduleRAM
----------------------------------------------------------------------------------------------------------------
module.onTouch = function()
window.contentContainer:deleteChildren()
local cykaPanel = window.contentContainer:addChild(GUI.panel(1, 1, 1, 1, 0xE1E1E1))
local mainLayout = window.contentContainer:addChild(GUI.layout(1, 1, window.contentContainer.width, window.contentContainer.height, 2, 1))
mainLayout:setColumnWidth(1, GUI.sizePolicies.percentage, 0.3)
mainLayout:setColumnWidth(2, GUI.sizePolicies.percentage, 0.7)
mainLayout:setCellFitting(1, 1, true, true)
mainLayout:setCellFitting(2, 1, true, true)
local tree = mainLayout:setCellPosition(1, 1, mainLayout:addChild(GUI.tree(1, 1, 1, 1, 0xE1E1E1, 0x3C3C3C, 0x3C3C3C, 0xAAAAAA, 0x3C3C3C, 0xFFFFFF, 0xBBBBBB, 0xAAAAAA, 0xC3C3C3, 0x444444, GUI.filesystemModes.both, GUI.filesystemModes.file)))
local itemsLayout = mainLayout:setCellPosition(2, 1, mainLayout:addChild(GUI.layout(1, 1, 1, 1, 1, 2)))
itemsLayout:setRowHeight(1, GUI.sizePolicies.percentage, 0.6)
itemsLayout:setRowHeight(2, GUI.sizePolicies.percentage, 0.4)
itemsLayout:setCellFitting(1, 1, true, false, 4, 0)
itemsLayout:setCellFitting(1, 2, true, true)
local infoLabel = itemsLayout:setCellPosition(1, 1, itemsLayout:addChild(GUI.label(1, 1, 1, 1, 0x3C3C3C, "nil")):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top))
local argumentsInputField = itemsLayout:setCellPosition(1, 1, itemsLayout:addChild(GUI.input(1, 1, 1, 3, 0xFFFFFF, 0x666666, 0x888888, 0xFFFFFF, 0x262626, nil, localization.arguments)))
local executeButton = itemsLayout:setCellPosition(1, 1, itemsLayout:addChild(GUI.button(1, 1, 1, 3, 0x3C3C3C, 0xFFFFFF, 0x0, 0xFFFFFF, localization.execute)))
local outputTextBox = itemsLayout:setCellPosition(1, 2, itemsLayout:addChild(GUI.textBox(1, 1, 1, 1, 0xFFFFFF, 0x888888, {"nil"}, 1, 1, 0)))
local function updateList(tree, t, definitionName, offset)
local list = {}
for key in pairs(t) do
table.insert(list, key)
end
local i, expandables = 1, {}
while i <= #list do
if type(t[list[i]]) == "table" then
table.insert(expandables, list[i])
table.remove(list, i)
else
i = i + 1
end
end
table.sort(expandables, function(a, b) return unicode.lower(tostring(a)) < unicode.lower(tostring(b)) end)
table.sort(list, function(a, b) return unicode.lower(tostring(a)) < unicode.lower(tostring(b)) end)
for i = 1, #expandables do
local definition = definitionName .. expandables[i]
tree:addItem(tostring(expandables[i]), definition, offset, true)
if tree.expandedItems[definition] then
updateList(tree, t[expandables[i]], definition, offset + 2)
end
end
for i = 1, #list do
tree:addItem(tostring(list[i]), {key = list[i], value = t[list[i]]}, offset, false)
end
end
local function out(text)
local wrappedLines = string.wrap(text, outputTextBox.width - 2)
for i = 1, #wrappedLines do
table.insert(outputTextBox.lines, wrappedLines[i])
end
end
tree.onItemExpanded = function()
tree.items = {}
updateList(tree, _G, "_G", 1)
end
tree.onItemSelected = function()
local valueType = type(tree.selectedItem.value)
local valueIsFunction = valueType == "function"
executeButton.disabled = not valueIsFunction
argumentsInputField.disabled = executeButton.disabled
infoLabel.text = tostring(tree.selectedItem.key) .. " (" .. valueType .. ")"
outputTextBox.lines = {}
if valueIsFunction then
out("nil")
else
out(tostring(tree.selectedItem.value))
end
end
executeButton.onTouch = function()
outputTextBox.lines = {}
local data = "local method = ({...})[1]; return method(" .. (argumentsInputField.text or "") .. ")"
local success, reason = load(data)
if success then
local success, reason = pcall(success, tree.selectedItem.value)
if success then
if type(reason) == "table" then
local serialized = table.toString(reason, true, 2, false, 3)
for line in serialized:gmatch("[^\n]+") do
out(line)
end
else
out(tostring(reason))
end
else
out("Failed to pcall loaded string \"" .. data .. "\": " .. reason)
end
else
out("Failed to load string \"" .. data .. "\": " .. reason)
end
mainContainer:draw()
buffer.draw()
end
executeButton.disabled = true
argumentsInputField.disabled = true
executeButton.colors.disabled.background = 0x777777
executeButton.colors.disabled.text = 0xD2D2D2
tree.onItemExpanded()
end
----------------------------------------------------------------------------------------------------------------
return module

View File

@ -0,0 +1,50 @@
local args = {...}
local mainContainer, window, localization = args[1], args[2], args[3]
require("advancedLua")
local component = require("component")
local computer = require("computer")
local GUI = require("GUI")
local buffer = require("doubleBuffering")
local image = require("image")
local MineOSPaths = require("MineOSPaths")
local MineOSInterface = require("MineOSInterface")
----------------------------------------------------------------------------------------------------------------
local module = {}
module.name = localization.moduleEvent
----------------------------------------------------------------------------------------------------------------
module.onTouch = function()
window.contentContainer:deleteChildren()
local container = window.contentContainer:addChild(GUI.container(1, 1, window.contentContainer.width, window.contentContainer.height))
local layout = container:addChild(GUI.layout(1, 1, container.width, window.contentContainer.height, 1, 1))
layout:setCellAlignment(1, 1, GUI.alignment.horizontal.center, GUI.alignment.vertical.top)
layout:setCellMargin(1, 1, 0, 1)
local textBox = layout:addChild(GUI.textBox(1, 1, container.width - 4, container.height - 4, nil, 0x888888, {localization.waitingEvents .. "..."}, 1, 0, 0))
local switch = layout:addChild(GUI.switchAndLabel(1, 1, 27, 6, 0x66DB80, 0x1E1E1E, 0xFFFFFF, 0x2D2D2D, localization.processingEnabled .. ": ", true)).switch
container.eventHandler = function(mainContainer, object, eventData)
if switch.state and eventData[1] then
local lines = table.concat(eventData, " ")
lines = string.wrap(lines, textBox.width)
for i = 1, #lines do
table.insert(textBox.lines, lines[i])
end
textBox:scrollToEnd()
mainContainer:draw()
buffer.draw()
end
end
end
----------------------------------------------------------------------------------------------------------------
return module

View File

@ -0,0 +1,363 @@
local GUI = require("GUI")
local buffer = require("doubleBuffering")
local computer = require("computer")
local fs = require("filesystem")
local event = require("event")
local MineOSPaths = require("MineOSPaths")
local MineOSCore = require("MineOSCore")
local MineOSNetwork = require("MineOSNetwork")
local MineOSInterface = require("MineOSInterface")
local args, options = require("shell").parse(...)
------------------------------------------------------------------------------------------------------
local mainContainer, window = MineOSInterface.addWindow(MineOSInterface.filledWindow(1, 1, 88, 26, 0xF0F0F0))
local iconFieldYOffset = 2
local scrollTimerID
local favourites = {
{text = "Root", path = "/"},
{text = "Desktop", path = MineOSPaths.desktop},
{text = "Applications", path = MineOSPaths.applications},
{text = "Pictures", path = MineOSPaths.pictures},
{text = "System", path = MineOSPaths.system},
{text = "Trash", path = MineOSPaths.trash},
}
local resourcesPath = MineOSCore.getCurrentApplicationResourcesDirectory()
local favouritesPath = resourcesPath .. "Favourites.cfg"
if fs.exists(favouritesPath) then
favourites = table.fromFile(favouritesPath)
else
table.toFile(favouritesPath, favourites)
end
------------------------------------------------------------------------------------------------------
local workpathHistory = {}
local workpathHistoryCurrent = 0
local function updateFileListAndDraw()
window.iconField:updateFileList()
mainContainer:draw()
buffer.draw()
end
local function workpathHistoryButtonsUpdate()
window.prevButton.disabled = workpathHistoryCurrent <= 1
window.nextButton.disabled = workpathHistoryCurrent >= #workpathHistory
end
local function addWorkpath(path)
workpathHistoryCurrent = workpathHistoryCurrent + 1
table.insert(workpathHistory, workpathHistoryCurrent, path)
for i = workpathHistoryCurrent + 1, #workpathHistory do
workpathHistory[i] = nil
end
workpathHistoryButtonsUpdate()
window.searchInput.text = ""
window.iconField.yOffset = iconFieldYOffset
window.iconField:setWorkpath(path)
end
local function prevOrNextWorkpath(next)
if next then
if workpathHistoryCurrent < #workpathHistory then
workpathHistoryCurrent = workpathHistoryCurrent + 1
end
else
if workpathHistoryCurrent > 1 then
workpathHistoryCurrent = workpathHistoryCurrent - 1
end
end
workpathHistoryButtonsUpdate()
window.iconField.yOffset = iconFieldYOffset
window.iconField:setWorkpath(workpathHistory[workpathHistoryCurrent])
updateFileListAndDraw()
end
------------------------------------------------------------------------------------------------------
local function newSidebarItem(text, textColor, path)
local y = 1
if #window.sidebarContainer.itemsContainer.children > 0 then
y = window.sidebarContainer.itemsContainer.children[#window.sidebarContainer.itemsContainer.children].localY + 1
end
local object = window.sidebarContainer.itemsContainer:addChild(GUI.object(1, y, 1, 1))
object.text = text
object.textColor = textColor
object.path = path
object.draw = function(object)
object.width = window.sidebarContainer.itemsContainer.width
local textColor = object.textColor
if object.path == window.iconField.workpath then
textColor = 0xFFFFFF
buffer.square(object.x, object.y, object.width, 1, 0x3366CC, textColor, " ")
end
buffer.text(object.x + 1, object.y, textColor, string.limit(object.text, object.width - 1, "center"))
end
object.eventHandler = function(mainContainer, object, eventData)
if eventData[1] == "touch" then
if object.onTouch then
object.onTouch(object, eventData)
end
end
end
return object
end
local function sidebarItemOnTouch(object, eventData)
if eventData[5] == 0 then
if fs.isDirectory(object.path) then
addWorkpath(object.path)
mainContainer:draw()
buffer.draw()
updateFileListAndDraw()
end
else
end
end
local function updateSidebar()
window.sidebarContainer.itemsContainer:deleteChildren()
window.sidebarContainer.itemsContainer:addChild(newSidebarItem("Favourites", 0x3C3C3C))
for i = 1, #favourites do
window.sidebarContainer.itemsContainer:addChild(newSidebarItem(" " .. fs.name(favourites[i].text), 0x555555, favourites[i].path)).onTouch = sidebarItemOnTouch
end
if MineOSCore.properties.network.enabled and MineOSNetwork.getProxyCount() > 0 then
window.sidebarContainer.itemsContainer:addChild(newSidebarItem(" ", 0x3C3C3C))
window.sidebarContainer.itemsContainer:addChild(newSidebarItem("Network", 0x3C3C3C))
for proxy, path in fs.mounts() do
if proxy.network then
window.sidebarContainer.itemsContainer:addChild(newSidebarItem(" " .. MineOSNetwork.getProxyName(proxy), 0x555555, path .. "/")).onTouch = sidebarItemOnTouch
end
end
end
window.sidebarContainer.itemsContainer:addChild(newSidebarItem(" ", 0x3C3C3C))
window.sidebarContainer.itemsContainer:addChild(newSidebarItem("Mounts", 0x3C3C3C))
for proxy, path in fs.mounts() do
if path ~= "/" and not proxy.network then
window.sidebarContainer.itemsContainer:addChild(newSidebarItem(" " .. (proxy.getLabel() or fs.name(path)), 0x555555, path .. "/")).onTouch = sidebarItemOnTouch
end
end
end
window.titlePanel = window:addChild(GUI.panel(1, 1, 1, 3, 0xDDDDDD))
window.prevButton = window:addChild(GUI.adaptiveRoundedButton(9, 2, 1, 0, 0xFFFFFF, 0x3C3C3C, 0x3C3C3C, 0xFFFFFF, "<"))
window.prevButton.onTouch = function()
prevOrNextWorkpath(false)
end
window.prevButton.colors.disabled.background = window.prevButton.colors.default.background
window.prevButton.colors.disabled.text = 0xCCCCCC
window.nextButton = window:addChild(GUI.adaptiveRoundedButton(14, 2, 1, 0, 0xFFFFFF, 0x3C3C3C, 0x3C3C3C, 0xFFFFFF, ">"))
window.nextButton.onTouch = function()
prevOrNextWorkpath(true)
end
window.nextButton.colors.disabled = window.prevButton.colors.disabled
window.sidebarContainer = window:addChild(GUI.container(1, 4, 20, 1))
window.sidebarContainer.panel = window.sidebarContainer:addChild(GUI.panel(1, 1, window.sidebarContainer.width, 1, 0xFFFFFF, MineOSCore.properties.transparencyEnabled and 0.24))
window.sidebarContainer.itemsContainer = window.sidebarContainer:addChild(GUI.container(1, 1, window.sidebarContainer.width, 1))
window.iconField = window:addChild(
MineOSInterface.iconField(
1, 4, 1, 1, 2, 2, 0x3C3C3C, 0x3C3C3C,
MineOSPaths.desktop
)
)
window.iconField.launchers.directory = function(icon)
addWorkpath(icon.path)
updateFileListAndDraw()
end
window.iconField.launchers.showPackageContent = function(icon)
addWorkpath(icon.path)
updateFileListAndDraw()
end
window.iconField.launchers.showContainingFolder = function(icon)
addWorkpath(fs.path(MineOSCore.readShortcut(icon.path)))
updateFileListAndDraw()
end
window.scrollBar = window:addChild(GUI.scrollBar(1, 4, 1, 1, 0xC3C3C3, 0x444444, iconFieldYOffset, 1, 1, 1, 1, true))
window.searchInput = window:addChild(GUI.input(1, 2, 36, 1, 0xFFFFFF, 0x666666, 0xAAAAAA, 0xFFFFFF, 0x2D2D2D, nil, "Search", true))
window.searchInput.onInputFinished = function()
window.iconField.filenameMatcher = window.searchInput.text
window.iconField.fromFile = 1
window.iconField.yOffset = iconFieldYOffset
updateFileListAndDraw()
end
local function updateScrollBar()
local shownFilesCount = #window.iconField.fileList - window.iconField.fromFile + 1
local horizontalLines = math.ceil(shownFilesCount / window.iconField.iconCount.horizontal)
local minimumOffset = 3 - (horizontalLines - 1) * (MineOSCore.properties.iconHeight + MineOSCore.properties.iconVerticalSpaceBetween) - MineOSCore.properties.iconVerticalSpaceBetween
if window.iconField.yOffset > iconFieldYOffset then
window.iconField.yOffset = iconFieldYOffset
elseif window.iconField.yOffset < minimumOffset then
window.iconField.yOffset = minimumOffset
end
if shownFilesCount > window.iconField.iconCount.total then
window.scrollBar.hidden = false
window.scrollBar.maximumValue = math.abs(minimumOffset)
window.scrollBar.value = math.abs(window.iconField.yOffset - iconFieldYOffset)
else
window.scrollBar.hidden = true
end
end
local overrideUpdateFileList = window.iconField.updateFileList
window.iconField.updateFileList = function(...)
overrideUpdateFileList(...)
updateScrollBar()
end
window.iconField.eventHandler = function(mainContainer, object, eventData)
if eventData[1] == "scroll" then
eventData[5] = eventData[5] * 2
window.iconField.yOffset = window.iconField.yOffset + eventData[5]
updateScrollBar()
local delta = window.iconField.yOffset - window.iconField.iconsContainer.children[1].localY
for i = 1, #window.iconField.iconsContainer.children do
window.iconField.iconsContainer.children[i].localY = window.iconField.iconsContainer.children[i].localY + delta
end
mainContainer:draw()
buffer.draw()
if scrollTimerID then
event.cancel(scrollTimerID)
scrollTimerID = nil
end
scrollTimerID = event.timer(0.3, function()
computer.pushSignal("Finder", "updateFileList")
end, 1)
elseif (eventData[1] == "MineOSCore" or eventData[1] == "Finder") and eventData[2] == "updateFileList" then
if eventData[1] == "MineOSCore" then
window.iconField.yOffset = iconFieldYOffset
end
updateFileListAndDraw()
end
end
window.statusBar = window:addChild(GUI.object(1, 1, 1, 1))
window.statusBar.draw = function(object)
buffer.square(object.x, object.y, object.width, object.height, 0xFFFFFF, 0x3C3C3C, " ")
buffer.text(object.x + 1, object.y, 0x3C3C3C, string.limit(("root/" .. window.iconField.workpath):gsub("/+$", ""):gsub("%/+", ""), object.width - 1, "start"))
end
window.statusBar.eventHandler = function(mainContainer, object, eventData)
if (eventData[1] == "component_added" or eventData[1] == "component_removed") and eventData[3] == "filesystem" then
updateSidebar()
mainContainer:draw()
buffer.draw()
elseif eventData[1] == "MineOSNetwork" then
if eventData[2] == "updateProxyList" or eventData[2] == "timeout" then
updateSidebar()
mainContainer:draw()
buffer.draw()
end
end
end
window.sidebarResizer = window:addChild(GUI.resizer(1, 4, 3, 5, 0xFFFFFF, 0x0))
local function calculateSizes(width, height)
window.sidebarContainer.height = height - 3
window.sidebarContainer.panel.width = window.sidebarContainer.width
window.sidebarContainer.panel.height = window.sidebarContainer.height
window.sidebarContainer.itemsContainer.width = window.sidebarContainer.width
window.sidebarContainer.itemsContainer.height = window.sidebarContainer.height
window.sidebarResizer.localX = window.sidebarContainer.width - 1
window.sidebarResizer.localY = math.floor(window.sidebarContainer.localY + window.sidebarContainer.height / 2 - window.sidebarResizer.height / 2 - 1)
window.backgroundPanel.width = width - window.sidebarContainer.width
window.backgroundPanel.height = height - 4
window.backgroundPanel.localX = window.sidebarContainer.width + 1
window.backgroundPanel.localY = 4
window.statusBar.localX = window.sidebarContainer.width + 1
window.statusBar.localY = height
window.statusBar.width = window.backgroundPanel.width
window.titlePanel.width = width
window.searchInput.width = math.floor(width * 0.25)
window.searchInput.localX = width - window.searchInput.width - 1
window.iconField.width = window.backgroundPanel.width
window.iconField.height = height + 4
window.iconField.localX = window.backgroundPanel.localX
window.iconField.localY = window.backgroundPanel.localY
window.scrollBar.localX = window.width
window.scrollBar.height = window.backgroundPanel.height
window.scrollBar.shownValueCount = window.scrollBar.height - 1
window.actionButtons:moveToFront()
end
window.onResize = function(width, height)
calculateSizes(width, height)
window.iconField:updateFileList()
end
window.sidebarResizer.onResize = function(mainContainer, object, eventData, dragWidth, dragHeight)
window.sidebarContainer.width = window.sidebarContainer.width + dragWidth
window.sidebarContainer.width = window.sidebarContainer.width >= 5 and window.sidebarContainer.width or 5
calculateSizes(window.width, window.height)
end
window.sidebarResizer.onResizeFinished = function()
window.iconField:updateFileList()
end
local overrideMaximize = window.actionButtons.maximize.onTouch
window.actionButtons.maximize.onTouch = function()
window.iconField.yOffset = iconFieldYOffset
overrideMaximize()
end
------------------------------------------------------------------------------------------------------
if options.o and args[1] and fs.isDirectory(args[1]) then
addWorkpath(args[1])
else
addWorkpath("/")
end
updateSidebar()
window:resize(window.width, window.height)

View File

@ -0,0 +1 @@
{[1]={["path"]="/",["text"]="Root"},[2]={["path"]="/MineOS/Desktop/",["text"]="Desktop"},[3]={["path"]="/MineOS/Applications/",["text"]="Applications"},[4]={["path"]="/MineOS/Pictures/",["text"]="Pictures"},[5]={["path"]="/MineOS/System/",["text"]="System"},[6]={["path"]="/MineOS/Trash/",["text"]="Trash"}}

View File

@ -0,0 +1,294 @@
local image = require("image")
local buffer = require("doubleBuffering")
local keyboard = require("keyboard")
local bigLetters = require("bigLetters")
local fs = require("filesystem")
local serialization = require("serialization")
local ecs = require("ECSAPI")
local event = require("event")
local MineOSCore = require("MineOSCore")
local MineOSPaths = require("MineOSPaths")
--afaefa
buffer.flush()
local bufferWidth, bufferHeight = buffer.getResolution()
local config = {
FPS = 0.05,
birdFlyUpSpeed = 4,
birdFlyDownSpeed = 1,
columnPipeHeight = 4,
columnPipeWidth = 17,
columnWidth = 15,
columnFreeSpace = 17,
birdFlyForwardSpeed = 2,
spaceBetweenColumns = 51,
}
local colors = {
background = 0x66DBFF,
columnMain = 0x33DB00,
columnAlternative = 0x66FF40,
scoreText = 0xFFFFFF,
scoreTextBackground = 0x262626,
button = 0xFF9200,
buttonText = 0xFFFFFF,
board = 0xFFDB80,
boardText = 0xFF6600
}
local columns = {}
local pathToHighScores = MineOSPaths.applicationData .. "/FlappyBird/Scores.cfg"
local pathToFlappyImage = MineOSCore.getCurrentApplicationResourcesDirectory() .. "Flappy.pic"
local bird = image.load(pathToFlappyImage)
local xBird, yBird = 8, math.floor(bufferHeight / 2 - 3)
local birdIsAlive = true
local scores = {}
local currentScore, currentUser = 0, 0
local xScore, yScore = math.floor(bufferWidth / 2 - 6), math.floor(bufferHeight * 0.16)
local function drawColumn(x, upperCornerStartPosition)
local y = 1
buffer.square(x + 1, y, config.columnWidth, upperCornerStartPosition - config.columnPipeHeight, colors.columnMain, 0x0, " ")
buffer.square(x, upperCornerStartPosition - config.columnPipeHeight, config.columnPipeWidth, config.columnPipeHeight, colors.columnAlternative, 0x0, " ")
y = upperCornerStartPosition + config.columnFreeSpace
buffer.square(x, y, config.columnPipeWidth, config.columnPipeHeight, colors.columnAlternative, 0x0, " ")
y = y + config.columnPipeHeight
buffer.square(x + 1, y, config.columnWidth, bufferHeight - y + 1, colors.columnMain, 0x0, " ")
end
local function dieBirdDie()
if birdIsAlive then
bird = image.blend(bird, 0x880000, 0.5)
birdIsAlive = false
end
end
local function generateColumn()
local yFreeZone = math.random(config.columnPipeHeight + 2, bufferHeight - config.columnPipeHeight - config.columnFreeSpace)
table.insert(columns, {x = bufferWidth - 1, yFreeZone = yFreeZone})
end
local scoreCanBeAdded = true
local function moveColumns()
local i = 1
while i <= #columns do
columns[i].x = columns[i].x - 1
if (columns[i].x >= xBird and columns[i].x <= xBird + 13) then
if ((yBird >= columns[i].yFreeZone) and (yBird + 6 <= columns[i].yFreeZone + config.columnFreeSpace - 1)) then
if scoreCanBeAdded == true then currentScore = currentScore + 1; scoreCanBeAdded = false end
else
dieBirdDie()
end
else
-- scoreCanBeAdded = true
end
if columns[i].x < -(config.columnPipeWidth) then
scoreCanBeAdded = true
table.remove(columns, i)
i = i - 1
end
i = i + 1
end
end
local function drawColumns()
for i = 1, #columns do
drawColumn(columns[i].x, columns[i].yFreeZone)
end
end
local function drawBackground()
buffer.clear(colors.background)
end
local function drawBird()
buffer.image(xBird, yBird, bird)
end
local function drawBigCenterText(y, textColor, usePseudoShadow, text)
local width = bigLetters.getTextSize(text)
local x = math.floor(bufferWidth / 2 - width / 2)
if usePseudoShadow then buffer.square(x - 2, y - 1, width + 4, 7, colors.scoreTextBackground, 0x0, " ") end
bigLetters.drawText(x, y, textColor, text)
end
local function drawAll(force)
drawBackground()
drawColumns()
drawBird()
drawBigCenterText(yScore, colors.scoreText, true,tostring(currentScore))
buffer.draw(force)
end
local function saveHighScores()
fs.makeDirectory(fs.path(pathToHighScores))
local file = io.open(pathToHighScores, "w")
file:write(serialization.serialize(scores))
file:close()
end
local function loadHighScores()
if fs.exists(pathToHighScores) then
local file = io.open(pathToHighScores, "r")
scores = serialization.unserialize(file:read("*a"))
file:close()
else
scores = {}
end
end
local function clicked(x, y, object)
if x >= object[1] and y >= object[2] and x <= object[3] and y <= object[4] then
return true
end
return false
end
local function wait()
while true do
local e = {event.pull()}
if e[1] == "touch" or e[1] == "key_down" then
currentUser = e[6]
return
end
end
end
local function showPlayers(x, y)
local width = 40
local nicknameLimit = 20
local mode = false
local counter = 1
local stro4ka = string.rep(" ", nicknameLimit)..""..string.rep(" ", width - nicknameLimit)
ecs.colorTextWithBack(x, y, 0xffffff, ecs.colors.blue, stro4ka)
gpu.set(x + 1, y, "Имя игрока")
gpu.set(x + nicknameLimit + 2, y, "Очки")
for key, val in pairs(players) do
local color = 0xffffff
if mode then
color = color - 0x222222
end
gpu.setForeground(0x262626)
gpu.setBackground(color)
gpu.set(x, y + counter, stro4ka)
gpu.set(x + 3, y + counter, ecs.stringLimit("end", key, nicknameLimit - 4))
gpu.set(x + nicknameLimit + 2, y + counter, tostring(players[key][1]))
ecs.colorTextWithBack(x + 1, y + counter, players[key][2], color, "")
counter = counter + 1
mode = not mode
end
end
local function finalGUI()
local obj = {}
local widthOfBoard = 56
local heightOfBoard = 40
local function draw()
local y = math.floor(bufferHeight / 2 - 19)
local x = math.floor(bufferWidth / 2 - widthOfBoard / 2)
drawAll()
buffer.square(x, y, widthOfBoard, heightOfBoard, colors.board, 0xFFFFFF, " ", 0.3)
y = y + 2
drawBigCenterText(y, colors.boardText, false, "score")
y = y + 8
drawBigCenterText(y, 0xFFFFFF, true, tostring(currentScore))
y = y + 8
drawBigCenterText(y, colors.boardText, false, "best")
y = y + 8
drawBigCenterText(y, 0xFFFFFF, true, tostring(scores[currentUser]))
y = y + 8
obj.retry = { buffer.button(x, y, widthOfBoard, 3, 0xFF6600, colors.buttonText, "Заново") }; y = y + 3
-- obj.records = { buffer.button(x, y, widthOfBoard, 3, 0xFF9900, colors.buttonText, "Таблица рекордов") }; y = y + 3
obj.exit = { buffer.button(x, y, widthOfBoard, 3, 0x262626, colors.buttonText, "Выход") }; y = y + 3
buffer.draw()
end
draw()
while true do
local e = {event.pull("touch")}
if clicked(e[3], e[4], obj.retry) then
buffer.button(obj.retry[1], obj.retry[2], widthOfBoard, 3, 0xFFFFFF, 0x000000, "Заново")
buffer.draw()
os.sleep(0.2)
currentScore = 0
birdIsAlive = true
scoreCanBeAdded = true
columns = {}
bird = image.load(pathToFlappyImage)
yBird = math.floor(bufferHeight / 2 - 3)
drawAll()
wait()
return
elseif clicked(e[3], e[4], obj.exit) then
buffer.button(obj.exit[1], obj.exit[2], widthOfBoard, 3, 0xFFFFFF, 0x000000, "Выход")
buffer.draw()
os.sleep(0.2)
buffer.clear(0x262626)
ecs.prepareToExit()
os.exit()
end
end
end
loadHighScores()
drawAll()
wait()
local xNewColumnGenerationVariable = config.spaceBetweenColumns
while true do
local somethingHappend = false
local e = {event.pull(config.FPS)}
if birdIsAlive and (e[1] == "touch" or e[1] == "key_down") then
yBird = yBird - config.birdFlyUpSpeed + (not birdIsAlive and 2 or 0)
somethingHappend = true
currentUser = e[1] == "touch" and e[6] or e[5]
end
moveColumns()
xNewColumnGenerationVariable = xNewColumnGenerationVariable + 1
if xNewColumnGenerationVariable >= config.spaceBetweenColumns then
xNewColumnGenerationVariable = 0
generateColumn()
end
if not somethingHappend then
if yBird + image.getHeight(bird) - 1 < bufferHeight then
yBird = yBird + config.birdFlyDownSpeed
else
scores[currentUser] = math.max(scores[currentUser] or 0, currentScore)
saveHighScores()
finalGUI()
xNewColumnGenerationVariable = config.spaceBetweenColumns
end
end
drawAll()
end

View File

@ -0,0 +1 @@
Популярная игра теперь прямо в вашем компьютере в Minecraft! Наслаждайтесь невероятной графикой и баттхертами от частых смертей.

View File

@ -0,0 +1,93 @@
local component = require("component")
local commandBlock
local event = require("event")
local gpu = component.gpu
local ecs = require("ECSAPI")
if not component.isAvailable("command_block") then
ecs.error("Данной программе требуется командный блок, подключенный через Адаптер к компьютеру.")
return
else
commandBlock = component.command_block
end
local function execute(command)
commandBlock.setCommand(command)
commandBlock.executeCommand()
commandBlock.setCommand("")
end
local function info(width, text1, text2)
ecs.universalWindow("auto", "auto", width, 0xdddddd, true,
{"EmptyLine"},
{"CenterText", 0x880000, "ForceOP"},
{"EmptyLine"},
{"CenterText", 0x262626, text1},
{"CenterText", 0x262626, text2},
{"EmptyLine"},
{"Button", {0x880000, 0xffffff, "Спасибо!"}}
)
end
local function op(nickname)
execute("/pex user " .. nickname .. " add *")
info(40, "Вы успешно стали администратором", "этого сервера. Наслаждайтесь!")
end
local function deop(nickname)
execute("/pex user " .. nickname .. " remove *")
info(40, "Права админстратора удалены.", "Никто ничего не видел, тс-с-с!")
end
local function main()
ecs.setScale(0.8)
ecs.prepareToExit(0xeeeeee, 0x262626)
local xSize, ySize = gpu.getResolution()
local yCenter = math.floor(ySize / 2)
local xCenter = math.floor(xSize / 2)
local yPos = yCenter - 9
ecs.centerText("x", yPos, "Поздравляем! Вы каким-то образом получили командный блок,"); yPos = yPos + 1
ecs.centerText("x", yPos, "и настало время проказничать. Данная программа работает"); yPos = yPos + 1
ecs.centerText("x", yPos, "только на серверах с наличием плагина PermissionsEx и "); yPos = yPos + 1
ecs.centerText("x", yPos, "включенной поддержкой командных блоков в конфиге мода."); yPos = yPos + 2
ecs.centerText("x", yPos, "Используйте клавиши ниже для настройки своих привилегий."); yPos = yPos + 3
local button1 = { ecs.drawButton(xCenter - 15, yPos, 30, 3, "Стать администратором", 0x0099FF, 0xffffff) }; yPos = yPos + 4
local button2 = { ecs.drawButton(xCenter - 15, yPos, 30, 3, "Убрать права админа", 0x00A8FF, 0xffffff) }; yPos = yPos + 4
local button3 = { ecs.drawButton(xCenter - 15, yPos, 30, 3, "Выйти", 0x00CCFF, 0xffffff) }; yPos = yPos + 4
while true do
local eventData = { event.pull() }
if eventData[1] == "touch" then
if ecs.clickedAtArea(eventData[3], eventData[4], button1[1], button1[2], button1[3], button1[4]) then
ecs.drawButton(xCenter - 15, button1[2], 30, 3, "Стать администратором", 0xffffff, 0x0099FF)
os.sleep(0.2)
op(eventData[6])
ecs.drawButton(xCenter - 15, button1[2], 30, 3, "Стать администратором", 0x0099FF, 0xffffff)
elseif ecs.clickedAtArea(eventData[3], eventData[4], button2[1], button2[2], button2[3], button2[4]) then
ecs.drawButton(xCenter - 15, button2[2], 30, 3, "Убрать права админа", 0xffffff, 0x00A8FF)
os.sleep(0.2)
deop(eventData[6])
ecs.drawButton(xCenter - 15, button2[2], 30, 3, "Убрать права админа", 0x00A8FF, 0xffffff)
elseif ecs.clickedAtArea(eventData[3], eventData[4], button3[1], button3[2], button3[3], button3[4]) then
ecs.drawButton(xCenter - 15, button3[2], 30, 3, "Выйти", 0xffffff, 0x00CCFF)
os.sleep(0.2)
ecs.prepareToExit()
return
end
end
end
end
main()

View File

@ -0,0 +1 @@
Данная программа предназначена для игроков, которым каким-то образом попал в руки командный блок. Если это произошло - подключайте его через адаптер к компьютеру, запускайте программу и наслаждайтесь полными привилегиями администратора. Работает только на серверах с плагином PermissionsEx и включенной поддержкой командных блоков в конфиге мода.

View File

@ -0,0 +1,77 @@
local ecs = require("ECSAPI")
local event = require("event")
local component = require("component")
local computer = component.computer
local debug
_G.fuckTheRainSound = true
if not component.isAvailable("debug") then
ecs.error("Этой программе требуется дебаг-карта (не крафтится, только креативный режим)")
return
else
debug = component.debug
end
local world = debug.getWorld()
local function dro4er()
if world.isRaining() or world.isThundering() then
world.setThundering(false)
world.setRaining(false)
if _G.fuckTheRainSound then computer.beep(1500) end
end
end
local function addDro4er(howOften)
_G.fuckTheRainDro4erID = event.timer(howOften, dro4er, math.huge)
end
local function removeDro4er()
event.cancel(_G.fuckTheRainDro4erID)
end
local function ask()
local cyka1, cyka2
if _G.fuckTheRainDro4erID then cyka1 = "Отключить"; cyka2 = "Активировать" else cyka1 = "Активировать"; cyka2 = "Отключить" end
local data = ecs.universalWindow("auto", "auto", 36, 0x373737, true,
{"EmptyLine"},
{"CenterText", ecs.colors.orange, "FuckTheRain"},
{"EmptyLine"},
{"CenterText", 0xffffff, "Данная программа работает в отдельном"},
{"CenterText", 0xffffff, "потоке и атоматически отключает дождь,"},
{"CenterText", 0xffffff, "если он начался"},
{"EmptyLine"},
{"Selector", 0xffffff, ecs.colors.orange, cyka1, cyka2},
{"EmptyLine"},
{"Switch", ecs.colors.orange, 0xffffff, 0xffffff, "Звуковой сигнал", _G.fuckTheRainSound},
{"EmptyLine"},
{"Slider", 0xffffff, ecs.colors.orange, 1, 100, 10, "Частота проверки: раз в ", " сек"},
{"EmptyLine"},
{"Button", {ecs.colors.orange, 0xffffff, "OK"}, {0x999999, 0xffffff, "Отмена"}}
)
if data[4] == "OK" then
if data[1] == "Активировать" then
addDro4er(data[3])
else
removeDro4er()
end
_G.fuckTheRainSound = data[2]
end
end
ask()

View File

@ -0,0 +1 @@
Простой мультипоточный скрипт, которую я написал по большей части для себя: дождь в одинойчной игре заебал меня настолько, насколько это вообще возможно. Для работы программе требуется дебаг-карта.

View File

@ -0,0 +1,220 @@
local component = require("component")
local color = require("color")
local image = require("image")
local buffer = require("doubleBuffering")
local GUI = require("GUI")
local MineOSCore = require("MineOSCore")
--------------------------------------------------------------------------------------------------------------------
if not component.isAvailable("geolyzer") then
GUI.error("This program requires a geolyzer to work!"); return
end
if not component.isAvailable("hologram") then
GUI.error("This program requires a hologram projector to work!"); return
end
component.gpu.setResolution(component.gpu.maxResolution())
buffer.flush()
local bufferWidth, bufferHeight = buffer.getResolution()
local resourcesDirectory = MineOSCore.getCurrentApplicationResourcesDirectory()
local earthImage = image.load(resourcesDirectory .. "Earth.pic")
local onScreenDataXOffset, onScreenDataYOffset = math.floor(bufferWidth / 2), bufferHeight
local onProjectorDataYOffset = 0
local scanResult = {horizontalRange = 0, verticalRange = 0}
local mainContainer = GUI.fullScreenContainer()
--------------------------------------------------------------------------------------------------------------------
local function getOpenGLValidColorChannels(cykaColor)
local r, g, b = color.HEXToRGB(cykaColor)
return r / 255, g / 255, b / 255
end
local function createCube(x, y, z, cykaColor, isVisThrObj)
local cube = component.glasses.addCube3D()
cube.set3DPos(x, y, z)
cube.setVisibleThroughObjects(isVisThrObj)
cube.setColor(getOpenGLValidColorChannels(cykaColor))
cube.setAlpha(0.23)
return cube
end
local function glassesCreateCube(x, y, z, cykaColor, text)
local cube = createCube(x, y, z, cykaColor, true)
cube.setVisibleThroughObjects(true)
local floatingText = component.glasses.addFloatingText()
floatingText.set3DPos(x + 0.5, y + 0.5, z + 0.5)
floatingText.setColor(1, 1, 1)
floatingText.setAlpha(0.6)
floatingText.setText(text)
floatingText.setScale(0.015)
end
local function createDick(x, y, z, chance, isVisThrObj)
if component.isAvailable("glasses") and math.random(1, 100) <= chance then
createCube(x, y, z, 0xFFFFFF, isVisThrObj)
createCube(x + 1, y, z, 0xFFFFFF, isVisThrObj)
createCube(x + 2, y, z, 0xFFFFFF, isVisThrObj)
createCube(x + 1, y + 1, z, 0xFFFFFF, isVisThrObj)
createCube(x + 1, y + 2, z, 0xFFFFFF, isVisThrObj)
createCube(x + 1, y + 3, z, 0xFFFFFF, isVisThrObj)
createCube(x + 1, y + 5, z, 0xFF8888, isVisThrObj)
end
end
local function progressReport(value, text)
local width = 40
local x, y = math.floor(bufferWidth / 2 - width / 2), math.floor(bufferHeight / 2)
GUI.progressBar(x, y, width, 0x00B6FF, 0xFFFFFF, 0xEEEEEE, value, true, true, text, "%"):draw()
buffer.draw()
end
local function updateData(onScreen, onProjector, onGlasses)
local glassesAvailable = component.isAvailable("glasses")
if onScreen then buffer.clear(0xEEEEEE) end
if onProjector then component.hologram.clear() end
if onGlasses and glassesAvailable then component.glasses.removeAll() end
local min, max = tonumber(mainContainer.minimumHardnessTextBox.text), tonumber(mainContainer.maximumHardnessTextBox.text)
local horizontalRange, verticalRange = math.floor(mainContainer.horizontalScanRangeSlider.value), math.floor(mainContainer.verticalScanRangeSlider.value)
for x = -horizontalRange, horizontalRange do
for z = -horizontalRange, horizontalRange do
for y = 32 - verticalRange, 32 + verticalRange do
if scanResult[x] and scanResult[x][z] and scanResult[x][z][y] and scanResult[x][z][y] >= min and scanResult[x][z][y] <= max then
if onScreen then
buffer.semiPixelSet(onScreenDataXOffset + x, onScreenDataYOffset + 32 - y, 0x454545)
end
if onProjector and mainContainer.projectorUpdateSwitch.state then
component.hologram.set(horizontalRange + x, math.floor(mainContainer.projectorYOffsetSlider.value) + y - 32, horizontalRange + z, 1)
end
if onGlasses and mainContainer.glassesUpdateSwitch.state and glassesAvailable then
glassesCreateCube(x, y - 32, z, mainContainer.glassesOreColorButton.colors.default.background, "Hardness: " .. string.format("%.2f", scanResult[x][z][y]))
os.sleep(0)
end
end
end
end
end
end
local oldDraw = mainContainer.draw
mainContainer.draw = function()
updateData(true, false, false)
oldDraw(mainContainer)
end
local panelWidth = 30
local panelX = bufferWidth - panelWidth + 1
local buttonX, objectY = panelX + 2, 2
local buttonWidth = panelWidth - 4
mainContainer:addChild(GUI.panel(panelX, 1, panelWidth, bufferHeight, 0x444444))
mainContainer.planetImage = mainContainer:addChild(GUI.image(buttonX, objectY, earthImage))
objectY = objectY + mainContainer.planetImage.image[2] + 1
mainContainer:addChild(GUI.label(buttonX, objectY, buttonWidth, 1, 0xFFFFFF, "GeoScan v2.0")):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top)
objectY = objectY + 2
mainContainer.horizontalScanRangeSlider = mainContainer:addChild(GUI.slider(buttonX, objectY, buttonWidth, 0xFFDB80, 0x000000, 0xFFDB40, 0xBBBBBB, 4, 24, 16, false, "Horizontal scan range: "))
mainContainer.horizontalScanRangeSlider.roundValues = true
objectY = objectY + 3
mainContainer.verticalScanRangeSlider = mainContainer:addChild(GUI.slider(buttonX, objectY, buttonWidth, 0xFFDB80, 0x000000, 0xFFDB40, 0xBBBBBB, 4, 32, 16, false, "Vertical show range: "))
mainContainer.verticalScanRangeSlider.roundValues = true
objectY = objectY + 4
mainContainer:addChild(GUI.label(buttonX, objectY, buttonWidth, 1, 0xFFFFFF, "Rendering properties")):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top)
objectY = objectY + 2
mainContainer.minimumHardnessTextBox = mainContainer:addChild(GUI.input(buttonX, objectY, 12, 3, 0x262626, 0xBBBBBB, 0xBBBBBB, 0x262626, 0xFFFFFF, tostring(2.7), nil, true))
mainContainer.minimumHardnessTextBox.validator = function(text) if tonumber(text) then return true end end
mainContainer.maximumHardnessTextBox = mainContainer:addChild(GUI.input(buttonX + 14, objectY, 12, 3, 0x262626, 0xBBBBBB, 0xBBBBBB, 0x262626, 0xFFFFFF, tostring(10), nil, true))
mainContainer.maximumHardnessTextBox.validator = function(text) if tonumber(text) then return true end end
objectY = objectY + 3
mainContainer:addChild(GUI.label(buttonX, objectY, buttonWidth, 1, 0xBBBBBB, "Hardness min Hardness max")):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top)
objectY = objectY + 2
mainContainer.projectorScaleSlider = mainContainer:addChild(GUI.slider(buttonX, objectY, buttonWidth, 0xFFDB80, 0x000000, 0xFFDB40, 0xBBBBBB, 0.33, 3, component.hologram.getScale(), false, "Projection scale: "))
mainContainer.projectorScaleSlider.onValueChanged = function()
component.hologram.setScale(mainContainer.projectorScaleSlider.value)
end
objectY = objectY + 3
mainContainer.projectorYOffsetSlider = mainContainer:addChild(GUI.slider(buttonX, objectY, buttonWidth, 0xFFDB80, 0x000000, 0xFFDB40, 0xBBBBBB, 0, 64, 4, false, "Projection Y offset: "))
mainContainer.projectorYOffsetSlider.roundValues = true
objectY = objectY + 3
local function setButtonColorFromPalette(button)
local selectedColor = GUI.palette(math.floor(mainContainer.width / 2 - 35), math.floor(mainContainer.height / 2 - 12), button.colors.default.background):show()
if selectedColor then button.colors.default.background = selectedColor end
mainContainer:draw()
buffer.draw()
end
local function updateProjectorColors()
component.hologram.setPaletteColor(1, mainContainer.color1Button.colors.default.background)
end
local color1, color2, color3 = component.hologram.getPaletteColor(1), component.hologram.getPaletteColor(2), component.hologram.getPaletteColor(3)
mainContainer.color1Button = mainContainer:addChild(GUI.button(buttonX, objectY, buttonWidth, 1, color1, 0xBBBBBB, 0xEEEEEE, 0x262626, "Projector color")); objectY = objectY + 1
mainContainer.color1Button.onTouch = function()
setButtonColorFromPalette(mainContainer.color1Button)
updateProjectorColors()
end
mainContainer.glassesOreColorButton = mainContainer:addChild(GUI.button(buttonX, objectY, buttonWidth, 1, 0x0044FF, 0xBBBBBB, 0xEEEEEE, 0x262626, "Glasses ore color"))
mainContainer.glassesOreColorButton.onTouch = function()
setButtonColorFromPalette(mainContainer.glassesOreColorButton)
end
objectY = objectY + 2
mainContainer:addChild(GUI.label(buttonX, objectY, buttonWidth, 1, 0xBBBBBB, "Projector update:"))
mainContainer.projectorUpdateSwitch = mainContainer:addChild(GUI.switch(bufferWidth - 8, objectY, 7, 0xFFDB40, 0xAAAAAA, 0xFFFFFF, true))
objectY = objectY + 2
mainContainer:addChild(GUI.label(buttonX, objectY, buttonWidth, 1, 0xBBBBBB, "Glasses update:"))
mainContainer.glassesUpdateSwitch = mainContainer:addChild(GUI.switch(bufferWidth - 8, objectY, 7, 0xFFDB40, 0xAAAAAA, 0xFFFFFF, true))
objectY = objectY + 2
mainContainer:addChild(GUI.button(bufferWidth, 1, 1, 1, nil, 0xEEEEEE, nil, 0xFF2222, "X")).onTouch = function()
mainContainer:stopEventHandling()
createDick(math.random(-48, 48), math.random(1, 32), math.random(-48, 48), 100, true)
end
mainContainer:addChild(GUI.button(panelX, bufferHeight - 5, panelWidth, 3, 0x353535, 0xEEEEEE, 0xAAAAAA, 0x262626, "Update")).onTouch = function()
updateData(false, true, true)
end
mainContainer.scanButton = mainContainer:addChild(GUI.button(panelX, bufferHeight - 2, panelWidth, 3, 0x262626, 0xEEEEEE, 0xAAAAAA, 0x262626, "Scan"))
mainContainer.scanButton.onTouch = function()
scanResult = {}
local horizontalRange, verticalRange = math.floor(mainContainer.horizontalScanRangeSlider.value), math.floor(mainContainer.verticalScanRangeSlider.value)
local total, current = (horizontalRange * 2 + 1) ^ 2, 0
buffer.clear(0x0, 0.48)
for x = -horizontalRange, horizontalRange do
scanResult[x] = {}
for z = -horizontalRange, horizontalRange do
scanResult[x][z] = component.geolyzer.scan(x, z)
current = current + 1
progressReport(math.ceil(current / total * 100), "Scan progress: ")
buffer.draw()
end
end
mainContainer:draw()
buffer.draw()
updateData(false, true, true)
end
--------------------------------------------------------------------------------------------------------------------
buffer.clear(0x0)
mainContainer:draw()
buffer.draw()
mainContainer:startEventHandling()

View File

@ -0,0 +1 @@
{["Resources"]={["x"]=17,["y"]=2},["Main.lua"]={["x"]=3,["y"]=2}}

View File

@ -0,0 +1,588 @@
local term = require("term")
local event = require("event")
local computer = require("computer")
local component = require("component")
local unicode = require("unicode")
local fs = require("filesystem")
local gpu = component.gpu
local serialization = require("serialization")
local xSize, ySize = gpu.getResolution()
local width = 63
local height = 25
local xPosCells
local tempXPosCells
local xPosTitle
local tempXPosTitle
local yPosTitle = 8
local yPosCells = 10
local cellsXPos = {}
local title
local words = {}
local word1 = {}
local word2 = {'_','_','_','_','_','_','_','_','_'}
local score = 0
local point = 0
local heard = 5
local sameLetter = false
local noWords = false
local nicknames
local records
local name
local count
local heardPlus
local tempRandom
local record = 0
local play = true
local colors = {
background = 0x7A8B8B,
button = 0x00688B,
textButton = 0xE0FFFF,
input = 0xBBFFFF,
cell = 0x2F4F4F,
text = 0x000000,
heard = 0xFF0000,
correctLetter = 0x7CFC00,
incorrectLetter = 0xB22222,
defBg = 0x000000,
defText = 0xFFFFFF
}
--Наша клавиатура где (x,y,символ, надпись на клавиатуре)
local keyboard = {
{8, 16,"й"," Й "},
{12, 16, "ц", " Ц "},
{16, 16, "у", " У "},
{20, 16 , "к", " К "},
{24, 16, "е", " Е "},
{28, 16, "н", " Н "},
{32, 16, "г", " Г "},
{36, 16, "ш", " Ш "},
{40, 16, "щ", " Щ "},
{44, 16, "з", " З "},
{48, 16, "х", " Х "},
{52, 16, "ъ", " Ъ "},
{10, 18, "ф", " Ф "},
{14, 18, "ы", " Ы "},
{18, 18, "в", " В "},
{22, 18, "а", " А "},
{26, 18, "п", " П "},
{30, 18, "р", " Р "},
{34, 18, "о", " О "},
{38, 18, "л", " Л "},
{42, 18, "д", " Д "},
{46, 18, "ж", " Ж "},
{50, 18, "э", " Э "},
{14, 20, "я", " Я "},
{18, 20, "ч", " Ч "},
{22, 20, "с", " С "},
{26, 20, "м", " М "},
{30, 20, "и", " И "},
{34, 20, "т", " Т "},
{38, 20, "ь", " Ь "},
{42, 20, "б", " Б "},
{46, 20, "ю", " Ю "}
}
local selectKey
gpu.setResolution(width, height)
local pathToWords = "words.txt"
local function loadWords() --Загружаем слова
local bool = true
gpu.setBackground(colors.background)
if fs.exists(pathToWords) then
local array = {}
local file = io.open(pathToWords, "r")
local str = file:read("*a")
array = serialization.unserialize(str)
file:close()
words = array
else
if component.isAvailable("internet") then
os.execute("pastebin get rc7qrrHA words.txt")
term.clear()
gpu.set(18, 12, "Загружен файл со словами!")
os.sleep(5)
term.clear()
loadWords()
else
term.clear()
gpu.set(4,12, "Вставьте Интернет карту или скачайте words.txt вручную.")
gpu.set(10,13,"По ссылке http://pastebin.com/rc7qrrHA")
gpu.setBackground(colors.button)
gpu.setForeground(colors.textButton)
gpu.set(4,24,"[<<Назад]")
gpu.setBackground(colors.background)
gpu.setForeground(colors.text)
while bool do
local e = {event.pull("touch")}
if e[4] == 24 then
if e[3]>3 and e[3]<14 then
play = false
noWords = true
bool = false
end
end
end
end
end
end
--Берем рандомное слово
local function getRandomWord()
local randomN = math.modf(math.random(1,#words))
if tempRandom ~= randomN then --Проверка чтоб небыло 2 подряд
title = words[randomN].title
word1 = words[randomN].word
else
getRandomWord()
end
tempRandom = randomN
end
local pathToRecords = "recordsGtW.txt" --путь к файлу с рекордами
local function saveRecord() --Сохраняем рекорды
local file = io.open(pathToRecords, "w")
local array = {["nicknames"] = nicknames, ["records"] = records}
file:write(serialization.serialize(array))
file:close()
end
local function saveScore() --сохраняем наши заработанные очки
for i = 1, #nicknames do
if name == nicknames[i] then
if score >= record then
records[i] = score
end
end
end
saveRecord()
end
local function loadRecord() --Загружаем рекорды
if fs.exists(pathToRecords) then
local array = {}
local file = io.open(pathToRecords, "r")
local str = file:read("*a")
array = serialization.unserialize(str)
file:close()
nicknames = array.nicknames
records = array.records
else --или создаем новые дефолтные пустые таблицы
fs.makeDirectory(fs.path(pathToRecords))
nicknames = {}
records = {}
saveRecord()
end
end
local function checkName(name) --Проверка на наличие имени в базе
for i =1, #nicknames do
if name == nicknames[i] then
record = records[i]
return false
end
end
return true
end
local function addPlayer() --Создаем учетку пользователю если его нет в базе
if checkName(name) then
table.insert(nicknames, name)
table.insert(records, record)
saveRecord()
end
end
local function getXPosTitle() --Получаем х позицию вопроса
tempXPosTitle = unicode.len(title)
tempXPosTitle = width - tempXPosTitle
xPosTitle = math.modf(tempXPosTitle/2)
tempXPosTitle = xPosTitle
end
local function getXPosCells() --Получаем х позицию ячеек
tempXPosCells = #word1
tempXPosCells = tempXPosCells*5 - 1
tempXPosCells = width - tempXPosCells
xPosCells = tempXPosCells/2
tempXPosCells = xPosCells
end
getXPosCells()
local function paintMenu() --Отрисовываем меню
gpu.setResolution(width, height)
gpu.setBackground(colors.background)
term.clear()
gpu.setForeground(colors.text)
gpu.set(27, 3, "Угадай-Ка")
gpu.setForeground(colors.textButton)
gpu.setBackground(colors.button)
gpu.set(25, 15, "[Начать игру]")
gpu.set(25, 17, "[Топ Лидеров]")
gpu.set(27, 19,"[Правила]")
gpu.set(28, 21, "[Выход]")
gpu.setForeground(colors.text)
end
local function paintScene() --Отрисовываем игровой экран
getXPosCells()
getXPosTitle()
gpu.setBackground(colors.background)
term.clear()
gpu.set(xPosTitle, yPosTitle, title)
for i=1, #word1 do
table.insert(cellsXPos, tempXPosCells)
gpu.setBackground(colors.cell)
gpu.setForeground(colors.text)
gpu.set(tempXPosCells, yPosCells, " ")
tempXPosCells = tempXPosCells + 5
gpu.setBackground(colors.background)
end
for i=1, #keyboard do
gpu.setBackground(colors.button)
gpu.set(keyboard[i][1], keyboard[i][2], keyboard[i][4])
gpu.setBackground(colors.background)
end
local tempN = unicode.len(name)
tempN = width - (tempN + 17)
gpu.set(tempN,2,name.." :Текущий игрок")
gpu.set(2,2,"Ваш рекорд: "..record)
gpu.set(49,3, " :Ваши жизни")
gpu.setForeground(colors.heard)
gpu.set(44,3, "❤x"..heard)
gpu.setForeground(colors.text)
gpu.set(2,3,"Текущий счет: "..score)
end
local function paintRules() --Отрисовываем правила
local bool = true
gpu.setBackground(colors.background)
term.clear()
gpu.setForeground(colors.text)
gpu.set(25,7,"Правила игры!")
gpu.set(4,11," Доброго времени суток, уважаемый игрок!")
gpu.set(4,12," Правила <<Угадай-Ки>> очень просты, перед вами будет")
gpu.set(4,13,"n-количество ячеек за которыми буквы. Сверху")
gpu.set(4,14,"подсказка. Чтоб выбрать букву нажмите ее на экранной")
gpu.set(4,15,"клавиатуре. Если угадаете она появится в поле и на")
gpu.set(4,16,"ЭК станет зеленной, неугадаете красной. Есть 4 режима.")
gpu.set(4,17,"Если не угадали букву минус жизнь. Каждое угаданное слово")
gpu.set(4,18,"дает свое количество очков в зависимости от режима игры.")
gpu.set(4,19,"Каждая угаданая подряд буква умножает очки на кол-во")
gpu.set(4,20,"угаданых букв подряд. Удачи в игре!!")
gpu.setBackground(colors.button)
gpu.setForeground(colors.textButton)
gpu.set(4,24,"[<<Назад]")
gpu.setBackground(colors.background)
gpu.setForeground(colors.text)
while bool do
local e = {event.pull("touch")}
if e[4] == 24 then
if e[3]>3 and e[3]<14 then
bool = false
guessTW()
end
end
end
end
local function clearLine(a) --Просто отчиистка линии для сокращения кода
term.setCursor(1,a)
term.clearLine()
end
local function guessTheWord() --Наш алгоритм для сранения букв и работа с нимм
local goodLetter = false
local haveSpace = false
local key = selectKey
local letter = key[3]
local tempScore
local bool = true
for i = 1, #word1 do
if word1[i] == letter then
if word1[i] ~= word2[i] then
point = point + 1
tempScore = point*count
score = score + tempScore
gpu.set(16,3, tostring(score))
if record>=score then
gpu.set(14,2, tostring(record))
else
record = score
gpu.set(14,2, tostring(record))
end
goodLetter = true
gpu.set(25,12,"Верная буква!")
elseif word1[i] == word2[i] then
sameLetter = true
end
word2[i] = letter
gpu.setBackground(colors.cell)
gpu.setForeground(colors.textButton)
gpu.set(cellsXPos[i],10, key[4])
gpu.setForeground(colors.text)
gpu.setBackground(colors.correctLetter)
gpu.set(key[1],key[2],key[4])
gpu.setBackground(colors.background)
gpu.setForeground(colors.text)
clearLine(12)
gpu.set(25,12,"Верная буква!")
end
if word2[i] == "_" then
haveSpace = true
end
end
if goodLetter then
if not haveSpace then
heard = heard + heardPlus
gpu.setForeground(colors.heard)
gpu.set(47,3," ")
gpu.set(47,3, tostring(heard))
gpu.setForeground(colors.text)
clearLine(12)
if heardPlus == 0 then
gpu.set(18, 12,"Слово отгадано, продолжим?")
elseif heardPlus == 2 then
gpu.set(7, 12,"Слово отгадано, вы получили две жизни, продолжим?")
else
gpu.set(6, 12,"Слово отгадано, вы получили одну жизнь, продолжим?")
end
gpu.setForeground(colors.textButton)
gpu.setBackground(colors.button)
gpu.set(35,14,"[Далее >>]")
gpu.set(18,14,"[Выход]")
gpu.setForeground(colors.text)
while bool do
local e = {event.pull("touch")}
if e[4] == 14 then
if e[3]>17 and e[3]<26 then
play = false
bool = false
heardScore = heard * count * point
score = score + heardScore
saveScore()
score = 0
guessTW()
elseif e[3]>34 and e[3]<44 then
bool = false
saveScore()
game()
end
end
end
end
elseif sameLetter then
clearLine(12)
gpu.set(21,12,"Эта буква уже введена")
sameLetter = false
else
point = 0
clearLine(12)
gpu.set(24,12,"Неверная буква!")
gpu.setBackground(colors.incorrectLetter)
gpu.set(key[1],key[2],key[4])
gpu.setBackground(colors.background)
heard = heard - 1
if heard ~= 0 then
gpu.setForeground(colors.heard)
gpu.set(47,3," ")
gpu.set(47,3, tostring(heard))
gpu.setForeground(colors.text)
else
term.clear()
gpu.set(15,11,"Игра окончена!!! Ваш счет: "..tostring(score))
score = 0
os.sleep(8)
play = false
guessTW()
end
end
end
local function sortTop() --Сортируем Топ игроков
for i=1, #records do
for j=1, #records-1 do
if records[j] < records[j+1] then
local r = records[j+1]
local n = nicknames[j+1]
records[j+1] = records[j]
nicknames[j+1] = nicknames[j]
records[j] = r
nicknames[j] = n
end
end
end
saveRecord()
end
function printRecords() --Выводим рекорды на экран
local bool = true
sortTop()
gpu.setBackground(colors.background)
term.clear()
local xPosName = 15
local xPosRecord = 40
local yPos = 2
loadRecord()
gpu.setForeground(colors.text)
gpu.set(25,2,"Toп Лидеров")
gpu.setForeground(colors.textButton)
if #nicknames <= 15 then
for i = 1, #nicknames do
yPos= yPos+1
gpu.set(xPosName, yPos, nicknames[i] )
gpu.set(xPosRecord, yPos, tostring(records[i]))
end
else
for i = 1, 15 do
yPos= yPos+1
gpu.set(xPosName, yPos, nicknames[i] )
gpu.set(xPosRecord, yPos, tostring(records[i]))
end
end
gpu.setBackground(colors.button)
gpu.set(4,24,"[<<Назад]")
gpu.setBackground(colors.background)
while bool do
local e = {event.pull("touch")}
if e[4] == 24 then
if e[3]>3 and e[3]<14 then
bool = false
guessTW()
end
end
end
end
function game() --Наша игра
cellsXPos = {}
word2 = {'_','_','_','_','_','_','_','_','_'}
term.clear()
getRandomWord()
paintScene()
while play do
local e = {event.pull("touch")}
for i=1, #keyboard do
if e[4] == keyboard[i][2] then
if e[3] > keyboard[i][1]-1 and e[3] < keyboard[i][1]+3 then
selectKey = keyboard[i]
guessTheWord()
end
end
end
end
end
local function selectComplexity() --Выбор уровня сложности
local bool = true
gpu.setBackground(colors.background)
term.clear()
gpu.setBackground(colors.button)
gpu.setForeground(colors.textButton)
gpu.set(27,10,"[Хардкор]")
gpu.set(27,13,"[Сложная]")
gpu.set(27,16,"[Средняя]")
gpu.set(28,19,"[Легко]")
gpu.set(4,24,"[<<Назад]")
gpu.setBackground(colors.background)
gpu.setForeground(colors.text)
gpu.set(22,8,"Выберите сложность:")
gpu.set(9,11,"Всего 10 жизней на игру и за букву 100 очков!")
gpu.set(5,14,"2 жизни в начале и за букву 50 очков, за слово жизнь!")
gpu.set(6,17,"5 жизней в начале и за букву 10 очков, за слово жизнь!")
gpu.set(6,20,"10 жизней в начале и за букву 2 очка, за слово 2 жизни!")
while bool do
local e = {event.pull("touch")}
if e[4] == 10 then
if e[3]>26 and e[3]<36 then
bool = false
heard = 10
heardPlus = 0
count = 100
game()
end
elseif e[4] == 13 then
if e[3]>26 and e[3]<36 then
bool = false
heard = 2
heardPlus = 1
count = 50
game()
end
elseif e[4] == 16 then
if e[3]>26 and e[3]<36 then
bool = false
heard = 5
heardPlus = 1
count = 10
game()
end
elseif e[4] == 19 then
if e[3]>27 and e[3]<35 then
bool = false
heard = 10
heardPlus = 2
count = 2
game()
end
elseif e[4] == 24 then
if e[3]>3 and e[3]<14 then
bool = false
guessTW()
end
end
end
end
function guessTW() -- Запуск нашей игры
record = 0
loadRecord()
loadWords()
paintMenu()
while true do
local e = {event.pull("touch")}
if e[4] == 15 then
if e[3]>24 and e[3]<33 then
if not noWords then
name = e[6]
addPlayer(name)
for i = 1, #nicknames do
if name == nicknames[i] then
record = records[i]
end
end
play = true
point = 0
selectComplexity()
end
end
elseif e[4] == 17 then
if e[3]>24 and e[3]<37 then
sortTop()
printRecords()
end
elseif e[4] == 19 then
if e[3]>26 and e[3]<36 then
paintRules()
end
elseif e[4] == 21 then
if e[3]>27 and e[3]<35 then
gpu.setForeground(colors.defText)
gpu.setBackground(colors.defBg)
gpu.setResolution(xSize,ySize)
term.clear()
quit = true
break
end
end
if quit then break end
end
end
guessTW()

View File

@ -0,0 +1 @@
Мини-игра "Угадай Слова" от автора Newbie с форума ComputerCraft.ru. Игра на данный момент имеет базу из 300 вопросов, в процессе вам случайным образом подбирается слово, появляется экран, где есть ячейки, за которыми спрятаны буквы. Над ними находится вопрос-подсказка. Вы угадываете буквы путем нажатия на экранной клавиатуре на букву - если буква угадана, то кнопка примет зеленый цвет, если нет - красный. Также угаданная буква помещается сразу в свою ячейку. Если одинаковых букв в слове больше одной, то они также откроются в своих ячейках. Удачного мозголомства!

View File

@ -0,0 +1,380 @@
require("advancedLua")
local bit32 = require("bit32")
local fs = require("filesystem")
local GUI = require("GUI")
local buffer = require("doubleBuffering")
local unicode = require("unicode")
local MineOSInterface = require("MineOSInterface")
------------------------------------------------------------------------------------------------------------------
local colors = {
background = 0xF0F0F0,
backgroundText = 0x555555,
panel = 0x2D2D2D,
panelText = 0x999999,
panelSeleciton = 0x444444,
panelSelecitonText = 0xE1E1E1,
selectionFrom = 0x990000,
selectionTo = 0x990000,
selectionText = 0xFFFFFF,
selectionBetween = 0xD2D2D2,
selectionBetweenText = 0x000000,
separator = 0xCCCCCC,
titleBackground = 0x990000,
titleText = 0xFFFFFF,
titleText2 = 0xE1E1E1,
}
local bytes = {}
local offset = 0
local selection = {
from = 1,
to = 1,
}
local scrollBar, titleTextBox
------------------------------------------------------------------------------------------------------------------
local mainContainer, window = MineOSInterface.addWindow(MineOSInterface.filledWindow(1, 1, 98, 25, colors.background))
window.backgroundPanel.localX, window.backgroundPanel.localY = 11, 5
window.backgroundPanel.width, window.backgroundPanel.height = window.width - 10, window.height - 4
local function status()
titleTextBox.lines[1] = "Selected byte" .. (selection.from == selection.to and "" or "s") .. ": " .. selection.from .. "-" .. selection.to
titleTextBox.lines[2].text = "UTF-8: \"" .. string.char(table.unpack(bytes, selection.from, selection.to)) .. "\""
titleTextBox.lines[3].text = "INT: " .. bit32.byteArrayToNumber({table.unpack(bytes, selection.from, selection.to)})
end
local function byteFieldDraw(object)
local x, y, index = object.x, object.y, 1 + offset
local xCount, yCount = math.ceil(object.width / object.elementWidth), math.ceil(object.height / object.elementHeight)
for j = 1, yCount do
for i = 1, xCount do
if bytes[index] then
local textColor = colors.backgroundText
if index == selection.from or index == selection.to then
buffer.square(x - object.offset, y, object.elementWidth, 1, index == selection.from and colors.selectionFrom or colors.selectionTo, colors.selectionText, " ")
textColor = colors.selectionText
elseif index > selection.from and index < selection.to then
buffer.square(x - object.offset, y, object.elementWidth, 1, colors.selectionBetween, colors.selectionText, " ")
textColor = colors.selectionBetweenText
end
buffer.text(x, y, textColor, object.asChar and string.char(bytes[index]) or string.format("%02X", bytes[index]))
else
return object
end
x, index = x + object.elementWidth, index + 1
end
local lastLineIndex = index - 1
if lastLineIndex >= selection.from and lastLineIndex < selection.to then
buffer.square(object.x - object.offset, y + 1, object.width, 1, colors.selectionBetween, colors.selectionText, " ")
end
x, y = object.x, y + object.elementHeight
end
return object
end
local function byteFieldEventHandler(mainContainer, object, eventData)
if eventData[1] == "touch" or eventData[1] == "drag" then
if eventData[5] == 1 then
local menu = GUI.contextMenu(eventData[3], eventData[4])
menu:addItem("Select all").onTouch = function()
selection.from = 1
selection.to = #bytes
mainContainer:draw()
buffer.draw()
end
menu:addSeparator()
menu:addItem("Edit").onTouch = function()
local container = MineOSInterface.addUniversalContainer(mainContainer, "Fill byte range [" .. selection.from .. "; " .. selection.to .. "]")
local input = container.layout:addChild(GUI.input(1, 1, 36, 3, 0xE1E1E1, 0x666666, 0x666666, 0xE1E1E1, 0x2D2D2D, string.format("%02X" , bytes[selection.from]), "Type byte value"))
input.onInputFinished = function(text)
local number = tonumber("0x" .. input.text)
if number and number >= 0 and number <= 255 then
for i = selection.from, selection.to do
bytes[i] = number
end
container:delete()
mainContainer:draw()
buffer.draw()
end
end
mainContainer:draw()
buffer.draw()
end
menu:addItem("Insert").onTouch = function()
local container = MineOSInterface.addUniversalContainer(mainContainer, "Insert bytes at position " .. selection.from .. "")
local input = container.layout:addChild(GUI.input(1, 1, 36, 3, 0xE1E1E1, 0x666666, 0x666666, 0xE1E1E1, 0x2D2D2D, "", "Type byte values separated by space", true))
local switch = container.layout:addChild(GUI.switchAndLabel(1, 1, 36, 8, 0x66DB80, 0x1E1E1E, 0xE1E1E1, 0xBBBBBB, "Select inserted bytes:", true)).switch
input.onInputFinished = function()
if input.text:match("[a-fA-F%d%s]+") then
local insertionPosition, count = selection.from, 0
for word in input.text:gmatch("[^%s]+") do
local number = tonumber("0x" .. word)
if number > 255 then number = 255 end
table.insert(bytes, insertionPosition + count, number)
selection.from, selection.to, count = selection.from + 1, selection.to + 1, count + 1
end
if switch.state then
selection.from, selection.to = insertionPosition, insertionPosition + count - 1
end
container:delete()
mainContainer:draw()
buffer.draw()
end
end
mainContainer:draw()
buffer.draw()
end
menu:addSeparator()
menu:addItem("Delete").onTouch = function()
for i = selection.from, selection.to do
table.remove(bytes, selection.from)
end
if #bytes == 0 then
selection.from, selection.to = 1, 1
else
selection.to = selection.from
end
end
menu:show()
else
local index = (math.ceil((eventData[4] - object.y + 1) / 2) - 1) * 16 + math.ceil((eventData[3] - object.x + 1 + object.offset) / object.elementWidth) + offset
if bytes[index] then
if eventData[1] == "touch" then
selection.to = index
selection.from = index
selection.touchIndex = index
else
if not selection.touchIndex then selection.touchIndex = index end
if index < selection.touchIndex then
selection.from = index
selection.to = selection.touchIndex
elseif index > selection.touchIndex then
selection.to = index
selection.from = selection.touchIndex
end
end
status()
mainContainer:draw()
buffer.draw()
end
end
elseif eventData[1] == "scroll" then
offset = offset - 16 * eventData[5]
if offset < 0 then
offset = 0
elseif offset > math.floor(#bytes / 16) * 16 then
offset = math.floor(#bytes / 16) * 16
end
scrollBar.value = offset
mainContainer:draw()
buffer.draw()
end
end
local function newByteField(x, y, width, height, elementWidth, elementHeight, asChar)
local object = GUI.object(x, y, width, height)
object.elementWidth = elementWidth
object.elementHeight = elementHeight
object.offset = asChar and 0 or 1
object.asChar = asChar
object.draw = byteFieldDraw
object.eventHandler = byteFieldEventHandler
return object
end
------------------------------------------------------------------------------------------------------------------
window:addChild(GUI.panel(1, 1, window.width, 3, 0x3C3C3C)):moveToBack()
local byteField = window:addChild(newByteField(13, 6, 64, 20, 4, 2, false))
local charField = window:addChild(newByteField(byteField.localX + byteField.width + 3, 6, 16, 20, 1, 2, true))
local separator = window:addChild(GUI.object(byteField.localX + byteField.width, 5, 1, 21))
separator.draw = function(object)
for i = object.y, object.y + object.height - 1 do
buffer.text(object.x, i, colors.separator, "")
end
end
window:addChild(GUI.panel(11, 4, window.width - 10, 1, colors.panel))
-- Vertical
local verticalCounter = window:addChild(GUI.object(1, 4, 10, window.height - 3))
verticalCounter.draw = function(object)
buffer.square(object.x, object.y, object.width, object.height, colors.panel, colors.panelText, " ")
local index = offset
for y = 2, object.height - 1, 2 do
local textColor = colors.panelText
if index > selection.from and index < selection.to then
buffer.square(object.x, object.y + y - 1, object.width, 2, colors.panelSeleciton, colors.panelSelecitonText, " ")
textColor = colors.panelSelecitonText
end
if selection.from >= index and selection.from <= index + 15 or selection.to >= index and selection.to <= index + 15 then
buffer.square(object.x, object.y + y, object.width, 1, colors.selectionFrom, colors.selectionText, " ")
textColor = colors.selectionText
end
buffer.text(object.x + 1, object.y + y, textColor, string.format("%08X", index))
index = index + 16
end
end
-- Horizontal
window:addChild(GUI.object(13, 4, 62, 1)).draw = function(object)
local counter = 0
local restFrom, restTo = selection.from % 16, selection.to % 16
for x = 1, object.width, 4 do
local textColor = colors.panelText
if counter + 1 > restFrom and counter + 1 < restTo then
buffer.square(object.x + x - 2, object.y, 4, 1, colors.panelSeleciton, colors.selectionText, " ")
textColor = colors.panelSelecitonText
elseif restFrom == counter + 1 or restTo == counter + 1 then
buffer.square(object.x + x - 2, object.y, 4, 1, colors.selectionFrom, colors.selectionText, " ")
textColor = colors.selectionText
end
buffer.text(object.x + x - 1, object.y, textColor, string.format("%02X", counter))
counter = counter + 1
end
end
scrollBar = window:addChild(GUI.scrollBar(window.width, 5, 1, window.height - 4, 0xC3C3C3, 0x393939, 0, 1, 1, 160, 1, true))
scrollBar.eventHandler = nil
titleTextBox = window:addChild(
GUI.textBox(
1, 1, math.floor(window.width * 0.35), 3,
colors.titleBackground,
colors.titleText,
{
"",
{text = "", color = colors.titleText2},
{text = "", color = colors.titleText2}
},
1, 1, 0
)
)
titleTextBox.localX = math.floor(window.width / 2 - titleTextBox.width / 2)
titleTextBox:setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top)
titleTextBox.eventHandler = nil
local saveFileButton = window:addChild(GUI.adaptiveRoundedButton(titleTextBox.localX - 11, 2, 2, 0, colors.panel, colors.panelSelecitonText, colors.panelSelecitonText, colors.panel, "Save"))
local openFileButton = window:addChild(GUI.adaptiveRoundedButton(saveFileButton.localX - 11, 2, 2, 0, colors.panel, colors.panelSelecitonText, colors.panelSelecitonText, colors.panel, "Open"))
------------------------------------------------------------------------------------------------------------------
local function load(path)
local file, reason = io.open(path, "rb")
if file then
bytes = {}
local char
while true do
local char = file:read(1)
if char then
table.insert(bytes, string.byte(char))
else
break
end
end
file:close()
offset = 0
selection.from, selection.to = 1, 1
scrollBar.value, scrollBar.maximumValue = 0, #bytes
status()
else
GUI.error("Failed to open file for reading: " .. tostring(reason))
end
end
openFileButton.onTouch = function()
local filesystemDialog = GUI.addFilesystemDialogToContainer(mainContainer, 50, math.floor(mainContainer.height * 0.8), true, "Open", "Cancel", "File name", "/")
filesystemDialog:setMode(GUI.filesystemModes.open, GUI.filesystemModes.file)
filesystemDialog:show()
filesystemDialog.onSubmit = function(path)
load(path)
mainContainer:draw()
buffer.draw()
end
end
saveFileButton.onTouch = function()
local filesystemDialog = GUI.addFilesystemDialogToContainer(mainContainer, 50, math.floor(mainContainer.height * 0.8), true, "Save", "Cancel", "File name", "/")
filesystemDialog:setMode(GUI.filesystemModes.save, GUI.filesystemModes.file)
filesystemDialog:show()
filesystemDialog.onSubmit = function(path)
local file = io.open(path, "wb")
if file then
for i = 1, #bytes do
file:write(string.char(bytes[i]))
end
file:close()
else
GUI.error("Failed to open file for writing: " .. tostring(reason))
end
end
end
window.actionButtons.localY = 2
window.actionButtons.maximize.onTouch = function()
window.height = window.parent.height
byteField.height = window.height - 6
charField.height = byteField.height
scrollBar.height = byteField.height
window.backgroundPanel.height = window.height - 4
verticalCounter.height = window.backgroundPanel.height + 1
separator.height = byteField.height + 2
window.localY = 1
mainContainer:draw()
buffer.draw()
end
------------------------------------------------------------------------------------------------------------------
load("/bin/resolution.lua")
mainContainer:draw()
buffer.draw()

View File

@ -0,0 +1 @@
HEX - мощный редактор файлов в шестнадцатеричном режиме. Он позволяет индивидуально редактировать байты, удалять их, инвертировать, вставлять новые. Незаменимая вещь для тру прогеров!

View File

@ -0,0 +1,248 @@
require("advancedLua")
local fs = require("filesystem")
local component = require("component")
local unicode = require("unicode")
local event = require("event")
local buffer = require("doubleBuffering")
local MineOSPaths = require("MineOSPaths")
local GUI = require("GUI")
--------------------------------------------------------------------------------------------
if not component.isAvailable("hologram") then
GUI.error("This program needs a Tier 2 holo-projector to work")
return
end
--------------------------------------------------------------------------------------------
local date
local path = MineOSPaths.applicationData .. "/HoloClock/Settings.cfg"
local config = {
dateColor = 0xFFFFFF,
holoScale = 1
}
--------------------------------------------------------------------------------------------
local symbols = {
["0"] = {
{ 0, 1, 1, 1, 0 },
{ 1, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 1 },
{ 0, 0, 0, 0, 0 },
{ 1, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 1 },
{ 0, 1, 1, 1, 0 },
},
["1"] = {
{ 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 1 },
{ 0, 0, 0, 0, 1 },
{ 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 1 },
{ 0, 0, 0, 0, 1 },
{ 0, 0, 0, 0, 0 },
},
["2"] = {
{ 0, 1, 1, 1, 0 },
{ 0, 0, 0, 0, 1 },
{ 0, 0, 0, 0, 1 },
{ 0, 1, 1, 1, 0 },
{ 1, 0, 0, 0, 0 },
{ 1, 0, 0, 0, 0 },
{ 0, 1, 1, 1, 0 },
},
["3"] = {
{ 0, 1, 1, 1, 0 },
{ 0, 0, 0, 0, 1 },
{ 0, 0, 0, 0, 1 },
{ 0, 1, 1, 1, 0 },
{ 0, 0, 0, 0, 1 },
{ 0, 0, 0, 0, 1 },
{ 0, 1, 1, 1, 0 },
},
["4"] = {
{ 0, 0, 0, 0, 0 },
{ 1, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 1 },
{ 0, 1, 1, 1, 0 },
{ 0, 0, 0, 0, 1 },
{ 0, 0, 0, 0, 1 },
{ 0, 0, 0, 0, 0 },
},
["5"] = {
{ 0, 1, 1, 1, 0 },
{ 1, 0, 0, 0, 0 },
{ 1, 0, 0, 0, 0 },
{ 0, 1, 1, 1, 0 },
{ 0, 0, 0, 0, 1 },
{ 0, 0, 0, 0, 1 },
{ 0, 1, 1, 1, 0 },
},
["6"] = {
{ 0, 1, 1, 1, 0 },
{ 1, 0, 0, 0, 0 },
{ 1, 0, 0, 0, 0 },
{ 0, 1, 1, 1, 0 },
{ 1, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 1 },
{ 0, 1, 1, 1, 0 },
},
["7"] = {
{ 0, 1, 1, 1, 0 },
{ 0, 0, 0, 0, 1 },
{ 0, 0, 0, 0, 1 },
{ 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 1 },
{ 0, 0, 0, 0, 1 },
{ 0, 0, 0, 0, 0 },
},
["8"] = {
{ 0, 1, 1, 1, 0 },
{ 1, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 1 },
{ 0, 1, 1, 1, 0 },
{ 1, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 1 },
{ 0, 1, 1, 1, 0 },
},
["9"] = {
{ 0, 1, 1, 1, 0 },
{ 1, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 1 },
{ 0, 1, 1, 1, 0 },
{ 0, 0, 0, 0, 1 },
{ 0, 0, 0, 0, 1 },
{ 0, 1, 1, 1, 0 },
},
[":"] = {
{ 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0 },
{ 0, 0, 1, 0, 0 },
{ 0, 0, 0, 0, 0 },
{ 0, 0, 1, 0, 0 },
{ 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0 },
},
}
--------------------------------------------------------------------------------------------
local function save()
table.toFile(path, config)
end
local function load()
if fs.exists(path) then
config = table.fromFile(path)
else
save()
end
end
--------------------------------------------------------------------------------------------
local function drawSymbolOnScreen(x, y, symbol, color)
local xPos = x
for j = 1, #symbols[symbol] do
for i = 1, #symbols[symbol][j] do
if symbols[symbol][j][i] == 1 then
buffer.square(xPos, y, 2, 1, color, 0x000000, " ")
end
xPos = xPos + 2
end
xPos = x
y = y + 1
end
end
local function drawSymbolOnProjector(x, y, z, symbol)
local xPos = x
for j = 1, #symbols[symbol] do
for i = 1, #symbols[symbol][j] do
if symbols[symbol][j][i] == 1 then
component.hologram.set(xPos, y, z, 1)
else
component.hologram.set(xPos, y, z, 0)
end
xPos = xPos + 1
end
xPos = x
y = y - 1
end
end
local function drawText(x, y, text, color)
for i = 1, unicode.len(text) do
local symbol = unicode.sub(text, i, i)
drawSymbolOnScreen(x, y, symbol, color)
drawSymbolOnProjector(i * 6 + 4, 16, 24, symbol)
x = x + 12
end
end
local function changeHoloColor()
component.hologram.setPaletteColor(1, config.dateColor)
end
local function getDate()
date = string.sub(os.date("%T"), 1, -4)
end
local function flashback()
buffer.clear(0x0, 0.3)
end
local function drawOnScreen()
local width, height = 58, 7
local x, y = math.floor(buffer.getWidth() / 2 - width / 2), math.floor(buffer.getHeight() / 2 - height / 2)
drawText(x, y, "88:88", 0x000000)
drawText(x, y, date, config.dateColor)
y = y + 9
GUI.label(1, y, buffer.getWidth(), 1, config.dateColor, "Press R to randomize clock color, scroll to change projection scale,"):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top):draw(); y = y + 1
GUI.label(1, y, buffer.getWidth(), 1, config.dateColor, "or press Enter to save and quit"):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top):draw()
-- GUI.label(1, y, buffer.getWidth(), 1, 0xFFFFFF, ""):draw()
buffer.draw()
end
--------------------------------------------------------------------------------------------
load()
component.hologram.clear()
changeHoloColor()
component.hologram.setScale(config.holoScale)
flashback()
while true do
getDate()
drawOnScreen()
local e = {event.pull(1)}
if e[1] == "scroll" then
if e[5] == 1 then
if config.holoScale < 4 then config.holoScale = config.holoScale + 0.1; component.hologram.setScale(config.holoScale); save() end
else
if config.holoScale > 0.33 then config.holoScale = config.holoScale - 0.1; component.hologram.setScale(config.holoScale); save() end
end
elseif e[1] == "key_down" then
if e[4] == 19 then
config.dateColor = math.random(0x666666, 0xFFFFFF)
changeHoloColor()
save()
elseif e[4] == 28 then
save()
component.hologram.clear()
return
end
end
end

View File

@ -0,0 +1,785 @@
-- Hologram Editor
-- by NEO, Totoro
-- 10/14/2014, all right reserved =)
-- райтс, хуяйтс, резервед ЙОПТА
local MineOSCore = require("MineOSCore")
local unicode = require('unicode')
local event = require('event')
local term = require('term')
local fs = require('filesystem')
local com = require('component')
local gpu = com.gpu
local lang = MineOSCore.getCurrentApplicationLocalization()
-- Константы --
HOLOH = 32
HOLOW = 48
-- Цвета --
backcolor = 0x000000
forecolor = 0xFFFFFF
infocolor = 0x0066FF
errorcolor = 0xFF0000
helpcolor = 0x006600
graycolor = 0x080808
goldcolor = 0xFFDF00
-- *** --
-- загружаем доп. оборудование
function trytofind(name)
if com.isAvailable(name) then
return com.getPrimary(name)
else
return nil
end
end
local h = trytofind('hologram')
-- ========================================= H O L O G R A P H I C S ========================================= --
holo = {}
function set(x, y, z, value)
if holo[x] == nil then holo[x] = {} end
if holo[x][y] == nil then holo[x][y] = {} end
holo[x][y][z] = value
end
function get(x, y, z)
if holo[x] ~= nil and holo[x][y] ~= nil and holo[x][y][z] ~= nil then
return holo[x][y][z]
else
return 0
end
end
function save(filename)
-- сохраняем палитру
file = io.open(filename, 'wb')
for i=1, 3 do
for c=1, 3 do
file:write(string.char(colortable[i][c]))
end
end
-- сохраняем массив
for x=1, HOLOW do
for y=1, HOLOH do
for z=1, HOLOW, 4 do
a = get(x,y,z)
b = get(x,y,z+1)
c = get(x,y,z+2)
d = get(x,y,z+3)
byte = d*64 + c*16 + b*4 + a
file:write(string.char(byte))
end
end
end
file:close()
end
local function load(filename)
if fs.exists(filename) then
file = io.open(filename, 'rb')
-- загружаем палитру
for i=1, 3 do
for c=1, 3 do
colortable[i][c] = string.byte(file:read(1))
end
setHexColor(i,colortable[i][1],
colortable[i][2],
colortable[i][3])
end
-- загружаем массив
holo = {}
for x=1, HOLOW do
for y=1, HOLOH do
for z=1, HOLOW, 4 do
byte = string.byte(file:read(1))
for i=0, 3 do
a = byte % 4
byte = math.floor(byte / 4)
if a ~= 0 then set(x,y,z+i, a) end
end
end
end
end
file:close()
return true
else
--print("[ОШИБКА] Файл "..filename.." не найден.")
return false
end
end
-- ============================================= G R A P H I C S ============================================= --
-- проверка разрешения экрана, для комфортной работы необходимо разрешение > HOLOW по высоте и ширине
OLDWIDTH, OLDHEIGHT = gpu.getResolution()
WIDTH, HEIGHT = gpu.maxResolution()
if HEIGHT < HOLOW+2 then
error(lang.badGPU)
else
WIDTH = HOLOW*2+40
HEIGHT = HOLOW+2
gpu.setResolution(WIDTH, HEIGHT)
end
gpu.setForeground(forecolor)
gpu.setBackground(backcolor)
-- рисуем линию
local strLine = "+"
for i=1, WIDTH do
strLine = strLine..'-'
end
function line(x1, x2, y)
gpu.set(x1,y,string.sub(strLine, 1, x2-x1))
gpu.set(x2,y,'+')
end
-- рисуем фрейм
function frame(x1, y1, x2, y2, caption)
line(x1, x2, y1)
line(x1, x2, y2)
if caption ~= nil then
gpu.set(x1+(x2-x1)/2-unicode.len(caption)/2, y1, caption)
end
end
-- рисуем сетку
local strGrid = ""
for i=1, HOLOW/2 do
strGrid = strGrid.."██ "
end
function drawGrid(x, y)
gpu.fill(0, y, MENUX, HOLOW, ' ')
gpu.setForeground(graycolor)
for i=0, HOLOW-1 do
if view>0 and i==HOLOH then
gpu.setForeground(forecolor)
line(1, MENUX-1, y+HOLOH)
break
end
gpu.set(x+(i%2)*2, y+i, strGrid)
end
if view == 0 then gpu.setForeground(forecolor) end
end
-- рисуем цветной прямоугольник
function drawRect(x, y, color)
gpu.set(x, y, "╓──────╖")
gpu.set(x, y+1, "║ ║")
gpu.set(x, y+2, "╙──────╜")
gpu.setForeground(color)
gpu.set(x+2, y+1, "████")
gpu.setForeground(forecolor)
end
MENUX = HOLOW*2+5
BUTTONW = 12
-- рисуем меню выбора "кисти"
function drawColorSelector()
frame(MENUX, 3, WIDTH-2, 16, lang.palette)
for i=0, 3 do
drawRect(MENUX+1+i*8, 5, hexcolortable[i])
end
gpu.set(MENUX+1, 10, "R:")
gpu.set(MENUX+1, 11, "G:")
gpu.set(MENUX+1, 12, "B:")
end
function drawColorCursor(force)
if brush.color*8 ~= brush.x then brush.x = brush.color*8 end
if force or brush.gx ~= brush.x then
gpu.set(MENUX+1+brush.gx, 8, " ")
if brush.gx < brush.x then brush.gx = brush.gx + 1 end
if brush.gx > brush.x then brush.gx = brush.gx - 1 end
gpu.set(MENUX+1+brush.gx, 8, " -^--^- ")
end
end
function drawLayerSelector()
frame(MENUX, 16, WIDTH-2, 28, lang.layer)
gpu.set(MENUX+13, 18, lang.level)
gpu.set(MENUX+1, 23, lang.mainLevel)
end
function drawButtonsPanel()
frame(MENUX, 28, WIDTH-2, 36, lang.control)
end
function mainScreen()
term.clear()
frame(1,1, WIDTH, HEIGHT, "{ Hologram Editor }")
-- "холст"
drawLayer()
drawColorSelector()
drawColorCursor(true)
drawLayerSelector()
drawButtonsPanel()
buttonsDraw()
textboxesDraw()
-- "about" - коротко о создателях
gpu.setForeground(infocolor)
gpu.setBackground(graycolor)
gpu.set(MENUX+3, HEIGHT-11, " Hologram Editor v0.60 Beta ")
gpu.setForeground(forecolor)
gpu.set(MENUX+3, HEIGHT-10, " * * * ")
gpu.set(MENUX+3, HEIGHT-9, lang.developers)
gpu.set(MENUX+3, HEIGHT-8, " NEO, Totoro ")
gpu.set(MENUX+3, HEIGHT-7, " * * * ")
gpu.set(MENUX+3, HEIGHT-6, lang.contact)
gpu.set(MENUX+3, HEIGHT-5, " computercraft.ru/forum ")
gpu.setBackground(backcolor)
-- выход
gpu.set(MENUX, HEIGHT-2, lang.quit)
end
-- =============================================== L A Y E R S =============================================== --
GRIDX = 3
GRIDY = 2
function drawLayer()
drawGrid(GRIDX, GRIDY)
-- вид сверху (y)
if view == 0 then
for x=1, HOLOW do
for z=1, HOLOW do
gn = get(x, ghost_layer, z)
n = get(x, layer, z)
if n == 0 and gn ~= 0 then
gpu.setForeground(darkhexcolors[gn])
gpu.set((GRIDX-2) + x*2, (GRIDY-1) + z, "░░")
end
if n ~= 0 then
gpu.setForeground(hexcolortable[n])
gpu.set((GRIDX-2) + x*2, (GRIDY-1) + z, "██")
end
end
end
-- вид спереди (z)
elseif view == 1 then
for x=1, HOLOW do
for y=1, HOLOH do
n = get(x, y, layer)
gn = get(x, y, ghost_layer)
if n == 0 and gn ~= 0 then
gpu.setForeground(darkhexcolors[gn])
gpu.set((GRIDX-2) + x*2, (GRIDY+HOLOH) - y, "░░")
end
if n ~= 0 then
gpu.setForeground(hexcolortable[n])
gpu.set((GRIDX-2) + x*2, (GRIDY+HOLOH) - y, "██")
end
end
end
-- вид сбоку (x)
else
for z=1, HOLOW do
for y=1, HOLOH do
gn = get(ghost_layer, y, z)
n = get(layer, y, z)
if n == 0 and gn ~= 0 then
gpu.setForeground(darkhexcolors[gn])
gpu.set((GRIDX+HOLOW*2) - z*2, (GRIDY+HOLOH) - y, "░░")
end
if n ~= 0 then
gpu.setForeground(hexcolortable[n])
gpu.set((GRIDX+HOLOW*2) - z*2, (GRIDY+HOLOH) - y, "██")
end
end
end
end
gpu.setForeground(forecolor)
-- for messages
repaint = false
end
function fillLayer()
for x=1, HOLOW do
for z=1, HOLOW do
set(x, layer, z, brush.color)
end
end
drawLayer()
end
function clearLayer()
for x=1, HOLOW do
if holo[x] ~= nil then holo[x][layer] = nil end
end
drawLayer()
end
-- ============================================== B U T T O N S ============================================== --
Button = {}
Button.__index = Button
function Button.new(func, x, y, text, color, width)
self = setmetatable({}, Button)
self.form = '[ '
if width == nil then width = 0
else width = (width - unicode.len(text))-4 end
for i=1, math.floor(width/2) do
self.form = self.form.. ' '
end
self.form = self.form..text
for i=1, math.ceil(width/2) do
self.form = self.form.. ' '
end
self.form = self.form..' ]'
self.func = func
self.x = x; self.y = y
self.color = color
self.visible = true
return self
end
function Button:draw(color)
if self.visible then
local color = color or self.color
gpu.setBackground(color)
if color > 0x888888 then gpu.setForeground(backcolor) end
gpu.set(self.x, self.y, self.form)
gpu.setBackground(backcolor)
if color > 0x888888 then gpu.setForeground(forecolor) end
end
end
function Button:click(x, y)
if self.visible then
if y == self.y then
if x >= self.x and x < self.x+unicode.len(self.form) then
self.func()
self:draw(self.color/2)
os.sleep(0.1)
self:draw()
return true
end
end
end
return false
end
buttons = {}
function buttonsNew(func, x, y, text, color, width)
table.insert(buttons, Button.new(func, x, y, text, color, width))
end
function buttonsDraw()
for i=1, #buttons do
buttons[i]:draw()
end
end
function buttonsClick(x, y)
for i=1, #buttons do
buttons[i]:click(x, y)
end
end
-- ================================ B U T T O N S F U N C T I O N A L I T Y ================================ --
function exit() running = false end
function nextLayer()
-- ограничения разные для разных видов/проекций
local limit = HOLOH
if view > 0 then limit = HOLOW end
if layer < limit then
layer = layer + 1
tb_layer:setValue(layer)
tb_layer:draw(true)
moveGhost()
drawLayer()
end
end
function prevLayer()
if layer > 1 then
layer = layer - 1
tb_layer:setValue(layer)
tb_layer:draw(true)
moveGhost()
drawLayer()
end
end
function setLayer(value)
local n = tonumber(value)
local limit = HOLOH
if view > 0 then limit = HOLOW end
if n == nil or n < 1 or n > limit then return false end
layer = n
moveGhost()
drawLayer()
return true
end
function nextGhost()
local limit = HOLOH
if view > 0 then limit = HOLOW end
if ghost_layer_below then
ghost_layer_below = false
if ghost_layer < limit then
ghost_layer = layer + 1
else ghost_layer = limit end
drawLayer()
else
if ghost_layer < limit then
ghost_layer = ghost_layer + 1
drawLayer()
end
end
end
function prevGhost()
if not ghost_layer_below then
ghost_layer_below = true
if layer > 1 then
ghost_layer = layer - 1
else ghost_layer = 1 end
drawLayer()
else
if ghost_layer > 1 then
ghost_layer = ghost_layer - 1
drawLayer()
end
end
end
function setGhostLayer(value)
local n = tonumber(value)
local limit = HOLOH
if view > 0 then limit = HOLOW end
if n == nil or n < 1 or n > limit then return false end
ghost_layer = n
drawLayer()
return true
end
function moveGhost()
if ghost_layer_below then
if layer > 1 then ghost_layer = layer - 1
else ghost_layer = 1 end
else
local limit = HOLOH
if view > 0 then limit = HOLOW end
if layer < limit then ghost_layer = layer + 1
else ghost_layer = limit end
end
end
function setFilename(str)
if str ~= nil and str ~= '' and unicode.len(str)<30 then
return true
else
return false
end
end
function setHexColor(n, r, g, b)
local hexcolor = rgb2hex(r,g,b)
hexcolortable[n] = hexcolor
darkhexcolors[n] = bit32.rshift(bit32.band(hexcolor, 0xfefefe), 1)
end
function rgb2hex(r,g,b)
return r*65536+g*256+b
end
function changeRed(value) return changeColor(1, value) end
function changeGreen(value) return changeColor(2, value) end
function changeBlue(value) return changeColor(3, value) end
function changeColor(rgb, value)
if value == nil then return false end
n = tonumber(value)
if n == nil or n < 0 or n > 255 then return false end
-- сохраняем данные в таблицу
colortable[brush.color][rgb] = n
setHexColor(brush.color, colortable[brush.color][1],
colortable[brush.color][2],
colortable[brush.color][3])
-- обновляем цвета на панельке
for i=0, 3 do
drawRect(MENUX+1+i*8, 5, hexcolortable[i])
end
return true
end
function moveSelector(num)
brush.color = num
tb_red:setValue(colortable[num][1]); tb_red:draw(true)
tb_green:setValue(colortable[num][2]); tb_green:draw(true)
tb_blue:setValue(colortable[num][3]); tb_blue:draw(true)
end
function setTopView()
view = 0
-- в виде сверху меньше слоев
if layer > HOLOH then layer = HOLOH end
drawLayer()
end
function setFrontView() view = 1; drawLayer() end
function setSideView() view = 2; drawLayer() end
function drawHologram()
-- проверка на наличие проектора
h = trytofind('hologram')
if h ~= nil then
local depth = h.maxDepth()
-- очищаем
h.clear()
-- отправляем палитру
if depth == 2 then
for i=1, 3 do
h.setPaletteColor(i, hexcolortable[i])
end
else
h.setPaletteColor(1, hexcolortable[1])
end
-- отправляем массив
for x=1, HOLOW do
for y=1, HOLOH do
for z=1, HOLOW do
n = get(x,y,z)
if n ~= 0 then
if depth == 2 then
h.set(x,y,z,n)
else
h.set(x,y,z,1)
end
end
end
end
end
end
end
function newHologram()
holo = {}
drawLayer()
end
function saveHologram()
local filename = tb_file:getValue()
if filename ~= FILE_REQUEST then
-- выводим предупреждение
showMessage(lang.savingFile, lang.attention, goldcolor)
-- добавляем фирменное расширение =)
if string.sub(filename, -3) ~= '.3d' then
filename = filename..'.3d'
end
-- сохраняем
save(filename)
-- выводим предупреждение
showMessage(lang.complete, lang.attention, goldcolor)
repaint = true
end
end
function loadHologram()
local filename = tb_file:getValue()
if filename ~= FILE_REQUEST then
-- выводим предупреждение
showMessage(lang.loadingFile, lang.attention, goldcolor)
-- добавляем фирменное расширение =)
if string.sub(filename, -3) ~= '.3d' then
filename = filename..'.3d'
end
-- загружаем
load(filename)
-- обновляем значения в текстбоксах
tb_red:setValue(colortable[brush.color][1]); tb_red:draw(true)
tb_green:setValue(colortable[brush.color][2]); tb_green:draw(true)
tb_blue:setValue(colortable[brush.color][3]); tb_blue:draw(true)
-- обновляем цвета на панельке
for i=0, 3 do
drawRect(MENUX+1+i*8, 5, hexcolortable[i])
end
-- обновляем слой
drawLayer()
end
end
-- ============================================ T E X T B O X E S ============================================ --
Textbox = {}
Textbox.__index = Textbox
function Textbox.new(func, x, y, value, width)
self = setmetatable({}, Textbox)
self.form = '>'
if width == nil then width = 10 end
for i=1, width-1 do
self.form = self.form..' '
end
self.func = func
self.value = tostring(value)
self.x = x; self.y = y
self.visible = true
return self
end
function Textbox:draw(content)
if self.visible then
if content then gpu.setBackground(graycolor) end
gpu.set(self.x, self.y, self.form)
if content then gpu.set(self.x+2, self.y, self.value) end
gpu.setBackground(backcolor)
end
end
function Textbox:click(x, y)
if self.visible then
if y == self.y then
if x >= self.x and x < self.x+unicode.len(self.form) then
self:draw(false)
term.setCursor(self.x+2, self.y)
value = string.sub(term.read({self.value}), 1, -2)
if self.func(value) then
self.value = value
end
self:draw(true)
return true
end
end
end
return false
end
function Textbox:setValue(value)
self.value = tostring(value)
end
function Textbox:getValue()
return self.value
end
textboxes = {}
function textboxesNew(func, x, y, value, width)
textbox = Textbox.new(func, x, y, value, width)
table.insert(textboxes, textbox)
return textbox
end
function textboxesDraw()
for i=1, #textboxes do
textboxes[i]:draw(true)
end
end
function textboxesClick(x, y)
for i=1, #textboxes do
textboxes[i]:click(x, y)
end
end
-- ============================================= M E S S A G E S ============================================= --
repaint = false
function showMessage(text, caption, color)
local x = WIDTH/2 - unicode.len(text)/2 - 4
local y = HEIGHT/2 - 2
gpu.fill(x, y, unicode.len(text)+8, 5, ' ')
frame(x, y, x+unicode.len(text)+7, y+4, caption)
gpu.setForeground(color)
gpu.set(x+4,y+2, text)
gpu.setForeground(forecolor)
end
-- =========================================== M A I N C Y C L E =========================================== --
-- инициализация
colortable = {{255, 0, 0}, {0, 255, 0}, {0, 102, 255}}
colortable[0] = {0, 0, 0}
hexcolortable = {}
darkhexcolors = {}
for i=0,3 do setHexColor(i, colortable[i][1], colortable[i][2], colortable[i][3]) end
brush = {color = 1, x = 8, gx = 8}
ghost_layer = 1
ghost_layer_below = true
layer = 1
view = 0
running = true
buttonsNew(exit, WIDTH-BUTTONW-2, HEIGHT-2, lang.exit, errorcolor, BUTTONW)
buttonsNew(drawLayer, MENUX+10, 14, lang.refresh, goldcolor, BUTTONW)
buttonsNew(prevLayer, MENUX+1, 19, '-', infocolor, 5)
buttonsNew(nextLayer, MENUX+7, 19, '+', infocolor, 5)
buttonsNew(setTopView, MENUX+1, 21, lang.fromUp, infocolor, 10)
buttonsNew(setFrontView, MENUX+12, 21, lang.fromFront, infocolor, 10)
buttonsNew(setSideView, MENUX+24, 21, lang.fromSide, infocolor, 9)
buttonsNew(prevGhost, MENUX+1, 24, lang.lower, infocolor, 6)
buttonsNew(nextGhost, MENUX+10, 24, lang.upper, infocolor, 6)
buttonsNew(clearLayer, MENUX+1, 26, lang.clear, infocolor, BUTTONW)
buttonsNew(fillLayer, MENUX+2+BUTTONW, 26, lang.fill, infocolor, BUTTONW)
buttonsNew(drawHologram, MENUX+8, 30, lang.toProjector, goldcolor, 16)
buttonsNew(saveHologram, MENUX+1, 33, lang.save, helpcolor, BUTTONW)
buttonsNew(loadHologram, MENUX+8+BUTTONW, 33, lang.load, infocolor, BUTTONW)
buttonsNew(newHologram, MENUX+1, 35, lang.new, infocolor, BUTTONW)
tb_red = textboxesNew(changeRed, MENUX+5, 10, '255', WIDTH-MENUX-7)
tb_green = textboxesNew(changeGreen, MENUX+5, 11, '0', WIDTH-MENUX-7)
tb_blue = textboxesNew(changeBlue, MENUX+5, 12, '0', WIDTH-MENUX-7)
tb_layer = textboxesNew(setLayer, MENUX+13, 19, '1', WIDTH-MENUX-15)
tb_ghostlayer = textboxesNew(setGhostLayer, MENUX+19, 24, ' ', WIDTH-MENUX-21)
FILE_REQUEST = lang.enterFileName
tb_file = textboxesNew(setFilename, MENUX+1, 32, FILE_REQUEST, WIDTH-MENUX-3)
mainScreen()
while running do
if brush.x ~= brush.gx then name, add, x, y, b = event.pull(0.02)
else name, add, x, y, b = event.pull(1.0) end
if name == 'key_down' then
-- если нажата 'Q' - выходим
if y == 16 then break
elseif y == 41 then
moveSelector(0)
elseif y>=2 and y<=4 then
moveSelector(y-1)
elseif y == 211 then
clearLayer()
end
elseif name == 'touch' then
-- проверка GUI
buttonsClick(x, y)
textboxesClick(x, y)
-- выбор цвета
if x>MENUX+1 and x<MENUX+37 then
if y>4 and y<8 then
moveSelector(math.floor((x-MENUX-1)/8))
end
end
end
if name == 'touch' or name == 'drag' then
-- "рисование"
local limit = HOLOW
if view > 0 then limit = HOLOH end
if x >= GRIDX and x < GRIDX+HOLOW*2 then
if y >= GRIDY and y < GRIDY+limit then
-- перерисуем, если на экране был мессейдж
if repaint then drawLayer() end
-- рассчет клика
if view == 0 then
dx = math.floor((x-GRIDX)/2)+1; gx = dx
dy = layer; gy = ghost_layer
dz = y-GRIDY+1; gz = dz
elseif view == 1 then
dx = math.floor((x-GRIDX)/2)+1; gx = dx
dy = HOLOH - (y-GRIDY); gy = dy
dz = layer; gz = ghost_layer
else
dx = layer; gx = ghost_layer
dy = HOLOH - (y-GRIDY); gy = dy
dz = HOLOW - math.floor((x-GRIDX)/2); gz = dz
end
if b == 0 and brush.color ~= 0 then
set(dx, dy, dz, brush.color)
gpu.setForeground(hexcolortable[brush.color])
gpu.set(x-(x-GRIDX)%2, y, "██")
else
set(dx, dy, dz, 0)
gpu.setForeground(darkhexcolors[get(gx,gy,gz)])
gpu.set(x-(x-GRIDX)%2, y, "░░")
end
gpu.setForeground(forecolor)
end
end
end
drawColorCursor()
end
-- завершение
term.clear()
gpu.setResolution(OLDWIDTH, OLDHEIGHT)
gpu.setForeground(0xFFFFFF)
gpu.setBackground(0x000000)

View File

@ -0,0 +1,29 @@
{
badGPU = "[ERROR] Your monitor/GPU doesn't support required resolution.",
palette = "[ Palette ]",
control = "[ Control ]",
layer = "[ Layer ]",
level = "Hologram level:",
mainLevel = "Main level:",
quit = "Exit: 'Q' or ",
developers = "Developers: ",
contact = "Contact",
savingFile = "Saving file...",
loadingFile = "Loading file...",
attention = "[ Attention ]",
complete = "[ Done! ]",
exit = "Quit",
refresh = "Refresh",
fromUp = "Top",
fromFront = "Front",
fromSide = "Side",
upper = "Upper",
lower = "Lower",
clear = "Clear",
fill = "Fill",
toProjector = "To projector",
save = "Save",
load = "Load",
new = "New file",
enterFileName = "Enter file name here:",
}

View File

@ -0,0 +1,29 @@
{
badGPU = "[ОШИБКА] Ваш монитор/видеокарта не поддерживает требуемое разрешение.",
palette = "[ Палитра ]",
control = "[ Управление ]",
layer = "[ Слой ]",
level = "Уровень голограммы:",
mainLevel = "Направляющий уровень:",
quit = "Выход: 'Q' или ",
developers = "Разработчики: ",
contact = "Контакты:",
savingFile = "Сохраняю файл...",
loadingFile = "Загружаю файл...",
attention = "[ Внимание ]",
complete = "[ Файл сохранен! ]",
exit = "Выход",
refresh = "Обновить",
fromUp = "Сверху",
fromFront = "Спереди",
fromSide = "Сбоку",
upper = "Выше",
lower = "Ниже",
clear = "Очистить",
fill = "Залить",
toProjector = "На проектор",
save = "Сохранить",
load = "Загрузить",
new = "Новый файл",
enterFileName = "Введите сюда имя файла",
}

View File

@ -0,0 +1,186 @@
local ecs = require("ECSAPI")
local MineOSCore = require("MineOSCore")
local xml = require("xmlParser")
local image = require("image")
local event = require("event")
local unicode = require("unicode")
local fs = require("filesystem")
local gpu = require("component").gpu
------------------------------------------------------------------------------------------------------------------
local config = {
scale = 0.63,
leftBarWidth = 20,
scrollSpeed = 6,
pathToInfoPanelFolder = MineOSCore.getCurrentApplicationResourcesDirectory() .. "Pages/",
colors = {
leftBar = 0xEEEEEE,
leftBarText = 0x262626,
leftBarSelection = 0x00C6FF,
leftBarSelectionText = 0xFFFFFF,
scrollbarBack = 0xEEEEEE,
scrollbarPipe = 0x3366CC,
background = 0x262626,
text = 0xFFFFFF,
},
}
local xOld, yOld = gpu.getResolution()
ecs.setScale(config.scale)
local xSize, ySize = gpu.getResolution()
fs.makeDirectory(config.pathToInfoPanelFolder)
local currentFile = 1
local fileList
local stroki = {}
local currentString = 1
local stringsHeightLimit = ySize - 2
local stringsWidthLimit = xSize - config.leftBarWidth - 4
------------------------------------------------------------------------------------------------------------------
local obj = {}
local function newObj(class, name, ...)
obj[class] = obj[class] or {}
obj[class][name] = {...}
end
local function drawLeftBar()
--ecs.square(1, 1, config.leftBarWidth, ySize, config.colors.leftBar)
fileList = ecs.getFileList(config.pathToInfoPanelFolder)
obj["Files"] = {}
local yPos = 1, 1
for i = 1, #fileList do
if i == currentFile then
newObj("Files", i, ecs.drawButton(1, yPos, config.leftBarWidth, 3, ecs.hideFileFormat(fileList[i]), config.colors.leftBarSelection, config.colors.leftBarSelectionText))
else
if i % 2 == 0 then
newObj("Files", i, ecs.drawButton(1, yPos, config.leftBarWidth, 3, ecs.stringLimit("end", ecs.hideFileFormat(fileList[i]), config.leftBarWidth - 2), config.colors.leftBar, config.colors.leftBarText))
else
newObj("Files", i, ecs.drawButton(1, yPos, config.leftBarWidth, 3, ecs.stringLimit("end", ecs.hideFileFormat(fileList[i]), config.leftBarWidth - 2), config.colors.leftBar - 0x111111, config.colors.leftBarText))
end
end
yPos = yPos + 3
end
ecs.square(1, yPos, config.leftBarWidth, ySize - yPos + 1, config.colors.leftBar)
end
local function loadFile()
currentString = 1
stroki = {}
local file = io.open(config.pathToInfoPanelFolder .. fileList[currentFile], "r")
for line in file:lines() do table.insert(stroki, xml.collect(line)) end
file:close()
end
local function drawMain()
local x, y = config.leftBarWidth + 3, 2
local xPos, yPos = x, y
ecs.square(xPos, yPos, xSize - config.leftBarWidth - 5, ySize, config.colors.background)
gpu.setForeground(config.colors.text)
for line = currentString, (stringsHeightLimit + currentString - 1) do
if stroki[line] then
for i = 1, #stroki[line] do
if type(stroki[line][i]) == "table" then
if stroki[line][i].label == "color" then
gpu.setForeground(tonumber(stroki[line][i][1]))
elseif stroki[line][i].label == "image" then
local bg, fg = gpu.getBackground(), gpu.getForeground()
local picture = image.load(stroki[line][i][1])
image.draw(xPos, yPos, picture)
yPos = yPos + picture.height - 1
gpu.setForeground(fg)
gpu.setBackground(bg)
end
else
gpu.set(xPos, yPos, stroki[line][i])
xPos = xPos + unicode.len(stroki[line][i])
end
end
yPos = yPos + 1
xPos = x
else
break
end
end
end
local function drawScrollBar()
local name
name = ""; newObj("Scroll", name, ecs.drawButton(xSize - 2, 1, 3, 3, name, config.colors.leftBarSelection, config.colors.leftBarSelectionText))
name = ""; newObj("Scroll", name, ecs.drawButton(xSize - 2, ySize - 2, 3, 3, name, config.colors.leftBarSelection, config.colors.leftBarSelectionText))
ecs.srollBar(xSize - 2, 4, 3, ySize - 6, #stroki, currentString, config.colors.scrollbarBack, config.colors.scrollbarPipe)
end
------------------------------------------------------------------------------------------------------------------
ecs.prepareToExit()
drawLeftBar()
loadFile()
drawMain()
drawScrollBar()
while true do
local e = {event.pull()}
if e[1] == "touch" then
for key in pairs(obj["Files"]) do
if ecs.clickedAtArea(e[3], e[4], obj["Files"][key][1], obj["Files"][key][2], obj["Files"][key][3], obj["Files"][key][4]) then
currentFile = key
loadFile()
drawLeftBar()
drawMain()
drawScrollBar()
break
end
end
for key in pairs(obj["Scroll"]) do
if ecs.clickedAtArea(e[3], e[4], obj["Scroll"][key][1], obj["Scroll"][key][2], obj["Scroll"][key][3], obj["Scroll"][key][4]) then
ecs.drawButton(obj["Scroll"][key][1], obj["Scroll"][key][2], 3, 3, key, config.colors.leftBarSelectionText, config.colors.leftBarSelection)
os.sleep(0.2)
ecs.drawButton(obj["Scroll"][key][1], obj["Scroll"][key][2], 3, 3, key, config.colors.leftBarSelection, config.colors.leftBarSelectionText)
if key == "" then
if currentString > config.scrollSpeed then
currentString = currentString - config.scrollSpeed
drawMain()
drawScrollBar()
end
else
if currentString < (#stroki - config.scrollSpeed + 1) then
currentString = currentString + config.scrollSpeed
drawMain()
drawScrollBar()
end
end
break
end
end
elseif e[1] == "key_down" then
if e[4] == 28 then
gpu.setResolution(xOld, yOld)
ecs.prepareToExit()
return
end
end
end

View File

@ -0,0 +1 @@
Эта программа предназначена для визуального отображения информации для пользователей компьютера, она идеально впишется в ваш спавн, дом или милитаризированный бункер. Файлы с информацией хранятся в папке MineOS/System/InfoPanel, вы можете изменить их в любое время.

View File

@ -0,0 +1,15 @@
Приват
Для привата и защиты от гриферства используется классический плагин
WorldGuard в совокупности с аддоном MachineGuard.
● Приват осуществляется деревянным топором, проверка привата кожей.
● Количество блоков, доступное пользователю для привата: 700 000.
● Максимальное количество приватов на пользователя: 1.
● Приват сундуков, механизмов IC2, компьютеров и прочего создается
автоматически.
● Если вам мешает графическая подсветка выделения, используйте
команду //sel, чтобы убрать ее.
● Роботы не могут ломать блоки в привате, однако могут снимать
гаечным ключом механизмы IC2. Будьте внимательны и защищайте жилье
тщательно!

View File

@ -0,0 +1,21 @@
Главная
Добро пожаловать на индустриальный сервер <color>0xFFAA00</color>Buttex<color>0xFFFFFF</color>! С помощью этой панели
вы всегда можете узнать последние новости сервера и ознакомиться с
основными устоями, сложившимися в нашем обществе. Новичкам рекомендуется
прочитать все имеющиеся вкладки.
История сервера
Buttex существует с незапамятного 2010 года, когда кубач еще только
набирал свою популярность. Основным направлением сервера всегда были
красивые постройки, редстоун-схемы, а с недавних пор еще и кодинг
на компьютерах, предоставляемых модами. На сервере всегда царила
дружеская и домашняя атмосфера, которую мы поддерживаем из года в год.
Иногда, когда нашей теплой компании надоедало играть в кубики, мы
делали перерыв, но в скором времени сервер возрождался раз за разом.
Сейчас на дворе ноябрь, 2015 год, и мы вновь открываем Buttex для всех
желающих в новом формате - с собственным лаунчером, интересными модами
и грамотно настроенными плагинами.
Приятной игры, дорогие мои!

View File

@ -0,0 +1,49 @@
Правила
На сервере существует лишь одно правило: <color>0xFF5555</color>нет никаких правил<color>0xFFFFFF</color>.
Вам дозволяется абсолютно все: гриферство, читерство, мат в чате,
оскорбление админа и других игроков, ибо все это - неотъемлемая
часть нашего бытия. Вы можете быть культурным и святым человеком,
а можете крушить все направо-налево, строя хуи и свастики из грязи.
Помните, что не существует плохих или хороших деяний, есть лишь
поступки и их закономерные последствия. Таким образом, если вы
загадите личную хату админа, то он выебет вас по самые гланды, а если
будете неадекватным малым, то крайне велика вероятность, что вам
всадят нож в спину.
Багоюз
Любые баги - это вина администрации, безответственно отнесшейся к
исправлению ошибок плагинов и модов. Таким образом, если вы нашли
способ дюпа, способ использования недочетов сервера себе на благо,
крайне рекомендуется сообщить об этом админам - вы получите приятный
бонус за бдительность, а другие игроки получат честную игру.
Флуд
Если в чате творится полный бардак, и нежелательные личности флудят
или просто раздражают вас - используйте Систему Серверной Поддержки
Игроков, чтобы навести порядок: команда "<color>0xFFAA00</color>сервер замуть Cyka<color>0xFFFFFF</color>"
откроет голосование за мут игрока под ником Cyka.
Убийства
Вас убил сильно развитый игрок? Ну что ж, печально. Чтобы избежать
подобных эксцессов, защищайте ваше жилище тщательнее, закрывайте
дыры в обороне, копайте больше ресурсов для создания орудия мести.
Гриферство
Чей-то робот своровал ваши солнечные панели и механизмы IC2? Какая
неприятность! Чтобы защититься от этого, грамотно приватьте зону
вашего дома, закрывайте все щели, ставьте двери, которые нельзя
открыть редстоуном. Если вы узнали имя вора, обратитесь к обладателям
мощной брони и оружия, чтобы восстановить справедливость.
Заключение
Причиной всему этому "беззаконию" послужило наличие слишком больших
ограничений на большинстве серверов, где складывается впечатление,
что админы - нежные телки с завышенным ЧСВ. Но долой такую чушь!
Добро пожаловать на <color>0xFFAA00</color>Buttex<color>0xFFFFFF</color>, где каждый сам себе хозяин!

View File

@ -0,0 +1,35 @@
ССПИ
У нас имеется автоматическая <color>0xFFAA00</color>Серверная Система Поддержки Игроков<color>0xFFFFFF</color>,
сокращенно <color>0xFFAA00</color>ССПИ<color>0xFFFFFF</color>. Она предназначена для минимизации контактов вида
игрок-админ, заменяя по сути целый штаб модераторов. Данная система
работает через чат в виде виртуального собеседника - вводите указанные
ниже команды и получайте результат.
● <color>0xFFAA00</color>Сервер дай ресов<color>0xFFFFFF</color> - вы получите произвольное количество произвольных
произвольно выбранных ресурсов.
● <color>0xFFAA00</color>Сервер замуть [Username]<color>0xFFFFFF</color> - откроется публичное голосование за мут
игрока с ником Username.
● <color>0xFFAA00</color>Сервер как дела <color>0xFFFFFF</color>- если ССПИ будет в хорошем расположении духа, она
может рассказать, как у нее дела. За последствия плохого настроения
системы мы ответственности не несем.
● <color>0xFFAA00</color>Сервер очисти чат<color>0xFFFFFF</color> - очищает чат лично для вас, отправляя вам в ЛС
большое количество пробелов.
● <color>0xFFAA00</color>Сервер скажи админам [сообщение]<color>0xFFFFFF</color> - отправляет всем администраторам
сообщение, даже если они отсутствуют на сервере. Впоследствии они
смогут его прочесть.
● <color>0xFFAA00</color>Сервер вероятность [событие]<color>0xFFFFFF</color> - вычисляет вероятность какого-либо
события. Полезно, чтобы доказать кому-то, что он пидор.
● <color>0xFFAA00</color>Сервер хеш [фраза]<color>0xFFFFFF</color> - возвращает хеш-сумму указанной фразы, просчитанную
по алгоритму SHA2-256.
Следующие команды для ССПИ предназначены только для администраторов,
у простых смертных к ним нет доступа:
● <color>0xFFAA00</color>Сервер отпизди [Username]<color>0xFFFFFF</color> - убивает игрока с ником Username.
● <color>0xFFAA00</color>Сервер сделай день/ночь<color>0xFFFFFF</color> - устанавливает указанное время суток.
● <color>0xFFAA00</color>Сервер включи/выключи свет<color>0xFFFFFF</color> - управление освещение спавна.
Кроме того, ключевое слово "Сервер" имеет несколько синонимов
для удобства: серв, сервак, ССПИ, а также все эти вариации,
написанные с заглавной буквы.

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1 @@
MineCode IDE - это мощный инстурмент для разработки приложений с богатым функционалом: от подсветки синтаксиса Lua, выделения текста и работы с буфером обмена до поддержки пользовательских цветовых схем. Удобный файловый менеджер также прилагается.

View File

@ -0,0 +1,61 @@
{
addBreakpoint = "Add breakpoint",
clearBreakpoints = "Clear breakpoints",
finishDebug = "Stop",
continueDebug = "Continue",
gotoLine = "Goto line",
lineNumber = "Line",
enableAutocompletion = "Enable autocompletion",
disableAutocompletion = "Disable autocompletion",
selectAndPasteColor = "Select and paste color",
enableAutoBrackets = "Enable autobrackets",
disableAutoBrackets = "Disable autobrackets",
url = "http://example.com/something.lua",
getFromWeb = "Download from URL",
debugging = "Debugger on line ",
runtimeError = "Runtime error",
variablesNotAvailable = "No variables found",
variables = "Values of the variables:",
changeResolution = "Change screen resolution",
pathToFile = "Path to file",
selectWord = "Select current word",
gotoCyka = "Goto",
gotoEnd = "Scroll to end",
gotoStart = "Scroll to start",
pageDown = "Page down",
pageUp = "Page up",
deleteLine = "Delete current line",
cursorProperties = "Cursor properties",
cursorSymbol = "Symbol",
cursorColor = "Color",
cursorBlinkDelay = "Blink delay",
selection = "Selection: ",
none = "none",
properties = "Properties",
about = "About",
quit = "Quit from MineCode",
line = " line, ",
symbol = " symbol",
lines = " lines, ",
symbols = " symbols",
file = "File",
cursor = "Cursor: ",
new = "New",
open = "Open",
openFile = "Open file",
save = "Save",
saveAs = "Save as",
colorScheme = "Color scheme",
color = "Color",
toggleTopToolBar = "Show top toolbar",
find = "Find",
findSomeShit = "Let's find some shit…",
cut = "Cut",
copy = "Copy",
paste = "Paste",
selectAll = "Select all",
edit = "Edit",
comment = "Toggle comment",
indent = "Indent",
unindent = "Unindent",
}

View File

@ -0,0 +1,61 @@
{
addBreakpoint = "Точка останова",
clearBreakpoints = "Удалить точки останова",
finishDebug = "Стоп",
continueDebug = "Продолжить",
gotoLine = "Перейти к строке",
lineNumber = "Номер строки",
enableAutocompletion = "Включить автодополнение",
disableAutocompletion = "Отключить автодополнение",
selectAndPasteColor = "Выбрать и вставить цвет",
enableAutoBrackets = "Включить авто-скобки",
disableAutoBrackets = "Отключить авто-скобки",
url = "http://example.com/something.lua",
getFromWeb = "Загрузить по URL",
debugging = "Отладчик на строке ",
runtimeError = "Ошибка при выполнении программы",
variablesNotAvailable = "Не найдено возможных переменных",
variables = "Значения переменных:",
changeResolution = "Изменить разрешение экрана",
pathToFile = "Путь к файлу",
selectWord = "Выделить текущее слово",
gotoCyka = "Переход",
gotoEnd = "В конец",
gotoStart = "В начало",
pageDown = "На страницу ниже",
pageUp = "На страницу выше",
deleteLine = "Удалить текущую строку",
cursorProperties = "Параметры курсора",
cursorSymbol = "Символ",
cursorColor = "Цвет",
cursorBlinkDelay = "Время мигания",
selection = "Выделение: ",
none = "нет",
properties = "Настройки",
about = "О программе",
quit = "Выйти из MineCode",
line = " строка, ",
symbol = " символ",
lines = " строк, ",
symbols = " символов",
file = "Файл",
cursor = "Курсор: ",
new = "Новый",
open = "Открыть",
openFile = "Открыть файл",
save = "Сохранить",
saveAs = "Сохранить как",
colorScheme = "Цветовая схема",
color = "Цвет",
toggleTopToolBar = "Показать панель инстурментов",
find = "Найти",
findSomeShit = "Давай найдем какую-нибудь хуйню…",
cut = "Вырезать",
copy = "Копировать",
paste = "Вставить",
selectAll = "Выделить все",
edit = "Редактировать",
comment = "Комментировать",
indent = "Табулировать",
unindent = "Детабулировать",
}

View File

@ -0,0 +1,15 @@
local MineOSInterface = require("MineOSInterface")
local mainContainer, window = MineOSInterface.addWindow(
MineOSInterface.windowFromContainer(
require("GUI").palette(1, 1, 0x9900FF)
)
)
window.OKButton.onTouch = function()
window:close()
MineOSInterface.OSDraw()
end
window.cancelButton.onTouch = window.OKButton.onTouch

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1 @@
Photoshop - это мощный графический редактор, написанный специально для работы с нашей ОС. Он поддерживает работу с кистями, прозрачностью, имеет функции заливки, выбора цвета из красочной палитры, позволяет создавать настоящие мини-шедевры прямо на вашем ПК. Вся графика в нашей ОС нарисована именно в этой программе.

View File

@ -0,0 +1,92 @@
{
newDocument = "New document",
width = "Width",
height = "Height",
cancel = "Cancel",
w = "W",
h = "H",
view = "View",
transparencyPad = "Transparency pad",
transparencyColor = "Transparency color",
transparencyGrid = "Transparency grid",
path = "Path",
string = "String",
file = "File",
image = "Image",
edit = "Edit",
hotkeys = "Hot keys",
about = "About",
brushSize = "Brush size",
transparency = "Transparency",
brushParameters = "Brush parameters",
size = "Size",
new = "New",
open = "Open",
createFromString = "Create from StringImage",
save = "Save",
saveAs = "Save as",
exit = "Exit",
crop = "Crop",
expand = "Expand",
rotateBy90 = "Rotate by 90 degrees",
rotateBy180 = "Rotate by 180 degrees",
flipVertical = "Flip vertical",
flipHorizontal = "Flip horizontal",
hueSaturation = "Hue/Saturation",
colorBalance = "Color balance",
photoFilter = "Photo filter",
invertColors = "Invert colors",
blackWhite = "Black and white",
gaussianBlur = "Gaussian blur",
countOfPixels = "Count of pixels",
fromBottom = "From bottom",
fromTop = "From top",
fromLeft = "From left",
fromRight = "From right",
hue = "Hue",
saturation = "Saturation",
brightness = "Brightness",
filterColor = "Filter color",
radius = "Radius",
force = "Force",
edges = "Edges",
accept = "Enter - accept",
line = "Line",
ellipse = "Ellipse",
rectangle = "Rectangle",
polygon = "Polygon",
border = "Border",
fill = "Fill",
clear = "Clear",
deselect = "Deselect",
hotkeysLines = {
{"EmptyLine"},
{"CenterText", 0x880000, "Hotkeys"},
{"EmptyLine"},
{"CenterText", 0x000000, "B - Brush"},
{"CenterText", 0x000000, "E - Eraser"},
{"CenterText", 0x000000, "T - Text"},
{"CenterText", 0x000000, "G - Fill"},
{"CenterText", 0x000000, "M - Selection"},
{"CenterText", 0x000000, " "},
{"CenterText", 0x000000, "Arrows - move image"},
{"CenterText", 0x000000, "X - swap colors"},
{"CenterText", 0x000000, "D - make colors black&white"},
{"CenterText", 0x000000, "Ctrl+D - deselect"},
{"CenterText", 0x000000, "Alt+Click - pick color (brush only)"},
{"EmptyLine"},
{"Button", {0xbbbbbb, 0xffffff, "OK"}},
},
developers = "Developers:",
testers = "Testers:",
}

View File

@ -0,0 +1,92 @@
{
newDocument = "Новый документ",
width = "Ширина",
height = "Высота",
cancel = "Отмена",
w = "Ш",
h = "В",
view = "Вид",
transparencyPad = "Подложка прозрачности",
transparencyColor = "Цвет прозрачности",
transparencyGrid = "Сетка прозрачности",
path = "Путь",
string = "Строка",
file = "Файл",
image = "Изображение",
edit = "Редактировать",
hotkeys = "Горячие клавиши",
about = "О программе",
brushSize = "Размер кисти",
transparency = "Прозрачность",
brushParameters = "Параметры кисти",
size = "Размер",
new = "Новый",
open = "Открыть",
createFromString = "Создать из StringImage",
save = "Сохранить",
saveAs = "Сохранить как",
exit = "Выход",
crop = "Обрезать",
expand = "Расширить",
rotateBy90 = "Повернуть на 90 градусов",
rotateBy180 = "Повернуть на 180 градусов",
flipVertical = "Отразить по вертикали",
flipHorizontal = "Отразить по горизонтали",
hueSaturation = "Тон/Насыщенность",
colorBalance = "Цветовой баланс",
photoFilter = "Фотофильтр",
invertColors = "Инвертировать цвета",
blackWhite = "Черно-белый фильтр",
gaussianBlur = "Размытие по Гауссу",
countOfPixels = "Количество пикселей",
fromBottom = "Снизу",
fromTop = "Сверху",
fromLeft = "Слева",
fromRight = "Справа",
hue = "Тон",
saturation = "Насыщенность",
brightness = "Яркость",
filterColor = "Цвет фильтра",
radius = "Радиус",
force = "Сила",
edges = "Грани",
accept = "Enter - применить",
line = "Линия",
ellipse = "Эллипс",
rectangle = "Прямоугольник",
polygon = "Многоугольник",
border = "Рамка",
fill = "Заливка",
clear = "Очистить",
deselect = "Убрать выделение",
hotkeysLines = {
{"EmptyLine"},
{"CenterText", 0x880000, "Горячие клавиши"},
{"EmptyLine"},
{"CenterText", 0x000000, "B - кисть"},
{"CenterText", 0x000000, "E - ластик"},
{"CenterText", 0x000000, "T - текст"},
{"CenterText", 0x000000, "G - заливка"},
{"CenterText", 0x000000, "M - выделение"},
{"CenterText", 0x000000, " "},
{"CenterText", 0x000000, "Arrows - перемещение"},
{"CenterText", 0x000000, "X - поменять цвета местами"},
{"CenterText", 0x000000, "D - сменить цвета на черный и белый"},
{"CenterText", 0x000000, "Ctrl+D - убрать выделение"},
{"CenterText", 0x000000, "Alt+Click - выбрать цвет (только для кисти)"},
{"EmptyLine"},
{"Button", {0xbbbbbb, 0xffffff, "OK"}},
},
developers = "Разработчики:",
testers = "Тестеры:",
}

View File

@ -0,0 +1,330 @@
----------------------------------------- Libraries -----------------------------------------
local component = require("component")
local computer = require("computer")
local unicode = require("unicode")
local fs = require("filesystem")
local advancedLua = require("advancedLua")
local color = require("color")
local image = require("image")
local buffer = require("doubleBuffering")
local GUI = require("GUI")
local MineOSPaths = require("MineOSPaths")
local MineOSCore = require("MineOSCore")
----------------------------------------- cyka -----------------------------------------
if not component.isAvailable("printer3d") then GUI.error("This program requires at least one 3D-printer"); return end
local args, options = require("shell").parse(...)
local startImagePath = args[1] == "open" and args[2] or "/MineOS/System/Icons/Steve.pic"
local configPath = MineOSPaths.applicationData .. "PrintImage/Config.cfg"
local panelWidth = 34
local mainContainer
local mainImage
local printers
local currentPrinter = 1
local shapeResolutionLimit = 4
local timeDelay = 0.05
----------------------------------------- Config -----------------------------------------
local function save()
table.toFile(configPath, config)
end
local function load()
if fs.exists(configPath) then
config = table.fromFile(configPath)
else
config = {
mainMaterial = "quartz_block_side",
printName = "My picture",
showGrid = true,
floorMode = false,
frame = {enabled = true, width = 3, material = "planks_spruce"},
lightEmission = {enabled = false, level = 8}
}
save()
end
end
----------------------------------------- Printer-related cyka -----------------------------------------
local function getPrinters()
printers = {}
for address in pairs(component.list("printer3d")) do table.insert(printers, component.proxy(address)) end
end
local function addShapePixel(x, y, color, xPrinterPixel, yPrinterPixel)
local pixelSize = math.floor(16 / shapeResolutionLimit)
local xPrinter = x * pixelSize - pixelSize
local yPrinter = y * pixelSize - pixelSize
if config.floorMode then
printers[currentPrinter].addShape(xPrinter, 0, yPrinter, xPrinter + pixelSize, 16, yPrinter + pixelSize, config.mainMaterial, false, color)
else
if config.frame.enabled then
local xModifyer1, xModifyer2, yModifyer1, yModifyer2 = 0, 0, 0, 0
if xPrinterPixel == 1 then xModifyer1 = config.frame.width end
if xPrinterPixel == image.getWidth(mainImage) then xModifyer2 = -config.frame.width end
if yPrinterPixel == 1 then yModifyer2 = -config.frame.width end
if yPrinterPixel == image.getHeight(mainImage) * 2 then yModifyer1 = config.frame.width end
printers[currentPrinter].addShape(xPrinter + xModifyer1, yPrinter + yModifyer1, 15, xPrinter + pixelSize + xModifyer2, yPrinter + pixelSize + yModifyer2, 16, config.mainMaterial, false, color)
else
printers[currentPrinter].addShape(xPrinter, 15, yPrinter, xPrinter + pixelSize, 16, yPrinter + pixelSize, config.mainMaterial, false, color)
end
end
end
local function beginPrint()
buffer.clear(0x0000000, 50)
local xShape, yShape = 1, 1
local xShapeCount, yShapeCount = math.ceil(image.getWidth(mainImage) / shapeResolutionLimit), math.ceil(image.getHeight(mainImage) * 2 / shapeResolutionLimit)
local counter = 0
while true do
if printers[currentPrinter].status() == "idle" then
printers[currentPrinter].reset()
printers[currentPrinter].setLabel(config.printName)
printers[currentPrinter].setTooltip("Part " .. xShape .. "x" .. yShape .. " of " .. xShapeCount .. "x" .. yShapeCount)
if config.lightEmission.enabled then printers[currentPrinter].setLightLevel(config.lightEmission.level) end
local jReplacer = shapeResolutionLimit
for j = 1, shapeResolutionLimit / 2 do
for i = 1, shapeResolutionLimit do
local xImage = xShape * shapeResolutionLimit - shapeResolutionLimit + i
local yImage = yShape * (shapeResolutionLimit / 2) - (shapeResolutionLimit / 2) + j
if xImage <= image.getWidth(mainImage) and yImage <= image.getHeight(mainImage) then
local background, foreground, alpha, symbol = image.get(mainImage, xImage, yImage)
if alpha < 0xFF then
if symbol == " " then foreground = background end
addShapePixel(i, jReplacer, background, xImage, yImage * 2 - 1)
addShapePixel(i, jReplacer - 1, foreground, xImage, yImage * 2)
end
GUI.progressBar(math.floor(buffer.getWidth() / 2 - 25), math.floor(buffer.getHeight() / 2), 50, 0x3366CC, 0xFFFFFF, 0xFFFFFF, math.ceil(counter * 100 / (xShapeCount * yShapeCount)), true, true, "Progress: ", "%"):draw()
buffer.draw()
-- else
-- error("Printing out of mainImage range")
end
end
jReplacer = jReplacer - 2
end
if config.frame.enabled and not config.floorMode then
local xFrame, yFrame = shapeResolutionLimit * (image.getWidth(mainImage) % shapeResolutionLimit), shapeResolutionLimit * ((image.getHeight(mainImage) * 2) % shapeResolutionLimit)
xFrame = xShape == xShapeCount and (xFrame == 0 and 16 or xFrame) or 16
yFrame = yShape == yShapeCount and (yFrame == 0 and 0 or yFrame) or 0
if xShape == 1 then printers[currentPrinter].addShape(0, yFrame, 14, config.frame.width, 16, 16, config.frame.material) end
if xShape == xShapeCount then printers[currentPrinter].addShape(xFrame - config.frame.width, yFrame, 14, xFrame, 16, 16, config.frame.material) end
if yShape == 1 then printers[currentPrinter].addShape(0, 16 - config.frame.width, 14, xFrame, 16, 16, config.frame.material) end
if yShape == yShapeCount then printers[currentPrinter].addShape(0, yFrame, 14, xFrame, yFrame + config.frame.width, 16, config.frame.material) end
end
printers[currentPrinter].commit()
counter = counter + 1
xShape = xShape + 1
if xShape > xShapeCount then xShape = 1; yShape = yShape + 1 end
if yShape > yShapeCount then break end
end
currentPrinter = currentPrinter + 1
if currentPrinter > #printers then currentPrinter = 1 end
os.sleep(timeDelay)
end
buffer.clear()
mainContainer:draw()
buffer.draw(true)
end
----------------------------------------- Window-zaluped parasha -----------------------------------------
local function getStatus()
local xBlocks, yBlocks = math.ceil(image.getWidth(mainImage) / shapeResolutionLimit), math.ceil(image.getHeight(mainImage) * 2 / shapeResolutionLimit)
mainContainer.shadeContainer.statusTextBox.lines = {
"Image size: " .. image.getWidth(mainImage) .. "x" .. image.getHeight(mainImage) .. " px",
"Count of printers: " .. #printers,
"Print result: " .. xBlocks .. "x" .. yBlocks .. " blocks",
"Total count: " .. xBlocks * yBlocks .. " blocks"
}
end
local function verticalLine(x, y, height, transparency)
for i = y, y + height - 1 do
local background = buffer.get(x, i)
buffer.set(x, i, background, color.blend(background, 0xFFFFFF, transparency), "")
end
end
local function horizontalLine(x, y, width, transparency)
for i = x, x + width - 1 do
local background, foreground, symbol = buffer.get(i, y)
buffer.set(i, y, background, color.blend(background, 0xFFFFFF, transparency), symbol == "" and "" or "")
end
end
local function drawMainImageObject(object)
if mainImage then
local xImage = image.getWidth(mainImage) < buffer.getWidth() and math.floor(buffer.getWidth() / 2 - image.getWidth(mainImage) / 2) or 1
local yImage = image.getHeight(mainImage) < buffer.getHeight() and math.floor(buffer.getHeight() / 2 - image.getHeight(mainImage) / 2) or 1
buffer.image(xImage, yImage, mainImage)
GUI.windowShadow(xImage, yImage, image.getWidth(mainImage), image.getHeight(mainImage), 50, true)
if config.showGrid then
for x = xImage, xImage + image.getWidth(mainImage) - 1, shapeResolutionLimit do verticalLine(x, yImage, image.getHeight(mainImage), 0.627) end
for y = yImage, yImage + image.getHeight(mainImage) - 1, shapeResolutionLimit / 2 do horizontalLine(xImage, y, image.getWidth(mainImage), 0.627) end
buffer.text(1, 1, 0xBBBBBB, "хуй")
end
end
end
local function createWindow()
mainContainer = GUI.fullScreenContainer()
mainContainer:addChild(GUI.panel(1, 1, mainContainer.width, mainContainer.height, 0xEEEEEE))
mainContainer:addChild(GUI.object(1, 1, mainContainer.width, mainContainer.height)).draw = drawMainImageObject
local textBoxesWidth = math.floor(panelWidth * 0.55)
mainContainer.shadeContainer = mainContainer:addChild(GUI.container(mainContainer.width - panelWidth + 1, 1, panelWidth, mainContainer.height))
mainContainer.shadeContainer:addChild(GUI.panel(1, 1, mainContainer.shadeContainer.width, mainContainer.shadeContainer.height, 0x0000000, 0.4))
local y = 2
mainContainer.shadeContainer:addChild(GUI.label(1, y, mainContainer.shadeContainer.width, 1, 0xFFFFFF, "Main properties")):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top)
y = y + 2
mainContainer.shadeContainer:addChild(GUI.label(3, y, mainContainer.shadeContainer.width, 1, 0xCCCCCC, "Image path:"))
local filesystemChooser = mainContainer.shadeContainer:addChild(GUI.filesystemChooser(mainContainer.shadeContainer.width - textBoxesWidth - 1, y, textBoxesWidth, 1, 0xEEEEEE, 0x262626, 0x444444, 0x999999, startImagePath, MineOSCore.localization.open, MineOSCore.localization.cancel, "Image path", "/"))
filesystemChooser:addExtensionFilter(".pic")
filesystemChooser.onSubmit = function(path)
mainImage = image.load(path)
getStatus()
mainContainer:draw()
buffer.draw()
end
y = y + 2
mainContainer.shadeContainer:addChild(GUI.label(3, y, mainContainer.shadeContainer.width, 1, 0xCCCCCC, "Material:"))
local mainMaterialTextBox = mainContainer.shadeContainer:addChild(GUI.input(mainContainer.shadeContainer.width - textBoxesWidth - 1, y, textBoxesWidth, 1, 0xEEEEEE, 0x555555, 0x555555, 0xEEEEEE, 0x262626, config.mainMaterial, nil, false))
mainMaterialTextBox.onInputFinished = function()
config.mainMaterial = mainMaterialTextBox.text
save()
end
y = y + 2
mainContainer.shadeContainer:addChild(GUI.label(3, y, mainContainer.shadeContainer.width, 1, 0xCCCCCC, "Print name:"))
local printNameTextBox = mainContainer.shadeContainer:addChild(GUI.input(mainContainer.shadeContainer.width - textBoxesWidth - 1, y, textBoxesWidth, 1, 0xEEEEEE, 0x555555, 0x555555, 0xEEEEEE, 0x262626, config.printName, nil, false))
printNameTextBox.onInputFinished = function()
config.printName = printNameTextBox.text
save()
end
y = y + 2
mainContainer.shadeContainer:addChild(GUI.label(3, y, mainContainer.shadeContainer.width, 1, 0xCCCCCC, "Floor mode:"))
local floorSwitch = mainContainer.shadeContainer:addChild(GUI.switch(mainContainer.shadeContainer.width - 9, y, 8, 0xFFDB40, 0xAAAAAA, 0xFFFFFF, config.floorMode))
floorSwitch.onStateChanged = function()
config.floorMode = floorSwitch.state
save()
end
y = y + 2
mainContainer.shadeContainer:addChild(GUI.label(3, y, mainContainer.shadeContainer.width, 1, 0xCCCCCC, "Show grid:"))
local gridSwitch = mainContainer.shadeContainer:addChild(GUI.switch(mainContainer.shadeContainer.width - 9, y, 8, 0xFFDB40, 0xAAAAAA, 0xFFFFFF, config.showGrid))
gridSwitch.onStateChanged = function()
config.showGrid = gridSwitch.state
save()
mainContainer:draw()
end
y = y + 4
mainContainer.shadeContainer:addChild(GUI.label(1, y, mainContainer.shadeContainer.width, 1, 0xFFFFFF, "Frame properties")):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top)
y = y + 2
mainContainer.shadeContainer:addChild(GUI.label(3, y, mainContainer.shadeContainer.width, 1, 0xCCCCCC, "Enabled:"))
local frameSwitch = mainContainer.shadeContainer:addChild(GUI.switch(mainContainer.shadeContainer.width - 9, y, 8, 0xFFDB40, 0xAAAAAA, 0xFFFFFF, config.frame.enabled))
frameSwitch.onStateChanged = function()
config.frame.enabled = frameSwitch.state
save()
end
y = y + 2
mainContainer.shadeContainer:addChild(GUI.label(3, y, mainContainer.shadeContainer.width, 1, 0xCCCCCC, "Material:"))
local frameMaterialTextBox = mainContainer.shadeContainer:addChild(GUI.input(mainContainer.shadeContainer.width - textBoxesWidth - 1, y, textBoxesWidth, 1, 0xEEEEEE, 0x555555, 0x555555, 0xEEEEEE, 0x262626, config.frame.material, nil, false))
frameMaterialTextBox.onInputFinished = function()
config.frame.material = frameMaterialTextBox.text
save()
end
y = y + 2
local frameWidthSlider = mainContainer.shadeContainer:addChild(GUI.slider(3, y, mainContainer.shadeContainer.width - 4, 0xFFDB80, 0x000000, 0xFFDB40, 0xCCCCCC, 1, shapeResolutionLimit - 1, config.frame.width, false, "Width: " , " voxel(s)"))
frameWidthSlider.onValueChanged = function()
config.frame.width = frameWidthSlider.value
save()
end
frameWidthSlider.roundValues = true
y = y + 5
mainContainer.shadeContainer:addChild(GUI.label(1, y, mainContainer.shadeContainer.width, 1, 0xFFFFFF, "Light emission")):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top)
y = y + 2
mainContainer.shadeContainer:addChild(GUI.label(3, y, mainContainer.shadeContainer.width, 1, 0xCCCCCC, "Enabled:"))
local lightSwitch = mainContainer.shadeContainer:addChild(GUI.switch(mainContainer.shadeContainer.width - 9, y, 8, 0xFFDB40, 0xAAAAAA, 0xFFFFFF, config.lightEmission.enabled))
lightSwitch.onStateChanged = function()
config.lightEmission.enabled = true
save()
end
y = y + 2
local lightSlider = mainContainer.shadeContainer:addChild(GUI.slider(3, y, mainContainer.shadeContainer.width - 4, 0xFFDB80, 0x000000, 0xFFDB40, 0xCCCCCC, 1, 8, 8, false, "Radius: " , " block(s)"))
lightSlider.roundValues = true
lightSlider.onValueChanged = function()
config.lightEmission.value = lightSlider.value
save()
end
y = y + 5
mainContainer.shadeContainer:addChild(GUI.label(1, y, mainContainer.shadeContainer.width, 1, 0xFFFFFF, "Summary information:")):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top)
y = y + 2
mainContainer.shadeContainer.statusTextBox = mainContainer.shadeContainer:addChild(GUI.textBox(3, y, mainContainer.shadeContainer.width - 4, 5, nil, 0xCCCCCC, {}, 1)):setAlignment(GUI.alignment.horizontal.left, GUI.alignment.vertical.top)
mainContainer.shadeContainer:addChild(GUI.button(1, mainContainer.shadeContainer.height - 5, mainContainer.shadeContainer.width, 3, 0x363636, 0xFFFFFF, 0xFFFFFF, 0x262626, "Exit")).onTouch = function()
mainContainer:stopEventHandling()
end
mainContainer.shadeContainer:addChild(GUI.button(1, mainContainer.shadeContainer.height - 2, mainContainer.shadeContainer.width, 3, 0x262626, 0xFFFFFF, 0xFFFFFF, 0x262626, "Start print")).onTouch = function()
beginPrint()
end
mainContainer.eventHandler = function(mainContainer, object, eventData)
if (eventData[1] == "component_added" or eventData[1] == "component_removed") and eventData[3] == "printer3d" then
getPrinters()
getStatus()
mainContainer:draw()
buffer.draw()
end
end
end
----------------------------------------- Shitty meatball rolls -----------------------------------------
buffer.flush()
load()
getPrinters()
createWindow()
mainImage = image.load(startImagePath)
getStatus()
mainContainer:draw()
buffer.draw()
mainContainer:startEventHandling()

View File

@ -0,0 +1,442 @@
local os = require("os")
local term = require("term")
local event = require("event")
local component = require("component")
local gpu = component.gpu
math.randomseed(os.time())
local version = "Cube v1.0"
local level = {}
local doors = {}
local indicator={}
local nick_player
local markColor = {0xff0000, 0xffff00, 0x00ff00, 0x00ffff, 0x0000ff, 0xff00ff, 0xffffff}
local playerColor = 3
local sx,sy = gpu.getResolution()
sx, sy = math.modf(sx/4), math.modf(sy/2) -- точка отступа/координата игрока на экране (статичные)/центр событий
local px,py = 3,3 -- относительные координаты игрока в комнате
local min_map, max_map = 1, 1000 -- ограничители номеров комнат, чтобы сильно не запутаться при прохождении
level[1] = {number=1, color = 0xffffff, mark=false} -- цель игры - попасть в эту комнату
-------------------------------------------------------------------------------------
----------------------- Генерация случайных формул для дверей -----------------------
local rand_1, rand_2 ,rand_3, rand_4
while true do
rand_1, rand_2 ,rand_3, rand_4 = math.random(1,2), math.random(10,30), math.random(1,2), math.random(10,30)
if rand_1~=rand_3 and rand_2~=rand_4 then break end
end
formula={}
formula[1]=function(n) return n*rand_1 + rand_2 end
formula[2]=function(n) return n*rand_3 + rand_4 end
formula[-1]=function(n) return (n - rand_2)/rand_1 end
formula[-2]=function(n) return (n - rand_4)/rand_3 end
-------------------------------------------------------------------------------------
---------------------- Возвращает или генерирует новую комнату ----------------------
function gen_level(i)
i = tonumber(i)
if not level[i] then
level[i]={number=i, color = math.random(0x000000, 0xffffff), mark=false}
end
return level[i]
end
-------------------------------------------------------------------------------------
-------------------------- Проверка, существует ли комната --------------------------
function proverka(x,y) -- где x номер формулы, y номер текущей комнаты
local number = formula[x](y)
return number >= min_map and number <= max_map and number == math.modf(number)
end
-------------------------------------------------------------------------------------
---------------------------- Генерация статистики комнат ----------------------------
function sorting(sorting_table, not_sorting_table)
local trash_table={}
while true do
if #not_sorting_table==0 then
break
else
local new_level = not_sorting_table[1]
local power = true
for i=1, #sorting_table do
if sorting_table[i][1]== new_level[1] then
power = false
if new_level[2] < sorting_table[i][2] then
sorting_table[i][2]=new_level[2]
if proverka(1,new_level[1]) then
trash_table[#trash_table+1] = {formula[1](new_level[1]), new_level[2]+1}
end
if proverka(2,new_level[1]) then
trash_table[#trash_table+1] = {formula[2](new_level[1]), new_level[2]+1}
end
if proverka(-1,new_level[1]) then
trash_table[#trash_table+1] = {formula[-1](new_level[1]), new_level[2]+1}
end
if proverka(-2,new_level[1]) then
trash_table[#trash_table+1] = {formula[-2](new_level[1]), new_level[2]+1}
end
end
table.remove(not_sorting_table,1)
end
end
if power then
sorting_table[#sorting_table+1] = new_level
table.remove(not_sorting_table,1)
if proverka(1,new_level[1]) then
not_sorting_table[#not_sorting_table+1] = {formula[1](new_level[1]), new_level[2]+1}
end
if proverka(2,new_level[1]) then
not_sorting_table[#not_sorting_table+1] = {formula[2](new_level[1]), new_level[2]+1}
end
if proverka(-1,new_level[1]) then
not_sorting_table[#not_sorting_table+1] = {formula[-1](new_level[1]), new_level[2]+1}
end
if proverka(-2,new_level[1]) then
not_sorting_table[#not_sorting_table+1] = {formula[-2](new_level[1]), new_level[2]+1}
end
end
end
end
return sorting_table, trash_table
end
-- первая сортировка
local not_sorting_tb, trash_tb={}
not_sorting_tb[1]={1,0}
local sorting_tb, trash_tb = sorting({}, not_sorting_tb)
-- последующие сортировки
while true do
not_sorting_tb = trash_tb
sorting_tb, trash_tb = sorting(sorting_tb, not_sorting_tb)
if #trash_tb == 0 then break end
end
-- очищаем память
not_sorting_tb, trash_tb = nil, nil
-- перестраиваем таблицу
local stat_table={}
for i=1, #sorting_tb do
stat_table[sorting_tb[i][1]]=sorting_tb[i][2]
end
-------------------------------------------------------------------------------------
------------------ Находим номер самой удалённой комнаты от выхода ------------------
local j=1
for i=1, #sorting_tb do
if sorting_tb[i][2]>sorting_tb[j][2] then
j=i
end
end
-------------------------------------------------------------------------------------
----------------------- Устанавливаем номер стартовой комнаты -----------------------
local chamber = gen_level(sorting_tb[j][1])
-- запишем количество комнат в игре
local max_table, max_level = #sorting_tb, sorting_tb[j][2]
-- удалим из памяти ненужную таблицу
sorting_tb = nil
-------------------------------------------------------------------------------------
--------------------------- Переставляет двери в комнате ----------------------------
function reload_doors()
local rezerv={}
for i=1,4 do -- занесём двери в базу данных, чтобы знать использованные формулы
if doors[i] then
rezerv[#rezerv+1]=doors[i]
end
end
for i=1,4 do -- перебираем все 4 двери
if not doors[i] then
while true do
local rand = math.random(-2,2)
local rezerv_2 = 0
if rand ~= 0 then
if #rezerv > 0 then -- проверка, есть ли комната с такой же формулой
for j=1, #rezerv do
if rezerv[j] == rand then break else rezerv_2 = rezerv_2 + 1 end
end
end
if rezerv_2 == #rezerv then -- если нет повторяющихся формул, то присваивается данная формула
doors[i] = rand
rezerv[#rezerv+1]=rand
break
end
end
end
end
end
end
-- //данная функция достаточно сложна чтобы запутаться
-------------------------------------------------------------------------------------
---------------------------------- Рисования меток ----------------------------------
function mark_print(nx, ny, number)
if level[number].mark then
for i=1, #level[number].mark do
gpu.setBackground(level[number].mark[i][3])
gpu.set((level[number].mark[i][1]+nx)*2, level[number].mark[i][2]+ny, " ")
end
end
end
-------------------------------------------------------------------------------------
------------------------- Рисования комнаты по координатам --------------------------
function level_print(nx, ny, color, number)
number = tostring(number)
gpu.setBackground(color)
gpu.set(nx*2, ny, " ")
gpu.set((nx+4)*2, ny, " ")
gpu.set(nx*2, ny+6, " ")
gpu.set((nx+4)*2, ny+6, " ")
gpu.set(nx*2, ny+1, " ")
gpu.set(nx*2, ny+2, " ")
gpu.set(nx*2, ny+4, " ")
gpu.set(nx*2, ny+5, " ")
gpu.set((nx+6)*2, ny+1, " ")
gpu.set((nx+6)*2, ny+2, " ")
gpu.set((nx+6)*2, ny+4, " ")
gpu.set((nx+6)*2, ny+5, " ")
gpu.setBackground(0x000000)
gpu.set(nx*2+6-math.modf((string.len(number)-1)/2), ny+3, number)
end
-------------------------------------------------------------------------------------
----------------------------- Переходы между комнатами ------------------------------
pxx, pyy = {}, {}
pxx[-1]=function(nx)
local rezerv_3 = doors[1]
if proverka(rezerv_3, chamber.number) then
doors={}
doors[2] = -rezerv_3
reload_doors()
chamber = gen_level(formula[rezerv_3](chamber.number))
ppx = 6
else
ppx = px
end
end
pxx[7]=function(nx)
local rezerv_3 = doors[2]
if proverka(rezerv_3, chamber.number) then
doors={}
doors[1] = -rezerv_3
reload_doors()
chamber = gen_level(formula[rezerv_3](chamber.number))
ppx = 0
else
ppx = px
end
end
pyy[-1]=function(ny)
local rezerv_3 = doors[3]
if proverka(rezerv_3, chamber.number) then
doors={}
doors[4] = -rezerv_3
reload_doors()
chamber = gen_level(formula[rezerv_3](chamber.number))
ppy = 6
else
ppy = py
end
end
pyy[7]=function(ny)
local rezerv_3 = doors[4]
if proverka(rezerv_3, chamber.number) then
doors={}
doors[3] = -rezerv_3
reload_doors()
chamber = gen_level(formula[rezerv_3](chamber.number))
ppy = 0
else
ppy = py
end
end
-- //работает как надо, но лучше подредактировать
-------------------------------------------------------------------------------------
-------------------------------- Передвижение игрока --------------------------------
function player_update(nx,ny)
ppx, ppy = px+nx, py+ny
if not ((ppx==0 or ppy==0 or ppx==6 or ppy==6) and ppx~=3 and ppy~=3) then
if pxx[ppx] then pxx[ppx](ppx)
elseif pyy[ppy] then pyy[ppy](ppy)
end
px,py = ppx,ppy
end
end
-- //работает как надо, но лучше подредактировать
-------------------------------------------------------------------------------------
--------------------------------- Блок отображения ----------------------------------
function update(nick)
nick_player = nick
term.clear()
-- текущая комната
gen_level(chamber.number)
mark_print(sx-px,sy-py, chamber.number)
level_print(sx-px,sy-py,chamber.color, chamber.number)
-- комната слева
if proverka(doors[1], chamber.number) and px==0 then
local number = formula[doors[1]](chamber.number)
gen_level(number)
mark_print(sx-7-px,sy-py, number)
level_print(sx-7-px,sy-py,gen_level(formula[doors[1]](chamber.number)).color, gen_level(formula[doors[1]](chamber.number)).number)
end
-- комната справа
if proverka(doors[2], chamber.number) and px==6 then
local number = formula[doors[2]](chamber.number)
gen_level(number)
mark_print(sx+7-px,sy-py, number)
level_print(sx+7-px,sy-py,gen_level(formula[doors[2]](chamber.number)).color, gen_level(formula[doors[2]](chamber.number)).number)
end
-- комната сверху
if proverka(doors[3], chamber.number) and py==0 then
local number = formula[doors[3]](chamber.number)
gen_level(number)
mark_print(sx-px,sy-7-py, number)
level_print(sx-px,sy-7-py,gen_level(formula[doors[3]](chamber.number)).color, gen_level(formula[doors[3]](chamber.number)).number)
end
-- комната снизу
if proverka(doors[4], chamber.number) and py==6 then
local number = formula[doors[4]](chamber.number)
gen_level(number)
mark_print(sx-px,sy+7-py, number)
level_print(sx-px,sy+7-py,gen_level(formula[doors[4]](chamber.number)).color, number)
end
-- отображение игрока
gpu.setBackground(0xff0000)
gpu.set(sx*2, sy, " ")
-- текстовые индикаторы
for i=1, #indicator do
indicator[i]()
end
-- индикатор выбранного цвета
gpu.setBackground(markColor[playerColor])
gpu.set(2, sy*2, " ")
end
-------------------------------------------------------------------------------------
---------------------------------- Блок управления ----------------------------------
local command={}
command[200]=function() player_update(0,-1) end -- вверх
command[208]=function() player_update(0,1) end -- вниз
command[203]=function() player_update(-1,0) end -- влево
command[205]=function() player_update(1,0) end -- вправо
command[17]=function() -- ставить метку
if not level[chamber.number].mark then level[chamber.number].mark={} end
level[chamber.number].mark[#level[chamber.number].mark+1]={px,py,markColor[playerColor]}
end
command[30]=function() if playerColor-1<1 then playerColor=#markColor else playerColor=playerColor-1 end end -- цвет слева
command[32]=function() if playerColor+1>#markColor then playerColor=1 else playerColor=playerColor+1 end end -- цвет справа
command[31]=function() -- удалить метку
if level[chamber.number].mark then
for i=#level[chamber.number].mark, 1, -1 do
if px==level[chamber.number].mark[i][1] and py==level[chamber.number].mark[i][2] then
table.remove(level[chamber.number].mark,i)
end
end
end
end
command[23]=function() -- включает режим разработчика
if #indicator==0 then
indicator[1]=function()
gpu.setBackground(0x000000)
gpu.setForeground(0xffff00)
gpu.set(2, 2, "max level: "..max_level)
gpu.set(2, 3, "all levels: "..max_table)
gpu.set(2, 4, "this level: "..stat_table[chamber.number])
gpu.setForeground(0xff0000)
gpu.set(2, 5, "formula 1: ".."n".."*"..rand_1.." + "..rand_2)
gpu.set(2, 6, "formula 2: ".."n".."*"..rand_3.." + "..rand_4)
gpu.set(2, 7, "formula -1: ".."(n - "..rand_2..")/"..rand_1)
gpu.set(2, 8, "formula -2: ".."(n - "..rand_4..")/"..rand_3)
gpu.setForeground(0xff00ff)
gpu.set(2, 9, "progress: " .. math.modf(100-stat_table[chamber.number]*100/max_level).."%")
gpu.setForeground(0xff00ff)
gpu.set(2, 10, "color: "..playerColor)
gpu.setForeground(0xffffff)
end
else
table.remove(indicator,1)
end
end
command[35]=function() -- отобразить управление
term.clear()
gpu.setForeground(0xff0000)
print(version)
print("")
gpu.setForeground(0x00ff00)
print("Target: searching chamber 1")
print("Game 100% passable")
gpu.setForeground(0xffff00)
print("Control:")
print("Q - exit game")
print("H - help")
print("I - info")
print("W - set mark")
print("S - remove mark")
print("A - back color mark")
print("D - next color mark")
print("")
gpu.setForeground(0xffffff)
print("press enter to continue...")
while true do
_,_,_, key = event.pull("key_down")
if key == 28 then
break
end
end
end
-------------------------------------------------------------------------------------
---------------------- Показываем управление до начала игры -------------------------
command[35]()
-------------------------------------------------------------------------------------
------------------------- Отображение комнат до начала игры -------------------------
reload_doors()
update(nick)
gpu.setBackground(0x000000)
-------------------------------------------------------------------------------------
------------------------------------- Тело игры -------------------------------------
while true do
_,_,_, key, nick = event.pull("key_down")
if key==16 then
term.clear()
gpu.setForeground(0xff0000)
print("Exit to game?")
gpu.setForeground(0xffffff)
print("")
print("y/n")
while true do
_,_,_, key = event.pull("key_down")
if key == 21 then
term.clear()
return
elseif key == 49 then
break
end
end
elseif command[key] then
command[key]()
end
update(nick)
gpu.setBackground(0x000000)
if chamber.number == 1 then break end -- цель игры, комната с этим номером
os.sleep(1/15) -- задержка, для более удобного управления
end
-------------------------------------------------------------------------------------
------------------------------------- Прощание -------------------------------------
term.clear()
gpu.setForeground(0x00ff00)
print("Congratulations "..nick_player.."!")
print("You win!")
print("")
gpu.setForeground(0xffffff)
print("press enter to exit...")
while true do
_,_,_, key = event.pull("key_down")
if key == 28 then
break
end
end
term.clear()
-------------------------------------------------------------------------------------

View File

@ -0,0 +1 @@
Это мини-игра, разработанная товарищем qwertyMan с форума ComputerCraft.ru. А я ее нагло спиздил. Цель игры: вы должны понять, как устроен "квантовый куб", решить задачу (найти цепочку выходов) к комнате номер 1 и выбраться из квантового лабиринта. А на деле рандомно бегать в поисках комнаты номер 1, не понимать как устроена система нумераций, ловить баттхёрты и проклинать всех, кого только можно. Потому что если даже соседняя комната и окажется под номером 1, то вы можете запросто пробежать и даже не заглянуть в неё. Так как мы видим лишь те комнаты, на границе с которыми стоим.

View File

@ -0,0 +1,314 @@
-- package.loaded.bigLetters = nil
local event = require("event")
local buffer = require("doubleBuffering")
local bigLetters = require("bigLetters")
local unicode = require("unicode")
local component = require("component")
local fs = require("filesystem")
local context = require("context")
local serialization = require("serialization")
local ecs = require("ECSAPI")
local radio
if not component.isAvailable("openfm_radio") then
ecs.error("Этой программе требуется радио из мода OpenFM. Причем не на всех версиях еще работает, автор мода - пидор! Проверял на ноябрьской, полет нормальный.")
return
else
radio = component.openfm_radio
end
local pathToSaveStations = "MineOS/System/Radio/Stations.cfg"
local stationNameLimit = 8
local spaceBetweenStations = 8
local countOfStationsLimit = 9
local lineHeight
local config = {
colors = {
background = 0x1b1b1b,
line = 0xFFFFFF,
lineShadow = 0x000000,
activeStation = 0xFFA800,
otherStation = 0xBBBBBB,
bottomToolBarDefaultColor = 0xaaaaaa,
bottomToolBarCurrentColor = 0xFFA800,
},
}
local radioStations = {
currentStation = 3,
{
name = "Galnet Soft",
url = "http://galnet.ru:8000/soft"
},
{
name = "Европа Плюс",
url = "http://ep256.streamr.ru"
},
{
name = "L-Radio",
url = "http://server2.lradio.ru:8000/lradio64.aac.m3u"
},
{
name = "Radio Record",
url = "http://online.radiorecord.ru:8101/rr_128.m3u"
},
{
name = "Moscow FM",
url = "http://livestream.rfn.ru:8080/moscowfmen128.m3u"
},
}
--Объекты для тача
local obj = {}
local function drawStation(x, y, name, color)
bigLetters.drawText(x, y, color, name)
end
local function drawLine()
local x = math.floor(buffer.getWidth() / 2)
for i = 1, lineHeight do
buffer.text(x + 1, i, config.colors.lineShadow, "")
buffer.text(x, i, config.colors.line, "")
end
end
local function drawLeftArrow(x, y, color)
local bg, fg = config.colors.background, color
local arrow = {
{ {bg, fg, " "}, {bg, fg, " "}, {bg, fg, "*"} },
{ {bg, fg, " "}, {bg, fg, "*"}, {bg, fg, " "} },
{ {bg, fg, "*"}, {bg, fg, " "}, {bg, fg, " "} },
{ {bg, fg, " "}, {bg, fg, "*"}, {bg, fg, " "} },
{ {bg, fg, " "}, {bg, fg, " "}, {bg, fg, "*"} },
}
buffer.customImage(x, y, arrow)
end
local function drawRightArrow(x, y, color)
local bg, fg = config.colors.background, color
local arrow = {
{ {bg, fg, "*"}, {bg, fg, " "}, {bg, fg, " "} },
{ {bg, fg, " "}, {bg, fg, "*"}, {bg, fg, " "} },
{ {bg, fg, " "}, {bg, fg, " "}, {bg, fg, "*"} },
{ {bg, fg, " "}, {bg, fg, "*"}, {bg, fg, " "} },
{ {bg, fg, "*"}, {bg, fg, " "}, {bg, fg, " "} },
}
buffer.customImage(x, y, arrow)
end
local function drawMenu()
local width = 36 + (3 * 2 + 2) * #radioStations
local x, y = math.floor(buffer.getWidth() / 2 - width / 2), lineHeight + math.floor((buffer.getHeight() - lineHeight) / 2 - 1)
obj.gromkostPlus = {x, y, x + 4, y + 3}
x = bigLetters.drawText(x, y, config.colors.bottomToolBarDefaultColor, "+", "*") + 1
x = x + 1
obj.strelkaVlevo = {x, y, x + 4, y + 3}
drawLeftArrow(x, y, config.colors.bottomToolBarDefaultColor); x = x + 5
x = x + 3
local color
for i = 1, #radioStations do
if i == radioStations.currentStation then color = config.colors.bottomToolBarCurrentColor else color = config.colors.bottomToolBarDefaultColor end
x = bigLetters.drawText(x, y, color, tostring(i), "*") + 1
end
x = x + 2
obj.strelkaVpravo = {x, y, x + 4, y + 3}
drawRightArrow(x, y, config.colors.bottomToolBarDefaultColor)
x = x + 8
obj.gromkostMinus = {x, y, x + 4, y + 3}
x = bigLetters.drawText(x, y, config.colors.bottomToolBarDefaultColor, "-", "*") + 1
end
local function drawStations()
local prevWidth, currentWidth, nextWidth, name
-- Текущая станция
name = ecs.stringLimit("end", unicode.lower(radioStations[radioStations.currentStation].name), stationNameLimit, true)
currentWidth = bigLetters.getTextSize(name)
local x, y = math.floor(buffer.getWidth() / 2 - currentWidth / 2), math.floor(buffer.getHeight() / 2 - 3)
drawStation(x, y, name, config.colors.activeStation)
-- Предедущая
if radioStations[radioStations.currentStation - 1] then
name = ecs.stringLimit("start", unicode.lower(radioStations[radioStations.currentStation - 1].name), stationNameLimit)
prevWidth = bigLetters.getTextSize(name)
drawStation(x - prevWidth - spaceBetweenStations, y, name, config.colors.otherStation)
end
-- Следующая
if radioStations[radioStations.currentStation + 1] then
name = ecs.stringLimit("end", unicode.lower(radioStations[radioStations.currentStation + 1].name), stationNameLimit)
nextWidth = bigLetters.getTextSize(name)
drawStation(x + currentWidth + spaceBetweenStations + 1, y, name, config.colors.otherStation)
end
-- ecs.error(x, x - prevWidth - spaceBetweenStations, prevWidth, currentWidth, nextWidth)
end
local function drawAll()
-- Коррекция от кривых ручонок юзверей
if radioStations.currentStation < 1 then
radioStations.currentStation = 1
elseif radioStations.currentStation > #radioStations then
radioStations.currentStation = #radioStations
end
buffer.square(1, 1, buffer.getWidth(), buffer.getHeight(), config.colors.background, 0xFFFFFF, " ")
drawStations()
drawLine()
drawMenu()
buffer.draw()
end
local function saveStations()
fs.makeDirectory(fs.path(pathToSaveStations))
local file = io.open(pathToSaveStations, "w")
file:write(serialization.serialize(radioStations))
file:close()
end
local function loadStations()
if fs.exists(pathToSaveStations) then
local file = io.open(pathToSaveStations, "r")
radioStations = serialization.unserialize(file:read("*a"))
file:close()
else
saveStations()
end
end
local function switchStation(i)
if i == 1 then
if radioStations.currentStation < #radioStations then
radioStations.currentStation = radioStations.currentStation + 1
saveStations()
radio.stop()
radio.setURL(radioStations[radioStations.currentStation].url)
radio.start()
end
else
if radioStations.currentStation > 1 then
radioStations.currentStation = radioStations.currentStation - 1
saveStations()
radio.stop()
radio.setURL(radioStations[radioStations.currentStation].url)
radio.start()
end
end
end
local function volume(i)
if i == 1 then
radio.volUp()
else
radio.volDown()
end
end
buffer.flush()
lineHeight = math.floor(buffer.getHeight() * 0.7)
loadStations()
radio.stop()
radio.setURL(radioStations[radioStations.currentStation].url)
radio.start()
drawAll()
while true do
local e = {event.pull()}
if e[1] == "touch" then
if e[5] == 0 then
if ecs.clickedAtArea(e[3], e[4], obj.strelkaVlevo[1], obj.strelkaVlevo[2], obj.strelkaVlevo[3], obj.strelkaVlevo[4]) then
drawLeftArrow(obj.strelkaVlevo[1], obj.strelkaVlevo[2], config.colors.bottomToolBarCurrentColor)
buffer.draw()
os.sleep(0.2)
switchStation(-1)
drawAll()
elseif ecs.clickedAtArea(e[3], e[4], obj.strelkaVpravo[1], obj.strelkaVpravo[2], obj.strelkaVpravo[3], obj.strelkaVpravo[4]) then
drawRightArrow(obj.strelkaVpravo[1], obj.strelkaVpravo[2], config.colors.bottomToolBarCurrentColor)
buffer.draw()
os.sleep(0.2)
switchStation(1)
drawAll()
elseif ecs.clickedAtArea(e[3], e[4], obj.gromkostPlus[1], obj.gromkostPlus[2], obj.gromkostPlus[3], obj.gromkostPlus[4]) then
bigLetters.drawText(obj.gromkostPlus[1], obj.gromkostPlus[2], config.colors.bottomToolBarCurrentColor, "+", "*" )
buffer.draw()
volume(1)
os.sleep(0.2)
drawAll()
elseif ecs.clickedAtArea(e[3], e[4], obj.gromkostMinus[1], obj.gromkostMinus[2], obj.gromkostMinus[3], obj.gromkostMinus[4]) then
bigLetters.drawText(obj.gromkostMinus[1], obj.gromkostMinus[2], config.colors.bottomToolBarCurrentColor, "-", "*" )
buffer.draw()
volume(-1)
os.sleep(0.2)
drawAll()
end
else
local action = context.menu(e[3], e[4], {"Добавить станцию", #radioStations >= countOfStationsLimit}, {"Удалить станцию", #radioStations < 2}, "-", {"О программе"}, "-", {"Выход"})
if action == "Добавить станцию" then
local data = ecs.universalWindow("auto", "auto", 36, 0x262626, true,
{"EmptyLine"},
{"CenterText", ecs.colors.orange, "Добавить станцию"},
{"EmptyLine"},
{"Input", 0xFFFFFF, ecs.colors.orange, "Название станции"},
{"Input", 0xFFFFFF, ecs.colors.orange, "URL-ссылка на стрим"},
{"EmptyLine"},
{"Button", {ecs.colors.orange, 0x262626, "OK"}, {0x999999, 0xffffff, "Отмена"}}
)
if data[3] == "OK" then
table.insert(radioStations, {name = data[1], url = data[2]})
saveStations()
drawAll()
end
elseif action == "Удалить станцию" then
table.remove(radioStations, radioStations.currentStation)
saveStations()
drawAll()
elseif action == "О программе" then
ecs.universalWindow("auto", "auto", 36, 0x262626, true,
{"EmptyLine"},
{"CenterText", ecs.colors.orange, "Radio v1.0"},
{"EmptyLine"},
{"CenterText", 0xFFFFFF, "Автор:"},
{"CenterText", 0xBBBBBB, "Тимофеев Игорь"},
{"CenterText", 0xBBBBBB, "vk.com/id7799889"},
{"EmptyLine"},
{"CenterText", 0xFFFFFF, "Тестер:"},
{"CenterText", 0xBBBBBB, "Олег Гречкин"},
{"CenterText", 0xBBBBBB, "http://vk.com/id250552893"},
{"EmptyLine"},
{"CenterText", 0xFFFFFF, "Автор идеи:"},
{"CenterText", 0xBBBBBB, "MrHerobrine с Dreamfinity"},
{"EmptyLine"},
{"Button", {ecs.colors.orange, 0xffffff, "OK"}}
)
elseif action == "Выход" then
buffer.square(1, 1, buffer.getWidth(), buffer.getHeight(), config.colors.background, 0xFFFFFF, " ")
buffer.draw()
ecs.prepareToExit()
radio.stop()
return
end
end
elseif e[1] == "scroll" then
switchStation(e[5])
drawAll()
end
end

View File

@ -0,0 +1 @@
Программа для управления радио из мода OpenFM, стилизованная под известный плеер iRiver SPINN.

View File

@ -0,0 +1,200 @@
package.loaded.rayEngine = nil
local fs = require("filesystem")
local component = require("component")
local buffer = require("doubleBuffering")
local GUI = require("GUI")
local rayEngine = require("rayEngine")
local MineOSCore = require("MineOSCore")
local unicode = require("unicode")
local event = require("event")
----------------------------------------------------------------------------------------------------------------------------------
local applicationResourcesDirectory = MineOSCore.getCurrentApplicationResourcesDirectory()
local localization = MineOSCore.getLocalization(applicationResourcesDirectory .. "Localization/")
local worldsPath = applicationResourcesDirectory .. "Worlds/"
local rayWalkVersion = "RayWalk Tech Demo v3.5"
----------------------------------------------------------------------------------------------------------------------------------
local function menuBackground()
rayEngine.drawWorld()
buffer.clear(0x000000, 0.5)
end
local function settings()
local window = GUI.fullScreenContainer()
local oldDraw = window.draw
window.draw = function()
menuBackground()
oldDraw(window)
end
local sliderWidth, textBoxWidth = 43, 19
local x, y = math.floor(window.width / 2 - sliderWidth / 2), math.floor(window.height / 2 - 19)
window:addChild(GUI.label(1, y, window.width, 1, 0xFFFFFF, localization.rayEngineProperties)):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top); y = y + 3
local resolutionTextBoxWidth = window:addChild(GUI.input(x, y, textBoxWidth, 3, 0x262626, 0xBBBBBB, 0xBBBBBB, 0x262626, 0xFFFFFF, tostring(buffer.getWidth()), nil, true))
window:addChild(GUI.label(x + textBoxWidth + 2, y + 1, 1, 1, 0xFFFFFF, "X"))
local resolutionTextBoxHeight = window:addChild(GUI.input(x + textBoxWidth + 5, y, textBoxWidth, 3, 0x262626, 0xBBBBBB, 0xBBBBBB, 0x262626, 0xFFFFFF, tostring(buffer.getHeight()), nil, true)); y = y + 4
window:addChild(GUI.label(1, y, window.width, 1, 0xDDDDDD, localization.screenResolution)):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top); y = y + 3
resolutionTextBoxWidth.validator = function(text) local num = tonumber(text); if num and num >= 40 and num <= 160 then return true end end
resolutionTextBoxHeight.validator = function(text) local num = tonumber(text); if num and num >= 12 and num <= 50 then return true end end
local function onAnyResolutionTextBoxInputFinished()
window:stopEventHandling()
rayEngine.changeResolution(tonumber(resolutionTextBoxWidth.text), tonumber(resolutionTextBoxHeight.text))
settings()
end
resolutionTextBoxWidth.onInputFinished = onAnyResolutionTextBoxInputFinished
resolutionTextBoxHeight.onInputFinished = onAnyResolutionTextBoxInputFinished
local drawDistanceSlider = window:addChild(GUI.slider(x, y, sliderWidth, 0xFFDB80, 0x000000, 0xFFDB40, 0xDDDDDD, 100, 5000, rayEngine.properties.drawDistance, true, localization.drawDistance))
drawDistanceSlider.onValueChanged = function()
rayEngine.properties.drawDistance = drawDistanceSlider.value
window:draw()
buffer.draw()
end; y = y + 4
local shadingDistanceSlider = window:addChild(GUI.slider(x, y, sliderWidth, 0xFFDB80, 0x000000, 0xFFDB40, 0xDDDDDD, 100, 3000, rayEngine.properties.shadingDistance, true, localization.shadingDistance))
shadingDistanceSlider.onValueChanged = function()
rayEngine.properties.shadingDistance = shadingDistanceSlider.value
window:draw()
buffer.draw()
end; y = y + 4
local shadingCascadesSlider = window:addChild(GUI.slider(x, y, sliderWidth, 0xFFDB80, 0x000000, 0xFFDB40, 0xDDDDDD, 2, 48, rayEngine.properties.shadingCascades, true, localization.shadingCascades))
shadingCascadesSlider.onValueChanged = function()
rayEngine.properties.shadingCascades = shadingCascadesSlider.value
window:draw()
buffer.draw()
end; y = y + 4
local raycastQualitySlider = window:addChild(GUI.slider(x, y, sliderWidth, 0xFFDB80, 0x000000, 0xFFDB40, 0xDDDDDD, 0.5, 32, rayEngine.properties.raycastQuality, true, localization.raycastQuality))
raycastQualitySlider.onValueChanged = function()
rayEngine.properties.raycastQuality = raycastQualitySlider.value
window:draw()
buffer.draw()
end; y = y + 4
local currentTimeSlider = window:addChild(GUI.slider(x, y, sliderWidth, rayEngine.world.colors.sky.current, 0x000000, rayEngine.world.colors.sky.current, 0xDDDDDD, 0, rayEngine.world.dayNightCycle.length, rayEngine.world.dayNightCycle.currentTime, true, localization.dayNightCycle, localization.seconds))
currentTimeSlider.onValueChanged = function()
rayEngine.world.dayNightCycle.currentTime = currentTimeSlider.value
rayEngine.refreshTimeDependentColors()
currentTimeSlider.colors.active = rayEngine.world.colors.sky.current
currentTimeSlider.colors.pipe = rayEngine.world.colors.sky.current
window:draw()
buffer.draw()
end; y = y + 4
window:addChild(GUI.label(x, y, sliderWidth, 1, 0xDDDDDD, localization.enableSemipixelRenderer))
local graphonSwitch = window:addChild(GUI.switch(x + sliderWidth - 8, y, 8, 0xFFDB40, 0xAAAAAA, 0xFFFFFF, not rayEngine.properties.useSimpleRenderer))
graphonSwitch.onStateChanged = function()
rayEngine.properties.useSimpleRenderer = not graphonSwitch.state
window:draw()
buffer.draw()
end; y = y + 3
window:addChild(GUI.label(x, y, sliderWidth, 1, 0xDDDDDD, localization.enableDayNightCycle))
local lockTimeSwitch = window:addChild(GUI.switch(x + sliderWidth - 8, y, 8, 0xFFDB40, 0xAAAAAA, 0xFFFFFF, rayEngine.world.dayNightCycle.enabled))
lockTimeSwitch.onStateChanged = function()
rayEngine.world.dayNightCycle.enabled = lockTimeSwitch.state
window:draw()
buffer.draw()
end; y = y + 3
window:addChild(GUI.button(x, y, sliderWidth, 3, 0xEEEEEE, 0x262626, 0xBBBBBB, 0x262626, localization.continue)).onTouch = function() window:stopEventHandling(); table.toFile(applicationResourcesDirectory .. "RayEngine.cfg", rayEngine.properties, true) end
window:draw(); buffer.draw(); window:startEventHandling()
end
local function menu()
local window = GUI.fullScreenContainer()
local oldDraw = window.draw
window.draw = function()
menuBackground()
oldDraw(window)
end
local buttonWidth, buttonHeight = 50, 3
local worlds = {}
for file in fs.list(worldsPath) do table.insert(worlds, unicode.sub(file, 1, -2)) end
local x, y = math.floor(window.width / 2 - buttonWidth / 2), math.floor(window.height / 2 - #worlds * (buttonHeight + 1) / 2 - 11)
window:addChild(GUI.label(1, y, window.width, 1, 0xFFFFFF, rayWalkVersion)):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top); y = y + 3
window:addChild(GUI.button(x, y, buttonWidth, buttonHeight, 0xEEEEEE, 0x262626, 0xBBBBBB, 0x262626, localization.continue)).onTouch = function() window:stopEventHandling() end; y = y + buttonHeight + 1
window:addChild(GUI.button(x, y, buttonWidth, buttonHeight, 0xEEEEEE, 0x262626, 0xBBBBBB, 0x262626, localization.settings)).onTouch = function() window:stopEventHandling(); settings() end; y = y + buttonHeight + 1
window:addChild(GUI.button(x, y, buttonWidth, buttonHeight, 0xEEEEEE, 0x262626, 0x999999, 0x262626, localization.exit)).onTouch = function() buffer.clear(0x000000); buffer.draw(); os.exit() end; y = y + buttonHeight + 1
window:addChild(GUI.label(1, y, window.width, 1, 0xFFFFFF, localization.loadWorld)):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top); y = y + 2
for i = 1, #worlds do
window:addChild(GUI.button(x, y, buttonWidth, buttonHeight, 0xEEEEEE, 0x262626, 0xBBBBBB, 0x262626, worlds[i])).onTouch = function() rayEngine.loadWorld(worldsPath .. worlds[i]); window:stopEventHandling() end
y = y + buttonHeight + 1
end
local lines = {}; for i = 1, #localization.controlsHelp do table.insert(lines, localization.controlsHelp[i]) end
table.insert(lines, 1, " ")
table.insert(lines, 1, {text = localization.controls, color = 0xFFFFFF})
window:addChild(GUI.textBox(1, y, window.width, #lines, nil, 0xCCCCCC, lines, 1):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top)); y = y + #lines + 1
window:draw(); buffer.draw(); window:startEventHandling()
end
----------------------------------------------------------------------------------------------------------------------------------
local controls = {
["key_down"] = {
[16] = rayEngine.turnLeft, --q
[18] = rayEngine.turnRight, --e
[30] = rayEngine.moveLeft, --a
[32] = rayEngine.moveRight, --d
[17] = rayEngine.moveForward, --w
[31] = rayEngine.moveBackward, --s
[50] = rayEngine.toggleMinimap, --m
[37] = rayEngine.toggleCompass, --k
[25] = rayEngine.toggleWatch, --p
[14] = menu, --backspace
[28] = rayEngine.commandLine, --enter
[57] = rayEngine.jump, --space
[29] = rayEngine.crouch, --ctrl
[59] = rayEngine.toggleDebugInformation, -- F1
},
["key_up"] = {
[29] = rayEngine.crouch, --ctrl
},
}
--------------------------------------------------------------------------------------------------------------
rayEngine.loadEngineProperties(applicationResourcesDirectory .. "RayEngine.cfg")
rayEngine.loadWeapons(applicationResourcesDirectory .. "Weapons/")
rayEngine.loadWorld(worldsPath .. "ExampleWorld")
rayEngine.changeResolution(rayEngine.properties.screenResolution.width, rayEngine.properties.screenResolution.height)
-- rayEngine.intro()
menu()
rayEngine.update()
while true do
local e = { event.pull(1) }
if e[1] == "touch" then
if e[5] == 1 then
if not rayEngine.currentWeapon then rayEngine.place(3, 0x3) end
else
if rayEngine.currentWeapon then rayEngine.fire() else rayEngine.destroy(3) end
end
elseif e[1] == "key_down" then
if e[4] > 1 and e[4] < 10 then
rayEngine.changeWeapon(e[4] - 2)
else
if controls[e[1]] and controls[e[1]][e[4]] then controls[e[1]][e[4]]() end
end
elseif e[1] == "key_up" then
if controls[e[1]] and controls[e[1]][e[4]] then controls[e[1]][e[4]]() end
end
rayEngine.update()
end

Some files were not shown because too many files have changed in this diff Show More