This commit is contained in:
root 2021-09-05 16:06:04 +02:00
parent b17821de68
commit 8054d2caf5
53 changed files with 528 additions and 371 deletions

View file

@ -279,7 +279,8 @@ minetest.register_node("bees:hive_wild", {
{items = {"bees:honey_comb"}, rarity = 5} {items = {"bees:honey_comb"}, rarity = 5}
} }
}, },
groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3, attached_node = 1}, groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3},
--, attached_node = 1},
node_box = { -- VanessaE's wild hive nodebox contribution node_box = { -- VanessaE's wild hive nodebox contribution
type = "fixed", type = "fixed",
fixed = { fixed = {

View file

@ -68,6 +68,7 @@ if minetest.get_modpath("ethereal") then
{"ethereal:mushroom_sapling", ethereal.grow_mushroom_tree, "soil"}, {"ethereal:mushroom_sapling", ethereal.grow_mushroom_tree, "soil"},
{"ethereal:willow_sapling", ethereal.grow_willow_tree, "soil"}, {"ethereal:willow_sapling", ethereal.grow_willow_tree, "soil"},
{"ethereal:redwood_sapling", ethereal.grow_redwood_tree, "soil"}, {"ethereal:redwood_sapling", ethereal.grow_redwood_tree, "soil"},
{"ethereal:giant_redwood_sapling", ethereal.grow_giant_redwood_tree, "soil"},
{"ethereal:orange_tree_sapling", ethereal.grow_orange_tree, "soil"}, {"ethereal:orange_tree_sapling", ethereal.grow_orange_tree, "soil"},
{"ethereal:bamboo_sprout", ethereal.grow_bamboo_tree, "soil"}, {"ethereal:bamboo_sprout", ethereal.grow_bamboo_tree, "soil"},
{"ethereal:birch_sapling", ethereal.grow_birch_tree, "soil"}, {"ethereal:birch_sapling", ethereal.grow_birch_tree, "soil"},

Binary file not shown.

Before

Width:  |  Height:  |  Size: 187 B

After

Width:  |  Height:  |  Size: 173 B

View file

@ -1,6 +1,16 @@
local S = mobs.intllib local S = mobs.intllib
local master_types = {
{ nodes = {"nether:rack"},
skins = {"mobs_dungeon_master_nether.png"},
},
{ nodes = {"nether:rack_deep"},
skins = {"mobs_dungeon_master_netherdeep.png"},
}
}
-- Dungeon Master by PilzAdam -- Dungeon Master by PilzAdam
@ -59,13 +69,39 @@ mobs:register_mob("mobs_monster:dungeon_master", {
speed_normal = 15, speed_normal = 15,
speed_run = 15, speed_run = 15,
}, },
-- check surrounding nodes and spawn a specific monster
on_spawn = function(self)
local pos = self.object:get_pos() ; pos.y = pos.y - 1
local tmp
for n = 1, #master_types do
tmp = master_types[n]
if minetest.find_node_near(pos, 1, tmp.nodes) then
self.base_texture = tmp.skins
self.object:set_properties({textures = tmp.skins})
if tmp.drops then
self.drops = tmp.drops
end
return true
end
end
return true -- run only once, false/nil runs every activation
end
}) })
if not mobs.custom_spawn_monster then if not mobs.custom_spawn_monster then
mobs:spawn({ mobs:spawn({
name = "mobs_monster:dungeon_master", name = "mobs_monster:dungeon_master",
nodes = {"default:stone"}, nodes = {"default:stone", "nether:rack", "nether:rack_deep"},
max_light = 5, max_light = 5,
chance = 9000, chance = 9000,
active_object_count = 1, active_object_count = 1,

View file

@ -30,3 +30,7 @@ mobs.fireball.png was originally made by Sapier and edited by Benrob:
-- --
-- (c) Sapier -- (c) Sapier
-- Contact sapier a t gmx net -- Contact sapier a t gmx net
Textures created by wwar (cc0)
mobs_dungeon_master_nether.png
mobs_dungeon_master_netherdeep.png

View file

@ -12,6 +12,9 @@ mobs:register_mob("mobs_monster:mese_monster", {
shoot_interval = 0.5, shoot_interval = 0.5,
arrow = "mobs_monster:mese_arrow", arrow = "mobs_monster:mese_arrow",
shoot_offset = 2, shoot_offset = 2,
--arrow_override = function(self)
-- self.velocity = 20
--end,
hp_min = 10, hp_min = 10,
hp_max = 25, hp_max = 25,
armor = 80, armor = 80,

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

View file

@ -8,7 +8,7 @@ local use_cmi = minetest.global_exists("cmi")
mobs = { mobs = {
mod = "redo", mod = "redo",
version = "20210816", version = "20210905",
intllib = S, intllib = S,
invis = minetest.global_exists("invisibility") and invisibility or {} invis = minetest.global_exists("invisibility") and invisibility or {}
} }
@ -4771,6 +4771,10 @@ function mobs:feed_tame(self, clicker, feed_count, breed, tame)
if clicker:get_player_control().sneak then if clicker:get_player_control().sneak then
if type(self.follow) == "string" then
self.follow = {self.follow}
end
minetest.chat_send_player(clicker:get_player_name(), minetest.chat_send_player(clicker:get_player_name(),
S("@1 follows:\n- @2", S("@1 follows:\n- @2",
self.name:split(":")[2], self.name:split(":")[2],

View file

@ -337,6 +337,10 @@ function circular_saw.on_metadata_inventory_take(
local input_stack = inv:get_stack(listname, index) local input_stack = inv:get_stack(listname, index)
if not input_stack:is_empty() and input_stack:get_name()~=stack:get_name() then if not input_stack:is_empty() and input_stack:get_name()~=stack:get_name() then
local player_inv = player:get_inventory() local player_inv = player:get_inventory()
-- Prevent arbitrary item duplication.
inv:remove_item(listname, input_stack)
if player_inv:room_for_item("main", input_stack) then if player_inv:room_for_item("main", input_stack) then
player_inv:add_item("main", input_stack) player_inv:add_item("main", input_stack)
end end
@ -363,9 +367,15 @@ function circular_saw.on_metadata_inventory_take(
-- The recycle field plays no role here since it is processed immediately. -- The recycle field plays no role here since it is processed immediately.
end end
local has_default_mod = minetest.get_modpath("default")
function circular_saw.on_construct(pos) function circular_saw.on_construct(pos)
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
local fancy_inv = default.gui_bg..default.gui_bg_img..default.gui_slots local fancy_inv = ""
if has_default_mod then
-- prepend background and slot styles from default if available
fancy_inv = default.gui_bg..default.gui_bg_img..default.gui_slots
end
meta:set_string( meta:set_string(
"formspec", "size[11,10]"..fancy_inv.. "formspec", "size[11,10]"..fancy_inv..
"label[0,0;" ..F(S("Input\nmaterial")).. "]" .. "label[0,0;" ..F(S("Input\nmaterial")).. "]" ..
@ -437,7 +447,7 @@ minetest.register_node("moreblocks:circular_saw", {
sunlight_propagates = true, sunlight_propagates = true,
paramtype2 = "facedir", paramtype2 = "facedir",
groups = {choppy = 2,oddly_breakable_by_hand = 2}, groups = {choppy = 2,oddly_breakable_by_hand = 2},
sounds = default.node_sound_wood_defaults(), sounds = moreblocks.node_sound_wood_defaults(),
on_construct = circular_saw.on_construct, on_construct = circular_saw.on_construct,
can_dig = circular_saw.can_dig, can_dig = circular_saw.can_dig,
-- Set the owner of this circular saw. -- Set the owner of this circular saw.

View file

@ -17,9 +17,13 @@ moreblocks.S = S
moreblocks.NS = NS moreblocks.NS = NS
dofile(modpath .. "/config.lua") dofile(modpath .. "/config.lua")
dofile(modpath .. "/sounds.lua")
dofile(modpath .. "/circular_saw.lua") dofile(modpath .. "/circular_saw.lua")
dofile(modpath .. "/stairsplus/init.lua") dofile(modpath .. "/stairsplus/init.lua")
dofile(modpath .. "/nodes.lua")
dofile(modpath .. "/redefinitions.lua") if minetest.get_modpath("default") then
dofile(modpath .. "/crafting.lua") dofile(modpath .. "/nodes.lua")
dofile(modpath .. "/aliases.lua") dofile(modpath .. "/redefinitions.lua")
dofile(modpath .. "/crafting.lua")
dofile(modpath .. "/aliases.lua")
end

View file

@ -1,5 +1,4 @@
name = moreblocks name = moreblocks
description = Adds various miscellaneous blocks to the game. description = Adds various miscellaneous blocks to the game.
depends = default optional_depends = default,intllib,stairs,farming,wool,basic_materials
optional_depends = intllib,stairs,farming,wool,basic_materials
min_minetest_version = 5.0.0 min_minetest_version = 5.0.0

View file

@ -7,15 +7,15 @@ Licensed under the zlib license. See LICENSE.md for more information.
local S = moreblocks.S local S = moreblocks.S
local sound_dirt = default.node_sound_dirt_defaults() local sound_dirt = moreblocks.node_sound_dirt_defaults()
local sound_wood = default.node_sound_wood_defaults() local sound_wood = moreblocks.node_sound_wood_defaults()
local sound_stone = default.node_sound_stone_defaults() local sound_stone = moreblocks.node_sound_stone_defaults()
local sound_glass = default.node_sound_glass_defaults() local sound_glass = moreblocks.node_sound_glass_defaults()
local sound_leaves = default.node_sound_leaves_defaults() local sound_leaves = moreblocks.node_sound_leaves_defaults()
-- Don't break on 0.4.14 and earlier. -- Don't break on 0.4.14 and earlier.
local sound_metal = (default.node_sound_metal_defaults local sound_metal = (moreblocks.node_sound_metal_defaults
and default.node_sound_metal_defaults() or sound_stone) and moreblocks.node_sound_metal_defaults() or sound_stone)
local function tile_tiles(name) local function tile_tiles(name)
local tex = "moreblocks_" ..name.. ".png" local tex = "moreblocks_" ..name.. ".png"

View file

@ -0,0 +1,20 @@
--[[
More Blocks: sound definitions
Copyright © 2011-2021 Hugo Locurcio and contributors.
Licensed under the zlib license. See LICENSE.md for more information.
--]]
local has_default_mod = minetest.get_modpath("default")
for _, sound in ipairs({"dirt", "wood", "stone", "metal", "glass", "leaves"}) do
-- use sound-function from default if available
-- otherwise fall back to a no-op function (no sounds)
local sound_function_name = "node_sound_" .. sound .. "_defaults"
if has_default_mod then
-- use default sounds
moreblocks[sound_function_name] = default[sound_function_name]
else
-- no-op
moreblocks[sound_function_name] = function() end
end
end

View file

@ -10,7 +10,7 @@
description = "Wooden", description = "Wooden",
tiles = {"default_wood.png"}, tiles = {"default_wood.png"},
groups = {oddly_breakabe_by_hand=1}, groups = {oddly_breakabe_by_hand=1},
sounds = default.node_sound_wood_defaults(), sounds = moreblocks.node_sound_wood_defaults(),
}) })
``` ```
The following register only a particular type of microblock. The following register only a particular type of microblock.

View file

@ -69,7 +69,7 @@ local function register_custom_subset(subset, modname, subname, recipeitem, grou
description = description, description = description,
drop = drop, drop = drop,
light_source = light, light_source = light,
sounds = default.node_sound_stone_defaults(), sounds = moreblocks.node_sound_stone_defaults(),
}) })
end end

View file

@ -15,7 +15,7 @@ local function register_micro(modname, subname, recipeitem, groups, images, desc
description = description, description = description,
drop = drop, drop = drop,
light_source = light, light_source = light,
sounds = default.node_sound_stone_defaults(), sounds = moreblocks.node_sound_stone_defaults(),
}) })
end end

View file

@ -15,7 +15,7 @@ local function register_panel(modname, subname, recipeitem, groups, images, desc
description = description, description = description,
drop = drop, drop = drop,
light_source = light, light_source = light,
sounds = default.node_sound_stone_defaults(), sounds = moreblocks.node_sound_stone_defaults(),
}) })
end end

View file

@ -6,75 +6,77 @@ Licensed under the zlib license. See LICENSE.md for more information.
--]] --]]
-- default registrations -- default registrations
local default_nodes = { -- Default stairs/slabs/panels/microblocks: if minetest.get_modpath("default") then
"stone", local default_nodes = { -- Default stairs/slabs/panels/microblocks:
"stone_block", "stone",
"cobble", "stone_block",
"mossycobble", "cobble",
"brick", "mossycobble",
"sandstone", "brick",
"steelblock", "sandstone",
"goldblock", "steelblock",
"copperblock", "goldblock",
"bronzeblock", "copperblock",
"diamondblock", "bronzeblock",
"tinblock", "diamondblock",
"desert_stone", "tinblock",
"desert_stone_block", "desert_stone",
"desert_cobble", "desert_stone_block",
"meselamp", "desert_cobble",
"glass", "meselamp",
"tree", "glass",
"wood", "tree",
"jungletree", "wood",
"junglewood", "jungletree",
"pine_tree", "junglewood",
"pine_wood", "pine_tree",
"acacia_tree", "pine_wood",
"acacia_wood", "acacia_tree",
"aspen_tree", "acacia_wood",
"aspen_wood", "aspen_tree",
"obsidian", "aspen_wood",
"obsidian_block", "obsidian",
"obsidianbrick", "obsidian_block",
"obsidian_glass", "obsidianbrick",
"stonebrick", "obsidian_glass",
"desert_stonebrick", "stonebrick",
"sandstonebrick", "desert_stonebrick",
"silver_sandstone", "sandstonebrick",
"silver_sandstone_brick", "silver_sandstone",
"silver_sandstone_block", "silver_sandstone_brick",
"desert_sandstone", "silver_sandstone_block",
"desert_sandstone_brick", "desert_sandstone",
"desert_sandstone_block", "desert_sandstone_brick",
"sandstone_block", "desert_sandstone_block",
"coral_skeleton", "sandstone_block",
"ice", "coral_skeleton",
} "ice",
}
for _, name in pairs(default_nodes) do for _, name in pairs(default_nodes) do
local mod = "default" local mod = "default"
local nodename = mod .. ":" .. name local nodename = mod .. ":" .. name
local ndef = table.copy(minetest.registered_nodes[nodename]) local ndef = table.copy(minetest.registered_nodes[nodename])
ndef.sunlight_propagates = true ndef.sunlight_propagates = true
-- Stone and desert_stone drop cobble and desert_cobble respectively. -- Stone and desert_stone drop cobble and desert_cobble respectively.
if type(ndef.drop) == "string" then if type(ndef.drop) == "string" then
ndef.drop = ndef.drop:gsub(".+:", "") ndef.drop = ndef.drop:gsub(".+:", "")
end
-- Use the primary tile for all sides of cut glasslike nodes and disregard paramtype2.
if #ndef.tiles > 1 and ndef.drawtype and ndef.drawtype:find("glass") then
ndef.tiles = {ndef.tiles[1]}
ndef.paramtype2 = nil
end
mod = "moreblocks"
stairsplus:register_all(mod, name, nodename, ndef)
minetest.register_alias_force("stairs:stair_" .. name, mod .. ":stair_" .. name)
minetest.register_alias_force("stairs:stair_outer_" .. name, mod .. ":stair_" .. name .. "_outer")
minetest.register_alias_force("stairs:stair_inner_" .. name, mod .. ":stair_" .. name .. "_inner")
minetest.register_alias_force("stairs:slab_" .. name, mod .. ":slab_" .. name)
end end
-- Use the primary tile for all sides of cut glasslike nodes and disregard paramtype2.
if #ndef.tiles > 1 and ndef.drawtype and ndef.drawtype:find("glass") then
ndef.tiles = {ndef.tiles[1]}
ndef.paramtype2 = nil
end
mod = "moreblocks"
stairsplus:register_all(mod, name, nodename, ndef)
minetest.register_alias_force("stairs:stair_" .. name, mod .. ":stair_" .. name)
minetest.register_alias_force("stairs:stair_outer_" .. name, mod .. ":stair_" .. name .. "_outer")
minetest.register_alias_force("stairs:stair_inner_" .. name, mod .. ":stair_" .. name .. "_inner")
minetest.register_alias_force("stairs:slab_" .. name, mod .. ":slab_" .. name)
end end
-- farming registrations -- farming registrations
@ -118,7 +120,7 @@ if minetest.get_modpath("basic_materials") then
description = "Concrete", description = "Concrete",
tiles = {"basic_materials_concrete_block.png",}, tiles = {"basic_materials_concrete_block.png",},
groups = {cracky=1, level=2, concrete=1}, groups = {cracky=1, level=2, concrete=1},
sounds = default.node_sound_stone_defaults(), sounds = moreblocks.node_sound_stone_defaults(),
}) })
minetest.register_alias("prefab:concrete_stair","technic:stair_concrete") minetest.register_alias("prefab:concrete_stair","technic:stair_concrete")
@ -128,7 +130,7 @@ if minetest.get_modpath("basic_materials") then
description = "Cement", description = "Cement",
tiles = {"basic_materials_cement_block.png"}, tiles = {"basic_materials_cement_block.png"},
groups = {cracky=2, not_in_creative_inventory=1}, groups = {cracky=2, not_in_creative_inventory=1},
sounds = default.node_sound_stone_defaults(), sounds = moreblocks.node_sound_stone_defaults(),
sunlight_propagates = true, sunlight_propagates = true,
}) })

View file

@ -15,7 +15,7 @@ local function register_slab(modname, subname, recipeitem, groups, images, descr
description = description, description = description,
drop = drop, drop = drop,
light_source = light, light_source = light,
sounds = default.node_sound_stone_defaults(), sounds = moreblocks.node_sound_stone_defaults(),
}) })
end end

View file

@ -15,7 +15,7 @@ local function register_slope(modname, subname, recipeitem, groups, images, desc
description = description, description = description,
drop = drop, drop = drop,
light_source = light, light_source = light,
sounds = default.node_sound_stone_defaults(), sounds = moreblocks.node_sound_stone_defaults(),
}) })
end end

View file

@ -15,7 +15,7 @@ local function register_stair(modname, subname, recipeitem, groups, images, desc
description = description, description = description,
drop = drop, drop = drop,
light_source = light, light_source = light,
sounds = default.node_sound_stone_defaults(), sounds = moreblocks.node_sound_stone_defaults(),
}) })
end end

View file

@ -17,7 +17,7 @@ models.
Some nodes (ceiling lights, bar lights, poles) can be rotated to serve Some nodes (ceiling lights, bar lights, poles) can be rotated to serve
different purposes. different purposes.
Morelights currently supports both Minetest Game and MineClone 2. Morelights currently supports Minetest Game, MineClone 2, and Hades Revisited.
## Craft Recipes ## Craft Recipes

View file

@ -1,17 +1,22 @@
# Craft recipes for Morelights items # Craft recipes for Morelights items
Copper = copper ingot (Minetest Game) or redstone (MineClone 2) Copper = copper ingot (Minetest Game, Hades Revisited) or redstone
(MineClone 2).
Dye = white or dark grey dye, depending on the desired color of the item. Dye = white or dark grey dye, depending on the desired color of the item.
For MineClone 2, use bone meal or grey dye. For MineClone 2, use bone meal or grey dye.
Dark Wood = jungle wood planks (Minetest Game) or spruce wood (MineClone 2). Dark Wood = jungle wood planks (Minetest Game), spruce wood (MineClone 2), or
tropical wood planks (Hades Revisited).
Glass = regular, non-stained glass block. Glass = regular, non-stained glass block.
Glass Pane = regular, non-stained glass pane. Glass Pane = regular, non-stained glass pane. For Hades Revisited, if
`hades_extensionmods`/`hades_xpanes` is not available, use regular glass
instead.
Steel = steel ingot (Minetest Game) or iron ingot (MineClone 2). Steel = steel ingot (Minetest Game, Hades Revisited) or iron ingot
(MineClone 2).
## Basic items ## Basic items
@ -185,10 +190,12 @@ Use light/dark grey wool.
### Brass Ingot ### Brass Ingot
Minetest Game: Craft from one steel and one tin ingot. Minetest Game, Hades Revisited: Craft from one steel and one tin ingot.
MineClone 2: Craft from one iron ingot and one redstone. MineClone 2: Craft from one iron ingot and one redstone.
If `basic_materials` is installed, its Brass Ingot will be used instead.
### Brass Chain ### Brass Chain
``` ```
@ -259,14 +266,12 @@ MineClone 2: Craft from one iron ingot and one redstone.
+--------+ +--------+
| Glass | | Glass |
+--------+ +--------+
| Cotton | | String |
+--------+ +--------+
| Brass | | Brass |
+--------+ +--------+
``` ```
For MineClone 2, use string instead of cotton.
### Vintage Chandelier ### Vintage Chandelier
``` ```
@ -294,7 +299,8 @@ For MineClone 2, use string instead of cotton.
+---------+-------+---------+ +---------+-------+---------+
``` ```
Crystal = mese fragment (Minetest Game) or nether quartz (MineClone 2). Crystal = mese fragment (Minetest Game, Hades Revisited) or nether quartz
(MineClone 2).
### Grass Light ### Grass Light
@ -343,6 +349,8 @@ For MineClone 2, use polished stone.
For MineClone 2, use cut sandstone. For MineClone 2, use cut sandstone.
For Hades Revisited, use fine sandstone.
### Stair Light ### Stair Light
``` ```

View file

@ -1,2 +1,3 @@
name = morelights name = morelights
description = A lightweight modpack providing flexible interior and exterior lighting options for different styles of builds. description = A lightweight modpack providing flexible interior and exterior lighting options for different styles of builds.
min_minetest_version = 5.4

View file

@ -19,8 +19,8 @@ end
function morelights.on_place_hanging(itemstack, placer, pointed_thing, function morelights.on_place_hanging(itemstack, placer, pointed_thing,
ceilingName) ceilingName)
local ceiling = minetest.get_node(vector.add(pointed_thing.above, local ceiling = minetest.get_node(
{x=0, y=1, z=0})) vector.add(pointed_thing.above, vector.new(0, 1, 0)))
if ceiling.name ~= "air" if ceiling.name ~= "air"
and minetest.get_item_group(ceiling.name, "mounted_ceiling") == 0 and minetest.get_item_group(ceiling.name, "mounted_ceiling") == 0
@ -53,9 +53,11 @@ if minetest.get_modpath("mcl_core") then
morelights.game = "mineclone2" morelights.game = "mineclone2"
elseif minetest.get_modpath("default") then elseif minetest.get_modpath("default") then
morelights.game = "minetest_game" morelights.game = "minetest_game"
elseif minetest.get_modpath("hades_core") then
morelights.game = "hades_revisited"
else else
error("Morelights requires a compatible game " .. error("Morelights requires a compatible game " ..
"(Minetest Game or MineClone 2).") "(Minetest Game, MineClone 2, or Hades Revisited).")
end end
if morelights.game == "minetest_game" then if morelights.game == "minetest_game" then
@ -70,6 +72,12 @@ elseif morelights.game == "mineclone2" then
glass = mcl_sounds.node_sound_glass_defaults(), glass = mcl_sounds.node_sound_glass_defaults(),
metal = mcl_sounds.node_sound_metal_defaults() metal = mcl_sounds.node_sound_metal_defaults()
} }
elseif morelights.game == "hades_revisited" then
morelights.sounds = {
default = hades_sounds.node_sound_defaults(),
glass = hades_sounds.node_sound_glass_defaults(),
metal = hades_sounds.node_sound_metal_defaults()
}
end end
morelights.craft_items = { morelights.craft_items = {
@ -88,7 +96,7 @@ morelights.craft_items = {
sandstone_block = "default:sandstone_block", sandstone_block = "default:sandstone_block",
dirt = "default:dirt", dirt = "default:dirt",
grass = "default:grass_1", grass = "default:grass_1",
cotton = "farming:cotton", string = "farming:string",
stick = "default:stick", stick = "default:stick",
} }
@ -111,8 +119,31 @@ if morelights.game == "mineclone2" then
a.sandstone_block = "mcl_core:sandstonesmooth" a.sandstone_block = "mcl_core:sandstonesmooth"
a.dirt = "mcl_core:dirt" a.dirt = "mcl_core:dirt"
a.grass = "mcl_flowers:tallgrass" a.grass = "mcl_flowers:tallgrass"
a.cotton = "mcl_mobitems:string" a.string = "mcl_mobitems:string"
a.stick = "mcl_core:stick" a.stick = "mcl_core:stick"
elseif morelights.game == "hades_revisited" then
a.glass = "hades_core:glass"
-- HR doesn't have glass panes. :(
a.glass_pane = "hades_core:glass"
if minetest.get_modpath("hades_xpanes") then
a.glass_pane = "hades_xpanes:pane_flat"
end
a.steel = "hades_core:steel_ingot"
a.copper = "hades_core:copper_ingot"
a.tin = "hades_core:tin_ingot"
a.crystal_fragment = "hades_core:mese_crystal_fragment"
a.dye_dark = "dye:dark_grey"
a.dye_light = "dye:white"
a.wool_dark = "wool:grey"
a.wool_light = "wool:white"
a.wood_dark = "hades_trees:jungle_wood"
a.stone_block = "hades_core:stone_block"
a.sandstone_block = "hades_core:sandstone"
a.dirt = "hades_core:dirt"
a.grass = "hades_grass:grass_1"
a.string = "hades_farming:cotton"
a.stick = "hades_core:stick"
end end
-- Use basic_materials brass if available, otherwise register our own. -- Use basic_materials brass if available, otherwise register our own.
@ -121,4 +152,4 @@ if minetest.get_modpath("basic_materials") then
end end
local path = minetest.get_modpath("morelights") local path = minetest.get_modpath("morelights")
dofile(path .. DIR_DELIM .. "nodes.lua") dofile(path .. "/nodes.lua")

View file

@ -1,3 +1,3 @@
name = morelights name = morelights
description = Base mod providing basic items, which the rest of the modpack depends on. description = Base mod providing basic items, which the rest of the modpack depends on.
optional_depends = default, mcl_core optional_depends = default, mcl_core, hades_core

View file

@ -35,41 +35,63 @@ do
-- For MineClone 2, use node coloring to match environment. -- For MineClone 2, use node coloring to match environment.
-- See the mcl_core:dirt_with_grass definition in -- See the mcl_core:dirt_with_grass definition in
-- ITEMS/mcl_core/nodes_base.lua. -- ITEMS/mcl_core/nodes_base.lua.
local override = { def.tiles = {
tiles = { "mcl_core_grass_block_top.png",
"mcl_core_grass_block_top.png", {name = "default_dirt.png", color = "#FFFFFF"}
{name = "default_dirt.png", color = "#FFFFFF"} }
}, def.overlay_tiles = {
overlay_tiles = { {name = "morelights_extras_blocklight.png", color = "#FFFFFF"},
{name = "morelights_extras_blocklight.png", color = "#FFFFFF"}, "",
"", {
{ name = "mcl_core_grass_block_side_overlay.png",
name = "mcl_core_grass_block_side_overlay.png", tileable_vertical = false
tileable_vertical = false }
} }
}, def.paramtype2 = "color"
paramtype2 = "color", def.palette = "mcl_core_palette_grass.png"
palette = "mcl_core_palette_grass.png", def.palette_index = 0
palette_index = 0, def.color = "#55aa60"
color = "#55aa60", def.drop = "morelights_extras:dirt_with_grass"
drop = "morelights_extras:dirt_with_grass",
on_construct = function(pos) def.on_construct = function(pos)
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
if node.param2 == 0 then if node.param2 == 0 then
local grass_node = mcl_core.get_grass_block_type(pos) local grass_node = mcl_core.get_grass_block_type(pos)
if grass_node.param2 ~= 0 then if grass_node.param2 ~= 0 then
minetest.set_node(pos, { minetest.set_node(pos, {
name = "morelights_extras:dirt_with_grass", name = "morelights_extras:dirt_with_grass",
param2 = grass_node.param2 param2 = grass_node.param2
}) })
end
end end
end end
end
elseif morelights.game == "hades_revisited" then
-- For Hades Revisited, grass color is seasonal.
-- See hades_core/dirt.lua, ABM in hades_core/functions.lua.
def.tiles = {
"hades_core_grass_cover_colorable.png",
{name = "default_dirt.png", color = "#FFFFFF"},
} }
def.overlay_tiles = {
{name = "morelights_extras_blocklight.png", color = "#FFFFFF"},
"",
{
name = "hades_core_grass_side_cover_colorable.png",
tileable_vertical = false
},
}
def.paramtype2 = "color"
def.palette = "hades_core_palette_grass.png"
def.palette_index = 0
def.color = "#acef6a"
-- To enable seasonal grass coloring.
def.groups.dirt_with_grass = 1
-- To prevent color retention on digging.
def.drop = "morelights_extras:dirt_with_grass"
for k, v in pairs(override) do def.on_place = function(itemstack, placer, pointed_thing)
def[k] = v local param2 = hades_core.get_seasonal_grass_color_param2()
return minetest.item_place(itemstack, placer, pointed_thing, param2)
end end
end end
@ -97,6 +119,8 @@ do
local tile = "default_sandstone_block.png" local tile = "default_sandstone_block.png"
if morelights.game == "mineclone2" then if morelights.game == "mineclone2" then
tile = "mcl_core_sandstone_smooth.png" tile = "mcl_core_sandstone_smooth.png"
elseif morelights.game == "hades_revisited" then
tile = "default_sandstone.png"
end end
minetest.register_node("morelights_extras:sandstone_block", { minetest.register_node("morelights_extras:sandstone_block", {
@ -158,8 +182,8 @@ minetest.register_node("morelights_extras:stairlight", {
or node.name:match("^mcl_stairs:stair_")) then or node.name:match("^mcl_stairs:stair_")) then
-- Set `above` to the node actually above the stair, since that's -- Set `above` to the node actually above the stair, since that's
-- where the node is placed. -- where the node is placed.
pointed_thing.above = vector.add(pointed_thing.under, pointed_thing.above =
{x=0, y=1, z=0}) vector.add(pointed_thing.under, vector.new(0, 1, 0))
return minetest.item_place_node(itemstack, placer, pointed_thing, return minetest.item_place_node(itemstack, placer, pointed_thing,
node.param2) node.param2)
end end

View file

@ -348,7 +348,7 @@ minetest.register_craft({
output = "morelights_vintage:oillamp", output = "morelights_vintage:oillamp",
recipe = { recipe = {
{"", a.glass, ""}, {"", a.glass, ""},
{"", a.cotton, ""}, {"", a.string, ""},
{"", a.brass, ""} {"", a.brass, ""}
} }
}) })

View file

@ -805,4 +805,4 @@ if minetest.get_modpath("mesecons_mvps") then
end end
print (S("[MOD] Protector Redo loaded")) print ("[MOD] Protector Redo loaded")

View file

@ -23,7 +23,7 @@ and minetest.settings:get_bool("protector_pvp") then
if not player if not player
or not hitter then or not hitter then
print(S("[Protector] on_punchplayer called with nil objects")) print("[Protector] on_punchplayer called with nil objects")
end end
if not hitter:is_player() then if not hitter:is_player() then
@ -64,9 +64,9 @@ and minetest.settings:get_bool("protector_pvp") then
end) end)
else else
print(S("[Protector] pvp_protect not active, update your version of Minetest")) print("[Protector] pvp_protect not active, update your version of Minetest")
end end
else else
print(S("[Protector] pvp_protect is disabled")) print("[Protector] pvp_protect is disabled")
end end

View file

@ -78,6 +78,11 @@ minetest.register_craftitem("protector:tool", {
return return
end end
-- do not place protector out of map bounds
if minetest.find_node_near(pos, 1, {"ignore"}) then
return
end
-- do we have protectors to use ? -- do we have protectors to use ?
local nod local nod
local inv = user:get_inventory() local inv = user:get_inventory()

View file

@ -1,3 +1,3 @@
Skeleton Skeleton
I dont know I dont know
CC BY-SA 3.0 CC BY-SA 4.0

View file

@ -0,0 +1,3 @@
TommyInnit
Christian_Soldier
CC 0 (1.0)

View file

@ -0,0 +1,3 @@
Dream(fixed4Real)
Christian_Soldier
CC 0 (1.0)

View file

@ -0,0 +1,3 @@
Ranboo
Christian_Soldier
CC 0 (1.0)

View file

@ -1,3 +1,3 @@
nick_ nick_ I
nick_ nick_
CC BY-SA 3.0 CC BY-SA 3.0

View file

@ -0,0 +1,3 @@
RedMiniontoby
Miniontoby
CC BY-NC-SA 4.0

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

@ -186,6 +186,7 @@ tubelib_addons13 optional: minecart
- 2020-11-20 V2.04 * Switch to AGPL v3, adapt to minetest 5.3, add translation support, fix minor bugs - 2020-11-20 V2.04 * Switch to AGPL v3, adapt to minetest 5.3, add translation support, fix minor bugs
- 2021-01-24 V2.05 * PR #74, #76: Implement checks for valid connection sides for many nodes - 2021-01-24 V2.05 * PR #74, #76: Implement checks for valid connection sides for many nodes
- 2021-06-06 V2.06 * PR #78 - #89, chest cart added - 2021-06-06 V2.06 * PR #78 - #89, chest cart added
- 2021-09-03 V2.07 * FR #103, Add Altitude to harvester menu
## New in v2 (from players point of view) ## New in v2 (from players point of view)

View file

@ -693,7 +693,7 @@ minetest.register_node("gravelsieve:compressed_gravel", {
}) })
minetest.register_craft({ minetest.register_craft({
output = "gravelsieve:sieve", output = "gravelsieve:sieve3",
recipe = { recipe = {
{"group:wood", "", "group:wood"}, {"group:wood", "", "group:wood"},
{"group:wood", "default:steel_ingot", "group:wood"}, {"group:wood", "default:steel_ingot", "group:wood"},
@ -702,10 +702,10 @@ minetest.register_craft({
}) })
minetest.register_craft({ minetest.register_craft({
output = "gravelsieve:auto_sieve", output = "gravelsieve:auto_sieve3",
type = "shapeless", type = "shapeless",
recipe = { recipe = {
"gravelsieve:sieve", "default:mese_crystal", "default:mese_crystal", "gravelsieve:sieve3", "default:mese_crystal", "default:mese_crystal",
}, },
}) })

View file

@ -3,7 +3,7 @@
Tubelib Addons 1 Tubelib Addons 1
================ ================
Copyright (C) 2017-2020 Joachim Stolberg Copyright (C) 2017-2021 Joachim Stolberg
AGPL v3 AGPL v3
See LICENSE.txt for more information See LICENSE.txt for more information
@ -27,7 +27,7 @@ local P = minetest.string_to_pos
local M = minetest.get_meta local M = minetest.get_meta
local CYCLE_TIME = 6 local CYCLE_TIME = 6
local MAX_HEIGHT = 18 -- harvesting altitude local START_HEIGHT = 18 -- harvesting altitude
local MAX_DIAMETER = 33 local MAX_DIAMETER = 33
local BURNING_TIME = 20 -- fuel local BURNING_TIME = 20 -- fuel
local STANDBY_TICKS = 4 -- used for blocked state local STANDBY_TICKS = 4 -- used for blocked state
@ -35,13 +35,14 @@ local COUNTDOWN_TICKS = 2
local OFFSET = 5 -- for uneven terrains local OFFSET = 5 -- for uneven terrains
-- start on top of the base block -- start on top of the base block
local function working_start_pos(pos) local function working_start_pos(pos, altitude)
local working_pos = table.copy(pos) local working_pos = table.copy(pos)
working_pos.y = working_pos.y + MAX_HEIGHT working_pos.y = working_pos.y + (altitude or START_HEIGHT)
return working_pos return working_pos
end end
local Radius2Idx = {[4]=1 ,[6]=2, [8]=3, [10]=4, [12]=5, [14]=6, [16]=7} local Radius2Idx = {[4]=1 ,[6]=2, [8]=3, [10]=4, [12]=5, [14]=6, [16]=7}
local Altitude2Idx = {[-2]=1 ,[-1]=2, [0]=3, [1]=4, [2]=5, [4]=6, [6]=7, [8]=8, [10]=9, [14]=10, [18]=11}
local function formspec(self, pos, meta) local function formspec(self, pos, meta)
-- some recalculations -- some recalculations
@ -52,6 +53,7 @@ local function formspec(self, pos, meta)
fuel = 0 fuel = 0
end end
local radius = Radius2Idx[this.radius] or 2 local radius = Radius2Idx[this.radius] or 2
local altitude = Altitude2Idx[this.altitude or START_HEIGHT] or 11
return "size[9,8]".. return "size[9,8]"..
default.gui_bg.. default.gui_bg..
@ -59,7 +61,9 @@ local function formspec(self, pos, meta)
default.gui_slots.. default.gui_slots..
"dropdown[0,0;1.5;radius;4,6,8,10,12,14,16;"..radius.."]".. "dropdown[0,0;1.5;radius;4,6,8,10,12,14,16;"..radius.."]"..
"label[1.6,0.2;"..S("Area radius").."]".. "label[1.6,0.2;"..S("Area radius").."]"..
"checkbox[0,1;endless;"..S("Run endless")..";"..endless.."]".. "dropdown[0,1;1.5;altitude;-2,-1,0,1,2,4,6,8,10,14,18;"..altitude.."]"..
"label[1.6,1.2;"..S("Altitude ").."]"..
"checkbox[0,2;endless;"..S("Run endless")..";"..endless.."]"..
"list[context;main;5,0;4,4;]".. "list[context;main;5,0;4,4;]"..
"list[context;fuel;1.5,3;1,1;]".. "list[context;fuel;1.5,3;1,1;]"..
"item_image[1.5,3;1,1;tubelib_addons1:biofuel]".. "item_image[1.5,3;1,1;tubelib_addons1:biofuel]"..
@ -82,7 +86,7 @@ local State = tubelib.NodeStates:new({
on_start = function(pos, meta, oldstate) on_start = function(pos, meta, oldstate)
local this = minetest.deserialize(meta:get_string("this")) local this = minetest.deserialize(meta:get_string("this"))
this.idx = 0 this.idx = 0
this.working_pos = working_start_pos(pos) this.working_pos = working_start_pos(pos, this.altitude)
meta:set_string("this", minetest.serialize(this)) meta:set_string("this", minetest.serialize(this))
end, end,
formspec_func = formspec, formspec_func = formspec,
@ -210,7 +214,7 @@ local function calc_new_pos(pos, this, meta)
if this.idx >= this.max then if this.idx >= this.max then
if this.endless == 1 then if this.endless == 1 then
this.idx = 0 this.idx = 0
this.working_pos = working_start_pos(pos) this.working_pos = working_start_pos(pos, this.altitude)
return true return true
else else
return false return false
@ -227,7 +231,7 @@ local function harvest_field(this, meta)
local inv = meta:get_inventory() local inv = meta:get_inventory()
local pos = table.copy(this.working_pos) local pos = table.copy(this.working_pos)
local start_y_pos = pos.y - 1 local start_y_pos = pos.y - 1
local stop_y_pos = pos.y - MAX_HEIGHT - OFFSET local stop_y_pos = pos.y - (this.altitude or START_HEIGHT) - OFFSET
if minetest.is_protected(pos, this.owner) then if minetest.is_protected(pos, this.owner) then
return true return true
end end
@ -297,6 +301,7 @@ local function on_receive_fields(pos, formname, fields, player)
local meta = M(pos) local meta = M(pos)
local this = minetest.deserialize(meta:get_string("this")) local this = minetest.deserialize(meta:get_string("this"))
local radius = this.radius local radius = this.radius
local altitude = this.altitude or START_HEIGHT
if fields.radius ~= nil then if fields.radius ~= nil then
radius = tonumber(fields.radius) radius = tonumber(fields.radius)
@ -308,6 +313,15 @@ local function on_receive_fields(pos, formname, fields, player)
State:stop(pos, meta) State:stop(pos, meta)
end end
if fields.altitude ~= nil then
altitude = tonumber(fields.altitude)
end
if altitude ~= this.altitude then
this.altitude = altitude
meta:set_string("this", minetest.serialize(this))
State:stop(pos, meta)
end
if fields.endless ~= nil then if fields.endless ~= nil then
this.endless = fields.endless == "true" and 1 or 0 this.endless = fields.endless == "true" and 1 or 0
end end
@ -334,7 +348,7 @@ minetest.register_node("tubelib_addons1:harvester_base", {
local this = { local this = {
number = number, number = number,
owner = placer:get_player_name(), owner = placer:get_player_name(),
working_pos = working_start_pos(pos), working_pos = working_start_pos(pos, START_HEIGHT),
fuel = 0, fuel = 0,
endless = 0, endless = 0,
radius = 6, radius = 6,
@ -392,7 +406,7 @@ minetest.register_node("tubelib_addons1:harvester_defect", {
local this = { local this = {
number = number, number = number,
owner = placer:get_player_name(), owner = placer:get_player_name(),
working_pos = working_start_pos(pos), working_pos = working_start_pos(pos, START_HEIGHT),
fuel = 0, fuel = 0,
endless = 0, endless = 0,
radius = 6, radius = 6,
@ -487,7 +501,7 @@ minetest.register_lbm({
local meta = M(pos) local meta = M(pos)
local this = minetest.deserialize(meta:get_string("this")) local this = minetest.deserialize(meta:get_string("this"))
if this then if this then
this.working_pos = this.copter_pos or working_start_pos(pos) this.working_pos = this.copter_pos or working_start_pos(pos, this.altitude)
meta:set_string("this", minetest.serialize(this)) meta:set_string("this", minetest.serialize(this))
end end
end end

View file

@ -41,6 +41,7 @@ Tubelib Grinder=
### harvester.lua ### ### harvester.lua ###
: running (= : running (=
Altitude =
Area radius= Area radius=
Tubelib Harvester= Tubelib Harvester=
Tubelib Harvester Base= Tubelib Harvester Base=

View file

@ -41,6 +41,7 @@ Tubelib Grinder=Tubelib Mühle
### harvester.lua ### ### harvester.lua ###
: running (=: läuft ( : running (=: läuft (
Altitude = Flughöhe
Area radius=Flächenradius Area radius=Flächenradius
Tubelib Harvester=Tubelib Ernter Tubelib Harvester=Tubelib Ernter
Tubelib Harvester Base=Tubelib Ernter Basis Tubelib Harvester Base=Tubelib Ernter Basis

View file

@ -90,36 +90,44 @@ end
-- Farming Redo -- Farming Redo
----------------------------------------------- -------------------------------- ----------------------------------------------- --------------------------------
if farming.mod == "redo" then if farming.mod == "redo" then
fn("farming:wheat_8", "farming:wheat", "farming:wheat_1") fn("farming:artichoke_5", "farming:artichoke", "farming:artichoke_1")
fn("farming:cotton_8", "farming:cotton", "farming:cotton_1") fn("farming:barley_7", "farming:barley", "farming:barley_1")
fn("farming:carrot_8", "farming:carrot 2", "farming:carrot_1") fn("farming:beanpole_5", "farming:beans 3", "farming:beanpole_1")
fn("farming:potato_4", "farming:potato 3", "farming:potato_1") fn("farming:beetroot_5", "farming:beetroot 2", "farming:beetroot_1")
fn("farming:tomato_8", "farming:tomato 3", "farming:tomato_1") fn("farming:blackberry_4", "farming:blackberry", "farming:blackberry_1")
fn("farming:cucumber_4", "farming:cucumber 2", "farming:cucumber_1") fn("farming:blueberry_4", "farming:blueberries", "farming:blueberry_1")
fn("farming:corn_8", "farming:corn 2", "farming:corn_1") fn("farming:cabbage_6", "farming:cabbage", "farming:cabbage_1")
fn("farming:coffee_5", "farming:coffee_beans 2", "farming:coffee_1") fn("farming:carrot_8", "farming:carrot 2", "farming:carrot_1")
fn("farming:melon_8", "farming:melon_slice 4", "farming:melon_1") fn("farming:chili_8", "farming:chili_pepper 2", "farming:chili_1")
fn("farming:pumpkin_8", "farming:pumpkin_slice 4","farming:pumpkin_1") fn("farming:cocoa_4", "farming:cocoa_beans 2", "farming:cocoa_1")
fn("farming:raspberry_4", "farming:raspberries", "farming:raspberry_1") fn("farming:coffee_5", "farming:coffee_beans 2", "farming:coffee_1")
fn("farming:blueberry_4", "farming:blueberries", "farming:blueberry_1") fn("farming:corn_8", "farming:corn 2", "farming:corn_1")
fn("farming:rhubarb_3", "farming:rhubarb 2", "farming:rhubarb_1") fn("farming:cotton_8", "farming:cotton", "farming:cotton_1")
fn("farming:beanpole_5", "farming:beans 3", "farming:beanpole_1") fn("farming:cucumber_4", "farming:cucumber 2", "farming:cucumber_1")
fn("farming:grapes_8", "farming:grapes 3", "farming:grapes_1") fn("farming:garlic_5", "farming:garlic 2", "farming:garlic_1")
fn("farming:barley_7", "farming:barley", "farming:barley_1") fn("farming:grapes_8", "farming:grapes 3", "farming:grapes_1")
fn("farming:chili_8", "farming:chili_pepper 2", "farming:chili_1") fn("farming:hemp_8", "farming:hemp_leaf", "farming:hemp_1")
fn("farming:hemp_8", "farming:hemp_leaf", "farming:hemp_1") fn("farming:lettuce_5", "farming:lettuce", "farming:lettuce_1")
fn("farming:oat_8", "farming:oat", "farming:oat_1") fn("farming:melon_8", "farming:melon_slice 4", "farming:melon_1")
fn("farming:rye_8", "farming:rye", "farming:rye_1") fn("farming:mint_4", "farming:mint_leaf 2", "farming:mint_1")
fn("farming:rice_8", "farming:rice", "farming:rice_1") fn("farming:oat_8", "farming:oat", "farming:oat_1")
fn('farming:beetroot_5', 'farming:beetroot 2', 'farming:beetroot_1') fn("farming:onion_5", "farming:onion 2", "farming:onion_1")
fn('farming:cocoa_4', 'farming:cocoa_beans 2', 'farming:cocoa_1') fn("farming:parsley_3", "farming:parsley", "farming:parsley_1")
fn('farming:garlic_5', 'farming:garlic 2', 'farming:garlic_1') fn("farming:pea_5", "farming:pea_pod 3", "farming:pea_1")
fn('farming:onion_5', 'farming:onion 2', 'farming:onion_1') fn("farming:pepper_5", "farming:pepper 2", "farming:pepper_1")
fn('farming:pea_5', 'farming:pea_pod 3', 'farming:pea_1') fn("farming:pepper_6", "farming:pepper_yellow 2", "farming:pepper_1")
fn('farming:pepper_5', 'farming:pepper 2', 'farming:pepper_1') fn("farming:pepper_7", "farming:pepper_red 2", "farming:pepper_1")
fn('farming:pepper_6', 'farming:pepper_yellow 2','farming:pepper_1') fn("farming:pineapple_8", "farming:pineapple 1", "farming:pineapple_1")
fn('farming:pepper_7', 'farming:pepper_red 2', 'farming:pepper_1') fn("farming:potato_4", "farming:potato 3", "farming:potato_1")
fn('farming:pineapple_8', 'farming:pineapple 1', 'farming:pineapple_1') fn("farming:pumpkin_8", "farming:pumpkin_slice 4", "farming:pumpkin_1")
fn("farming:raspberry_4", "farming:raspberries", "farming:raspberry_1")
fn("farming:rhubarb_3", "farming:rhubarb 2", "farming:rhubarb_1")
fn("farming:rice_8", "farming:rice", "farming:rice_1")
fn("farming:rye_8", "farming:rye", "farming:rye_1")
fn("farming:soy_7", "farming:soy_pod", "farming:soy_1")
fn("farming:tomato_8", "farming:tomato 3", "farming:tomato_1")
fn("farming:vanilla_8", "farming:vanilla 2", "farming:vanilla_1")
fn("farming:wheat_8", "farming:wheat", "farming:wheat_1")
end end
------------------------------------------------------------------------------- -------------------------------------------------------------------------------

View file

@ -43,7 +43,8 @@ unified_inventory = {
imgscale = 1.25, imgscale = 1.25,
list_img_offset = 0.13, list_img_offset = 0.13,
standard_background = "background9[0,0;1,1;ui_formbg_9_sliced.png;true;16]", standard_background = "background9[0,0;1,1;ui_formbg_9_sliced.png;true;16]",
version = 2
version = 3
} }
local ui = unified_inventory local ui = unified_inventory

View file

@ -22,7 +22,9 @@ end
function ui.get_per_player_formspec(player_name) function ui.get_per_player_formspec(player_name)
local draw_lite_mode = ui.lite_mode and not minetest.check_player_privs(player_name, {ui_full=true}) local draw_lite_mode = ui.lite_mode and not minetest.check_player_privs(player_name, {ui_full=true})
return table.copy(draw_lite_mode and ui.style_lite or ui.style_full), draw_lite_mode local style = table.copy(draw_lite_mode and ui.style_lite or ui.style_full)
style.is_lite_mode = draw_lite_mode
return style
end end
local function formspec_button(ui_peruser, name, image, offset, pos, scale, label) local function formspec_button(ui_peruser, name, image, offset, pos, scale, label)
@ -41,113 +43,82 @@ local function formspec_button(ui_peruser, name, image, offset, pos, scale, labe
string.format("tooltip[%s;%s]", name, F(label or name)) string.format("tooltip[%s;%s]", name, F(label or name))
end end
function ui.get_formspec(player, page) local function formspec_add_filters(player, formspec, style)
if not player then
return ""
end
local player_name = player:get_player_name()
local ui_peruser,draw_lite_mode = ui.get_per_player_formspec(player_name)
ui.current_page[player_name] = page
local pagedef = ui.pages[page]
if not pagedef then
return "" -- Invalid page name
end
local formspec = {
"formspec_version[4]",
"size["..ui_peruser.formw..","..ui_peruser.formh.."]",
pagedef.formspec_prepend and "" or "no_prepend[]",
ui.standard_background
}
local n = 5
local perplayer_formspec = ui.get_per_player_formspec(player_name)
local fsdata = pagedef.get_formspec(player, perplayer_formspec)
formspec[n] = fsdata.formspec
n = n+1
local button_row = 0 local button_row = 0
local button_col = 0 local button_col = 0
local n = #formspec + 1
-- Main buttons -- Main buttons
local filtered_inv_buttons = {} local filtered_inv_buttons = {}
for i, def in pairs(ui.buttons) do for i, def in pairs(ui.buttons) do
if not (draw_lite_mode and def.hide_lite) then if not (style.is_lite_mode and def.hide_lite) then
table.insert(filtered_inv_buttons, def) table.insert(filtered_inv_buttons, def)
end end
end end
for i, def in pairs(filtered_inv_buttons) do for i, def in pairs(filtered_inv_buttons) do
if style.is_lite_mode and i > 4 then
if draw_lite_mode and i > 4 then
button_row = 1 button_row = 1
button_col = 1 button_col = 1
end end
if def.type == "image" then if def.type == "image" then
local pos_x = style.main_button_x + style.btn_spc * (i - 1) - button_col * style.btn_spc * 4
local pos_y = style.main_button_y + button_row * style.btn_spc
if (def.condition == nil or def.condition(player) == true) then if (def.condition == nil or def.condition(player) == true) then
formspec[n] = string.format("image_button[%f,%f;%f,%f;%s;%s;]", formspec[n] = string.format("image_button[%f,%f;%f,%f;%s;%s;]",
ui_peruser.main_button_x + ui_peruser.btn_spc * (i - 1) - button_col * ui_peruser.btn_spc * 4, pos_x, pos_y, style.btn_size, style.btn_size,
ui_peruser.main_button_y + button_row * ui_peruser.btn_spc,
ui_peruser.btn_size,ui_peruser.btn_size,
F(def.image), F(def.image),
F(def.name)) F(def.name))
formspec[n+1] = "tooltip["..F(def.name)..";"..(def.tooltip or "").."]" formspec[n+1] = "tooltip["..F(def.name)..";"..(def.tooltip or "").."]"
n = n+2 n = n+2
else else
formspec[n] = string.format("image[%f,%f;%f,%f;%s^[colorize:#808080:alpha]", formspec[n] = string.format("image[%f,%f;%f,%f;%s^[colorize:#808080:alpha]",
ui_peruser.main_button_x + ui_peruser.btn_spc * (i - 1) - button_col * ui_peruser.btn_spc * 4, pos_x, pos_y, style.btn_size, style.btn_size,
ui_peruser.main_button_y + button_row * ui_peruser.btn_spc, def.image)
ui_peruser.btn_size,ui_peruser.btn_size,def.image)
n = n+1 n = n+1
end end
end end
end end
end
if fsdata.draw_inventory ~= false then local function formspec_add_categories(player, formspec, ui_peruser)
-- Player inventory local player_name = player:get_player_name()
formspec[n] = "listcolors[#00000000;#00000000]" local n = #formspec + 1
formspec[n+1] = ui_peruser.standard_inv
n = n+2
end
if fsdata.draw_item_list == false then local categories_pos = {
return table.concat(formspec, "") ui_peruser.page_x,
end ui_peruser.page_y-ui_peruser.btn_spc-0.5
}
-- Category filters local categories_scroll_pos = {
ui_peruser.page_x,
local categories_pos = { ui_peruser.page_x, ui_peruser.page_y-ui_peruser.btn_spc-0.5 } ui_peruser.form_header_y - (ui_peruser.is_lite_mode and 0 or 0.2)
local categories_scroll_pos = { ui_peruser.page_x, ui_peruser.form_header_y-(draw_lite_mode and 0 or 0.2) } }
formspec[n] = string.format("background9[%f,%f;%f,%f;%s;false;3]", formspec[n] = string.format("background9[%f,%f;%f,%f;%s;false;3]",
ui_peruser.page_x-0.1, categories_scroll_pos[2], ui_peruser.page_x-0.1, categories_scroll_pos[2],
(ui_peruser.btn_spc * ui_peruser.pagecols) + 0.13, 1.4+(draw_lite_mode and 0 or 0.2), (ui_peruser.btn_spc * ui_peruser.pagecols) + 0.13, 1.4 + (ui_peruser.is_lite_mode and 0 or 0.2),
"ui_smallbg_9_sliced.png") "ui_smallbg_9_sliced.png")
n = n + 1 n = n + 1
formspec[n] = string.format("label[%f,%f;%s]", ui_peruser.page_x, ui_peruser.form_header_y+(draw_lite_mode and 0.3 or 0.2), "Category:") formspec[n] = string.format("label[%f,%f;%s]",
ui_peruser.page_x,
ui_peruser.form_header_y + (ui_peruser.is_lite_mode and 0.3 or 0.2), F(S("Category:")))
n = n + 1 n = n + 1
local scroll_offset = 0 local scroll_offset = 0
local category_count = #unified_inventory.category_list local category_count = #ui.category_list
if category_count > ui_peruser.pagecols then if category_count > ui_peruser.pagecols then
scroll_offset = unified_inventory.current_category_scroll[player_name] scroll_offset = ui.current_category_scroll[player_name]
end end
for index, category in ipairs(unified_inventory.category_list) do for index, category in ipairs(ui.category_list) do
local column = index - scroll_offset local column = index - scroll_offset
if column > 0 and column <= ui_peruser.pagecols then if column > 0 and column <= ui_peruser.pagecols then
local scale = 0.8 local scale = 0.8
if unified_inventory.current_category[player_name] == category.name then if ui.current_category[player_name] == category.name then
scale = 1 scale = 1
end end
formspec[n] = formspec_button(ui_peruser, "category_"..category.name, category.symbol, categories_pos, {column-1, 0}, scale, category.label) formspec[n] = formspec_button(ui_peruser, "category_"..category.name, category.symbol, categories_pos, {column-1, 0}, scale, category.label)
@ -162,10 +133,13 @@ function ui.get_formspec(player, page)
if category_count > ui_peruser.pagecols and category_count - scroll_offset > ui_peruser.pagecols then if category_count > ui_peruser.pagecols and category_count - scroll_offset > ui_peruser.pagecols then
-- next -- next
formspec[n] = formspec_button(ui_peruser, "next_category", "ui_right_icon.png", categories_scroll_pos, {ui_peruser.pagecols - 1, 0}, 0.8, S("Scroll categories right")) formspec[n] = formspec_button(ui_peruser, "next_category", "ui_right_icon.png", categories_scroll_pos, {ui_peruser.pagecols - 1, 0}, 0.8, S("Scroll categories right"))
n = n + 1
end end
end
local function formspec_add_search_box(player, formspec, ui_peruser)
local player_name = player:get_player_name()
local n = #formspec + 1
-- Search box
formspec[n] = "field_close_on_enter[searchbox;false]" formspec[n] = "field_close_on_enter[searchbox;false]"
formspec[n+1] = string.format("field[%f,%f;%f,%f;searchbox;;%s]", formspec[n+1] = string.format("field[%f,%f;%f,%f;searchbox;;%s]",
@ -182,7 +156,16 @@ function ui.get_formspec(player, page)
ui_peruser.btn_size, ui_peruser.btn_size) ui_peruser.btn_size, ui_peruser.btn_size)
formspec[n+5] = "tooltip[searchresetbutton;"..F(S("Reset search and display everything")).."]" formspec[n+5] = "tooltip[searchresetbutton;"..F(S("Reset search and display everything")).."]"
n = n + 6 if ui.activefilter[player_name] ~= "" then
formspec[n+6] = string.format("label[%f,%f;%s: %s]",
ui_peruser.page_x, ui_peruser.page_y - 0.25,
F(S("Filter")), F(ui.activefilter[player_name]))
end
end
local function formspec_add_item_browser(player, formspec, ui_peruser)
local player_name = player:get_player_name()
local n = #formspec + 1
-- Controls to flip items pages -- Controls to flip items pages
@ -195,9 +178,9 @@ function ui.get_formspec(player, page)
{ "ui_skip_forward_icon.png", "end_list", S("Last page") }, { "ui_skip_forward_icon.png", "end_list", S("Last page") },
} }
if draw_lite_mode then if ui_peruser.is_lite_mode then
btnlist[5] = nil
btnlist[2] = nil btnlist[2] = nil
btnlist[5] = nil
end end
local bn = 0 local bn = 0
@ -212,69 +195,109 @@ function ui.get_formspec(player, page)
n = n + 2 n = n + 2
end end
local no_matches = S("No matching items")
if draw_lite_mode then
no_matches = S("No matches.")
end
-- Items list -- Items list
if #ui.filtered_items_list[player_name] == 0 then if #ui.filtered_items_list[player_name] == 0 then
formspec[n] = "label["..ui_peruser.page_x..","..(ui_peruser.page_y+0.15)..";" .. F(no_matches) .. "]" local no_matches = S("No matching items")
else if ui_peruser.is_lite_mode then
local dir = ui.active_search_direction[player_name] no_matches = S("No matches.")
local list_index = ui.current_index[player_name] end
local page2 = math.floor(list_index / (ui_peruser.items_per_page) + 1)
local pagemax = math.floor(
(#ui.filtered_items_list[player_name] - 1)
/ (ui_peruser.items_per_page) + 1)
for y = 0, ui_peruser.pagerows - 1 do
for x = 0, ui_peruser.pagecols - 1 do
local name = ui.filtered_items_list[player_name][list_index]
local item = minetest.registered_items[name]
if item then
-- Clicked on current item: Flip crafting direction
if name == ui.current_item[player_name] then
local cdir = ui.current_craft_direction[player_name]
if cdir == "recipe" then
dir = "usage"
elseif cdir == "usage" then
dir = "recipe"
end
else
-- Default: use active search direction by default
dir = ui.active_search_direction[player_name]
end
local button_name = "item_button_" .. dir .. "_" formspec[n] = "label["..ui_peruser.page_x..","..(ui_peruser.page_y+0.15)..";" .. F(no_matches) .. "]"
.. ui.mangle_for_formspec(name) return
formspec[n] = ("item_image_button[%f,%f;%f,%f;%s;%s;]"):format( end
ui_peruser.page_x + x * ui_peruser.btn_spc,
ui_peruser.page_y + y * ui_peruser.btn_spc, local dir = ui.active_search_direction[player_name]
ui_peruser.btn_size, ui_peruser.btn_size, local list_index = ui.current_index[player_name]
name, button_name local page2 = math.floor(list_index / (ui_peruser.items_per_page) + 1)
) local pagemax = math.floor(
formspec[n + 1] = ("tooltip[%s;%s \\[%s\\]]"):format( (#ui.filtered_items_list[player_name] - 1)
button_name, minetest.formspec_escape(item.description), / (ui_peruser.items_per_page) + 1)
item.mod_origin or "??" for y = 0, ui_peruser.pagerows - 1 do
) for x = 0, ui_peruser.pagecols - 1 do
n = n + 2 local name = ui.filtered_items_list[player_name][list_index]
list_index = list_index + 1 local item = minetest.registered_items[name]
if item then
-- Clicked on current item: Flip crafting direction
if name == ui.current_item[player_name] then
local cdir = ui.current_craft_direction[player_name]
if cdir == "recipe" then
dir = "usage"
elseif cdir == "usage" then
dir = "recipe"
end
else
-- Default: use active search direction by default
dir = ui.active_search_direction[player_name]
end end
local button_name = "item_button_" .. dir .. "_"
.. ui.mangle_for_formspec(name)
formspec[n] = ("item_image_button[%f,%f;%f,%f;%s;%s;]"):format(
ui_peruser.page_x + x * ui_peruser.btn_spc,
ui_peruser.page_y + y * ui_peruser.btn_spc,
ui_peruser.btn_size, ui_peruser.btn_size,
name, button_name
)
formspec[n + 1] = ("tooltip[%s;%s \\[%s\\]]"):format(
button_name, minetest.formspec_escape(item.description),
item.mod_origin or "??"
)
n = n + 2
list_index = list_index + 1
end end
end end
formspec[n] = string.format("label[%f,%f;%s: %s]",
ui_peruser.page_buttons_x + ui_peruser.btn_spc * (draw_lite_mode and 1 or 2),
ui_peruser.page_buttons_y + 0.1 + ui_peruser.btn_spc * 2,
F(S("Page")), S("@1 of @2",page2,pagemax))
end end
n= n+1 formspec[n] = string.format("label[%f,%f;%s: %s]",
ui_peruser.page_buttons_x + ui_peruser.btn_spc * (ui_peruser.is_lite_mode and 1 or 2),
ui_peruser.page_buttons_y + 0.1 + ui_peruser.btn_spc * 2,
F(S("Page")), S("@1 of @2",page2,pagemax))
end
if ui.activefilter[player_name] ~= "" then function ui.get_formspec(player, page)
formspec[n] = string.format("label[%f,%f;%s: %s]",
ui_peruser.page_x, ui_peruser.page_y - 0.25, if not player then
F(S("Filter")), F(ui.activefilter[player_name])) return ""
end end
return table.concat(formspec, "")
local player_name = player:get_player_name()
local ui_peruser = ui.get_per_player_formspec(player_name)
ui.current_page[player_name] = page
local pagedef = ui.pages[page]
if not pagedef then
return "" -- Invalid page name
end
local fs = {
"formspec_version[4]",
"size["..ui_peruser.formw..","..ui_peruser.formh.."]",
pagedef.formspec_prepend and "" or "no_prepend[]",
ui.standard_background
}
local perplayer_formspec = ui.get_per_player_formspec(player_name)
local fsdata = pagedef.get_formspec(player, perplayer_formspec)
fs[#fs + 1] = fsdata.formspec
formspec_add_filters(player, fs, ui_peruser)
if fsdata.draw_inventory ~= false then
-- Player inventory
fs[#fs + 1] = "listcolors[#00000000;#00000000]"
fs[#fs + 1] = ui_peruser.standard_inv
end
if fsdata.draw_item_list == false then
return table.concat(fs, "")
end
formspec_add_categories(player, fs, ui_peruser)
formspec_add_search_box(player, fs, ui_peruser)
formspec_add_item_browser(player, fs, ui_peruser)
return table.concat(fs)
end end
function ui.set_inventory_formspec(player, page) function ui.set_inventory_formspec(player, page)
@ -355,60 +378,3 @@ function ui.apply_filter(player, filter, search_dir)
ui.set_inventory_formspec(player, ui.set_inventory_formspec(player,
ui.current_page[player_name]) ui.current_page[player_name])
end end
function ui.items_in_group(groups)
local items = {}
for name, item in pairs(minetest.registered_items) do
for _, group in pairs(groups:split(',')) do
if item.groups[group] then
table.insert(items, name)
end
end
end
return items
end
function ui.sort_inventory(inv)
local inlist = inv:get_list("main")
local typecnt = {}
local typekeys = {}
for _, st in ipairs(inlist) do
if not st:is_empty() then
local n = st:get_name()
local w = st:get_wear()
local m = st:get_metadata()
local k = string.format("%s %05d %s", n, w, m)
if not typecnt[k] then
typecnt[k] = {
name = n,
wear = w,
metadata = m,
stack_max = st:get_stack_max(),
count = 0,
}
table.insert(typekeys, k)
end
typecnt[k].count = typecnt[k].count + st:get_count()
end
end
table.sort(typekeys)
local outlist = {}
for _, k in ipairs(typekeys) do
local tc = typecnt[k]
while tc.count > 0 do
local c = math.min(tc.count, tc.stack_max)
table.insert(outlist, ItemStack({
name = tc.name,
wear = tc.wear,
metadata = tc.metadata,
count = c,
}))
tc.count = tc.count - c
end
end
if #outlist > #inlist then return end
while #outlist < #inlist do
table.insert(outlist, ItemStack(nil))
end
inv:set_list("main", outlist)
end