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" \ "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/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" \ "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") "minetest_game/default:i3_size.patch")
# "gui/i3:progressive_creative.patch" "gui/i3:notrash.patch" \
#"mobs/mobs_mobs/goblins:goblins_nil.patch" #"mobs/mobs_mobs/goblins:goblins_nil.patch"
#MOD_PATCHES=( ) #MOD_PATCHES=( )

View File

@ -41,7 +41,7 @@ origin git@github.com:Sokomine/bell.git (fetch)
Mod: buildings/bell Mod: buildings/bell
origin https://github.com/Sokomine/cottages (fetch) 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 Mod: buildings/cottages
origin https://bitbucket.org/sorcerykid/doors.git (fetch) 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 Mod: environment/dynamic_liquid
origin https://notabug.org/tenplus1/farming (fetch) 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 Mod: flora/farming
origin https://github.com/minetest-mods/i3.git (fetch) origin https://github.com/daretmavi/i3.git (fetch)
* main dde5148 [origin/main] Show a tooltip for waypoints upstream https://github.com/minetest-mods/i3.git (fetch)
* main 4e39096 [origin/main] Merge pull request #4 from daretmavi/devtest
Mod: gui/i3 Mod: gui/i3
origin https://repo.or.cz/minetest_hbarmor.git (fetch) origin https://repo.or.cz/minetest_hbarmor.git (fetch)
@ -113,11 +114,11 @@ origin https://github.com/TheTermos/mobkit (fetch)
Mod: lib_api/mobkit Mod: lib_api/mobkit
origin https://notabug.org/tenplus1/mobs_redo (fetch) 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 Mod: lib_api/mobs_redo
origin https://github.com/appgurueu/modlib (fetch) 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 Mod: lib_api/modlib
origin git@github.com:runsy/rcbows.git (fetch) 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 Mod: mobs/mobs_mobs/mobs_ghost_redo
origin https://notabug.org/TenPlus1/mobs_monster.git (fetch) 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 Mod: mobs/mobs_mobs/mobs_monster
origin https://github.com/berengma/aerotest (fetch) origin https://github.com/berengma/aerotest (fetch)
@ -157,7 +158,7 @@ origin https://github.com/berengma/aerotest (fetch)
Mod: mobs/mobs_mobkit/aerotest Mod: mobs/mobs_mobkit/aerotest
origin https://github.com/runsy/petz (fetch) 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 Mod: mobs/mobs_mobkit/petz
origin https://github.com/berengma/water_life (fetch) 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 Mod: mobs/mobs_mobkit/water_life
origin https://github.com/minetest-mods/3d_armor (fetch) 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 Mod: player/3d_armor
origin https://github.com/appgurueu/character_anim (fetch) 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 Mod: player/hunger_ng
origin https://github.com/minetest-mods/skinsdb.git (fetch) 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 Mod: player/skinsdb
origin https://github.com/stujones11/wield3d.git (fetch) 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 Mod: player/wielded_light
origin https://notabug.org/TenPlus1/bonemeal.git (fetch) 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 Mod: tools/bonemeal
origin git@gitlab.com:daretmavi/bucket-lite.git (fetch) origin git@gitlab.com:daretmavi/bucket-lite.git (fetch)

View File

@ -9,6 +9,12 @@
local S = cottages.S 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 -- the hammer for the anvil
minetest.register_tool("cottages:hammer", { minetest.register_tool("cottages:hammer", {
description = S("Steel hammer for repairing tools on the anvil"), 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.')); S('The workpiece slot is for damaged tools only.'));
return 0; return 0;
end 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() return stack:get_count()
end, end,
@ -181,6 +193,14 @@ minetest.register_node("cottages:anvil", {
-- 65535 is max damage -- 65535 is max damage
local damage_state = 40-math.floor(input:get_wear()/1638); 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 tool_name = input:get_name();
local hud_image = ""; local hud_image = "";
if( tool_name if( tool_name

View File

@ -117,7 +117,7 @@ minetest.register_node("cottages:water_gen", {
paramtype = "light", paramtype = "light",
paramtype2 = "facedir", paramtype2 = "facedir",
is_ground_content = false, 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, sounds = cottages.sounds.wood,
node_box = { node_box = {
type = "fixed", type = "fixed",
@ -178,8 +178,14 @@ minetest.register_node("cottages:water_gen", {
can_dig = function(pos,player) can_dig = function(pos,player)
local meta = minetest.get_meta(pos); local meta = minetest.get_meta(pos);
local inv = meta:get_inventory() local inv = meta:get_inventory()
return inv:is_empty("main") and local bucket = meta:get_string("bucket")
default.can_interact_with_node(player, pos) 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, end,
-- no inventory move allowed -- no inventory move allowed
allow_metadata_inventory_move = function(pos, from_list, from_index, 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') cottages.switch_public(pos, formname, fields, sender, 'tree trunk well')
end, end,
-- punch to place and retrieve bucket -- 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 if( not( pos ) or not( node ) or not( puncher )) then
return return
end end
@ -223,7 +229,8 @@ minetest.register_node("cottages:water_gen", {
local owner = meta:get_string("owner") local owner = meta:get_string("owner")
local public = meta:get_string("public") local public = meta:get_string("public")
if( name ~= owner and public~="public") then 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 return
end end
@ -233,13 +240,18 @@ minetest.register_node("cottages:water_gen", {
-- is the well working on something? (either empty or full bucket) -- is the well working on something? (either empty or full bucket)
local bucket = meta:get_string("bucket") local bucket = meta:get_string("bucket")
-- there is a bucket loaded - either empty or full -- 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 if( not(pinv:room_for_item("main", bucket))) then
minetest.chat_send_player( puncher:get_player_name(), minetest.chat_send_player( puncher:get_player_name(),
S("Sorry. You have no room for the bucket. Please free some ".. S("Sorry. You have no room for the bucket. Please free some "..
"space in your inventory first!")) "space in your inventory first!"))
return return
end 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 end
-- remove the old entity (either a bucket will be placed now or a bucket taken) -- 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 if( wielded
and wielded:get_name() and wielded:get_name()
and wielded:get_name() == "bucket:bucket_empty") then 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 -- remember that we got a bucket loaded
meta:set_string("bucket", "bucket:bucket_empty") meta:set_string("bucket", "bucket:bucket_empty")
-- create the entity -- 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) minetest.after(cottages.water_fill_time, cottages.water_gen_fill_bucket, pos)
-- the bucket will only be filled if the water ran long enough -- the bucket will only be filled if the water ran long enough
meta:set_string("fillstarttime", tostring(minetest.get_us_time()/1000000)) 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; return;
end end
-- buckets can also be emptied here -- 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"}, tiles = {"farming_cocoa_1.png"},
paramtype = "light", paramtype = "light",
walkable = false, walkable = false,
drop = {
items = {
{items = {"farming:cocoa_beans 1"}, rarity = 2},
}
},
selection_box = { selection_box = {
type = "fixed", type = "fixed",
fixed = {-0.3, -0.5, -0.3, 0.3, 0.5, 0.3} 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" 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 -- cornstarch
minetest.register_craftitem("farming:cornstarch", { minetest.register_craftitem("farming:cornstarch", {
description = S("Cornstarch"), description = S("Cornstarch"),

View File

@ -173,3 +173,6 @@ Created by gorlock (CC0)
Created by sirrobzeroone (CC0) Created by sirrobzeroone (CC0)
farming_gyoza.png farming_gyoza.png
farming_pineapple_ring.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. Updates the current formspec. `extra_formspec` adds an additional formspec string.
#### `i3.delete_tab(tabname)` #### `i3.remove_tab(tabname)`
Deletes a tab by name. Deletes a tab by name.
@ -141,7 +141,7 @@ Recipes can be registered from a given URL containing a JSON file (HTTP support
```Lua ```Lua
i3.register_craft({ 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. 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`. 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: Example usages:
- `+groups=cracky,crumbly`: search for groups `cracky` and `crumbly` in all items. - `+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 +groups=flammable`: search for group `flammable` amongst items which contain
`wood` in their names AND have a `node` drawtype. `wood` in their names.
Notes: Notes:
- If `optional_name` is omitted, the search filter will apply to all items, without pre-filtering. - 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))` #### `i3.add_search_filter(name, function(item, values))`
@ -237,15 +237,6 @@ Returns a map of search filters, indexed by name.
### Miscellaneous ### 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` #### `i3.export_url`
If set, the mod will export all the cached recipes and usages in a JSON format 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) - Inventory Sorting (alphabetical + item stack compression)
- Item Bookmarks - Item Bookmarks
- Waypoints - 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. **¹** *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`.* 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 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. # 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 = { mobs = {
mod = "redo", mod = "redo",
version = "20210613", version = "20210614",
intllib = S, intllib = S,
invis = minetest.global_exists("invisibility") and invisibility or {} 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 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 -- are we facing a fence or wall
if nod.name:find("fence") or nod.name:find("gate") or nod.name:find("wall") then if nod.name:find("fence") or nod.name:find("gate") or nod.name:find("wall") then
self.facing_fence = true self.facing_fence = true
end 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) 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() 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}})) 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 ### Bluon
Binary Lua object notation. **Experimental.** Handling of subnormal numbers (very small floats) may be broken. 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 ## Release Notes
### `rolling-70`
* Fixes module environments once and for all
* Fixes vector aliases
* Presumably boosts performance
### `rolling-69` ### `rolling-69`
* Fixes various things, **most importantly modules indexing the global table** * Fixes various things, **most importantly modules indexing the global table**

View File

@ -1,7 +1,11 @@
local class = getfenv(1) -- Localize globals
local metatable = {__index = function(_self, key) local assert, error, math, modlib, next, pairs, setmetatable, table = assert, error, math, modlib, next, pairs, setmetatable, table
return rawget(class, key)
end} -- Set environment
local _ENV = {}
setfenv(1, _ENV)
local metatable = {__index = _ENV}
--! experimental --! experimental
--+ Reads a single BB3D chunk from a stream --+ Reads a single BB3D chunk from a stream
@ -360,4 +364,7 @@ function get_animated_bone_properties(self, keyframe, interpolate)
end end
get_props(self.node) get_props(self.node)
return bone_properties 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 -- All little endian
--+ Reads doubles (f64) or floats (f32) --+ Reads doubles (f64) or floats (f32)
@ -23,7 +31,7 @@ function read_float(read_byte, double)
mantissa = (mantissa + byte_2) / 0x80 mantissa = (mantissa + byte_2) / 0x80
if exponent == 0xFF then if exponent == 0xFF then
if mantissa == 0 then if mantissa == 0 then
return sign * math.huge return sign * math_huge
end end
-- Differentiating quiet and signalling nan is not possible in Lua, hence we don't have to do it -- 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 -- HACK ((0/0)^1) yields nan, 0/0 yields -nan
@ -60,7 +68,7 @@ end
function write_uint(write_byte, uint, bytes) function write_uint(write_byte, uint, bytes)
for _ = 1, bytes do for _ = 1, bytes do
write_byte(uint % 0x100) write_byte(uint % 0x100)
uint = math.floor(uint / 0x100) uint = math_floor(uint / 0x100)
end end
assert(uint == 0) assert(uint == 0)
end end
@ -73,16 +81,16 @@ function write_float(write_byte, number, on_write, double)
number = -number number = -number
sign = 0x80 sign = 0x80
end end
local mantissa, exponent = math.frexp(number) local mantissa, exponent = math_frexp(number)
exponent = exponent + 127 exponent = exponent + 127
if exponent > 1 then if exponent > 1 then
-- TODO ensure this deals properly with subnormal numbers -- TODO ensure this deals properly with subnormal numbers
mantissa = mantissa * 2 - 1 mantissa = mantissa * 2 - 1
exponent = exponent - 1 exponent = exponent - 1
end end
local sign_byte = sign + math.floor(exponent / 2) local sign_byte = sign + math_floor(exponent / 2)
mantissa = mantissa * 0x80 mantissa = mantissa * 0x80
local exponent_byte = (exponent % 2) * 0x80 + math.floor(mantissa) local exponent_byte = (exponent % 2) * 0x80 + math_floor(mantissa)
mantissa = mantissa % 1 mantissa = mantissa % 1
local mantissa_bytes = {} local mantissa_bytes = {}
-- TODO ensure this check is proper -- 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 local len = double and 6 or 2
for index = len, 1, -1 do for index = len, 1, -1 do
mantissa = mantissa * 0x100 mantissa = mantissa * 0x100
mantissa_bytes[index] = math.floor(mantissa) mantissa_bytes[index] = math_floor(mantissa)
mantissa = mantissa % 1 mantissa = mantissa % 1
end end
assert(mantissa == 0) assert(mantissa == 0)
@ -112,4 +120,7 @@ end
function write_double(write_byte, number) function write_double(write_byte, number)
return write_float(write_byte, number, nil, true) 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 --! experimental
local bluon = getfenv(1)
local no_op = modlib.func.no_op local no_op = modlib.func.no_op
local write_float = modlib.binary.write_float local write_float = modlib.binary.write_float
local metatable = {__index = function(_self, key) local metatable = {__index = _ENV}
return rawget(bluon, key)
end}
function new(self) function new(self)
return setmetatable(self or {}, metatable) return setmetatable(self or {}, metatable)
@ -57,8 +62,8 @@ local constants = {
[0] = "\2", [0] = "\2",
-- not possible as table entry as Lua doesn't allow +/-nan as table key -- not possible as table entry as Lua doesn't allow +/-nan as table key
-- [0/0] = "\3", -- [0/0] = "\3",
[math.huge] = "\4", [math_huge] = "\4",
[-math.huge] = "\5", [-math_huge] = "\5",
[""] = "\20" [""] = "\20"
} }
@ -293,18 +298,18 @@ function read(self, stream)
end end
if type <= type_ranges.string then if type <= type_ranges.string then
local string = stream_read(uint(type - type_ranges.number)) local string = stream_read(uint(type - type_ranges.number))
table.insert(references, string) table_insert(references, string)
return string return string
end end
if type <= type_ranges.table then if type <= type_ranges.table then
type = type - type_ranges.string - 1 type = type - type_ranges.string - 1
local tab = {} local tab = {}
table.insert(references, tab) table_insert(references, tab)
if type == 0 then if type == 0 then
return tab return tab
end end
local list_len = uint(type % 5) 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 for index = 1, list_len do
tab[index] = _read(stream_read(1)) tab[index] = _read(stream_read(1))
end end
@ -323,4 +328,7 @@ function read(self, stream)
return return
end end
return _read(type) 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 -- not deprecated
function build_tree(dict) function build_tree(dict)
local tree = {} local tree = {}
@ -293,4 +300,7 @@ function check_constraints(value, constraints)
error(possible_errors) error(possible_errors)
end end
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) function variables(stacklevel)
stacklevel = (stacklevel or 1) + 1 stacklevel = (stacklevel or 1) + 1
local locals = {} local locals = {}
@ -40,4 +47,7 @@ function stack(stacklevel)
stacklevel = stacklevel + 1 stacklevel = stacklevel + 1
end end
return stack 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) function read(filename)
local file = io.open(filename, "r") local file = io.open(filename, "r")
if file == nil then return nil end if file == nil then return nil end
@ -104,4 +111,7 @@ end
function process_bridge_start(name, command, os_execute) function process_bridge_start(name, command, os_execute)
local bridge = process_bridges[name] local bridge = process_bridges[name]
os_execute(string.format(command, bridge.output, bridge.input, bridge.logs)) 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 no_op = function() end
function curry(func, ...) function curry(func, ...)
@ -10,7 +17,12 @@ function curry_tail(func, ...)
return function(...) return func(unpack(modlib.table.concat({...}, args))) end return function(...) return func(unpack(modlib.table.concat({...}, args))) end
end end
function call(...) function curry_full(func, ...)
local args = { ... }
return function() return func(unpack(args)) end
end
function args(...)
local args = { ... } local args = { ... }
return function(func) return func(unpack(args)) end return function(func) return func(unpack(args)) end
end end
@ -22,6 +34,31 @@ function values(...)
return function() return unpack(args) end return function() return unpack(args) end
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) function override_chain(func, override)
return function(...) return function(...)
func(...) func(...)
@ -110,4 +147,7 @@ end
function or_(a, b) function or_(a, b)
return a or 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 function less_than(a, b) return a < b end
@ -47,4 +54,7 @@ function pop(self)
end end
heapify(1) heapify(1)
return value return value
end end
-- Export environment
return _ENV

View File

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

View File

@ -1,7 +1,11 @@
local class = getfenv(1) -- Localize globals
local metatable = {__index = function(_self, key) local assert, math, modlib, setmetatable, table, unpack = assert, math, modlib, setmetatable, table, unpack
return rawget(class, key)
end} -- Set environment
local _ENV = {}
setfenv(1, _ENV)
local metatable = {__index = _ENV}
distance = modlib.vector.distance distance = modlib.vector.distance
@ -54,4 +58,7 @@ function get_nearest_neighbor(self, vector)
return nearest_neighbor, min_distance return nearest_neighbor, min_distance
end 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 -- Log helpers - write to log, force writing to file
minetest.mkdir(minetest.get_worldpath() .. "/logs") minetest.mkdir(minetest.get_worldpath() .. "/logs")
channels = {} channels = {}
@ -74,3 +81,7 @@ minetest.register_on_shutdown(
write_all_to_file() write_all_to_file()
end 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 -- Make random random
math.randomseed(minetest and minetest.get_us_time() or os.time() + os.clock()) math.randomseed(minetest and minetest.get_us_time() or os.time() + os.clock())
for _ = 1, 100 do math.random() end for _ = 1, 100 do math.random() end
@ -68,4 +75,7 @@ function fround(number)
return sign * math.huge return sign * math.huge
end end
return sign * powexp * (leading - mantissa / 0x800000) 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 {{...}} -- Minetest allows shorthand collisionbox = {...} instead of {{...}}
local function get_collisionboxes(box_or_boxes) local function get_collisionboxes(box_or_boxes)
return type(box_or_boxes[1]) == "number" and {box_or_boxes} or 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 -- As in src/util/string.cpp
named_colors = { named_colors = {
aliceblue = 0xf0f8ff, aliceblue = 0xf0f8ff,
@ -178,7 +185,7 @@ function colorspec.from_string(string)
if number then if number then
return colorspec.from_number(number * 0x100 + alpha) return colorspec.from_number(number * 0x100 + alpha)
end end
local hex_text = string:match(hex) local hex_text = string:match("^" .. hex .. "$")
local len, num = hex_text:len(), tonumber(hex_text, 16) local len, num = hex_text:len(), tonumber(hex_text, 16)
if len == 8 then if len == 8 then
return colorspec.from_number(num) 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 liquid_level_max = 8
--+ Calculates the corner levels of a flowingliquid node --+ Calculates the corner levels of a flowingliquid node
--> 4 corner levels from -0.5 to 0.5 as list of `modlib.vector` --> 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 max_wear = 2 ^ 16 - 1
function override(function_name, function_builder) function override(function_name, function_builder)
local func = minetest[function_name] 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 --+ Raycast wrapper with proper flowingliquid intersections
function raycast(_pos1, _pos2, objects, liquids) function raycast(_pos1, _pos2, objects, liquids)
local raycast = minetest.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 = {} schematic = {}
local metatable = {__index = 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 = {} players = {}
registered_on_wielditem_changes = {function(...) 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 -- get resource + dofile
function include(modname, file) function include(modname, file)
if not file then if not file then
@ -128,4 +143,7 @@ function configuration(modname)
return schema:load({}, {error_message = true}) return schema:load({}, {error_message = true})
end end
return conf 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 files = {}
local metatable = {__index = lua_log_file} local metatable = {__index = lua_log_file}
function lua_log_file.new(file_path, root) function lua_log_file.new(file_path, root, reference_strings)
local self = setmetatable({file_path = assert(file_path), root = root}, metatable) local self = setmetatable({
file_path = assert(file_path),
root = root,
reference_strings = reference_strings
}, metatable)
if minetest then if minetest then
files[self] = true files[self] = true
end end
return self return self
end 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() function lua_log_file:load()
-- Bytecode is blocked by the engine -- Bytecode is blocked by the engine
local read = assert(loadfile(self.file_path)) local read = assert(loadfile(self.file_path))
@ -20,7 +40,7 @@ function lua_log_file:load()
env.R = env.R or {{}} env.R = env.R or {{}}
self.reference_count = #env.R self.reference_count = #env.R
self.root = env.R[1] self.root = env.R[1]
self.references = modlib.table.flip(env.R) set_references(self, {})
end end
function lua_log_file:open() function lua_log_file:open()
@ -86,50 +106,51 @@ function lua_log_file:_dump(value, is_key)
end end
reference = self.reference_count + 1 reference = self.reference_count + 1
local key = "R[" .. reference .."]" local key = "R[" .. reference .."]"
local formatted
local function create_reference() local function create_reference()
self.reference_count = reference self.reference_count = reference
self.references[value] = reference self.references[value] = reference
end end
if _type == "string" then 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 -- Short key
return value, true return value, true
end end
formatted = ("%q"):format(value) local formatted = ("%q"):format(value)
if formatted:len() <= key:len() then if (not reference_strings) or formatted:len() <= key:len() then
-- Short string -- Short string
return formatted return formatted
end end
-- Use reference -- Use reference
create_reference() create_reference()
self:log(key .. "=" .. formatted)
elseif _type == "table" then elseif _type == "table" then
-- Tables always need a reference before they are traversed to prevent infinite recursion -- Tables always need a reference before they are traversed to prevent infinite recursion
create_reference() create_reference()
local entries = {} -- TODO traverse tables to determine whether this is actually needed
for _, value in ipairs(value) do self:log(key .. "={}")
table.insert(entries, self:_dump(value))
end
local tablelen = #value local tablelen = #value
for key, value in pairs(value) do for k, v in pairs(value) do
if type(key) ~= "number" or key % 1 ~= 0 or key < 1 or key > tablelen then if type(k) ~= "number" or k % 1 ~= 0 or k < 1 or k > tablelen then
local dumped, short = self:_dump(key, true) local dumped, short = self:_dump(k, true)
table.insert(entries, (short and dumped or ("[" .. dumped .. "]")) .. "=" .. self:_dump(value)) self:log(key .. (short and ("." .. dumped) or ("[" .. dumped .. "]")) .. "=" .. self:_dump(v))
end end
end end
formatted = "{" .. table.concat(entries, ";") .. "}"
else else
error("unsupported type: " .. _type) error("unsupported type: " .. _type)
end end
self:log(key .. "=" .. formatted)
return key return key
end end
function lua_log_file:set(table, key, value) function lua_log_file:set(table, key, value)
table[key] = value
if not self.references[table] then if not self.references[table] then
error"orphan table" error"orphan table"
end end
if table[key] == value then
-- No change
return
end
table[key] = value
table = self:_dump(table) table = self:_dump(table)
local key, short_key = self:_dump(key, true) local key, short_key = self:_dump(key, true)
self:log(table .. (short_key and ("." .. key) or ("[" .. key .. "]")) .. "=" .. self:_dump(value)) 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 end
function lua_log_file:_write() function lua_log_file:_write()
self.references = {} set_references(self, {})
self.reference_count = 0 self.reference_count = 0
self:log"R={}" self:log"R={}"
self:_dump(self.root) self:_dump(self.root)
@ -158,4 +179,7 @@ function lua_log_file:rewrite()
end end
self:_rewrite() self:_rewrite()
self:open() 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 = {} forbidden_names = {}
function register_forbidden_name(name) forbidden_names[name] = true end function register_forbidden_name(name) forbidden_names[name] = true end
@ -75,4 +82,7 @@ function datatable(table, default)
end) end)
minetest.register_on_leaveplayer(function(player) table[player:get_player_name()] = nil end) minetest.register_on_leaveplayer(function(player) table[player:get_player_name()] = nil end)
return table 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 -- TODO OOP, extend vector
function from_euler_rotation(rotation) function from_euler_rotation(rotation)
@ -126,4 +133,7 @@ function to_euler_rotation_irrlicht(self)
end end
return vector.apply(_calc(), math.deg) return vector.apply(_calc(), math.deg)
end end
-- Export environment
return _ENV

View File

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

View File

@ -1,7 +1,11 @@
local class = getfenv(1) -- Localize globals
local metatable = {__index = function(_self, key) 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
return rawget(class, key)
end} -- Set environment
local _ENV = {}
setfenv(1, _ENV)
local metatable = {__index = _ENV}
function new(def) function new(def)
-- TODO type inference, sanity checking etc. -- TODO type inference, sanity checking etc.
@ -295,4 +299,7 @@ function load(self, override, params)
end end
if self.func then self.func(override) end if self.func then self.func(override) end
return override 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 -- Table helpers
function map_index(table, func) function map_index(table, func)
@ -314,6 +321,43 @@ function foreach(table, func)
end end
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) function foreach_value(table, func)
for _, v in pairs(table) do for _, v in pairs(table) do
func(v) func(v)
@ -586,4 +630,7 @@ function repetition(value, count)
table[index] = value table[index] = value
end end
return table return table
end end
-- Export environment
return _ENV

View File

@ -16,6 +16,17 @@ setfenv(1, setmetatable({}, {
end 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 -- string
assert(string.escape_magic_chars"%" == "%%") assert(string.escape_magic_chars"%" == "%%")
@ -50,6 +61,24 @@ do
rope:write" " rope:write" "
rope:write"world" rope:write"world"
assert(rope:to_text() == "hello world", rope:to_text()) 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 end
-- heap -- heap
@ -137,10 +166,41 @@ for _ = 1, 1000 do
assert(distance == min_distance) assert(distance == min_distance)
end 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 -- bluon
do do
local bluon = bluon local bluon = bluon
local function assert_preserves(object) serializer_test(function(object)
local rope = table.rope{} local rope = table.rope{}
local written, read, input local written, read, input
local _, err = pcall(function() local _, err = pcall(function()
@ -157,25 +217,17 @@ do
written = written and text.hexdump(written), written = written and text.hexdump(written),
err = err err = err
}) })
end end)
for _, constant in pairs{true, false, huge, -huge} do end
assert_preserves(constant)
end -- luon
for i = 1, 1000 do do
assert_preserves(_G.table.concat(table.repetition(_G.string.char(i % 256), i))) serializer_test(function(object)
end local serialized = luon.write_string(object)
for _ = 1, 1000 do assert(table.equals_references(object, luon.read_string(serialized)), serialized)
local int = random(-2^50, 2^50) end)
assert(int % 1 == 0) local nan = luon.read_string(luon.write_string(0/0))
assert_preserves(int) assert(nan ~= nan)
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
if not _G.minetest then return 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("#694269", 0x694269FF)
test_from_string("#11223344", 0x11223344) test_from_string("#11223344", 0x11223344)
local logfile = persistence.lua_log_file.new(mod.get_resource"logfile.test.lua", {}) local function test_logfile(reference_strings)
logfile:init() local logfile = persistence.lua_log_file.new(mod.get_resource"logfile.test.lua", {}, reference_strings)
logfile.root = {} logfile:init()
logfile:rewrite() logfile.root = {a_longer_string = "test"}
logfile:set_root({a = 1}, {b = 2, c = 3, d = _G.math.huge, e = -_G.math.huge}) logfile:rewrite()
logfile:close() logfile:set_root({a = 1}, {b = 2, c = 3, d = _G.math.huge, e = -_G.math.huge})
logfile:init() local circular = {}
assert(table.equals(logfile.root, {[{a = 1}] = {b = 2, c = 3, d = _G.math.huge, e = -_G.math.huge}})) 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 -- in-game tests & b3d testing
local tests = { 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 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 function lower_first(text) return text:sub(1, 1):lower() .. text:sub(2) end
@ -163,4 +170,7 @@ function handle_ifdefs(code, vars)
end end
table.insert(finalcode, string.sub(code, after_endif + 2)) table.insert(finalcode, string.sub(code, after_endif + 2))
return table.concat(finalcode, "") return table.concat(finalcode, "")
end end
-- Export environment
return _ENV

View File

@ -1,7 +1,11 @@
local class = getfenv(1) -- Localize globals
local metatable = {__index = function(_self, key) local math, next, pairs, setmetatable, string, table, unpack = math, next, pairs, setmetatable, string, table, unpack
return rawget(class, key)
end} -- Set environment
local _ENV = {}
setfenv(1, _ENV)
local metatable = {__index = _ENV}
function new(table) return setmetatable(table or {}, metatable) end function new(table) return setmetatable(table or {}, metatable) end
@ -121,4 +125,7 @@ function find_longest(self, query, query_offset)
end end
end end
return last_leaf, leaf_pos 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 mt_vector = vector
local class = getfenv(1)
index_aliases = { index_aliases = {
x = 1, x = 1,
@ -16,10 +22,11 @@ metatable = {
if index ~= nil then if index ~= nil then
return table[index] return table[index]
end end
return rawget(class, key) return _ENV[key]
end, end,
__newindex = function(table, key, value) __newindex = function(table, key, value)
local index = letters[key] -- TODO
local index = index_aliases[key]
if index ~= nil then if index ~= nil then
return rawset(table, index, value) return rawset(table, index, value)
end end
@ -183,6 +190,14 @@ function angle(v, w)
return math.acos(dot(v, w) / length(v) / length(w)) return math.acos(dot(v, w) / length(v) / length(w))
end 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) function box_box_collision(diff, box, other_box)
for index, diff in pairs(diff) do for index, diff in pairs(diff) do
if box[index] + diff > other_box[index + 3] or other_box[index] > box[index + 3] + diff then 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 point_1, point_2, point_3 = unpack(triangle)
local edge_1, edge_2 = subtract(point_2, point_1), subtract(point_3, point_1) local edge_1, edge_2 = subtract(point_2, point_1), subtract(point_3, point_1)
return normalize(cross3(edge_1, edge_2)) 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 return
end end
local food_count_wool = self.food_count_wool + 1 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 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.food_count_wool = mobkit.remember(self, "food_count_wool", 0)
self.shaved = mobkit.remember(self, "shaved", false) 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}, {name = "mobs:lava_orb", chance = 15, min = 1, max = 1},
}, },
water_damage = 8, water_damage = 8,
lava_damage = 0, lava_damage = -1,
fire_damage = 0, fire_damage = 0,
light_damage = 0, light_damage = 0,
immune_to = { immune_to = {
@ -53,7 +53,7 @@ mobs:register_mob("mobs_monster:lava_flan", {
run_start = 20, run_start = 20,
run_end = 28, run_end = 28,
punch_start = 20, punch_start = 20,
punch_end = 28, punch_end = 28
}, },
on_die = function(self, pos) on_die = function(self, pos)
@ -174,9 +174,13 @@ minetest.register_tool(":mobs:pick_lava", {
inventory_image = "mobs_pick_lava.png", inventory_image = "mobs_pick_lava.png",
tool_capabilities = { tool_capabilities = {
full_punch_interval = 0.4, full_punch_interval = 0.4,
max_drop_level=3, max_drop_level = 3,
groupcaps={ groupcaps = {
cracky = {times={[1]=1.80, [2]=0.80, [3]=0.40}, uses=40, maxlevel=3}, cracky = {
times = {[1] = 1.80, [2] = 0.80, [3] = 0.40},
uses = 40,
maxlevel = 3
}
}, },
damage_groups = {fleshy = 6, fire = 1}, damage_groups = {fleshy = 6, fire = 1},
}, },
@ -189,7 +193,7 @@ minetest.register_craft({
recipe = { recipe = {
{"mobs:lava_orb", "mobs:lava_orb", "mobs:lava_orb"}, {"mobs:lava_orb", "mobs:lava_orb", "mobs:lava_orb"},
{"", "default:obsidian_shard", ""}, {"", "default:obsidian_shard", ""},
{"", "default:obsidian_shard", ""}, {"", "default:obsidian_shard", ""}
} }
}) })
@ -253,7 +257,7 @@ mobs:register_mob("mobs_monster:obsidian_flan", {
run_start = 20, run_start = 20,
run_end = 28, run_end = 28,
punch_start = 20, punch_start = 20,
punch_end = 28, punch_end = 28
} }
}) })
@ -296,9 +300,11 @@ mobs:register_arrow("mobs_monster:obsidian_arrow", {
local radius = 1 local radius = 1
local def = minetest.registered_nodes[node] local def = minetest.registered_nodes[node]
if def then if def then
node = { name = node } node = {name = node}
end end
if def and def.tiles and def.tiles[1] then if def and def.tiles and def.tiles[1] then
texture = def.tiles[1] texture = def.tiles[1]
end end
@ -325,7 +331,7 @@ mobs:register_arrow("mobs_monster:obsidian_arrow", {
texture = texture, texture = texture,
-- ^ only as fallback for clients without support for `node` parameter -- ^ only as fallback for clients without support for `node` parameter
node = node, node = node,
collisiondetection = true, collisiondetection = true
}) })
minetest.set_node(pos, {name = "air"}) minetest.set_node(pos, {name = "air"})

View File

@ -55,12 +55,14 @@ armor = {
crystal = "ethereal:crystal_ingot", crystal = "ethereal:crystal_ingot",
}, },
fire_nodes = { fire_nodes = {
{"nether:lava_source", 5, 8},
{"default:lava_source", 5, 8}, {"default:lava_source", 5, 8},
{"default:lava_flowing", 5, 8}, {"default:lava_flowing", 5, 8},
{"fire:basic_flame", 3, 4}, {"fire:basic_flame", 3, 4},
{"fire:permanent_flame", 3, 4}, {"fire:permanent_flame", 3, 4},
{"ethereal:crystal_spike", 2, 1}, {"ethereal:crystal_spike", 2, 1},
{"ethereal:fire_flower", 2, 1}, {"ethereal:fire_flower", 2, 1},
{"nether:lava_crust", 2, 1},
{"default:torch", 1, 1}, {"default:torch", 1, 1},
{"default:torch_ceiling", 1, 1}, {"default:torch_ceiling", 1, 1},
{"default:torch_wall", 1, 1}, {"default:torch_wall", 1, 1},
@ -671,3 +673,10 @@ armor.drop_armor = function(pos, stack)
end end
end 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) minetest.register_on_joinplayer(function(player)
local name = player:get_player_name() local name = player:get_player_name()
wieldview.wielded_item[name] = "" wieldview.wielded_item[name] = ""
minetest.after(0, function() minetest.after(0, function(pname)
local pplayer = minetest.get_player_by_name(name) local pplayer = minetest.get_player_by_name(pname)
if player then if pplayer then
wieldview:update_wielded_item(pplayer) wieldview:update_wielded_item(pplayer)
end end
end) end, name)
end) end)
minetest.register_globalstep(function(dtime) minetest.register_globalstep(function(dtime)

View File

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

View File

@ -95,6 +95,8 @@ end)
-- default biomes deco -- default biomes deco
local 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:dirt_with_dry_grass", dry_grass, flowers},
{"default:sand", {}, {"default:dry_shrub", "", "", ""} }, {"default:sand", {}, {"default:dry_shrub", "", "", ""} },
{"default:desert_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