Compare commits

...

5 Commits

Author SHA1 Message Date
Daretmavi ed2630c292 Mods update 2021-07-07 17:02:36 +02:00
Daretmavi f11ec46f3f Mods update 2021-07-04 11:34:10 +02:00
Daretmavi 7237aa5091 i3 is from fork, not directly patched 2021-07-01 18:21:54 +02:00
Daretmavi 5f8b4428c8 Mods update 2021-07-01 18:21:22 +02:00
Daretmavi 4d568e86da scripts update 2021-07-01 18:20:53 +02:00
89 changed files with 2735 additions and 7317 deletions

View File

@ -47,8 +47,8 @@ MOD_PATCHES=(\
"player/fire_plus:extend_fire.patch" \
"mobs/mobs_mobs/advanced_npc:adv_npc_log.patch" "mobs/mobs_mobs/advanced_npc:bugtrade184.patch" \
"mobs/mobs_mobs/mg_villages_npc:bug.patch" "mobs/mobs_mobs/mg_villages_npc:patch_log.patch" \
"gui/i3:progressive_creative.patch" "gui/i3:notrash.patch" \
"minetest_game/default:i3_size.patch")
# "gui/i3:progressive_creative.patch" "gui/i3:notrash.patch" \
#"mobs/mobs_mobs/goblins:goblins_nil.patch"
#MOD_PATCHES=( )

View File

@ -41,7 +41,7 @@ origin git@github.com:Sokomine/bell.git (fetch)
Mod: buildings/bell
origin https://github.com/Sokomine/cottages (fetch)
* master 3dec7bf [origin/master] fixed bug with hud removal
* master 2b10e6f [origin/master] fixed tree well
Mod: buildings/cottages
origin https://bitbucket.org/sorcerykid/doors.git (fetch)
@ -73,11 +73,12 @@ origin https://github.com/minetest-mods/dynamic_liquid (fetch)
Mod: environment/dynamic_liquid
origin https://notabug.org/tenplus1/farming (fetch)
* master 70803f8 [origin/master] add pumpkin bottom texture, redo melon node, fix typo in scythe, make pumpkin/melon rotatable
* master a5ea92b [origin/master] fix cocoa drops
Mod: flora/farming
origin https://github.com/minetest-mods/i3.git (fetch)
* main dde5148 [origin/main] Show a tooltip for waypoints
origin https://github.com/daretmavi/i3.git (fetch)
upstream https://github.com/minetest-mods/i3.git (fetch)
* main 4e39096 [origin/main] Merge pull request #4 from daretmavi/devtest
Mod: gui/i3
origin https://repo.or.cz/minetest_hbarmor.git (fetch)
@ -113,11 +114,11 @@ origin https://github.com/TheTermos/mobkit (fetch)
Mod: lib_api/mobkit
origin https://notabug.org/tenplus1/mobs_redo (fetch)
* master 33589eb [origin/master] improve pathfinding level 2 digging/building, add infotext, stop mob attack spin, tweak & tidy code
* master e50d04a [origin/master] fix facing fence jump bug
Mod: lib_api/mobs_redo
origin https://github.com/appgurueu/modlib (fetch)
* master d8f3bf2 [origin/master] Fix debug.stack
* master 35081f3 [origin/master] Localize global fields
Mod: lib_api/modlib
origin git@github.com:runsy/rcbows.git (fetch)
@ -149,7 +150,7 @@ origin https://codeberg.org/Hamlet/mobs_ghost_redo (fetch)
Mod: mobs/mobs_mobs/mobs_ghost_redo
origin https://notabug.org/TenPlus1/mobs_monster.git (fetch)
* master 9b3c1e1 [origin/master] fire spirit additions
* master 5009e74 [origin/master] lava flan heals while in lava
Mod: mobs/mobs_mobs/mobs_monster
origin https://github.com/berengma/aerotest (fetch)
@ -157,7 +158,7 @@ origin https://github.com/berengma/aerotest (fetch)
Mod: mobs/mobs_mobkit/aerotest
origin https://github.com/runsy/petz (fetch)
* master b593d81 [origin/master] fix: pumpkin grenade respects protected nodes
* master 48a3df7 [origin/master] Merge pull request #71 from snowyu/fix/cant_wool_regrow
Mod: mobs/mobs_mobkit/petz
origin https://github.com/berengma/water_life (fetch)
@ -165,7 +166,7 @@ origin https://github.com/berengma/water_life (fetch)
Mod: mobs/mobs_mobkit/water_life
origin https://github.com/minetest-mods/3d_armor (fetch)
* master a0cf12b [origin/master] Add setting to disable armor visuals on player model (#48)
* master 38fc2cf [origin/master] Fix typo in wieldview (#56)
Mod: player/3d_armor
origin https://github.com/appgurueu/character_anim (fetch)
@ -189,7 +190,7 @@ origin https://gitlab.com/4w/hunger_ng.git (fetch)
Mod: player/hunger_ng
origin https://github.com/minetest-mods/skinsdb.git (fetch)
* master c53158d [origin/master] Update to work with Unified Inventory v2 i.e. the formspec v4 rewrite Requires UI "version-2" tag or commit a7556c50 or later and and Minetest v5.4.0 or later
* master 716a9a3 [origin/master] fix get_string() on wrong variable
Mod: player/skinsdb
origin https://github.com/stujones11/wield3d.git (fetch)
@ -201,7 +202,7 @@ origin https://github.com/minetest-mods/wielded_light.git (fetch)
Mod: player/wielded_light
origin https://notabug.org/TenPlus1/bonemeal.git (fetch)
* master b5819d0 [origin/master] reduce shapeless crafts
* master 75ec006 [origin/master] dry grass grows on dry dirt
Mod: tools/bonemeal
origin git@gitlab.com:daretmavi/bucket-lite.git (fetch)

View File

@ -9,6 +9,12 @@
local S = cottages.S
-- disable repair with anvil by setting a message for the item in question
cottages.forbid_repair = {}
-- example for hammer no longer beeing able to repair the hammer
--cottages.forbid_repair["cottages:hammer"] = 'The hammer is too complex for repairing.'
-- the hammer for the anvil
minetest.register_tool("cottages:hammer", {
description = S("Steel hammer for repairing tools on the anvil"),
@ -138,6 +144,12 @@ minetest.register_node("cottages:anvil", {
S('The workpiece slot is for damaged tools only.'));
return 0;
end
if( listname=='input'
and cottages.forbid_repair[ stack:get_name() ]) then
minetest.chat_send_player( player:get_player_name(),
S(cottages.forbid_repair[ stack:get_name() ]));
return 0;
end
return stack:get_count()
end,
@ -181,6 +193,14 @@ minetest.register_node("cottages:anvil", {
-- 65535 is max damage
local damage_state = 40-math.floor(input:get_wear()/1638);
-- just to make sure that it really can't get repaired if it should not
-- (if the check of placing the item in the input slot failed somehow)
if( puncher and name and cottages.forbid_repair[ input:get_name() ]) then
minetest.chat_send_player( name,
S(cottages.forbid_repair[ input:get_name() ]));
return;
end
local tool_name = input:get_name();
local hud_image = "";
if( tool_name

View File

@ -117,7 +117,7 @@ minetest.register_node("cottages:water_gen", {
paramtype = "light",
paramtype2 = "facedir",
is_ground_content = false,
groups = {tree = 1, choppy = 2, oddly_breakable_by_hand = 1, flammable = 2},
groups = {tree = 1, choppy = 2, cracky = 1, flammable = 2},
sounds = cottages.sounds.wood,
node_box = {
type = "fixed",
@ -178,8 +178,14 @@ minetest.register_node("cottages:water_gen", {
can_dig = function(pos,player)
local meta = minetest.get_meta(pos);
local inv = meta:get_inventory()
return inv:is_empty("main") and
default.can_interact_with_node(player, pos)
local bucket = meta:get_string("bucket")
local start = meta:get_string("fillstarttime")
return inv:is_empty("main")
and default.can_interact_with_node(player, pos)
and (not(bucket) or bucket == "")
and ((not(start) or start == "" or
(minetest.get_us_time()/1000000) - tonumber(start)
>= cottages.water_fill_time -2))
end,
-- no inventory move allowed
allow_metadata_inventory_move = function(pos, from_list, from_index,
@ -213,7 +219,7 @@ minetest.register_node("cottages:water_gen", {
cottages.switch_public(pos, formname, fields, sender, 'tree trunk well')
end,
-- punch to place and retrieve bucket
on_punch = function(pos, node, puncher)
on_punch = function(pos, node, puncher, pointed_thing)
if( not( pos ) or not( node ) or not( puncher )) then
return
end
@ -223,7 +229,8 @@ minetest.register_node("cottages:water_gen", {
local owner = meta:get_string("owner")
local public = meta:get_string("public")
if( name ~= owner and public~="public") then
minetest.chat_send_player( name, S("This tree trunk well is owned by %s. You can't use it."):format(name))
minetest.chat_send_player( name,
S("This tree trunk well is owned by %s. You can't use it."):format(owner))
return
end
@ -233,13 +240,18 @@ minetest.register_node("cottages:water_gen", {
-- is the well working on something? (either empty or full bucket)
local bucket = meta:get_string("bucket")
-- there is a bucket loaded - either empty or full
if( bucket and bucket~="") then
if( bucket and bucket~="" and bucket ~= "bucket:bucket_empty") then
if( not(pinv:room_for_item("main", bucket))) then
minetest.chat_send_player( puncher:get_player_name(),
S("Sorry. You have no room for the bucket. Please free some "..
"space in your inventory first!"))
return
end
elseif( bucket and bucket == "bucket:bucket_empty") then
minetest.chat_send_player( puncher:get_player_name(),
S("Please wait until your bucket has been filled."))
-- do not give the empty bucket back immediately
return
end
-- remove the old entity (either a bucket will be placed now or a bucket taken)
@ -267,8 +279,6 @@ minetest.register_node("cottages:water_gen", {
if( wielded
and wielded:get_name()
and wielded:get_name() == "bucket:bucket_empty") then
-- remove the bucket from the players inventory
pinv:remove_item( "main", "bucket:bucket_empty")
-- remember that we got a bucket loaded
meta:set_string("bucket", "bucket:bucket_empty")
-- create the entity
@ -280,6 +290,8 @@ minetest.register_node("cottages:water_gen", {
minetest.after(cottages.water_fill_time, cottages.water_gen_fill_bucket, pos)
-- the bucket will only be filled if the water ran long enough
meta:set_string("fillstarttime", tostring(minetest.get_us_time()/1000000))
-- remove the bucket from the players inventory
pinv:remove_item( "main", "bucket:bucket_empty")
return;
end
-- buckets can also be emptied here

View File

@ -0,0 +1,659 @@
ts_doors = {}
ts_doors.registered_doors = {}
ts_doors.sounds = {}
-- Used for localization
local S = minetest.get_translator("ts_doors")
-- Get texture by node name
local T = function (node_name)
local def = minetest.registered_nodes[node_name]
if not (def and def.tiles) then
return ""
end
local tile = def.tiles[5] or def.tiles[4] or def.tiles[3] or def.tiles[2] or def.tiles[1]
if type(tile) == "string" then
return tile
elseif type(tile) == "table" and tile.name then
return tile.name
end
return ""
end
-- Use this to generate the translation template file.
--[[
local oldS = S
local function S(x)
print(x .. "=")
return oldS(x)
end
]]
if default.node_sound_metal_defaults then
ts_doors.sounds.metal = {
sounds = default.node_sound_metal_defaults(),
sound_open = "doors_steel_door_open",
sound_close = "doors_steel_door_close",
}
else
ts_doors.sounds.metal = {
sounds = default.node_sound_stone_defaults(),
sound_open = "doors_steel_door_open",
sound_close = "doors_steel_door_close",
}
end
ts_doors.sounds.wood = {
sounds = default.node_sound_wood_defaults(),
sound_open = "doors_door_open",
sound_close = "doors_door_close"
}
ts_doors.sounds.glass = {
sounds = default.node_sound_glass_defaults(),
sound_open = "doors_glass_door_open",
sound_close = "doors_glass_door_close",
}
local function get_door_name(meta, item)
local door_type_string = meta:get_int("trapdoor") == 1 and "trapdoor_" or "door_"
local locked_string = meta:get_int("locked") == 1 and "locked_" or ""
local solid_string = meta:get_int("solid") == 1 and "full_" or ""
return "ts_doors:" .. door_type_string .. solid_string .. locked_string .. item:gsub(":", "_")
end
local function register_door_alias(name, convert_to)
minetest.register_alias(name, convert_to)
minetest.register_alias(name .. "_a", convert_to .. "_a")
minetest.register_alias(name .. "_b", convert_to .. "_b")
minetest.register_alias(name .. "_c", convert_to .. "_c")
minetest.register_alias(name .. "_d", convert_to .. "_d")
end
local function register_trapdoor_alias(name, convert_to)
minetest.register_alias(name, convert_to)
minetest.register_alias(name .. "_open", convert_to .. "_open")
end
function ts_doors.register_alias(name, convert_to)
name = name:gsub(":", "_")
convert_to = convert_to:gsub(":", "_")
for _,style in pairs({"", "full_", "locked_", "full_locked_"}) do
register_door_alias("ts_doors:door_" .. style .. name, "ts_doors:door_" .. style .. convert_to)
register_trapdoor_alias("ts_doors:trapdoor_" .. style .. name, "ts_doors:trapdoor_" .. style .. convert_to)
end
end
function ts_doors.register_door(item, description, texture, sounds, recipe)
if not minetest.registered_nodes[item] then
minetest.log("[ts_doors] bug found: "..item.." is not a registered node. Cannot create doors")
return
end
if not sounds then
sounds = {}
end
if not texture then
texture = T(item)
end
recipe = recipe or item
ts_doors.registered_doors[item:gsub(":", "_")] = recipe
register_door_alias("doors:ts_door_" .. item:gsub(":", "_"), "ts_doors:door_" .. item:gsub(":", "_"))
register_door_alias("doors:ts_door_full_" .. item:gsub(":", "_"), "ts_doors:door_full_" .. item:gsub(":", "_"))
register_door_alias("doors:ts_door_locked_" .. item:gsub(":", "_"), "ts_doors:door_locked_" .. item:gsub(":", "_"))
register_door_alias("doors:ts_door_full_locked_" .. item:gsub(":", "_"), "ts_doors:door_full_locked_" .. item:gsub(":", "_"))
local groups = minetest.registered_nodes[item].groups
local door_groups = {door=1}
for k, v in pairs(groups) do
if k ~= "wood" then
door_groups[k] = v
end
end
doors.register("ts_doors:door_" .. item:gsub(":", "_"), {
tiles = { { name = "[combine:32x38:0,0=" .. texture .. ":0,16=" .. texture .. ":0,32=" .. texture .. ":16,0=" .. texture .. ":16,16=" .. texture .. ":16,32=" .. texture .. "^[transformR90^[colorize:#fff:30^ts_doors_base.png^[noalpha^[makealpha:0,255,0", backface_culling = true } },
description = S(description .. " Windowed Door"),
inventory_image = "[combine:32x32:0,8=" .. texture .. ":16,8=" .. texture .. "^[transformR90^[colorize:#fff:30^ts_doors_base_inv.png^[noalpha^[makealpha:0,255,0",
groups = table.copy(door_groups),
sounds = sounds.sounds or nil,
sound_open = sounds.sound_open or nil,
sound_close = sounds.sound_close or nil,
})
doors.register("ts_doors:door_full_" .. item:gsub(":", "_"), {
tiles = { { name = "[combine:32x38:0,0=" .. texture .. ":0,16=" .. texture .. ":0,32=" .. texture .. ":16,0=" .. texture .. ":16,16=" .. texture .. ":16,32=" .. texture .. "^[transformR90^[colorize:#fff:30^ts_doors_base_full.png^[noalpha", backface_culling = true } },
description = S("Solid " .. description .. " Door"),
inventory_image = "[combine:32x32:0,8=" .. texture .. ":16,8=" .. texture .. "^[transformR90^[colorize:#fff:30^ts_doors_base_full_inv.png^[noalpha^[makealpha:0,255,0",
groups = table.copy(door_groups),
sounds = sounds.sounds or nil,
sound_open = sounds.sound_open or nil,
sound_close = sounds.sound_close or nil,
})
doors.register_trapdoor("ts_doors:trapdoor_" .. item:gsub(":", "_"), {
description = S("Windowed " .. description .. " Trapdoor"),
inventory_image = texture .. "^[transformR90^[colorize:#fff:30^ts_doors_base_trapdoor.png^[noalpha^[makealpha:0,255,0",
wield_image = texture .. "^[transformR90^[colorize:#fff:30^ts_doors_base_trapdoor.png^[noalpha^[makealpha:0,255,0",
tile_front = texture .. "^[transformR90^[colorize:#fff:30^ts_doors_base_trapdoor.png^[noalpha^[makealpha:0,255,0",
tile_side = texture .. "^[colorize:#fff:30",
groups = table.copy(door_groups),
sounds = sounds.sounds or nil,
sound_open = sounds.sound_open or nil,
sound_close = sounds.sound_close or nil,
})
doors.register_trapdoor("ts_doors:trapdoor_full_" .. item:gsub(":", "_"), {
description = S("Solid " .. description .. " Trapdoor"),
inventory_image = texture .. "^[transformR90^[colorize:#fff:30^ts_doors_base_trapdoor_full.png^[noalpha",
wield_image = texture .. "^[transformR90^[colorize:#fff:30^ts_doors_base_trapdoor_full.png^[noalpha",
tile_front = texture .. "^[transformR90^[colorize:#fff:30^ts_doors_base_trapdoor_full.png^[noalpha",
tile_side = texture .. "^[colorize:#fff:30",
groups = table.copy(door_groups),
sounds = sounds.sounds or nil,
sound_open = sounds.sound_open or nil,
sound_close = sounds.sound_close or nil,
})
door_groups.level = 2
doors.register("ts_doors:door_locked_" .. item:gsub(":", "_"), {
tiles = { { name = "[combine:32x38:0,0=" .. texture .. ":0,16=" .. texture .. ":0,32=" .. texture .. ":16,0=" .. texture .. ":16,16=" .. texture .. ":16,32=" .. texture .. "^[transformR90^[colorize:#fff:30^ts_doors_base_locked.png^[noalpha^[makealpha:0,255,0", backface_culling = true } },
description = S("Windowed Locked " .. description .. " Door"),
inventory_image = "[combine:32x32:0,8=" .. texture .. ":16,8=" .. texture .. "^[transformR90^[colorize:#fff:30^ts_doors_base_locked_inv.png^[noalpha^[makealpha:0,255,0",
protected = true,
groups = table.copy(door_groups),
sound_open = "doors_steel_door_open",
sound_close = "doors_steel_door_close",
sounds = sounds.sounds or nil,
sound_open = sounds.sound_open or nil,
sound_close = sounds.sound_close or nil,
})
doors.register("ts_doors:door_full_locked_" .. item:gsub(":", "_"), {
tiles = { { name = "[combine:32x38:0,0=" .. texture .. ":0,16=" .. texture .. ":0,32=" .. texture .. ":16,0=" .. texture .. ":16,16=" .. texture .. ":16,32=" .. texture .. "^[transformR90^[colorize:#fff:30^ts_doors_base_full_locked.png^[noalpha", backface_culling = true } },
description = S("Solid Locked " .. description .. " Door"),
inventory_image = "[combine:32x32:0,8=" .. texture .. ":16,8=" .. texture .. "^[transformR90^[colorize:#fff:30^ts_doors_base_full_locked_inv.png^[noalpha^[makealpha:0,255,0",
protected = true,
groups = table.copy(door_groups),
sound_open = "doors_steel_door_open",
sound_close = "doors_steel_door_close",
sounds = sounds.sounds or nil,
sound_open = sounds.sound_open or nil,
sound_close = sounds.sound_close or nil,
})
doors.register_trapdoor("ts_doors:trapdoor_locked_" .. item:gsub(":", "_"), {
description = S("Windowed Locked " .. description .. " Trapdoor"),
inventory_image = texture .. "^[transformR90^[colorize:#fff:30^ts_doors_base_trapdoor_locked.png^[noalpha^[makealpha:0,255,0",
wield_image = texture .. "^[transformR90^[colorize:#fff:30^ts_doors_base_trapdoor_locked.png^[noalpha^[makealpha:0,255,0",
tile_front = texture .. "^[transformR90^[colorize:#fff:30^ts_doors_base_trapdoor_locked.png^[noalpha^[makealpha:0,255,0",
tile_side = texture .. "^[colorize:#fff:30",
protected = true,
groups = table.copy(door_groups),
sounds = sounds.sounds or nil,
sound_open = sounds.sound_open or nil,
sound_close = sounds.sound_close or nil,
})
doors.register_trapdoor("ts_doors:trapdoor_full_locked_" .. item:gsub(":", "_"), {
description = S("Solid Locked " .. description .. " Trapdoor"),
inventory_image = texture .. "^[transformR90^[colorize:#fff:30^ts_doors_base_trapdoor_full_locked.png^[noalpha",
wield_image = texture .. "^[transformR90^[colorize:#fff:30^ts_doors_base_trapdoor_full_locked.png^[noalpha",
tile_front = texture .. "^[transformR90^[colorize:#fff:30^ts_doors_base_trapdoor_full_locked.png^[noalpha",
tile_side = texture .. "^[colorize:#fff:30",
protected = true,
groups = table.copy(door_groups),
sounds = sounds.sounds or nil,
sound_open = sounds.sound_open or nil,
sound_close = sounds.sound_close or nil,
})
end
ts_doors.register_door("default:aspen_wood", "Aspen", nil, ts_doors.sounds.wood)
ts_doors.register_door("default:pine_wood", "Pine", nil, ts_doors.sounds.wood)
ts_doors.register_door("default:acacia_wood", "Acacia", nil, ts_doors.sounds.wood)
ts_doors.register_door("default:wood", "Wooden", nil, ts_doors.sounds.wood)
ts_doors.register_door("default:junglewood", "Jungle Wood", nil, ts_doors.sounds.wood)
if minetest.get_modpath("moretrees") then
ts_doors.register_door("moretrees:apple_tree_planks", "Apple Tree", nil, ts_doors.sounds.wood)
ts_doors.register_door("moretrees:beech_planks", "Beech", nil, ts_doors.sounds.wood)
ts_doors.register_door("moretrees:birch_planks", "Birch", nil, ts_doors.sounds.wood)
ts_doors.register_door("moretrees:fir_planks", "Fir", nil, ts_doors.sounds.wood)
ts_doors.register_door("moretrees:oak_planks", "Oak", nil, ts_doors.sounds.wood)
ts_doors.register_door("moretrees:palm_planks", "Palm", nil, ts_doors.sounds.wood)
ts_doors.register_door("moretrees:rubber_tree_planks", "Rubber Tree", nil, ts_doors.sounds.wood)
ts_doors.register_door("moretrees:sequoia_planks", "Sequoia", nil, ts_doors.sounds.wood)
ts_doors.register_door("moretrees:spruce_planks", "Spruce", nil, ts_doors.sounds.wood)
ts_doors.register_door("moretrees:willow_planks", "Willow", nil, ts_doors.sounds.wood)
end
if minetest.get_modpath("ethereal") then
ts_doors.register_door("ethereal:banana_wood", "Banana", nil, ts_doors.sounds.wood)
ts_doors.register_door("ethereal:birch_wood", "Birch", nil, ts_doors.sounds.wood)
ts_doors.register_door("ethereal:frost_wood", "Frost", nil, ts_doors.sounds.wood)
ts_doors.register_door("ethereal:mushroom_trunk", "Mushroom", nil, ts_doors.sounds.wood)
ts_doors.register_door("ethereal:palm_wood", "Palm", nil, ts_doors.sounds.wood)
ts_doors.register_door("ethereal:redwood_wood", "Redwood", nil, ts_doors.sounds.wood)
ts_doors.register_door("ethereal:sakura_wood", "Sakura", nil, ts_doors.sounds.wood)
ts_doors.register_door("ethereal:scorched_tree", "Scorched", nil, ts_doors.sounds.wood)
ts_doors.register_door("ethereal:willow_wood", "Willow", nil, ts_doors.sounds.wood)
ts_doors.register_door("ethereal:yellow_wood", "Healing Tree", nil, ts_doors.sounds.wood)
ts_doors.register_door("ethereal:crystal_block", "Crystal", nil, ts_doors.sounds.metal, "ethereal:crystal_ingot")
end
ts_doors.register_door("default:bronzeblock", "Bronze", nil, ts_doors.sounds.metal, "default:bronze_ingot")
ts_doors.register_door("default:copperblock", "Copper", nil, ts_doors.sounds.metal, "default:copper_ingot")
ts_doors.register_door("default:diamondblock", "Diamond", nil, ts_doors.sounds.metal, "default:diamond")
ts_doors.register_door("default:goldblock", "Gold", nil, ts_doors.sounds.metal, "default:gold_ingot")
ts_doors.register_door("default:steelblock", "Steel", nil, ts_doors.sounds.metal, "default:steel_ingot")
if minetest.get_modpath("moreores") then
ts_doors.register_door("moreores:mithril_block", "Mithril", nil, ts_doors.sounds.metal, "moreores:mithril_ingot")
ts_doors.register_door("moreores:silver_block", "Silver", nil, ts_doors.sounds.metal, "moreores:silver_ingot")
ts_doors.register_door("moreores:tin_block", "Tin", nil, ts_doors.sounds.metal, "moreores:tin_ingot")
end
if minetest.get_modpath("technic") then
ts_doors.register_door("technic:carbon_steel_block", "Carbon Steel", nil, ts_doors.sounds.metal, "technic:carbon_steel_ingot")
ts_doors.register_door("technic:cast_iron_block", "Cast Iron", nil, ts_doors.sounds.metal, "technic:cast_iron_ingot")
ts_doors.register_door("technic:chromium_block", "Chromium", nil, ts_doors.sounds.metal, "technic:chromium_ingot")
ts_doors.register_door("technic:lead_block", "Lead", nil, ts_doors.sounds.metal, "technic:lead_ingot")
ts_doors.register_door("technic:stainless_steel_block", "Stainless Steel", nil, ts_doors.sounds.metal, "technic:stainless_steel_ingot")
ts_doors.register_door("technic:zinc_block", "Zinc", nil, ts_doors.sounds.metal, "technic:zinc_ingot")
ts_doors.register_door("technic:blast_resistant_concrete", "Blast Resistant Concrete", nil, ts_doors.sounds.metal)
end
if minetest.get_modpath("basic_materials") then
ts_doors.register_door("basic_materials:brass_block", "Brass", nil, ts_doors.sounds.metal, "basic_materials:brass_ingot")
ts_doors.register_door("basic_materials:concrete_block", "Concrete", nil, ts_doors.sounds.metal)
ts_doors.register_alias("technic:brass_block", "basic_materials:brass_block")
ts_doors.register_alias("technic:concrete", "basic_materials:concrete_block")
end
minetest.override_item("doors:door_steel", {
description = S("Windowed Locked Plain Steel Door"),
})
minetest.override_item("doors:door_wood", {
description = S("Windowed Mixed Wood Door"),
})
minetest.override_item("doors:trapdoor", {
description = S("Windowed Mixed Wood Trapdoor"),
})
minetest.override_item("doors:trapdoor_steel", {
description = S("Windowed Locked Plain Steel Trapdoor"),
})
ts_doors.workshop = {}
function ts_doors.workshop.update_formspec(pos)
local meta = minetest.get_meta(pos)
local page = meta:get_int("page")
local maxpage = meta:get_int("maxpage")
local selection = meta:get_string("selection")
local trapdoor = meta:get_int("trapdoor") == 1
local locked = meta:get_int("locked") == 1
local solid = meta:get_int("solid") == 1
if page < 1 then
page = maxpage
elseif page > maxpage then
page = 1
end
meta:set_int("page", page)
local fs = "size[9,9;]"
fs = fs .. default.gui_bg .. default.gui_bg_img .. default.gui_slots
if minetest.colorize then
if not locked then
fs = fs .. "button[0,0;2,1;unlocked;" .. minetest.colorize("#ffff00", "Unlocked") .. "]"
fs = fs .. "button[0,0.75;2,1;locked;Locked]"
else
fs = fs .. "button[0,0;2,1;unlocked;Unlocked]"
fs = fs .. "button[0,0.75;2,1;locked;" .. minetest.colorize("#ffff00", "Locked") .. "]"
end
if not solid then
fs = fs .. "button[2,0;2,1;windowed;" .. minetest.colorize("#ffff00", "Windowed") .. "]"
fs = fs .. "button[2,0.75;2,1;solid;Solid]"
else
fs = fs .. "button[2,0;2,1;windowed;Windowed]"
fs = fs .. "button[2,0.75;2,1;solid;" .. minetest.colorize("#ffff00", "Solid") .. "]"
end
if not trapdoor then
fs = fs .. "button[4,0;2,1;doors;" .. minetest.colorize("#ffff00", "Doors") .. "]"
fs = fs .. "button[4,0.75;2,1;trapdoors;Trapdoors]"
else
fs = fs .. "button[4,0;2,1;doors;Doors]"
fs = fs .. "button[4,0.75;2,1;trapdoors;" .. minetest.colorize("#ffff00", "Trapdoors") .. "]"
end
else
fs = fs .. "button[0,0;2,1;unlocked;Unlocked]"
fs = fs .. "button[0,0.75;2,1;locked;Locked]"
fs = fs .. "button[2,0;2,1;windowed;Windowed]"
fs = fs .. "button[2,0.75;2,1;solid;Solid]"
fs = fs .. "button[4,0;2,1;doors;Doors]"
fs = fs .. "button[4,0.75;2,1;trapdoors;Trapdoors]"
end
fs = fs .. "label[0,1.6;Material]"
fs = fs .. "label[0,1.9;needed]"
fs = fs .. "list[context;material_needed;0,2.3;1,1]"
fs = fs .. "label[0,3.25;Input]"
fs = fs .. "list[context;material;0,3.75;1,1]"
fs = fs .. "label[1,1.6;Steel]"
fs = fs .. "label[1,1.9;needed]"
fs = fs .. "list[context;steel_needed;1,2.3;1,1]"
fs = fs .. "label[1,3.25;Input]"
fs = fs .. "list[context;steel;1,3.75;1,1]"
local x = 2
local y = 1.75
local count = 0
for item, recipe in pairs(ts_doors.registered_doors) do
count = count + 1
if (count >= (page - 1) * 12 + 1 and count <= page * 12) then
local door = get_door_name(meta, item)
fs = fs .. "item_image_button[" .. x .. "," .. y .. ";1,1;" .. door .. ";" .. door .. ";]"
x = x + 1
if x > 5 then
x = 2
y = y + 1
end
end
end
fs = fs .. "button[6, 1;1,1;noselection;X]"
fs = fs .. "tooltip[noselection;Remove Current Selection]"
if maxpage > 1 then
fs = fs .. "button[6,2.25;1,1;prevpage;<-]"
fs = fs .. "button[6,3.25;1,1;nextpage;->]"
fs = fs .. "label[6,4;" .. string.format("Page %s of %s", page, maxpage) .. "]"
end
fs = fs .. "label[7.5,0.2;Current]"
fs = fs .. "label[7.5,0.5;Door]"
fs = fs .. "item_image[7.5,1;1,1;" .. selection .. "]"
fs = fs .. "image[7.5,2;1,1;gui_furnace_arrow_bg.png^[lowpart:" .. meta:get_int("progress") * 10 .. ":gui_furnace_arrow_fg.png^[transformR180]"
fs = fs .. "list[context;output;7.5,3;1,1]"
fs = fs .. "list[current_player;main;0.5,5;8,4]"
fs = fs .. "listring[current_player;main]"
fs = fs .. "listring[context;material]"
fs = fs .. "listring[current_player;main]"
fs = fs .. "listring[context;steel]"
fs = fs .. "listring[current_player;main]"
fs = fs .. "listring[context;output]"
meta:set_string("formspec", fs)
end
local function update_inventory(pos)
local meta = minetest.get_meta(pos)
local itemcount = 0
for k, v in pairs(ts_doors.registered_doors) do
itemcount = itemcount + 1
end
meta:set_int("maxpage", math.ceil(itemcount / 16))
local inv = meta:get_inventory()
inv:set_size("material_needed", 0)
inv:set_size("material_needed", 1)
inv:set_size("steel_needed", 0)
inv:set_size("steel_needed", 1)
inv:set_size("material", 1)
inv:set_size("steel", 1)
inv:set_size("output", 1)
local trapdoor = meta:get_int("trapdoor") == 1
local locked = meta:get_int("locked") == 1
local solid = meta:get_int("solid") == 1
local selection = meta:get_string("selection")
if selection and selection ~= "" then
local door = selection:sub(10)
if door:sub(0, 4) == "trap" then
trapdoor = true
door = door:sub(10)
else
trapdoor = false
door = door:sub(6)
end
if door:sub(0, 4) == "full" then
solid = true
door = door:sub(6)
else
solid = false
end
if door:sub(0, 7) == "locked_" then
locked = true
door = door:sub(8)
else
locked = false
end
local material_needed = 1
if trapdoor then
material_needed = 4
else
material_needed = 6
end
if solid then
material_needed = material_needed + 1
end
local steel_needed = 0
if locked then
steel_needed = 1
end
inv:add_item("material_needed", { name = ts_doors.registered_doors[door], count = material_needed })
inv:add_item("steel_needed", { name = "default:steel_ingot", count = steel_needed })
end
end
local function on_receive_fields(pos, formname, fields, sender)
local meta = minetest.get_meta(pos)
if fields.unlocked then
meta:set_int("locked", 0)
elseif fields.locked then
meta:set_int("locked", 1)
elseif fields.windowed then
meta:set_int("solid", 0)
elseif fields.solid then
meta:set_int("solid", 1)
elseif fields.doors then
meta:set_int("trapdoor", 0)
elseif fields.trapdoors then
meta:set_int("trapdoor", 1)
elseif fields.prevpage then
meta:set_int("page", meta:get_int("page") - 1)
elseif fields.nextpage then
meta:set_int("page", meta:get_int("page") + 1)
elseif fields.noselection then
meta:set_string("selection", "")
else
for item, recipe in pairs(ts_doors.registered_doors) do
if fields[get_door_name(meta, item)] then
meta:set_string("selection", get_door_name(meta, item))
end
end
end
end
local function on_construct(pos)
local meta = minetest.get_meta(pos)
meta:set_int("trapdoor", 0)
meta:set_int("locked", 0)
meta:set_int("solid", 0)
meta:set_int("progress", 0)
meta:set_string("working_on", "")
meta:set_int("page", 1)
meta:set_int("maxpage", 1)
meta:set_string("selection", "")
end
local function allow_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player)
return 0
end
local function allow_metadata_inventory_put(pos, listname, index, stack, player)
if listname == "material" then
local meta = minetest.get_meta(pos)
local selection = meta:get_string("selection")
if selection and selection ~= "" then
local door = selection:sub(10)
if door:sub(0, 4) == "trap" then
door = door:sub(10)
else
door = door:sub(6)
end
if door:sub(0, 4) == "full" then
door = door:sub(6)
end
if door:sub(0, 7) == "locked_" then
door = door:sub(8)
end
if stack:get_name() == ts_doors.registered_doors[door] then
return stack:get_count()
else
return 0
end
else
return 0
end
elseif listname == "steel" and (stack:get_name() == "default:steel_ingot") then
return stack:get_count()
else
return 0
end
end
local function allow_metadata_inventory_take(pos, listname, index, stack, player)
if listname == "material" or listname == "steel" or listname == "output" then
return stack:get_count()
else
return 0
end
end
local function on_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player)
end
local function on_metadata_inventory_put(pos, listname, index, stack, player)
end
local function on_metadata_inventory_take(pos, listname, index, stack, player)
end
local function can_dig(pos, player)
local inv = minetest.get_meta(pos):get_inventory()
if inv:is_empty("material") and inv:is_empty("steel") and inv:is_empty("output") then
return true
else
return false
end
end
ts_workshop.register_workshop("ts_doors", "workshop", {
description = S("Door Workshop"),
tiles = {
"default_wood.png",
"default_wood.png",
"default_wood.png^doors_item_wood.png",
"default_wood.png^doors_item_wood.png",
"default_wood.png",
"default_wood.png"
},
drawtype = "nodebox",
paramtype = "light",
paramtype2 = "facedir",
groups = { choppy = 2, oddly_breakable_by_hand = 2 },
node_box = {
type = "fixed",
fixed = {
{ -0.5, -0.5, -0.5, 0.5, -0.3125, 0.5 }, -- NodeBox1
{ -0.5, -0.5, -0.5, -0.375, 0.5, 0.5 }, -- NodeBox2
{ 0.375, -0.5, -0.5, 0.5, 0.5, 0.5 }, -- NodeBox3
{ -0.5, -0.5, 0.375, 0.5, 0.5, 0.5 }, -- NodeBox4
{ -0.5, 0.3125, -0.4375, 0.5, 0.4375, -0.3125 }, -- NodeBox5
}
},
selection_box = {
type = "regular"
},
on_receive_fields = on_receive_fields,
on_construct = on_construct,
allow_metadata_inventory_take = allow_metadata_inventory_take,
allow_metadata_inventory_move = allow_metadata_inventory_move,
allow_metadata_inventory_put = allow_metadata_inventory_put,
on_metadata_inventory_move = on_metadata_inventory_move,
on_metadata_inventory_put = on_metadata_inventory_put,
on_metadata_inventory_take = on_metadata_inventory_take,
can_dig = can_dig,
sounds = default.node_sound_wood_defaults(),
enough_supply = function(pos, selection)
local meta = minetest.get_meta(pos)
if meta:get_string("working_on") ~= "" then
return
end
local inv = meta:get_inventory()
local selection = meta:get_string("selection")
local material = inv:get_stack("material", 1):get_name()
local material_needed_name = inv:get_stack("material_needed", 1):get_name()
local material_needed = inv:get_stack("material_needed", 1):get_count()
local material_ok = inv:get_stack("material", 1):get_count() >= material_needed
local steel = inv:get_stack("steel", 1):get_name()
local steel_needed = inv:get_stack("steel_needed", 1):get_count()
local steel_ok = inv:get_stack("steel", 1):get_count() >= steel_needed
if not (material_ok and steel_ok
and (steel and steel == "default:steel_ingot" or steel_needed == 0)
and selection and selection ~= ""
and material == material_needed_name)
then
return false
else
return true
end
end,
remove_supply = function(pos, selection)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local material = inv:get_stack("material", 1):get_name()
local material_needed = inv:get_stack("material_needed", 1):get_count()
local steel_needed = inv:get_stack("steel_needed", 1):get_count()
inv:remove_item("material", { name = material, count = material_needed })
inv:remove_item("steel", { name = "default:steel_ingot", count = steel_needed })
end,
update_inventory = update_inventory,
update_formspec = ts_doors.workshop.update_formspec,
})
minetest.register_lbm({
name = "ts_doors:update_door_workshop",
nodenames = { "ts_doors:door_workshop" },
action = function(pos, node)
update_inventory(pos)
end,
})
minetest.register_craft({
output = "ts_doors:workshop",
recipe = {
{ "default:wood", "default:wood", "default:wood" },
{ "default:wood", "doors:door_wood", "default:wood" },
{ "default:wood", "default:wood", "default:wood" },
}
})
minetest.register_craft({
type = "fuel",
recipe = "ts_doors:workshop",
burntime = 30,
})

View File

@ -135,11 +135,6 @@ local def = {
tiles = {"farming_cocoa_1.png"},
paramtype = "light",
walkable = false,
drop = {
items = {
{items = {"farming:cocoa_beans 1"}, rarity = 2},
}
},
selection_box = {
type = "fixed",
fixed = {-0.3, -0.5, -0.3, 0.3, 0.5, 0.3}

View File

@ -32,6 +32,25 @@ minetest.register_craft({
recipe = "group:food_corn"
})
-- popcorn
minetest.register_craftitem("farming:popcorn", {
description = S("Popcorn"),
inventory_image = "farming_popcorn.png",
groups = {food_popcorn = 1, flammable = 2},
on_use = minetest.item_eat(4)
})
minetest.register_craft({
output = "farming:popcorn",
recipe = {
{"group:food_pot", "group:food_oil", "group:food_corn"}
},
replacements = {
{"group:food_pot", "farming:pot"},
{"group:food_oil", "vessels:glass_bottle"}
}
})
-- cornstarch
minetest.register_craftitem("farming:cornstarch", {
description = S("Cornstarch"),

View File

@ -173,3 +173,6 @@ Created by gorlock (CC0)
Created by sirrobzeroone (CC0)
farming_gyoza.png
farming_pineapple_ring.png
Created by TechM8 (https://www.deviantart.com/techm8)
farming_popcorn.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 292 B

View File

@ -0,0 +1,9 @@
[*]
end_of_line = lf
[*.{lua,txt,md,json}]
charset = utf8
indent_size = 8
indent_style = tab
insert_final_newline = true
trim_trailing_whitespace = true

View File

@ -38,7 +38,7 @@ i3.new_tab {
Updates the current formspec. `extra_formspec` adds an additional formspec string.
#### `i3.delete_tab(tabname)`
#### `i3.remove_tab(tabname)`
Deletes a tab by name.
@ -141,7 +141,7 @@ Recipes can be registered from a given URL containing a JSON file (HTTP support
```Lua
i3.register_craft({
url = "https://raw.githubusercontent.com/minetest-mods/i3/main/test_online_recipe.json"
url = "https://raw.githubusercontent.com/minetest-mods/i3/main/tests/test_online_recipe.json"
})
```
@ -178,7 +178,7 @@ end)
Removes all recipe filters and adds a new one.
#### `i3.delete_recipe_filter(name)`
#### `i3.remove_recipe_filter(name)`
Removes the recipe filter with the given `name`.
@ -197,12 +197,12 @@ They can be used like so: `<optional_name> +<filter name>=<value1>,<value2>,<...
Example usages:
- `+groups=cracky,crumbly`: search for groups `cracky` and `crumbly` in all items.
- `wood +groups=flammable +types=node`: search for group `flammable` amongst items which contain
`wood` in their names AND have a `node` drawtype.
- `wood +groups=flammable`: search for group `flammable` amongst items which contain
`wood` in their names.
Notes:
- If `optional_name` is omitted, the search filter will apply to all items, without pre-filtering.
- The `+groups` and `+types` filters are currently implemented by default.
- The `+groups` filter is currently implemented by default.
#### `i3.add_search_filter(name, function(item, values))`
@ -237,15 +237,6 @@ Returns a map of search filters, indexed by name.
### Miscellaneous
#### `i3.group_stereotypes`
This is the table indexing the item groups by stereotypes.
You can add a stereotype like so:
```Lua
i3.group_stereotypes.radioactive = "mod:item"
```
#### `i3.export_url`
If set, the mod will export all the cached recipes and usages in a JSON format

View File

@ -18,6 +18,7 @@ This mod requires **Minetest 5.4+**
- Inventory Sorting (alphabetical + item stack compression)
- Item Bookmarks
- Waypoints
- Item List Compression (**`moreblocks`** supported)
**¹** *This mode is a Terraria-like system that shows recipes you can craft from items you ever had in your inventory.
To enable it: `i3_progressive_mode = true` in `minetest.conf`.*
@ -48,4 +49,4 @@ Love this mod? Donations are appreciated: https://www.paypal.me/jpg84240
Demo video (outdated): https://www.youtube.com/watch?v=25nCAaqeacU
![Preview](https://user-images.githubusercontent.com/7883281/116791813-0edf7b00-aabd-11eb-90b3-11c604af34dc.png)
![Preview](https://user-images.githubusercontent.com/7883281/123561657-10ba7780-d7aa-11eb-8bbe-dcec348bb28c.png)

View File

@ -0,0 +1,319 @@
local fmt, insert = string.format, table.insert
local wood_types = {
"acacia_wood", "aspen_wood", "junglewood", "pine_wood",
}
local material_tools = {
"bronze", "diamond", "mese", "stone", "wood",
}
local material_stairs = {
"acacia_wood", "aspen_wood", "brick", "bronzeblock", "cobble", "copperblock",
"desert_cobble", "desert_sandstone", "desert_sandstone_block", "desert_sandstone_brick",
"desert_stone", "desert_stone_block", "desert_stonebrick",
"glass", "goldblock", "ice", "junglewood", "mossycobble", "obsidian",
"obsidian_block", "obsidian_glass", "obsidianbrick", "pine_wood",
"sandstone", "sandstone_block", "sandstonebrick",
"silver_sandstone", "silver_sandstone_block", "silver_sandstone_brick",
"snowblock", "steelblock", "stone", "stone_block", "stonebrick",
"straw", "tinblock",
}
local colors = {
"black", "blue", "brown", "cyan", "dark_green", "dark_grey", "green",
"grey", "magenta", "orange", "pink", "red", "violet", "yellow",
}
local to_compress = {
["default:wood"] = {
replace = "wood",
by = wood_types,
},
["default:fence_wood"] = {
replace = "wood",
by = wood_types,
},
["default:fence_rail_wood"] = {
replace = "wood",
by = wood_types,
},
["default:mese_post_light"] = {
replace = "mese_post_light",
by = {
"mese_post_light_acacia",
"mese_post_light_aspen_wood",
"mese_post_light_junglewood",
"mese_post_light_pine_wood",
}
},
["doors:gate_wood_closed"] = {
replace = "wood",
by = wood_types,
},
["wool:white"] = {
replace = "white",
by = colors
},
["dye:white"] = {
replace = "white",
by = colors
},
["default:axe_steel"] = {
replace = "steel",
by = material_tools
},
["default:pick_steel"] = {
replace = "steel",
by = material_tools
},
["default:shovel_steel"] = {
replace = "steel",
by = material_tools
},
["default:sword_steel"] = {
replace = "steel",
by = material_tools
},
["farming:hoe_steel"] = {
replace = "steel",
by = {"wood", "stone"}
},
["stairs:slab_wood"] = {
replace = "wood",
by = material_stairs
},
["stairs:stair_wood"] = {
replace = "wood",
by = material_stairs
},
["stairs:stair_inner_wood"] = {
replace = "wood",
by = material_stairs
},
["stairs:stair_outer_wood"] = {
replace = "wood",
by = material_stairs
},
["walls:cobble"] = {
replace = "cobble",
by = {"desertcobble", "mossycobble"}
},
}
local circular_saw_names = {
{"micro", "_1"},
{"panel", "_1"},
{"micro", "_2"},
{"panel", "_2"},
{"micro", "_4"},
{"panel", "_4"},
{"micro", ""},
{"panel", ""},
{"micro", "_12"},
{"panel", "_12"},
{"micro", "_14"},
{"panel", "_14"},
{"micro", "_15"},
{"panel", "_15"},
{"stair", "_outer"},
{"stair", ""},
{"stair", "_inner"},
{"slab", "_1"},
{"slab", "_2"},
{"slab", "_quarter"},
{"slab", ""},
{"slab", "_three_quarter"},
{"slab", "_14"},
{"slab", "_15"},
{"slab", "_two_sides"},
{"slab", "_three_sides"},
{"slab", "_three_sides_u"},
{"stair", "_half"},
{"stair", "_alt_1"},
{"stair", "_alt_2"},
{"stair", "_alt_4"},
{"stair", "_alt"},
{"stair", "_right_half"},
{"slope", ""},
{"slope", "_half"},
{"slope", "_half_raised"},
{"slope", "_inner"},
{"slope", "_inner_half"},
{"slope", "_inner_half_raised"},
{"slope", "_inner_cut"},
{"slope", "_inner_cut_half"},
{"slope", "_inner_cut_half_raised"},
{"slope", "_outer"},
{"slope", "_outer_half"},
{"slope", "_outer_half_raised"},
{"slope", "_outer_cut"},
{"slope", "_outer_cut_half"},
{"slope", "_outer_cut_half_raised"},
{"slope", "_cut"},
}
local moreblocks_nodes = {
"coal_stone",
"wood_tile",
"iron_checker",
"circle_stone_bricks",
"cobble_compressed",
"plankstone",
"clean_glass",
"split_stone_tile",
"all_faces_tree",
"dirt_compressed",
"coal_checker",
"clean_glow_glass",
"tar",
"clean_super_glow_glass",
"stone_tile",
"cactus_brick",
"super_glow_glass",
"desert_cobble_compressed",
"copperpatina",
"coal_stone_bricks",
"glow_glass",
"cactus_checker",
"all_faces_pine_tree",
"all_faces_aspen_tree",
"all_faces_acacia_tree",
"all_faces_jungle_tree",
"iron_stone",
"grey_bricks",
"wood_tile_left",
"wood_tile_down",
"wood_tile_center",
"wood_tile_right",
"wood_tile_full",
"checker_stone_tile",
"iron_glass",
"iron_stone_bricks",
"wood_tile_flipped",
"wood_tile_offset",
"coal_glass",
"straw",
"stone",
"stone_block",
"cobble",
"mossycobble",
"brick",
"sandstone",
"steelblock",
"goldblock",
"copperblock",
"bronzeblock",
"diamondblock",
"tinblock",
"desert_stone",
"desert_stone_block",
"desert_cobble",
"meselamp",
"glass",
"tree",
"wood",
"jungletree",
"junglewood",
"pine_tree",
"pine_wood",
"acacia_tree",
"acacia_wood",
"aspen_tree",
"aspen_wood",
"obsidian",
"obsidian_block",
"obsidianbrick",
"obsidian_glass",
"stonebrick",
"desert_stonebrick",
"sandstonebrick",
"silver_sandstone",
"silver_sandstone_brick",
"silver_sandstone_block",
"desert_sandstone",
"desert_sandstone_brick",
"desert_sandstone_block",
"sandstone_block",
"coral_skeleton",
"ice",
}
local colors_moreblocks = table.copy(colors)
insert(colors_moreblocks, "white")
local moreblocks_mods = {
wool = colors_moreblocks,
moreblocks = moreblocks_nodes,
}
local t = {}
for mod, v in pairs(moreblocks_mods) do
for _, nodename in ipairs(v) do
t[nodename] = {}
for _, shape in ipairs(circular_saw_names) do
local to_add = true
if shape[1] == "slope" and shape[2] == "" then
to_add = nil
end
if to_add then
insert(t[nodename], fmt("%s_%s%s", shape[1], nodename, shape[2]))
end
end
local slope_name = fmt("slope_%s", nodename)
to_compress[fmt("%s:%s", mod, slope_name)] = {
replace = slope_name,
by = t[nodename]
}
end
end
local compressed = {}
for k, v in pairs(to_compress) do
compressed[k] = compressed[k] or {}
for _, str in ipairs(v.by) do
local it = k:gsub(v.replace, str)
insert(compressed[k], it)
end
end
local _compressed = {}
for _, v in pairs(compressed) do
for _, v2 in ipairs(v) do
_compressed[v2] = true
end
end
return compressed, _compressed

View File

@ -0,0 +1,62 @@
local S = core.get_translator "i3"
local group_stereotypes = {
dye = "dye:white",
wool = "wool:white",
wood = "default:wood",
tree = "default:tree",
sand = "default:sand",
glass = "default:glass",
stick = "default:stick",
stone = "default:stone",
leaves = "default:leaves",
coal = "default:coal_lump",
vessel = "vessels:glass_bottle",
flower = "flowers:dandelion_yellow",
water_bucket = "bucket:bucket_water",
mesecon_conductor_craftable = "mesecons:wire_00000000_off",
}
local group_names = {
dye = S"Any dye",
coal = S"Any coal",
sand = S"Any sand",
tree = S"Any tree",
wool = S"Any wool",
glass = S"Any glass",
stick = S"Any stick",
stone = S"Any stone",
carpet = S"Any carpet",
flower = S"Any flower",
leaves = S"Any leaves",
vessel = S"Any vessel",
wood = S"Any wood planks",
mushroom = S"Any mushroom",
["color_red,flower"] = S"Any red flower",
["color_blue,flower"] = S"Any blue flower",
["color_black,flower"] = S"Any black flower",
["color_white,flower"] = S"Any white flower",
["color_green,flower"] = S"Any green flower",
["color_orange,flower"] = S"Any orange flower",
["color_yellow,flower"] = S"Any yellow flower",
["color_violet,flower"] = S"Any violet flower",
["color_red,dye"] = S"Any red dye",
["color_blue,dye"] = S"Any blue dye",
["color_grey,dye"] = S"Any grey dye",
["color_pink,dye"] = S"Any pink dye",
["color_cyan,dye"] = S"Any cyan dye",
["color_black,dye"] = S"Any black dye",
["color_white,dye"] = S"Any white dye",
["color_brown,dye"] = S"Any brown dye",
["color_green,dye"] = S"Any green dye",
["color_orange,dye"] = S"Any orange dye",
["color_yellow,dye"] = S"Any yellow dye",
["color_violet,dye"] = S"Any violet dye",
["color_magenta,dye"] = S"Any magenta dye",
["color_dark_grey,dye"] = S"Any dark grey dye",
["color_dark_green,dye"] = S"Any dark green dye",
}
return group_stereotypes, group_names

View File

@ -0,0 +1,13 @@
local model_alias = {
["boats:boat"] = {name = "boats:boat", drawtype = "entity"},
["carts:cart"] = {name = "carts:cart", drawtype = "entity", frames = "0,0"},
["default:chest"] = {name = "default:chest_open"},
["default:chest_locked"] = {name = "default:chest_locked_open"},
["doors:door_wood"] = {name = "doors:door_wood_a"},
["doors:door_glass"] = {name = "doors:door_glass_a"},
["doors:door_obsidian_glass"] = {name = "doors:door_obsidian_glass_a"},
["doors:door_steel"] = {name = "doors:door_steel_a"},
["xpanes:door_steel_bar"] = {name = "xpanes:door_steel_bar_a"},
}
return model_alias

119
mods/gui/i3/etc/styles.lua Normal file
View File

@ -0,0 +1,119 @@
local fmt = string.format
local PNG = {
bg = "i3_bg.png",
bg_full = "i3_bg_full.png",
bar = "i3_bar.png",
hotbar = "i3_hotbar.png",
search = "i3_search.png",
heart = "i3_heart.png",
heart_half = "i3_heart_half.png",
heart_grey = "i3_heart_grey.png",
prev = "i3_next.png^\\[transformFX",
next = "i3_next.png",
arrow = "i3_arrow.png",
trash = "i3_trash.png",
sort_az = "i3_sort_az.png",
sort_za = "i3_sort_za.png",
compress = "i3_compress.png",
fire = "i3_fire.png",
fire_anim = "i3_fire_anim.png",
book = "i3_book.png",
sign = "i3_sign.png",
cancel = "i3_cancel.png",
export = "i3_export.png",
slot = "i3_slot.png",
tab = "i3_tab.png",
tab_small = "i3_tab_small.png",
tab_top = "i3_tab.png^\\[transformFY",
furnace_anim = "i3_furnace_anim.png",
bag = "i3_bag.png",
armor = "i3_armor.png",
awards = "i3_award.png",
skins = "i3_skin.png",
waypoints = "i3_waypoint.png",
teleport = "i3_teleport.png",
add = "i3_add.png",
refresh = "i3_refresh.png",
visible = "i3_visible.png^\\[brighten",
nonvisible = "i3_non_visible.png",
exit = "i3_exit.png",
cancel_hover = "i3_cancel.png^\\[brighten",
search_hover = "i3_search.png^\\[brighten",
export_hover = "i3_export.png^\\[brighten",
trash_hover = "i3_trash.png^\\[brighten^\\[colorize:#f00:100",
compress_hover = "i3_compress.png^\\[brighten",
sort_az_hover = "i3_sort_az.png^\\[brighten",
sort_za_hover = "i3_sort_za.png^\\[brighten",
prev_hover = "i3_next_hover.png^\\[transformFX",
next_hover = "i3_next_hover.png",
tab_hover = "i3_tab_hover.png",
tab_small_hover = "i3_tab_small_hover.png",
tab_hover_top = "i3_tab_hover.png^\\[transformFY",
bag_hover = "i3_bag_hover.png",
armor_hover = "i3_armor_hover.png",
awards_hover = "i3_award_hover.png",
skins_hover = "i3_skin_hover.png",
waypoints_hover = "i3_waypoint_hover.png",
teleport_hover = "i3_teleport.png^\\[brighten",
add_hover = "i3_add.png^\\[brighten",
refresh_hover = "i3_refresh.png^\\[brighten",
exit_hover = "i3_exit.png^\\[brighten",
}
local styles = fmt([[
style_type[field;border=false;bgcolor=transparent]
style_type[label,field;font_size=16]
style_type[button;border=false;content_offset=0]
style_type[image_button,item_image_button;border=false;sound=i3_click]
style_type[item_image_button;bgimg_hovered=%s]
style[pagenum,no_item,no_rcp;font=bold;font_size=18]
style[exit;fgimg=%s;fgimg_hovered=%s;content_offset=0]
style[cancel;fgimg=%s;fgimg_hovered=%s;content_offset=0]
style[search;fgimg=%s;fgimg_hovered=%s;content_offset=0]
style[prev_page;fgimg=%s;fgimg_hovered=%s]
style[next_page;fgimg=%s;fgimg_hovered=%s]
style[prev_recipe;fgimg=%s;fgimg_hovered=%s]
style[next_recipe;fgimg=%s;fgimg_hovered=%s]
style[prev_usage;fgimg=%s;fgimg_hovered=%s]
style[next_usage;fgimg=%s;fgimg_hovered=%s]
style[waypoint_add;fgimg=%s;fgimg_hovered=%s;content_offset=0]
style[btn_bag,btn_armor,btn_skins;font=bold;font_size=18;content_offset=0;sound=i3_click]
style[craft_rcp,craft_usg;noclip=true;font_size=16;sound=i3_craft;
bgimg=i3_btn9.png;bgimg_hovered=i3_btn9_hovered.png;
bgimg_pressed=i3_btn9_pressed.png;bgimg_middle=4,6]
style[confirm_trash_yes,confirm_trash_no;noclip=true;font_size=16;
bgimg=i3_btn9.png;bgimg_hovered=i3_btn9_hovered.png;
bgimg_pressed=i3_btn9_pressed.png;bgimg_middle=4,6]
]],
PNG.slot,
PNG.exit, PNG.exit_hover,
PNG.cancel, PNG.cancel_hover,
PNG.search, PNG.search_hover,
PNG.prev, PNG.prev_hover,
PNG.next, PNG.next_hover,
PNG.prev, PNG.prev_hover,
PNG.next, PNG.next_hover,
PNG.prev, PNG.prev_hover,
PNG.next, PNG.next_hover,
PNG.add, PNG.add_hover)
local fs_elements = {
label = "label[%f,%f;%s]",
box = "box[%f,%f;%f,%f;%s]",
image = "image[%f,%f;%f,%f;%s]",
tooltip = "tooltip[%f,%f;%f,%f;%s]",
button = "button[%f,%f;%f,%f;%s;%s]",
item_image = "item_image[%f,%f;%f,%f;%s]",
hypertext = "hypertext[%f,%f;%f,%f;%s;%s]",
bg9 = "background9[%f,%f;%f,%f;%s;false;%u]",
scrollbar = "scrollbar[%f,%f;%f,%f;%s;%s;%u]",
model = "model[%f,%f;%f,%f;%s;%s;%s;%s;%s;%s;%s]",
image_button = "image_button[%f,%f;%f,%f;%s;%s;%s]",
animated_image = "animated_image[%f,%f;%f,%f;;%s;%u;%u]",
item_image_button = "item_image_button[%f,%f;%f,%f;%s;%s;%s]",
}
return PNG, styles, fs_elements

View File

@ -0,0 +1,251 @@
-- ****************************************************************************
-- Funnctions and Variables from i3 init.lua
local modpath = core.get_modpath "i3"
local maxn, sort, concat, copy, insert, remove, indexof =
table.maxn, table.sort, table.concat, table.copy,
table.insert, table.remove, table.indexof
local sprintf, find, gmatch, match, sub, split, upper, lower =
string.format, string.find, string.gmatch, string.match,
string.sub, string.split, string.upper, string.lower
local PNG, styles, fs_elements = loadfile(modpath .. "/etc/styles.lua")()
local ESC = core.formspec_escape
local S = core.get_translator "i3"
local ES = function(...)
return ESC(S(...))
end
local function fmt(elem, ...)
if not fs_elements[elem] then
return sprintf(elem, ...)
end
return sprintf(fs_elements[elem], ...)
end
local function add_subtitle(fs, name, y, ctn_len, font_size, sep, label)
fs(fmt("style[%s;font=bold;font_size=%u]", name, font_size))
fs("button", 0, y, ctn_len, 0.5, name, ESC(label))
if sep then
fs("image", 0, y + 0.55, ctn_len, 0.035, PNG.bar)
end
end
-- ****************************************************************************
-- Function to get detail info aout texture
-- Forked from skinsdb mod
local function get_skin_info_formspec(skin, xoffset, yoffset)
local texture = skin:get_texture()
local m_name = skin:get_meta_string("name")
local m_author = skin:get_meta_string("author")
local m_license = skin:get_meta_string("license")
local m_format = skin:get_meta("format")
-- overview page
local raw_size = m_format == "1.8" and "2,2" or "2,1"
--local lxoffs = 0.8 + xoffset
local cxoffs = 2 + xoffset
local rxoffs = 2 + xoffset
local formspec = "" -- = "image["..lxoffs..","..0.6 + yoffset..";1,2;"..minetest.formspec_escape(skin:get_preview()).."]"
if texture then
formspec = formspec.."label["..rxoffs..","..2 + yoffset..";"..S("Raw texture")..":]"
.."image["..1 + rxoffs..","..2.5 + yoffset..";"..raw_size..";"..texture.."]"
end
if m_name ~= "" then
formspec = formspec.."label["..cxoffs..","..0.5 + yoffset..";"..S("Name")..": "..minetest.formspec_escape(m_name).."]"
end
if m_author ~= "" then
formspec = formspec.."label["..cxoffs..","..1 + yoffset..";"..S("Author")..": "..minetest.formspec_escape(m_author).."]"
end
if m_license ~= "" then
formspec = formspec.."label["..cxoffs..","..1.5 + yoffset..";"..S("License")..": "..minetest.formspec_escape(m_license).."]"
end
return formspec
end
-- skin images and pages
local function get_skin_selection_formspec(player, context)
context.skins_list = skins.get_skinlist_for_player(player:get_player_name())
context.total_pages = 1
local xoffs = 0.8
local yoffs = 6.5
local xspc = 1.1
local yspc = 2.1
local skinwidth = 1
local skinheight = 2
local xscale = 1
local btn_y = yoffs + 4.5
local drop_y = yoffs + 4.5
local btn_width = 0.35
local btn_heigh = 0.35
local droppos = xoffs + 1.3
local droplen = 6.2
local btn_left = droppos - btn_width
local btn_right = droppos + droplen
local maxdisp = 16
local ctrls_height = 0.4
for i, skin in ipairs(context.skins_list ) do
local page = math.floor((i-1) / maxdisp)+1
skin:set_meta("inv_page", page)
skin:set_meta("inv_page_index", (i-1)%maxdisp+1)
context.total_pages = page
end
context.skins_page = context.skins_page or skins.get_player_skin(player):get_meta("inv_page") or 1
context.dropdown_values = nil
local page = context.skins_page
local formspec = ""
for i = (page-1)*maxdisp+1, page*maxdisp do
local skin = context.skins_list[i]
if not skin then
break
end
local index_p = skin:get_meta("inv_page_index")
local x = ((index_p-1) % 8) * xspc + xoffs
local y
if index_p > 8 then
y = yoffs + yspc
else
y = yoffs
end
formspec = formspec..
string.format("image_button[%f,%f;%f,%f;%s;skins_set$%i;]",
x, y, skinwidth, skinheight,
minetest.formspec_escape(skin:get_preview()), i)..
"tooltip[skins_set$"..i..";"..minetest.formspec_escape(skin:get_meta_string("name")).."]"
end
if context.total_pages > 1 then
local page_prev = page - 1
local page_next = page + 1
if page_prev < 1 then
page_prev = context.total_pages
end
if page_next > context.total_pages then
page_next = 1
end
local page_list = ""
context.dropdown_values = {}
for pg=1, context.total_pages do
local pagename = S("Page").." "..pg.."/"..context.total_pages
context.dropdown_values[pagename] = pg
if pg > 1 then page_list = page_list.."," end
page_list = page_list..pagename
end
formspec = formspec..
string.format("image_button[%f,%f;%f,%f;%s;skins_page$%i;]",
btn_left, btn_y, btn_width, btn_heigh, PNG.prev, page_prev)..
string.format("image_button[%f,%f;%f,%f;%s;skins_page$%i;]",
btn_right, btn_y, btn_width, btn_heigh, PNG.next, page_next)..
string.format("dropdown[%f,%f;%f,%f;skins_selpg;%s;%i]",
droppos, drop_y, droplen, ctrls_height, page_list, page)
end
return formspec
end
-- ****************************************************************************
-- i3 Tab definition
i3.new_tab {
name = "Skins",
description = "Skins",
image = "i3_skin.png",
formspec = function(player, data, fs)
--fs("label[3,1;Test 1]")
local name = player:get_player_name()
local ctn_len, ctn_hgt = 5.7, 6.3
local yextra = 1
local yoffset = 0
local xpos = 5
local _skins = skins.get_skinlist_for_player(name)
local skin_name = skins.get_player_skin(player).name
local sks, id = {}, 1
local props = player:get_properties()
for i, skin in ipairs(_skins) do
if skin.name == skin_name then
id = i
end
sks[#sks + 1] = skin.name
end
sks = concat(sks, ","):gsub(";", "")
add_subtitle(fs, "player_name", 0, ctn_len + 4.5, 22, true, ESC(name))
if props.mesh ~= "" then
local anim = player:get_local_animation()
local armor_skin = __3darmor or __skinsdb
local t = {}
for _, v in ipairs(props.textures) do
t[#t + 1] = ESC(v):gsub(",", "!")
end
local textures = concat(t, ","):gsub("!", ",")
local skinxoffset = 1.3
--fs("style[player_model;bgcolor=black]")
fs("model", skinxoffset, 0.2, armor_skin and 4 or 3.4, ctn_hgt,
"player_model", props.mesh, textures, "0,-150", "false", "false",
fmt("%u,%u%s", anim.x, anim.y, data.fs_version >= 5 and ";30" or ""))
else
local size = 2.5
fs("image", 0.7, 0.2, size, size * props.visual_size.y, props.textures[1])
end
fs("label", xpos, yextra, fmt("%s:", ES"Select a skin"))
fs(fmt("dropdown[%f,%f;4,0.6;skins;%s;%u;true]", xpos, yextra + 0.2, sks, id))
local skin = skins.get_player_skin(player)
local formspec = get_skin_info_formspec(skin, 3, 2)
fs(formspec)
--core.log("fs skins: "..dump(formspec))
local context = skins.get_formspec_context(player)
local formspec = get_skin_selection_formspec(player, context)
--core.log("skins context: "..dump(context))
--core.log("fs skins: "..dump(formspec))
fs(formspec)
end,
-- click button handlers - giving fields
fields = function(player, data, fields)
local name = player:get_player_name()
local sb_inv = fields.scrbar_inv
--core.log("fields: "..dump(fields))
-- set skin with dropdown from original i3 inventory
if fields.skins then
local id = tonumber(fields.skins)
local _skins = skins.get_skinlist_for_player(name)
skins.set_player_skin(player, _skins[id])
end
-- set skin with skinddb image an page change
local context = skins.get_formspec_context(player)
local action = skins.on_skin_selection_receive_fields(player, context, fields)
-- update formspec
return i3.set_fs(player)
end,
}
-- ****************************************************************************

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,2 +1,15 @@
# The progressive mode shows recipes you can craft from items you ever had in your inventory.
i3_progressive_mode (Learn crafting recipes progressively) bool false
i3_progressive_mode (Learn crafting recipes progressively) bool true
# Regroup the items of the same type in the item list.
i3_item_compression (Regroup items of the same type) bool true
# ------------ NEW SETTINGS ------------
# not in original i3 available
# Show trash only in creative mode, or with creative privileges
i3_no_trash_in_survival (Trash is available only in creative) bool true
# For skin choice use tab instead of inventory dropdown only
i3_skinsdb_tab (Use tab for skins) bool true

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

@ -8,7 +8,7 @@ local use_cmi = minetest.global_exists("cmi")
mobs = {
mod = "redo",
version = "20210613",
version = "20210614",
intllib = S,
invis = minetest.global_exists("invisibility") and invisibility or {}
}
@ -1235,18 +1235,21 @@ function mob_class:do_jump()
local blocked = minetest.registered_nodes[nodt.name].walkable
--print("standing on:", self.standing_on, pos.y - 0.25)
--print("in front:", nod.name, pos.y + 0.5)
--print("in front above:", nodt.name, pos.y + 1.5)
-- are we facing a fence or wall
if nod.name:find("fence") or nod.name:find("gate") or nod.name:find("wall") then
self.facing_fence = true
end
-- jump if standing on solid node (not snow) and not blocked above
--[[
print("on: " .. self.standing_on
.. ", front: " .. nod.name
.. ", front above: " .. nodt.name
.. ", blocked: " .. (blocked and "yes" or "no")
.. ", fence: " .. (self.facing_fence and "yes" or "no")
)
]]
-- jump if standing on solid node (not snow) and not blocked
if (self.walk_chance == 0 or minetest.registered_items[nod.name].walkable)
and not blocked and nod.name ~= node_snow then
and not blocked and not self.facing_fence and nod.name ~= node_snow then
local v = self.object:get_velocity()

View File

@ -0,0 +1,7 @@
Copyright 2019 - 2021 Lars Mueller alias LMD or appguru(eu)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -27,6 +27,15 @@ logfile:init()
assert(table.equals(logfile.root, {[{a = 1}] = {b = 2, c = 3}}))
```
Both strings and tables are stored in a reference table. Unused strings won't be garbage collected as Lua doesn't allow marking them as weak references.
This means that setting lots of temporary strings will waste memory until you call `:rewrite()` on the log file. An alternative is to set the third parameter, `reference_strings`, to `false` (default value is `true`):
```lua
persistence.lua_log_file.new(mod.get_resource"logfile.test.lua", {}, false)
```
This will prevent strings from being referenced, possibly bloating file size, but saving memory.
### Bluon
Binary Lua object notation. **Experimental.** Handling of subnormal numbers (very small floats) may be broken.
@ -242,6 +251,12 @@ A schematic format with support for metadata and baked light data. **Experimenta
## Release Notes
### `rolling-70`
* Fixes module environments once and for all
* Fixes vector aliases
* Presumably boosts performance
### `rolling-69`
* Fixes various things, **most importantly modules indexing the global table**

View File

@ -1,7 +1,11 @@
local class = getfenv(1)
local metatable = {__index = function(_self, key)
return rawget(class, key)
end}
-- Localize globals
local assert, error, math, modlib, next, pairs, setmetatable, table = assert, error, math, modlib, next, pairs, setmetatable, table
-- Set environment
local _ENV = {}
setfenv(1, _ENV)
local metatable = {__index = _ENV}
--! experimental
--+ Reads a single BB3D chunk from a stream
@ -360,4 +364,7 @@ function get_animated_bone_properties(self, keyframe, interpolate)
end
get_props(self.node)
return bone_properties
end
end
-- Export environment
return _ENV

View File

@ -1,3 +1,11 @@
-- Localize globals
local assert, math_huge, math_frexp, math_floor
= assert, math.huge, math.frexp, math.floor
-- Set environment
local _ENV = {}
setfenv(1, _ENV)
-- All little endian
--+ Reads doubles (f64) or floats (f32)
@ -23,7 +31,7 @@ function read_float(read_byte, double)
mantissa = (mantissa + byte_2) / 0x80
if exponent == 0xFF then
if mantissa == 0 then
return sign * math.huge
return sign * math_huge
end
-- Differentiating quiet and signalling nan is not possible in Lua, hence we don't have to do it
-- HACK ((0/0)^1) yields nan, 0/0 yields -nan
@ -60,7 +68,7 @@ end
function write_uint(write_byte, uint, bytes)
for _ = 1, bytes do
write_byte(uint % 0x100)
uint = math.floor(uint / 0x100)
uint = math_floor(uint / 0x100)
end
assert(uint == 0)
end
@ -73,16 +81,16 @@ function write_float(write_byte, number, on_write, double)
number = -number
sign = 0x80
end
local mantissa, exponent = math.frexp(number)
local mantissa, exponent = math_frexp(number)
exponent = exponent + 127
if exponent > 1 then
-- TODO ensure this deals properly with subnormal numbers
mantissa = mantissa * 2 - 1
exponent = exponent - 1
end
local sign_byte = sign + math.floor(exponent / 2)
local sign_byte = sign + math_floor(exponent / 2)
mantissa = mantissa * 0x80
local exponent_byte = (exponent % 2) * 0x80 + math.floor(mantissa)
local exponent_byte = (exponent % 2) * 0x80 + math_floor(mantissa)
mantissa = mantissa % 1
local mantissa_bytes = {}
-- TODO ensure this check is proper
@ -95,7 +103,7 @@ function write_float(write_byte, number, on_write, double)
local len = double and 6 or 2
for index = len, 1, -1 do
mantissa = mantissa * 0x100
mantissa_bytes[index] = math.floor(mantissa)
mantissa_bytes[index] = math_floor(mantissa)
mantissa = mantissa % 1
end
assert(mantissa == 0)
@ -112,4 +120,7 @@ end
function write_double(write_byte, number)
return write_float(write_byte, number, nil, true)
end
end
-- Export environment
return _ENV

View File

@ -1,12 +1,17 @@
-- Localize globals
local assert, error, ipairs, math_floor, math_huge, modlib, next, pairs, setmetatable, string, table_insert, type, unpack
= assert, error, ipairs, math.floor, math.huge, modlib, next, pairs, setmetatable, string, table.insert, type, unpack
-- Set environment
local _ENV = {}
setfenv(1, _ENV)
--! experimental
local bluon = getfenv(1)
local no_op = modlib.func.no_op
local write_float = modlib.binary.write_float
local metatable = {__index = function(_self, key)
return rawget(bluon, key)
end}
local metatable = {__index = _ENV}
function new(self)
return setmetatable(self or {}, metatable)
@ -57,8 +62,8 @@ local constants = {
[0] = "\2",
-- not possible as table entry as Lua doesn't allow +/-nan as table key
-- [0/0] = "\3",
[math.huge] = "\4",
[-math.huge] = "\5",
[math_huge] = "\4",
[-math_huge] = "\5",
[""] = "\20"
}
@ -293,18 +298,18 @@ function read(self, stream)
end
if type <= type_ranges.string then
local string = stream_read(uint(type - type_ranges.number))
table.insert(references, string)
table_insert(references, string)
return string
end
if type <= type_ranges.table then
type = type - type_ranges.string - 1
local tab = {}
table.insert(references, tab)
table_insert(references, tab)
if type == 0 then
return tab
end
local list_len = uint(type % 5)
local kv_len = uint(math.floor(type / 5))
local kv_len = uint(math_floor(type / 5))
for index = 1, list_len do
tab[index] = _read(stream_read(1))
end
@ -323,4 +328,7 @@ function read(self, stream)
return
end
return _read(type)
end
end
-- Export environment
return _ENV

View File

@ -1,3 +1,10 @@
-- Localize globals
local assert, dump, error, ipairs, minetest, modlib, pairs, pcall, table, tonumber, type = assert, dump, error, ipairs, minetest, modlib, pairs, pcall, table, tonumber, type
-- Set environment
local _ENV = {}
setfenv(1, _ENV)
-- not deprecated
function build_tree(dict)
local tree = {}
@ -293,4 +300,7 @@ function check_constraints(value, constraints)
error(possible_errors)
end
end
end
end
-- Export environment
return _ENV

View File

@ -1,3 +1,10 @@
-- Localize globals
local _G, debug, getfenv, table, tostring = _G, debug, getfenv, table, tostring
-- Set environment
local _ENV = {}
setfenv(1, _ENV)
function variables(stacklevel)
stacklevel = (stacklevel or 1) + 1
local locals = {}
@ -40,4 +47,7 @@ function stack(stacklevel)
stacklevel = stacklevel + 1
end
return stack
end
end
-- Export environment
return _ENV

View File

@ -1,3 +1,10 @@
-- Localize globals
local io, minetest, modlib, string = io, minetest, modlib, string
-- Set environment
local _ENV = {}
setfenv(1, _ENV)
function read(filename)
local file = io.open(filename, "r")
if file == nil then return nil end
@ -104,4 +111,7 @@ end
function process_bridge_start(name, command, os_execute)
local bridge = process_bridges[name]
os_execute(string.format(command, bridge.output, bridge.input, bridge.logs))
end
end
-- Export environment
return _ENV

View File

@ -1,3 +1,10 @@
-- Localize globals
local error, modlib, unpack = error, modlib, unpack
-- Set environment
local _ENV = {}
setfenv(1, _ENV)
no_op = function() end
function curry(func, ...)
@ -10,7 +17,12 @@ function curry_tail(func, ...)
return function(...) return func(unpack(modlib.table.concat({...}, args))) end
end
function call(...)
function curry_full(func, ...)
local args = { ... }
return function() return func(unpack(args)) end
end
function args(...)
local args = { ... }
return function(func) return func(unpack(args)) end
end
@ -22,6 +34,31 @@ function values(...)
return function() return unpack(args) end
end
-- Equivalent to `for x, y, z in iterator(...) do callback(x, y, z) end`
function iterate(callback, iterator, ...)
local function _iterate(iterable, state, ...)
local function loop(...)
if ... == nil then return end
callback(...)
return loop(iterable(state, ...))
end
return loop(iterable(state, ...))
end
return _iterate(iterator(...))
end
-- Does not use select magic, stops at the first nil value
function aggregate(binary_func, total, ...)
if total == nil then return end
local function _aggregate(value, ...)
if value == nil then return end
total = binary_func(total, value)
return _aggregate(...)
end
_aggregate(...)
return total
end
function override_chain(func, override)
return function(...)
func(...)
@ -110,4 +147,7 @@ end
function or_(a, b)
return a or b
end
end
-- Export environment
return _ENV

View File

@ -1,4 +1,11 @@
local metatable = {__index = getfenv(1)}
-- Localize globals
local math, setmetatable, table = math, setmetatable, table
-- Set environment
local _ENV = {}
setfenv(1, _ENV)
local metatable = {__index = _ENV}
function less_than(a, b) return a < b end
@ -47,4 +54,7 @@ function pop(self)
end
heapify(1)
return value
end
end
-- Export environment
return _ENV

View File

@ -1,5 +1,3 @@
local rawget, rawset = rawget, rawset
-- Lua version check
if _VERSION then
if _VERSION < "Lua 5" then
@ -52,6 +50,7 @@ for _, file in pairs{
"ranked_set",
"binary",
"b3d",
"luon",
"bluon",
"persistence",
"debug"
@ -59,16 +58,8 @@ for _, file in pairs{
modules[file] = file
end
if minetest then
modules.minetest = {
"misc",
"collisionboxes",
"liquid",
"raycast",
"wielditem_change",
"colorspec",
"schematic"
}
for _, file in pairs{
"minetest",
"log",
"player",
-- deprecated
@ -77,12 +68,31 @@ if minetest then
modules[file] = file
end
end
-- aliases
modules.string = "text"
modules.number = "math"
local load_module, get_resource, loadfile_exports
local parent_dir
if not minetest then
local init_path = arg and arg[0]
parent_dir = init_path and init_path:match"^.[/\\]" or ""
end
-- only used if Minetest is available
local function get_resource(modname, resource, ...)
if not resource then
resource = modname
modname = minetest.get_current_modname()
end
return table.concat({minetest.get_modpath(modname), resource, ...}, modlib.dir_delim)
end
local rawget, rawset = rawget, rawset
modlib = setmetatable({
-- TODO bump on release
version = 69,
version = 70,
modname = minetest and minetest.get_current_modname(),
-- TODO
dir_delim = rawget(_G, "DIR_DELIM") or "/",
_RG = setmetatable({}, {
__index = function(_, index)
@ -98,66 +108,31 @@ modlib = setmetatable({
end
end
}, {
__index = function(self, module_name)
local files = modules[module_name]
local environment
if type(files) == "string" then
environment = load_module(files)
elseif files then
environment = loadfile_exports(get_resource(self.modname, module_name, files[1] .. ".lua"))
for index = 2, #files do
self.mod.include_env(get_resource(self.modname, module_name, files[index] .. ".lua"), environment)
end
else
__index = function(self, module_name_or_alias)
local module_name = modules[module_name_or_alias]
if not module_name then
-- module not available, return nil
return
end
local module = {}
for key, value in pairs(environment) do
-- Shallow copy. Doesn't use `modlib.table.shallowcopy` as that is part of a module, too.
module[key] = value
local environment
if module_name ~= module_name_or_alias then
-- alias handling
environment = self[module_name]
else
environment = dofile(minetest
and get_resource(self.modname, module_name .. ".lua")
or (parent_dir .. module_name .. ".lua"))
end
self[module_name] = module
return module
self[module_name_or_alias] = environment
return environment
end
})
function get_resource(modname, resource, ...)
if not resource then
resource = modname
modname = minetest.get_current_modname()
end
return table.concat({minetest.get_modpath(modname), resource, ...}, modlib.dir_delim)
end
function loadfile_exports(filename)
local env = setmetatable({}, {__index = _G})
local file = assert(loadfile(filename))
setfenv(file, env)
file()
return env
end
local parent_dir
if not minetest then
local init_path = arg and arg[0]
parent_dir = init_path and init_path:match"^.[/\\]" or ""
end
function load_module(module_name)
local file = module_name .. ".lua"
return loadfile_exports(minetest and get_resource(modlib.modname, file) or (parent_dir .. file))
end
modlib.mod = minetest and loadfile_exports(get_resource(modlib.modname, "mod.lua"))
-- Aliases
modlib.string = modlib.text
modlib.number = modlib.math
modlib.mod = minetest and dofile(get_resource(modlib.modname, "mod.lua"))
if minetest then
modlib.conf.build_setting_tree()
modlib.mod.get_resource = get_resource
modlib.mod.loadfile_exports = loadfile_exports
end
_ml = modlib
@ -166,4 +141,5 @@ _ml = modlib
--modlib.mod.include"test.lua"
]]
-- TODO verify localizations suffice
return modlib

View File

@ -1,7 +1,11 @@
local class = getfenv(1)
local metatable = {__index = function(_self, key)
return rawget(class, key)
end}
-- Localize globals
local assert, math, modlib, setmetatable, table, unpack = assert, math, modlib, setmetatable, table, unpack
-- Set environment
local _ENV = {}
setfenv(1, _ENV)
local metatable = {__index = _ENV}
distance = modlib.vector.distance
@ -54,4 +58,7 @@ function get_nearest_neighbor(self, vector)
return nearest_neighbor, min_distance
end
-- TODO insertion & deletion + rebalancing
-- TODO insertion & deletion + rebalancing
-- Export environment
return _ENV

View File

@ -1,3 +1,10 @@
-- Localize globals
local ipairs, minetest, modlib, os, pairs, table = ipairs, minetest, modlib, os, pairs, table
-- Set environment
local _ENV = {}
setfenv(1, _ENV)
-- Log helpers - write to log, force writing to file
minetest.mkdir(minetest.get_worldpath() .. "/logs")
channels = {}
@ -74,3 +81,7 @@ minetest.register_on_shutdown(
write_all_to_file()
end
)
-- Export environment
return _ENV

View File

@ -0,0 +1,165 @@
local assert, next, pairs, pcall, error, type, table_insert, table_concat, string_format, string_match, setfenv, math_huge, loadfile, loadstring
= assert, next, pairs, pcall, error, type, table.insert, table.concat, string.format, string.match, setfenv, math.huge, loadfile, loadstring
local count_values = modlib.table.count_values
-- Build a table with the succeeding character from A-Z
local succ = {}
for char = ("A"):byte(), ("Z"):byte() - 1 do
succ[string.char(char)] = string.char(char + 1)
end
local function quote(string)
return string_format("%q", string)
end
local _ENV = {}
setfenv(1, _ENV)
function write(object, write)
local reference = {"A"}
local function increment_reference(place)
if not reference[place] then
reference[place] = "B"
elseif reference[place] == "Z" then
reference[place] = "A"
return increment_reference(place + 1)
else
reference[place] = succ[reference[place]]
end
end
local references = {}
local to_fill = {}
for value, count in pairs(count_values(object)) do
local type_ = type(value)
if count >= 2 and ((type_ == "string" and #reference + 2 >= #value) or type_ == "table") then
local ref = table_concat(reference)
write(ref)
write"="
write(type_ == "table" and "{}" or quote(value))
write";"
references[value] = ref
if type_ == "table" then
to_fill[value] = true
end
increment_reference(1)
end
end
local function is_short_key(key)
return not references[key] and type(key) == "string" and string_match(key, "^[%a_][%a%d_]*$")
end
local function dump(value)
-- Primitive types
if value == nil then
return write"nil"
end
if value == true then
return write"true"
end
if value == false then
return write"false"
end
local type_ = type(value)
if type_ == "number" then
return write(string_format("%.17g", value))
end
-- Reference types: table and string
local ref = references[value]
if ref then
-- Referenced
if not to_fill[value] then
return write(ref)
end
-- Fill table
to_fill[value] = false
for k, v in pairs(value) do
write(ref)
if is_short_key(k) then
write"."
write(k)
else
write"["
dump(k)
write"]"
end
write"="
dump(v)
write";"
end
elseif type_ == "string" then
return write(quote(value))
elseif type_ == "table" then
local first = true
write"{"
local len = #value
for i = 1, len do
if not first then write";" end
dump(value[i])
first = false
end
for k, v in next, value do
if type(k) ~= "number" or k % 1 ~= 0 or k < 1 or k > len then
if not first then write";" end
if is_short_key(k) then
write(k)
else
write"["
dump(k)
write"]"
end
write"="
dump(v)
first = false
end
end
write"}"
else
error("unsupported type: " .. type_)
end
end
local fill_root = to_fill[object]
if fill_root then
-- Root table is circular, must return by named reference
dump(object)
write"return "
write(references[object])
else
-- Root table is not circular, can directly start writing
write"return "
dump(object)
end
end
function write_file(object, file)
return write(object, function(text)
file:write(text)
end)
end
function write_string(object)
local rope = {}
write(object, function(text)
table_insert(rope, text)
end)
return table_concat(rope)
end
function read(...)
local read = assert(...)
-- math.huge is serialized to inf, 0/0 is serialized to -nan
setfenv(read, {inf = math_huge, nan = 0/0})
local success, value_or_err = pcall(read)
if success then
return value_or_err
end
return nil, value_or_err
end
function read_file(path)
return read(loadfile(path))
end
function read_string(string)
return read(loadstring(string))
end
return _ENV

View File

@ -1,3 +1,10 @@
-- Localize globals
local math, minetest, modlib, os, string, table = math, minetest, modlib, os, string, table
-- Set environment
local _ENV = {}
setfenv(1, _ENV)
-- Make random random
math.randomseed(minetest and minetest.get_us_time() or os.time() + os.clock())
for _ = 1, 100 do math.random() end
@ -68,4 +75,7 @@ function fround(number)
return sign * math.huge
end
return sign * powexp * (leading - mantissa / 0x800000)
end
end
-- Export environment
return _ENV

View File

@ -0,0 +1,12 @@
local _ENV = setmetatable({}, {__index = _G})
local function load(filename)
assert(loadfile(modlib.mod.get_resource(modlib.modname, "minetest", filename .. ".lua")))(_ENV)
end
load"misc"
load"collisionboxes"
load"liquid"
load"raycast"
load"wielditem_change"
load"colorspec"
load"schematic"
return _ENV

View File

@ -1,3 +1,10 @@
-- Localize globals
local assert, ipairs, math, minetest, pairs, table, type, vector = assert, ipairs, math, minetest, pairs, table, type, vector
-- Set environment
local _ENV = ...
setfenv(1, _ENV)
-- Minetest allows shorthand collisionbox = {...} instead of {{...}}
local function get_collisionboxes(box_or_boxes)
return type(box_or_boxes[1]) == "number" and {box_or_boxes} or box_or_boxes

View File

@ -1,3 +1,10 @@
-- Localize globals
local assert, error, math, minetest, setmetatable, tonumber, type = assert, error, math, minetest, setmetatable, tonumber, type
-- Set environment
local _ENV = ...
setfenv(1, _ENV)
-- As in src/util/string.cpp
named_colors = {
aliceblue = 0xf0f8ff,
@ -178,7 +185,7 @@ function colorspec.from_string(string)
if number then
return colorspec.from_number(number * 0x100 + alpha)
end
local hex_text = string:match(hex)
local hex_text = string:match("^" .. hex .. "$")
local len, num = hex_text:len(), tonumber(hex_text, 16)
if len == 8 then
return colorspec.from_number(num)

View File

@ -1,3 +1,10 @@
-- Localize globals
local minetest, modlib, pairs = minetest, modlib, pairs
-- Set environment
local _ENV = ...
setfenv(1, _ENV)
liquid_level_max = 8
--+ Calculates the corner levels of a flowingliquid node
--> 4 corner levels from -0.5 to 0.5 as list of `modlib.vector`

View File

@ -1,3 +1,10 @@
-- Localize globals
local assert, minetest, modlib, next, pairs, string, table, type = assert, minetest, modlib, next, pairs, string, table, type
-- Set environment
local _ENV = ...
setfenv(1, _ENV)
max_wear = 2 ^ 16 - 1
function override(function_name, function_builder)
local func = minetest[function_name]

View File

@ -1,3 +1,10 @@
-- Localize globals
local assert, math, minetest, modlib, pairs, setmetatable, vector = assert, math, minetest, modlib, pairs, setmetatable, vector
-- Set environment
local _ENV = ...
setfenv(1, _ENV)
--+ Raycast wrapper with proper flowingliquid intersections
function raycast(_pos1, _pos2, objects, liquids)
local raycast = minetest.raycast(_pos1, _pos2, objects, liquids)

View File

@ -1,3 +1,10 @@
-- Localize globals
local VoxelArea, assert, error, io, ipairs, math, minetest, modlib, next, pairs, setmetatable, table, vector = VoxelArea, assert, error, io, ipairs, math, minetest, modlib, next, pairs, setmetatable, table, vector
-- Set environment
local _ENV = ...
setfenv(1, _ENV)
schematic = {}
local metatable = {__index = schematic}

View File

@ -1,3 +1,10 @@
-- Localize globals
local minetest, modlib, pairs, table = minetest, modlib, pairs, table
-- Set environment
local _ENV = ...
setfenv(1, _ENV)
players = {}
registered_on_wielditem_changes = {function(...)

View File

@ -1,3 +1,18 @@
-- Localize globals
local Settings, _G, assert, dofile, error, getmetatable, ipairs, loadfile, loadstring, minetest, modlib, pairs, rawget, rawset, setfenv, setmetatable, tonumber, type = Settings, _G, assert, dofile, error, getmetatable, ipairs, loadfile, loadstring, minetest, modlib, pairs, rawget, rawset, setfenv, setmetatable, tonumber, type
-- Set environment
local _ENV = {}
setfenv(1, _ENV)
function loadfile_exports(filename)
local env = setmetatable({}, {__index = _G})
local file = assert(loadfile(filename))
setfenv(file, env)
file()
return env
end
-- get resource + dofile
function include(modname, file)
if not file then
@ -128,4 +143,7 @@ function configuration(modname)
return schema:load({}, {error_message = true})
end
return conf
end
end
-- Export environment
return _ENV

View File

@ -1,15 +1,35 @@
lua_log_file = {}
-- Localize globals
local assert, error, io, ipairs, loadfile, math, minetest, modlib, pairs, setfenv, setmetatable, table, type = assert, error, io, ipairs, loadfile, math, minetest, modlib, pairs, setfenv, setmetatable, table, type
-- Set environment
local _ENV = {}
setfenv(1, _ENV)
lua_log_file = {
-- default value
reference_strings = true
}
local files = {}
local metatable = {__index = lua_log_file}
function lua_log_file.new(file_path, root)
local self = setmetatable({file_path = assert(file_path), root = root}, metatable)
function lua_log_file.new(file_path, root, reference_strings)
local self = setmetatable({
file_path = assert(file_path),
root = root,
reference_strings = reference_strings
}, metatable)
if minetest then
files[self] = true
end
return self
end
local function set_references(self, table)
-- Weak table keys to allow the collection of dead reference tables
-- TODO garbage collect strings in the references table
self.references = setmetatable(table, {__mode = "k"})
end
function lua_log_file:load()
-- Bytecode is blocked by the engine
local read = assert(loadfile(self.file_path))
@ -20,7 +40,7 @@ function lua_log_file:load()
env.R = env.R or {{}}
self.reference_count = #env.R
self.root = env.R[1]
self.references = modlib.table.flip(env.R)
set_references(self, {})
end
function lua_log_file:open()
@ -86,50 +106,51 @@ function lua_log_file:_dump(value, is_key)
end
reference = self.reference_count + 1
local key = "R[" .. reference .."]"
local formatted
local function create_reference()
self.reference_count = reference
self.references[value] = reference
end
if _type == "string" then
if is_key and value:len() <= key:len() and value:match"[%a_][%a%d_]*" then
local reference_strings = self.reference_strings
if is_key and ((not reference_strings) or value:len() <= key:len()) and value:match"^[%a_][%a%d_]*$" then
-- Short key
return value, true
end
formatted = ("%q"):format(value)
if formatted:len() <= key:len() then
local formatted = ("%q"):format(value)
if (not reference_strings) or formatted:len() <= key:len() then
-- Short string
return formatted
end
-- Use reference
create_reference()
self:log(key .. "=" .. formatted)
elseif _type == "table" then
-- Tables always need a reference before they are traversed to prevent infinite recursion
create_reference()
local entries = {}
for _, value in ipairs(value) do
table.insert(entries, self:_dump(value))
end
-- TODO traverse tables to determine whether this is actually needed
self:log(key .. "={}")
local tablelen = #value
for key, value in pairs(value) do
if type(key) ~= "number" or key % 1 ~= 0 or key < 1 or key > tablelen then
local dumped, short = self:_dump(key, true)
table.insert(entries, (short and dumped or ("[" .. dumped .. "]")) .. "=" .. self:_dump(value))
for k, v in pairs(value) do
if type(k) ~= "number" or k % 1 ~= 0 or k < 1 or k > tablelen then
local dumped, short = self:_dump(k, true)
self:log(key .. (short and ("." .. dumped) or ("[" .. dumped .. "]")) .. "=" .. self:_dump(v))
end
end
formatted = "{" .. table.concat(entries, ";") .. "}"
else
error("unsupported type: " .. _type)
end
self:log(key .. "=" .. formatted)
return key
end
function lua_log_file:set(table, key, value)
table[key] = value
if not self.references[table] then
error"orphan table"
end
if table[key] == value then
-- No change
return
end
table[key] = value
table = self:_dump(table)
local key, short_key = self:_dump(key, true)
self:log(table .. (short_key and ("." .. key) or ("[" .. key .. "]")) .. "=" .. self:_dump(value))
@ -140,7 +161,7 @@ function lua_log_file:set_root(key, value)
end
function lua_log_file:_write()
self.references = {}
set_references(self, {})
self.reference_count = 0
self:log"R={}"
self:_dump(self.root)
@ -158,4 +179,7 @@ function lua_log_file:rewrite()
end
self:_rewrite()
self:open()
end
end
-- Export environment
return _ENV

View File

@ -1,3 +1,10 @@
-- Localize globals
local ipairs, minetest, modlib, table = ipairs, minetest, modlib, table
-- Set environment
local _ENV = {}
setfenv(1, _ENV)
forbidden_names = {}
function register_forbidden_name(name) forbidden_names[name] = true end
@ -75,4 +82,7 @@ function datatable(table, default)
end)
minetest.register_on_leaveplayer(function(player) table[player:get_player_name()] = nil end)
return table
end
end
-- Export environment
return _ENV

View File

@ -1,3 +1,10 @@
-- Localize globals
local math, modlib, pairs, unpack, vector = math, modlib, pairs, unpack, vector
-- Set environment
local _ENV = {}
setfenv(1, _ENV)
-- TODO OOP, extend vector
function from_euler_rotation(rotation)
@ -126,4 +133,7 @@ function to_euler_rotation_irrlicht(self)
end
return vector.apply(_calc(), math.deg)
end
end
-- Export environment
return _ENV

View File

@ -1,7 +1,11 @@
local class = getfenv(1)
local metatable = {__index = function(_self, key)
return rawget(class, key)
end}
-- Localize globals
local assert, modlib, pairs, setmetatable, table = assert, modlib, pairs, setmetatable, table
-- Set environment
local _ENV = {}
setfenv(1, _ENV)
local metatable = {__index = _ENV}
comparator = modlib.table.default_comparator
@ -311,4 +315,7 @@ function get_by_rank(self, rank)
tree = right
end
until not tree
end
end
-- Export environment
return _ENV

View File

@ -1,7 +1,11 @@
local class = getfenv(1)
local metatable = {__index = function(_self, key)
return rawget(class, key)
end}
-- Localize globals
local assert, error, ipairs, math, minetest, modlib, pairs, setmetatable, table, tonumber, tostring, type = assert, error, ipairs, math, minetest, modlib, pairs, setmetatable, table, tonumber, tostring, type
-- Set environment
local _ENV = {}
setfenv(1, _ENV)
local metatable = {__index = _ENV}
function new(def)
-- TODO type inference, sanity checking etc.
@ -295,4 +299,7 @@ function load(self, override, params)
end
if self.func then self.func(override) end
return override
end
end
-- Export environment
return _ENV

View File

@ -1,3 +1,10 @@
-- Localize globals
local assert, error, ipairs, math, next, pairs, rawget, rawset, setmetatable, string, table, type = assert, error, ipairs, math, next, pairs, rawget, rawset, setmetatable, string, table, type
-- Set environment
local _ENV = {}
setfenv(1, _ENV)
-- Table helpers
function map_index(table, func)
@ -314,6 +321,43 @@ function foreach(table, func)
end
end
function deep_foreach_any(table, func)
local seen = {}
local function visit(value)
func(value)
if type(value) == "table" then
if seen[value] then return end
seen[value] = true
for k, v in pairs(value) do
visit(k)
visit(v)
end
end
end
visit(table)
end
-- Recursively counts occurences of values in a table
-- Also counts primitive values like boolean and number
-- Does not count NaN, because that doesn't work as a table index
function count_values(value)
local counts = {}
local function count_values_(value)
-- Ignore NaN
if value ~= value then return end
local count = counts[value]
counts[value] = (count or 0) + 1
if not count and type(value) == "table" then
for k, v in pairs(value) do
count_values_(k)
count_values_(v)
end
end
end
count_values_(value)
return counts
end
function foreach_value(table, func)
for _, v in pairs(table) do
func(v)
@ -586,4 +630,7 @@ function repetition(value, count)
table[index] = value
end
return table
end
end
-- Export environment
return _ENV

View File

@ -16,6 +16,17 @@ setfenv(1, setmetatable({}, {
end
}))
-- func
do
local tab = {a = 1, b = 2}
func.iterate(function(key, value)
assert(tab[key] == value)
tab[key] = nil
end, pairs, tab)
assert(next(tab) == nil)
assert(func.aggregate(func.add, 1, 2, 3) == 6)
end
-- string
assert(string.escape_magic_chars"%" == "%%")
@ -50,6 +61,24 @@ do
rope:write" "
rope:write"world"
assert(rope:to_text() == "hello world", rope:to_text())
tab = {a = 1, b = {2}}
tab[3] = tab
local contents = {
a = 1,
[1] = 1,
b = 1,
[tab.b] = 1,
[2] = 1,
[tab] = 1,
[3] = 1
}
table.deep_foreach_any(tab, function(content)
assert(contents[content], content)
contents[content] = 2
end)
for _, value in pairs(contents) do
assert(value == 2)
end
end
-- heap
@ -137,10 +166,41 @@ for _ = 1, 1000 do
assert(distance == min_distance)
end
local function serializer_test(assert_preserves)
-- TODO nan
for _, constant in pairs{true, false, huge, -huge} do
assert_preserves(constant)
end
-- Strings
for i = 1, 1000 do
assert_preserves(_G.table.concat(table.repetition(_G.string.char(i % 256), i)))
end
-- Numbers
for _ = 1, 1000 do
local int = random(-2^50, 2^50)
assert(int % 1 == 0)
assert_preserves(int)
assert_preserves((random() - 0.5) * 2^random(-20, 20))
end
-- Simple tables
assert_preserves{hello = "world", welt = "hallo"}
assert_preserves{"hello", "hello", "hello"}
local circular = {}
circular[circular] = circular
circular[1] = circular
assert_preserves(circular)
local mixed = {1, 2, 3}
mixed[mixed] = mixed
mixed.vec = {x = 1, y = 2, z = 3}
mixed.vec2 = modlib.table.copy(mixed.vec)
mixed.blah = "blah"
assert_preserves(mixed)
end
-- bluon
do
local bluon = bluon
local function assert_preserves(object)
serializer_test(function(object)
local rope = table.rope{}
local written, read, input
local _, err = pcall(function()
@ -157,25 +217,17 @@ do
written = written and text.hexdump(written),
err = err
})
end
for _, constant in pairs{true, false, huge, -huge} do
assert_preserves(constant)
end
for i = 1, 1000 do
assert_preserves(_G.table.concat(table.repetition(_G.string.char(i % 256), i)))
end
for _ = 1, 1000 do
local int = random(-2^50, 2^50)
assert(int % 1 == 0)
assert_preserves(int)
assert_preserves((random() - 0.5) * 2^random(-20, 20))
end
assert_preserves{hello = "world", welt = "hallo"}
assert_preserves{"hello", "hello", "hello"}
local a = {}
a[a] = a
a[1] = a
assert_preserves(a)
end)
end
-- luon
do
serializer_test(function(object)
local serialized = luon.write_string(object)
assert(table.equals_references(object, luon.read_string(serialized)), serialized)
end)
local nan = luon.read_string(luon.write_string(0/0))
assert(nan ~= nan)
end
if not _G.minetest then return end
@ -195,14 +247,30 @@ test_from_string("#333", 0x333333FF)
test_from_string("#694269", 0x694269FF)
test_from_string("#11223344", 0x11223344)
local logfile = persistence.lua_log_file.new(mod.get_resource"logfile.test.lua", {})
logfile:init()
logfile.root = {}
logfile:rewrite()
logfile:set_root({a = 1}, {b = 2, c = 3, d = _G.math.huge, e = -_G.math.huge})
logfile:close()
logfile:init()
assert(table.equals(logfile.root, {[{a = 1}] = {b = 2, c = 3, d = _G.math.huge, e = -_G.math.huge}}))
local function test_logfile(reference_strings)
local logfile = persistence.lua_log_file.new(mod.get_resource"logfile.test.lua", {}, reference_strings)
logfile:init()
logfile.root = {a_longer_string = "test"}
logfile:rewrite()
logfile:set_root({a = 1}, {b = 2, c = 3, d = _G.math.huge, e = -_G.math.huge})
local circular = {}
circular[circular] = circular
logfile:set_root(circular, circular)
logfile:close()
logfile:init()
assert(table.equals_references(logfile.root, {
a_longer_string = "test",
[{a = 1}] = {b = 2, c = 3, d = _G.math.huge, e = -_G.math.huge},
[circular] = circular,
}))
if not reference_strings then
for key in pairs(logfile.references) do
assert(type(key) ~= "string")
end
end
end
test_logfile(true)
test_logfile(false)
-- in-game tests & b3d testing
local tests = {

View File

@ -1,3 +1,10 @@
-- Localize globals
local math, modlib, pairs, setmetatable, string, table = math, modlib, pairs, setmetatable, string, table
-- Set environment
local _ENV = {}
setfenv(1, _ENV)
function upper_first(text) return text:sub(1, 1):upper() .. text:sub(2) end
function lower_first(text) return text:sub(1, 1):lower() .. text:sub(2) end
@ -163,4 +170,7 @@ function handle_ifdefs(code, vars)
end
table.insert(finalcode, string.sub(code, after_endif + 2))
return table.concat(finalcode, "")
end
end
-- Export environment
return _ENV

View File

@ -1,7 +1,11 @@
local class = getfenv(1)
local metatable = {__index = function(_self, key)
return rawget(class, key)
end}
-- Localize globals
local math, next, pairs, setmetatable, string, table, unpack = math, next, pairs, setmetatable, string, table, unpack
-- Set environment
local _ENV = {}
setfenv(1, _ENV)
local metatable = {__index = _ENV}
function new(table) return setmetatable(table or {}, metatable) end
@ -121,4 +125,7 @@ function find_longest(self, query, query_offset)
end
end
return last_leaf, leaf_pos
end
end
-- Export environment
return _ENV

View File

@ -1,5 +1,11 @@
-- Localize globals
local assert, math, modlib, pairs, rawset, setmetatable, unpack, vector = assert, math, modlib, pairs, rawset, setmetatable, unpack, vector
-- Set environment
local _ENV = {}
setfenv(1, _ENV)
local mt_vector = vector
local class = getfenv(1)
index_aliases = {
x = 1,
@ -16,10 +22,11 @@ metatable = {
if index ~= nil then
return table[index]
end
return rawget(class, key)
return _ENV[key]
end,
__newindex = function(table, key, value)
local index = letters[key]
-- TODO
local index = index_aliases[key]
if index ~= nil then
return rawset(table, index, value)
end
@ -183,6 +190,14 @@ function angle(v, w)
return math.acos(dot(v, w) / length(v) / length(w))
end
-- Uses Rodrigues' rotation formula
function rotate3(v, axis, angle)
local cos = math.cos(angle)
return multiply_scalar(v, cos)
+ multiply_scalar(cross3(axis, v), math.sin(angle))
+ multiply_scalar(axis, dot(axis, v) * (1 - cos))
end
function box_box_collision(diff, box, other_box)
for index, diff in pairs(diff) do
if box[index] + diff > other_box[index + 3] or other_box[index] > box[index + 3] + diff then
@ -222,4 +237,7 @@ function triangle_normal(triangle)
local point_1, point_2, point_3 = unpack(triangle)
local edge_1, edge_2 = subtract(point_2, point_1), subtract(point_3, point_1)
return normalize(cross3(edge_1, edge_2))
end
end
-- Export environment
return _ENV

View File

@ -21,7 +21,7 @@ petz.lamb_wool_regrow = function(self)
return
end
local food_count_wool = self.food_count_wool + 1
mobkit.remember(self, "food_count_wool", food_count_wool)
self.food_count_wool = mobkit.remember(self, "food_count_wool", food_count_wool)
if self.food_count_wool >= 5 then -- if lamb replaces 5x grass then it regrows wool
self.food_count_wool = mobkit.remember(self, "food_count_wool", 0)
self.shaved = mobkit.remember(self, "shaved", false)

View File

@ -36,7 +36,7 @@ mobs:register_mob("mobs_monster:lava_flan", {
{name = "mobs:lava_orb", chance = 15, min = 1, max = 1},
},
water_damage = 8,
lava_damage = 0,
lava_damage = -1,
fire_damage = 0,
light_damage = 0,
immune_to = {
@ -53,7 +53,7 @@ mobs:register_mob("mobs_monster:lava_flan", {
run_start = 20,
run_end = 28,
punch_start = 20,
punch_end = 28,
punch_end = 28
},
on_die = function(self, pos)
@ -174,9 +174,13 @@ minetest.register_tool(":mobs:pick_lava", {
inventory_image = "mobs_pick_lava.png",
tool_capabilities = {
full_punch_interval = 0.4,
max_drop_level=3,
groupcaps={
cracky = {times={[1]=1.80, [2]=0.80, [3]=0.40}, uses=40, maxlevel=3},
max_drop_level = 3,
groupcaps = {
cracky = {
times = {[1] = 1.80, [2] = 0.80, [3] = 0.40},
uses = 40,
maxlevel = 3
}
},
damage_groups = {fleshy = 6, fire = 1},
},
@ -189,7 +193,7 @@ minetest.register_craft({
recipe = {
{"mobs:lava_orb", "mobs:lava_orb", "mobs:lava_orb"},
{"", "default:obsidian_shard", ""},
{"", "default:obsidian_shard", ""},
{"", "default:obsidian_shard", ""}
}
})
@ -253,7 +257,7 @@ mobs:register_mob("mobs_monster:obsidian_flan", {
run_start = 20,
run_end = 28,
punch_start = 20,
punch_end = 28,
punch_end = 28
}
})
@ -296,9 +300,11 @@ mobs:register_arrow("mobs_monster:obsidian_arrow", {
local radius = 1
local def = minetest.registered_nodes[node]
if def then
node = { name = node }
node = {name = node}
end
if def and def.tiles and def.tiles[1] then
texture = def.tiles[1]
end
@ -325,7 +331,7 @@ mobs:register_arrow("mobs_monster:obsidian_arrow", {
texture = texture,
-- ^ only as fallback for clients without support for `node` parameter
node = node,
collisiondetection = true,
collisiondetection = true
})
minetest.set_node(pos, {name = "air"})

View File

@ -55,12 +55,14 @@ armor = {
crystal = "ethereal:crystal_ingot",
},
fire_nodes = {
{"nether:lava_source", 5, 8},
{"default:lava_source", 5, 8},
{"default:lava_flowing", 5, 8},
{"fire:basic_flame", 3, 4},
{"fire:permanent_flame", 3, 4},
{"ethereal:crystal_spike", 2, 1},
{"ethereal:fire_flower", 2, 1},
{"nether:lava_crust", 2, 1},
{"default:torch", 1, 1},
{"default:torch_ceiling", 1, 1},
{"default:torch_wall", 1, 1},
@ -671,3 +673,10 @@ armor.drop_armor = function(pos, stack)
end
end
end
--- Allows skin mod to be set manually.
--
-- Useful for skin mod forks that do not use the same name.
armor.set_skin_mod = function(mod)
armor.skin_mod = mod
end

View File

@ -69,12 +69,12 @@ end
minetest.register_on_joinplayer(function(player)
local name = player:get_player_name()
wieldview.wielded_item[name] = ""
minetest.after(0, function()
local pplayer = minetest.get_player_by_name(name)
if player then
minetest.after(0, function(pname)
local pplayer = minetest.get_player_by_name(pname)
if pplayer then
wieldview:update_wielded_item(pplayer)
end
end)
end, name)
end)
minetest.register_globalstep(function(dtime)

View File

@ -5,7 +5,7 @@ function skins.get_player_skin(player)
local meta = player:get_meta()
if meta:get("skinsdb:skin_key") then
-- Move player data prior July 2018 to mod storage
storage:set_string(player:get_player_name(), player:get_string("skinsdb:skin_key"))
storage:set_string(player:get_player_name(), meta:get_string("skinsdb:skin_key"))
meta:set_string("skinsdb:skin_key", "")
end
local skin = storage:get_string(player:get_player_name())

View File

@ -95,6 +95,8 @@ end)
-- default biomes deco
local deco = {
{"default:dry_dirt", dry_grass, {}},
{"default:dry_dirt_with_dry_grass", dry_grass, {}},
{"default:dirt_with_dry_grass", dry_grass, flowers},
{"default:sand", {}, {"default:dry_shrub", "", "", ""} },
{"default:desert_sand", {}, {"default:dry_shrub", "", "", ""} },

View File

@ -0,0 +1,3 @@
gui/i3/
Original: https://github.com/minetest-mods/i3
Fork: https://github.com/daretmavi/i3

View File

@ -1,35 +0,0 @@
diff --git a/init.lua b/init.lua
index 3bb0605..9f308b5 100644
--- a/init.lua
+++ b/init.lua
@@ -1893,9 +1893,13 @@ local function get_ctn_content(fs, data, player, yoffset, ctn_len, award_list, a
fs(fmt("list[current_player;craft;%f,%f;3,3;]", 0, yoffset + 1.45))
fs("image", 3.47, yoffset + 2.69, 0.85, 0.85, PNG.arrow)
- fs(fmt("list[current_player;craftpreview;%f,%f;1,1;]", 4.45, yoffset + 2.6),
- fmt("list[detached:i3_trash;main;%f,%f;1,1;]", 4.45, yoffset + 3.75))
- fs("image", 4.45, yoffset + 3.75, 1, 1, PNG.trash)
+ fs(fmt("list[current_player;craftpreview;%f,%f;1,1;]", 4.45, yoffset + 2.6))--,
+ -- fmt("list[detached:i3_trash;main;%f,%f;1,1;]", 4.45, yoffset + 3.75))
+ --fs("image", 4.45, yoffset + 3.75, 1, 1, PNG.trash)
+ if core.is_creative_enabled(name) then
+ fs(fmt("list[detached:i3_trash;main;%f,%f;1,1;]", 4.45, yoffset + 3.75))
+ fs("image", 4.45, yoffset + 3.75, 1, 1, PNG.trash)
+ end
local yextra = 5.5
@@ -2388,11 +2392,12 @@ local function get_inventory_fs(player, data, fs)
fs("scroll_container_end[]")
local btn = {
- {"trash", ES"Trash all items"},
+ --{"trash", ES"Trash all items"},
{"sort_az", ES"Sort items (A-Z)"},
{"sort_za", ES"Sort items (Z-A)"},
{"compress", ES"Compress items"},
}
+ if core.is_creative_enabled(name) then table.insert(btn, 1, {"trash", ES"Trash all items"}) end
for i, v in ipairs(btn) do
local btn_name, tooltip = unpack(v)

File diff suppressed because it is too large Load Diff

View File

@ -1,13 +0,0 @@
diff --git a/init.lua b/init.lua
index 0a953e7..619952d 100644
--- a/init.lua
+++ b/init.lua
@@ -12,7 +12,7 @@ local toolrepair
local tabs = {}
-local progressive_mode = core.settings:get_bool "i3_progressive_mode"
+local progressive_mode = core.settings:get_bool "i3_progressive_mode" and not(core.is_creative_enabled())
local damage_enabled = core.settings:get_bool "enable_damage"
local __3darmor, __skinsdb, __awards

Binary file not shown.

Before

Width:  |  Height:  |  Size: 274 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 274 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 274 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 362 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 442 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 326 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 339 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 310 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 315 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 311 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 333 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 333 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 431 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 318 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 313 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 335 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 360 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 377 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 369 B