Merge branch 'MihailRis:main' into main
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"texture": "bazalt",
|
||||
"breakable": false
|
||||
"breakable": false,
|
||||
"base:durability": 1e9
|
||||
}
|
||||
|
||||
@@ -9,5 +9,6 @@
|
||||
"grounded": true,
|
||||
"model": "X",
|
||||
"hitbox": [0.15, 0.0, 0.15, 0.7, 0.7, 0.7],
|
||||
"base:durability": 0.0
|
||||
"base:durability": 0.0,
|
||||
"base:loot": []
|
||||
}
|
||||
|
||||
@@ -8,5 +8,8 @@
|
||||
"grass_side",
|
||||
"grass_side"
|
||||
],
|
||||
"base:durability": 1.3
|
||||
"base:durability": 1.3,
|
||||
"base:loot": [
|
||||
{"item": "base:dirt.item"}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
"base:durability" = {}
|
||||
"base:loot" = {}
|
||||
|
||||
@@ -11,4 +11,34 @@ function util.drop(ppos, itemid, count, pickup_delay)
|
||||
}})
|
||||
end
|
||||
|
||||
local function calc_loot(loot_table)
|
||||
local results = {}
|
||||
for _, loot in ipairs(loot_table) do
|
||||
local chance = loot.chance or 1
|
||||
local count = loot.count or 1
|
||||
|
||||
local roll = math.random()
|
||||
|
||||
if roll < chance then
|
||||
if loot.min and loot.max then
|
||||
count = math.random(loot.min, loot.max)
|
||||
end
|
||||
if count == 0 then
|
||||
goto continue
|
||||
end
|
||||
table.insert(results, {item=item.index(loot.item), count=count})
|
||||
end
|
||||
::continue::
|
||||
end
|
||||
return results
|
||||
end
|
||||
|
||||
function util.block_loot(blockid)
|
||||
local lootscheme = block.properties[blockid]["base:loot"]
|
||||
if lootscheme then
|
||||
return calc_loot(lootscheme)
|
||||
end
|
||||
return {{item=block.get_picking_item(blockid), count=1}}
|
||||
end
|
||||
|
||||
return util
|
||||
|
||||
@@ -3,17 +3,32 @@ local body = entity.rigidbody
|
||||
local rig = entity.skeleton
|
||||
|
||||
local blockid = ARGS.block
|
||||
local blockstates = ARGS.states or 0
|
||||
if SAVED_DATA.block then
|
||||
blockid = SAVED_DATA.block
|
||||
blockstates = SAVED_DATA.states or 0
|
||||
else
|
||||
SAVED_DATA.block = blockid
|
||||
SAVED_DATA.states = blockstates
|
||||
end
|
||||
|
||||
do -- setup visuals
|
||||
local textures = block.get_textures(block.index(blockid))
|
||||
local id = block.index(blockid)
|
||||
local rotation = block.decompose_state(blockstates)[1]
|
||||
local textures = block.get_textures(id)
|
||||
for i,t in ipairs(textures) do
|
||||
rig:set_texture("$"..tostring(i-1), "blocks:"..textures[i])
|
||||
end
|
||||
local axisX = {block.get_X(id, rotation)}
|
||||
local axisY = {block.get_Y(id, rotation)}
|
||||
local axisZ = {block.get_Z(id, rotation)}
|
||||
local matrix = {
|
||||
axisX[1], axisX[2], axisX[3], 0,
|
||||
axisY[1], axisY[2], axisY[3], 0,
|
||||
axisZ[1], axisZ[2], axisZ[3], 0,
|
||||
0, 0, 0, 1
|
||||
}
|
||||
rig:set_matrix(0, matrix)
|
||||
end
|
||||
|
||||
function on_grounded()
|
||||
@@ -22,7 +37,7 @@ function on_grounded()
|
||||
local iy = math.floor(pos[2])
|
||||
local iz = math.floor(pos[3])
|
||||
if block.is_replaceable_at(ix, iy, iz) then
|
||||
block.place(ix, iy, iz, block.index(blockid), 0)
|
||||
block.place(ix, iy, iz, block.index(blockid), blockstates)
|
||||
else
|
||||
local picking_item = block.get_picking_item(block.index(blockid))
|
||||
local drop = entities.spawn("base:drop", pos, {base__drop={id=picking_item, count=1}})
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
function on_block_broken(id, x, y, z, playerid)
|
||||
gfx.particles.emit({x+0.5, y+0.5, z+0.5}, 64, {
|
||||
lifetime=1.0,
|
||||
spawn_interval=0.0001,
|
||||
explosion={4, 4, 4},
|
||||
texture="blocks:"..block.get_textures(id)[1],
|
||||
random_sub_uv=0.1,
|
||||
size={0.1, 0.1, 0.1},
|
||||
spawn_shape="box",
|
||||
spawn_spread={0.4, 0.4, 0.4}
|
||||
})
|
||||
if gfx then
|
||||
gfx.particles.emit({x+0.5, y+0.5, z+0.5}, 64, {
|
||||
lifetime=1.0,
|
||||
spawn_interval=0.0001,
|
||||
explosion={4, 4, 4},
|
||||
texture="blocks:"..block.get_textures(id)[1],
|
||||
random_sub_uv=0.1,
|
||||
size={0.1, 0.1, 0.1},
|
||||
spawn_shape="box",
|
||||
spawn_spread={0.4, 0.4, 0.4}
|
||||
})
|
||||
end
|
||||
|
||||
rules.create("do-loot-non-player", true)
|
||||
end
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
bazalt breaker=bazalt sindiruvchi
|
||||
bazalt=bazalt
|
||||
blue lamp=ko‘k lampa
|
||||
brick=g'isht
|
||||
dirt=yer
|
||||
flower=gul
|
||||
glass=shisha
|
||||
grass block=o'tli blok
|
||||
green lamp=yashil lampa
|
||||
ice=muz
|
||||
lamp=lampa
|
||||
leaves=barglar
|
||||
light bulb=chiroq
|
||||
metal=metal
|
||||
pane=panel
|
||||
pipe=quvur
|
||||
planks=yog'och
|
||||
red lamp=qizil lampa
|
||||
rust=zang
|
||||
sand=qum
|
||||
stone=tosh
|
||||
tall grass=Baland o't
|
||||
torch=fakel
|
||||
water=suv
|
||||
wood=yog'och
|
||||
wooden door=yog'och eshik
|
||||
@@ -185,8 +185,14 @@ function refresh()
|
||||
end
|
||||
end
|
||||
|
||||
local packids = {unpack(packs_installed)}
|
||||
for i,k in ipairs(packs_available) do
|
||||
table.insert(packids, k)
|
||||
end
|
||||
local packinfos = pack.get_info(packids)
|
||||
|
||||
for i,id in ipairs(packs_installed) do
|
||||
local packinfo = pack.get_info(id)
|
||||
local packinfo = packinfos[id]
|
||||
packinfo.index = i
|
||||
callback = not table.has(base_packs, id) and string.format('move_pack("%s")', id) or nil
|
||||
packinfo.error = check_dependencies(packinfo)
|
||||
@@ -194,7 +200,7 @@ function refresh()
|
||||
end
|
||||
|
||||
for i,id in ipairs(packs_available) do
|
||||
local packinfo = pack.get_info(id)
|
||||
local packinfo = packinfos[id]
|
||||
packinfo.index = i
|
||||
callback = string.format('move_pack("%s")', id)
|
||||
packinfo.error = check_dependencies(packinfo)
|
||||
|
||||
@@ -247,8 +247,9 @@ function refresh()
|
||||
local contents = document.contents
|
||||
contents:clear()
|
||||
|
||||
local packinfos = pack.get_info(packs_installed)
|
||||
for i, id in ipairs(packs_installed) do
|
||||
local packinfo = pack.get_info(id)
|
||||
local packinfo = packinfos[id]
|
||||
|
||||
packinfo.id = id
|
||||
packs_installed[i] = {packinfo.id, packinfo.title}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<panel size='400' color='0' interval='1' context='menu'>
|
||||
<button onclick='menu.page="worlds"'>@Worlds</button>
|
||||
<button onclick='menu.page="scripts"'>@Scripts</button>
|
||||
<button onclick='menu.page="settings"'>@Settings</button>
|
||||
<button onclick='menu.page="content_menu"'>@Contents Menu</button>
|
||||
<button onclick='core.quit()'>@Quit</button>
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
<panel size='400' color='#00000030' context='menu'>
|
||||
<container size='400,32'>
|
||||
<label pos='2,10'>@Scripts</label>
|
||||
<image onclick='refresh()' interactive='true' src='gui/refresh'
|
||||
size='32' gravity='top-right'
|
||||
color='#FFFFFF80' hover-color='#FFFFFF10'/>
|
||||
</container>
|
||||
<panel id="list" size='400' interval='1' color='0' max-length='300'>
|
||||
<!-- content is generated in script -->
|
||||
</panel>
|
||||
<button onclick='menu:back()'>@Back</button>
|
||||
</panel>
|
||||
@@ -0,0 +1,40 @@
|
||||
function run_script(path)
|
||||
debug.log("starting application script "..path)
|
||||
|
||||
local code = file.read(path)
|
||||
local chunk, err = loadstring(code, path)
|
||||
if chunk == nil then
|
||||
error(err)
|
||||
end
|
||||
setfenv(chunk, setmetatable({app=__vc_app}, {__index=_G}))
|
||||
start_coroutine(chunk, path)
|
||||
end
|
||||
|
||||
function refresh()
|
||||
document.list:clear()
|
||||
|
||||
local available = pack.get_available()
|
||||
local infos = pack.get_info(available)
|
||||
for _, name in ipairs(available) do
|
||||
local info = infos[name]
|
||||
local scripts_dir = info.path.."/scripts/app"
|
||||
if not file.exists(scripts_dir) then
|
||||
goto continue
|
||||
end
|
||||
local files = file.list(scripts_dir)
|
||||
for _, filename in ipairs(files) do
|
||||
if file.ext(filename) == "lua" then
|
||||
document.list:add(gui.template("script", {
|
||||
pack=name,
|
||||
name=file.stem(filename),
|
||||
path=filename
|
||||
}))
|
||||
end
|
||||
end
|
||||
::continue::
|
||||
end
|
||||
end
|
||||
|
||||
function on_open()
|
||||
refresh()
|
||||
end
|
||||
@@ -0,0 +1,3 @@
|
||||
<button color='#10305080' hover-color='#10305040' onclick='run_script("%{path}")'>
|
||||
%{name} [%{pack}]
|
||||
</button>
|
||||
+134
-133
@@ -13,15 +13,15 @@ local MAX_INT64 = 9223372036854775807
|
||||
local MIN_INT64 = -9223372036854775808
|
||||
|
||||
local function maskHighBytes(num)
|
||||
return bit.band(num, 0xFF)
|
||||
return bit.band(num, 0xFF)
|
||||
end
|
||||
|
||||
local function reverse(tbl)
|
||||
for i=1, math.floor(#tbl / 2) do
|
||||
local tmp = tbl[i]
|
||||
tbl[i] = tbl[#tbl - i + 1]
|
||||
tbl[#tbl - i + 1] = tmp
|
||||
end
|
||||
for i=1, math.floor(#tbl / 2) do
|
||||
local tmp = tbl[i]
|
||||
tbl[i] = tbl[#tbl - i + 1]
|
||||
tbl[#tbl - i + 1] = tmp
|
||||
end
|
||||
return tbl
|
||||
end
|
||||
|
||||
@@ -29,60 +29,60 @@ local orders = { "LE", "BE" }
|
||||
|
||||
local fromLEConvertors =
|
||||
{
|
||||
LE = function(bytes) return bytes end,
|
||||
BE = function(bytes) return reverse(bytes) end
|
||||
LE = function(bytes) return bytes end,
|
||||
BE = function(bytes) return reverse(bytes) end
|
||||
}
|
||||
|
||||
local toLEConvertors =
|
||||
{
|
||||
LE = function(bytes) return bytes end,
|
||||
BE = function(bytes) return reverse(bytes) end
|
||||
LE = function(bytes) return bytes end,
|
||||
BE = function(bytes) return reverse(bytes) end
|
||||
}
|
||||
|
||||
bit_converter.default_order = "LE"
|
||||
bit_converter.default_order = "BE"
|
||||
|
||||
local function fromLE(bytes, orderTo)
|
||||
if orderTo then
|
||||
bit_converter.validate_order(orderTo)
|
||||
return fromLEConvertors[orderTo](bytes)
|
||||
else return bytes end
|
||||
if orderTo then
|
||||
bit_converter.validate_order(orderTo)
|
||||
return fromLEConvertors[orderTo](bytes)
|
||||
else return bytes end
|
||||
end
|
||||
|
||||
local function toLE(bytes, orderFrom)
|
||||
if orderFrom then
|
||||
bit_converter.validate_order(orderFrom)
|
||||
return toLEConvertors[orderFrom](bytes)
|
||||
else return bytes end
|
||||
if orderFrom then
|
||||
bit_converter.validate_order(orderFrom)
|
||||
return toLEConvertors[orderFrom](bytes)
|
||||
else return bytes end
|
||||
end
|
||||
|
||||
function bit_converter.validate_order(order)
|
||||
if not bit_converter.is_valid_order(order) then
|
||||
error("invalid order: "..order)
|
||||
end
|
||||
if not bit_converter.is_valid_order(order) then
|
||||
error("invalid order: "..order)
|
||||
end
|
||||
end
|
||||
|
||||
function bit_converter.is_valid_order(order) return table.has(orders, order) end
|
||||
|
||||
function bit_converter.string_to_bytes(str)
|
||||
local bytes = { }
|
||||
local bytes = { }
|
||||
|
||||
local len = string.len(str)
|
||||
local len = string.len(str)
|
||||
|
||||
local lenBytes = bit_converter.uint16_to_bytes(len)
|
||||
local lenBytes = bit_converter.uint16_to_bytes(len)
|
||||
|
||||
for i = 1, #lenBytes do
|
||||
bytes[i] = lenBytes[i]
|
||||
end
|
||||
for i = 1, #lenBytes do
|
||||
bytes[i] = lenBytes[i]
|
||||
end
|
||||
|
||||
for i = 1, len do
|
||||
bytes[#bytes + 1] = string.byte(string.sub(str, i, i))
|
||||
end
|
||||
for i = 1, len do
|
||||
bytes[#bytes + 1] = string.byte(string.sub(str, i, i))
|
||||
end
|
||||
|
||||
return bytes
|
||||
return bytes
|
||||
end
|
||||
|
||||
function bit_converter.bool_to_byte(bool)
|
||||
return bool and 1 or 0
|
||||
return bool and 1 or 0
|
||||
end
|
||||
|
||||
-- Credits to Iryont <https://github.com/iryont/lua-struct>
|
||||
@@ -151,177 +151,178 @@ end
|
||||
--
|
||||
|
||||
function bit_converter.float32_to_bytes(float, order)
|
||||
return fromLE(floatOrDoubleToBytes(float, 'f'), order)
|
||||
return fromLE(floatOrDoubleToBytes(float, 'f'), order)
|
||||
end
|
||||
|
||||
function bit_converter.float64_to_bytes(float, order)
|
||||
return fromLE(floatOrDoubleToBytes(float, 'd'), order)
|
||||
return fromLE(floatOrDoubleToBytes(float, 'd'), order)
|
||||
end
|
||||
|
||||
function bit_converter.single_to_bytes(float, order)
|
||||
on_deprecated_call("bit_converter.float_to_bytes", "bit_converter.float32_to_bytes")
|
||||
return bit_converter.float32_to_bytes(bytes, order)
|
||||
on_deprecated_call("bit_converter.float_to_bytes", "bit_converter.float32_to_bytes")
|
||||
return bit_converter.float32_to_bytes(bytes, order)
|
||||
end
|
||||
|
||||
function bit_converter.double_to_bytes(double, order)
|
||||
on_deprecated_call("bit_converter.double_to_bytes", "bit_converter.float64_to_bytes")
|
||||
return bit_converter.float64_to_bytes(bytes, order)
|
||||
on_deprecated_call("bit_converter.double_to_bytes", "bit_converter.float64_to_bytes")
|
||||
return bit_converter.float64_to_bytes(bytes, order)
|
||||
end
|
||||
|
||||
local function uint32ToBytes(int, order)
|
||||
return fromLE({
|
||||
maskHighBytes(bit.rshift(int, 24)),
|
||||
maskHighBytes(bit.rshift(int, 16)),
|
||||
maskHighBytes(bit.rshift(int, 8)),
|
||||
maskHighBytes(int)
|
||||
}, order)
|
||||
return fromLE({
|
||||
maskHighBytes(int),
|
||||
maskHighBytes(bit.rshift(int, 8)),
|
||||
maskHighBytes(bit.rshift(int, 16)),
|
||||
maskHighBytes(bit.rshift(int, 24))
|
||||
}, order)
|
||||
end
|
||||
|
||||
local function uint16ToBytes(int, order)
|
||||
return fromLE({
|
||||
maskHighBytes(bit.rshift(int, 8)),
|
||||
maskHighBytes(int)
|
||||
}, order)
|
||||
return fromLE({
|
||||
maskHighBytes(int),
|
||||
maskHighBytes(bit.rshift(int, 8))
|
||||
}, order)
|
||||
end
|
||||
|
||||
function bit_converter.uint32_to_bytes(int, order)
|
||||
if int > MAX_UINT32 or int < MIN_UINT32 then
|
||||
error("invalid uint32")
|
||||
end
|
||||
if int > MAX_UINT32 or int < MIN_UINT32 then
|
||||
error("invalid uint32")
|
||||
end
|
||||
|
||||
return uint32ToBytes(int, order)
|
||||
return uint32ToBytes(int, order)
|
||||
end
|
||||
|
||||
function bit_converter.uint16_to_bytes(int, order)
|
||||
if int > MAX_UINT16 or int < MIN_UINT16 then
|
||||
error("invalid uint16")
|
||||
end
|
||||
if int > MAX_UINT16 or int < MIN_UINT16 then
|
||||
error("invalid uint16")
|
||||
end
|
||||
|
||||
return uint16ToBytes(int, order)
|
||||
return uint16ToBytes(int, order)
|
||||
end
|
||||
|
||||
function bit_converter.int64_to_bytes(int, order)
|
||||
if int > MAX_INT64 or int < MIN_INT64 then
|
||||
error("invalid int64")
|
||||
end
|
||||
if int > MAX_INT64 or int < MIN_INT64 then
|
||||
error("invalid int64")
|
||||
end
|
||||
|
||||
return fromLE({
|
||||
maskHighBytes(bit.rshift(int, 56)),
|
||||
maskHighBytes(bit.rshift(int, 48)),
|
||||
maskHighBytes(bit.rshift(int, 40)),
|
||||
maskHighBytes(bit.rshift(int, 32)),
|
||||
maskHighBytes(bit.rshift(int, 24)),
|
||||
maskHighBytes(bit.rshift(int, 16)),
|
||||
maskHighBytes(bit.rshift(int, 8)),
|
||||
maskHighBytes(int)
|
||||
}, order)
|
||||
return fromLE({
|
||||
maskHighBytes(int),
|
||||
maskHighBytes(bit.rshift(int, 8)),
|
||||
maskHighBytes(bit.rshift(int, 16)),
|
||||
maskHighBytes(bit.rshift(int, 24)),
|
||||
maskHighBytes(bit.rshift(int, 32)),
|
||||
maskHighBytes(bit.rshift(int, 40)),
|
||||
maskHighBytes(bit.rshift(int, 48)),
|
||||
maskHighBytes(bit.rshift(int, 56))
|
||||
}, order)
|
||||
end
|
||||
|
||||
function bit_converter.int32_to_bytes(int, order)
|
||||
on_deprecated_call("bit_converter.int32_to_bytes", "bit_converter.sint32_to_bytes")
|
||||
on_deprecated_call("bit_converter.int32_to_bytes", "bit_converter.sint32_to_bytes")
|
||||
|
||||
if int > MAX_INT32 or int < MIN_INT32 then
|
||||
error("invalid int32")
|
||||
end
|
||||
if int > MAX_INT32 or int < MIN_INT32 then
|
||||
error("invalid int32")
|
||||
end
|
||||
|
||||
return uint32ToBytes(int + MAX_INT32, order)
|
||||
return uint32ToBytes(int + MAX_INT32, order)
|
||||
end
|
||||
|
||||
function bit_converter.int16_to_bytes(int, order)
|
||||
on_deprecated_call("bit_converter.int32_to_bytes", "bit_converter.sint16_to_bytes")
|
||||
on_deprecated_call("bit_converter.int32_to_bytes", "bit_converter.sint16_to_bytes")
|
||||
|
||||
if int > MAX_INT16 or int < MIN_INT16 then
|
||||
error("invalid int16")
|
||||
end
|
||||
if int > MAX_INT16 or int < MIN_INT16 then
|
||||
error("invalid int16")
|
||||
end
|
||||
|
||||
return uint16ToBytes(int + MAX_INT16, order)
|
||||
return uint16ToBytes(int + MAX_INT16, order)
|
||||
end
|
||||
|
||||
function bit_converter.sint32_to_bytes(int, order)
|
||||
if int > MAX_INT32 or int < MIN_INT32 then
|
||||
error("invalid sint32")
|
||||
end
|
||||
if int > MAX_INT32 or int < MIN_INT32 then
|
||||
error("invalid sint32")
|
||||
end
|
||||
|
||||
return uint32ToBytes(int + MAX_UINT32 + 1, order)
|
||||
return uint32ToBytes(int + MAX_UINT32 + 1, order)
|
||||
end
|
||||
|
||||
function bit_converter.sint16_to_bytes(int, order)
|
||||
if int > MAX_INT16 or int < MIN_INT16 then
|
||||
error("invalid sint16")
|
||||
end
|
||||
if int > MAX_INT16 or int < MIN_INT16 then
|
||||
error("invalid sint16")
|
||||
end
|
||||
|
||||
return uint16ToBytes(int + MAX_UINT16 + 1, order)
|
||||
return uint16ToBytes(int + MAX_UINT16 + 1, order)
|
||||
end
|
||||
|
||||
function bit_converter.bytes_to_float32(bytes, order)
|
||||
return bytesToFloatOrDouble(toLE(bytes, order), 'f')
|
||||
return bytesToFloatOrDouble(toLE(bytes, order), 'f')
|
||||
end
|
||||
|
||||
function bit_converter.bytes_to_float64(bytes, order)
|
||||
return bytesToFloatOrDouble(toLE(bytes, order), 'd')
|
||||
return bytesToFloatOrDouble(toLE(bytes, order), 'd')
|
||||
end
|
||||
|
||||
function bit_converter.bytes_to_single(bytes, order)
|
||||
on_deprecated_call("bit_converter.bytes_to_single", "bit_converter.bytes_to_float32")
|
||||
return bit_converter.bytes_to_float32(bytes, order)
|
||||
on_deprecated_call("bit_converter.bytes_to_single", "bit_converter.bytes_to_float32")
|
||||
return bit_converter.bytes_to_float32(bytes, order)
|
||||
end
|
||||
|
||||
function bit_converter.bytes_to_double(bytes, order)
|
||||
on_deprecated_call("bit_converter.bytes_to_double", "bit_converter.bytes_to_float64")
|
||||
return bit_converter.bytes_to_float64(bytes, order)
|
||||
on_deprecated_call("bit_converter.bytes_to_double", "bit_converter.bytes_to_float64")
|
||||
return bit_converter.bytes_to_float64(bytes, order)
|
||||
end
|
||||
|
||||
function bit_converter.bytes_to_string(bytes, order)
|
||||
local len = bit_converter.bytes_to_uint16({ bytes[1], bytes[2] })
|
||||
local len = bit_converter.bytes_to_uint16({ bytes[1], bytes[2] })
|
||||
|
||||
local str = ""
|
||||
local str = ""
|
||||
|
||||
for i = 1, len do
|
||||
str = str..string.char(bytes[i + 2])
|
||||
end
|
||||
for i = 1, len do
|
||||
str = str..string.char(bytes[i + 2])
|
||||
end
|
||||
|
||||
return str
|
||||
return str
|
||||
end
|
||||
|
||||
function bit_converter.byte_to_bool(byte)
|
||||
return byte ~= 0
|
||||
return byte ~= 0
|
||||
end
|
||||
|
||||
function bit_converter.bytes_to_uint32(bytes, order)
|
||||
if #bytes < 4 then
|
||||
error("eof")
|
||||
end
|
||||
if #bytes < 4 then
|
||||
error("eof")
|
||||
end
|
||||
|
||||
bytes = toLE(bytes, order)
|
||||
bytes = toLE(bytes, order)
|
||||
|
||||
return
|
||||
bit.bor(
|
||||
bit.bor(
|
||||
bit.bor(
|
||||
bit.lshift(bytes[1], 24),
|
||||
bit.lshift(bytes[2], 16)),
|
||||
bit.lshift(bytes[3], 8)),bytes[4])
|
||||
bytes[1],
|
||||
bit.lshift(bytes[2], 8)),
|
||||
bit.lshift(bytes[3], 16)),
|
||||
bit.lshift(bytes[4], 24))
|
||||
end
|
||||
|
||||
function bit_converter.bytes_to_uint16(bytes, order)
|
||||
if #bytes < 2 then
|
||||
error("eof")
|
||||
end
|
||||
if #bytes < 2 then
|
||||
error("eof")
|
||||
end
|
||||
|
||||
bytes = toLE(bytes, order)
|
||||
bytes = toLE(bytes, order)
|
||||
|
||||
return
|
||||
bit.bor(
|
||||
bit.lshift(bytes[1], 8),
|
||||
bytes[2], 0)
|
||||
bit.lshift(bytes[2], 8),
|
||||
bytes[1], 0)
|
||||
end
|
||||
|
||||
function bit_converter.bytes_to_int64(bytes, order)
|
||||
if #bytes < 8 then
|
||||
error("eof")
|
||||
end
|
||||
if #bytes < 8 then
|
||||
error("eof")
|
||||
end
|
||||
|
||||
bytes = toLE(bytes, order)
|
||||
bytes = toLE(bytes, order)
|
||||
|
||||
return
|
||||
bit.bor(
|
||||
@@ -331,35 +332,35 @@ function bit_converter.bytes_to_int64(bytes, order)
|
||||
bit.bor(
|
||||
bit.bor(
|
||||
bit.bor(
|
||||
bit.lshift(bytes[1], 56),
|
||||
bit.lshift(bytes[2], 48)),
|
||||
bit.lshift(bytes[3], 40)),
|
||||
bit.lshift(bytes[4], 32)),
|
||||
bit.lshift(bytes[5], 24)),
|
||||
bit.lshift(bit.band(bytes[6], 0xFF), 16)),
|
||||
bit.lshift(bit.band(bytes[7], 0xFF), 8)),bit.band(bytes[8], 0xFF))
|
||||
bit.lshift(bytes[8], 56),
|
||||
bit.lshift(bytes[7], 48)),
|
||||
bit.lshift(bytes[6], 40)),
|
||||
bit.lshift(bytes[5], 32)),
|
||||
bit.lshift(bytes[4], 24)),
|
||||
bit.lshift(bit.band(bytes[3], 0xFF), 16)),
|
||||
bit.lshift(bit.band(bytes[2], 0xFF), 8)),bit.band(bytes[1], 0xFF))
|
||||
end
|
||||
|
||||
function bit_converter.bytes_to_int32(bytes, order)
|
||||
on_deprecated_call("bit_converter.bytes_to_int32", "bit_converter.bytes_to_sint32")
|
||||
return bit_converter.bytes_to_uint32(bytes, order) - MAX_INT32
|
||||
on_deprecated_call("bit_converter.bytes_to_int32", "bit_converter.bytes_to_sint32")
|
||||
return bit_converter.bytes_to_uint32(bytes, order) - MAX_INT32
|
||||
end
|
||||
|
||||
function bit_converter.bytes_to_int16(bytes, order)
|
||||
on_deprecated_call("bit_converter.bytes_to_int16", "bit_converter.bytes_to_sint16")
|
||||
return bit_converter.bytes_to_uint16(bytes, order) - MAX_INT16
|
||||
on_deprecated_call("bit_converter.bytes_to_int16", "bit_converter.bytes_to_sint16")
|
||||
return bit_converter.bytes_to_uint16(bytes, order) - MAX_INT16
|
||||
end
|
||||
|
||||
function bit_converter.bytes_to_sint32(bytes, order)
|
||||
local num = bit_converter.bytes_to_uint32(bytes, order)
|
||||
local num = bit_converter.bytes_to_uint32(bytes, order)
|
||||
|
||||
return MIN_INT32 * (bit.band(MAX_INT32 + 1, num) ~= 0 and 1 or 0) + bit.band(MAX_INT32, num)
|
||||
return MIN_INT32 * (bit.band(MAX_INT32 + 1, num) ~= 0 and 1 or 0) + bit.band(MAX_INT32, num)
|
||||
end
|
||||
|
||||
function bit_converter.bytes_to_sint16(bytes, order)
|
||||
local num = bit_converter.bytes_to_uint16(bytes, order)
|
||||
local num = bit_converter.bytes_to_uint16(bytes, order)
|
||||
|
||||
return MIN_INT16 * (bit.band(MAX_INT16 + 1, num) ~= 0 and 1 or 0) + bit.band(MAX_INT16, num)
|
||||
return MIN_INT16 * (bit.band(MAX_INT16 + 1, num) ~= 0 and 1 or 0) + bit.band(MAX_INT16, num)
|
||||
end
|
||||
|
||||
return bit_converter
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
local gui_util = {}
|
||||
|
||||
--- Parse `pagename?arg1=value1&arg2=value2` queries
|
||||
--- @param query page query string
|
||||
--- @return page_name, args_table
|
||||
function gui_util.parse_query(query)
|
||||
local args = {}
|
||||
local name
|
||||
|
||||
local index = string.find(query, '?')
|
||||
if index then
|
||||
local argstr = string.sub(query, index + 1)
|
||||
name = string.sub(query, 1, index - 1)
|
||||
|
||||
for key, value in string.gmatch(argstr, "([^=&]*)=([^&]*)") do
|
||||
args[key] = value
|
||||
end
|
||||
else
|
||||
name = query
|
||||
end
|
||||
return name, args
|
||||
end
|
||||
|
||||
--- @param query page query string
|
||||
--- @return document_id
|
||||
function gui_util.load_page(query)
|
||||
local name, args = gui_util.parse_query(query)
|
||||
local filename = file.find(string.format("layouts/pages/%s.xml", name))
|
||||
if filename then
|
||||
name = file.prefix(filename)..":pages/"..name
|
||||
gui.load_document(filename, name, args)
|
||||
return name
|
||||
end
|
||||
end
|
||||
|
||||
return gui_util
|
||||
@@ -0,0 +1,8 @@
|
||||
local util = {}
|
||||
|
||||
function util.create_demo_world(generator)
|
||||
app.config_packs({"base"})
|
||||
app.new_world("demo", "2019", generator or "core:default")
|
||||
end
|
||||
|
||||
return util
|
||||
@@ -34,5 +34,8 @@
|
||||
"blocks",
|
||||
"items",
|
||||
"particles"
|
||||
],
|
||||
"models": [
|
||||
"block"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -40,6 +40,7 @@ local Socket = {__index={
|
||||
send=function(self, ...) return network.__send(self.id, ...) end,
|
||||
recv=function(self, ...) return network.__recv(self.id, ...) end,
|
||||
close=function(self) return network.__close(self.id) end,
|
||||
available=function(self) return network.__available(self.id) or 0 end,
|
||||
is_alive=function(self) return network.__is_alive(self.id) end,
|
||||
is_connected=function(self) return network.__is_connected(self.id) end,
|
||||
get_address=function(self) return network.__get_address(self.id) end,
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
function on_hud_open()
|
||||
input.add_callback("player.pick", function ()
|
||||
if hud.is_paused() or hud.is_inventory_open() then
|
||||
return
|
||||
end
|
||||
local pid = hud.get_player()
|
||||
local x, y, z = player.get_selected_block(pid)
|
||||
if x == nil then
|
||||
return
|
||||
end
|
||||
local id = block.get_picking_item(block.get(x, y, z))
|
||||
local inv, cur_slot = player.get_inventory(pid)
|
||||
local slot = inventory.find_by_item(inv, id, 0, 9)
|
||||
if slot then
|
||||
player.set_selected_slot(pid, slot)
|
||||
return
|
||||
end
|
||||
if not rules.get("allow-content-access") then
|
||||
return
|
||||
end
|
||||
slot = inventory.find_by_item(inv, 0, 0, 9)
|
||||
if slot then
|
||||
cur_slot = slot
|
||||
end
|
||||
player.set_selected_slot(pid, cur_slot)
|
||||
inventory.set(inv, cur_slot, id, 1)
|
||||
end)
|
||||
|
||||
input.add_callback("player.noclip", function ()
|
||||
if hud.is_paused() or hud.is_inventory_open() then
|
||||
return
|
||||
end
|
||||
local pid = hud.get_player()
|
||||
if player.is_noclip(pid) then
|
||||
player.set_flight(pid, false)
|
||||
player.set_noclip(pid, false)
|
||||
else
|
||||
player.set_flight(pid, true)
|
||||
player.set_noclip(pid, true)
|
||||
end
|
||||
end)
|
||||
|
||||
input.add_callback("player.flight", function ()
|
||||
if hud.is_paused() or hud.is_inventory_open() then
|
||||
return
|
||||
end
|
||||
local pid = hud.get_player()
|
||||
if player.is_noclip(pid) then
|
||||
return
|
||||
end
|
||||
if player.is_flight(pid) then
|
||||
player.set_flight(pid, false)
|
||||
else
|
||||
player.set_flight(pid, true)
|
||||
player.set_vel(pid, 0, 1, 0)
|
||||
end
|
||||
end)
|
||||
end
|
||||
@@ -7,7 +7,7 @@ local names = {
|
||||
"hidden", "draw-group", "picking-item", "surface-replacement", "script-name",
|
||||
"ui-layout", "inventory-size", "tick-interval", "overlay-texture",
|
||||
"translucent", "fields", "particles", "icon-type", "icon", "placing-block",
|
||||
"stack-size"
|
||||
"stack-size", "name"
|
||||
}
|
||||
for name, _ in pairs(user_props) do
|
||||
table.insert(names, name)
|
||||
@@ -40,3 +40,24 @@ make_read_only(block.properties)
|
||||
for k,v in pairs(block.properties) do
|
||||
make_read_only(v)
|
||||
end
|
||||
|
||||
local function cache_names(library)
|
||||
local indices = {}
|
||||
local names = {}
|
||||
for id=0,library.defs_count()-1 do
|
||||
local name = library.properties[id].name
|
||||
indices[name] = id
|
||||
names[id] = name
|
||||
end
|
||||
|
||||
function library.name(id)
|
||||
return names[id]
|
||||
end
|
||||
|
||||
function library.index(name)
|
||||
return indices[name]
|
||||
end
|
||||
end
|
||||
|
||||
cache_names(block)
|
||||
cache_names(item)
|
||||
|
||||
+171
-18
@@ -9,6 +9,87 @@ function sleep(timesec)
|
||||
end
|
||||
end
|
||||
|
||||
function tb_frame_tostring(frame)
|
||||
local s = frame.short_src
|
||||
if frame.what ~= "C" then
|
||||
s = s .. ":" .. tostring(frame.currentline)
|
||||
end
|
||||
if frame.what == "main" then
|
||||
s = s .. ": in main chunk"
|
||||
elseif frame.name then
|
||||
s = s .. ": in function " .. utf8.escape(frame.name)
|
||||
end
|
||||
return s
|
||||
end
|
||||
|
||||
local function complete_app_lib(app)
|
||||
app.sleep = sleep
|
||||
app.script = __VC_SCRIPT_NAME
|
||||
app.new_world = core.new_world
|
||||
app.open_world = core.open_world
|
||||
app.save_world = core.save_world
|
||||
app.close_world = core.close_world
|
||||
app.reopen_world = core.reopen_world
|
||||
app.delete_world = core.delete_world
|
||||
app.reconfig_packs = core.reconfig_packs
|
||||
app.get_setting = core.get_setting
|
||||
app.set_setting = core.set_setting
|
||||
app.tick = coroutine.yield
|
||||
app.get_version = core.get_version
|
||||
app.get_setting_info = core.get_setting_info
|
||||
app.load_content = core.load_content
|
||||
app.reset_content = core.reset_content
|
||||
|
||||
function app.config_packs(packs_list)
|
||||
-- Check if packs are valid and add dependencies to the configuration
|
||||
packs_list = pack.assemble(packs_list)
|
||||
|
||||
local installed = pack.get_installed()
|
||||
local toremove = {}
|
||||
for _, packid in ipairs(installed) do
|
||||
if not table.has(packs_list, packid) then
|
||||
table.insert(toremove, packid)
|
||||
end
|
||||
end
|
||||
local toadd = {}
|
||||
for _, packid in ipairs(packs_list) do
|
||||
if not table.has(installed, packid) then
|
||||
table.insert(toadd, packid)
|
||||
end
|
||||
end
|
||||
app.reconfig_packs(toadd, toremove)
|
||||
end
|
||||
|
||||
function app.quit()
|
||||
local tb = debug.get_traceback(1)
|
||||
local s = "app.quit() traceback:"
|
||||
for i, frame in ipairs(tb) do
|
||||
s = s .. "\n\t"..tb_frame_tostring(frame)
|
||||
end
|
||||
debug.log(s)
|
||||
core.quit()
|
||||
coroutine.yield()
|
||||
end
|
||||
|
||||
function app.sleep_until(predicate, max_ticks)
|
||||
max_ticks = max_ticks or 1e9
|
||||
local ticks = 0
|
||||
while ticks < max_ticks and not predicate() do
|
||||
app.tick()
|
||||
ticks = ticks + 1
|
||||
end
|
||||
if ticks == max_ticks then
|
||||
error("max ticks exceed")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if app then
|
||||
complete_app_lib(app)
|
||||
elseif __vc_app then
|
||||
complete_app_lib(__vc_app)
|
||||
end
|
||||
|
||||
------------------------------------------------
|
||||
------------------- Events ---------------------
|
||||
------------------------------------------------
|
||||
@@ -54,7 +135,12 @@ function events.emit(event, ...)
|
||||
return nil
|
||||
end
|
||||
for _, func in ipairs(handlers) do
|
||||
result = result or func(...)
|
||||
local status, newres = xpcall(func, __vc__error, ...)
|
||||
if not status then
|
||||
debug.error("error in event ("..event..") handler: "..newres)
|
||||
else
|
||||
result = result or newres
|
||||
end
|
||||
end
|
||||
return result
|
||||
end
|
||||
@@ -85,7 +171,7 @@ function Document.new(docname)
|
||||
end
|
||||
|
||||
local _RadioGroup = {}
|
||||
function _RadioGroup.set(self, key)
|
||||
function _RadioGroup:set(key)
|
||||
if type(self) ~= 'table' then
|
||||
error("called as non-OOP via '.', use radiogroup:set")
|
||||
end
|
||||
@@ -98,7 +184,7 @@ function _RadioGroup.set(self, key)
|
||||
self.callback(key)
|
||||
end
|
||||
end
|
||||
function _RadioGroup.__call(self, elements, onset, default)
|
||||
function _RadioGroup:__call(elements, onset, default)
|
||||
local group = setmetatable({
|
||||
elements=elements,
|
||||
callback=onset,
|
||||
@@ -114,20 +200,8 @@ _GUI_ROOT = Document.new("core:root")
|
||||
_MENU = _GUI_ROOT.menu
|
||||
menu = _MENU
|
||||
|
||||
local __post_runnables = {}
|
||||
|
||||
function __process_post_runnables()
|
||||
if #__post_runnables then
|
||||
for _, func in ipairs(__post_runnables) do
|
||||
func()
|
||||
end
|
||||
__post_runnables = {}
|
||||
end
|
||||
end
|
||||
|
||||
function time.post_runnable(runnable)
|
||||
table.insert(__post_runnables, runnable)
|
||||
end
|
||||
local gui_util = require "core:gui_util"
|
||||
__vc_page_loader = gui_util.load_page
|
||||
|
||||
--- Console library extension ---
|
||||
console.cheats = {}
|
||||
@@ -272,7 +346,6 @@ function __vc_on_hud_open()
|
||||
|
||||
_rules.create("allow-content-access", hud._is_content_access(), function(value)
|
||||
hud._set_content_access(value)
|
||||
input.set_enabled("player.pick", value)
|
||||
end)
|
||||
_rules.create("allow-flight", true, function(value)
|
||||
input.set_enabled("player.flight", value)
|
||||
@@ -328,6 +401,86 @@ function __vc_on_world_quit()
|
||||
_rules.clear()
|
||||
end
|
||||
|
||||
local __vc_coroutines = {}
|
||||
local __vc_named_coroutines = {}
|
||||
local __vc_next_coroutine = 1
|
||||
local __vc_coroutine_error = nil
|
||||
|
||||
function __vc_start_coroutine(chunk)
|
||||
local co = coroutine.create(function()
|
||||
local status, err = pcall(chunk)
|
||||
if not status then
|
||||
__vc_coroutine_error = err
|
||||
end
|
||||
end)
|
||||
local id = __vc_next_coroutine
|
||||
__vc_next_coroutine = __vc_next_coroutine + 1
|
||||
__vc_coroutines[id] = co
|
||||
return id
|
||||
end
|
||||
|
||||
function __vc_resume_coroutine(id)
|
||||
local co = __vc_coroutines[id]
|
||||
if co then
|
||||
coroutine.resume(co)
|
||||
if __vc_coroutine_error then
|
||||
debug.error(__vc_coroutine_error)
|
||||
error(__vc_coroutine_error)
|
||||
end
|
||||
return coroutine.status(co) ~= "dead"
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function __vc_stop_coroutine(id)
|
||||
local co = __vc_coroutines[id]
|
||||
if co then
|
||||
if coroutine.close then
|
||||
coroutine.close(co)
|
||||
end
|
||||
__vc_coroutines[id] = nil
|
||||
end
|
||||
end
|
||||
|
||||
function start_coroutine(chunk, name)
|
||||
local co = coroutine.create(function()
|
||||
local status, error = xpcall(chunk, __vc__error)
|
||||
if not status then
|
||||
debug.error(error)
|
||||
end
|
||||
end)
|
||||
__vc_named_coroutines[name] = co
|
||||
end
|
||||
|
||||
local __post_runnables = {}
|
||||
|
||||
function __process_post_runnables()
|
||||
if #__post_runnables then
|
||||
for _, func in ipairs(__post_runnables) do
|
||||
local status, result = xpcall(func, __vc__error)
|
||||
if not status then
|
||||
debug.error("error in post_runnable: "..result)
|
||||
end
|
||||
end
|
||||
__post_runnables = {}
|
||||
end
|
||||
|
||||
local dead = {}
|
||||
for name, co in pairs(__vc_named_coroutines) do
|
||||
coroutine.resume(co)
|
||||
if coroutine.status(co) == "dead" then
|
||||
table.insert(dead, name)
|
||||
end
|
||||
end
|
||||
for _, name in ipairs(dead) do
|
||||
__vc_named_coroutines[name] = nil
|
||||
end
|
||||
end
|
||||
|
||||
function time.post_runnable(runnable)
|
||||
table.insert(__post_runnables, runnable)
|
||||
end
|
||||
|
||||
assets = {}
|
||||
assets.load_texture = core.__load_texture
|
||||
|
||||
|
||||
+19
-2
@@ -34,11 +34,11 @@ end
|
||||
|
||||
|
||||
function timeit(iters, func, ...)
|
||||
local tm = time.uptime()
|
||||
local tm = os.clock()
|
||||
for i=1,iters do
|
||||
func(...)
|
||||
end
|
||||
print("[time mcs]", (time.uptime()-tm) * 1000000)
|
||||
print("[time mcs]", (os.clock()-tm) * 1000000)
|
||||
end
|
||||
|
||||
----------------------------------------------
|
||||
@@ -361,3 +361,20 @@ function __vc_warning(msg, detail, n)
|
||||
"core:warning", msg, detail, debug.get_traceback(1 + (n or 0)))
|
||||
end
|
||||
end
|
||||
|
||||
function file.name(path)
|
||||
return path:match("([^:/\\]+)$")
|
||||
end
|
||||
|
||||
function file.stem(path)
|
||||
local name = file.name(path)
|
||||
return name:match("(.+)%.[^%.]+$") or name
|
||||
end
|
||||
|
||||
function file.ext(path)
|
||||
return path:match("%.([^:/\\]+)$")
|
||||
end
|
||||
|
||||
function file.prefix(path)
|
||||
return path:match("^([^:]+)")
|
||||
end
|
||||
|
||||
@@ -34,6 +34,7 @@ graphics.dense-render.tooltip=Включает прозрачность блок
|
||||
menu.Apply=Применить
|
||||
menu.Audio=Звук
|
||||
menu.Back to Main Menu=Вернуться в Меню
|
||||
menu.Scripts=Сценарии
|
||||
menu.Content Error=Ошибка Контента
|
||||
menu.Content=Контент
|
||||
menu.Continue=Продолжить
|
||||
|
||||
+2
-2
@@ -17,10 +17,10 @@ Console=Konsol
|
||||
Log=log
|
||||
Problems=Muammolar
|
||||
Monitor=Monitoring
|
||||
Debug=Xatolarni tuzatish (Debug)
|
||||
Debug=Debug
|
||||
File=Fayl
|
||||
|
||||
devtools.traceback=Chaqiruvlar steki (so‘nggisidan boshlab)
|
||||
devtools.traceback=Chaqiruvlar steki (so`nggisidan boshlab)
|
||||
error.pack-not-found=Paketni topib bo'lmadi
|
||||
error.dependency-not-found=Amaldagi qaramliklar topilmadi
|
||||
pack.remove-confirm=Paketlar bilan taqdim etilgan barcha contentni dunyodan olib tashlash (qaytarib bo'lmaydi)?
|
||||
|
||||
Reference in New Issue
Block a user