Merge pull request 'develop' (#40) from develop into master
Reviewed-on: #40
|
@ -118,7 +118,7 @@ end
|
|||
-- by ChillCode, available under the MIT license.
|
||||
local function deserialize_workaround(content)
|
||||
local nodes
|
||||
if not jit then
|
||||
if not minetest.global_exists("jit") then
|
||||
nodes = minetest.deserialize(content, true)
|
||||
else
|
||||
-- XXX: This is a filthy hack that works surprisingly well
|
||||
|
|
|
@ -279,7 +279,8 @@ minetest.register_node("bees:hive_wild", {
|
|||
{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
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
|
|
|
@ -68,6 +68,7 @@ if minetest.get_modpath("ethereal") then
|
|||
{"ethereal:mushroom_sapling", ethereal.grow_mushroom_tree, "soil"},
|
||||
{"ethereal:willow_sapling", ethereal.grow_willow_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:bamboo_sprout", ethereal.grow_bamboo_tree, "soil"},
|
||||
{"ethereal:birch_sapling", ethereal.grow_birch_tree, "soil"},
|
||||
|
|
Before Width: | Height: | Size: 187 B After Width: | Height: | Size: 173 B |
|
@ -1,6 +1,16 @@
|
|||
|
||||
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
|
||||
|
||||
|
@ -59,13 +69,39 @@ mobs:register_mob("mobs_monster:dungeon_master", {
|
|||
speed_normal = 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
|
||||
mobs:spawn({
|
||||
name = "mobs_monster:dungeon_master",
|
||||
nodes = {"default:stone"},
|
||||
nodes = {"default:stone", "nether:rack", "nether:rack_deep"},
|
||||
max_light = 5,
|
||||
chance = 9000,
|
||||
active_object_count = 1,
|
||||
|
|
|
@ -30,3 +30,7 @@ mobs.fireball.png was originally made by Sapier and edited by Benrob:
|
|||
--
|
||||
-- (c) Sapier
|
||||
-- Contact sapier a t gmx net
|
||||
|
||||
Textures created by wwar (cc0)
|
||||
mobs_dungeon_master_nether.png
|
||||
mobs_dungeon_master_netherdeep.png
|
||||
|
|
|
@ -12,6 +12,9 @@ mobs:register_mob("mobs_monster:mese_monster", {
|
|||
shoot_interval = 0.5,
|
||||
arrow = "mobs_monster:mese_arrow",
|
||||
shoot_offset = 2,
|
||||
--arrow_override = function(self)
|
||||
-- self.velocity = 20
|
||||
--end,
|
||||
hp_min = 10,
|
||||
hp_max = 25,
|
||||
armor = 80,
|
||||
|
|
BIN
mods/mobs_monster/textures/mobs_dungeon_master_nether.png
Normal file
After Width: | Height: | Size: 3.1 KiB |
BIN
mods/mobs_monster/textures/mobs_dungeon_master_netherdeep.png
Normal file
After Width: | Height: | Size: 2.7 KiB |
|
@ -8,7 +8,7 @@ local use_cmi = minetest.global_exists("cmi")
|
|||
|
||||
mobs = {
|
||||
mod = "redo",
|
||||
version = "20210801",
|
||||
version = "20210905",
|
||||
intllib = S,
|
||||
invis = minetest.global_exists("invisibility") and invisibility or {}
|
||||
}
|
||||
|
@ -160,6 +160,7 @@ local mob_class = {
|
|||
attack_players = true,
|
||||
attack_npcs = true,
|
||||
facing_fence = false,
|
||||
_breed_countdown = nil,
|
||||
_cmi_is_mob = true
|
||||
}
|
||||
|
||||
|
@ -722,6 +723,13 @@ function mobs:effect(pos, amount, texture, min_size, max_size,
|
|||
end
|
||||
|
||||
|
||||
-- Thanks Wuzzy for the following editable settings
|
||||
|
||||
local HORNY_TIME = 30
|
||||
local HORNY_AGAIN_TIME = 60 * 5 -- 5 minutes
|
||||
local CHILD_GROW_TIME = 60 * 20 -- 20 minutes
|
||||
|
||||
|
||||
-- update nametag colour
|
||||
function mob_class:update_tag()
|
||||
|
||||
|
@ -740,9 +748,25 @@ function mob_class:update_tag()
|
|||
col = "#FF0000"
|
||||
end
|
||||
|
||||
-- build infotext
|
||||
local text = ""
|
||||
|
||||
if self.horny == true then
|
||||
|
||||
text = "\nLoving: " .. (self.hornytimer - (HORNY_TIME + HORNY_AGAIN_TIME))
|
||||
|
||||
elseif self.child == true then
|
||||
|
||||
text = "\nGrowing: " .. (self.hornytimer - CHILD_GROW_TIME)
|
||||
|
||||
elseif self._breed_countdown then
|
||||
|
||||
text = "\nBreeding: " .. self._breed_countdown
|
||||
|
||||
end
|
||||
|
||||
self.infotext = "Health: " .. self.health .. " / " .. self.hp_max
|
||||
.. "\n" .. "Owner: " .. self.owner
|
||||
.. text
|
||||
|
||||
-- set changes
|
||||
self.object:set_properties({
|
||||
|
@ -1358,10 +1382,6 @@ function mob_class:follow_holding(clicker)
|
|||
return false
|
||||
end
|
||||
|
||||
-- Thanks Wuzzy for the following editable settings
|
||||
local HORNY_TIME = 30
|
||||
local HORNY_AGAIN_TIME = 60 * 5 -- 5 minutes
|
||||
local CHILD_GROW_TIME = 60 * 20 -- 20 minutes
|
||||
|
||||
-- find two animals of same type and breed if nearby and horny
|
||||
function mob_class:breed()
|
||||
|
@ -1414,6 +1434,8 @@ function mob_class:breed()
|
|||
self.hornytimer = 0
|
||||
self.horny = false
|
||||
end
|
||||
|
||||
self:update_tag()
|
||||
end
|
||||
|
||||
-- find another same animal who is also horny and mate if nearby
|
||||
|
@ -1469,6 +1491,8 @@ function mob_class:breed()
|
|||
self.hornytimer = HORNY_TIME + 1
|
||||
ent.hornytimer = HORNY_TIME + 1
|
||||
|
||||
self:update_tag()
|
||||
|
||||
-- have we reached active mob limit
|
||||
if active_limit > 0 and active_mobs >= active_limit then
|
||||
minetest.chat_send_player(self.owner,
|
||||
|
@ -4667,25 +4691,25 @@ function mobs:feed_tame(self, clicker, feed_count, breed, tame)
|
|||
|
||||
self.object:set_hp(self.health)
|
||||
|
||||
self:update_tag()
|
||||
|
||||
-- make children grow quicker
|
||||
if self.child == true then
|
||||
|
||||
-- self.hornytimer = self.hornytimer + 20
|
||||
-- deduct 10% of the time to adulthood
|
||||
self.hornytimer = self.hornytimer + (
|
||||
(CHILD_GROW_TIME - self.hornytimer) * 0.1)
|
||||
self.hornytimer = math.floor(self.hornytimer + (
|
||||
(CHILD_GROW_TIME - self.hornytimer) * 0.1))
|
||||
--print ("====", self.hornytimer)
|
||||
return true
|
||||
end
|
||||
|
||||
-- feed and tame
|
||||
self.food = (self.food or 0) + 1
|
||||
self._breed_countdown = feed_count - self.food
|
||||
|
||||
if self.food >= feed_count then
|
||||
|
||||
self.food = 0
|
||||
self._breed_countdown = nil
|
||||
|
||||
if breed and self.hornytimer == 0 then
|
||||
self.horny = true
|
||||
|
@ -4711,6 +4735,8 @@ function mobs:feed_tame(self, clicker, feed_count, breed, tame)
|
|||
self:mob_sound(self.sounds.random)
|
||||
end
|
||||
|
||||
self:update_tag()
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
|
@ -4740,6 +4766,22 @@ function mobs:feed_tame(self, clicker, feed_count, breed, tame)
|
|||
return true
|
||||
end
|
||||
|
||||
-- if mob follows items and user right clicks while holding sneak it shows info
|
||||
if self.follow 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(),
|
||||
S("@1 follows:\n- @2",
|
||||
self.name:split(":")[2],
|
||||
table.concat(self.follow, "\n- ")))
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
|
|
|
@ -337,6 +337,10 @@ function circular_saw.on_metadata_inventory_take(
|
|||
local input_stack = inv:get_stack(listname, index)
|
||||
if not input_stack:is_empty() and input_stack:get_name()~=stack:get_name() then
|
||||
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
|
||||
player_inv:add_item("main", input_stack)
|
||||
end
|
||||
|
@ -363,9 +367,15 @@ function circular_saw.on_metadata_inventory_take(
|
|||
-- The recycle field plays no role here since it is processed immediately.
|
||||
end
|
||||
|
||||
local has_default_mod = minetest.get_modpath("default")
|
||||
|
||||
function circular_saw.on_construct(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(
|
||||
"formspec", "size[11,10]"..fancy_inv..
|
||||
"label[0,0;" ..F(S("Input\nmaterial")).. "]" ..
|
||||
|
@ -437,7 +447,7 @@ minetest.register_node("moreblocks:circular_saw", {
|
|||
sunlight_propagates = true,
|
||||
paramtype2 = "facedir",
|
||||
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,
|
||||
can_dig = circular_saw.can_dig,
|
||||
-- Set the owner of this circular saw.
|
||||
|
|
|
@ -17,9 +17,13 @@ moreblocks.S = S
|
|||
moreblocks.NS = NS
|
||||
|
||||
dofile(modpath .. "/config.lua")
|
||||
dofile(modpath .. "/sounds.lua")
|
||||
dofile(modpath .. "/circular_saw.lua")
|
||||
dofile(modpath .. "/stairsplus/init.lua")
|
||||
|
||||
if minetest.get_modpath("default") then
|
||||
dofile(modpath .. "/nodes.lua")
|
||||
dofile(modpath .. "/redefinitions.lua")
|
||||
dofile(modpath .. "/crafting.lua")
|
||||
dofile(modpath .. "/aliases.lua")
|
||||
end
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
name = moreblocks
|
||||
description = Adds various miscellaneous blocks to the game.
|
||||
depends = default
|
||||
optional_depends = intllib,stairs,farming,wool,basic_materials
|
||||
optional_depends = default,intllib,stairs,farming,wool,basic_materials
|
||||
min_minetest_version = 5.0.0
|
||||
|
|
|
@ -7,15 +7,15 @@ Licensed under the zlib license. See LICENSE.md for more information.
|
|||
|
||||
local S = moreblocks.S
|
||||
|
||||
local sound_dirt = default.node_sound_dirt_defaults()
|
||||
local sound_wood = default.node_sound_wood_defaults()
|
||||
local sound_stone = default.node_sound_stone_defaults()
|
||||
local sound_glass = default.node_sound_glass_defaults()
|
||||
local sound_leaves = default.node_sound_leaves_defaults()
|
||||
local sound_dirt = moreblocks.node_sound_dirt_defaults()
|
||||
local sound_wood = moreblocks.node_sound_wood_defaults()
|
||||
local sound_stone = moreblocks.node_sound_stone_defaults()
|
||||
local sound_glass = moreblocks.node_sound_glass_defaults()
|
||||
local sound_leaves = moreblocks.node_sound_leaves_defaults()
|
||||
|
||||
-- Don't break on 0.4.14 and earlier.
|
||||
local sound_metal = (default.node_sound_metal_defaults
|
||||
and default.node_sound_metal_defaults() or sound_stone)
|
||||
local sound_metal = (moreblocks.node_sound_metal_defaults
|
||||
and moreblocks.node_sound_metal_defaults() or sound_stone)
|
||||
|
||||
local function tile_tiles(name)
|
||||
local tex = "moreblocks_" ..name.. ".png"
|
||||
|
|
20
mods/moreblocks/sounds.lua
Normal 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
|
|
@ -10,7 +10,7 @@
|
|||
description = "Wooden",
|
||||
tiles = {"default_wood.png"},
|
||||
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.
|
||||
|
|
|
@ -69,7 +69,7 @@ local function register_custom_subset(subset, modname, subname, recipeitem, grou
|
|||
description = description,
|
||||
drop = drop,
|
||||
light_source = light,
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
sounds = moreblocks.node_sound_stone_defaults(),
|
||||
})
|
||||
end
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ local function register_micro(modname, subname, recipeitem, groups, images, desc
|
|||
description = description,
|
||||
drop = drop,
|
||||
light_source = light,
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
sounds = moreblocks.node_sound_stone_defaults(),
|
||||
})
|
||||
end
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ local function register_panel(modname, subname, recipeitem, groups, images, desc
|
|||
description = description,
|
||||
drop = drop,
|
||||
light_source = light,
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
sounds = moreblocks.node_sound_stone_defaults(),
|
||||
})
|
||||
end
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ Licensed under the zlib license. See LICENSE.md for more information.
|
|||
--]]
|
||||
|
||||
-- default registrations
|
||||
if minetest.get_modpath("default") then
|
||||
local default_nodes = { -- Default stairs/slabs/panels/microblocks:
|
||||
"stone",
|
||||
"stone_block",
|
||||
|
@ -76,6 +77,7 @@ for _, name in pairs(default_nodes) do
|
|||
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
|
||||
if minetest.get_modpath("farming") then
|
||||
|
@ -118,7 +120,7 @@ if minetest.get_modpath("basic_materials") then
|
|||
description = "Concrete",
|
||||
tiles = {"basic_materials_concrete_block.png",},
|
||||
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")
|
||||
|
@ -128,7 +130,7 @@ if minetest.get_modpath("basic_materials") then
|
|||
description = "Cement",
|
||||
tiles = {"basic_materials_cement_block.png"},
|
||||
groups = {cracky=2, not_in_creative_inventory=1},
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
sounds = moreblocks.node_sound_stone_defaults(),
|
||||
sunlight_propagates = true,
|
||||
})
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ local function register_slab(modname, subname, recipeitem, groups, images, descr
|
|||
description = description,
|
||||
drop = drop,
|
||||
light_source = light,
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
sounds = moreblocks.node_sound_stone_defaults(),
|
||||
})
|
||||
end
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ local function register_slope(modname, subname, recipeitem, groups, images, desc
|
|||
description = description,
|
||||
drop = drop,
|
||||
light_source = light,
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
sounds = moreblocks.node_sound_stone_defaults(),
|
||||
})
|
||||
end
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ local function register_stair(modname, subname, recipeitem, groups, images, desc
|
|||
description = description,
|
||||
drop = drop,
|
||||
light_source = light,
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
sounds = moreblocks.node_sound_stone_defaults(),
|
||||
})
|
||||
end
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ models.
|
|||
Some nodes (ceiling lights, bar lights, poles) can be rotated to serve
|
||||
different purposes.
|
||||
|
||||
Morelights currently supports both Minetest Game and MineClone 2.
|
||||
Morelights currently supports Minetest Game, MineClone 2, and Hades Revisited.
|
||||
|
||||
## Craft Recipes
|
||||
|
||||
|
|
|
@ -1,17 +1,22 @@
|
|||
# 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.
|
||||
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 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
|
||||
|
||||
|
@ -185,10 +190,12 @@ Use light/dark grey wool.
|
|||
|
||||
### 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.
|
||||
|
||||
If `basic_materials` is installed, its Brass Ingot will be used instead.
|
||||
|
||||
### Brass Chain
|
||||
|
||||
```
|
||||
|
@ -259,14 +266,12 @@ MineClone 2: Craft from one iron ingot and one redstone.
|
|||
+--------+
|
||||
| Glass |
|
||||
+--------+
|
||||
| Cotton |
|
||||
| String |
|
||||
+--------+
|
||||
| Brass |
|
||||
+--------+
|
||||
```
|
||||
|
||||
For MineClone 2, use string instead of cotton.
|
||||
|
||||
### 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
|
||||
|
||||
|
@ -343,6 +349,8 @@ For MineClone 2, use polished stone.
|
|||
|
||||
For MineClone 2, use cut sandstone.
|
||||
|
||||
For Hades Revisited, use fine sandstone.
|
||||
|
||||
### Stair Light
|
||||
|
||||
```
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
name = morelights
|
||||
description = A lightweight modpack providing flexible interior and exterior lighting options for different styles of builds.
|
||||
min_minetest_version = 5.4
|
||||
|
|
|
@ -19,8 +19,8 @@ end
|
|||
|
||||
function morelights.on_place_hanging(itemstack, placer, pointed_thing,
|
||||
ceilingName)
|
||||
local ceiling = minetest.get_node(vector.add(pointed_thing.above,
|
||||
{x=0, y=1, z=0}))
|
||||
local ceiling = minetest.get_node(
|
||||
vector.add(pointed_thing.above, vector.new(0, 1, 0)))
|
||||
|
||||
if ceiling.name ~= "air"
|
||||
and minetest.get_item_group(ceiling.name, "mounted_ceiling") == 0
|
||||
|
@ -53,9 +53,11 @@ if minetest.get_modpath("mcl_core") then
|
|||
morelights.game = "mineclone2"
|
||||
elseif minetest.get_modpath("default") then
|
||||
morelights.game = "minetest_game"
|
||||
elseif minetest.get_modpath("hades_core") then
|
||||
morelights.game = "hades_revisited"
|
||||
else
|
||||
error("Morelights requires a compatible game " ..
|
||||
"(Minetest Game or MineClone 2).")
|
||||
"(Minetest Game, MineClone 2, or Hades Revisited).")
|
||||
end
|
||||
|
||||
if morelights.game == "minetest_game" then
|
||||
|
@ -70,6 +72,12 @@ elseif morelights.game == "mineclone2" then
|
|||
glass = mcl_sounds.node_sound_glass_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
|
||||
|
||||
morelights.craft_items = {
|
||||
|
@ -88,7 +96,7 @@ morelights.craft_items = {
|
|||
sandstone_block = "default:sandstone_block",
|
||||
dirt = "default:dirt",
|
||||
grass = "default:grass_1",
|
||||
cotton = "farming:cotton",
|
||||
string = "farming:string",
|
||||
stick = "default:stick",
|
||||
}
|
||||
|
||||
|
@ -111,8 +119,31 @@ if morelights.game == "mineclone2" then
|
|||
a.sandstone_block = "mcl_core:sandstonesmooth"
|
||||
a.dirt = "mcl_core:dirt"
|
||||
a.grass = "mcl_flowers:tallgrass"
|
||||
a.cotton = "mcl_mobitems:string"
|
||||
a.string = "mcl_mobitems:string"
|
||||
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
|
||||
|
||||
-- Use basic_materials brass if available, otherwise register our own.
|
||||
|
@ -121,4 +152,4 @@ if minetest.get_modpath("basic_materials") then
|
|||
end
|
||||
|
||||
local path = minetest.get_modpath("morelights")
|
||||
dofile(path .. DIR_DELIM .. "nodes.lua")
|
||||
dofile(path .. "/nodes.lua")
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
name = morelights
|
||||
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
|
||||
|
|
|
@ -35,26 +35,25 @@ do
|
|||
-- For MineClone 2, use node coloring to match environment.
|
||||
-- See the mcl_core:dirt_with_grass definition in
|
||||
-- ITEMS/mcl_core/nodes_base.lua.
|
||||
local override = {
|
||||
tiles = {
|
||||
def.tiles = {
|
||||
"mcl_core_grass_block_top.png",
|
||||
{name = "default_dirt.png", color = "#FFFFFF"}
|
||||
},
|
||||
overlay_tiles = {
|
||||
}
|
||||
def.overlay_tiles = {
|
||||
{name = "morelights_extras_blocklight.png", color = "#FFFFFF"},
|
||||
"",
|
||||
{
|
||||
name = "mcl_core_grass_block_side_overlay.png",
|
||||
tileable_vertical = false
|
||||
}
|
||||
},
|
||||
paramtype2 = "color",
|
||||
palette = "mcl_core_palette_grass.png",
|
||||
palette_index = 0,
|
||||
color = "#55aa60",
|
||||
drop = "morelights_extras:dirt_with_grass",
|
||||
}
|
||||
def.paramtype2 = "color"
|
||||
def.palette = "mcl_core_palette_grass.png"
|
||||
def.palette_index = 0
|
||||
def.color = "#55aa60"
|
||||
def.drop = "morelights_extras:dirt_with_grass"
|
||||
|
||||
on_construct = function(pos)
|
||||
def.on_construct = function(pos)
|
||||
local node = minetest.get_node(pos)
|
||||
if node.param2 == 0 then
|
||||
local grass_node = mcl_core.get_grass_block_type(pos)
|
||||
|
@ -66,10 +65,33 @@ do
|
|||
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[k] = v
|
||||
def.on_place = function(itemstack, placer, pointed_thing)
|
||||
local param2 = hades_core.get_seasonal_grass_color_param2()
|
||||
return minetest.item_place(itemstack, placer, pointed_thing, param2)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -97,6 +119,8 @@ do
|
|||
local tile = "default_sandstone_block.png"
|
||||
if morelights.game == "mineclone2" then
|
||||
tile = "mcl_core_sandstone_smooth.png"
|
||||
elseif morelights.game == "hades_revisited" then
|
||||
tile = "default_sandstone.png"
|
||||
end
|
||||
|
||||
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
|
||||
-- Set `above` to the node actually above the stair, since that's
|
||||
-- where the node is placed.
|
||||
pointed_thing.above = vector.add(pointed_thing.under,
|
||||
{x=0, y=1, z=0})
|
||||
pointed_thing.above =
|
||||
vector.add(pointed_thing.under, vector.new(0, 1, 0))
|
||||
return minetest.item_place_node(itemstack, placer, pointed_thing,
|
||||
node.param2)
|
||||
end
|
||||
|
|
|
@ -348,7 +348,7 @@ minetest.register_craft({
|
|||
output = "morelights_vintage:oillamp",
|
||||
recipe = {
|
||||
{"", a.glass, ""},
|
||||
{"", a.cotton, ""},
|
||||
{"", a.string, ""},
|
||||
{"", a.brass, ""}
|
||||
}
|
||||
})
|
||||
|
|
|
@ -805,4 +805,4 @@ if minetest.get_modpath("mesecons_mvps") then
|
|||
end
|
||||
|
||||
|
||||
print (S("[MOD] Protector Redo loaded"))
|
||||
print ("[MOD] Protector Redo loaded")
|
||||
|
|
|
@ -23,7 +23,7 @@ and minetest.settings:get_bool("protector_pvp") then
|
|||
|
||||
if not player
|
||||
or not hitter then
|
||||
print(S("[Protector] on_punchplayer called with nil objects"))
|
||||
print("[Protector] on_punchplayer called with nil objects")
|
||||
end
|
||||
|
||||
if not hitter:is_player() then
|
||||
|
@ -64,9 +64,9 @@ and minetest.settings:get_bool("protector_pvp") then
|
|||
|
||||
end)
|
||||
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
|
||||
else
|
||||
print(S("[Protector] pvp_protect is disabled"))
|
||||
print("[Protector] pvp_protect is disabled")
|
||||
end
|
||||
|
|
|
@ -78,6 +78,11 @@ minetest.register_craftitem("protector:tool", {
|
|||
return
|
||||
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 ?
|
||||
local nod
|
||||
local inv = user:get_inventory()
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
Skeleton
|
||||
I dont know
|
||||
CC BY-SA 3.0
|
||||
CC BY-SA 4.0
|
||||
|
|
3
mods/skinsdb/meta/character_2114.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
TommyInnit
|
||||
Christian_Soldier
|
||||
CC 0 (1.0)
|
3
mods/skinsdb/meta/character_2115.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
Dream(fixed4Real)
|
||||
Christian_Soldier
|
||||
CC 0 (1.0)
|
3
mods/skinsdb/meta/character_2116.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
Ranboo
|
||||
Christian_Soldier
|
||||
CC 0 (1.0)
|
3
mods/skinsdb/meta/character_2117.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
nick_ I
|
||||
nick_
|
||||
CC BY-SA 3.0
|
3
mods/skinsdb/meta/character_2118.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
RedMiniontoby
|
||||
Miniontoby
|
||||
CC BY-NC-SA 4.0
|
3
mods/skinsdb/meta/character_2119.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
Steven
|
||||
Tim7
|
||||
CC BY-SA 3.0
|
3
mods/skinsdb/meta/character_2120.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
Mal
|
||||
TheMalaysianDude
|
||||
CC BY-SA 3.0
|
3
mods/skinsdb/meta/character_2121.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
Paintball Gun Pixel 3D Zombie
|
||||
Mercenary S. Double 1.8W
|
||||
CC BY-SA 4.0
|
BIN
mods/skinsdb/textures/character_2114.png
Normal file
After Width: | Height: | Size: 9.3 KiB |
BIN
mods/skinsdb/textures/character_2115.png
Normal file
After Width: | Height: | Size: 6.1 KiB |
BIN
mods/skinsdb/textures/character_2116.png
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
mods/skinsdb/textures/character_2117.png
Normal file
After Width: | Height: | Size: 3.7 KiB |
BIN
mods/skinsdb/textures/character_2118.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
mods/skinsdb/textures/character_2119.png
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
mods/skinsdb/textures/character_2120.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
mods/skinsdb/textures/character_2121.png
Normal file
After Width: | Height: | Size: 580 B |
|
@ -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
|
||||
- 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-09-03 V2.07 * FR #103, Add Altitude to harvester menu
|
||||
|
||||
|
||||
## New in v2 (from players point of view)
|
||||
|
|
|
@ -693,7 +693,7 @@ minetest.register_node("gravelsieve:compressed_gravel", {
|
|||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "gravelsieve:sieve",
|
||||
output = "gravelsieve:sieve3",
|
||||
recipe = {
|
||||
{"group:wood", "", "group:wood"},
|
||||
{"group:wood", "default:steel_ingot", "group:wood"},
|
||||
|
@ -702,10 +702,10 @@ minetest.register_craft({
|
|||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "gravelsieve:auto_sieve",
|
||||
output = "gravelsieve:auto_sieve3",
|
||||
type = "shapeless",
|
||||
recipe = {
|
||||
"gravelsieve:sieve", "default:mese_crystal", "default:mese_crystal",
|
||||
"gravelsieve:sieve3", "default:mese_crystal", "default:mese_crystal",
|
||||
},
|
||||
})
|
||||
|
||||
|
|
|
@ -14,6 +14,18 @@
|
|||
|
||||
]]--
|
||||
|
||||
local function is_source(pos,meta, item)
|
||||
local inv = minetest.get_inventory({type="node", pos=pos})
|
||||
local name = item:get_name()
|
||||
if meta:get_string("src_item") == name then
|
||||
return true
|
||||
elseif inv:get_stack("src", 1):get_name() == name then
|
||||
meta:set_string("src_item", name)
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
tubelib.register_node("default:chest", {"default:chest_open"}, {
|
||||
on_pull_item = function(pos, side)
|
||||
local meta = minetest.get_meta(pos)
|
||||
|
@ -65,7 +77,9 @@ tubelib.register_node("default:furnace", {"default:furnace_active"}, {
|
|||
on_push_item = function(pos, side, item)
|
||||
local meta = minetest.get_meta(pos)
|
||||
minetest.get_node_timer(pos):start(1.0)
|
||||
if minetest.get_craft_result({method="fuel", width=1, items={item}}).time ~= 0 then
|
||||
if is_source(pos, meta, item) then
|
||||
return tubelib.put_item(meta, "src", item)
|
||||
elseif minetest.get_craft_result({method="fuel", width=1, items={item}}).time ~= 0 then
|
||||
return tubelib.put_item(meta, "fuel", item)
|
||||
else
|
||||
return tubelib.put_item(meta, "src", item)
|
||||
|
|
|
@ -317,6 +317,74 @@ function tubelib.add_grinder_recipe(recipe)
|
|||
end
|
||||
end
|
||||
|
||||
local function remove_unified_inventory_recipe(recipe)
|
||||
if recipe.input and recipe.output then
|
||||
local output_name = ItemStack(recipe.output):get_name()
|
||||
local crafts = unified_inventory.crafts_for.recipe[output_name]
|
||||
if crafts then
|
||||
for i, craft in ipairs(crafts) do
|
||||
if craft.type == recipe.type
|
||||
and ItemStack(craft.output):get_name() == output_name
|
||||
and #craft.items == 1
|
||||
and craft.items[1] == recipe.input
|
||||
then
|
||||
table.remove(crafts, i)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
elseif recipe.input then
|
||||
for output_name, crafts in pairs(unified_inventory.crafts_for.recipe) do
|
||||
for i, craft in ipairs(crafts) do
|
||||
if craft.type == recipe.type
|
||||
and #craft.items == 1
|
||||
and craft.items[1] == recipe.input
|
||||
then
|
||||
table.remove(crafts, i)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
elseif recipe.output then
|
||||
local output_name = ItemStack(recipe.output):get_name()
|
||||
local crafts = unified_inventory.crafts_for.recipe[output_name]
|
||||
if crafts then
|
||||
for i, craft in ipairs(crafts) do
|
||||
if craft.type == recipe.type
|
||||
and ItemStack(craft.output):get_name() == output_name then
|
||||
table.remove(crafts, i)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function tubelib.remove_grinder_recipe(recipe)
|
||||
if recipe.input and recipe.output then
|
||||
if Recipes[recipe.input]:get_name() ~= ItemStack(recipe.output):get_name() then
|
||||
return
|
||||
end
|
||||
Recipes[recipe.input] = nil
|
||||
elseif recipe.input then
|
||||
Recipes[recipe.input] = nil
|
||||
elseif recipe.output then
|
||||
local output_name = ItemStack(recipe.output):get_name()
|
||||
for input_name, output in pairs(Recipes) do
|
||||
if output:get_name() == output_name then
|
||||
Recipes[input_name] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
if minetest.global_exists("unified_inventory") then
|
||||
remove_unified_inventory_recipe({
|
||||
input = recipe.input,
|
||||
output = recipe.output,
|
||||
type = "grinding"
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
for k,v in pairs({
|
||||
["default:cobble"] = "default:gravel",
|
||||
["default:desert_cobble"] = "default:gravel",
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
Tubelib Addons 1
|
||||
================
|
||||
|
||||
Copyright (C) 2017-2020 Joachim Stolberg
|
||||
Copyright (C) 2017-2021 Joachim Stolberg
|
||||
|
||||
AGPL v3
|
||||
See LICENSE.txt for more information
|
||||
|
@ -27,7 +27,7 @@ local P = minetest.string_to_pos
|
|||
local M = minetest.get_meta
|
||||
|
||||
local CYCLE_TIME = 6
|
||||
local MAX_HEIGHT = 18 -- harvesting altitude
|
||||
local START_HEIGHT = 18 -- harvesting altitude
|
||||
local MAX_DIAMETER = 33
|
||||
local BURNING_TIME = 20 -- fuel
|
||||
local STANDBY_TICKS = 4 -- used for blocked state
|
||||
|
@ -35,13 +35,14 @@ local COUNTDOWN_TICKS = 2
|
|||
local OFFSET = 5 -- for uneven terrains
|
||||
|
||||
-- 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)
|
||||
working_pos.y = working_pos.y + MAX_HEIGHT
|
||||
working_pos.y = working_pos.y + (altitude or START_HEIGHT)
|
||||
return working_pos
|
||||
end
|
||||
|
||||
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)
|
||||
-- some recalculations
|
||||
|
@ -52,6 +53,7 @@ local function formspec(self, pos, meta)
|
|||
fuel = 0
|
||||
end
|
||||
local radius = Radius2Idx[this.radius] or 2
|
||||
local altitude = Altitude2Idx[this.altitude or START_HEIGHT] or 11
|
||||
|
||||
return "size[9,8]"..
|
||||
default.gui_bg..
|
||||
|
@ -59,7 +61,9 @@ local function formspec(self, pos, meta)
|
|||
default.gui_slots..
|
||||
"dropdown[0,0;1.5;radius;4,6,8,10,12,14,16;"..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;fuel;1.5,3;1,1;]"..
|
||||
"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)
|
||||
local this = minetest.deserialize(meta:get_string("this"))
|
||||
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))
|
||||
end,
|
||||
formspec_func = formspec,
|
||||
|
@ -210,7 +214,7 @@ local function calc_new_pos(pos, this, meta)
|
|||
if this.idx >= this.max then
|
||||
if this.endless == 1 then
|
||||
this.idx = 0
|
||||
this.working_pos = working_start_pos(pos)
|
||||
this.working_pos = working_start_pos(pos, this.altitude)
|
||||
return true
|
||||
else
|
||||
return false
|
||||
|
@ -227,7 +231,7 @@ local function harvest_field(this, meta)
|
|||
local inv = meta:get_inventory()
|
||||
local pos = table.copy(this.working_pos)
|
||||
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
|
||||
return true
|
||||
end
|
||||
|
@ -297,6 +301,7 @@ local function on_receive_fields(pos, formname, fields, player)
|
|||
local meta = M(pos)
|
||||
local this = minetest.deserialize(meta:get_string("this"))
|
||||
local radius = this.radius
|
||||
local altitude = this.altitude or START_HEIGHT
|
||||
|
||||
if fields.radius ~= nil then
|
||||
radius = tonumber(fields.radius)
|
||||
|
@ -308,6 +313,15 @@ local function on_receive_fields(pos, formname, fields, player)
|
|||
State:stop(pos, meta)
|
||||
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
|
||||
this.endless = fields.endless == "true" and 1 or 0
|
||||
end
|
||||
|
@ -334,7 +348,7 @@ minetest.register_node("tubelib_addons1:harvester_base", {
|
|||
local this = {
|
||||
number = number,
|
||||
owner = placer:get_player_name(),
|
||||
working_pos = working_start_pos(pos),
|
||||
working_pos = working_start_pos(pos, START_HEIGHT),
|
||||
fuel = 0,
|
||||
endless = 0,
|
||||
radius = 6,
|
||||
|
@ -392,7 +406,7 @@ minetest.register_node("tubelib_addons1:harvester_defect", {
|
|||
local this = {
|
||||
number = number,
|
||||
owner = placer:get_player_name(),
|
||||
working_pos = working_start_pos(pos),
|
||||
working_pos = working_start_pos(pos, START_HEIGHT),
|
||||
fuel = 0,
|
||||
endless = 0,
|
||||
radius = 6,
|
||||
|
@ -487,7 +501,7 @@ minetest.register_lbm({
|
|||
local meta = M(pos)
|
||||
local this = minetest.deserialize(meta:get_string("this"))
|
||||
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))
|
||||
end
|
||||
end
|
||||
|
|
|
@ -41,6 +41,7 @@ Tubelib Grinder=
|
|||
### harvester.lua ###
|
||||
|
||||
: running (=
|
||||
Altitude =
|
||||
Area radius=
|
||||
Tubelib Harvester=
|
||||
Tubelib Harvester Base=
|
||||
|
|
|
@ -41,6 +41,7 @@ Tubelib Grinder=Tubelib Mühle
|
|||
### harvester.lua ###
|
||||
|
||||
: running (=: läuft (
|
||||
Altitude = Flughöhe
|
||||
Area radius=Flächenradius
|
||||
Tubelib Harvester=Tubelib Ernter
|
||||
Tubelib Harvester Base=Tubelib Ernter Basis
|
||||
|
|
|
@ -90,36 +90,44 @@ end
|
|||
-- Farming Redo
|
||||
----------------------------------------------- --------------------------------
|
||||
if farming.mod == "redo" then
|
||||
fn("farming:wheat_8", "farming:wheat", "farming:wheat_1")
|
||||
fn("farming:cotton_8", "farming:cotton", "farming:cotton_1")
|
||||
fn("farming:artichoke_5", "farming:artichoke", "farming:artichoke_1")
|
||||
fn("farming:barley_7", "farming:barley", "farming:barley_1")
|
||||
fn("farming:beanpole_5", "farming:beans 3", "farming:beanpole_1")
|
||||
fn("farming:beetroot_5", "farming:beetroot 2", "farming:beetroot_1")
|
||||
fn("farming:blackberry_4", "farming:blackberry", "farming:blackberry_1")
|
||||
fn("farming:blueberry_4", "farming:blueberries", "farming:blueberry_1")
|
||||
fn("farming:cabbage_6", "farming:cabbage", "farming:cabbage_1")
|
||||
fn("farming:carrot_8", "farming:carrot 2", "farming:carrot_1")
|
||||
fn("farming:potato_4", "farming:potato 3", "farming:potato_1")
|
||||
fn("farming:tomato_8", "farming:tomato 3", "farming:tomato_1")
|
||||
fn("farming:cucumber_4", "farming:cucumber 2", "farming:cucumber_1")
|
||||
fn("farming:corn_8", "farming:corn 2", "farming:corn_1")
|
||||
fn("farming:chili_8", "farming:chili_pepper 2", "farming:chili_1")
|
||||
fn("farming:cocoa_4", "farming:cocoa_beans 2", "farming:cocoa_1")
|
||||
fn("farming:coffee_5", "farming:coffee_beans 2", "farming:coffee_1")
|
||||
fn("farming:corn_8", "farming:corn 2", "farming:corn_1")
|
||||
fn("farming:cotton_8", "farming:cotton", "farming:cotton_1")
|
||||
fn("farming:cucumber_4", "farming:cucumber 2", "farming:cucumber_1")
|
||||
fn("farming:garlic_5", "farming:garlic 2", "farming:garlic_1")
|
||||
fn("farming:grapes_8", "farming:grapes 3", "farming:grapes_1")
|
||||
fn("farming:hemp_8", "farming:hemp_leaf", "farming:hemp_1")
|
||||
fn("farming:lettuce_5", "farming:lettuce", "farming:lettuce_1")
|
||||
fn("farming:melon_8", "farming:melon_slice 4", "farming:melon_1")
|
||||
fn("farming:mint_4", "farming:mint_leaf 2", "farming:mint_1")
|
||||
fn("farming:oat_8", "farming:oat", "farming:oat_1")
|
||||
fn("farming:onion_5", "farming:onion 2", "farming:onion_1")
|
||||
fn("farming:parsley_3", "farming:parsley", "farming:parsley_1")
|
||||
fn("farming:pea_5", "farming:pea_pod 3", "farming:pea_1")
|
||||
fn("farming:pepper_5", "farming:pepper 2", "farming:pepper_1")
|
||||
fn("farming:pepper_6", "farming:pepper_yellow 2", "farming:pepper_1")
|
||||
fn("farming:pepper_7", "farming:pepper_red 2", "farming:pepper_1")
|
||||
fn("farming:pineapple_8", "farming:pineapple 1", "farming:pineapple_1")
|
||||
fn("farming:potato_4", "farming:potato 3", "farming:potato_1")
|
||||
fn("farming:pumpkin_8", "farming:pumpkin_slice 4", "farming:pumpkin_1")
|
||||
fn("farming:raspberry_4", "farming:raspberries", "farming:raspberry_1")
|
||||
fn("farming:blueberry_4", "farming:blueberries", "farming:blueberry_1")
|
||||
fn("farming:rhubarb_3", "farming:rhubarb 2", "farming:rhubarb_1")
|
||||
fn("farming:beanpole_5", "farming:beans 3", "farming:beanpole_1")
|
||||
fn("farming:grapes_8", "farming:grapes 3", "farming:grapes_1")
|
||||
fn("farming:barley_7", "farming:barley", "farming:barley_1")
|
||||
fn("farming:chili_8", "farming:chili_pepper 2", "farming:chili_1")
|
||||
fn("farming:hemp_8", "farming:hemp_leaf", "farming:hemp_1")
|
||||
fn("farming:oat_8", "farming:oat", "farming:oat_1")
|
||||
fn("farming:rye_8", "farming:rye", "farming:rye_1")
|
||||
fn("farming:rice_8", "farming:rice", "farming:rice_1")
|
||||
fn('farming:beetroot_5', 'farming:beetroot 2', 'farming:beetroot_1')
|
||||
fn('farming:cocoa_4', 'farming:cocoa_beans 2', 'farming:cocoa_1')
|
||||
fn('farming:garlic_5', 'farming:garlic 2', 'farming:garlic_1')
|
||||
fn('farming:onion_5', 'farming:onion 2', 'farming:onion_1')
|
||||
fn('farming:pea_5', 'farming:pea_pod 3', 'farming:pea_1')
|
||||
fn('farming:pepper_5', 'farming:pepper 2', 'farming:pepper_1')
|
||||
fn('farming:pepper_6', 'farming:pepper_yellow 2','farming:pepper_1')
|
||||
fn('farming:pepper_7', 'farming:pepper_red 2', 'farming:pepper_1')
|
||||
fn('farming:pineapple_8', 'farming:pineapple 1', 'farming:pineapple_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
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
@ -155,6 +163,7 @@ fn("ethereal:bamboo_leaves")
|
|||
fn("ethereal:banana")
|
||||
fn("ethereal:orange")
|
||||
fn("ethereal:coconut")
|
||||
fn("ethereal:golden_apple")
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Default Ground
|
||||
|
|
|
@ -43,7 +43,8 @@ unified_inventory = {
|
|||
imgscale = 1.25,
|
||||
list_img_offset = 0.13,
|
||||
standard_background = "background9[0,0;1,1;ui_formbg_9_sliced.png;true;16]",
|
||||
version = 2
|
||||
|
||||
version = 3
|
||||
}
|
||||
|
||||
local ui = unified_inventory
|
||||
|
|
|
@ -22,7 +22,9 @@ end
|
|||
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})
|
||||
|
||||
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
|
||||
|
||||
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))
|
||||
end
|
||||
|
||||
function ui.get_formspec(player, page)
|
||||
|
||||
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 function formspec_add_filters(player, formspec, style)
|
||||
local button_row = 0
|
||||
local button_col = 0
|
||||
local n = #formspec + 1
|
||||
|
||||
-- Main buttons
|
||||
|
||||
local filtered_inv_buttons = {}
|
||||
|
||||
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)
|
||||
end
|
||||
end
|
||||
|
||||
for i, def in pairs(filtered_inv_buttons) do
|
||||
|
||||
if draw_lite_mode and i > 4 then
|
||||
if style.is_lite_mode and i > 4 then
|
||||
button_row = 1
|
||||
button_col = 1
|
||||
end
|
||||
|
||||
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
|
||||
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,
|
||||
ui_peruser.main_button_y + button_row * ui_peruser.btn_spc,
|
||||
ui_peruser.btn_size,ui_peruser.btn_size,
|
||||
pos_x, pos_y, style.btn_size, style.btn_size,
|
||||
F(def.image),
|
||||
F(def.name))
|
||||
formspec[n+1] = "tooltip["..F(def.name)..";"..(def.tooltip or "").."]"
|
||||
n = n+2
|
||||
else
|
||||
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,
|
||||
ui_peruser.main_button_y + button_row * ui_peruser.btn_spc,
|
||||
ui_peruser.btn_size,ui_peruser.btn_size,def.image)
|
||||
pos_x, pos_y, style.btn_size, style.btn_size,
|
||||
def.image)
|
||||
n = n+1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if fsdata.draw_inventory ~= false then
|
||||
-- Player inventory
|
||||
formspec[n] = "listcolors[#00000000;#00000000]"
|
||||
formspec[n+1] = ui_peruser.standard_inv
|
||||
n = n+2
|
||||
end
|
||||
|
||||
if fsdata.draw_item_list == false then
|
||||
return table.concat(formspec, "")
|
||||
end
|
||||
local function formspec_add_categories(player, formspec, ui_peruser)
|
||||
local player_name = player:get_player_name()
|
||||
local n = #formspec + 1
|
||||
|
||||
-- Category filters
|
||||
|
||||
local categories_pos = { ui_peruser.page_x, ui_peruser.page_y-ui_peruser.btn_spc-0.5 }
|
||||
local categories_scroll_pos = { ui_peruser.page_x, ui_peruser.form_header_y-(draw_lite_mode and 0 or 0.2) }
|
||||
local categories_pos = {
|
||||
ui_peruser.page_x,
|
||||
ui_peruser.page_y-ui_peruser.btn_spc-0.5
|
||||
}
|
||||
local categories_scroll_pos = {
|
||||
ui_peruser.page_x,
|
||||
ui_peruser.form_header_y - (ui_peruser.is_lite_mode and 0 or 0.2)
|
||||
}
|
||||
|
||||
formspec[n] = string.format("background9[%f,%f;%f,%f;%s;false;3]",
|
||||
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")
|
||||
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
|
||||
|
||||
local scroll_offset = 0
|
||||
local category_count = #unified_inventory.category_list
|
||||
local category_count = #ui.category_list
|
||||
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
|
||||
|
||||
for index, category in ipairs(unified_inventory.category_list) do
|
||||
for index, category in ipairs(ui.category_list) do
|
||||
local column = index - scroll_offset
|
||||
if column > 0 and column <= ui_peruser.pagecols then
|
||||
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
|
||||
end
|
||||
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
|
||||
-- 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"))
|
||||
n = n + 1
|
||||
end
|
||||
end
|
||||
|
||||
-- Search box
|
||||
local function formspec_add_search_box(player, formspec, ui_peruser)
|
||||
local player_name = player:get_player_name()
|
||||
local n = #formspec + 1
|
||||
|
||||
formspec[n] = "field_close_on_enter[searchbox;false]"
|
||||
|
||||
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)
|
||||
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
|
||||
|
||||
|
@ -195,9 +178,9 @@ function ui.get_formspec(player, page)
|
|||
{ "ui_skip_forward_icon.png", "end_list", S("Last page") },
|
||||
}
|
||||
|
||||
if draw_lite_mode then
|
||||
btnlist[5] = nil
|
||||
if ui_peruser.is_lite_mode then
|
||||
btnlist[2] = nil
|
||||
btnlist[5] = nil
|
||||
end
|
||||
|
||||
local bn = 0
|
||||
|
@ -212,15 +195,17 @@ function ui.get_formspec(player, page)
|
|||
n = n + 2
|
||||
end
|
||||
|
||||
-- Items list
|
||||
if #ui.filtered_items_list[player_name] == 0 then
|
||||
local no_matches = S("No matching items")
|
||||
if draw_lite_mode then
|
||||
if ui_peruser.is_lite_mode then
|
||||
no_matches = S("No matches.")
|
||||
end
|
||||
|
||||
-- Items list
|
||||
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) .. "]"
|
||||
else
|
||||
return
|
||||
end
|
||||
|
||||
local dir = ui.active_search_direction[player_name]
|
||||
local list_index = ui.current_index[player_name]
|
||||
local page2 = math.floor(list_index / (ui_peruser.items_per_page) + 1)
|
||||
|
@ -263,18 +248,56 @@ function ui.get_formspec(player, page)
|
|||
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_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
|
||||
n= n+1
|
||||
|
||||
if ui.activefilter[player_name] ~= "" then
|
||||
formspec[n] = 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]))
|
||||
function ui.get_formspec(player, page)
|
||||
|
||||
if not player then
|
||||
return ""
|
||||
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
|
||||
|
||||
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.current_page[player_name])
|
||||
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
|
||||
|
|