mirror of
https://github.com/IgorTimofeev/MineOS.git
synced 2026-01-07 19:52:40 +01:00
Бекап
This commit is contained in:
parent
4ac241bc3e
commit
bdc80516c0
1
640cd89f-8e29-4b66-a0eb-7680c33760b4/.prop
Executable file
1
640cd89f-8e29-4b66-a0eb-7680c33760b4/.prop
Executable file
@ -0,0 +1 @@
|
||||
{label = "OpenOS", reboot=true, setlabel=true, setboot=true}
|
||||
BIN
640cd89f-8e29-4b66-a0eb-7680c33760b4/1.pic
Normal file
BIN
640cd89f-8e29-4b66-a0eb-7680c33760b4/1.pic
Normal file
Binary file not shown.
@ -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}}
|
||||
764
640cd89f-8e29-4b66-a0eb-7680c33760b4/MineOS/Applications/3DPrint.app/Main.lua
Executable file
764
640cd89f-8e29-4b66-a0eb-7680c33760b4/MineOS/Applications/3DPrint.app/Main.lua
Executable 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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1 @@
|
||||
Это профессиональный инструмент для создания и распечатки моделей на 3D-принтере. Поддерживает все возможные функции принтера без исключения. Для работы требуется сам принтер и, по желанию, голографический проектор 2 уровня.
|
||||
Binary file not shown.
539
640cd89f-8e29-4b66-a0eb-7680c33760b4/MineOS/Applications/3DTest.app/Main.lua
Executable file
539
640cd89f-8e29-4b66-a0eb-7680c33760b4/MineOS/Applications/3DTest.app/Main.lua
Executable 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)
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1 @@
|
||||
Программа-демонстратор возможностей 3D-движка, созданного специально для низкопроизводительных компьютеров. В ней воплощены практически все наработки нашей команды: от отрисовки сложных трехмерных объектов и динамического освещения до текстурирования и пользовательского интерфейса на мощной GUI-библиотеке.
|
||||
Binary file not shown.
246
640cd89f-8e29-4b66-a0eb-7680c33760b4/MineOS/Applications/AppMarket.app/Main.lua
Executable file
246
640cd89f-8e29-4b66-a0eb-7680c33760b4/MineOS/Applications/AppMarket.app/Main.lua
Executable 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()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1 @@
|
||||
Одно из главных системных приложений, позволяющее проверять наличие необходимых обновлений, а также загружать красивейшие программы, созданные специально для MineOS.
|
||||
Binary file not shown.
@ -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 ",
|
||||
}
|
||||
@ -0,0 +1,17 @@
|
||||
{
|
||||
applications = "Приложения",
|
||||
libraries = "Библиотеки",
|
||||
wallpapers = "Обои",
|
||||
other = "Другое",
|
||||
updates = "Обновления",
|
||||
checkingForUpdates = "Проверка наличия обновлений",
|
||||
version = "Версия: ",
|
||||
updateAll = "Обновить все",
|
||||
download = "Загрузить",
|
||||
downloading = "Загрузка",
|
||||
downloaded = "Установлено",
|
||||
search = "Поиск",
|
||||
page = "Страница ",
|
||||
youHaveNewestApps = "У вас самое новое ПО",
|
||||
updating = "Обновление ",
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
339
640cd89f-8e29-4b66-a0eb-7680c33760b4/MineOS/Applications/Battleship.app/Main.lua
Executable file
339
640cd89f-8e29-4b66-a0eb-7680c33760b4/MineOS/Applications/Battleship.app/Main.lua
Executable 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())
|
||||
@ -0,0 +1 @@
|
||||
Популярная игра "Морской бой", написанная товарищем Nezn с форума ComputerCraft.ru. Рассчитана на одного игрока, вам предстоит захватывающее сражение с флотом противника, контролируемым ИИ на Lua.
|
||||
Binary file not shown.
160
640cd89f-8e29-4b66-a0eb-7680c33760b4/MineOS/Applications/BufferDemo.app/Main.lua
Executable file
160
640cd89f-8e29-4b66-a0eb-7680c33760b4/MineOS/Applications/BufferDemo.app/Main.lua
Executable 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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1 @@
|
||||
Программа-демонстратор возможностей нашей библиотеки двойной буферизации изображения. Вся ОС работает именно на этой библиотеке.
|
||||
Binary file not shown.
Binary file not shown.
379
640cd89f-8e29-4b66-a0eb-7680c33760b4/MineOS/Applications/Calendar.app/Main.lua
Executable file
379
640cd89f-8e29-4b66-a0eb-7680c33760b4/MineOS/Applications/Calendar.app/Main.lua
Executable 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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1 @@
|
||||
Calendar - простая программа, не нуждающаяся в особом представлении. Красивый интерфейс позволяет легко узнать день недели конкретной даты любого года.
|
||||
Binary file not shown.
229
640cd89f-8e29-4b66-a0eb-7680c33760b4/MineOS/Applications/Camera.app/Main.lua
Executable file
229
640cd89f-8e29-4b66-a0eb-7680c33760b4/MineOS/Applications/Camera.app/Main.lua
Executable 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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1 @@
|
||||
Программа-рейкастер, делающая снимки местности с помощью камеры из мода Computronix. Разумеется, данный мод должен быть установлен для работы.
|
||||
Binary file not shown.
@ -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
|
||||
@ -0,0 +1 @@
|
||||
Красивая новогодняя программа, написанная разработчиком Doob, сотворяющая атмосферу праздника в любом месте, где бы вы ни находились.
|
||||
Binary file not shown.
276
640cd89f-8e29-4b66-a0eb-7680c33760b4/MineOS/Applications/CodeDoor.app/Main.lua
Executable file
276
640cd89f-8e29-4b66-a0eb-7680c33760b4/MineOS/Applications/CodeDoor.app/Main.lua
Executable 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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1 @@
|
||||
Программа для защиты вашего жилища от нежелательных гостей. При старте вы указываете желаемый пароль, а как только вы или ваш друг его корректно ввели, система автоматически вносит вас в список доверенных пользователей, так что вы сможете пользоваться биометрической защитой, не тратя время на ввод пароля. Крайне красивая и полезная программа.
|
||||
Binary file not shown.
@ -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)
|
||||
|
||||
|
||||
Binary file not shown.
@ -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"
|
||||
}
|
||||
@ -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 = "Введите выражение здесь"
|
||||
}
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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)
|
||||
|
||||
@ -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"}}
|
||||
Binary file not shown.
294
640cd89f-8e29-4b66-a0eb-7680c33760b4/MineOS/Applications/FlappyBird.app/Main.lua
Executable file
294
640cd89f-8e29-4b66-a0eb-7680c33760b4/MineOS/Applications/FlappyBird.app/Main.lua
Executable 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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1 @@
|
||||
Популярная игра теперь прямо в вашем компьютере в Minecraft! Наслаждайтесь невероятной графикой и баттхертами от частых смертей.
|
||||
Binary file not shown.
Binary file not shown.
@ -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()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1 @@
|
||||
Данная программа предназначена для игроков, которым каким-то образом попал в руки командный блок. Если это произошло - подключайте его через адаптер к компьютеру, запускайте программу и наслаждайтесь полными привилегиями администратора. Работает только на серверах с плагином PermissionsEx и включенной поддержкой командных блоков в конфиге мода.
|
||||
Binary file not shown.
@ -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()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1 @@
|
||||
Простой мультипоточный скрипт, которую я написал по большей части для себя: дождь в одинойчной игре заебал меня настолько, насколько это вообще возможно. Для работы программе требуется дебаг-карта.
|
||||
Binary file not shown.
220
640cd89f-8e29-4b66-a0eb-7680c33760b4/MineOS/Applications/GeoScan2.app/Main.lua
Executable file
220
640cd89f-8e29-4b66-a0eb-7680c33760b4/MineOS/Applications/GeoScan2.app/Main.lua
Executable 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()
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@ -0,0 +1 @@
|
||||
{["Resources"]={["x"]=17,["y"]=2},["Main.lua"]={["x"]=3,["y"]=2}}
|
||||
588
640cd89f-8e29-4b66-a0eb-7680c33760b4/MineOS/Applications/GuessWord.app/Main.lua
Executable file
588
640cd89f-8e29-4b66-a0eb-7680c33760b4/MineOS/Applications/GuessWord.app/Main.lua
Executable 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()
|
||||
@ -0,0 +1 @@
|
||||
Мини-игра "Угадай Слова" от автора Newbie с форума ComputerCraft.ru. Игра на данный момент имеет базу из 300 вопросов, в процессе вам случайным образом подбирается слово, появляется экран, где есть ячейки, за которыми спрятаны буквы. Над ними находится вопрос-подсказка. Вы угадываете буквы путем нажатия на экранной клавиатуре на букву - если буква угадана, то кнопка примет зеленый цвет, если нет - красный. Также угаданная буква помещается сразу в свою ячейку. Если одинаковых букв в слове больше одной, то они также откроются в своих ячейках. Удачного мозголомства!
|
||||
Binary file not shown.
380
640cd89f-8e29-4b66-a0eb-7680c33760b4/MineOS/Applications/HEX.app/Main.lua
Executable file
380
640cd89f-8e29-4b66-a0eb-7680c33760b4/MineOS/Applications/HEX.app/Main.lua
Executable 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()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1 @@
|
||||
HEX - мощный редактор файлов в шестнадцатеричном режиме. Он позволяет индивидуально редактировать байты, удалять их, инвертировать, вставлять новые. Незаменимая вещь для тру прогеров!
|
||||
Binary file not shown.
248
640cd89f-8e29-4b66-a0eb-7680c33760b4/MineOS/Applications/HoloClock.app/Main.lua
Executable file
248
640cd89f-8e29-4b66-a0eb-7680c33760b4/MineOS/Applications/HoloClock.app/Main.lua
Executable 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
|
||||
|
||||
|
||||
|
||||
|
||||
Binary file not shown.
785
640cd89f-8e29-4b66-a0eb-7680c33760b4/MineOS/Applications/HoloEdit.app/Main.lua
Executable file
785
640cd89f-8e29-4b66-a0eb-7680c33760b4/MineOS/Applications/HoloEdit.app/Main.lua
Executable 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)
|
||||
Binary file not shown.
@ -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:",
|
||||
}
|
||||
@ -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 = "Введите сюда имя файла",
|
||||
}
|
||||
186
640cd89f-8e29-4b66-a0eb-7680c33760b4/MineOS/Applications/InfoPanel.app/Main.lua
Executable file
186
640cd89f-8e29-4b66-a0eb-7680c33760b4/MineOS/Applications/InfoPanel.app/Main.lua
Executable 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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1 @@
|
||||
Эта программа предназначена для визуального отображения информации для пользователей компьютера, она идеально впишется в ваш спавн, дом или милитаризированный бункер. Файлы с информацией хранятся в папке MineOS/System/InfoPanel, вы можете изменить их в любое время.
|
||||
Binary file not shown.
@ -0,0 +1,15 @@
|
||||
Приват
|
||||
|
||||
Для привата и защиты от гриферства используется классический плагин
|
||||
WorldGuard в совокупности с аддоном MachineGuard.
|
||||
|
||||
● Приват осуществляется деревянным топором, проверка привата кожей.
|
||||
● Количество блоков, доступное пользователю для привата: 700 000.
|
||||
● Максимальное количество приватов на пользователя: 1.
|
||||
● Приват сундуков, механизмов IC2, компьютеров и прочего создается
|
||||
автоматически.
|
||||
● Если вам мешает графическая подсветка выделения, используйте
|
||||
команду //sel, чтобы убрать ее.
|
||||
● Роботы не могут ломать блоки в привате, однако могут снимать
|
||||
гаечным ключом механизмы IC2. Будьте внимательны и защищайте жилье
|
||||
тщательно!
|
||||
@ -0,0 +1,21 @@
|
||||
Главная
|
||||
|
||||
Добро пожаловать на индустриальный сервер <color>0xFFAA00</color>Buttex<color>0xFFFFFF</color>! С помощью этой панели
|
||||
вы всегда можете узнать последние новости сервера и ознакомиться с
|
||||
основными устоями, сложившимися в нашем обществе. Новичкам рекомендуется
|
||||
прочитать все имеющиеся вкладки.
|
||||
|
||||
История сервера
|
||||
|
||||
Buttex существует с незапамятного 2010 года, когда кубач еще только
|
||||
набирал свою популярность. Основным направлением сервера всегда были
|
||||
красивые постройки, редстоун-схемы, а с недавних пор еще и кодинг
|
||||
на компьютерах, предоставляемых модами. На сервере всегда царила
|
||||
дружеская и домашняя атмосфера, которую мы поддерживаем из года в год.
|
||||
Иногда, когда нашей теплой компании надоедало играть в кубики, мы
|
||||
делали перерыв, но в скором времени сервер возрождался раз за разом.
|
||||
Сейчас на дворе ноябрь, 2015 год, и мы вновь открываем Buttex для всех
|
||||
желающих в новом формате - с собственным лаунчером, интересными модами
|
||||
и грамотно настроенными плагинами.
|
||||
|
||||
Приятной игры, дорогие мои!
|
||||
@ -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>, где каждый сам себе хозяин!
|
||||
@ -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> - управление освещение спавна.
|
||||
|
||||
Кроме того, ключевое слово "Сервер" имеет несколько синонимов
|
||||
для удобства: серв, сервак, ССПИ, а также все эти вариации,
|
||||
написанные с заглавной буквы.
|
||||
1855
640cd89f-8e29-4b66-a0eb-7680c33760b4/MineOS/Applications/MineCode IDE.app/Main.lua
Executable file
1855
640cd89f-8e29-4b66-a0eb-7680c33760b4/MineOS/Applications/MineCode IDE.app/Main.lua
Executable file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1 @@
|
||||
MineCode IDE - это мощный инстурмент для разработки приложений с богатым функционалом: от подсветки синтаксиса Lua, выделения текста и работы с буфером обмена до поддержки пользовательских цветовых схем. Удобный файловый менеджер также прилагается.
|
||||
Binary file not shown.
@ -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",
|
||||
}
|
||||
@ -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 = "Детабулировать",
|
||||
}
|
||||
@ -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
|
||||
Binary file not shown.
1381
640cd89f-8e29-4b66-a0eb-7680c33760b4/MineOS/Applications/Photoshop.app/Main.lua
Executable file
1381
640cd89f-8e29-4b66-a0eb-7680c33760b4/MineOS/Applications/Photoshop.app/Main.lua
Executable file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1 @@
|
||||
Photoshop - это мощный графический редактор, написанный специально для работы с нашей ОС. Он поддерживает работу с кистями, прозрачностью, имеет функции заливки, выбора цвета из красочной палитры, позволяет создавать настоящие мини-шедевры прямо на вашем ПК. Вся графика в нашей ОС нарисована именно в этой программе.
|
||||
Binary file not shown.
@ -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:",
|
||||
}
|
||||
@ -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 = "Тестеры:",
|
||||
}
|
||||
330
640cd89f-8e29-4b66-a0eb-7680c33760b4/MineOS/Applications/PrintImage.app/Main.lua
Executable file
330
640cd89f-8e29-4b66-a0eb-7680c33760b4/MineOS/Applications/PrintImage.app/Main.lua
Executable 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()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Binary file not shown.
@ -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()
|
||||
-------------------------------------------------------------------------------------
|
||||
@ -0,0 +1 @@
|
||||
Это мини-игра, разработанная товарищем qwertyMan с форума ComputerCraft.ru. А я ее нагло спиздил. Цель игры: вы должны понять, как устроен "квантовый куб", решить задачу (найти цепочку выходов) к комнате номер 1 и выбраться из квантового лабиринта. А на деле рандомно бегать в поисках комнаты номер 1, не понимать как устроена система нумераций, ловить баттхёрты и проклинать всех, кого только можно. Потому что если даже соседняя комната и окажется под номером 1, то вы можете запросто пробежать и даже не заглянуть в неё. Так как мы видим лишь те комнаты, на границе с которыми стоим.
|
||||
Binary file not shown.
314
640cd89f-8e29-4b66-a0eb-7680c33760b4/MineOS/Applications/Radio.app/Main.lua
Executable file
314
640cd89f-8e29-4b66-a0eb-7680c33760b4/MineOS/Applications/Radio.app/Main.lua
Executable 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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1 @@
|
||||
Программа для управления радио из мода OpenFM, стилизованная под известный плеер iRiver SPINN.
|
||||
Binary file not shown.
200
640cd89f-8e29-4b66-a0eb-7680c33760b4/MineOS/Applications/RayWalk.app/Main.lua
Executable file
200
640cd89f-8e29-4b66-a0eb-7680c33760b4/MineOS/Applications/RayWalk.app/Main.lua
Executable 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
Loading…
x
Reference in New Issue
Block a user