Mods update
|
@ -1,6 +1,6 @@
|
|||
|
||||
origin https://github.com/minetest/minetest_game.git (fetch)
|
||||
* master 4945f4b [origin/master] Carts: Fix 0/0 condition on faulty tool capabilities
|
||||
* master c96cc55 [origin/master] Fix incorrect documentation of "default_coal_lump.png"
|
||||
Mod: minetest_game/mods/beds
|
||||
Mod: minetest_game/mods/binoculars
|
||||
Mod: minetest_game/mods/boats
|
||||
|
@ -61,11 +61,11 @@ origin https://github.com/Sokomine/mg_villages (fetch)
|
|||
Mod: buildings/mg_villages
|
||||
|
||||
origin git@github.com:minetest-mods/ts_doors.git (fetch)
|
||||
* master 2e8dd2d [origin/master] Add basic_materials to optional dependencies.
|
||||
* master 3c4141b [origin/master] Dynamically use textures from base nodes
|
||||
Mod: buildings/ts_doors
|
||||
|
||||
origin https://github.com/sirrobzeroone/comboblock (fetch)
|
||||
* master ac04448 [origin/master] Add Spanish and Russian
|
||||
* master d078ea1 [origin/master] Testing and confirmed 5.4 working
|
||||
Mod: environment/comboblock
|
||||
|
||||
origin https://github.com/minetest-mods/dynamic_liquid (fetch)
|
||||
|
@ -73,11 +73,11 @@ origin https://github.com/minetest-mods/dynamic_liquid (fetch)
|
|||
Mod: environment/dynamic_liquid
|
||||
|
||||
origin https://notabug.org/tenplus1/farming (fetch)
|
||||
* master 4b033fe [origin/master] add new melon textures (thanks 7eventy7)
|
||||
* master 70803f8 [origin/master] add pumpkin bottom texture, redo melon node, fix typo in scythe, make pumpkin/melon rotatable
|
||||
Mod: flora/farming
|
||||
|
||||
origin https://github.com/minetest-mods/i3.git (fetch)
|
||||
* main ca5cd92 [origin/main] Update Screenshot
|
||||
* main dde5148 [origin/main] Show a tooltip for waypoints
|
||||
Mod: gui/i3
|
||||
|
||||
origin https://repo.or.cz/minetest_hbarmor.git (fetch)
|
||||
|
@ -113,11 +113,11 @@ origin https://github.com/TheTermos/mobkit (fetch)
|
|||
Mod: lib_api/mobkit
|
||||
|
||||
origin https://notabug.org/tenplus1/mobs_redo (fetch)
|
||||
* master 70c68f6 [origin/master] change so only players can push mobs
|
||||
* master 33589eb [origin/master] improve pathfinding level 2 digging/building, add infotext, stop mob attack spin, tweak & tidy code
|
||||
Mod: lib_api/mobs_redo
|
||||
|
||||
origin https://github.com/appgurueu/modlib (fetch)
|
||||
* master 68f6573 [origin/master] Bump version
|
||||
* master d8f3bf2 [origin/master] Fix debug.stack
|
||||
Mod: lib_api/modlib
|
||||
|
||||
origin git@github.com:runsy/rcbows.git (fetch)
|
||||
|
@ -149,7 +149,7 @@ origin https://codeberg.org/Hamlet/mobs_ghost_redo (fetch)
|
|||
Mod: mobs/mobs_mobs/mobs_ghost_redo
|
||||
|
||||
origin https://notabug.org/TenPlus1/mobs_monster.git (fetch)
|
||||
* master e39d06b [origin/master] add fire damage to obsidian flan
|
||||
* master 9b3c1e1 [origin/master] fire spirit additions
|
||||
Mod: mobs/mobs_mobs/mobs_monster
|
||||
|
||||
origin https://github.com/berengma/aerotest (fetch)
|
||||
|
@ -157,15 +157,15 @@ origin https://github.com/berengma/aerotest (fetch)
|
|||
Mod: mobs/mobs_mobkit/aerotest
|
||||
|
||||
origin https://github.com/runsy/petz (fetch)
|
||||
* master db3fa98 [origin/master] fixes
|
||||
* master b593d81 [origin/master] fix: pumpkin grenade respects protected nodes
|
||||
Mod: mobs/mobs_mobkit/petz
|
||||
|
||||
origin https://github.com/berengma/water_life (fetch)
|
||||
* master 1919e32 [origin/master] Merge pull request #75 from berengma/test
|
||||
* master bc2f245 [origin/master] disable chat spamming
|
||||
Mod: mobs/mobs_mobkit/water_life
|
||||
|
||||
origin https://github.com/minetest-mods/3d_armor (fetch)
|
||||
* master f07f050 [origin/master] Silence warnings when ui is not enabled
|
||||
* master a0cf12b [origin/master] Add setting to disable armor visuals on player model (#48)
|
||||
Mod: player/3d_armor
|
||||
|
||||
origin https://github.com/appgurueu/character_anim (fetch)
|
||||
|
|
|
@ -7,6 +7,21 @@ ts_doors.sounds = {}
|
|||
-- Used for localization
|
||||
local S = minetest.get_translator("ts_doors")
|
||||
|
||||
-- Get texture by node name
|
||||
local T = function (node_name)
|
||||
local def = minetest.registered_nodes[node_name]
|
||||
if not (def and def.tiles) then
|
||||
return ""
|
||||
end
|
||||
local tile = def.tiles[5] or def.tiles[4] or def.tiles[3] or def.tiles[2] or def.tiles[1]
|
||||
if type(tile) == "string" then
|
||||
return tile
|
||||
elseif type(tile) == "table" and tile.name then
|
||||
return tile.name
|
||||
end
|
||||
return ""
|
||||
end
|
||||
|
||||
-- Use this to generate the translation template file.
|
||||
--[[
|
||||
local oldS = S
|
||||
|
@ -78,6 +93,9 @@ function ts_doors.register_door(item, description, texture, sounds, recipe)
|
|||
if not sounds then
|
||||
sounds = {}
|
||||
end
|
||||
if not texture then
|
||||
texture = T(item)
|
||||
end
|
||||
recipe = recipe or item
|
||||
ts_doors.registered_doors[item:gsub(":", "_")] = recipe
|
||||
register_door_alias("doors:ts_door_" .. item:gsub(":", "_"), "ts_doors:door_" .. item:gsub(":", "_"))
|
||||
|
@ -200,65 +218,65 @@ function ts_doors.register_door(item, description, texture, sounds, recipe)
|
|||
})
|
||||
end
|
||||
|
||||
ts_doors.register_door("default:aspen_wood", "Aspen", "default_aspen_wood.png", ts_doors.sounds.wood)
|
||||
ts_doors.register_door("default:pine_wood", "Pine", "default_pine_wood.png", ts_doors.sounds.wood)
|
||||
ts_doors.register_door("default:acacia_wood", "Acacia", "default_acacia_wood.png", ts_doors.sounds.wood)
|
||||
ts_doors.register_door("default:wood", "Wooden", "default_wood.png", ts_doors.sounds.wood)
|
||||
ts_doors.register_door("default:junglewood", "Jungle Wood", "default_junglewood.png", ts_doors.sounds.wood)
|
||||
ts_doors.register_door("default:aspen_wood", "Aspen", nil, ts_doors.sounds.wood)
|
||||
ts_doors.register_door("default:pine_wood", "Pine", nil, ts_doors.sounds.wood)
|
||||
ts_doors.register_door("default:acacia_wood", "Acacia", nil, ts_doors.sounds.wood)
|
||||
ts_doors.register_door("default:wood", "Wooden", nil, ts_doors.sounds.wood)
|
||||
ts_doors.register_door("default:junglewood", "Jungle Wood", nil, ts_doors.sounds.wood)
|
||||
|
||||
if minetest.get_modpath("moretrees") then
|
||||
ts_doors.register_door("moretrees:apple_tree_planks", "Apple Tree", "moretrees_apple_tree_wood.png", ts_doors.sounds.wood)
|
||||
ts_doors.register_door("moretrees:beech_planks", "Beech", "moretrees_beech_wood.png", ts_doors.sounds.wood)
|
||||
ts_doors.register_door("moretrees:birch_planks", "Birch", "moretrees_birch_wood.png", ts_doors.sounds.wood)
|
||||
ts_doors.register_door("moretrees:fir_planks", "Fir", "moretrees_fir_wood.png", ts_doors.sounds.wood)
|
||||
ts_doors.register_door("moretrees:oak_planks", "Oak", "moretrees_oak_wood.png", ts_doors.sounds.wood)
|
||||
ts_doors.register_door("moretrees:palm_planks", "Palm", "moretrees_palm_wood.png", ts_doors.sounds.wood)
|
||||
ts_doors.register_door("moretrees:rubber_tree_planks", "Rubber Tree", "moretrees_rubber_tree_wood.png", ts_doors.sounds.wood)
|
||||
ts_doors.register_door("moretrees:sequoia_planks", "Sequoia", "moretrees_sequoia_wood.png", ts_doors.sounds.wood)
|
||||
ts_doors.register_door("moretrees:spruce_planks", "Spruce", "moretrees_spruce_wood.png", ts_doors.sounds.wood)
|
||||
ts_doors.register_door("moretrees:willow_planks", "Willow", "moretrees_willow_wood.png", ts_doors.sounds.wood)
|
||||
ts_doors.register_door("moretrees:apple_tree_planks", "Apple Tree", nil, ts_doors.sounds.wood)
|
||||
ts_doors.register_door("moretrees:beech_planks", "Beech", nil, ts_doors.sounds.wood)
|
||||
ts_doors.register_door("moretrees:birch_planks", "Birch", nil, ts_doors.sounds.wood)
|
||||
ts_doors.register_door("moretrees:fir_planks", "Fir", nil, ts_doors.sounds.wood)
|
||||
ts_doors.register_door("moretrees:oak_planks", "Oak", nil, ts_doors.sounds.wood)
|
||||
ts_doors.register_door("moretrees:palm_planks", "Palm", nil, ts_doors.sounds.wood)
|
||||
ts_doors.register_door("moretrees:rubber_tree_planks", "Rubber Tree", nil, ts_doors.sounds.wood)
|
||||
ts_doors.register_door("moretrees:sequoia_planks", "Sequoia", nil, ts_doors.sounds.wood)
|
||||
ts_doors.register_door("moretrees:spruce_planks", "Spruce", nil, ts_doors.sounds.wood)
|
||||
ts_doors.register_door("moretrees:willow_planks", "Willow", nil, ts_doors.sounds.wood)
|
||||
end
|
||||
|
||||
if minetest.get_modpath("ethereal") then
|
||||
ts_doors.register_door("ethereal:banana_wood", "Banana", "banana_wood.png", ts_doors.sounds.wood)
|
||||
ts_doors.register_door("ethereal:birch_wood", "Birch", "moretrees_birch_wood.png", ts_doors.sounds.wood)
|
||||
ts_doors.register_door("ethereal:frost_wood", "Frost", "frost_wood.png", ts_doors.sounds.wood)
|
||||
ts_doors.register_door("ethereal:mushroom_trunk", "Mushroom", "mushroom_trunk.png", ts_doors.sounds.wood)
|
||||
ts_doors.register_door("ethereal:palm_wood", "Palm", "moretrees_palm_wood.png", ts_doors.sounds.wood)
|
||||
ts_doors.register_door("ethereal:redwood_wood", "Redwood", "redwood_wood.png", ts_doors.sounds.wood)
|
||||
ts_doors.register_door("ethereal:sakura_wood", "Sakura", "ethereal_sakura_wood.png", ts_doors.sounds.wood)
|
||||
ts_doors.register_door("ethereal:scorched_tree", "Scorched", "scorched_tree.png", ts_doors.sounds.wood)
|
||||
ts_doors.register_door("ethereal:willow_wood", "Willow", "willow_wood.png", ts_doors.sounds.wood)
|
||||
ts_doors.register_door("ethereal:yellow_wood", "Healing Tree", "yellow_wood.png", ts_doors.sounds.wood)
|
||||
ts_doors.register_door("ethereal:crystal_block", "Crystal", "crystal_block.png", ts_doors.sounds.metal, "ethereal:crystal_ingot")
|
||||
ts_doors.register_door("ethereal:banana_wood", "Banana", nil, ts_doors.sounds.wood)
|
||||
ts_doors.register_door("ethereal:birch_wood", "Birch", nil, ts_doors.sounds.wood)
|
||||
ts_doors.register_door("ethereal:frost_wood", "Frost", nil, ts_doors.sounds.wood)
|
||||
ts_doors.register_door("ethereal:mushroom_trunk", "Mushroom", nil, ts_doors.sounds.wood)
|
||||
ts_doors.register_door("ethereal:palm_wood", "Palm", nil, ts_doors.sounds.wood)
|
||||
ts_doors.register_door("ethereal:redwood_wood", "Redwood", nil, ts_doors.sounds.wood)
|
||||
ts_doors.register_door("ethereal:sakura_wood", "Sakura", nil, ts_doors.sounds.wood)
|
||||
ts_doors.register_door("ethereal:scorched_tree", "Scorched", nil, ts_doors.sounds.wood)
|
||||
ts_doors.register_door("ethereal:willow_wood", "Willow", nil, ts_doors.sounds.wood)
|
||||
ts_doors.register_door("ethereal:yellow_wood", "Healing Tree", nil, ts_doors.sounds.wood)
|
||||
ts_doors.register_door("ethereal:crystal_block", "Crystal", nil, ts_doors.sounds.metal, "ethereal:crystal_ingot")
|
||||
end
|
||||
|
||||
|
||||
ts_doors.register_door("default:bronzeblock", "Bronze", "default_bronze_block.png", ts_doors.sounds.metal, "default:bronze_ingot")
|
||||
ts_doors.register_door("default:copperblock", "Copper", "default_copper_block.png", ts_doors.sounds.metal, "default:copper_ingot")
|
||||
ts_doors.register_door("default:diamondblock", "Diamond", "default_diamond_block.png", ts_doors.sounds.metal, "default:diamond")
|
||||
ts_doors.register_door("default:goldblock", "Gold", "default_gold_block.png", ts_doors.sounds.metal, "default:gold_ingot")
|
||||
ts_doors.register_door("default:steelblock", "Steel", minetest.registered_nodes["default:steelblock"].tiles[1], ts_doors.sounds.metal, "default:steel_ingot")
|
||||
ts_doors.register_door("default:bronzeblock", "Bronze", nil, ts_doors.sounds.metal, "default:bronze_ingot")
|
||||
ts_doors.register_door("default:copperblock", "Copper", nil, ts_doors.sounds.metal, "default:copper_ingot")
|
||||
ts_doors.register_door("default:diamondblock", "Diamond", nil, ts_doors.sounds.metal, "default:diamond")
|
||||
ts_doors.register_door("default:goldblock", "Gold", nil, ts_doors.sounds.metal, "default:gold_ingot")
|
||||
ts_doors.register_door("default:steelblock", "Steel", nil, ts_doors.sounds.metal, "default:steel_ingot")
|
||||
|
||||
if minetest.get_modpath("moreores") then
|
||||
ts_doors.register_door("moreores:mithril_block", "Mithril", "moreores_mithril_block.png", ts_doors.sounds.metal, "moreores:mithril_ingot")
|
||||
ts_doors.register_door("moreores:silver_block", "Silver", "moreores_silver_block.png", ts_doors.sounds.metal, "moreores:silver_ingot")
|
||||
ts_doors.register_door("moreores:tin_block", "Tin", "moreores_tin_block.png", ts_doors.sounds.metal, "moreores:tin_ingot")
|
||||
ts_doors.register_door("moreores:mithril_block", "Mithril", nil, ts_doors.sounds.metal, "moreores:mithril_ingot")
|
||||
ts_doors.register_door("moreores:silver_block", "Silver", nil, ts_doors.sounds.metal, "moreores:silver_ingot")
|
||||
ts_doors.register_door("moreores:tin_block", "Tin", nil, ts_doors.sounds.metal, "moreores:tin_ingot")
|
||||
end
|
||||
|
||||
if minetest.get_modpath("technic") then
|
||||
ts_doors.register_door("technic:carbon_steel_block", "Carbon Steel", "technic_carbon_steel_block.png", ts_doors.sounds.metal, "technic:carbon_steel_ingot")
|
||||
ts_doors.register_door("technic:cast_iron_block", "Cast Iron", "technic_cast_iron_block.png", ts_doors.sounds.metal, "technic:cast_iron_ingot")
|
||||
ts_doors.register_door("technic:chromium_block", "Chromium", "technic_chromium_block.png", ts_doors.sounds.metal, "technic:chromium_ingot")
|
||||
ts_doors.register_door("technic:lead_block", "Lead", "technic_lead_block.png", ts_doors.sounds.metal, "technic:lead_ingot")
|
||||
ts_doors.register_door("technic:stainless_steel_block", "Stainless Steel", "technic_stainless_steel_block.png", ts_doors.sounds.metal, "technic:stainless_steel_ingot")
|
||||
ts_doors.register_door("technic:zinc_block", "Zinc", "technic_zinc_block.png", ts_doors.sounds.metal, "technic:zinc_ingot")
|
||||
ts_doors.register_door("technic:blast_resistant_concrete", "Blast Resistant Concrete", "technic_blast_resistant_concrete_block.png", ts_doors.sounds.metal)
|
||||
ts_doors.register_door("technic:carbon_steel_block", "Carbon Steel", nil, ts_doors.sounds.metal, "technic:carbon_steel_ingot")
|
||||
ts_doors.register_door("technic:cast_iron_block", "Cast Iron", nil, ts_doors.sounds.metal, "technic:cast_iron_ingot")
|
||||
ts_doors.register_door("technic:chromium_block", "Chromium", nil, ts_doors.sounds.metal, "technic:chromium_ingot")
|
||||
ts_doors.register_door("technic:lead_block", "Lead", nil, ts_doors.sounds.metal, "technic:lead_ingot")
|
||||
ts_doors.register_door("technic:stainless_steel_block", "Stainless Steel", nil, ts_doors.sounds.metal, "technic:stainless_steel_ingot")
|
||||
ts_doors.register_door("technic:zinc_block", "Zinc", nil, ts_doors.sounds.metal, "technic:zinc_ingot")
|
||||
ts_doors.register_door("technic:blast_resistant_concrete", "Blast Resistant Concrete", nil, ts_doors.sounds.metal)
|
||||
end
|
||||
|
||||
if minetest.get_modpath("basic_materials") then
|
||||
ts_doors.register_door("basic_materials:brass_block", "Brass", "basic_materials_brass_block.png", ts_doors.sounds.metal, "basic_materials:brass_ingot")
|
||||
ts_doors.register_door("basic_materials:concrete_block", "Concrete", "basic_materials_concrete_block.png", ts_doors.sounds.metal)
|
||||
ts_doors.register_door("basic_materials:brass_block", "Brass", nil, ts_doors.sounds.metal, "basic_materials:brass_ingot")
|
||||
ts_doors.register_door("basic_materials:concrete_block", "Concrete", nil, ts_doors.sounds.metal)
|
||||
ts_doors.register_alias("technic:brass_block", "basic_materials:brass_block")
|
||||
ts_doors.register_alias("technic:concrete", "basic_materials:concrete_block")
|
||||
end
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
-- \/ \/ \/ \/ \/ \/ --
|
||||
-- --
|
||||
-- Orginally written/created by Pithydon/Pithy --
|
||||
-- Version 5.3.0.1 --
|
||||
-- Version 5.4.0.1 --
|
||||
-- first 3 numbers version of minetest created for, --
|
||||
-- last digit mod version for MT version --
|
||||
-------------------------------------------------------------------------------------
|
||||
|
|
|
@ -74,7 +74,7 @@ Issue 2 - If you rotate a comboblock with a screwdriver type tool (lots out ther
|
|||
Big thanks to Pithy for writting the orginal mod and the help from various people on the
|
||||
MT forum boards even if they probably don't know they have helped:
|
||||
|
||||
blert2112, Linuxdirk, Krock, Rubenwardy, Pampogokiraly, Joe7575, Sorcerykid, Daretmavi
|
||||
blert2112, Linuxdirk, Krock, Rubenwardy, Pampogokiraly, Joe7575, Sorcerykid
|
||||
|
||||
And of course the Coredevs and Celeron55 for designing/keeping the engine running
|
||||
|
||||
|
|
|
@ -15,13 +15,6 @@ minetest.override_item("default:apple", {
|
|||
leafdecay = 3, leafdecay_drop = 1}
|
||||
})
|
||||
|
||||
if minetest.registered_nodes["flowers:mushroom_brown"] then
|
||||
minetest.override_item("flowers:mushroom_brown", {
|
||||
light_source = 1,
|
||||
groups = {food_mushroom = 1, snappy = 3, attached_node = 1, flammable = 2}
|
||||
})
|
||||
end
|
||||
|
||||
--= Aliases
|
||||
|
||||
-- Banana
|
||||
|
|
|
@ -28,11 +28,10 @@ minetest.register_craftitem("farming:barley", {
|
|||
|
||||
-- flour
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
output = "farming:flour",
|
||||
recipe = {
|
||||
"farming:barley", "farming:barley", "farming:barley",
|
||||
"farming:barley", "farming:mortar_pestle"
|
||||
{"farming:barley", "farming:barley", "farming:barley"},
|
||||
{"farming:barley", "farming:mortar_pestle", ""}
|
||||
},
|
||||
replacements = {{"group:food_mortar_pestle", "farming:mortar_pestle"}}
|
||||
})
|
||||
|
|
|
@ -81,9 +81,7 @@ minetest.register_craftitem("farming:beans", {
|
|||
-- beans can be used for green dye
|
||||
minetest.register_craft({
|
||||
output = "dye:green",
|
||||
recipe = {
|
||||
{"farming:beans"}
|
||||
}
|
||||
recipe = {{"farming:beans"}}
|
||||
})
|
||||
|
||||
-- beanpole
|
||||
|
|
|
@ -21,20 +21,17 @@ minetest.register_craftitem("farming:beetroot_soup", {
|
|||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
output = "farming:beetroot_soup",
|
||||
recipe = {
|
||||
"group:food_beetroot", "group:food_beetroot",
|
||||
"group:food_beetroot", "group:food_beetroot",
|
||||
"group:food_beetroot", "group:food_beetroot","group:food_bowl"
|
||||
{"group:food_beetroot", "group:food_beetroot", "group:food_beetroot"},
|
||||
{"group:food_beetroot", "group:food_bowl", "group:food_beetroot"}
|
||||
}
|
||||
})
|
||||
|
||||
-- red dye
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
output = "dye:red",
|
||||
recipe = {"group:food_beetroot"}
|
||||
recipe = {{"group:food_beetroot"}}
|
||||
})
|
||||
|
||||
local def = {
|
||||
|
|
|
@ -36,10 +36,9 @@ minetest.register_craftitem("farming:blueberry_pie", {
|
|||
|
||||
minetest.register_craft({
|
||||
output = "farming:blueberry_pie",
|
||||
type = "shapeless",
|
||||
recipe = {
|
||||
"group:food_flour", "group:food_sugar",
|
||||
"group:food_blueberries", "group:food_baking_tray"
|
||||
{"group:food_flour", "group:food_sugar", "group:food_blueberries"},
|
||||
{"group:food_baking_tray", "", ""}
|
||||
},
|
||||
replacements = {{"group:food_baking_tray", "farming:baking_tray"}}
|
||||
})
|
||||
|
@ -79,7 +78,7 @@ def.drop = {
|
|||
items = {
|
||||
{items = {"farming:blueberries 2"}, rarity = 1},
|
||||
{items = {"farming:blueberries"}, rarity = 2},
|
||||
{items = {"farming:blueberries"}, rarity = 3},
|
||||
{items = {"farming:blueberries"}, rarity = 3}
|
||||
}
|
||||
}
|
||||
minetest.register_node("farming:blueberry_4", table.copy(def))
|
||||
|
|
|
@ -27,9 +27,10 @@ minetest.register_craftitem("farming:carrot_juice", {
|
|||
|
||||
minetest.register_craft({
|
||||
output = "farming:carrot_juice",
|
||||
type = "shapeless",
|
||||
recipe = {
|
||||
"vessels:drinking_glass", "group:food_carrot", "farming:juicer"
|
||||
{"group:food_carrot"},
|
||||
{"farming:juicer"},
|
||||
{"vessels:drinking_glass"}
|
||||
},
|
||||
replacements = {
|
||||
{"group:food_juicer", "farming:juicer"}
|
||||
|
|
|
@ -20,20 +20,17 @@ minetest.register_craftitem("farming:chili_bowl", {
|
|||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
output = "farming:chili_bowl",
|
||||
recipe = {
|
||||
"group:food_chili_pepper", "group:food_barley",
|
||||
"group:food_tomato", "group:food_beans", "group:food_bowl"
|
||||
{"group:food_chili_pepper", "group:food_rice", "group:food_tomato"},
|
||||
{"group:food_beans", "group:food_bowl", ""}
|
||||
}
|
||||
})
|
||||
|
||||
-- chili can be used for red dye
|
||||
minetest.register_craft({
|
||||
output = "dye:red",
|
||||
recipe = {
|
||||
{"farming:chili_pepper"}
|
||||
}
|
||||
recipe = {{"farming:chili_pepper"}}
|
||||
})
|
||||
|
||||
-- chili definition
|
||||
|
|
|
@ -75,9 +75,7 @@ minetest.register_craftitem("farming:cocoa_beans", {
|
|||
|
||||
minetest.register_craft( {
|
||||
output = "dye:brown 2",
|
||||
recipe = {
|
||||
{ "farming:cocoa_beans" }
|
||||
}
|
||||
recipe = {{"farming:cocoa_beans"}}
|
||||
})
|
||||
|
||||
-- chocolate cookie
|
||||
|
@ -128,9 +126,7 @@ minetest.register_craft({
|
|||
|
||||
minetest.register_craft({
|
||||
output = "farming:chocolate_dark 9",
|
||||
recipe = {
|
||||
{"farming:chocolate_block"}
|
||||
}
|
||||
recipe = {{"farming:chocolate_block"}}
|
||||
})
|
||||
|
||||
-- cocoa definition
|
||||
|
|
|
@ -34,10 +34,10 @@ minetest.register_alias("farming:drinking_cup", "vessels:drinking_glass")
|
|||
|
||||
minetest.register_craft( {
|
||||
output = "farming:coffee_cup",
|
||||
type = "shapeless",
|
||||
recipe = {
|
||||
"vessels:drinking_glass", "group:food_coffee",
|
||||
"group:water_bucket", "group:food_saucepan"},
|
||||
{"group:food_saucepan", "group:food_coffee", "group:water_bucket"},
|
||||
{"", "vessels:drinking_glass", ""}
|
||||
},
|
||||
replacements = {
|
||||
{"group:water_bucket", "bucket:bucket_empty"},
|
||||
{"group:food_saucepan", "farming:saucepan"}
|
||||
|
@ -47,10 +47,10 @@ minetest.register_craft( {
|
|||
if minetest.get_modpath("bucket_wooden") then
|
||||
minetest.register_craft( {
|
||||
output = "farming:coffee_cup",
|
||||
type = "shapeless",
|
||||
recipe = {
|
||||
"vessels:drinking_glass", "group:food_coffee",
|
||||
"group:water_bucket_wooden", "group:food_saucepan"},
|
||||
{"group:food_saucepan", "group:food_coffee", "group:water_bucket_wooden"},
|
||||
{"", "vessels:drinking_glass", ""}
|
||||
},
|
||||
replacements = {
|
||||
{"group:water_bucket_wooden", "bucket_wooden:bucket_empty"},
|
||||
{"group:food_saucepan", "farming:saucepan"}
|
||||
|
|
|
@ -47,7 +47,7 @@ minetest.register_craft({
|
|||
},
|
||||
replacements = {
|
||||
{"group:food_mortar_pestle", "farming:mortar_pestle"},
|
||||
{"group:food_baking_tray", "farming:baking_tray"},
|
||||
{"group:food_baking_tray", "farming:baking_tray"}
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -72,9 +72,9 @@ minetest.register_node("farming:bottle_ethanol", {
|
|||
minetest.register_craft( {
|
||||
output = "farming:bottle_ethanol",
|
||||
recipe = {
|
||||
{ "vessels:glass_bottle", "group:food_corn", "group:food_corn"},
|
||||
{ "group:food_corn", "group:food_corn", "group:food_corn"},
|
||||
{ "group:food_corn", "group:food_corn", "group:food_corn"}
|
||||
{"group:food_corn", "group:food_corn", "group:food_corn"},
|
||||
{"group:food_corn", "vessels:glass_bottle", "group:food_corn"},
|
||||
{"group:food_corn", "group:food_corn", "group:food_corn"}
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -82,7 +82,7 @@ minetest.register_craft({
|
|||
type = "fuel",
|
||||
recipe = "farming:bottle_ethanol",
|
||||
burntime = 80,
|
||||
replacements = {{ "farming:bottle_ethanol", "vessels:glass_bottle"}}
|
||||
replacements = {{"farming:bottle_ethanol", "vessels:glass_bottle"}}
|
||||
})
|
||||
|
||||
-- corn definition
|
||||
|
|
|
@ -76,9 +76,7 @@ minetest.register_craftitem("farming:grapes", {
|
|||
-- grapes can be used for violet dye
|
||||
minetest.register_craft({
|
||||
output = "dye:violet",
|
||||
recipe = {
|
||||
{"farming:grapes"}
|
||||
}
|
||||
recipe = {{"farming:grapes"}}
|
||||
})
|
||||
|
||||
-- trellis
|
||||
|
|
|
@ -65,7 +65,7 @@ minetest.register_craft({
|
|||
type = "fuel",
|
||||
recipe = "farming:hemp_oil",
|
||||
burntime = 20,
|
||||
replacements = {{ "farming:hemp_oil", "vessels:glass_bottle"}}
|
||||
replacements = {{"farming:hemp_oil", "vessels:glass_bottle"}}
|
||||
})
|
||||
|
||||
-- hemp fibre
|
||||
|
|
|
@ -48,7 +48,7 @@ def.groups.growing = nil
|
|||
def.drop = {
|
||||
items = {
|
||||
{items = {'farming:lettuce 2'}, rarity = 1},
|
||||
{items = {'farming:lettuce 1'}, rarity = 2},
|
||||
{items = {'farming:lettuce 1'}, rarity = 2}
|
||||
}
|
||||
}
|
||||
minetest.register_node("farming:lettuce_5", table.copy(def))
|
||||
|
|
|
@ -21,9 +21,8 @@ minetest.register_craft({
|
|||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
output = "farming:melon_slice 4",
|
||||
recipe = {"farming:melon_8", "farming:cutting_board"},
|
||||
recipe = {{"farming:cutting_board", "farming:melon_8"}},
|
||||
replacements = {{"farming:cutting_board", "farming:cutting_board"}}
|
||||
})
|
||||
|
||||
|
@ -72,22 +71,22 @@ def.tiles = {"farming_melon_7.png"}
|
|||
minetest.register_node("farming:melon_7", table.copy(def))
|
||||
|
||||
-- stage 8 (final)
|
||||
def.drawtype = "nodebox"
|
||||
def.description = S("Melon")
|
||||
def.tiles = {
|
||||
"farming_melon_top.png", "farming_melon_bottom.png", "farming_melon_side.png"
|
||||
}
|
||||
def.selection_box = {-.5, -.5, -.5, .5, .5, .5}
|
||||
def.walkable = true
|
||||
def.buildable_to = false
|
||||
def.paramtype2 = "facedir"
|
||||
def.groups = {
|
||||
food_melon = 1, snappy = 2, oddly_breakable_by_hand = 1,
|
||||
flammable = 2, plant = 1
|
||||
}
|
||||
def.drop = "farming:melon_8"
|
||||
def.on_place = minetest.rotate_node
|
||||
minetest.register_node("farming:melon_8", table.copy(def))
|
||||
minetest.register_node("farming:melon_8", {
|
||||
description = S("Melon"),
|
||||
tiles = {
|
||||
"farming_melon_top.png",
|
||||
"farming_melon_bottom.png",
|
||||
"farming_melon_side.png"
|
||||
},
|
||||
groups = {
|
||||
food_melon = 1, snappy = 2, oddly_breakable_by_hand = 1,
|
||||
flammable = 2, plant = 1
|
||||
},
|
||||
drop = "farming:melon_8",
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
paramtype2 = "facedir",
|
||||
on_place = minetest.rotate_node
|
||||
})
|
||||
|
||||
-- add to registered_plants
|
||||
farming.registered_plants["farming:melon"] = {
|
||||
|
|
|
@ -29,11 +29,9 @@ minetest.register_craftitem("farming:mint_tea", {
|
|||
|
||||
minetest.register_craft({
|
||||
output = "farming:mint_tea",
|
||||
type = "shapeless",
|
||||
recipe = {
|
||||
"vessels:drinking_glass", "group:food_mint",
|
||||
"group:food_mint", "group:food_mint",
|
||||
"farming:juicer", "group:water_bucket"
|
||||
{"group:food_mint", "group:food_mint", "group:food_mint"},
|
||||
{"group:water_bucket", "farming:juicer", "vessels:drinking_glass"}
|
||||
},
|
||||
replacements = {
|
||||
{"group:food_juicer", "farming:juicer"},
|
||||
|
@ -44,11 +42,9 @@ minetest.register_craft({
|
|||
if minetest.get_modpath("bucket_wooden") then
|
||||
minetest.register_craft({
|
||||
output = "farming:mint_tea",
|
||||
type = "shapeless",
|
||||
recipe = {
|
||||
"vessels:drinking_glass", "group:food_mint",
|
||||
"group:food_mint", "group:food_mint",
|
||||
"farming:juicer", "group:water_bucket_wooden"
|
||||
{"group:food_mint", "group:food_mint", "group:food_mint"},
|
||||
{"group:water_bucket_wooden", "farming:juicer", "vessels:drinking_glass"}
|
||||
},
|
||||
replacements = {
|
||||
{"group:food_juicer", "farming:juicer"},
|
||||
|
@ -92,7 +88,7 @@ def.drop = {
|
|||
{items = {"farming:mint_leaf 2"}, rarity = 1},
|
||||
{items = {"farming:mint_leaf 2"}, rarity = 2},
|
||||
{items = {"farming:seed_mint 1"}, rarity = 1},
|
||||
{items = {"farming:seed_mint 2"}, rarity = 2},
|
||||
{items = {"farming:seed_mint 2"}, rarity = 2}
|
||||
}
|
||||
}
|
||||
minetest.register_node("farming:mint_4", table.copy(def))
|
||||
|
|
|
@ -27,12 +27,11 @@ minetest.register_craftitem("farming:onion_soup", {
|
|||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
output = "farming:onion_soup",
|
||||
recipe = {
|
||||
"group:food_onion", "group:food_onion", "group:food_pot",
|
||||
"group:food_onion", "group:food_onion",
|
||||
"group:food_onion", "group:food_onion", "group:food_bowl"
|
||||
{"group:food_onion", "group:food_onion", "group:food_onion"},
|
||||
{"group:food_onion", "group:food_pot", "group:food_onion"},
|
||||
{"", "group:food_bowl", ""}
|
||||
},
|
||||
replacements = {{"farming:pot", "farming:pot"}}
|
||||
})
|
||||
|
@ -81,7 +80,7 @@ def.drop = {
|
|||
{items = {"farming:onion"}, rarity = 1},
|
||||
{items = {"farming:onion"}, rarity = 2},
|
||||
{items = {"farming:onion"}, rarity = 2},
|
||||
{items = {"farming:onion"}, rarity = 5},
|
||||
{items = {"farming:onion"}, rarity = 5}
|
||||
}
|
||||
}
|
||||
minetest.register_node("farming:onion_5", table.copy(def))
|
||||
|
|
|
@ -21,9 +21,8 @@ minetest.register_craftitem("farming:peas", {
|
|||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
output = "farming:peas",
|
||||
recipe = {"farming:pea_pod"}
|
||||
recipe = {{"farming:pea_pod"}}
|
||||
})
|
||||
|
||||
-- pea soup
|
||||
|
@ -35,9 +34,12 @@ minetest.register_craftitem("farming:pea_soup", {
|
|||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
output = "farming:pea_soup",
|
||||
recipe = {"group:food_peas", "group:food_peas", "group:food_bowl"}
|
||||
recipe = {
|
||||
{"group:food_peas"},
|
||||
{"group:food_peas"},
|
||||
{"group:food_bowl"}
|
||||
}
|
||||
})
|
||||
|
||||
local def = {
|
||||
|
|
|
@ -30,7 +30,7 @@ minetest.register_craftitem("farming:pepper_yellow", {
|
|||
description = S("Yellow Pepper"),
|
||||
inventory_image = "crops_pepper_yellow.png",
|
||||
on_use = minetest.item_eat(3),
|
||||
groups = {food_pepper = 1, flammable = 3},
|
||||
groups = {food_pepper = 1, flammable = 3}
|
||||
})
|
||||
|
||||
-- red pepper
|
||||
|
@ -38,13 +38,12 @@ minetest.register_craftitem("farming:pepper_red", {
|
|||
description = S("Red Pepper"),
|
||||
inventory_image = "crops_pepper_red.png",
|
||||
on_use = minetest.item_eat(4),
|
||||
groups = {food_pepper = 1, flammable = 3},
|
||||
groups = {food_pepper = 1, flammable = 3}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
output = "farming:peppercorn",
|
||||
recipe = {"group:food_pepper"}
|
||||
recipe = {{"group:food_pepper"}}
|
||||
})
|
||||
|
||||
-- ground pepper
|
||||
|
@ -69,8 +68,11 @@ minetest.register_node("farming:pepper_ground", {
|
|||
|
||||
minetest.register_craft( {
|
||||
output = "farming:pepper_ground",
|
||||
type = "shapeless",
|
||||
recipe = {"group:food_peppercorn", "vessels:glass_bottle", "farming:mortar_pestle"},
|
||||
recipe = {
|
||||
{"group:food_peppercorn"},
|
||||
{"farming:mortar_pestle"},
|
||||
{"vessels:glass_bottle"}
|
||||
},
|
||||
replacements = {{"group:food_mortar_pestle", "farming:mortar_pestle"}}
|
||||
})
|
||||
|
||||
|
@ -124,9 +126,9 @@ minetest.register_node("farming:pepper_5", table.copy(def))
|
|||
def.tiles = {"crops_pepper_plant_6.png"}
|
||||
def.drop = {
|
||||
max_items = 2, items = {
|
||||
{items = {'farming:pepper_yellow 2'}, rarity = 1},
|
||||
{items = {'farming:pepper_yellow'}, rarity = 2},
|
||||
{items = {'farming:pepper_yellow'}, rarity = 3},
|
||||
{items = {"farming:pepper_yellow 2"}, rarity = 1},
|
||||
{items = {"farming:pepper_yellow"}, rarity = 2},
|
||||
{items = {"farming:pepper_yellow"}, rarity = 3}
|
||||
}
|
||||
}
|
||||
minetest.register_node("farming:pepper_6", table.copy(def))
|
||||
|
@ -136,9 +138,9 @@ def.tiles = {"crops_pepper_plant_7.png"}
|
|||
def.groups.growing = nil
|
||||
def.drop = {
|
||||
max_items = 2, items = {
|
||||
{items = {'farming:pepper_red 2'}, rarity = 1},
|
||||
{items = {'farming:pepper_red'}, rarity = 2},
|
||||
{items = {'farming:pepper_red'}, rarity = 3},
|
||||
{items = {"farming:pepper_red 2"}, rarity = 1},
|
||||
{items = {"farming:pepper_red"}, rarity = 2},
|
||||
{items = {"farming:pepper_red"}, rarity = 3}
|
||||
}
|
||||
}
|
||||
minetest.register_node("farming:pepper_7", table.copy(def))
|
||||
|
|
|
@ -38,8 +38,7 @@ minetest.register_craftitem("farming:pineapple_ring", {
|
|||
|
||||
minetest.register_craft( {
|
||||
output = "farming:pineapple_ring 5",
|
||||
type = "shapeless",
|
||||
recipe = {"group:food_pineapple"},
|
||||
recipe = {{"group:food_pineapple"}},
|
||||
replacements = {{"farming:pineapple", "farming:pineapple_top"}}
|
||||
})
|
||||
|
||||
|
@ -53,11 +52,12 @@ minetest.register_craftitem("farming:pineapple_juice", {
|
|||
|
||||
minetest.register_craft({
|
||||
output = "farming:pineapple_juice",
|
||||
type = "shapeless",
|
||||
recipe = {
|
||||
"vessels:drinking_glass", "group:food_pineapple_ring",
|
||||
"group:food_pineapple_ring", "group:food_pineapple_ring",
|
||||
"farming:juicer"},
|
||||
{"group:food_pineapple_ring", "group:food_pineapple_ring",
|
||||
"group:food_pineapple_ring"},
|
||||
{"", "farming:juicer", ""},
|
||||
{"", "vessels:drinking_glass", ""}
|
||||
},
|
||||
replacements = {
|
||||
{"group:food_juicer", "farming:juicer"}
|
||||
}
|
||||
|
@ -65,10 +65,10 @@ minetest.register_craft({
|
|||
|
||||
minetest.register_craft({
|
||||
output = "farming:pineapple_juice 2",
|
||||
type = "shapeless",
|
||||
recipe = {
|
||||
"vessels:drinking_glass", "vessels:drinking_glass",
|
||||
"group:food_pineapple", "farming:juicer"
|
||||
{"group:food_pineapple", ""},
|
||||
{"farming:juicer", ""},
|
||||
{"vessels:drinking_glass", "vessels:drinking_glass"}
|
||||
},
|
||||
replacements = {
|
||||
{"group:food_juicer", "farming:juicer"}
|
||||
|
|
|
@ -25,9 +25,8 @@ minetest.register_craft({
|
|||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
output = "farming:pumpkin_slice 4",
|
||||
recipe = {"farming:pumpkin", "farming:cutting_board"},
|
||||
recipe = {{"farming:cutting_board", "farming:pumpkin"}},
|
||||
replacements = {{"farming:cutting_board", "farming:cutting_board"}}
|
||||
})
|
||||
|
||||
|
@ -122,8 +121,9 @@ minetest.register_craftitem("farming:pumpkin_dough", {
|
|||
|
||||
minetest.register_craft({
|
||||
output = "farming:pumpkin_dough",
|
||||
type = "shapeless",
|
||||
recipe = {"group:food_flour", "group:food_pumpkin_slice", "group:food_pumpkin_slice"}
|
||||
recipe = {
|
||||
{"group:food_pumpkin_slice", "group:food_flour", "group:food_pumpkin_slice"}
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
|
@ -183,7 +183,7 @@ minetest.register_node("farming:pumpkin_8", {
|
|||
description = S("Pumpkin"),
|
||||
tiles = {
|
||||
"farming_pumpkin_top.png",
|
||||
"farming_pumpkin_top.png",
|
||||
"farming_pumpkin_bottom.png",
|
||||
"farming_pumpkin_side.png"
|
||||
},
|
||||
groups = {
|
||||
|
@ -191,7 +191,9 @@ minetest.register_node("farming:pumpkin_8", {
|
|||
flammable = 2, plant = 1
|
||||
},
|
||||
drop = "farming:pumpkin_8",
|
||||
sounds = default.node_sound_wood_defaults()
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
paramtype2 = "facedir",
|
||||
on_place = minetest.rotate_node
|
||||
})
|
||||
|
||||
minetest.register_alias("farming:pumpkin", "farming:pumpkin_8")
|
||||
|
|
|
@ -45,7 +45,7 @@ local def = {
|
|||
},
|
||||
sounds = default.node_sound_leaves_defaults(),
|
||||
minlight = 10,
|
||||
maxlight = 12,
|
||||
maxlight = 12
|
||||
}
|
||||
|
||||
-- stage 1
|
||||
|
|
|
@ -19,11 +19,10 @@ minetest.override_item("farming:rye", {
|
|||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
output = "farming:flour",
|
||||
recipe = {
|
||||
"farming:rye", "farming:rye", "farming:rye", "farming:rye",
|
||||
"farming:mortar_pestle"
|
||||
{"farming:rye", "farming:rye", "farming:rye"},
|
||||
{"farming:rye", "farming:mortar_pestle", ""}
|
||||
},
|
||||
replacements = {{"group:food_mortar_pestle", "farming:mortar_pestle"}}
|
||||
})
|
||||
|
@ -44,11 +43,10 @@ minetest.override_item("farming:oat", {
|
|||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
output = "farming:flour",
|
||||
recipe = {
|
||||
"farming:oat", "farming:oat", "farming:oat", "farming:oat",
|
||||
"farming:mortar_pestle"
|
||||
{"farming:oat", "farming:oat", "farming:oat"},
|
||||
{"farming:oat", "farming:mortar_pestle", ""}
|
||||
},
|
||||
replacements = {{"group:food_mortar_pestle", "farming:mortar_pestle"}}
|
||||
})
|
||||
|
@ -82,11 +80,10 @@ minetest.register_craftitem("farming:rice_flour", {
|
|||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
output = "farming:rice_flour",
|
||||
recipe = {
|
||||
"farming:rice", "farming:rice", "farming:rice", "farming:rice",
|
||||
"farming:mortar_pestle"
|
||||
{"farming:rice", "farming:rice", "farming:rice"},
|
||||
{"farming:rice", "farming:mortar_pestle", ""}
|
||||
},
|
||||
replacements = {{"group:food_mortar_pestle", "farming:mortar_pestle"}}
|
||||
})
|
||||
|
|
|
@ -19,9 +19,8 @@ minetest.register_craftitem("farming:soy_beans", {
|
|||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
output = "farming:soy_beans",
|
||||
recipe = {"farming:soy_pod"}
|
||||
recipe = {{"farming:soy_pod"}}
|
||||
})
|
||||
|
||||
-- soy sauce
|
||||
|
@ -43,15 +42,26 @@ minetest.register_node("farming:soy_sauce", {
|
|||
sounds = default.node_sound_glass_defaults()
|
||||
})
|
||||
|
||||
-- river water availability check
|
||||
local bucket_water
|
||||
|
||||
if minetest.get_mapgen_setting("mgname") == "valleys"
|
||||
or minetest.get_modpath("ethereal") then
|
||||
bucket_water = "bucket:bucket_river_water"
|
||||
else
|
||||
bucket_water = "bucket:bucket_water"
|
||||
end
|
||||
|
||||
-- soy sauce recipe
|
||||
minetest.register_craft( {
|
||||
type = "shapeless",
|
||||
output = "farming:soy_sauce",
|
||||
recipe = {
|
||||
"group:food_soy", "group:food_soy", "group:food_juicer",
|
||||
"bucket:bucket_river_water", "vessels:glass_bottle", "group:food_salt"
|
||||
{"group:food_soy", "group:food_salt", "group:food_soy"},
|
||||
{"", "group:food_juicer", ""},
|
||||
{"", bucket_water, "vessels:glass_bottle"}
|
||||
},
|
||||
replacements = {
|
||||
{"bucket:bucket_river_water", "bucket:bucket_empty"},
|
||||
{bucket_water, "bucket:bucket_empty"},
|
||||
{"group:food_juicer", "farming:juicer"}
|
||||
}
|
||||
})
|
||||
|
@ -78,11 +88,10 @@ minetest.register_node("farming:soy_milk", {
|
|||
})
|
||||
|
||||
minetest.register_craft( {
|
||||
type = "shapeless",
|
||||
output = "farming:soy_milk",
|
||||
recipe = {
|
||||
"group:food_soy", "group:food_soy", "group:food_soy",
|
||||
"farming:vanilla_extract", "bucket:bucket_water", "vessels:drinking_glass"
|
||||
{"group:food_soy", "group:food_soy", "group:food_soy"},
|
||||
{"farming:vanilla_extract", "bucket:bucket_water", "vessels:drinking_glass"}
|
||||
},
|
||||
replacements = {
|
||||
{"bucket:bucket_water", "bucket:bucket_empty"},
|
||||
|
@ -100,10 +109,9 @@ minetest.register_craftitem("farming:tofu", {
|
|||
|
||||
minetest.register_craft({
|
||||
output = "farming:tofu",
|
||||
type = "shapeless",
|
||||
recipe = {
|
||||
"farming:baking_tray", "group:food_soy", "group:food_soy",
|
||||
"group:food_soy", "group:food_soy", "group:food_soy",
|
||||
{"farming:baking_tray", "group:food_soy", "group:food_soy"},
|
||||
{"group:food_soy", "group:food_soy", "group:food_soy"}
|
||||
},
|
||||
replacements = {{"farming:baking_tray", "farming:baking_tray"}}
|
||||
})
|
||||
|
@ -163,7 +171,7 @@ minetest.register_node("farming:soy_4", table.copy(def))
|
|||
def.tiles = {"farming_soy_5.png"}
|
||||
def.drop = {
|
||||
max_items = 1, items = {
|
||||
{items = {'farming:soy_pod'}, rarity = 1},
|
||||
{items = {"farming:soy_pod"}, rarity = 1},
|
||||
}
|
||||
}
|
||||
minetest.register_node("farming:soy_5", table.copy(def))
|
||||
|
@ -172,9 +180,9 @@ minetest.register_node("farming:soy_5", table.copy(def))
|
|||
def.tiles = {"farming_soy_6.png"}
|
||||
def.drop = {
|
||||
max_items = 3, items = {
|
||||
{items = {'farming:soy_pod'}, rarity = 1},
|
||||
{items = {'farming:soy_pod'}, rarity = 2},
|
||||
{items = {'farming:soy_pod'}, rarity = 3},
|
||||
{items = {"farming:soy_pod"}, rarity = 1},
|
||||
{items = {"farming:soy_pod"}, rarity = 2},
|
||||
{items = {"farming:soy_pod"}, rarity = 3},
|
||||
}
|
||||
}
|
||||
minetest.register_node("farming:soy_6", table.copy(def))
|
||||
|
@ -184,11 +192,11 @@ def.tiles = {"farming_soy_7.png"}
|
|||
def.groups.growing = nil
|
||||
def.drop = {
|
||||
max_items = 5, items = {
|
||||
{items = {'farming:soy_pod'}, rarity = 1},
|
||||
{items = {'farming:soy_pod'}, rarity = 2},
|
||||
{items = {'farming:soy_pod'}, rarity = 3},
|
||||
{items = {'farming:soy_pod'}, rarity = 4},
|
||||
{items = {'farming:soy_pod'}, rarity = 5}
|
||||
{items = {"farming:soy_pod"}, rarity = 1},
|
||||
{items = {"farming:soy_pod"}, rarity = 2},
|
||||
{items = {"farming:soy_pod"}, rarity = 3},
|
||||
{items = {"farming:soy_pod"}, rarity = 4},
|
||||
{items = {"farming:soy_pod"}, rarity = 5}
|
||||
}
|
||||
}
|
||||
minetest.register_node("farming:soy_7", table.copy(def))
|
||||
|
|
|
@ -17,6 +17,23 @@ minetest.register_craftitem("farming:tomato", {
|
|||
on_use = minetest.item_eat(4)
|
||||
})
|
||||
|
||||
-- tomato soup
|
||||
minetest.register_craftitem("farming:tomato_soup", {
|
||||
description = S("Tomato Soup"),
|
||||
inventory_image = "farming_tomato_soup.png",
|
||||
groups = {flammable = 2},
|
||||
on_use = minetest.item_eat(8, "farming:bowl")
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "farming:tomato_soup",
|
||||
recipe = {
|
||||
{"group:food_tomato"},
|
||||
{"group:food_tomato"},
|
||||
{"group:food_bowl"}
|
||||
}
|
||||
})
|
||||
|
||||
-- tomato definition
|
||||
local def = {
|
||||
drawtype = "plantlike",
|
||||
|
|
|
@ -8,7 +8,7 @@ minetest.register_craftitem("farming:vanilla", {
|
|||
on_place = function(itemstack, placer, pointed_thing)
|
||||
return farming.place_seed(itemstack, placer, pointed_thing, "farming:vanilla_1")
|
||||
end,
|
||||
on_use = minetest.item_eat(1),
|
||||
on_use = minetest.item_eat(1)
|
||||
})
|
||||
|
||||
-- crop definition
|
||||
|
@ -49,8 +49,8 @@ minetest.register_node("farming:vanilla_extract", {
|
|||
minetest.register_craft( {
|
||||
output = "farming:vanilla_extract",
|
||||
recipe = {
|
||||
{ "group:food_vanilla", "group:food_vanilla", "group:food_vanilla"},
|
||||
{ "group:food_vanilla", "farming:bottle_ethanol", "bucket:bucket_water"},
|
||||
{"group:food_vanilla", "group:food_vanilla", "group:food_vanilla"},
|
||||
{"group:food_vanilla", "farming:bottle_ethanol", "bucket:bucket_water"},
|
||||
},
|
||||
replacements = {
|
||||
{"bucket:bucket_water", "bucket:bucket_empty"},
|
||||
|
@ -61,7 +61,7 @@ minetest.register_craft({
|
|||
type = "fuel",
|
||||
recipe = "farming:vanilla_extract",
|
||||
burntime = 25,
|
||||
replacements = {{ "farming:vanilla_extract", "vessels:glass_bottle" }}
|
||||
replacements = {{"farming:vanilla_extract", "vessels:glass_bottle"}}
|
||||
})
|
||||
|
||||
-- stage 1
|
||||
|
@ -92,9 +92,9 @@ minetest.register_node("farming:vanilla_6", table.copy(def))
|
|||
def.tiles = {"farming_vanilla_7.png"}
|
||||
def.drop = {
|
||||
items = {
|
||||
{items = {'farming:vanilla'}, rarity = 1},
|
||||
{items = {'farming:vanilla'}, rarity = 2},
|
||||
{items = {'farming:vanilla'}, rarity = 3}
|
||||
{items = {"farming:vanilla"}, rarity = 1},
|
||||
{items = {"farming:vanilla"}, rarity = 2},
|
||||
{items = {"farming:vanilla"}, rarity = 3}
|
||||
}
|
||||
}
|
||||
minetest.register_node("farming:vanilla_7", table.copy(def))
|
||||
|
@ -104,10 +104,10 @@ def.tiles = {"farming_vanilla_8.png"}
|
|||
def.groups.growing = nil
|
||||
def.drop = {
|
||||
items = {
|
||||
{items = {'farming:vanilla 2'}, rarity = 1},
|
||||
{items = {'farming:vanilla 2'}, rarity = 2},
|
||||
{items = {'farming:vanilla 2'}, rarity = 2},
|
||||
{items = {'farming:vanilla 2'}, rarity = 3}
|
||||
{items = {"farming:vanilla 2"}, rarity = 1},
|
||||
{items = {"farming:vanilla 2"}, rarity = 2},
|
||||
{items = {"farming:vanilla 2"}, rarity = 2},
|
||||
{items = {"farming:vanilla 2"}, rarity = 3}
|
||||
}
|
||||
}
|
||||
minetest.register_node("farming:vanilla_8", table.copy(def))
|
||||
|
|
|
@ -46,9 +46,7 @@ minetest.register_craft({
|
|||
|
||||
minetest.register_craft({
|
||||
output = "farming:wheat 3",
|
||||
recipe = {
|
||||
{"farming:straw"}
|
||||
}
|
||||
recipe = {{"farming:straw"}}
|
||||
})
|
||||
|
||||
-- check and register stairs
|
||||
|
@ -80,11 +78,10 @@ minetest.register_craftitem("farming:flour", {
|
|||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
output = "farming:flour",
|
||||
recipe = {
|
||||
"farming:wheat", "farming:wheat", "farming:wheat",
|
||||
"farming:wheat", "farming:mortar_pestle"
|
||||
{"farming:wheat", "farming:wheat", "farming:wheat"},
|
||||
{"farming:wheat", "farming:mortar_pestle", ""}
|
||||
},
|
||||
replacements = {{"group:food_mortar_pestle", "farming:mortar_pestle"}}
|
||||
})
|
||||
|
@ -113,9 +110,8 @@ minetest.register_craftitem("farming:bread_slice", {
|
|||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
output = "farming:bread_slice 5",
|
||||
recipe = {"farming:bread", "group:food_cutting_board"},
|
||||
recipe = {{"group:food_cutting_board", "farming:bread"}},
|
||||
replacements = {{"group:food_cutting_board", "farming:cutting_board"}}
|
||||
})
|
||||
|
||||
|
|
|
@ -318,7 +318,6 @@ minetest.register_craftitem("farming:apple_pie", {
|
|||
|
||||
minetest.register_craft({
|
||||
output = "farming:apple_pie",
|
||||
-- type = "shapeless",
|
||||
recipe = {
|
||||
{"group:food_flour", "group:food_sugar", "group:food_apple"},
|
||||
{"", "group:food_baking_tray", ""}
|
||||
|
@ -347,9 +346,10 @@ minetest.register_craftitem("farming:cactus_juice", {
|
|||
|
||||
minetest.register_craft({
|
||||
output = "farming:cactus_juice",
|
||||
-- type = "shapeless",
|
||||
recipe = {
|
||||
{"default:cactus", "farming:juicer", "vessels:drinking_glass"}
|
||||
{"default:cactus"},
|
||||
{"farming:juicer"},
|
||||
{"vessels:drinking_glass"}
|
||||
},
|
||||
replacements = {
|
||||
{"group:food_juicer", "farming:juicer"}
|
||||
|
@ -366,7 +366,6 @@ minetest.register_craftitem("farming:pasta", {
|
|||
|
||||
minetest.register_craft({
|
||||
output = "farming:pasta",
|
||||
-- type = "shapeless",
|
||||
recipe = {
|
||||
{"group:food_flour", "group:food_butter", "group:food_mixing_bowl"}
|
||||
},
|
||||
|
@ -375,7 +374,6 @@ minetest.register_craft({
|
|||
|
||||
minetest.register_craft({
|
||||
output = "farming:pasta",
|
||||
-- type = "shapeless",
|
||||
recipe = {
|
||||
{"group:food_flour", "group:food_oil", "group:food_mixing_bowl"}
|
||||
},
|
||||
|
@ -395,7 +393,6 @@ minetest.register_craftitem("farming:spaghetti", {
|
|||
|
||||
minetest.register_craft({
|
||||
output = "farming:spaghetti",
|
||||
-- type = "shapeless",
|
||||
recipe = {
|
||||
{"group:food_pasta", "group:food_saucepan", "group:food_tomato"},
|
||||
{"group:food_garlic_clove", "group:food_garlic_clove", ""}
|
||||
|
@ -413,7 +410,6 @@ minetest.register_craftitem("farming:bibimbap", {
|
|||
|
||||
minetest.register_craft({
|
||||
output = "farming:bibimbap",
|
||||
-- type = "shapeless",
|
||||
recipe = {
|
||||
{"group:food_skillet", "group:food_bowl", "group:food_egg"},
|
||||
{"group:food_rice", "group:food_chicken_raw", "group:food_cabbage"},
|
||||
|
@ -442,7 +438,6 @@ minetest.register_craftitem("farming:burger", {
|
|||
})
|
||||
|
||||
minetest.register_craft({
|
||||
-- type = "shapeless",
|
||||
output = "farming:burger",
|
||||
recipe = {
|
||||
{"farming:bread", "group:food_meat", "group:food_cheese"},
|
||||
|
@ -550,7 +545,6 @@ minetest.register_craftitem("farming:flan", {
|
|||
})
|
||||
|
||||
minetest.register_craft({
|
||||
-- type = "shapeless",
|
||||
output = "farming:flan",
|
||||
recipe = {
|
||||
{"group:food_sugar", "group:food_milk", "farming:caramel"},
|
||||
|
@ -574,7 +568,6 @@ minetest.register_craftitem("farming:cheese_vegan", {
|
|||
|
||||
|
||||
minetest.register_craft({
|
||||
-- type = "shapeless",
|
||||
output = "farming:cheese_vegan",
|
||||
recipe = {
|
||||
{"farming:soy_milk", "farming:soy_milk", "farming:soy_milk"},
|
||||
|
@ -589,7 +582,6 @@ minetest.register_craft({
|
|||
})
|
||||
|
||||
minetest.register_craft({
|
||||
-- type = "shapeless",
|
||||
output = "farming:cheese_vegan",
|
||||
recipe = {
|
||||
{"farming:soy_milk", "farming:soy_milk", "farming:soy_milk"},
|
||||
|
@ -608,14 +600,14 @@ minetest.register_craftitem("farming:onigiri", {
|
|||
description = S("Onirigi"),
|
||||
inventory_image = "farming_onigiri.png",
|
||||
on_use = minetest.item_eat(2),
|
||||
groups = {flammable = 2},
|
||||
groups = {flammable = 2}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
output = "farming:onigiri",
|
||||
recipe = {
|
||||
"group:food_rice", "group:food_rice", "group:food_seaweed", "group:food_salt"
|
||||
{"group:food_rice", "group:food_salt", "group:food_rice"},
|
||||
{"", "group:food_seaweed", ""}
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -625,16 +617,16 @@ minetest.register_craftitem("farming:gyoza", {
|
|||
description = S("Gyoza"),
|
||||
inventory_image = "farming_gyoza.png",
|
||||
on_use = minetest.item_eat(4),
|
||||
groups = {flammable = 2},
|
||||
groups = {flammable = 2}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
output = "farming:gyoza 4",
|
||||
recipe = {
|
||||
"group:food_cabbage", "group:food_garlic_clove", "group:food_onion",
|
||||
"group:food_meat_raw", "group:food_salt", "group:food_skillet",
|
||||
"group:food_flour"
|
||||
{"group:food_cabbage", "group:food_garlic_clove", "group:food_onion"},
|
||||
{"group:food_meat_raw", "group:food_salt", "group:food_flour"},
|
||||
{"", "group:food_skillet", ""}
|
||||
|
||||
},
|
||||
replacements = {
|
||||
{"group:food_skillet", "farming:skillet"}
|
||||
|
@ -647,15 +639,15 @@ minetest.register_craftitem("farming:mochi", {
|
|||
description = S("Mochi"),
|
||||
inventory_image = "farming_mochi.png",
|
||||
on_use = minetest.item_eat(3),
|
||||
groups = {flammable = 2},
|
||||
groups = {flammable = 2}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
output = "farming:mochi",
|
||||
recipe = {
|
||||
"group:food_mortar_pestle", "group:food_rice", "group:food_rice",
|
||||
"group:food_sugar", "bucket:bucket_river_water"
|
||||
{"group:food_rice", "group:food_sugar", "group:food_rice"},
|
||||
{"", "group:food_mortar_pestle", ""},
|
||||
{"", "bucket:bucket_river_water", ""}
|
||||
},
|
||||
replacements = {
|
||||
{"group:food_mortar_pestle", "farming:mortar_pestle"},
|
||||
|
|
|
@ -361,7 +361,7 @@ farming.add_to_scythe_not_drops = function(item)
|
|||
end
|
||||
|
||||
minetest.register_tool("farming:scythe_mithril", {
|
||||
description = S("Mithril Scythe (Right-click to harvest and replant crops)"),
|
||||
description = S("Mithril Scythe (Use to harvest and replant crops)"),
|
||||
inventory_image = "farming_scythe_mithril.png",
|
||||
sound = {breaks = "default_tool_breaks"},
|
||||
|
||||
|
|
|
@ -169,3 +169,7 @@ Created by Felfa (CC0)
|
|||
|
||||
Created by gorlock (CC0)
|
||||
farming_salt_crystal.png
|
||||
|
||||
Created by sirrobzeroone (CC0)
|
||||
farming_gyoza.png
|
||||
farming_pineapple_ring.png
|
||||
|
|
Before Width: | Height: | Size: 603 B After Width: | Height: | Size: 266 B |
Before Width: | Height: | Size: 114 B After Width: | Height: | Size: 155 B |
Before Width: | Height: | Size: 122 B After Width: | Height: | Size: 172 B |
Before Width: | Height: | Size: 132 B After Width: | Height: | Size: 191 B |
Before Width: | Height: | Size: 174 B After Width: | Height: | Size: 233 B |
Before Width: | Height: | Size: 158 B After Width: | Height: | Size: 253 B |
Before Width: | Height: | Size: 166 B After Width: | Height: | Size: 289 B |
Before Width: | Height: | Size: 164 B After Width: | Height: | Size: 449 B |
After Width: | Height: | Size: 258 B |
After Width: | Height: | Size: 161 B |
|
@ -20,7 +20,7 @@ minetest.register_craft({
|
|||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "farming:bowl",
|
||||
burntime = 10,
|
||||
burntime = 10
|
||||
})
|
||||
|
||||
-- saucepan
|
||||
|
@ -155,9 +155,6 @@ minetest.register_craft({
|
|||
})
|
||||
|
||||
minetest.register_craft( {
|
||||
type = "shapeless",
|
||||
output = "vessels:glass_fragments",
|
||||
recipe = {
|
||||
"farming:mixing_bowl"
|
||||
}
|
||||
recipe = {{"farming:mixing_bowl"}}
|
||||
})
|
||||
|
|
|
@ -6,7 +6,6 @@ ignore = {
|
|||
|
||||
read_globals = {
|
||||
"minetest",
|
||||
"default",
|
||||
"armor",
|
||||
"skins",
|
||||
"awards",
|
||||
|
@ -19,4 +18,6 @@ read_globals = {
|
|||
globals = {
|
||||
"i3",
|
||||
"core",
|
||||
"sfinv",
|
||||
"unified_inventory",
|
||||
}
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
i3 = {}
|
||||
|
||||
local storage = core.get_mod_storage()
|
||||
local slz, dslz = core.serialize, core.deserialize
|
||||
local pdata = dslz(storage:get_string "pdata") or {}
|
||||
|
||||
-- Caches
|
||||
local pdata = {}
|
||||
local init_items = {}
|
||||
local searches = {}
|
||||
local recipes_cache = {}
|
||||
|
@ -16,7 +19,8 @@ local progressive_mode = core.settings:get_bool "i3_progressive_mode" and not(co
|
|||
local damage_enabled = core.settings:get_bool "enable_damage"
|
||||
|
||||
local __3darmor, __skinsdb, __awards
|
||||
local sfinv, unified_inventory, old_unified_inventory_fn
|
||||
local __sfinv, old_sfinv_fn
|
||||
local __unified_inventory, old_unified_inventory_fn
|
||||
|
||||
local http = core.request_http_api()
|
||||
local singleplayer = core.is_singleplayer()
|
||||
|
@ -37,6 +41,7 @@ local write_json = core.write_json
|
|||
local get_inv = core.get_inventory
|
||||
local chat_send = core.chat_send_player
|
||||
local show_formspec = core.show_formspec
|
||||
local pos_to_string = core.pos_to_string
|
||||
local check_privs = core.check_player_privs
|
||||
local globalstep = core.register_globalstep
|
||||
local on_shutdown = core.register_on_shutdown
|
||||
|
@ -45,9 +50,8 @@ local get_craft_result = core.get_craft_result
|
|||
local translate = minetest.get_translated_string
|
||||
local on_joinplayer = core.register_on_joinplayer
|
||||
local get_all_recipes = core.get_all_craft_recipes
|
||||
local slz, dslz = core.serialize, core.deserialize
|
||||
local on_mods_loaded = core.register_on_mods_loaded
|
||||
local on_leaveplayer = core.register_on_leaveplayer
|
||||
local on_mods_loaded = core.register_on_mods_loaded
|
||||
local get_player_info = core.get_player_information
|
||||
local create_inventory = core.create_detached_inventory
|
||||
local on_receive_fields = core.register_on_player_receive_fields
|
||||
|
@ -73,7 +77,8 @@ local min, max, floor, ceil, random =
|
|||
local pairs, ipairs, next, type, setmetatable, tonum, unpack, select =
|
||||
pairs, ipairs, next, type, setmetatable, tonumber, unpack, select
|
||||
|
||||
local vec_add, vec_mul = vector.add, vector.multiply
|
||||
local vec_new, vec_add, vec_mul, vec_eq, vec_round =
|
||||
vector.new, vector.add, vector.multiply, vector.equals, vector.round
|
||||
|
||||
local MAX_FAVS = 6
|
||||
local ITEM_BTN_SIZE = 1.1
|
||||
|
@ -81,14 +86,15 @@ local ITEM_BTN_SIZE = 1.1
|
|||
local INV_SIZE = 36
|
||||
local HOTBAR_COUNT = 9
|
||||
|
||||
-- Players data interval
|
||||
local SAVE_INTERVAL = 600
|
||||
|
||||
-- Progressive mode
|
||||
local POLL_FREQ = 0.25
|
||||
local HUD_TIMER_MAX = 1.5
|
||||
|
||||
local MIN_FORMSPEC_VERSION = 4
|
||||
|
||||
local META_SAVES = {"bag_size", "waypoints"}
|
||||
|
||||
local BAG_SIZES = {
|
||||
small = INV_SIZE + 3,
|
||||
medium = INV_SIZE + 6,
|
||||
|
@ -468,18 +474,6 @@ local function table_replace(t, val, new)
|
|||
end
|
||||
end
|
||||
|
||||
local function save_meta(player, entries)
|
||||
local name = player:get_player_name()
|
||||
local data = pdata[name]
|
||||
if not data then return end
|
||||
|
||||
local meta = player:get_meta()
|
||||
|
||||
for _, entry in ipairs(entries) do
|
||||
meta:set_string(entry, slz(data[entry]))
|
||||
end
|
||||
end
|
||||
|
||||
local craft_types = {}
|
||||
|
||||
function i3.register_craft_type(name, def)
|
||||
|
@ -1249,8 +1243,6 @@ local function select_item(player, name, data, _f)
|
|||
|
||||
if not item then
|
||||
return
|
||||
elseif sub(item, -4) == "_inv" then
|
||||
item = sub(item, 1, -5)
|
||||
elseif sub(item, 1, 1) == "_" then
|
||||
item = sub(item, 2)
|
||||
elseif sub(item, 1, 6) == "group|" then
|
||||
|
@ -1839,7 +1831,7 @@ local function get_items_fs(fs, data, extend)
|
|||
local Y = round((i % ipp - X) / rows + 1, 0)
|
||||
Y = Y - (Y * (extend and 0.085 or 0.035)) + 0.95
|
||||
|
||||
fs[#fs + 1] = fmt("item_image_button", X, Y, size, size, item, fmt("%s_inv", item), "")
|
||||
fs[#fs + 1] = fmt("item_image_button", X, Y, size, size, item, item, "")
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -1982,7 +1974,7 @@ local function get_award_list(data, fs, ctn_len, yextra, award_list, awards_unlo
|
|||
end
|
||||
end
|
||||
|
||||
local function get_waypoint_fs(fs, data, name, yextra, ctn_len)
|
||||
local function get_waypoint_fs(fs, data, player, yextra, ctn_len)
|
||||
fs(fmt("box[0,%f;4.9,0.6;#bababa25]", yextra + 1.1))
|
||||
fs("label", 0, yextra + 0.85, ES"Waypoint name:")
|
||||
fs(fmt("field[0.1,%f;4.8,0.6;waypoint_name;;]", yextra + 1.1))
|
||||
|
@ -2014,6 +2006,10 @@ local function get_waypoint_fs(fs, data, name, yextra, ctn_len)
|
|||
|
||||
fs("label", 0.15, y + 0.33, clr(fmt("#%s", hex), waypoint_name))
|
||||
|
||||
fs("tooltip", 0, y, ctn_len - 2.5, 0.65,
|
||||
fmt("Name: %s\nPosition:%s", clr("#ff0", v.name),
|
||||
pos_to_string(v.pos, 0):sub(2,-2):gsub("(%-*%d+)", clr("#ff0", " %1"))))
|
||||
|
||||
local del = fmt("waypoint_%u_delete", i)
|
||||
fs(fmt("style[%s;fgimg=%s;fgimg_hovered=%s;content_offset=0]", del, PNG.trash, PNG.trash_hover))
|
||||
fs("image_button", ctn_len - 0.5, yi, icon_size, icon_size, "", del, "")
|
||||
|
@ -2029,7 +2025,7 @@ local function get_waypoint_fs(fs, data, name, yextra, ctn_len)
|
|||
fs("image_button", ctn_len - 1.5, yi, icon_size, icon_size, "", vsb, "")
|
||||
fs(fmt("tooltip[%s;%s]", vsb, v.hide and ES"Show waypoint" or ES"Hide waypoint"))
|
||||
|
||||
if check_privs(name, {teleport = true}) then
|
||||
if check_privs(player, {teleport = true}) then
|
||||
local tp = fmt("waypoint_%u_teleport", i)
|
||||
|
||||
fs(fmt("style[%s;fgimg=%s;fgimg_hovered=%s;content_offset=0]",
|
||||
|
@ -2047,23 +2043,25 @@ local function get_ctn_content(fs, data, player, yoffset, ctn_len, award_list, a
|
|||
local name = player:get_player_name()
|
||||
add_subtitle(fs, "player_name", 0, ctn_len, 22, true, ESC(name))
|
||||
|
||||
local hp = damage_enabled and (data.hp or player:get_hp()) or 20
|
||||
local half = ceil((hp / 2) % 1)
|
||||
local hearts = (hp / 2) + half
|
||||
local heart_size = 0.35
|
||||
local heart_x, heart_h = 0.65, yoffset + 0.75
|
||||
|
||||
for i = 1, 10 do
|
||||
fs("image", heart_x + ((i - 1) * (heart_size + 0.1)), heart_h,
|
||||
heart_size, heart_size, PNG.heart_grey)
|
||||
end
|
||||
|
||||
if damage_enabled then
|
||||
local hp = data.hp or player:get_hp() or 20
|
||||
local half = ceil((hp / 2) % 1)
|
||||
local hearts = (hp / 2) + half
|
||||
local heart_size = 0.35
|
||||
local heart_x, heart_h = 0.65, yoffset + 0.75
|
||||
|
||||
for i = 1, 10 do
|
||||
fs("image", heart_x + ((i - 1) * (heart_size + 0.1)), heart_h,
|
||||
heart_size, heart_size, PNG.heart_grey)
|
||||
end
|
||||
|
||||
for i = 1, hearts do
|
||||
fs("image", heart_x + ((i - 1) * (heart_size + 0.1)), heart_h,
|
||||
heart_size, heart_size,
|
||||
(half == 1 and i == floor(hearts)) and PNG.heart_half or PNG.heart)
|
||||
end
|
||||
else
|
||||
yoffset = yoffset - 0.5
|
||||
end
|
||||
|
||||
fs(fmt("list[current_player;craft;%f,%f;3,3;]", 0, yoffset + 1.45))
|
||||
|
@ -2076,7 +2074,7 @@ local function get_ctn_content(fs, data, player, yoffset, ctn_len, award_list, a
|
|||
fs("image", 4.45, yoffset + 3.75, 1, 1, PNG.trash)
|
||||
end
|
||||
|
||||
local yextra = 5.5
|
||||
local yextra = damage_enabled and 5.5 or 5
|
||||
|
||||
for i, title in ipairs(SUBCAT) do
|
||||
local btn_name = fmt("btn_%s", title)
|
||||
|
@ -2143,7 +2141,7 @@ local function get_ctn_content(fs, data, player, yoffset, ctn_len, award_list, a
|
|||
end
|
||||
|
||||
elseif data.subcat == 5 then
|
||||
get_waypoint_fs(fs, data, name, yextra, ctn_len)
|
||||
get_waypoint_fs(fs, data, player, yextra, ctn_len)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -2254,6 +2252,7 @@ local function make_fs(player, data)
|
|||
end
|
||||
|
||||
function i3.set_fs(player, _fs)
|
||||
if not player or player.is_fake_player then return end
|
||||
local name = player:get_player_name()
|
||||
local data = pdata[name]
|
||||
if not data then return end
|
||||
|
@ -2347,27 +2346,19 @@ end
|
|||
|
||||
local function init_data(player, info)
|
||||
local name = player:get_player_name()
|
||||
|
||||
pdata[name] = {
|
||||
filter = "",
|
||||
pagenum = 1,
|
||||
items = init_items,
|
||||
items_raw = init_items,
|
||||
favs = {},
|
||||
export_counts = {},
|
||||
current_tab = 1,
|
||||
subcat = 1,
|
||||
scrbar_inv = 0,
|
||||
lang_code = get_lang_code(info),
|
||||
}
|
||||
|
||||
pdata[name] = pdata[name] or {}
|
||||
local data = pdata[name]
|
||||
local meta = player:get_meta()
|
||||
|
||||
for i = 1, #META_SAVES do
|
||||
local recover = META_SAVES[i]
|
||||
data[recover] = dslz(meta:get_string(recover))
|
||||
end
|
||||
data.filter = ""
|
||||
data.pagenum = 1
|
||||
data.items = init_items
|
||||
data.items_raw = init_items
|
||||
data.favs = {}
|
||||
data.export_counts = {}
|
||||
data.current_tab = 1
|
||||
data.subcat = 1
|
||||
data.scrbar_inv = 0
|
||||
data.lang_code = get_lang_code(info)
|
||||
|
||||
after(0, set_fs, player)
|
||||
end
|
||||
|
@ -2534,7 +2525,7 @@ local function get_inventory_fs(player, data, fs)
|
|||
|
||||
local award_list, award_list_nb
|
||||
local awards_unlocked = 0
|
||||
local max_val = 12
|
||||
local max_val = damage_enabled and 12 or 7
|
||||
|
||||
if __3darmor and data.subcat == 2 then
|
||||
if data.scrbar_inv >= max_val then
|
||||
|
@ -2571,7 +2562,7 @@ local function get_inventory_fs(player, data, fs)
|
|||
scrollbar[%f,0.2;0.2,%f;vertical;scrbar_inv;%u]
|
||||
scrollbaroptions[arrows=default;thumbsize=0;max=1000]
|
||||
]],
|
||||
(max_val * 4) / 15, max_val, 9.8, ctn_hgt, data.scrbar_inv))
|
||||
(max_val * 4) / 12, max_val, 9.8, ctn_hgt, data.scrbar_inv))
|
||||
|
||||
fs(fmt("scroll_container[3.9,0.2;%f,%f;scrbar_inv;vertical]", ctn_len, ctn_hgt))
|
||||
|
||||
|
@ -2629,10 +2620,13 @@ i3.new_tab {
|
|||
remove(data.waypoints, id)
|
||||
|
||||
elseif action == "teleport" then
|
||||
local pos = waypoint.pos
|
||||
local pos = vec_new(waypoint.pos)
|
||||
pos.y = pos.y + 0.5
|
||||
|
||||
local vel = player:get_velocity()
|
||||
player:add_velocity(vec_mul(vel, -1))
|
||||
player:set_pos(pos)
|
||||
|
||||
msg(name, fmt("Teleported to %s", clr("#ff0", waypoint.name)))
|
||||
|
||||
elseif action == "refresh" then
|
||||
|
@ -2679,6 +2673,14 @@ i3.new_tab {
|
|||
return
|
||||
|
||||
elseif fields.waypoint_add then
|
||||
local pos = player:get_pos()
|
||||
|
||||
for _, v in ipairs(data.waypoints) do
|
||||
if vec_eq(vec_round(pos), vec_round(v.pos)) then
|
||||
return msg(name, "You already set a waypoint at this position")
|
||||
end
|
||||
end
|
||||
|
||||
local waypoint = fields.waypoint_name
|
||||
|
||||
if fields.waypoint_name == "" then
|
||||
|
@ -2686,7 +2688,6 @@ i3.new_tab {
|
|||
end
|
||||
|
||||
local color = random(0xffffff)
|
||||
local pos = player:get_pos()
|
||||
|
||||
local id = player:hud_add {
|
||||
hud_elem_type = "waypoint",
|
||||
|
@ -2746,7 +2747,6 @@ end
|
|||
|
||||
if rawget(_G, "skins") then
|
||||
__skinsdb = true
|
||||
insert(META_SAVES, "skin_id")
|
||||
end
|
||||
|
||||
if rawget(_G, "awards") then
|
||||
|
@ -2772,24 +2772,22 @@ if rawget(_G, "awards") then
|
|||
core.register_on_dieplayer(set_fs)
|
||||
end
|
||||
|
||||
core.register_on_chatcommand(function(name, command, params)
|
||||
if sub(command, 1, 5) == "grant" then
|
||||
params = split(params, " ")
|
||||
|
||||
for _, v in ipairs(params) do
|
||||
if find(v, "creative") then
|
||||
local data = pdata[name]
|
||||
reset_data(data)
|
||||
data.favs = {}
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
core.register_on_chatcommand(function(name)
|
||||
local player = core.get_player_by_name(name)
|
||||
after(0, set_fs, player)
|
||||
end)
|
||||
|
||||
core.register_on_priv_grant(function(name, _, priv)
|
||||
if priv == "creative" or priv == "all" then
|
||||
local data = pdata[name]
|
||||
reset_data(data)
|
||||
data.favs = {}
|
||||
|
||||
local player = core.get_player_by_name(name)
|
||||
after(0, set_fs, player)
|
||||
end
|
||||
end)
|
||||
|
||||
i3.register_craft_type("digging", {
|
||||
description = ES"Digging",
|
||||
icon = "i3_steelpick.png",
|
||||
|
@ -2955,15 +2953,17 @@ end
|
|||
on_mods_loaded(function()
|
||||
get_init_items()
|
||||
|
||||
sfinv = rawget(_G, "sfinv")
|
||||
__sfinv = rawget(_G, "sfinv")
|
||||
|
||||
if sfinv then
|
||||
if __sfinv then
|
||||
old_sfinv_fn = sfinv.set_player_inventory_formspec
|
||||
function sfinv.set_player_inventory_formspec() return end
|
||||
sfinv.enabled = false
|
||||
end
|
||||
|
||||
unified_inventory = rawget(_G, "unified_inventory")
|
||||
__unified_inventory = rawget(_G, "unified_inventory")
|
||||
|
||||
if unified_inventory then
|
||||
if __unified_inventory then
|
||||
old_unified_inventory_fn = unified_inventory.set_inventory_formspec
|
||||
function unified_inventory.set_inventory_formspec() return end
|
||||
end
|
||||
|
@ -3045,14 +3045,15 @@ on_joinplayer(function(player)
|
|||
local info = get_player_info(name)
|
||||
|
||||
if get_formspec_version(info) < MIN_FORMSPEC_VERSION then
|
||||
if sfinv then
|
||||
if __sfinv then
|
||||
sfinv.set_player_inventory_formspec = old_sfinv_fn
|
||||
sfinv.enabled = true
|
||||
end
|
||||
|
||||
if unified_inventory then
|
||||
if __unified_inventory then
|
||||
unified_inventory.set_inventory_formspec = old_unified_inventory_fn
|
||||
|
||||
if sfinv then
|
||||
if __sfinv then
|
||||
sfinv.enabled = false
|
||||
end
|
||||
end
|
||||
|
@ -3084,22 +3085,46 @@ core.register_on_dieplayer(function(player)
|
|||
set_fs(player)
|
||||
end)
|
||||
|
||||
on_leaveplayer(function(player)
|
||||
save_meta(player, META_SAVES)
|
||||
local META_SAVES = {
|
||||
bag_size = true,
|
||||
waypoints = true,
|
||||
skin_id = true,
|
||||
inv_items = true,
|
||||
known_recipes = true,
|
||||
}
|
||||
|
||||
local name = player:get_player_name()
|
||||
pdata[name] = nil
|
||||
end)
|
||||
local function save_data(player_name)
|
||||
local _pdata = copy(pdata)
|
||||
|
||||
on_shutdown(function()
|
||||
local players = get_players()
|
||||
for name, v in pairs(_pdata) do
|
||||
for dat in pairs(v) do
|
||||
if not META_SAVES[dat] then
|
||||
_pdata[name][dat] = nil
|
||||
|
||||
for i = 1, #players do
|
||||
local player = players[i]
|
||||
save_meta(player, META_SAVES)
|
||||
if player_name then
|
||||
pdata[player_name][dat] = nil -- To free up some memory
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
storage:set_string("pdata", slz(_pdata))
|
||||
end
|
||||
|
||||
on_leaveplayer(function(player)
|
||||
local name = player:get_player_name()
|
||||
save_data(name)
|
||||
end)
|
||||
|
||||
on_shutdown(save_data)
|
||||
|
||||
local function routine()
|
||||
save_data()
|
||||
after(SAVE_INTERVAL, routine)
|
||||
end
|
||||
|
||||
after(SAVE_INTERVAL, routine)
|
||||
|
||||
on_receive_fields(function(player, formname, fields)
|
||||
if formname ~= "" then
|
||||
return false
|
||||
|
@ -3348,11 +3373,10 @@ if progressive_mode then
|
|||
|
||||
on_joinplayer(function(player)
|
||||
local name = player:get_player_name()
|
||||
local meta = player:get_meta()
|
||||
local data = pdata[name]
|
||||
|
||||
data.inv_items = dslz(meta:get_string "inv_items") or {}
|
||||
data.known_recipes = dslz(meta:get_string "known_recipes") or 0
|
||||
data.inv_items = data.inv_items or {}
|
||||
data.known_recipes = data.known_recipes or 0
|
||||
|
||||
local items = get_filtered_items(player, data)
|
||||
data.items_raw = items
|
||||
|
@ -3362,8 +3386,6 @@ if progressive_mode then
|
|||
init_hud(player, data)
|
||||
end
|
||||
end)
|
||||
|
||||
table_merge(META_SAVES, {"inv_items", "known_recipes"})
|
||||
end
|
||||
|
||||
local bag_recipes = {
|
||||
|
|
|
@ -8,7 +8,7 @@ local use_cmi = minetest.global_exists("cmi")
|
|||
|
||||
mobs = {
|
||||
mod = "redo",
|
||||
version = "20210418",
|
||||
version = "20210613",
|
||||
intllib = S,
|
||||
invis = minetest.global_exists("invisibility") and invisibility or {}
|
||||
}
|
||||
|
@ -28,8 +28,7 @@ local rad = math.rad
|
|||
local atann = math.atan
|
||||
local atan = function(x)
|
||||
if not x or x ~= x then
|
||||
--error("atan bassed NaN")
|
||||
return 0
|
||||
return 0 -- NaN
|
||||
else
|
||||
return atann(x)
|
||||
end
|
||||
|
@ -66,9 +65,9 @@ local mob_nospawn_range = tonumber(settings:get("mob_nospawn_range") or 12)
|
|||
local active_limit = tonumber(settings:get("mob_active_limit") or 0)
|
||||
local mob_chance_multiplier = tonumber(settings:get("mob_chance_multiplier") or 1)
|
||||
local peaceful_player_enabled = settings:get_bool("enable_peaceful_player")
|
||||
local mob_smooth_rotate = settings:get_bool("mob_smooth_rotate") ~= false
|
||||
local active_mobs = 0
|
||||
|
||||
|
||||
-- Peaceful mode message so players will know there are no monsters
|
||||
if peaceful_only then
|
||||
minetest.register_on_joinplayer(function(player)
|
||||
|
@ -225,9 +224,6 @@ function mob_class:collision()
|
|||
for _,object in ipairs(minetest.get_objects_inside_radius(pos, width)) do
|
||||
|
||||
if object:is_player() then
|
||||
-- or (object:get_luaentity()
|
||||
-- and object:get_luaentity()._cmi_is_mob == true
|
||||
-- and object ~= self.object) then
|
||||
|
||||
local pos2 = object:get_pos()
|
||||
local vec = {x = pos.x - pos2.x, z = pos.z - pos2.z}
|
||||
|
@ -339,10 +335,12 @@ function mob_class:set_yaw(yaw, delay)
|
|||
yaw = 0
|
||||
end
|
||||
|
||||
delay = delay or 0
|
||||
delay = mob_smooth_rotate and (delay or 0) or 0
|
||||
|
||||
if delay == 0 then
|
||||
|
||||
self.object:set_yaw(yaw)
|
||||
|
||||
return yaw
|
||||
end
|
||||
|
||||
|
@ -404,7 +402,6 @@ function mob_class:set_animation(anim, force)
|
|||
0, self.animation[anim .. "_loop"] ~= false)
|
||||
end
|
||||
|
||||
-- above function exported for mount.lua
|
||||
function mobs:set_animation(entity, anim)
|
||||
entity.set_animation(entity, anim)
|
||||
end
|
||||
|
@ -591,7 +588,7 @@ function mob_class:attempt_flight_correction(override)
|
|||
local escape_direction = vdirection(pos, escape_target)
|
||||
|
||||
self.object:set_velocity(
|
||||
vmultiply(escape_direction, 1)) --self.run_velocity))
|
||||
vmultiply(escape_direction, 1))
|
||||
|
||||
return true
|
||||
end
|
||||
|
@ -643,7 +640,7 @@ function mobs:yaw_to_pos(self, target, rot)
|
|||
end
|
||||
|
||||
|
||||
-- if stay near set then check periodically for nodes and turn towards them
|
||||
-- if stay near set then periodically check for nodes and turn towards them
|
||||
function mob_class:do_stay_near()
|
||||
|
||||
if not self.stay_near then return false end
|
||||
|
@ -740,9 +737,15 @@ function mob_class:update_tag()
|
|||
col = "#FF0000"
|
||||
end
|
||||
|
||||
-- build infotext
|
||||
self.infotext = "Health: " .. self.health .. " / " .. self.hp_max
|
||||
.. "\n" .. "Owner: " .. self.owner
|
||||
|
||||
-- set changes
|
||||
self.object:set_properties({
|
||||
nametag = self.nametag,
|
||||
nametag_color = col
|
||||
nametag_color = col,
|
||||
infotext = self.infotext
|
||||
})
|
||||
end
|
||||
|
||||
|
@ -790,10 +793,7 @@ function mob_class:item_drop()
|
|||
end
|
||||
|
||||
-- only drop rare items (drops.min = 0) if killed by player
|
||||
if death_by_player then
|
||||
obj = minetest.add_item(pos, ItemStack(item .. " " .. num))
|
||||
|
||||
elseif self.drops[n].min ~= 0 then
|
||||
if death_by_player or self.drops[n].min ~= 0 then
|
||||
obj = minetest.add_item(pos, ItemStack(item .. " " .. num))
|
||||
end
|
||||
|
||||
|
@ -868,18 +868,17 @@ function mob_class:check_for_death(cmi_cause)
|
|||
end
|
||||
|
||||
-- backup nametag so we can show health stats
|
||||
if not self.nametag2 then
|
||||
self.nametag2 = self.nametag or ""
|
||||
end
|
||||
-- if not self.nametag2 then
|
||||
-- self.nametag2 = self.nametag or ""
|
||||
-- end
|
||||
|
||||
if show_health
|
||||
and (cmi_cause and cmi_cause.type == "punch") then
|
||||
|
||||
self.htimer = 2
|
||||
self.nametag = "♥ " .. self.health .. " / " .. self.hp_max
|
||||
-- if show_health
|
||||
-- and (cmi_cause and cmi_cause.type == "punch") then
|
||||
|
||||
-- self.htimer = 2
|
||||
-- self.nametag = "♥ " .. self.health .. " / " .. self.hp_max
|
||||
self:update_tag()
|
||||
end
|
||||
-- end
|
||||
|
||||
return false
|
||||
end
|
||||
|
@ -1049,13 +1048,13 @@ function mob_class:do_env_damage()
|
|||
end
|
||||
|
||||
-- reset nametag after showing health stats
|
||||
if self.htimer < 1 and self.nametag2 then
|
||||
-- if self.htimer < 1 and self.nametag2 then
|
||||
|
||||
self.nametag = self.nametag2
|
||||
self.nametag2 = nil
|
||||
-- self.nametag = self.nametag2
|
||||
-- self.nametag2 = nil
|
||||
|
||||
self:update_tag()
|
||||
end
|
||||
-- end
|
||||
|
||||
local pos = self.object:get_pos() ; if not pos then return end
|
||||
|
||||
|
@ -1079,8 +1078,7 @@ function mob_class:do_env_damage()
|
|||
local nodef = minetest.registered_nodes[self.standing_in]
|
||||
|
||||
-- water
|
||||
if self.water_damage ~= 0
|
||||
and nodef.groups.water then
|
||||
if self.water_damage ~= 0 and nodef.groups.water then
|
||||
|
||||
self.health = self.health - self.water_damage
|
||||
|
||||
|
@ -1092,8 +1090,7 @@ function mob_class:do_env_damage()
|
|||
end
|
||||
|
||||
-- lava damage
|
||||
elseif self.lava_damage ~= 0
|
||||
and nodef.groups.lava then
|
||||
elseif self.lava_damage ~= 0 and nodef.groups.lava then
|
||||
|
||||
self.health = self.health - self.lava_damage
|
||||
|
||||
|
@ -1105,8 +1102,7 @@ function mob_class:do_env_damage()
|
|||
end
|
||||
|
||||
-- fire damage
|
||||
elseif self.fire_damage ~= 0
|
||||
and nodef.groups.fire then
|
||||
elseif self.fire_damage ~= 0 and nodef.groups.fire then
|
||||
|
||||
self.health = self.health - self.fire_damage
|
||||
|
||||
|
@ -1243,54 +1239,51 @@ function mob_class:do_jump()
|
|||
--print("in front:", nod.name, pos.y + 0.5)
|
||||
--print("in front above:", nodt.name, pos.y + 1.5)
|
||||
|
||||
-- jump if standing on solid node (not snow) and not blocked above
|
||||
if (self.walk_chance == 0
|
||||
or minetest.registered_items[nod.name].walkable)
|
||||
and not blocked
|
||||
and nod.name ~= node_snow then
|
||||
|
||||
if not nod.name:find("fence")
|
||||
and not nod.name:find("gate")
|
||||
and not nod.name:find("wall") then
|
||||
|
||||
local v = self.object:get_velocity()
|
||||
|
||||
v.y = self.jump_height
|
||||
|
||||
self:set_animation("jump") -- only when defined
|
||||
|
||||
self.object:set_velocity(v)
|
||||
|
||||
-- when in air move forward
|
||||
minetest.after(0.3, function(self, v)
|
||||
|
||||
if self.object:get_luaentity() then
|
||||
|
||||
self.object:set_acceleration({
|
||||
x = v.x * 2,
|
||||
y = 0,
|
||||
z = v.z * 2
|
||||
})
|
||||
end
|
||||
end, self, v)
|
||||
|
||||
if self:get_velocity() > 0 then
|
||||
self:mob_sound(self.sounds.jump)
|
||||
end
|
||||
|
||||
return true
|
||||
else
|
||||
self.facing_fence = true
|
||||
end
|
||||
-- are we facing a fence or wall
|
||||
if nod.name:find("fence") or nod.name:find("gate") or nod.name:find("wall") then
|
||||
self.facing_fence = true
|
||||
end
|
||||
|
||||
-- if blocked against a block/wall for 5 counts then turn
|
||||
if not self.following
|
||||
and (self.facing_fence or blocked) then
|
||||
-- jump if standing on solid node (not snow) and not blocked above
|
||||
if (self.walk_chance == 0 or minetest.registered_items[nod.name].walkable)
|
||||
and not blocked and nod.name ~= node_snow then
|
||||
|
||||
local v = self.object:get_velocity()
|
||||
|
||||
v.y = self.jump_height
|
||||
|
||||
self:set_animation("jump") -- only when defined
|
||||
|
||||
self.object:set_velocity(v)
|
||||
|
||||
-- when in air move forward
|
||||
minetest.after(0.3, function(self, v)
|
||||
|
||||
if self.object:get_luaentity() then
|
||||
|
||||
self.object:set_acceleration({
|
||||
x = v.x * 2,
|
||||
y = 0,
|
||||
z = v.z * 2
|
||||
})
|
||||
end
|
||||
end, self, v)
|
||||
|
||||
if self:get_velocity() > 0 then
|
||||
self:mob_sound(self.sounds.jump)
|
||||
end
|
||||
|
||||
self.jump_count = 0
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
-- if blocked for 3 counts then turn
|
||||
if not self.following and (self.facing_fence or blocked) then
|
||||
|
||||
self.jump_count = (self.jump_count or 0) + 1
|
||||
|
||||
if self.jump_count > 4 then
|
||||
if self.jump_count > 2 then
|
||||
|
||||
local yaw = self.object:get_yaw() or 0
|
||||
local turn = random(0, 2) + 1.35
|
||||
|
@ -1361,7 +1354,7 @@ end
|
|||
|
||||
-- Thanks Wuzzy for the following editable settings
|
||||
local HORNY_TIME = 30
|
||||
local HORNY_AGAIN_TIME = 300
|
||||
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
|
||||
|
@ -1389,16 +1382,15 @@ function mob_class:breed()
|
|||
if self.on_grown then
|
||||
self.on_grown(self)
|
||||
else
|
||||
-- jump when fully grown so as not to fall into ground
|
||||
-- self.object:set_velocity({
|
||||
-- x = 0,
|
||||
-- y = self.jump_height,
|
||||
-- z = 0
|
||||
-- })
|
||||
local pos = self.object:get_pos() ; if not pos then return end
|
||||
local ent = self.object:get_luaentity()
|
||||
|
||||
pos.y = pos.y + (ent.collisionbox[2] * -1) - 0.4
|
||||
|
||||
self.object:set_pos(pos)
|
||||
|
||||
-- jump slightly when fully grown so as not to fall into ground
|
||||
self.object:set_velocity({x = 0, y = 0.5, z = 0 })
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -1621,6 +1613,40 @@ end
|
|||
|
||||
local los_switcher = false
|
||||
local height_switcher = false
|
||||
local can_dig_drop = function(pos)
|
||||
|
||||
if minetest.is_protected(pos, "") then
|
||||
return false
|
||||
end
|
||||
|
||||
local node = node_ok(pos, "air").name
|
||||
local ndef = minetest.registered_nodes[node]
|
||||
|
||||
if node ~= "ignore"
|
||||
and ndef
|
||||
and ndef.drawtype ~= "airlike"
|
||||
and not ndef.groups.level
|
||||
and not ndef.groups.unbreakable
|
||||
and not ndef.groups.liquid then
|
||||
|
||||
local drops = minetest.get_node_drops(node)
|
||||
|
||||
for _, item in ipairs(drops) do
|
||||
|
||||
minetest.add_item({
|
||||
x = pos.x - 0.5 + random(),
|
||||
y = pos.y - 0.5 + random(),
|
||||
z = pos.z - 0.5 + random()
|
||||
}, item)
|
||||
end
|
||||
|
||||
minetest.remove_node(pos)
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
-- path finding and smart mob routine by rnd,
|
||||
-- line_of_sight and other edits by Elkien3
|
||||
|
@ -1786,8 +1812,8 @@ function mob_class:smart_mobs(s, p, dist, dtime)
|
|||
-- lets make way by digging/building if not accessible
|
||||
if self.pathfinding == 2 and mobs_griefing then
|
||||
|
||||
-- is player higher than mob?
|
||||
if s.y < p1.y then
|
||||
-- is player more than 1 block higher than mob?
|
||||
if p1.y > (s.y + 1) then
|
||||
|
||||
-- build upwards
|
||||
if not minetest.is_protected(s, "") then
|
||||
|
@ -1795,8 +1821,7 @@ function mob_class:smart_mobs(s, p, dist, dtime)
|
|||
local ndef1 = minetest.registered_nodes[self.standing_in]
|
||||
|
||||
if ndef1 and (ndef1.buildable_to or ndef1.groups.liquid) then
|
||||
|
||||
minetest.set_node(s, {name = mobs.fallback_node})
|
||||
minetest.set_node(s, {name = mobs.fallback_node})
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -1806,27 +1831,19 @@ function mob_class:smart_mobs(s, p, dist, dtime)
|
|||
s.y = s.y + sheight
|
||||
|
||||
-- remove one block above to make room to jump
|
||||
if not minetest.is_protected(s, "") then
|
||||
|
||||
local node1 = node_ok(s, "air").name
|
||||
local ndef1 = minetest.registered_nodes[node1]
|
||||
|
||||
if node1 ~= "air"
|
||||
and node1 ~= "ignore"
|
||||
and ndef1
|
||||
and not ndef1.groups.level
|
||||
and not ndef1.groups.unbreakable
|
||||
and not ndef1.groups.liquid then
|
||||
|
||||
minetest.set_node(s, {name = "air"})
|
||||
minetest.add_item(s, ItemStack(node1))
|
||||
|
||||
end
|
||||
end
|
||||
can_dig_drop(s)
|
||||
|
||||
s.y = s.y - sheight
|
||||
self.object:set_pos({x = s.x, y = s.y + 2, z = s.z})
|
||||
|
||||
-- is player more than 1 block lower than mob
|
||||
elseif p1.y < (s.y - 1) then
|
||||
|
||||
-- dig down
|
||||
s.y = s.y - self.collisionbox[4] - 0.2
|
||||
|
||||
can_dig_drop(s)
|
||||
|
||||
else -- dig 2 blocks to make door toward player direction
|
||||
|
||||
local yaw1 = self.object:get_yaw() + pi / 2
|
||||
|
@ -1836,37 +1853,12 @@ function mob_class:smart_mobs(s, p, dist, dtime)
|
|||
z = s.z + sin(yaw1)
|
||||
}
|
||||
|
||||
if not minetest.is_protected(p1, "") then
|
||||
-- dig bottom node first incase of door
|
||||
can_dig_drop(p1)
|
||||
|
||||
local node1 = node_ok(p1, "air").name
|
||||
local ndef1 = minetest.registered_nodes[node1]
|
||||
p1.y = p1.y + 1
|
||||
|
||||
if node1 ~= "air"
|
||||
and node1 ~= "ignore"
|
||||
and ndef1
|
||||
and not ndef1.groups.level
|
||||
and not ndef1.groups.unbreakable
|
||||
and not ndef1.groups.liquid then
|
||||
|
||||
minetest.add_item(p1, ItemStack(node1))
|
||||
minetest.set_node(p1, {name = "air"})
|
||||
end
|
||||
|
||||
p1.y = p1.y + 1
|
||||
node1 = node_ok(p1, "air").name
|
||||
ndef1 = minetest.registered_nodes[node1]
|
||||
|
||||
if node1 ~= "air"
|
||||
and node1 ~= "ignore"
|
||||
and ndef1
|
||||
and not ndef1.groups.level
|
||||
and not ndef1.groups.unbreakable
|
||||
and not ndef1.groups.liquid then
|
||||
|
||||
minetest.add_item(p1, ItemStack(node1))
|
||||
minetest.set_node(p1, {name = "air"})
|
||||
end
|
||||
end
|
||||
can_dig_drop(p1)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -2598,7 +2590,10 @@ function mob_class:do_states(dtime)
|
|||
self:smart_mobs(s, p, dist, dtime)
|
||||
end
|
||||
|
||||
if self.at_cliff then
|
||||
-- distance padding to stop spinning mob
|
||||
local pad = abs(p.x - s.x) + abs(p.z - s.z)
|
||||
|
||||
if self.at_cliff or pad < 0.2 then
|
||||
|
||||
self:set_velocity(0)
|
||||
self:set_animation("stand")
|
||||
|
@ -2616,7 +2611,6 @@ function mob_class:do_states(dtime)
|
|||
self:set_animation("walk")
|
||||
end
|
||||
end
|
||||
|
||||
else -- rnd: if inside reach range
|
||||
|
||||
self.path.stuck = false
|
||||
|
@ -2652,9 +2646,11 @@ function mob_class:do_states(dtime)
|
|||
self.attack = attached
|
||||
end
|
||||
|
||||
local dgroup = self.damage_group or "fleshy"
|
||||
|
||||
self.attack:punch(self.object, 1.0, {
|
||||
full_punch_interval = 1.0,
|
||||
damage_groups = {fleshy = self.damage}
|
||||
damage_groups = {[dgroup] = self.damage}
|
||||
}, nil)
|
||||
end
|
||||
end
|
||||
|
@ -2761,11 +2757,7 @@ function mob_class:falling(pos)
|
|||
end
|
||||
|
||||
-- fall at set speed
|
||||
self.object:set_acceleration({
|
||||
x = 0,
|
||||
y = fall_speed,
|
||||
z = 0
|
||||
})
|
||||
self.object:set_acceleration({x = 0, y = fall_speed, z = 0})
|
||||
end
|
||||
|
||||
|
||||
|
@ -2788,8 +2780,9 @@ function mob_class:on_punch(hitter, tflp, tool_capabilities, dir, damage)
|
|||
|
||||
-- error checking when mod profiling is enabled
|
||||
if not tool_capabilities then
|
||||
minetest.log("warning",
|
||||
"[mobs] Mod profiling enabled, damage not enabled")
|
||||
|
||||
minetest.log("warning", "[mobs] Mod profiling enabled, damage not enabled")
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
|
@ -2865,6 +2858,7 @@ function mob_class:on_punch(hitter, tflp, tool_capabilities, dir, damage)
|
|||
if self.immune_to[n][1] == weapon_def.name then
|
||||
|
||||
damage = self.immune_to[n][2] or 0
|
||||
|
||||
break
|
||||
|
||||
-- if "all" then no tools deal damage unless it's specified in list
|
||||
|
@ -2877,13 +2871,14 @@ function mob_class:on_punch(hitter, tflp, tool_capabilities, dir, damage)
|
|||
|
||||
-- healing
|
||||
if damage <= -1 then
|
||||
|
||||
self.health = self.health - floor(damage)
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
if use_cmi
|
||||
and cmi.notify_punch(
|
||||
self.object, hitter, tflp, tool_capabilities, dir, damage) then
|
||||
and cmi.notify_punch(self.object, hitter, tflp, tool_capabilities, dir, damage) then
|
||||
return true
|
||||
end
|
||||
|
||||
|
@ -2902,10 +2897,8 @@ function mob_class:on_punch(hitter, tflp, tool_capabilities, dir, damage)
|
|||
end
|
||||
end
|
||||
|
||||
if tr then
|
||||
if weapon_def.original_description then
|
||||
toolranks.new_afteruse(weapon, hitter, nil, {wear = wear})
|
||||
end
|
||||
if tr and weapon_def.original_description then
|
||||
toolranks.new_afteruse(weapon, hitter, nil, {wear = wear})
|
||||
else
|
||||
weapon:add_wear(wear)
|
||||
end
|
||||
|
@ -2915,21 +2908,11 @@ function mob_class:on_punch(hitter, tflp, tool_capabilities, dir, damage)
|
|||
-- only play hit sound and show blood effects if damage is 1 or over
|
||||
if damage >= 1 then
|
||||
|
||||
-- weapon sounds
|
||||
if weapon_def.sounds then
|
||||
-- select tool use sound if found, or fallback to default
|
||||
local snd = weapon_def.sound and weapon_def.sound.use
|
||||
or "default_punch"
|
||||
|
||||
local s = random(0, #weapon_def.sounds)
|
||||
|
||||
minetest.sound_play(weapon_def.sounds[s], {
|
||||
object = self.object,
|
||||
max_hear_distance = 8
|
||||
}, true)
|
||||
else
|
||||
minetest.sound_play("default_punch", {
|
||||
object = self.object,
|
||||
max_hear_distance = 5
|
||||
}, true)
|
||||
end
|
||||
minetest.sound_play(snd, {object = self.object, max_hear_distance = 8}, true)
|
||||
|
||||
-- blood_particles
|
||||
if not disable_blood and self.blood_amount > 0 then
|
||||
|
@ -2938,8 +2921,7 @@ function mob_class:on_punch(hitter, tflp, tool_capabilities, dir, damage)
|
|||
local blood = self.blood_texture
|
||||
local amount = self.blood_amount
|
||||
|
||||
pos.y = pos.y + (-self.collisionbox[2]
|
||||
+ self.collisionbox[5]) * .5
|
||||
pos.y = pos.y + (-self.collisionbox[2] + self.collisionbox[5]) * .5
|
||||
|
||||
-- lots of damage = more blood :)
|
||||
if damage > 10 then
|
||||
|
@ -2952,7 +2934,6 @@ function mob_class:on_punch(hitter, tflp, tool_capabilities, dir, damage)
|
|||
end
|
||||
|
||||
effect(pos, amount, blood, 1, 2, 1.75, nil, nil, true)
|
||||
|
||||
end
|
||||
|
||||
-- do damage
|
||||
|
@ -2962,29 +2943,13 @@ function mob_class:on_punch(hitter, tflp, tool_capabilities, dir, damage)
|
|||
local hot = tool_capabilities and tool_capabilities.damage_groups
|
||||
and tool_capabilities.damage_groups.fire
|
||||
|
||||
if self:check_for_death({type = "punch",
|
||||
puncher = hitter, hot = hot}) then
|
||||
if self:check_for_death({type = "punch", puncher = hitter, hot = hot}) then
|
||||
return true
|
||||
end
|
||||
|
||||
--[[ add healthy afterglow when hit (causes lag with large textures)
|
||||
minetest.after(0.1, function()
|
||||
|
||||
if not self.object:get_luaentity() then return end
|
||||
|
||||
self.object:set_texture_mod("^[colorize:#c9900070")
|
||||
|
||||
minetest.after(0.3, function()
|
||||
if not self.object:get_luaentity() then return end
|
||||
self.object:set_texture_mod(self.texture_mods)
|
||||
end)
|
||||
end) ]]
|
||||
|
||||
end -- END if damage
|
||||
|
||||
-- knock back effect (only on full punch)
|
||||
if self.knock_back
|
||||
and tflp >= punch_interval then
|
||||
if self.knock_back and tflp >= punch_interval then
|
||||
|
||||
local v = self.object:get_velocity()
|
||||
|
||||
|
@ -3006,11 +2971,7 @@ function mob_class:on_punch(hitter, tflp, tool_capabilities, dir, damage)
|
|||
-- use tool knockback value or default
|
||||
kb = tool_capabilities.damage_groups["knockback"] or kb
|
||||
|
||||
self.object:set_velocity({
|
||||
x = dir.x * kb,
|
||||
y = up,
|
||||
z = dir.z * kb
|
||||
})
|
||||
self.object:set_velocity({x = dir.x * kb, y = up, z = dir.z * kb})
|
||||
|
||||
self.pause_timer = 0.25
|
||||
end
|
||||
|
@ -3257,10 +3218,8 @@ function mob_class:mob_activate(staticdata, def, dtime)
|
|||
local armor
|
||||
if type(self.armor) == "table" then
|
||||
armor = table_copy(self.armor)
|
||||
-- armor.immortal = 1
|
||||
else
|
||||
-- armor = {immortal = 1, fleshy = self.armor}
|
||||
armor = {fleshy = self.armor}
|
||||
armor = {fleshy = self.armor} -- immortal = 1
|
||||
end
|
||||
self.object:set_armor_groups(armor)
|
||||
|
||||
|
@ -3358,23 +3317,7 @@ end
|
|||
-- main mob function
|
||||
function mob_class:on_step(dtime, moveresult)
|
||||
|
||||
--[[ moveresult contains this for physical mobs
|
||||
{
|
||||
touching_ground = boolean,
|
||||
collides = boolean,
|
||||
standing_on_object = boolean,
|
||||
collisions = {
|
||||
{
|
||||
type = string, -- "node" or "object",
|
||||
axis = string, -- "x", "y" or "z"
|
||||
node_pos = vector, -- if type is "node"
|
||||
object = ObjectRef, -- if type is "object"
|
||||
old_velocity = vector,
|
||||
new_velocity = vector,
|
||||
}}
|
||||
}]]
|
||||
|
||||
if self.state == "die" then return end ----------------
|
||||
if self.state == "die" then return end
|
||||
|
||||
if use_cmi then
|
||||
cmi.notify_step(self.object, dtime)
|
||||
|
@ -3563,6 +3506,13 @@ function mobs:register_mob(name, def)
|
|||
|
||||
mobs.spawning_mobs[name] = {}
|
||||
|
||||
local collisionbox = def.collisionbox or {-0.25, -0.25, -0.25, 0.25, 0.25, 0.25}
|
||||
|
||||
-- quick fix to stop mobs glitching through nodes if too small
|
||||
if -collisionbox[2] + collisionbox[5] < 1.01 then
|
||||
collisionbox[5] = collisionbox[2] + 0.99
|
||||
end
|
||||
|
||||
minetest.register_entity(name, setmetatable({
|
||||
|
||||
stepheight = def.stepheight,
|
||||
|
@ -3584,8 +3534,8 @@ minetest.register_entity(name, setmetatable({
|
|||
lifetimer = def.lifetimer,
|
||||
hp_min = max(1, (def.hp_min or 5) * difficulty),
|
||||
hp_max = max(1, (def.hp_max or 10) * difficulty),
|
||||
collisionbox = def.collisionbox,
|
||||
selectionbox = def.selectionbox or def.collisionbox,
|
||||
collisionbox = collisionbox, --def.collisionbox,
|
||||
selectionbox = def.selectionbox or collisionbox, --def.collisionbox,
|
||||
visual = def.visual,
|
||||
visual_size = def.visual_size,
|
||||
mesh = def.mesh,
|
||||
|
@ -3594,6 +3544,8 @@ minetest.register_entity(name, setmetatable({
|
|||
walk_velocity = def.walk_velocity,
|
||||
run_velocity = def.run_velocity,
|
||||
damage = max(0, (def.damage or 0) * difficulty),
|
||||
damage_group = def.damage_group,
|
||||
damage_texture_modifier = def.damage_texture_modifier,
|
||||
light_damage = def.light_damage,
|
||||
light_damage_min = def.light_damage_min,
|
||||
light_damage_max = def.light_damage_max,
|
||||
|
@ -3891,11 +3843,13 @@ function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light, inter
|
|||
local numbers = settings:get(name)
|
||||
|
||||
if numbers then
|
||||
|
||||
numbers = numbers:split(",")
|
||||
chance = tonumber(numbers[1]) or chance
|
||||
aoc = tonumber(numbers[2]) or aoc
|
||||
|
||||
if chance == 0 then
|
||||
|
||||
minetest.log("warning",
|
||||
string.format("[mobs] %s has spawning disabled", name))
|
||||
return
|
||||
|
@ -4127,7 +4081,10 @@ function mobs:register_arrow(name, def)
|
|||
|
||||
minetest.register_entity(name, {
|
||||
|
||||
physical = false,
|
||||
physical = def.physical or false,
|
||||
collide_with_objects = def.collide_with_objects or false,
|
||||
static_save = false,
|
||||
|
||||
visual = def.visual,
|
||||
visual_size = def.visual_size,
|
||||
textures = def.textures,
|
||||
|
@ -4286,7 +4243,7 @@ function mobs:boom(self, pos, radius)
|
|||
radius = radius,
|
||||
damage_radius = radius,
|
||||
sound = self.sounds and self.sounds.explode,
|
||||
explode_center = true,
|
||||
explode_center = true
|
||||
})
|
||||
else
|
||||
mobs:safe_boom(self, pos, radius)
|
||||
|
@ -4676,14 +4633,14 @@ function mobs:feed_tame(self, clicker, feed_count, breed, tame)
|
|||
|
||||
self.health = self.hp_max
|
||||
|
||||
if self.htimer < 1 then
|
||||
-- if self.htimer < 1 then
|
||||
|
||||
minetest.chat_send_player(clicker:get_player_name(),
|
||||
S("@1 at full health (@2)",
|
||||
self.name:split(":")[2], tostring(self.health)))
|
||||
-- minetest.chat_send_player(clicker:get_player_name(),
|
||||
-- S("@1 at full health (@2)",
|
||||
-- self.name:split(":")[2], tostring(self.health)))
|
||||
|
||||
self.htimer = 5
|
||||
end
|
||||
-- self.htimer = 5
|
||||
-- end
|
||||
end
|
||||
|
||||
self.object:set_hp(self.health)
|
||||
|
@ -4825,14 +4782,13 @@ function mobs:alias_mob(old_name, new_name)
|
|||
-- entity
|
||||
minetest.register_entity(":" .. old_name, {
|
||||
|
||||
physical = false,
|
||||
physical = false, static_save = false,
|
||||
|
||||
on_activate = function(self, staticdata)
|
||||
|
||||
if minetest.registered_entities[new_name] then
|
||||
|
||||
minetest.add_entity(self.object:get_pos(),
|
||||
new_name, staticdata)
|
||||
minetest.add_entity(self.object:get_pos(), new_name, staticdata)
|
||||
end
|
||||
|
||||
remove_mob(self)
|
||||
|
|
|
@ -56,6 +56,8 @@ functions needed for the mob to work properly which contains the following:
|
|||
'view_range' how many nodes in distance the mob can see a player.
|
||||
'damage' how many health points the mob does to a player or another
|
||||
mob when melee attacking.
|
||||
'damage_group' group in which damage is dealt, dedaults to "fleshy".
|
||||
'damage_texture_modifier' applies texture modifier on hit e.g "^[brighten"
|
||||
'knock_back' when true has mobs falling backwards when hit, the greater
|
||||
the damage the more they move back.
|
||||
'fear_height' is how high a cliff or edge has to be before the mob stops
|
||||
|
@ -465,6 +467,8 @@ This function registers a arrow for mobs with the attack type shoot.
|
|||
'visual' same is in minetest.register_entity()
|
||||
'visual_size' same is in minetest.register_entity()
|
||||
'textures' same is in minetest.register_entity()
|
||||
'physical' same is in minetest.register_entity() [default: false]
|
||||
'collide_with_objects' same as above
|
||||
'velocity' the velocity of the arrow
|
||||
'drop' if set to true any arrows hitting a node will drop as item
|
||||
'hit_player' a function that is called when the arrow hits a player;
|
||||
|
@ -718,6 +722,7 @@ External Settings for "minetest.conf"
|
|||
'mob_area_spawn' When true will check surrounding area the size of the
|
||||
mob for obstructions before spawning, otherwise it
|
||||
defaults to checking the height of the mob only.
|
||||
'mob_smooth_rotate' Enables smooth rotation when mobs turn by default.
|
||||
|
||||
Players can override the spawn chance for each mob registered by adding a line
|
||||
to their minetest.conf file with a new value, the lower the value the more each
|
||||
|
|
|
@ -299,12 +299,18 @@ minetest.register_tool(":mobs:mob_reset_stick", {
|
|||
|
||||
tex_obj = obj
|
||||
|
||||
-- get base texture
|
||||
local bt = tex_obj:get_luaentity().base_texture[1]
|
||||
|
||||
if type(bt) ~= "string" then
|
||||
bt = ""
|
||||
end
|
||||
|
||||
local name = user:get_player_name()
|
||||
local tex = ""
|
||||
|
||||
minetest.show_formspec(name, "mobs_texture", "size[8,4]"
|
||||
.. "field[0.5,1;7.5,0;name;"
|
||||
.. minetest.formspec_escape(S("Enter texture:")) .. ";" .. tex .. "]"
|
||||
.. minetest.formspec_escape(S("Enter texture:")) .. ";" .. bt .. "]"
|
||||
.. "button_exit[2.5,3.5;3,1;mob_texture_change;"
|
||||
.. minetest.formspec_escape(S("Change")) .. "]")
|
||||
end
|
||||
|
|
|
@ -22,6 +22,7 @@ end
|
|||
|
||||
|
||||
local function node_is(pos)
|
||||
|
||||
local node = node_ok(pos)
|
||||
|
||||
if node.name == "air" then
|
||||
|
@ -69,6 +70,7 @@ end
|
|||
|
||||
|
||||
local function force_detach(player)
|
||||
|
||||
local attached_to = player:get_attach()
|
||||
|
||||
if not attached_to then
|
||||
|
@ -97,7 +99,9 @@ minetest.register_on_leaveplayer(function(player)
|
|||
end)
|
||||
|
||||
minetest.register_on_shutdown(function()
|
||||
|
||||
local players = minetest.get_connected_players()
|
||||
|
||||
for i = 1, #players do
|
||||
force_detach(players[i])
|
||||
end
|
||||
|
@ -112,6 +116,7 @@ end)
|
|||
|
||||
-- Just for correct detaching
|
||||
local function find_free_pos(pos)
|
||||
|
||||
local check = {
|
||||
{x = 1, y = 0, z = 0},
|
||||
{x = 1, y = 1, z = 0},
|
||||
|
@ -124,10 +129,14 @@ local function find_free_pos(pos)
|
|||
}
|
||||
|
||||
for _, c in pairs(check) do
|
||||
|
||||
local npos = {x = pos.x + c.x, y = pos.y + c.y, z = pos.z + c.z}
|
||||
local node = minetest.get_node_or_nil(npos)
|
||||
|
||||
if node and node.name then
|
||||
|
||||
local def = minetest.registered_nodes[node.name]
|
||||
|
||||
if def and not def.walkable and
|
||||
def.liquidtype == "none" then
|
||||
return npos
|
||||
|
@ -141,6 +150,7 @@ end
|
|||
-------------------------------------------------------------------------------
|
||||
|
||||
function mobs.attach(entity, player)
|
||||
|
||||
entity.player_rotation = entity.player_rotation or {x = 0, y = 0, z = 0}
|
||||
entity.driver_attach_at = entity.driver_attach_at or {x = 0, y = 0, z = 0}
|
||||
entity.driver_eye_offset = entity.driver_eye_offset or {x = 0, y = 0, z = 0}
|
||||
|
@ -154,6 +164,7 @@ function mobs.attach(entity, player)
|
|||
|
||||
local attach_at = entity.driver_attach_at
|
||||
local eye_offset = entity.driver_eye_offset
|
||||
|
||||
entity.driver = player
|
||||
|
||||
force_detach(player)
|
||||
|
@ -170,6 +181,7 @@ function mobs.attach(entity, player)
|
|||
})
|
||||
|
||||
minetest.after(0.2, function()
|
||||
|
||||
if player and player:is_player() then
|
||||
player_api.set_animation(player, "sit", 30)
|
||||
end
|
||||
|
@ -183,9 +195,13 @@ function mobs.detach(player)
|
|||
force_detach(player)
|
||||
|
||||
minetest.after(0.1, function()
|
||||
|
||||
if player and player:is_player() then
|
||||
|
||||
local pos = find_free_pos(player:get_pos())
|
||||
|
||||
pos.y = pos.y + 0.5
|
||||
|
||||
player:set_pos(pos)
|
||||
end
|
||||
end)
|
||||
|
@ -193,8 +209,8 @@ end
|
|||
|
||||
|
||||
function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
|
||||
local yaw = entity.object:get_yaw() or 0
|
||||
|
||||
local yaw = entity.object:get_yaw() or 0
|
||||
local rot_view = 0
|
||||
|
||||
if entity.player_rotation.y == 90 then
|
||||
|
@ -208,14 +224,17 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
|
|||
|
||||
-- process controls
|
||||
if entity.driver then
|
||||
|
||||
local ctrl = entity.driver:get_player_control()
|
||||
|
||||
-- move forwards
|
||||
if ctrl.up then
|
||||
|
||||
entity.v = entity.v + entity.accel / 10
|
||||
|
||||
-- move backwards
|
||||
elseif ctrl.down then
|
||||
|
||||
if entity.max_speed_reverse == 0 and entity.v == 0 then
|
||||
return
|
||||
end
|
||||
|
@ -225,7 +244,9 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
|
|||
|
||||
-- mob rotation
|
||||
local horz
|
||||
|
||||
if entity.alt_turn == true then
|
||||
|
||||
horz = yaw
|
||||
|
||||
if ctrl.left then
|
||||
|
@ -243,21 +264,29 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
|
|||
if can_fly then
|
||||
-- fly up
|
||||
if ctrl.jump then
|
||||
|
||||
velo.y = velo.y + 1
|
||||
|
||||
if velo.y > entity.accel then velo.y = entity.accel end
|
||||
|
||||
elseif velo.y > 0 then
|
||||
|
||||
velo.y = velo.y - 0.1
|
||||
|
||||
if velo.y < 0 then velo.y = 0 end
|
||||
end
|
||||
|
||||
-- fly down
|
||||
if ctrl.sneak then
|
||||
|
||||
velo.y = velo.y - 1
|
||||
|
||||
if velo.y < -entity.accel then velo.y = -entity.accel end
|
||||
|
||||
elseif velo.y < 0 then
|
||||
|
||||
velo.y = velo.y + 0.1
|
||||
|
||||
if velo.y > 0 then velo.y = 0 end
|
||||
end
|
||||
else
|
||||
|
@ -274,6 +303,7 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
|
|||
|
||||
-- if not moving then set animation and return
|
||||
if entity.v == 0 and velo.x == 0 and velo.y == 0 and velo.z == 0 then
|
||||
|
||||
if stand_anim then
|
||||
mobs:set_animation(entity, stand_anim)
|
||||
end
|
||||
|
@ -292,8 +322,10 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
|
|||
entity.v = entity.v - 0.02 * s
|
||||
|
||||
if s ~= get_sign(entity.v) then
|
||||
|
||||
entity.object:set_velocity({x = 0, y = 0, z = 0})
|
||||
entity.v = 0
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
|
@ -310,6 +342,7 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
|
|||
|
||||
-- Set position, velocity and acceleration
|
||||
local p = entity.object:get_pos()
|
||||
|
||||
if not p then return end
|
||||
|
||||
local new_acce = {x = 0, y = -9.81, z = 0}
|
||||
|
@ -320,18 +353,23 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
|
|||
local v = entity.v
|
||||
|
||||
if ni == "air" then
|
||||
|
||||
if can_fly == true then
|
||||
new_acce.y = 0
|
||||
end
|
||||
|
||||
elseif ni == "liquid" or ni == "lava" then
|
||||
|
||||
if ni == "lava" and entity.lava_damage ~= 0 then
|
||||
|
||||
entity.lava_counter = (entity.lava_counter or 0) + dtime
|
||||
|
||||
if entity.lava_counter > 1 then
|
||||
|
||||
minetest.sound_play("default_punch", {
|
||||
object = entity.object,
|
||||
max_hear_distance = 5
|
||||
})
|
||||
}, true)
|
||||
|
||||
entity.object:punch(entity.object, 1.0, {
|
||||
full_punch_interval = 1.0,
|
||||
|
@ -343,11 +381,14 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
|
|||
end
|
||||
|
||||
local terrain_type = entity.terrain_type
|
||||
|
||||
if terrain_type == 2 or terrain_type == 3 then
|
||||
|
||||
new_acce.y = 0
|
||||
p.y = p.y + 1
|
||||
|
||||
if node_is(p) == "liquid" then
|
||||
|
||||
if velo.y >= 5 then
|
||||
velo.y = 5
|
||||
elseif velo.y < 0 then
|
||||
|
@ -357,7 +398,9 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
|
|||
end
|
||||
else
|
||||
if abs(velo.y) < 1 then
|
||||
|
||||
local pos = entity.object:get_pos()
|
||||
|
||||
if not pos then return end
|
||||
|
||||
pos.y = floor(pos.y) + 0.5
|
||||
|
@ -371,6 +414,7 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
|
|||
end
|
||||
|
||||
local new_velo = get_velocity(v, yaw - rot_view, velo.y)
|
||||
|
||||
new_acce.y = new_acce.y + acce_y
|
||||
|
||||
entity.object:set_velocity(new_velo)
|
||||
|
@ -382,11 +426,14 @@ end
|
|||
|
||||
-- directional flying routine by D00Med (edited by TenPlus1)
|
||||
function mobs.fly(entity, _, speed, shoots, arrow, moving_anim, stand_anim)
|
||||
|
||||
local ctrl = entity.driver:get_player_control()
|
||||
local velo = entity.object:get_velocity()
|
||||
local dir = entity.driver:get_look_dir()
|
||||
local yaw = entity.driver:get_look_horizontal() + 1.57 -- offset fix between old and new commands
|
||||
|
||||
if not ctrl or not velo then return end
|
||||
|
||||
if ctrl.up then
|
||||
entity.object:set_velocity({
|
||||
x = dir.x * speed,
|
||||
|
@ -395,6 +442,7 @@ function mobs.fly(entity, _, speed, shoots, arrow, moving_anim, stand_anim)
|
|||
})
|
||||
|
||||
elseif ctrl.down then
|
||||
|
||||
entity.object:set_velocity({
|
||||
x = -dir.x * speed,
|
||||
y = dir.y * speed + 2,
|
||||
|
@ -409,6 +457,7 @@ function mobs.fly(entity, _, speed, shoots, arrow, moving_anim, stand_anim)
|
|||
|
||||
-- firing arrows
|
||||
if ctrl.LMB and ctrl.sneak and shoots then
|
||||
|
||||
local pos = entity.object:get_pos()
|
||||
local obj = minetest.add_entity({
|
||||
x = pos.x + 0 + dir.x * 2.5,
|
||||
|
@ -416,11 +465,15 @@ function mobs.fly(entity, _, speed, shoots, arrow, moving_anim, stand_anim)
|
|||
z = pos.z + 0 + dir.z * 2.5}, arrow)
|
||||
|
||||
local ent = obj:get_luaentity()
|
||||
|
||||
if ent then
|
||||
|
||||
ent.switch = 1 -- for mob specific arrows
|
||||
ent.owner_id = tostring(entity.object) -- so arrows dont hurt entity you are riding
|
||||
local vec = {x = dir.x * 6, y = dir.y * 6, z = dir.z * 6}
|
||||
|
||||
yaw = entity.driver:get_look_horizontal()
|
||||
|
||||
obj:set_yaw(yaw + pi / 2)
|
||||
obj:set_velocity(vec)
|
||||
else
|
||||
|
|
|
@ -39,3 +39,6 @@ mob_area_spawn (Mob Area Spawn) bool false
|
|||
|
||||
# Enable peaceful player attack prevention
|
||||
enable_peaceful_player (Mobs do not attack peaceful player without reason) bool false
|
||||
|
||||
# Enable mobs smooth rotation
|
||||
mob_smooth_rotate (Smooth rotation for mobs) bool true
|
||||
|
|
|
@ -222,8 +222,30 @@ This is best left explicit. First, you shouldn't be using numbered field keys if
|
|||
4. [`json`](https://json.org)
|
||||
* Not recommended
|
||||
|
||||
## `debug`
|
||||
|
||||
`modlib.debug` offers utilities dumping program state in tables.
|
||||
|
||||
### `variables(stacklevel)`
|
||||
|
||||
Dumps local variables, upvalues and the function environment of the function at the given stacklevel (default `1`).
|
||||
|
||||
### `stack(stacklevel)`
|
||||
|
||||
Dumps function info & variables for all functions in stack, starting with stacklevel (default `1`).
|
||||
|
||||
## `minetest`
|
||||
|
||||
### `schematic`
|
||||
|
||||
A schematic format with support for metadata and baked light data. **Experimental.**
|
||||
|
||||
## Release Notes
|
||||
|
||||
### `rolling-69`
|
||||
|
||||
* Fixes various things, **most importantly modules indexing the global table**
|
||||
|
||||
### `rolling-68`
|
||||
|
||||
* Replace changelog by release notes (see the commit log for changes)
|
||||
|
|
|
@ -1,6 +1,12 @@
|
|||
--! experimental
|
||||
local bluon = getfenv(1)
|
||||
local metatable = {__index = bluon}
|
||||
|
||||
local no_op = modlib.func.no_op
|
||||
local write_float = modlib.binary.write_float
|
||||
|
||||
local metatable = {__index = function(_self, key)
|
||||
return rawget(bluon, key)
|
||||
end}
|
||||
|
||||
function new(self)
|
||||
return setmetatable(self or {}, metatable)
|
||||
|
@ -95,23 +101,28 @@ local function is_map_key(key, list_len)
|
|||
end
|
||||
|
||||
function len(self, object)
|
||||
if object == nil then
|
||||
return 0
|
||||
end
|
||||
if constants[object] then
|
||||
return 1
|
||||
end
|
||||
local object_ids = {}
|
||||
local current_id = 0
|
||||
local _type = type(object)
|
||||
if _type == "number" then
|
||||
if object ~= object then
|
||||
stream:write(constant_nan)
|
||||
return
|
||||
return 1
|
||||
end
|
||||
if object % 1 == 0 then
|
||||
return 1 + uint_len(object > 0 and object or -object)
|
||||
end
|
||||
-- TODO ensure this check is proper
|
||||
if mantissa % 2^-23 > 0 then
|
||||
return 9
|
||||
end
|
||||
return 5
|
||||
-- HACK use write_float to get the length
|
||||
local bytes = 4
|
||||
write_float(no_op, object, function(double)
|
||||
if double then bytes = 8 end
|
||||
end)
|
||||
return 1 + bytes
|
||||
end
|
||||
local id = object_ids[object]
|
||||
if id then
|
||||
|
@ -126,7 +137,6 @@ function len(self, object)
|
|||
if _type == "table" then
|
||||
if next(object) == nil then
|
||||
-- empty {} table
|
||||
byte(type_ranges.string + 1)
|
||||
return 1
|
||||
end
|
||||
local list_len = #object
|
||||
|
@ -138,14 +148,14 @@ function len(self, object)
|
|||
end
|
||||
local table_len = 1 + uint_len(list_len) + uint_len(kv_len)
|
||||
for index = 1, list_len do
|
||||
table_len = table_len + len(self, object[index])
|
||||
table_len = table_len + self:len(object[index])
|
||||
end
|
||||
for key, value in pairs(object) do
|
||||
if is_map_key(key, list_len) then
|
||||
table_len = table_len + len(self, key) + len(self, value)
|
||||
table_len = table_len + self:len(key) + self:len(value)
|
||||
end
|
||||
end
|
||||
return len
|
||||
return kv_len + table_len
|
||||
end
|
||||
return self.aux_len(object)
|
||||
end
|
||||
|
@ -169,7 +179,6 @@ function write(self, object, stream)
|
|||
byte(base + type_offset)
|
||||
uint(type_offset, _uint)
|
||||
end
|
||||
local write_float = modlib.binary.write_float
|
||||
local function float_on_write(double)
|
||||
byte(double and type_ranges.number or type_ranges.number_f32)
|
||||
end
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
minetest.mkdir(minetest.get_worldpath().."/data")
|
||||
function create_mod_storage(modname)
|
||||
minetest.mkdir(minetest.get_worldpath().."/data/"..modname)
|
||||
end
|
||||
function get_path(modname, filename)
|
||||
return minetest.get_worldpath().."/data/"..modname.."/"..filename
|
||||
end
|
||||
function load(modname, filename)
|
||||
return minetest.deserialize(modlib.file.read(get_path(modname, filename)..".lua"))
|
||||
end
|
||||
function save(modname, filename, stuff)
|
||||
return modlib.file.write(get_path(modname, filename)..".lua", minetest.serialize(stuff))
|
||||
end
|
||||
function load_json(modname, filename)
|
||||
return minetest.parse_json(modlib.file.read(get_path(modname, filename)..".json") or "null")
|
||||
end
|
||||
function save_json(modname, filename, stuff)
|
||||
return modlib.file.write(get_path(modname, filename)..".json", minetest.write_json(stuff))
|
||||
end
|
|
@ -1,34 +1,43 @@
|
|||
local function gather_info()
|
||||
local locals = {}
|
||||
local index = 1
|
||||
while true do
|
||||
local name, value = debug.getlocal(2, index)
|
||||
if not name then break end
|
||||
table.insert(locals, {name, value})
|
||||
index = index + 1
|
||||
end
|
||||
local upvalues = {}
|
||||
local func = debug.getinfo(2).func
|
||||
local envs = getfenv(func)
|
||||
index = 1
|
||||
while true do
|
||||
local name, value = debug.getupvalue(func, index)
|
||||
if not name then break end
|
||||
table.insert(upvalues, {name, value})
|
||||
index = index + 1
|
||||
end
|
||||
return {
|
||||
locals = locals,
|
||||
upvalues = upvalues,
|
||||
[envs == _G and "globals" or "envs"] = envs
|
||||
}
|
||||
function variables(stacklevel)
|
||||
stacklevel = (stacklevel or 1) + 1
|
||||
local locals = {}
|
||||
local index = 1
|
||||
while true do
|
||||
local name, value = debug.getlocal(stacklevel, index)
|
||||
if not name then break end
|
||||
table.insert(locals, {name, value})
|
||||
index = index + 1
|
||||
end
|
||||
local upvalues = {}
|
||||
local func = debug.getinfo(stacklevel).func
|
||||
local fenv = getfenv(func)
|
||||
index = 1
|
||||
while true do
|
||||
local name, value = debug.getupvalue(func, index)
|
||||
if not name then break end
|
||||
table.insert(upvalues, {name, value})
|
||||
index = index + 1
|
||||
end
|
||||
return {
|
||||
locals = locals,
|
||||
upvalues = upvalues,
|
||||
fenv = fenv,
|
||||
fenv_global = fenv == _G
|
||||
}
|
||||
end
|
||||
|
||||
local c = 3
|
||||
function test()
|
||||
local a = 1
|
||||
b = 2
|
||||
error(gather_info().upvalues[1][1])
|
||||
end
|
||||
|
||||
test()
|
||||
function stack(stacklevel)
|
||||
stacklevel = (stacklevel or 1) + 1
|
||||
local stack = {}
|
||||
while true do
|
||||
local info = debug.getinfo(stacklevel, "nfSlu")
|
||||
if not info then
|
||||
break
|
||||
end
|
||||
info.func = tostring(info.func)
|
||||
info.variables = variables(stacklevel)
|
||||
stack[stacklevel - 1] = info
|
||||
stacklevel = stacklevel + 1
|
||||
end
|
||||
return stack
|
||||
end
|
|
@ -38,4 +38,76 @@ end
|
|||
--+ Calls func using the provided arguments, deepcopies all arguments
|
||||
function call_by_value(func, ...)
|
||||
return func(unpack(modlib.table.deepcopy{...}))
|
||||
end
|
||||
|
||||
-- Functional wrappers for Lua's builtin metatable operators (arithmetic, concatenation, length, comparison, indexing, call)
|
||||
|
||||
function add(a, b)
|
||||
return a + b
|
||||
end
|
||||
|
||||
function mul(a, b)
|
||||
return a * b
|
||||
end
|
||||
|
||||
function div(a, b)
|
||||
return a / b
|
||||
end
|
||||
|
||||
function mod(a, b)
|
||||
return a % b
|
||||
end
|
||||
|
||||
function pow(a, b)
|
||||
return a ^ b
|
||||
end
|
||||
|
||||
function unm(a)
|
||||
return -a
|
||||
end
|
||||
|
||||
function concat(a, b)
|
||||
return a .. b
|
||||
end
|
||||
|
||||
function len(a)
|
||||
return #a
|
||||
end
|
||||
|
||||
function eq(a, b)
|
||||
return a == b
|
||||
end
|
||||
|
||||
function lt(a, b)
|
||||
return a < b
|
||||
end
|
||||
|
||||
function le(a, b)
|
||||
return a <= b
|
||||
end
|
||||
|
||||
function index(object, key)
|
||||
return object[key]
|
||||
end
|
||||
|
||||
function newindex(object, key, value)
|
||||
object[key] = value
|
||||
end
|
||||
|
||||
function call(object, ...)
|
||||
object(...)
|
||||
end
|
||||
|
||||
-- Functional wrappers for logical operators, suffixed with _ to avoid a syntax error
|
||||
|
||||
function not_(a)
|
||||
return not a
|
||||
end
|
||||
|
||||
function and_(a, b)
|
||||
return a and b
|
||||
end
|
||||
|
||||
function or_(a, b)
|
||||
return a or b
|
||||
end
|
|
@ -53,7 +53,8 @@ for _, file in pairs{
|
|||
"binary",
|
||||
"b3d",
|
||||
"bluon",
|
||||
"persistence"
|
||||
"persistence",
|
||||
"debug"
|
||||
} do
|
||||
modules[file] = file
|
||||
end
|
||||
|
@ -64,10 +65,10 @@ if minetest then
|
|||
"liquid",
|
||||
"raycast",
|
||||
"wielditem_change",
|
||||
"colorspec"
|
||||
"colorspec",
|
||||
"schematic"
|
||||
}
|
||||
for _, file in pairs{
|
||||
"data",
|
||||
"log",
|
||||
"player",
|
||||
-- deprecated
|
||||
|
@ -80,7 +81,7 @@ end
|
|||
local load_module, get_resource, loadfile_exports
|
||||
modlib = setmetatable({
|
||||
-- TODO bump on release
|
||||
version = 68,
|
||||
version = 69,
|
||||
modname = minetest and minetest.get_current_modname(),
|
||||
dir_delim = rawget(_G, "DIR_DELIM") or "/",
|
||||
_RG = setmetatable({}, {
|
||||
|
@ -99,14 +100,21 @@ modlib = setmetatable({
|
|||
}, {
|
||||
__index = function(self, module_name)
|
||||
local files = modules[module_name]
|
||||
local module
|
||||
local environment
|
||||
if type(files) == "string" then
|
||||
module = load_module(files)
|
||||
environment = load_module(files)
|
||||
elseif files then
|
||||
module = loadfile_exports(get_resource(self.modname, module_name, files[1] .. ".lua"))
|
||||
environment = loadfile_exports(get_resource(self.modname, module_name, files[1] .. ".lua"))
|
||||
for index = 2, #files do
|
||||
self.mod.include_env(get_resource(self.modname, module_name, files[index] .. ".lua"), module)
|
||||
self.mod.include_env(get_resource(self.modname, module_name, files[index] .. ".lua"), environment)
|
||||
end
|
||||
else
|
||||
return
|
||||
end
|
||||
local module = {}
|
||||
for key, value in pairs(environment) do
|
||||
-- Shallow copy. Doesn't use `modlib.table.shallowcopy` as that is part of a module, too.
|
||||
module[key] = value
|
||||
end
|
||||
self[module_name] = module
|
||||
return module
|
||||
|
@ -154,8 +162,6 @@ end
|
|||
|
||||
_ml = modlib
|
||||
|
||||
modlib.mod.include"test.lua"
|
||||
--modlib.mod.include"bench.lua"
|
||||
--[[
|
||||
--modlib.mod.include"test.lua"
|
||||
]]
|
||||
|
|
|
@ -14,7 +14,6 @@ local function get_gametime_init(dtime)
|
|||
return
|
||||
end
|
||||
get_gametime_initialized = true
|
||||
assert(dtime == 0)
|
||||
local gametime = minetest.get_gametime()
|
||||
assert(gametime)
|
||||
function modlib.minetest.get_gametime()
|
||||
|
|
|
@ -0,0 +1,137 @@
|
|||
schematic = {}
|
||||
local metatable = {__index = schematic}
|
||||
|
||||
function schematic.setmetatable(self)
|
||||
return setmetatable(self, metatable)
|
||||
end
|
||||
|
||||
function schematic.create(self, pos_min, pos_max)
|
||||
self.size = vector.subtract(pos_max, pos_min)
|
||||
local voxelmanip = minetest.get_voxel_manip(pos_min, pos_max)
|
||||
local emin, emax = voxelmanip:read_from_map(pos_min, pos_max)
|
||||
local voxelarea = VoxelArea:new{ MinEdge = emin, MaxEdge = emax }
|
||||
local nodes, light_values, param2s = {}, self.light_values and {}, {}
|
||||
local vm_nodes, vm_light_values, vm_param2s = voxelmanip:get_data(), light_values and voxelmanip:get_light_data(), voxelmanip:get_param2_data()
|
||||
local node_names, node_ids = {}, {}
|
||||
local i = 0
|
||||
for index in voxelarea:iterp(pos_min, pos_max) do
|
||||
if nodes[index] == minetest.CONTENT_UNKNOWN or nodes[index] == minetest.CONTENT_IGNORE then
|
||||
error("unknown or ignore node at " .. minetest.pos_to_string(voxelarea:position(index)))
|
||||
end
|
||||
local name = minetest.get_name_from_content_id(vm_nodes[index])
|
||||
local id = node_ids[name]
|
||||
if not id then
|
||||
table.insert(node_names, name)
|
||||
id = #node_names
|
||||
node_ids[name] = id
|
||||
end
|
||||
i = i + 1
|
||||
nodes[i] = id
|
||||
if self.light_values then
|
||||
light_values[i] = vm_light_values[index]
|
||||
end
|
||||
param2s[i] = vm_param2s[index]
|
||||
end
|
||||
local metas = self.metas
|
||||
if metas or metas == nil then
|
||||
local indexing = vector.add(self.size, 1)
|
||||
metas = {}
|
||||
for _, pos in ipairs(minetest.find_nodes_with_meta(pos_min, pos_max)) do
|
||||
local meta = minetest.get_meta(pos):to_table()
|
||||
if next(meta.fields) ~= nil or next(meta.inventory) ~= nil then
|
||||
local relative = vector.subtract(pos, pos_min)
|
||||
metas[((relative.z * indexing.y) + relative.y) * indexing.x + relative.x] = meta
|
||||
end
|
||||
end
|
||||
end
|
||||
self.node_names = node_names
|
||||
self.nodes = nodes
|
||||
self.light_values = light_values
|
||||
self.param2s = param2s
|
||||
self.metas = metas
|
||||
return schematic.setmetatable(self)
|
||||
end
|
||||
|
||||
function schematic:write_to_voxelmanip(voxelmanip, pos_min)
|
||||
local pos_max = vector.add(pos_min, self.size)
|
||||
local emin, emax = voxelmanip:read_from_map(pos_min, pos_max)
|
||||
local voxelarea = VoxelArea:new{ MinEdge = emin, MaxEdge = emax }
|
||||
local nodes, light_values, param2s, metas = self.nodes, self.light_values, self.param2s, self.metas
|
||||
local vm_nodes, vm_lights, vm_param2s = voxelmanip:get_data(), light_values and voxelmanip:get_light_data(), voxelmanip:get_param2_data()
|
||||
for _, pos in ipairs(minetest.find_nodes_with_meta(pos_min, pos_max)) do
|
||||
-- Clear all metadata. Due to an engine bug, nodes will actually have empty metadata.
|
||||
minetest.get_meta(pos):from_table{}
|
||||
end
|
||||
local content_ids = {}
|
||||
for index, name in ipairs(self.node_names) do
|
||||
content_ids[index] = assert(minetest.get_content_id(name), ("unknown node %q"):format(name))
|
||||
end
|
||||
local i = 0
|
||||
for index in voxelarea:iterp(pos_min, pos_max) do
|
||||
i = i + 1
|
||||
vm_nodes[index] = content_ids[nodes[i]]
|
||||
if light_values then
|
||||
vm_lights[index] = light_values[i]
|
||||
end
|
||||
vm_param2s[index] = param2s[i]
|
||||
end
|
||||
voxelmanip:set_data(vm_nodes)
|
||||
if light_values then
|
||||
voxelmanip:set_light_data(vm_lights)
|
||||
end
|
||||
voxelmanip:set_param2_data(vm_param2s)
|
||||
if metas then
|
||||
local indexing = vector.add(self.size, 1)
|
||||
for index, meta in pairs(metas) do
|
||||
local floored = math.floor(index / indexing.x)
|
||||
local relative = {
|
||||
x = index % indexing.x,
|
||||
y = floored % indexing.y,
|
||||
z = math.floor(floored / indexing.y)
|
||||
}
|
||||
minetest.get_meta(vector.add(relative, pos_min)):from_table(meta)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function schematic:place(pos_min)
|
||||
local pos_max = vector.add(pos_min, self.size)
|
||||
local voxelmanip = minetest.get_voxel_manip(pos_min, pos_max)
|
||||
self:write_to_voxelmanip(voxelmanip, pos_min)
|
||||
voxelmanip:write_to_map(not self.light_values)
|
||||
return voxelmanip
|
||||
end
|
||||
|
||||
function schematic:write_bluon(path)
|
||||
local file = io.open(path, "w")
|
||||
-- Header, short for "ModLib Bluon Schematic"
|
||||
file:write"MLBS"
|
||||
modlib.bluon:write(self, file)
|
||||
file:close()
|
||||
end
|
||||
|
||||
function schematic.read_bluon(path)
|
||||
local file = io.open(path, "r")
|
||||
assert(file:read(4) == "MLBS", "not a modlib bluon schematic")
|
||||
local self = modlib.bluon:read(file)
|
||||
assert(not file:read(), "expected EOF")
|
||||
return schematic.setmetatable(self)
|
||||
end
|
||||
|
||||
function schematic:write_zlib_bluon(path, compression)
|
||||
local file = io.open(path, "w")
|
||||
-- Header, short for "ModLib Zlib-compressed-bluon Schematic"
|
||||
file:write"MLZS"
|
||||
local rope = modlib.table.rope{}
|
||||
modlib.bluon:write(self, rope)
|
||||
local text = rope:to_text()
|
||||
file:write(minetest.compress(text, "deflate", compression or 9))
|
||||
file:close()
|
||||
end
|
||||
|
||||
function schematic.read_zlib_bluon(path)
|
||||
local file = io.open(path, "r")
|
||||
assert(file:read(4) == "MLZS", "not a modlib zlib compressed bluon schematic")
|
||||
local self = modlib.bluon:read(modlib.text.inputstream(minetest.decompress(file:read"*a", "deflate")))
|
||||
return schematic.setmetatable(self)
|
||||
end
|
|
@ -80,14 +80,17 @@ function lua_log_file:_dump(value, is_key)
|
|||
if _type == "number" then
|
||||
return ("%.17g"):format(value)
|
||||
end
|
||||
if self.references[value] then
|
||||
return "R[" .. self.references[value] .. "]"
|
||||
local reference = self.references[value]
|
||||
if reference then
|
||||
return "R[" .. reference .."]"
|
||||
end
|
||||
self.reference_count = self.reference_count + 1
|
||||
local reference = self.reference_count
|
||||
reference = self.reference_count + 1
|
||||
local key = "R[" .. reference .."]"
|
||||
self.references[value] = reference
|
||||
local formatted
|
||||
local function create_reference()
|
||||
self.reference_count = reference
|
||||
self.references[value] = reference
|
||||
end
|
||||
if _type == "string" then
|
||||
if is_key and value:len() <= key:len() and value:match"[%a_][%a%d_]*" then
|
||||
-- Short key
|
||||
|
@ -98,13 +101,18 @@ function lua_log_file:_dump(value, is_key)
|
|||
-- Short string
|
||||
return formatted
|
||||
end
|
||||
-- Use reference
|
||||
create_reference()
|
||||
elseif _type == "table" then
|
||||
-- Tables always need a reference before they are traversed to prevent infinite recursion
|
||||
create_reference()
|
||||
local entries = {}
|
||||
for _, value in ipairs(value) do
|
||||
table.insert(entries, self:_dump(value))
|
||||
end
|
||||
local tablelen = #value
|
||||
for key, value in pairs(value) do
|
||||
if type(key) ~= "number" or key % 1 ~= 0 or key < 1 or key > #value then
|
||||
if type(key) ~= "number" or key % 1 ~= 0 or key < 1 or key > tablelen then
|
||||
local dumped, short = self:_dump(key, true)
|
||||
table.insert(entries, (short and dumped or ("[" .. dumped .. "]")) .. "=" .. self:_dump(value))
|
||||
end
|
||||
|
|
|
@ -214,7 +214,7 @@ local function _delete(self, key, is_rank)
|
|||
sidemost = sidemost[other_side]
|
||||
end
|
||||
-- Replace deleted key
|
||||
tree.key = rightmost.key
|
||||
tree.key = sidemost.key
|
||||
-- Replace the successor by it's single child
|
||||
parents[len][sides[len]] = sidemost[side]
|
||||
else
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
-- ensure modlib API isn't leaking into global environment
|
||||
assert(modlib.bluon.assert ~= assert)
|
||||
|
||||
local random, huge = math.random, math.huge
|
||||
local parent_env = getfenv(1)
|
||||
setfenv(1, setmetatable({}, {
|
||||
|
|
|
@ -102,6 +102,11 @@ local function lay_down(player, pos, bed_pos, state, skip)
|
|||
return false
|
||||
end
|
||||
|
||||
-- Check if player is attached to an object
|
||||
if player:get_attach() then
|
||||
return false
|
||||
end
|
||||
|
||||
if beds.player[name] then
|
||||
-- player already in bed, do nothing
|
||||
return false
|
||||
|
|
|
@ -53,6 +53,7 @@ minetest.register_craftitem("binoculars:binoculars", {
|
|||
description = S("Binoculars") .. "\n" .. S("Use with 'Zoom' key"),
|
||||
inventory_image = "binoculars_binoculars.png",
|
||||
stack_max = 1,
|
||||
groups = {tool = 1},
|
||||
|
||||
on_use = function(itemstack, user, pointed_thing)
|
||||
binoculars.update_player_property(user)
|
||||
|
|
|
@ -53,31 +53,24 @@ function boat.on_rightclick(self, clicker)
|
|||
end
|
||||
local name = clicker:get_player_name()
|
||||
if self.driver and name == self.driver then
|
||||
self.driver = nil
|
||||
self.auto = false
|
||||
-- Cleanup happens in boat.on_detach_child
|
||||
clicker:set_detach()
|
||||
player_api.player_attached[name] = false
|
||||
player_api.set_animation(clicker, "stand" , 30)
|
||||
|
||||
player_api.set_animation(clicker, "stand", 30)
|
||||
local pos = clicker:get_pos()
|
||||
pos = {x = pos.x, y = pos.y + 0.2, z = pos.z}
|
||||
minetest.after(0.1, function()
|
||||
clicker:set_pos(pos)
|
||||
end)
|
||||
elseif not self.driver then
|
||||
local attach = clicker:get_attach()
|
||||
if attach and attach:get_luaentity() then
|
||||
local luaentity = attach:get_luaentity()
|
||||
if luaentity.driver then
|
||||
luaentity.driver = nil
|
||||
end
|
||||
clicker:set_detach()
|
||||
end
|
||||
self.driver = name
|
||||
clicker:set_attach(self.object, "",
|
||||
{x = 0.5, y = 1, z = -3}, {x = 0, y = 0, z = 0})
|
||||
|
||||
self.driver = name
|
||||
player_api.player_attached[name] = true
|
||||
|
||||
minetest.after(0.2, function()
|
||||
player_api.set_animation(clicker, "sit" , 30)
|
||||
player_api.set_animation(clicker, "sit", 30)
|
||||
end)
|
||||
clicker:set_look_horizontal(self.object:get_yaw())
|
||||
end
|
||||
|
@ -86,8 +79,12 @@ end
|
|||
|
||||
-- If driver leaves server while driving boat
|
||||
function boat.on_detach_child(self, child)
|
||||
self.driver = nil
|
||||
self.auto = false
|
||||
if child and child:get_player_name() == self.driver then
|
||||
player_api.player_attached[child:get_player_name()] = false
|
||||
|
||||
self.driver = nil
|
||||
self.auto = false
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
|
|
@ -29,15 +29,10 @@ function cart_entity:on_rightclick(clicker)
|
|||
end
|
||||
local player_name = clicker:get_player_name()
|
||||
if self.driver and player_name == self.driver then
|
||||
self.driver = nil
|
||||
carts:manage_attachment(clicker, nil)
|
||||
elseif not self.driver then
|
||||
self.driver = player_name
|
||||
carts:manage_attachment(clicker, self.object)
|
||||
|
||||
-- player_api does not update the animation
|
||||
-- when the player is attached, reset to default animation
|
||||
player_api.set_animation(clicker, "stand")
|
||||
self.driver = player_name
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -66,8 +61,9 @@ end
|
|||
-- 0.5.x and later: When the driver leaves
|
||||
function cart_entity:on_detach_child(child)
|
||||
if child and child:get_player_name() == self.driver then
|
||||
self.driver = nil
|
||||
-- Clean up eye height
|
||||
carts:manage_attachment(child, nil)
|
||||
self.driver = nil
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ function carts:manage_attachment(player, obj)
|
|||
end
|
||||
local status = obj ~= nil
|
||||
local player_name = player:get_player_name()
|
||||
if player_api.player_attached[player_name] == status then
|
||||
if obj and player:get_attach() == obj then
|
||||
return
|
||||
end
|
||||
player_api.player_attached[player_name] = status
|
||||
|
@ -20,6 +20,10 @@ function carts:manage_attachment(player, obj)
|
|||
if status then
|
||||
player:set_attach(obj, "", {x=0, y=-4.5, z=0}, {x=0, y=0, z=0})
|
||||
player:set_eye_offset({x=0, y=-4, z=0},{x=0, y=-4, z=0})
|
||||
|
||||
-- player_api does not update the animation
|
||||
-- when the player is attached, reset to default animation
|
||||
player_api.set_animation(player, "stand")
|
||||
else
|
||||
player:set_detach()
|
||||
player:set_eye_offset({x=0, y=0, z=0},{x=0, y=0, z=0})
|
||||
|
|
|
@ -178,7 +178,7 @@ Gambit (CC BY-SA 3.0):
|
|||
default_iron_lump.png
|
||||
default_gold_lump.png
|
||||
default_clay_lump.png
|
||||
default_coal.png
|
||||
default_coal_lump.png
|
||||
default_grass_*.png
|
||||
default_paper.png
|
||||
default_diamond_block.png
|
||||
|
|
|
@ -248,7 +248,7 @@ end
|
|||
|
||||
minetest.register_abm({
|
||||
label = "Mushroom spread",
|
||||
nodenames = {"flowers:mushroom_brown", "flowers:mushroom_red"},
|
||||
nodenames = {"group:mushroom"},
|
||||
interval = 11,
|
||||
chance = 150,
|
||||
action = function(...)
|
||||
|
|
|
@ -51,7 +51,7 @@ minetest.register_craftitem("map:mapping_kit", {
|
|||
description = S("Mapping Kit") .. "\n" .. S("Use with 'Minimap' key"),
|
||||
inventory_image = "map_mapping_kit.png",
|
||||
stack_max = 1,
|
||||
groups = {flammable = 3},
|
||||
groups = {flammable = 3, tool = 1},
|
||||
|
||||
on_use = function(itemstack, user, pointed_thing)
|
||||
map.update_hud_flags(user)
|
||||
|
|
|
@ -227,6 +227,8 @@ if minetest.get_modpath("doors") then
|
|||
sounds = default.node_sound_metal_defaults(),
|
||||
sound_open = "xpanes_steel_bar_door_open",
|
||||
sound_close = "xpanes_steel_bar_door_close",
|
||||
gain_open = 0.15,
|
||||
gain_close = 0.13,
|
||||
recipe = {
|
||||
{"xpanes:bar_flat", "xpanes:bar_flat"},
|
||||
{"xpanes:bar_flat", "xpanes:bar_flat"},
|
||||
|
@ -245,6 +247,8 @@ if minetest.get_modpath("doors") then
|
|||
sounds = default.node_sound_metal_defaults(),
|
||||
sound_open = "xpanes_steel_bar_door_open",
|
||||
sound_close = "xpanes_steel_bar_door_close",
|
||||
gain_open = 0.15,
|
||||
gain_close = 0.13,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
|
|
|
@ -61,8 +61,9 @@ function petz.throw(self, dtime, damage, effect, particles, sound)
|
|||
z = node_pos.z,
|
||||
}
|
||||
local node_above = minetest.get_node(pos_above)
|
||||
if minetest.get_item_group(node_name, "flammable") > 1 then
|
||||
minetest.set_node(node_pos, {name = "fire:basic_flame"})
|
||||
if minetest.get_item_group(node_name, "flammable") > 1
|
||||
and not minetest.is_protected(node_pos, "") then
|
||||
minetest.set_node(node_pos, {name = "fire:basic_flame"})
|
||||
end
|
||||
if node_above.name == "air" then
|
||||
--if minetest.get_node(pos_above).name == "air" then
|
||||
|
|
|
@ -78,7 +78,7 @@ minetest.register_chatcommand("wl_lb", {
|
|||
params = "",
|
||||
description = "list biomes",
|
||||
privs = {interact = true},
|
||||
func = function()
|
||||
func = function(name)
|
||||
|
||||
|
||||
local biom = water_life.get_biomes()
|
||||
|
@ -86,7 +86,7 @@ minetest.register_chatcommand("wl_lb", {
|
|||
if not biom then return end
|
||||
|
||||
for i=1,#biom,1 do
|
||||
minetest.chat_send_all(dump(i)..") "..dump(biom[i]))
|
||||
minetest.chat_send_player(name, dump(i)..") "..dump(biom[i]))
|
||||
|
||||
end
|
||||
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
|
||||
local S = mobs.intllib
|
||||
|
||||
local mob_drops = {
|
||||
{name = "fireflies:firefly", chance = 1, min = 1, max = 1}
|
||||
}
|
||||
|
||||
if minetest.get_modpath("ethereal") then
|
||||
|
||||
table.insert(mob_drops,
|
||||
{name = "ethereal:fire_dust", chance = 1, min = 1, max = 1})
|
||||
end
|
||||
|
||||
-- Fire Spirit
|
||||
|
||||
mobs:register_mob("mobs_monster:fire_spirit", {
|
||||
type = "monster",
|
||||
passive = false,
|
||||
attack_type = "dogfight",
|
||||
pathfinding = true,
|
||||
reach = 2,
|
||||
damage = 4,
|
||||
hp_min = 25,
|
||||
hp_max = 45,
|
||||
armor = 100,
|
||||
collisionbox = {-0.1, -0.1, -0.1, 0.1, 0.1, 0.1},
|
||||
visual_scale = {x = 0.5, y = 0.5, z = 0.5},
|
||||
visual = "sprite",
|
||||
textures = {
|
||||
{"mobs_fire_spirit.png"}
|
||||
},
|
||||
glow = 14,
|
||||
blood_texture = "fire_basic_flame.png",
|
||||
immune_to = {
|
||||
{"bucket:bucket_water", 1},
|
||||
{"bucket:bucket_river_water", 1},
|
||||
{"all"}
|
||||
},
|
||||
makes_footstep_sound = false,
|
||||
sounds = {
|
||||
random = "fire_fire",
|
||||
damage = "fire_extinguish_flame",
|
||||
death = "fire_extinguish_flame"
|
||||
},
|
||||
view_range = 14,
|
||||
walk_velocity = 2,
|
||||
run_velocity = 3,
|
||||
jump = true,
|
||||
jump_height = 6,
|
||||
drops = mob_drops,
|
||||
water_damage = 1,
|
||||
lava_damage = 0,
|
||||
fire_damage = 0,
|
||||
light_damage = 0,
|
||||
fall_damage = false,
|
||||
fear_height = 8,
|
||||
animation = {},
|
||||
|
||||
on_die = function(self, pos)
|
||||
|
||||
mobs:effect(pos, 20, "tnt_smoke.png", 3, 5, 2, 0.5, nil, false)
|
||||
|
||||
self.object:remove()
|
||||
end,
|
||||
|
||||
do_custom = function(self, dtime)
|
||||
|
||||
self.flame_timer = (self.flame_timer or 0) + dtime
|
||||
|
||||
if self.flame_timer < 0.25 then
|
||||
return
|
||||
end
|
||||
|
||||
self.flame_timer = 0
|
||||
|
||||
local pos = self.object:get_pos()
|
||||
|
||||
-- pos, amount, texture, min_size, max_size, radius, gravity, glow, fall
|
||||
mobs:effect(pos, 5, "fire_basic_flame.png", 1, 2, 0.1, 0.2, 14, nil)
|
||||
end
|
||||
})
|
||||
|
||||
|
||||
if not mobs.custom_spawn_monster then
|
||||
mobs:spawn({
|
||||
name = "mobs_monster:fire_spirit",
|
||||
nodes = {"default:obsidian", "caverealms:hot_cobble"},
|
||||
neighbors = {"group:fire"},
|
||||
min_light = 12,
|
||||
max_light = 15,
|
||||
chance = 1500,
|
||||
active_object_count = 1,
|
||||
max_height = -150
|
||||
})
|
||||
end
|
||||
|
||||
|
||||
mobs:register_egg("mobs_monster:fire_spirit", S("Fire Spirit"), "fire_basic_flame.png", 1)
|
|
@ -29,6 +29,7 @@ dofile(path .. "lava_flan.lua") -- Zeg9
|
|||
dofile(path .. "mese_monster.lua")
|
||||
dofile(path .. "spider.lua") -- AspireMint
|
||||
dofile(path .. "land_guard.lua")
|
||||
dofile(path .. "fire_spirit.lua")
|
||||
|
||||
|
||||
-- Load custom spawning
|
||||
|
|
|
@ -41,4 +41,8 @@ Land Guard
|
|||
|
||||
- These huge monsters roam the land in cold, hot and temperate areas and don't like players wandering around their domain.
|
||||
|
||||
Fire Spirit
|
||||
|
||||
- Fire Spirits will not tolerate players roaming around their domain and will fiercely attack until their dying puff of smoke. Will drop it's spirit and some fire dust when using ethereal.
|
||||
|
||||
Lucky Blocks: 11
|
||||
|
|
After Width: | Height: | Size: 274 B |
|
@ -200,6 +200,10 @@ armor.update_player_visuals = function(self, player)
|
|||
self:run_callbacks("on_update", player)
|
||||
end
|
||||
|
||||
|
||||
-- armor is not visible on player model if enabled
|
||||
local transparent_armor = minetest.settings:get_bool("armor_transparent", false)
|
||||
|
||||
armor.set_player_armor = function(self, player)
|
||||
local name, armor_inv = self:get_valid_player(player, "[set_player_armor]")
|
||||
if not name then
|
||||
|
@ -258,7 +262,9 @@ armor.set_player_armor = function(self, player)
|
|||
tex = tex:gsub(".png$", "")
|
||||
local prev = def.preview or tex.."_preview"
|
||||
prev = prev:gsub(".png$", "")
|
||||
texture = texture.."^"..tex..".png"
|
||||
if not transparent_armor then
|
||||
texture = texture.."^"..tex..".png"
|
||||
end
|
||||
preview = preview.."^"..prev..".png"
|
||||
state = state + stack:get_wear()
|
||||
count = count + 1
|
||||
|
|
|
@ -58,6 +58,9 @@ armor_punch_damage (Enable damage effects) bool true
|
|||
# Enable migration of old armor inventories.
|
||||
armor_migrate_old_inventory (Migrate old armor inventories) bool true
|
||||
|
||||
# Don't show armor on character model.
|
||||
armor_transparent (Transparent armor) bool false
|
||||
|
||||
|
||||
[shields]
|
||||
|
||||
|
|