Mods update

master
daretmavi 2021-06-13 11:38:12 +02:00
parent 4eb9a6093b
commit e341523ef8
80 changed files with 1110 additions and 691 deletions

View File

@ -1,6 +1,6 @@
origin https://github.com/minetest/minetest_game.git (fetch) 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/beds
Mod: minetest_game/mods/binoculars Mod: minetest_game/mods/binoculars
Mod: minetest_game/mods/boats Mod: minetest_game/mods/boats
@ -61,11 +61,11 @@ origin https://github.com/Sokomine/mg_villages (fetch)
Mod: buildings/mg_villages Mod: buildings/mg_villages
origin git@github.com:minetest-mods/ts_doors.git (fetch) 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 Mod: buildings/ts_doors
origin https://github.com/sirrobzeroone/comboblock (fetch) 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 Mod: environment/comboblock
origin https://github.com/minetest-mods/dynamic_liquid (fetch) 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 Mod: environment/dynamic_liquid
origin https://notabug.org/tenplus1/farming (fetch) 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 Mod: flora/farming
origin https://github.com/minetest-mods/i3.git (fetch) 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 Mod: gui/i3
origin https://repo.or.cz/minetest_hbarmor.git (fetch) origin https://repo.or.cz/minetest_hbarmor.git (fetch)
@ -113,11 +113,11 @@ origin https://github.com/TheTermos/mobkit (fetch)
Mod: lib_api/mobkit Mod: lib_api/mobkit
origin https://notabug.org/tenplus1/mobs_redo (fetch) origin https://notabug.org/tenplus1/mobs_redo (fetch)
* master 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 Mod: lib_api/mobs_redo
origin https://github.com/appgurueu/modlib (fetch) origin https://github.com/appgurueu/modlib (fetch)
* master 68f6573 [origin/master] Bump version * master d8f3bf2 [origin/master] Fix debug.stack
Mod: lib_api/modlib Mod: lib_api/modlib
origin git@github.com:runsy/rcbows.git (fetch) origin git@github.com:runsy/rcbows.git (fetch)
@ -149,7 +149,7 @@ origin https://codeberg.org/Hamlet/mobs_ghost_redo (fetch)
Mod: mobs/mobs_mobs/mobs_ghost_redo Mod: mobs/mobs_mobs/mobs_ghost_redo
origin https://notabug.org/TenPlus1/mobs_monster.git (fetch) origin https://notabug.org/TenPlus1/mobs_monster.git (fetch)
* master e39d06b [origin/master] add fire damage to obsidian flan * master 9b3c1e1 [origin/master] fire spirit additions
Mod: mobs/mobs_mobs/mobs_monster Mod: mobs/mobs_mobs/mobs_monster
origin https://github.com/berengma/aerotest (fetch) origin https://github.com/berengma/aerotest (fetch)
@ -157,15 +157,15 @@ origin https://github.com/berengma/aerotest (fetch)
Mod: mobs/mobs_mobkit/aerotest Mod: mobs/mobs_mobkit/aerotest
origin https://github.com/runsy/petz (fetch) origin https://github.com/runsy/petz (fetch)
* master db3fa98 [origin/master] fixes * master b593d81 [origin/master] fix: pumpkin grenade respects protected nodes
Mod: mobs/mobs_mobkit/petz Mod: mobs/mobs_mobkit/petz
origin https://github.com/berengma/water_life (fetch) origin https://github.com/berengma/water_life (fetch)
* master 1919e32 [origin/master] Merge pull request #75 from berengma/test * master bc2f245 [origin/master] disable chat spamming
Mod: mobs/mobs_mobkit/water_life Mod: mobs/mobs_mobkit/water_life
origin https://github.com/minetest-mods/3d_armor (fetch) origin https://github.com/minetest-mods/3d_armor (fetch)
* master 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 Mod: player/3d_armor
origin https://github.com/appgurueu/character_anim (fetch) origin https://github.com/appgurueu/character_anim (fetch)

View File

@ -7,6 +7,21 @@ ts_doors.sounds = {}
-- Used for localization -- Used for localization
local S = minetest.get_translator("ts_doors") 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. -- Use this to generate the translation template file.
--[[ --[[
local oldS = S local oldS = S
@ -78,6 +93,9 @@ function ts_doors.register_door(item, description, texture, sounds, recipe)
if not sounds then if not sounds then
sounds = {} sounds = {}
end end
if not texture then
texture = T(item)
end
recipe = recipe or item recipe = recipe or item
ts_doors.registered_doors[item:gsub(":", "_")] = recipe ts_doors.registered_doors[item:gsub(":", "_")] = recipe
register_door_alias("doors:ts_door_" .. item:gsub(":", "_"), "ts_doors:door_" .. item:gsub(":", "_")) register_door_alias("doors:ts_door_" .. item:gsub(":", "_"), "ts_doors:door_" .. item:gsub(":", "_"))
@ -200,65 +218,65 @@ function ts_doors.register_door(item, description, texture, sounds, recipe)
}) })
end end
ts_doors.register_door("default:aspen_wood", "Aspen", "default_aspen_wood.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", "default_pine_wood.png", 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", "default_acacia_wood.png", ts_doors.sounds.wood) ts_doors.register_door("default:acacia_wood", "Acacia", nil, ts_doors.sounds.wood)
ts_doors.register_door("default:wood", "Wooden", "default_wood.png", ts_doors.sounds.wood) ts_doors.register_door("default:wood", "Wooden", nil, ts_doors.sounds.wood)
ts_doors.register_door("default:junglewood", "Jungle Wood", "default_junglewood.png", ts_doors.sounds.wood) ts_doors.register_door("default:junglewood", "Jungle Wood", nil, ts_doors.sounds.wood)
if minetest.get_modpath("moretrees") then 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:apple_tree_planks", "Apple Tree", nil, 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:beech_planks", "Beech", nil, 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:birch_planks", "Birch", nil, 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:fir_planks", "Fir", nil, 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:oak_planks", "Oak", nil, 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:palm_planks", "Palm", nil, 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:rubber_tree_planks", "Rubber Tree", nil, 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:sequoia_planks", "Sequoia", nil, 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:spruce_planks", "Spruce", nil, 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:willow_planks", "Willow", nil, ts_doors.sounds.wood)
end end
if minetest.get_modpath("ethereal") then 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:banana_wood", "Banana", nil, 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:birch_wood", "Birch", nil, ts_doors.sounds.wood)
ts_doors.register_door("ethereal:frost_wood", "Frost", "frost_wood.png", 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", "mushroom_trunk.png", 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", "moretrees_palm_wood.png", 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", "redwood_wood.png", 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", "ethereal_sakura_wood.png", 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", "scorched_tree.png", 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", "willow_wood.png", 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", "yellow_wood.png", 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", "crystal_block.png", ts_doors.sounds.metal, "ethereal:crystal_ingot") ts_doors.register_door("ethereal:crystal_block", "Crystal", nil, ts_doors.sounds.metal, "ethereal:crystal_ingot")
end end
ts_doors.register_door("default:bronzeblock", "Bronze", "default_bronze_block.png", ts_doors.sounds.metal, "default:bronze_ingot") ts_doors.register_door("default:bronzeblock", "Bronze", nil, 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:copperblock", "Copper", nil, 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:diamondblock", "Diamond", nil, 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:goldblock", "Gold", nil, 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:steelblock", "Steel", nil, ts_doors.sounds.metal, "default:steel_ingot")
if minetest.get_modpath("moreores") then 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:mithril_block", "Mithril", nil, 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:silver_block", "Silver", nil, 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:tin_block", "Tin", nil, ts_doors.sounds.metal, "moreores:tin_ingot")
end end
if minetest.get_modpath("technic") then 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:carbon_steel_block", "Carbon Steel", nil, 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:cast_iron_block", "Cast Iron", nil, 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:chromium_block", "Chromium", nil, 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:lead_block", "Lead", nil, 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:stainless_steel_block", "Stainless Steel", nil, 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:zinc_block", "Zinc", nil, 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:blast_resistant_concrete", "Blast Resistant Concrete", nil, ts_doors.sounds.metal)
end end
if minetest.get_modpath("basic_materials") then 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:brass_block", "Brass", nil, 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:concrete_block", "Concrete", nil, ts_doors.sounds.metal)
ts_doors.register_alias("technic:brass_block", "basic_materials:brass_block") ts_doors.register_alias("technic:brass_block", "basic_materials:brass_block")
ts_doors.register_alias("technic:concrete", "basic_materials:concrete_block") ts_doors.register_alias("technic:concrete", "basic_materials:concrete_block")
end end

View File

@ -7,7 +7,7 @@
-- \/ \/ \/ \/ \/ \/ -- -- \/ \/ \/ \/ \/ \/ --
-- -- -- --
-- Orginally written/created by Pithydon/Pithy -- -- Orginally written/created by Pithydon/Pithy --
-- Version 5.3.0.1 -- -- Version 5.4.0.1 --
-- first 3 numbers version of minetest created for, -- -- first 3 numbers version of minetest created for, --
-- last digit mod version for MT version -- -- last digit mod version for MT version --
------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------

View File

@ -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 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: 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 And of course the Coredevs and Celeron55 for designing/keeping the engine running

View File

@ -15,13 +15,6 @@ minetest.override_item("default:apple", {
leafdecay = 3, leafdecay_drop = 1} 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 --= Aliases
-- Banana -- Banana

View File

@ -28,11 +28,10 @@ minetest.register_craftitem("farming:barley", {
-- flour -- flour
minetest.register_craft({ minetest.register_craft({
type = "shapeless",
output = "farming:flour", output = "farming:flour",
recipe = { recipe = {
"farming:barley", "farming:barley", "farming:barley", {"farming:barley", "farming:barley", "farming:barley"},
"farming:barley", "farming:mortar_pestle" {"farming:barley", "farming:mortar_pestle", ""}
}, },
replacements = {{"group:food_mortar_pestle", "farming:mortar_pestle"}} replacements = {{"group:food_mortar_pestle", "farming:mortar_pestle"}}
}) })

View File

@ -81,9 +81,7 @@ minetest.register_craftitem("farming:beans", {
-- beans can be used for green dye -- beans can be used for green dye
minetest.register_craft({ minetest.register_craft({
output = "dye:green", output = "dye:green",
recipe = { recipe = {{"farming:beans"}}
{"farming:beans"}
}
}) })
-- beanpole -- beanpole

View File

@ -21,20 +21,17 @@ minetest.register_craftitem("farming:beetroot_soup", {
}) })
minetest.register_craft({ minetest.register_craft({
type = "shapeless",
output = "farming:beetroot_soup", output = "farming:beetroot_soup",
recipe = { recipe = {
"group:food_beetroot", "group:food_beetroot", {"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_bowl"
} }
}) })
-- red dye -- red dye
minetest.register_craft({ minetest.register_craft({
type = "shapeless",
output = "dye:red", output = "dye:red",
recipe = {"group:food_beetroot"} recipe = {{"group:food_beetroot"}}
}) })
local def = { local def = {

View File

@ -36,10 +36,9 @@ minetest.register_craftitem("farming:blueberry_pie", {
minetest.register_craft({ minetest.register_craft({
output = "farming:blueberry_pie", output = "farming:blueberry_pie",
type = "shapeless",
recipe = { recipe = {
"group:food_flour", "group:food_sugar", {"group:food_flour", "group:food_sugar", "group:food_blueberries"},
"group:food_blueberries", "group:food_baking_tray" {"group:food_baking_tray", "", ""}
}, },
replacements = {{"group:food_baking_tray", "farming:baking_tray"}} replacements = {{"group:food_baking_tray", "farming:baking_tray"}}
}) })
@ -79,7 +78,7 @@ def.drop = {
items = { items = {
{items = {"farming:blueberries 2"}, rarity = 1}, {items = {"farming:blueberries 2"}, rarity = 1},
{items = {"farming:blueberries"}, rarity = 2}, {items = {"farming:blueberries"}, rarity = 2},
{items = {"farming:blueberries"}, rarity = 3}, {items = {"farming:blueberries"}, rarity = 3}
} }
} }
minetest.register_node("farming:blueberry_4", table.copy(def)) minetest.register_node("farming:blueberry_4", table.copy(def))

View File

@ -27,9 +27,10 @@ minetest.register_craftitem("farming:carrot_juice", {
minetest.register_craft({ minetest.register_craft({
output = "farming:carrot_juice", output = "farming:carrot_juice",
type = "shapeless",
recipe = { recipe = {
"vessels:drinking_glass", "group:food_carrot", "farming:juicer" {"group:food_carrot"},
{"farming:juicer"},
{"vessels:drinking_glass"}
}, },
replacements = { replacements = {
{"group:food_juicer", "farming:juicer"} {"group:food_juicer", "farming:juicer"}

View File

@ -20,20 +20,17 @@ minetest.register_craftitem("farming:chili_bowl", {
}) })
minetest.register_craft({ minetest.register_craft({
type = "shapeless",
output = "farming:chili_bowl", output = "farming:chili_bowl",
recipe = { recipe = {
"group:food_chili_pepper", "group:food_barley", {"group:food_chili_pepper", "group:food_rice", "group:food_tomato"},
"group:food_tomato", "group:food_beans", "group:food_bowl" {"group:food_beans", "group:food_bowl", ""}
} }
}) })
-- chili can be used for red dye -- chili can be used for red dye
minetest.register_craft({ minetest.register_craft({
output = "dye:red", output = "dye:red",
recipe = { recipe = {{"farming:chili_pepper"}}
{"farming:chili_pepper"}
}
}) })
-- chili definition -- chili definition

View File

@ -75,9 +75,7 @@ minetest.register_craftitem("farming:cocoa_beans", {
minetest.register_craft( { minetest.register_craft( {
output = "dye:brown 2", output = "dye:brown 2",
recipe = { recipe = {{"farming:cocoa_beans"}}
{ "farming:cocoa_beans" }
}
}) })
-- chocolate cookie -- chocolate cookie
@ -128,9 +126,7 @@ minetest.register_craft({
minetest.register_craft({ minetest.register_craft({
output = "farming:chocolate_dark 9", output = "farming:chocolate_dark 9",
recipe = { recipe = {{"farming:chocolate_block"}}
{"farming:chocolate_block"}
}
}) })
-- cocoa definition -- cocoa definition

View File

@ -34,10 +34,10 @@ minetest.register_alias("farming:drinking_cup", "vessels:drinking_glass")
minetest.register_craft( { minetest.register_craft( {
output = "farming:coffee_cup", output = "farming:coffee_cup",
type = "shapeless",
recipe = { recipe = {
"vessels:drinking_glass", "group:food_coffee", {"group:food_saucepan", "group:food_coffee", "group:water_bucket"},
"group:water_bucket", "group:food_saucepan"}, {"", "vessels:drinking_glass", ""}
},
replacements = { replacements = {
{"group:water_bucket", "bucket:bucket_empty"}, {"group:water_bucket", "bucket:bucket_empty"},
{"group:food_saucepan", "farming:saucepan"} {"group:food_saucepan", "farming:saucepan"}
@ -47,10 +47,10 @@ minetest.register_craft( {
if minetest.get_modpath("bucket_wooden") then if minetest.get_modpath("bucket_wooden") then
minetest.register_craft( { minetest.register_craft( {
output = "farming:coffee_cup", output = "farming:coffee_cup",
type = "shapeless",
recipe = { recipe = {
"vessels:drinking_glass", "group:food_coffee", {"group:food_saucepan", "group:food_coffee", "group:water_bucket_wooden"},
"group:water_bucket_wooden", "group:food_saucepan"}, {"", "vessels:drinking_glass", ""}
},
replacements = { replacements = {
{"group:water_bucket_wooden", "bucket_wooden:bucket_empty"}, {"group:water_bucket_wooden", "bucket_wooden:bucket_empty"},
{"group:food_saucepan", "farming:saucepan"} {"group:food_saucepan", "farming:saucepan"}

View File

@ -47,7 +47,7 @@ minetest.register_craft({
}, },
replacements = { replacements = {
{"group:food_mortar_pestle", "farming:mortar_pestle"}, {"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( { minetest.register_craft( {
output = "farming:bottle_ethanol", output = "farming:bottle_ethanol",
recipe = { 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", "vessels:glass_bottle", "group:food_corn"},
{ "group:food_corn", "group:food_corn", "group:food_corn"} {"group:food_corn", "group:food_corn", "group:food_corn"}
} }
}) })
@ -82,7 +82,7 @@ minetest.register_craft({
type = "fuel", type = "fuel",
recipe = "farming:bottle_ethanol", recipe = "farming:bottle_ethanol",
burntime = 80, burntime = 80,
replacements = {{ "farming:bottle_ethanol", "vessels:glass_bottle"}} replacements = {{"farming:bottle_ethanol", "vessels:glass_bottle"}}
}) })
-- corn definition -- corn definition

View File

@ -76,9 +76,7 @@ minetest.register_craftitem("farming:grapes", {
-- grapes can be used for violet dye -- grapes can be used for violet dye
minetest.register_craft({ minetest.register_craft({
output = "dye:violet", output = "dye:violet",
recipe = { recipe = {{"farming:grapes"}}
{"farming:grapes"}
}
}) })
-- trellis -- trellis

View File

@ -65,7 +65,7 @@ minetest.register_craft({
type = "fuel", type = "fuel",
recipe = "farming:hemp_oil", recipe = "farming:hemp_oil",
burntime = 20, burntime = 20,
replacements = {{ "farming:hemp_oil", "vessels:glass_bottle"}} replacements = {{"farming:hemp_oil", "vessels:glass_bottle"}}
}) })
-- hemp fibre -- hemp fibre

View File

@ -48,7 +48,7 @@ def.groups.growing = nil
def.drop = { def.drop = {
items = { items = {
{items = {'farming:lettuce 2'}, rarity = 1}, {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)) minetest.register_node("farming:lettuce_5", table.copy(def))

View File

@ -21,9 +21,8 @@ minetest.register_craft({
}) })
minetest.register_craft({ minetest.register_craft({
type = "shapeless",
output = "farming:melon_slice 4", 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"}} 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)) minetest.register_node("farming:melon_7", table.copy(def))
-- stage 8 (final) -- stage 8 (final)
def.drawtype = "nodebox" minetest.register_node("farming:melon_8", {
def.description = S("Melon") description = S("Melon"),
def.tiles = { tiles = {
"farming_melon_top.png", "farming_melon_bottom.png", "farming_melon_side.png" "farming_melon_top.png",
} "farming_melon_bottom.png",
def.selection_box = {-.5, -.5, -.5, .5, .5, .5} "farming_melon_side.png"
def.walkable = true },
def.buildable_to = false groups = {
def.paramtype2 = "facedir" food_melon = 1, snappy = 2, oddly_breakable_by_hand = 1,
def.groups = { flammable = 2, plant = 1
food_melon = 1, snappy = 2, oddly_breakable_by_hand = 1, },
flammable = 2, plant = 1 drop = "farming:melon_8",
} sounds = default.node_sound_wood_defaults(),
def.drop = "farming:melon_8" paramtype2 = "facedir",
def.on_place = minetest.rotate_node on_place = minetest.rotate_node
minetest.register_node("farming:melon_8", table.copy(def)) })
-- add to registered_plants -- add to registered_plants
farming.registered_plants["farming:melon"] = { farming.registered_plants["farming:melon"] = {

View File

@ -29,11 +29,9 @@ minetest.register_craftitem("farming:mint_tea", {
minetest.register_craft({ minetest.register_craft({
output = "farming:mint_tea", output = "farming:mint_tea",
type = "shapeless",
recipe = { recipe = {
"vessels:drinking_glass", "group:food_mint", {"group:food_mint", "group:food_mint", "group:food_mint"},
"group:food_mint", "group:food_mint", {"group:water_bucket", "farming:juicer", "vessels:drinking_glass"}
"farming:juicer", "group:water_bucket"
}, },
replacements = { replacements = {
{"group:food_juicer", "farming:juicer"}, {"group:food_juicer", "farming:juicer"},
@ -44,11 +42,9 @@ minetest.register_craft({
if minetest.get_modpath("bucket_wooden") then if minetest.get_modpath("bucket_wooden") then
minetest.register_craft({ minetest.register_craft({
output = "farming:mint_tea", output = "farming:mint_tea",
type = "shapeless",
recipe = { recipe = {
"vessels:drinking_glass", "group:food_mint", {"group:food_mint", "group:food_mint", "group:food_mint"},
"group:food_mint", "group:food_mint", {"group:water_bucket_wooden", "farming:juicer", "vessels:drinking_glass"}
"farming:juicer", "group:water_bucket_wooden"
}, },
replacements = { replacements = {
{"group:food_juicer", "farming:juicer"}, {"group:food_juicer", "farming:juicer"},
@ -92,7 +88,7 @@ def.drop = {
{items = {"farming:mint_leaf 2"}, rarity = 1}, {items = {"farming:mint_leaf 2"}, rarity = 1},
{items = {"farming:mint_leaf 2"}, rarity = 2}, {items = {"farming:mint_leaf 2"}, rarity = 2},
{items = {"farming:seed_mint 1"}, rarity = 1}, {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)) minetest.register_node("farming:mint_4", table.copy(def))

View File

@ -27,12 +27,11 @@ minetest.register_craftitem("farming:onion_soup", {
}) })
minetest.register_craft({ minetest.register_craft({
type = "shapeless",
output = "farming:onion_soup", output = "farming:onion_soup",
recipe = { recipe = {
"group:food_onion", "group:food_onion", "group:food_pot", {"group:food_onion", "group:food_onion", "group:food_onion"},
"group:food_onion", "group:food_onion", {"group:food_onion", "group:food_pot", "group:food_onion"},
"group:food_onion", "group:food_onion", "group:food_bowl" {"", "group:food_bowl", ""}
}, },
replacements = {{"farming:pot", "farming:pot"}} replacements = {{"farming:pot", "farming:pot"}}
}) })
@ -81,7 +80,7 @@ def.drop = {
{items = {"farming:onion"}, rarity = 1}, {items = {"farming:onion"}, rarity = 1},
{items = {"farming:onion"}, rarity = 2}, {items = {"farming:onion"}, rarity = 2},
{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)) minetest.register_node("farming:onion_5", table.copy(def))

View File

@ -21,9 +21,8 @@ minetest.register_craftitem("farming:peas", {
}) })
minetest.register_craft({ minetest.register_craft({
type = "shapeless",
output = "farming:peas", output = "farming:peas",
recipe = {"farming:pea_pod"} recipe = {{"farming:pea_pod"}}
}) })
-- pea soup -- pea soup
@ -35,9 +34,12 @@ minetest.register_craftitem("farming:pea_soup", {
}) })
minetest.register_craft({ minetest.register_craft({
type = "shapeless",
output = "farming:pea_soup", 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 = { local def = {

View File

@ -30,7 +30,7 @@ minetest.register_craftitem("farming:pepper_yellow", {
description = S("Yellow Pepper"), description = S("Yellow Pepper"),
inventory_image = "crops_pepper_yellow.png", inventory_image = "crops_pepper_yellow.png",
on_use = minetest.item_eat(3), on_use = minetest.item_eat(3),
groups = {food_pepper = 1, flammable = 3}, groups = {food_pepper = 1, flammable = 3}
}) })
-- red pepper -- red pepper
@ -38,13 +38,12 @@ minetest.register_craftitem("farming:pepper_red", {
description = S("Red Pepper"), description = S("Red Pepper"),
inventory_image = "crops_pepper_red.png", inventory_image = "crops_pepper_red.png",
on_use = minetest.item_eat(4), on_use = minetest.item_eat(4),
groups = {food_pepper = 1, flammable = 3}, groups = {food_pepper = 1, flammable = 3}
}) })
minetest.register_craft({ minetest.register_craft({
type = "shapeless",
output = "farming:peppercorn", output = "farming:peppercorn",
recipe = {"group:food_pepper"} recipe = {{"group:food_pepper"}}
}) })
-- ground pepper -- ground pepper
@ -69,8 +68,11 @@ minetest.register_node("farming:pepper_ground", {
minetest.register_craft( { minetest.register_craft( {
output = "farming:pepper_ground", output = "farming:pepper_ground",
type = "shapeless", recipe = {
recipe = {"group:food_peppercorn", "vessels:glass_bottle", "farming:mortar_pestle"}, {"group:food_peppercorn"},
{"farming:mortar_pestle"},
{"vessels:glass_bottle"}
},
replacements = {{"group:food_mortar_pestle", "farming:mortar_pestle"}} 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.tiles = {"crops_pepper_plant_6.png"}
def.drop = { def.drop = {
max_items = 2, items = { max_items = 2, items = {
{items = {'farming:pepper_yellow 2'}, rarity = 1}, {items = {"farming:pepper_yellow 2"}, rarity = 1},
{items = {'farming:pepper_yellow'}, rarity = 2}, {items = {"farming:pepper_yellow"}, rarity = 2},
{items = {'farming:pepper_yellow'}, rarity = 3}, {items = {"farming:pepper_yellow"}, rarity = 3}
} }
} }
minetest.register_node("farming:pepper_6", table.copy(def)) 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.groups.growing = nil
def.drop = { def.drop = {
max_items = 2, items = { max_items = 2, items = {
{items = {'farming:pepper_red 2'}, rarity = 1}, {items = {"farming:pepper_red 2"}, rarity = 1},
{items = {'farming:pepper_red'}, rarity = 2}, {items = {"farming:pepper_red"}, rarity = 2},
{items = {'farming:pepper_red'}, rarity = 3}, {items = {"farming:pepper_red"}, rarity = 3}
} }
} }
minetest.register_node("farming:pepper_7", table.copy(def)) minetest.register_node("farming:pepper_7", table.copy(def))

View File

@ -38,8 +38,7 @@ minetest.register_craftitem("farming:pineapple_ring", {
minetest.register_craft( { minetest.register_craft( {
output = "farming:pineapple_ring 5", output = "farming:pineapple_ring 5",
type = "shapeless", recipe = {{"group:food_pineapple"}},
recipe = {"group:food_pineapple"},
replacements = {{"farming:pineapple", "farming:pineapple_top"}} replacements = {{"farming:pineapple", "farming:pineapple_top"}}
}) })
@ -53,11 +52,12 @@ minetest.register_craftitem("farming:pineapple_juice", {
minetest.register_craft({ minetest.register_craft({
output = "farming:pineapple_juice", output = "farming:pineapple_juice",
type = "shapeless",
recipe = { recipe = {
"vessels:drinking_glass", "group:food_pineapple_ring", {"group:food_pineapple_ring", "group:food_pineapple_ring",
"group:food_pineapple_ring", "group:food_pineapple_ring", "group:food_pineapple_ring"},
"farming:juicer"}, {"", "farming:juicer", ""},
{"", "vessels:drinking_glass", ""}
},
replacements = { replacements = {
{"group:food_juicer", "farming:juicer"} {"group:food_juicer", "farming:juicer"}
} }
@ -65,10 +65,10 @@ minetest.register_craft({
minetest.register_craft({ minetest.register_craft({
output = "farming:pineapple_juice 2", output = "farming:pineapple_juice 2",
type = "shapeless",
recipe = { recipe = {
"vessels:drinking_glass", "vessels:drinking_glass", {"group:food_pineapple", ""},
"group:food_pineapple", "farming:juicer" {"farming:juicer", ""},
{"vessels:drinking_glass", "vessels:drinking_glass"}
}, },
replacements = { replacements = {
{"group:food_juicer", "farming:juicer"} {"group:food_juicer", "farming:juicer"}

View File

@ -25,9 +25,8 @@ minetest.register_craft({
}) })
minetest.register_craft({ minetest.register_craft({
type = "shapeless",
output = "farming:pumpkin_slice 4", output = "farming:pumpkin_slice 4",
recipe = {"farming:pumpkin", "farming:cutting_board"}, recipe = {{"farming:cutting_board", "farming:pumpkin"}},
replacements = {{"farming:cutting_board", "farming:cutting_board"}} replacements = {{"farming:cutting_board", "farming:cutting_board"}}
}) })
@ -122,8 +121,9 @@ minetest.register_craftitem("farming:pumpkin_dough", {
minetest.register_craft({ minetest.register_craft({
output = "farming:pumpkin_dough", output = "farming:pumpkin_dough",
type = "shapeless", recipe = {
recipe = {"group:food_flour", "group:food_pumpkin_slice", "group:food_pumpkin_slice"} {"group:food_pumpkin_slice", "group:food_flour", "group:food_pumpkin_slice"}
}
}) })
minetest.register_craft({ minetest.register_craft({
@ -183,7 +183,7 @@ minetest.register_node("farming:pumpkin_8", {
description = S("Pumpkin"), description = S("Pumpkin"),
tiles = { tiles = {
"farming_pumpkin_top.png", "farming_pumpkin_top.png",
"farming_pumpkin_top.png", "farming_pumpkin_bottom.png",
"farming_pumpkin_side.png" "farming_pumpkin_side.png"
}, },
groups = { groups = {
@ -191,7 +191,9 @@ minetest.register_node("farming:pumpkin_8", {
flammable = 2, plant = 1 flammable = 2, plant = 1
}, },
drop = "farming:pumpkin_8", 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") minetest.register_alias("farming:pumpkin", "farming:pumpkin_8")

View File

@ -45,7 +45,7 @@ local def = {
}, },
sounds = default.node_sound_leaves_defaults(), sounds = default.node_sound_leaves_defaults(),
minlight = 10, minlight = 10,
maxlight = 12, maxlight = 12
} }
-- stage 1 -- stage 1

View File

@ -19,11 +19,10 @@ minetest.override_item("farming:rye", {
}) })
minetest.register_craft({ minetest.register_craft({
type = "shapeless",
output = "farming:flour", output = "farming:flour",
recipe = { recipe = {
"farming:rye", "farming:rye", "farming:rye", "farming:rye", {"farming:rye", "farming:rye", "farming:rye"},
"farming:mortar_pestle" {"farming:rye", "farming:mortar_pestle", ""}
}, },
replacements = {{"group:food_mortar_pestle", "farming:mortar_pestle"}} replacements = {{"group:food_mortar_pestle", "farming:mortar_pestle"}}
}) })
@ -44,11 +43,10 @@ minetest.override_item("farming:oat", {
}) })
minetest.register_craft({ minetest.register_craft({
type = "shapeless",
output = "farming:flour", output = "farming:flour",
recipe = { recipe = {
"farming:oat", "farming:oat", "farming:oat", "farming:oat", {"farming:oat", "farming:oat", "farming:oat"},
"farming:mortar_pestle" {"farming:oat", "farming:mortar_pestle", ""}
}, },
replacements = {{"group:food_mortar_pestle", "farming:mortar_pestle"}} replacements = {{"group:food_mortar_pestle", "farming:mortar_pestle"}}
}) })
@ -82,11 +80,10 @@ minetest.register_craftitem("farming:rice_flour", {
}) })
minetest.register_craft({ minetest.register_craft({
type = "shapeless",
output = "farming:rice_flour", output = "farming:rice_flour",
recipe = { recipe = {
"farming:rice", "farming:rice", "farming:rice", "farming:rice", {"farming:rice", "farming:rice", "farming:rice"},
"farming:mortar_pestle" {"farming:rice", "farming:mortar_pestle", ""}
}, },
replacements = {{"group:food_mortar_pestle", "farming:mortar_pestle"}} replacements = {{"group:food_mortar_pestle", "farming:mortar_pestle"}}
}) })

View File

@ -19,9 +19,8 @@ minetest.register_craftitem("farming:soy_beans", {
}) })
minetest.register_craft({ minetest.register_craft({
type = "shapeless",
output = "farming:soy_beans", output = "farming:soy_beans",
recipe = {"farming:soy_pod"} recipe = {{"farming:soy_pod"}}
}) })
-- soy sauce -- soy sauce
@ -43,15 +42,26 @@ minetest.register_node("farming:soy_sauce", {
sounds = default.node_sound_glass_defaults() 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( { minetest.register_craft( {
type = "shapeless",
output = "farming:soy_sauce", output = "farming:soy_sauce",
recipe = { recipe = {
"group:food_soy", "group:food_soy", "group:food_juicer", {"group:food_soy", "group:food_salt", "group:food_soy"},
"bucket:bucket_river_water", "vessels:glass_bottle", "group:food_salt" {"", "group:food_juicer", ""},
{"", bucket_water, "vessels:glass_bottle"}
}, },
replacements = { replacements = {
{"bucket:bucket_river_water", "bucket:bucket_empty"}, {bucket_water, "bucket:bucket_empty"},
{"group:food_juicer", "farming:juicer"} {"group:food_juicer", "farming:juicer"}
} }
}) })
@ -78,11 +88,10 @@ minetest.register_node("farming:soy_milk", {
}) })
minetest.register_craft( { minetest.register_craft( {
type = "shapeless",
output = "farming:soy_milk", output = "farming:soy_milk",
recipe = { recipe = {
"group:food_soy", "group:food_soy", "group:food_soy", {"group:food_soy", "group:food_soy", "group:food_soy"},
"farming:vanilla_extract", "bucket:bucket_water", "vessels:drinking_glass" {"farming:vanilla_extract", "bucket:bucket_water", "vessels:drinking_glass"}
}, },
replacements = { replacements = {
{"bucket:bucket_water", "bucket:bucket_empty"}, {"bucket:bucket_water", "bucket:bucket_empty"},
@ -100,10 +109,9 @@ minetest.register_craftitem("farming:tofu", {
minetest.register_craft({ minetest.register_craft({
output = "farming:tofu", output = "farming:tofu",
type = "shapeless",
recipe = { recipe = {
"farming:baking_tray", "group:food_soy", "group:food_soy", {"farming:baking_tray", "group:food_soy", "group:food_soy"},
"group:food_soy", "group:food_soy", "group:food_soy", {"group:food_soy", "group:food_soy", "group:food_soy"}
}, },
replacements = {{"farming:baking_tray", "farming:baking_tray"}} 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.tiles = {"farming_soy_5.png"}
def.drop = { def.drop = {
max_items = 1, items = { 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)) 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.tiles = {"farming_soy_6.png"}
def.drop = { def.drop = {
max_items = 3, items = { max_items = 3, items = {
{items = {'farming:soy_pod'}, rarity = 1}, {items = {"farming:soy_pod"}, rarity = 1},
{items = {'farming:soy_pod'}, rarity = 2}, {items = {"farming:soy_pod"}, rarity = 2},
{items = {'farming:soy_pod'}, rarity = 3}, {items = {"farming:soy_pod"}, rarity = 3},
} }
} }
minetest.register_node("farming:soy_6", table.copy(def)) minetest.register_node("farming:soy_6", table.copy(def))
@ -184,11 +192,11 @@ def.tiles = {"farming_soy_7.png"}
def.groups.growing = nil def.groups.growing = nil
def.drop = { def.drop = {
max_items = 5, items = { max_items = 5, items = {
{items = {'farming:soy_pod'}, rarity = 1}, {items = {"farming:soy_pod"}, rarity = 1},
{items = {'farming:soy_pod'}, rarity = 2}, {items = {"farming:soy_pod"}, rarity = 2},
{items = {'farming:soy_pod'}, rarity = 3}, {items = {"farming:soy_pod"}, rarity = 3},
{items = {'farming:soy_pod'}, rarity = 4}, {items = {"farming:soy_pod"}, rarity = 4},
{items = {'farming:soy_pod'}, rarity = 5} {items = {"farming:soy_pod"}, rarity = 5}
} }
} }
minetest.register_node("farming:soy_7", table.copy(def)) minetest.register_node("farming:soy_7", table.copy(def))

View File

@ -17,6 +17,23 @@ minetest.register_craftitem("farming:tomato", {
on_use = minetest.item_eat(4) 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 -- tomato definition
local def = { local def = {
drawtype = "plantlike", drawtype = "plantlike",

View File

@ -8,7 +8,7 @@ minetest.register_craftitem("farming:vanilla", {
on_place = function(itemstack, placer, pointed_thing) on_place = function(itemstack, placer, pointed_thing)
return farming.place_seed(itemstack, placer, pointed_thing, "farming:vanilla_1") return farming.place_seed(itemstack, placer, pointed_thing, "farming:vanilla_1")
end, end,
on_use = minetest.item_eat(1), on_use = minetest.item_eat(1)
}) })
-- crop definition -- crop definition
@ -49,8 +49,8 @@ minetest.register_node("farming:vanilla_extract", {
minetest.register_craft( { minetest.register_craft( {
output = "farming:vanilla_extract", output = "farming:vanilla_extract",
recipe = { recipe = {
{ "group:food_vanilla", "group:food_vanilla", "group:food_vanilla"}, {"group:food_vanilla", "group:food_vanilla", "group:food_vanilla"},
{ "group:food_vanilla", "farming:bottle_ethanol", "bucket:bucket_water"}, {"group:food_vanilla", "farming:bottle_ethanol", "bucket:bucket_water"},
}, },
replacements = { replacements = {
{"bucket:bucket_water", "bucket:bucket_empty"}, {"bucket:bucket_water", "bucket:bucket_empty"},
@ -61,7 +61,7 @@ minetest.register_craft({
type = "fuel", type = "fuel",
recipe = "farming:vanilla_extract", recipe = "farming:vanilla_extract",
burntime = 25, burntime = 25,
replacements = {{ "farming:vanilla_extract", "vessels:glass_bottle" }} replacements = {{"farming:vanilla_extract", "vessels:glass_bottle"}}
}) })
-- stage 1 -- stage 1
@ -92,9 +92,9 @@ minetest.register_node("farming:vanilla_6", table.copy(def))
def.tiles = {"farming_vanilla_7.png"} def.tiles = {"farming_vanilla_7.png"}
def.drop = { def.drop = {
items = { items = {
{items = {'farming:vanilla'}, rarity = 1}, {items = {"farming:vanilla"}, rarity = 1},
{items = {'farming:vanilla'}, rarity = 2}, {items = {"farming:vanilla"}, rarity = 2},
{items = {'farming:vanilla'}, rarity = 3} {items = {"farming:vanilla"}, rarity = 3}
} }
} }
minetest.register_node("farming:vanilla_7", table.copy(def)) minetest.register_node("farming:vanilla_7", table.copy(def))
@ -104,10 +104,10 @@ def.tiles = {"farming_vanilla_8.png"}
def.groups.growing = nil def.groups.growing = nil
def.drop = { def.drop = {
items = { items = {
{items = {'farming:vanilla 2'}, rarity = 1}, {items = {"farming:vanilla 2"}, rarity = 1},
{items = {'farming:vanilla 2'}, rarity = 2}, {items = {"farming:vanilla 2"}, rarity = 2},
{items = {'farming:vanilla 2'}, rarity = 2}, {items = {"farming:vanilla 2"}, rarity = 2},
{items = {'farming:vanilla 2'}, rarity = 3} {items = {"farming:vanilla 2"}, rarity = 3}
} }
} }
minetest.register_node("farming:vanilla_8", table.copy(def)) minetest.register_node("farming:vanilla_8", table.copy(def))

View File

@ -46,9 +46,7 @@ minetest.register_craft({
minetest.register_craft({ minetest.register_craft({
output = "farming:wheat 3", output = "farming:wheat 3",
recipe = { recipe = {{"farming:straw"}}
{"farming:straw"}
}
}) })
-- check and register stairs -- check and register stairs
@ -80,11 +78,10 @@ minetest.register_craftitem("farming:flour", {
}) })
minetest.register_craft({ minetest.register_craft({
type = "shapeless",
output = "farming:flour", output = "farming:flour",
recipe = { recipe = {
"farming:wheat", "farming:wheat", "farming:wheat", {"farming:wheat", "farming:wheat", "farming:wheat"},
"farming:wheat", "farming:mortar_pestle" {"farming:wheat", "farming:mortar_pestle", ""}
}, },
replacements = {{"group:food_mortar_pestle", "farming:mortar_pestle"}} replacements = {{"group:food_mortar_pestle", "farming:mortar_pestle"}}
}) })
@ -113,9 +110,8 @@ minetest.register_craftitem("farming:bread_slice", {
}) })
minetest.register_craft({ minetest.register_craft({
type = "shapeless",
output = "farming:bread_slice 5", 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"}} replacements = {{"group:food_cutting_board", "farming:cutting_board"}}
}) })

View File

@ -318,7 +318,6 @@ minetest.register_craftitem("farming:apple_pie", {
minetest.register_craft({ minetest.register_craft({
output = "farming:apple_pie", output = "farming:apple_pie",
-- type = "shapeless",
recipe = { recipe = {
{"group:food_flour", "group:food_sugar", "group:food_apple"}, {"group:food_flour", "group:food_sugar", "group:food_apple"},
{"", "group:food_baking_tray", ""} {"", "group:food_baking_tray", ""}
@ -347,9 +346,10 @@ minetest.register_craftitem("farming:cactus_juice", {
minetest.register_craft({ minetest.register_craft({
output = "farming:cactus_juice", output = "farming:cactus_juice",
-- type = "shapeless",
recipe = { recipe = {
{"default:cactus", "farming:juicer", "vessels:drinking_glass"} {"default:cactus"},
{"farming:juicer"},
{"vessels:drinking_glass"}
}, },
replacements = { replacements = {
{"group:food_juicer", "farming:juicer"} {"group:food_juicer", "farming:juicer"}
@ -366,7 +366,6 @@ minetest.register_craftitem("farming:pasta", {
minetest.register_craft({ minetest.register_craft({
output = "farming:pasta", output = "farming:pasta",
-- type = "shapeless",
recipe = { recipe = {
{"group:food_flour", "group:food_butter", "group:food_mixing_bowl"} {"group:food_flour", "group:food_butter", "group:food_mixing_bowl"}
}, },
@ -375,7 +374,6 @@ minetest.register_craft({
minetest.register_craft({ minetest.register_craft({
output = "farming:pasta", output = "farming:pasta",
-- type = "shapeless",
recipe = { recipe = {
{"group:food_flour", "group:food_oil", "group:food_mixing_bowl"} {"group:food_flour", "group:food_oil", "group:food_mixing_bowl"}
}, },
@ -395,7 +393,6 @@ minetest.register_craftitem("farming:spaghetti", {
minetest.register_craft({ minetest.register_craft({
output = "farming:spaghetti", output = "farming:spaghetti",
-- type = "shapeless",
recipe = { recipe = {
{"group:food_pasta", "group:food_saucepan", "group:food_tomato"}, {"group:food_pasta", "group:food_saucepan", "group:food_tomato"},
{"group:food_garlic_clove", "group:food_garlic_clove", ""} {"group:food_garlic_clove", "group:food_garlic_clove", ""}
@ -413,7 +410,6 @@ minetest.register_craftitem("farming:bibimbap", {
minetest.register_craft({ minetest.register_craft({
output = "farming:bibimbap", output = "farming:bibimbap",
-- type = "shapeless",
recipe = { recipe = {
{"group:food_skillet", "group:food_bowl", "group:food_egg"}, {"group:food_skillet", "group:food_bowl", "group:food_egg"},
{"group:food_rice", "group:food_chicken_raw", "group:food_cabbage"}, {"group:food_rice", "group:food_chicken_raw", "group:food_cabbage"},
@ -442,7 +438,6 @@ minetest.register_craftitem("farming:burger", {
}) })
minetest.register_craft({ minetest.register_craft({
-- type = "shapeless",
output = "farming:burger", output = "farming:burger",
recipe = { recipe = {
{"farming:bread", "group:food_meat", "group:food_cheese"}, {"farming:bread", "group:food_meat", "group:food_cheese"},
@ -550,7 +545,6 @@ minetest.register_craftitem("farming:flan", {
}) })
minetest.register_craft({ minetest.register_craft({
-- type = "shapeless",
output = "farming:flan", output = "farming:flan",
recipe = { recipe = {
{"group:food_sugar", "group:food_milk", "farming:caramel"}, {"group:food_sugar", "group:food_milk", "farming:caramel"},
@ -574,7 +568,6 @@ minetest.register_craftitem("farming:cheese_vegan", {
minetest.register_craft({ minetest.register_craft({
-- type = "shapeless",
output = "farming:cheese_vegan", output = "farming:cheese_vegan",
recipe = { recipe = {
{"farming:soy_milk", "farming:soy_milk", "farming:soy_milk"}, {"farming:soy_milk", "farming:soy_milk", "farming:soy_milk"},
@ -589,7 +582,6 @@ minetest.register_craft({
}) })
minetest.register_craft({ minetest.register_craft({
-- type = "shapeless",
output = "farming:cheese_vegan", output = "farming:cheese_vegan",
recipe = { recipe = {
{"farming:soy_milk", "farming:soy_milk", "farming:soy_milk"}, {"farming:soy_milk", "farming:soy_milk", "farming:soy_milk"},
@ -608,14 +600,14 @@ minetest.register_craftitem("farming:onigiri", {
description = S("Onirigi"), description = S("Onirigi"),
inventory_image = "farming_onigiri.png", inventory_image = "farming_onigiri.png",
on_use = minetest.item_eat(2), on_use = minetest.item_eat(2),
groups = {flammable = 2}, groups = {flammable = 2}
}) })
minetest.register_craft({ minetest.register_craft({
type = "shapeless",
output = "farming:onigiri", output = "farming:onigiri",
recipe = { 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"), description = S("Gyoza"),
inventory_image = "farming_gyoza.png", inventory_image = "farming_gyoza.png",
on_use = minetest.item_eat(4), on_use = minetest.item_eat(4),
groups = {flammable = 2}, groups = {flammable = 2}
}) })
minetest.register_craft({ minetest.register_craft({
type = "shapeless",
output = "farming:gyoza 4", output = "farming:gyoza 4",
recipe = { recipe = {
"group:food_cabbage", "group:food_garlic_clove", "group:food_onion", {"group:food_cabbage", "group:food_garlic_clove", "group:food_onion"},
"group:food_meat_raw", "group:food_salt", "group:food_skillet", {"group:food_meat_raw", "group:food_salt", "group:food_flour"},
"group:food_flour" {"", "group:food_skillet", ""}
}, },
replacements = { replacements = {
{"group:food_skillet", "farming:skillet"} {"group:food_skillet", "farming:skillet"}
@ -647,15 +639,15 @@ minetest.register_craftitem("farming:mochi", {
description = S("Mochi"), description = S("Mochi"),
inventory_image = "farming_mochi.png", inventory_image = "farming_mochi.png",
on_use = minetest.item_eat(3), on_use = minetest.item_eat(3),
groups = {flammable = 2}, groups = {flammable = 2}
}) })
minetest.register_craft({ minetest.register_craft({
type = "shapeless",
output = "farming:mochi", output = "farming:mochi",
recipe = { recipe = {
"group:food_mortar_pestle", "group:food_rice", "group:food_rice", {"group:food_rice", "group:food_sugar", "group:food_rice"},
"group:food_sugar", "bucket:bucket_river_water" {"", "group:food_mortar_pestle", ""},
{"", "bucket:bucket_river_water", ""}
}, },
replacements = { replacements = {
{"group:food_mortar_pestle", "farming:mortar_pestle"}, {"group:food_mortar_pestle", "farming:mortar_pestle"},

View File

@ -361,7 +361,7 @@ farming.add_to_scythe_not_drops = function(item)
end end
minetest.register_tool("farming:scythe_mithril", { 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", inventory_image = "farming_scythe_mithril.png",
sound = {breaks = "default_tool_breaks"}, sound = {breaks = "default_tool_breaks"},

View File

@ -169,3 +169,7 @@ Created by Felfa (CC0)
Created by gorlock (CC0) Created by gorlock (CC0)
farming_salt_crystal.png farming_salt_crystal.png
Created by sirrobzeroone (CC0)
farming_gyoza.png
farming_pineapple_ring.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 603 B

After

Width:  |  Height:  |  Size: 266 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 114 B

After

Width:  |  Height:  |  Size: 155 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 122 B

After

Width:  |  Height:  |  Size: 172 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 132 B

After

Width:  |  Height:  |  Size: 191 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 174 B

After

Width:  |  Height:  |  Size: 233 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 158 B

After

Width:  |  Height:  |  Size: 253 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 166 B

After

Width:  |  Height:  |  Size: 289 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 164 B

After

Width:  |  Height:  |  Size: 449 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 258 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 161 B

View File

@ -20,7 +20,7 @@ minetest.register_craft({
minetest.register_craft({ minetest.register_craft({
type = "fuel", type = "fuel",
recipe = "farming:bowl", recipe = "farming:bowl",
burntime = 10, burntime = 10
}) })
-- saucepan -- saucepan
@ -155,9 +155,6 @@ minetest.register_craft({
}) })
minetest.register_craft( { minetest.register_craft( {
type = "shapeless",
output = "vessels:glass_fragments", output = "vessels:glass_fragments",
recipe = { recipe = {{"farming:mixing_bowl"}}
"farming:mixing_bowl"
}
}) })

View File

@ -6,7 +6,6 @@ ignore = {
read_globals = { read_globals = {
"minetest", "minetest",
"default",
"armor", "armor",
"skins", "skins",
"awards", "awards",
@ -19,4 +18,6 @@ read_globals = {
globals = { globals = {
"i3", "i3",
"core", "core",
"sfinv",
"unified_inventory",
} }

View File

@ -1,7 +1,10 @@
i3 = {} i3 = {}
local storage = core.get_mod_storage()
local slz, dslz = core.serialize, core.deserialize
local pdata = dslz(storage:get_string "pdata") or {}
-- Caches -- Caches
local pdata = {}
local init_items = {} local init_items = {}
local searches = {} local searches = {}
local recipes_cache = {} 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 damage_enabled = core.settings:get_bool "enable_damage"
local __3darmor, __skinsdb, __awards 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 http = core.request_http_api()
local singleplayer = core.is_singleplayer() local singleplayer = core.is_singleplayer()
@ -37,6 +41,7 @@ local write_json = core.write_json
local get_inv = core.get_inventory local get_inv = core.get_inventory
local chat_send = core.chat_send_player local chat_send = core.chat_send_player
local show_formspec = core.show_formspec local show_formspec = core.show_formspec
local pos_to_string = core.pos_to_string
local check_privs = core.check_player_privs local check_privs = core.check_player_privs
local globalstep = core.register_globalstep local globalstep = core.register_globalstep
local on_shutdown = core.register_on_shutdown 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 translate = minetest.get_translated_string
local on_joinplayer = core.register_on_joinplayer local on_joinplayer = core.register_on_joinplayer
local get_all_recipes = core.get_all_craft_recipes 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_leaveplayer = core.register_on_leaveplayer
local on_mods_loaded = core.register_on_mods_loaded
local get_player_info = core.get_player_information local get_player_info = core.get_player_information
local create_inventory = core.create_detached_inventory local create_inventory = core.create_detached_inventory
local on_receive_fields = core.register_on_player_receive_fields 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 = local pairs, ipairs, next, type, setmetatable, tonum, unpack, select =
pairs, ipairs, next, type, setmetatable, tonumber, 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 MAX_FAVS = 6
local ITEM_BTN_SIZE = 1.1 local ITEM_BTN_SIZE = 1.1
@ -81,14 +86,15 @@ local ITEM_BTN_SIZE = 1.1
local INV_SIZE = 36 local INV_SIZE = 36
local HOTBAR_COUNT = 9 local HOTBAR_COUNT = 9
-- Players data interval
local SAVE_INTERVAL = 600
-- Progressive mode -- Progressive mode
local POLL_FREQ = 0.25 local POLL_FREQ = 0.25
local HUD_TIMER_MAX = 1.5 local HUD_TIMER_MAX = 1.5
local MIN_FORMSPEC_VERSION = 4 local MIN_FORMSPEC_VERSION = 4
local META_SAVES = {"bag_size", "waypoints"}
local BAG_SIZES = { local BAG_SIZES = {
small = INV_SIZE + 3, small = INV_SIZE + 3,
medium = INV_SIZE + 6, medium = INV_SIZE + 6,
@ -468,18 +474,6 @@ local function table_replace(t, val, new)
end end
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 = {} local craft_types = {}
function i3.register_craft_type(name, def) function i3.register_craft_type(name, def)
@ -1249,8 +1243,6 @@ local function select_item(player, name, data, _f)
if not item then if not item then
return return
elseif sub(item, -4) == "_inv" then
item = sub(item, 1, -5)
elseif sub(item, 1, 1) == "_" then elseif sub(item, 1, 1) == "_" then
item = sub(item, 2) item = sub(item, 2)
elseif sub(item, 1, 6) == "group|" then 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) local Y = round((i % ipp - X) / rows + 1, 0)
Y = Y - (Y * (extend and 0.085 or 0.035)) + 0.95 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
end end
@ -1982,7 +1974,7 @@ local function get_award_list(data, fs, ctn_len, yextra, award_list, awards_unlo
end end
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(fmt("box[0,%f;4.9,0.6;#bababa25]", yextra + 1.1))
fs("label", 0, yextra + 0.85, ES"Waypoint name:") fs("label", 0, yextra + 0.85, ES"Waypoint name:")
fs(fmt("field[0.1,%f;4.8,0.6;waypoint_name;;]", yextra + 1.1)) 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("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) 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(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, "") 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("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")) 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) local tp = fmt("waypoint_%u_teleport", i)
fs(fmt("style[%s;fgimg=%s;fgimg_hovered=%s;content_offset=0]", 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() local name = player:get_player_name()
add_subtitle(fs, "player_name", 0, ctn_len, 22, true, ESC(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 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 for i = 1, hearts do
fs("image", heart_x + ((i - 1) * (heart_size + 0.1)), heart_h, fs("image", heart_x + ((i - 1) * (heart_size + 0.1)), heart_h,
heart_size, heart_size, heart_size, heart_size,
(half == 1 and i == floor(hearts)) and PNG.heart_half or PNG.heart) (half == 1 and i == floor(hearts)) and PNG.heart_half or PNG.heart)
end end
else
yoffset = yoffset - 0.5
end end
fs(fmt("list[current_player;craft;%f,%f;3,3;]", 0, yoffset + 1.45)) 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) fs("image", 4.45, yoffset + 3.75, 1, 1, PNG.trash)
end end
local yextra = 5.5 local yextra = damage_enabled and 5.5 or 5
for i, title in ipairs(SUBCAT) do for i, title in ipairs(SUBCAT) do
local btn_name = fmt("btn_%s", title) 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 end
elseif data.subcat == 5 then 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
end end
@ -2254,6 +2252,7 @@ local function make_fs(player, data)
end end
function i3.set_fs(player, _fs) function i3.set_fs(player, _fs)
if not player or player.is_fake_player then return end
local name = player:get_player_name() local name = player:get_player_name()
local data = pdata[name] local data = pdata[name]
if not data then return end if not data then return end
@ -2347,27 +2346,19 @@ end
local function init_data(player, info) local function init_data(player, info)
local name = player:get_player_name() local name = player:get_player_name()
pdata[name] = pdata[name] or {}
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),
}
local data = pdata[name] local data = pdata[name]
local meta = player:get_meta()
for i = 1, #META_SAVES do data.filter = ""
local recover = META_SAVES[i] data.pagenum = 1
data[recover] = dslz(meta:get_string(recover)) data.items = init_items
end 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) after(0, set_fs, player)
end end
@ -2534,7 +2525,7 @@ local function get_inventory_fs(player, data, fs)
local award_list, award_list_nb local award_list, award_list_nb
local awards_unlocked = 0 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 __3darmor and data.subcat == 2 then
if data.scrbar_inv >= max_val 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] scrollbar[%f,0.2;0.2,%f;vertical;scrbar_inv;%u]
scrollbaroptions[arrows=default;thumbsize=0;max=1000] 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)) 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) remove(data.waypoints, id)
elseif action == "teleport" then elseif action == "teleport" then
local pos = waypoint.pos local pos = vec_new(waypoint.pos)
pos.y = pos.y + 0.5 pos.y = pos.y + 0.5
local vel = player:get_velocity()
player:add_velocity(vec_mul(vel, -1))
player:set_pos(pos) player:set_pos(pos)
msg(name, fmt("Teleported to %s", clr("#ff0", waypoint.name))) msg(name, fmt("Teleported to %s", clr("#ff0", waypoint.name)))
elseif action == "refresh" then elseif action == "refresh" then
@ -2679,6 +2673,14 @@ i3.new_tab {
return return
elseif fields.waypoint_add then 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 local waypoint = fields.waypoint_name
if fields.waypoint_name == "" then if fields.waypoint_name == "" then
@ -2686,7 +2688,6 @@ i3.new_tab {
end end
local color = random(0xffffff) local color = random(0xffffff)
local pos = player:get_pos()
local id = player:hud_add { local id = player:hud_add {
hud_elem_type = "waypoint", hud_elem_type = "waypoint",
@ -2746,7 +2747,6 @@ end
if rawget(_G, "skins") then if rawget(_G, "skins") then
__skinsdb = true __skinsdb = true
insert(META_SAVES, "skin_id")
end end
if rawget(_G, "awards") then if rawget(_G, "awards") then
@ -2772,24 +2772,22 @@ if rawget(_G, "awards") then
core.register_on_dieplayer(set_fs) core.register_on_dieplayer(set_fs)
end end
core.register_on_chatcommand(function(name, command, params) core.register_on_chatcommand(function(name)
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
local player = core.get_player_by_name(name) local player = core.get_player_by_name(name)
after(0, set_fs, player) after(0, set_fs, player)
end) 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", { i3.register_craft_type("digging", {
description = ES"Digging", description = ES"Digging",
icon = "i3_steelpick.png", icon = "i3_steelpick.png",
@ -2955,15 +2953,17 @@ end
on_mods_loaded(function() on_mods_loaded(function()
get_init_items() 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 sfinv.enabled = false
end 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 old_unified_inventory_fn = unified_inventory.set_inventory_formspec
function unified_inventory.set_inventory_formspec() return end function unified_inventory.set_inventory_formspec() return end
end end
@ -3045,14 +3045,15 @@ on_joinplayer(function(player)
local info = get_player_info(name) local info = get_player_info(name)
if get_formspec_version(info) < MIN_FORMSPEC_VERSION then 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 sfinv.enabled = true
end end
if unified_inventory then if __unified_inventory then
unified_inventory.set_inventory_formspec = old_unified_inventory_fn unified_inventory.set_inventory_formspec = old_unified_inventory_fn
if sfinv then if __sfinv then
sfinv.enabled = false sfinv.enabled = false
end end
end end
@ -3084,22 +3085,46 @@ core.register_on_dieplayer(function(player)
set_fs(player) set_fs(player)
end) end)
on_leaveplayer(function(player) local META_SAVES = {
save_meta(player, META_SAVES) bag_size = true,
waypoints = true,
skin_id = true,
inv_items = true,
known_recipes = true,
}
local name = player:get_player_name() local function save_data(player_name)
pdata[name] = nil local _pdata = copy(pdata)
end)
on_shutdown(function() for name, v in pairs(_pdata) do
local players = get_players() for dat in pairs(v) do
if not META_SAVES[dat] then
_pdata[name][dat] = nil
for i = 1, #players do if player_name then
local player = players[i] pdata[player_name][dat] = nil -- To free up some memory
save_meta(player, META_SAVES) end
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) 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) on_receive_fields(function(player, formname, fields)
if formname ~= "" then if formname ~= "" then
return false return false
@ -3348,11 +3373,10 @@ if progressive_mode then
on_joinplayer(function(player) on_joinplayer(function(player)
local name = player:get_player_name() local name = player:get_player_name()
local meta = player:get_meta()
local data = pdata[name] local data = pdata[name]
data.inv_items = dslz(meta:get_string "inv_items") or {} data.inv_items = data.inv_items or {}
data.known_recipes = dslz(meta:get_string "known_recipes") or 0 data.known_recipes = data.known_recipes or 0
local items = get_filtered_items(player, data) local items = get_filtered_items(player, data)
data.items_raw = items data.items_raw = items
@ -3362,8 +3386,6 @@ if progressive_mode then
init_hud(player, data) init_hud(player, data)
end end
end) end)
table_merge(META_SAVES, {"inv_items", "known_recipes"})
end end
local bag_recipes = { local bag_recipes = {

View File

@ -8,7 +8,7 @@ local use_cmi = minetest.global_exists("cmi")
mobs = { mobs = {
mod = "redo", mod = "redo",
version = "20210418", version = "20210613",
intllib = S, intllib = S,
invis = minetest.global_exists("invisibility") and invisibility or {} invis = minetest.global_exists("invisibility") and invisibility or {}
} }
@ -28,8 +28,7 @@ local rad = math.rad
local atann = math.atan local atann = math.atan
local atan = function(x) local atan = function(x)
if not x or x ~= x then if not x or x ~= x then
--error("atan bassed NaN") return 0 -- NaN
return 0
else else
return atann(x) return atann(x)
end 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 active_limit = tonumber(settings:get("mob_active_limit") or 0)
local mob_chance_multiplier = tonumber(settings:get("mob_chance_multiplier") or 1) local mob_chance_multiplier = tonumber(settings:get("mob_chance_multiplier") or 1)
local peaceful_player_enabled = settings:get_bool("enable_peaceful_player") 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 local active_mobs = 0
-- Peaceful mode message so players will know there are no monsters -- Peaceful mode message so players will know there are no monsters
if peaceful_only then if peaceful_only then
minetest.register_on_joinplayer(function(player) 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 for _,object in ipairs(minetest.get_objects_inside_radius(pos, width)) do
if object:is_player() then 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 pos2 = object:get_pos()
local vec = {x = pos.x - pos2.x, z = pos.z - pos2.z} 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 yaw = 0
end end
delay = delay or 0 delay = mob_smooth_rotate and (delay or 0) or 0
if delay == 0 then if delay == 0 then
self.object:set_yaw(yaw) self.object:set_yaw(yaw)
return yaw return yaw
end end
@ -404,7 +402,6 @@ function mob_class:set_animation(anim, force)
0, self.animation[anim .. "_loop"] ~= false) 0, self.animation[anim .. "_loop"] ~= false)
end end
-- above function exported for mount.lua
function mobs:set_animation(entity, anim) function mobs:set_animation(entity, anim)
entity.set_animation(entity, anim) entity.set_animation(entity, anim)
end end
@ -591,7 +588,7 @@ function mob_class:attempt_flight_correction(override)
local escape_direction = vdirection(pos, escape_target) local escape_direction = vdirection(pos, escape_target)
self.object:set_velocity( self.object:set_velocity(
vmultiply(escape_direction, 1)) --self.run_velocity)) vmultiply(escape_direction, 1))
return true return true
end end
@ -643,7 +640,7 @@ function mobs:yaw_to_pos(self, target, rot)
end 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() function mob_class:do_stay_near()
if not self.stay_near then return false end if not self.stay_near then return false end
@ -740,9 +737,15 @@ function mob_class:update_tag()
col = "#FF0000" col = "#FF0000"
end end
-- build infotext
self.infotext = "Health: " .. self.health .. " / " .. self.hp_max
.. "\n" .. "Owner: " .. self.owner
-- set changes
self.object:set_properties({ self.object:set_properties({
nametag = self.nametag, nametag = self.nametag,
nametag_color = col nametag_color = col,
infotext = self.infotext
}) })
end end
@ -790,10 +793,7 @@ function mob_class:item_drop()
end end
-- only drop rare items (drops.min = 0) if killed by player -- only drop rare items (drops.min = 0) if killed by player
if death_by_player then if death_by_player or self.drops[n].min ~= 0 then
obj = minetest.add_item(pos, ItemStack(item .. " " .. num))
elseif self.drops[n].min ~= 0 then
obj = minetest.add_item(pos, ItemStack(item .. " " .. num)) obj = minetest.add_item(pos, ItemStack(item .. " " .. num))
end end
@ -868,18 +868,17 @@ function mob_class:check_for_death(cmi_cause)
end end
-- backup nametag so we can show health stats -- backup nametag so we can show health stats
if not self.nametag2 then -- if not self.nametag2 then
self.nametag2 = self.nametag or "" -- self.nametag2 = self.nametag or ""
end -- end
if show_health -- if show_health
and (cmi_cause and cmi_cause.type == "punch") then -- and (cmi_cause and cmi_cause.type == "punch") then
self.htimer = 2
self.nametag = "" .. self.health .. " / " .. self.hp_max
-- self.htimer = 2
-- self.nametag = "♥ " .. self.health .. " / " .. self.hp_max
self:update_tag() self:update_tag()
end -- end
return false return false
end end
@ -1049,13 +1048,13 @@ function mob_class:do_env_damage()
end end
-- reset nametag after showing health stats -- 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.nametag = self.nametag2
self.nametag2 = nil -- self.nametag2 = nil
self:update_tag() self:update_tag()
end -- end
local pos = self.object:get_pos() ; if not pos then return 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] local nodef = minetest.registered_nodes[self.standing_in]
-- water -- water
if self.water_damage ~= 0 if self.water_damage ~= 0 and nodef.groups.water then
and nodef.groups.water then
self.health = self.health - self.water_damage self.health = self.health - self.water_damage
@ -1092,8 +1090,7 @@ function mob_class:do_env_damage()
end end
-- lava damage -- lava damage
elseif self.lava_damage ~= 0 elseif self.lava_damage ~= 0 and nodef.groups.lava then
and nodef.groups.lava then
self.health = self.health - self.lava_damage self.health = self.health - self.lava_damage
@ -1105,8 +1102,7 @@ function mob_class:do_env_damage()
end end
-- fire damage -- fire damage
elseif self.fire_damage ~= 0 elseif self.fire_damage ~= 0 and nodef.groups.fire then
and nodef.groups.fire then
self.health = self.health - self.fire_damage 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:", nod.name, pos.y + 0.5)
--print("in front above:", nodt.name, pos.y + 1.5) --print("in front above:", nodt.name, pos.y + 1.5)
-- jump if standing on solid node (not snow) and not blocked above -- are we facing a fence or wall
if (self.walk_chance == 0 if nod.name:find("fence") or nod.name:find("gate") or nod.name:find("wall") then
or minetest.registered_items[nod.name].walkable) self.facing_fence = true
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
end end
-- if blocked against a block/wall for 5 counts then turn -- jump if standing on solid node (not snow) and not blocked above
if not self.following if (self.walk_chance == 0 or minetest.registered_items[nod.name].walkable)
and (self.facing_fence or blocked) then 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 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 yaw = self.object:get_yaw() or 0
local turn = random(0, 2) + 1.35 local turn = random(0, 2) + 1.35
@ -1361,7 +1354,7 @@ end
-- Thanks Wuzzy for the following editable settings -- Thanks Wuzzy for the following editable settings
local HORNY_TIME = 30 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 local CHILD_GROW_TIME = 60 * 20 -- 20 minutes
-- find two animals of same type and breed if nearby and horny -- 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 if self.on_grown then
self.on_grown(self) self.on_grown(self)
else 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 pos = self.object:get_pos() ; if not pos then return end
local ent = self.object:get_luaentity() local ent = self.object:get_luaentity()
pos.y = pos.y + (ent.collisionbox[2] * -1) - 0.4 pos.y = pos.y + (ent.collisionbox[2] * -1) - 0.4
self.object:set_pos(pos) 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
end end
@ -1621,6 +1613,40 @@ end
local los_switcher = false local los_switcher = false
local height_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, -- path finding and smart mob routine by rnd,
-- line_of_sight and other edits by Elkien3 -- 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 -- lets make way by digging/building if not accessible
if self.pathfinding == 2 and mobs_griefing then if self.pathfinding == 2 and mobs_griefing then
-- is player higher than mob? -- is player more than 1 block higher than mob?
if s.y < p1.y then if p1.y > (s.y + 1) then
-- build upwards -- build upwards
if not minetest.is_protected(s, "") then 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] local ndef1 = minetest.registered_nodes[self.standing_in]
if ndef1 and (ndef1.buildable_to or ndef1.groups.liquid) then 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
end end
@ -1806,27 +1831,19 @@ function mob_class:smart_mobs(s, p, dist, dtime)
s.y = s.y + sheight s.y = s.y + sheight
-- remove one block above to make room to jump -- remove one block above to make room to jump
if not minetest.is_protected(s, "") then can_dig_drop(s)
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
s.y = s.y - sheight s.y = s.y - sheight
self.object:set_pos({x = s.x, y = s.y + 2, z = s.z}) 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 else -- dig 2 blocks to make door toward player direction
local yaw1 = self.object:get_yaw() + pi / 2 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) 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 p1.y = p1.y + 1
local ndef1 = minetest.registered_nodes[node1]
if node1 ~= "air" can_dig_drop(p1)
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
end end
end end
@ -2598,7 +2590,10 @@ function mob_class:do_states(dtime)
self:smart_mobs(s, p, dist, dtime) self:smart_mobs(s, p, dist, dtime)
end 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_velocity(0)
self:set_animation("stand") self:set_animation("stand")
@ -2616,7 +2611,6 @@ function mob_class:do_states(dtime)
self:set_animation("walk") self:set_animation("walk")
end end
end end
else -- rnd: if inside reach range else -- rnd: if inside reach range
self.path.stuck = false self.path.stuck = false
@ -2652,9 +2646,11 @@ function mob_class:do_states(dtime)
self.attack = attached self.attack = attached
end end
local dgroup = self.damage_group or "fleshy"
self.attack:punch(self.object, 1.0, { self.attack:punch(self.object, 1.0, {
full_punch_interval = 1.0, full_punch_interval = 1.0,
damage_groups = {fleshy = self.damage} damage_groups = {[dgroup] = self.damage}
}, nil) }, nil)
end end
end end
@ -2761,11 +2757,7 @@ function mob_class:falling(pos)
end end
-- fall at set speed -- fall at set speed
self.object:set_acceleration({ self.object:set_acceleration({x = 0, y = fall_speed, z = 0})
x = 0,
y = fall_speed,
z = 0
})
end end
@ -2788,8 +2780,9 @@ function mob_class:on_punch(hitter, tflp, tool_capabilities, dir, damage)
-- error checking when mod profiling is enabled -- error checking when mod profiling is enabled
if not tool_capabilities then 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 return true
end 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 if self.immune_to[n][1] == weapon_def.name then
damage = self.immune_to[n][2] or 0 damage = self.immune_to[n][2] or 0
break break
-- if "all" then no tools deal damage unless it's specified in list -- 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 -- healing
if damage <= -1 then if damage <= -1 then
self.health = self.health - floor(damage) self.health = self.health - floor(damage)
return true return true
end end
if use_cmi if use_cmi
and cmi.notify_punch( and cmi.notify_punch(self.object, hitter, tflp, tool_capabilities, dir, damage) then
self.object, hitter, tflp, tool_capabilities, dir, damage) then
return true return true
end end
@ -2902,10 +2897,8 @@ function mob_class:on_punch(hitter, tflp, tool_capabilities, dir, damage)
end end
end end
if tr then if tr and weapon_def.original_description then
if weapon_def.original_description then toolranks.new_afteruse(weapon, hitter, nil, {wear = wear})
toolranks.new_afteruse(weapon, hitter, nil, {wear = wear})
end
else else
weapon:add_wear(wear) weapon:add_wear(wear)
end 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 -- only play hit sound and show blood effects if damage is 1 or over
if damage >= 1 then if damage >= 1 then
-- weapon sounds -- select tool use sound if found, or fallback to default
if weapon_def.sounds then local snd = weapon_def.sound and weapon_def.sound.use
or "default_punch"
local s = random(0, #weapon_def.sounds) minetest.sound_play(snd, {object = self.object, max_hear_distance = 8}, true)
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
-- blood_particles -- blood_particles
if not disable_blood and self.blood_amount > 0 then 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 blood = self.blood_texture
local amount = self.blood_amount local amount = self.blood_amount
pos.y = pos.y + (-self.collisionbox[2] pos.y = pos.y + (-self.collisionbox[2] + self.collisionbox[5]) * .5
+ self.collisionbox[5]) * .5
-- lots of damage = more blood :) -- lots of damage = more blood :)
if damage > 10 then if damage > 10 then
@ -2952,7 +2934,6 @@ function mob_class:on_punch(hitter, tflp, tool_capabilities, dir, damage)
end end
effect(pos, amount, blood, 1, 2, 1.75, nil, nil, true) effect(pos, amount, blood, 1, 2, 1.75, nil, nil, true)
end end
-- do damage -- 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 local hot = tool_capabilities and tool_capabilities.damage_groups
and tool_capabilities.damage_groups.fire and tool_capabilities.damage_groups.fire
if self:check_for_death({type = "punch", if self:check_for_death({type = "punch", puncher = hitter, hot = hot}) then
puncher = hitter, hot = hot}) then
return true return true
end 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 end -- END if damage
-- knock back effect (only on full punch) -- knock back effect (only on full punch)
if self.knock_back if self.knock_back and tflp >= punch_interval then
and tflp >= punch_interval then
local v = self.object:get_velocity() 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 -- use tool knockback value or default
kb = tool_capabilities.damage_groups["knockback"] or kb kb = tool_capabilities.damage_groups["knockback"] or kb
self.object:set_velocity({ self.object:set_velocity({x = dir.x * kb, y = up, z = dir.z * kb})
x = dir.x * kb,
y = up,
z = dir.z * kb
})
self.pause_timer = 0.25 self.pause_timer = 0.25
end end
@ -3257,10 +3218,8 @@ function mob_class:mob_activate(staticdata, def, dtime)
local armor local armor
if type(self.armor) == "table" then if type(self.armor) == "table" then
armor = table_copy(self.armor) armor = table_copy(self.armor)
-- armor.immortal = 1
else else
-- armor = {immortal = 1, fleshy = self.armor} armor = {fleshy = self.armor} -- immortal = 1
armor = {fleshy = self.armor}
end end
self.object:set_armor_groups(armor) self.object:set_armor_groups(armor)
@ -3358,23 +3317,7 @@ end
-- main mob function -- main mob function
function mob_class:on_step(dtime, moveresult) function mob_class:on_step(dtime, moveresult)
--[[ moveresult contains this for physical mobs if self.state == "die" then return end
{
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 use_cmi then if use_cmi then
cmi.notify_step(self.object, dtime) cmi.notify_step(self.object, dtime)
@ -3563,6 +3506,13 @@ function mobs:register_mob(name, def)
mobs.spawning_mobs[name] = {} 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({ minetest.register_entity(name, setmetatable({
stepheight = def.stepheight, stepheight = def.stepheight,
@ -3584,8 +3534,8 @@ minetest.register_entity(name, setmetatable({
lifetimer = def.lifetimer, lifetimer = def.lifetimer,
hp_min = max(1, (def.hp_min or 5) * difficulty), hp_min = max(1, (def.hp_min or 5) * difficulty),
hp_max = max(1, (def.hp_max or 10) * difficulty), hp_max = max(1, (def.hp_max or 10) * difficulty),
collisionbox = def.collisionbox, collisionbox = collisionbox, --def.collisionbox,
selectionbox = def.selectionbox or def.collisionbox, selectionbox = def.selectionbox or collisionbox, --def.collisionbox,
visual = def.visual, visual = def.visual,
visual_size = def.visual_size, visual_size = def.visual_size,
mesh = def.mesh, mesh = def.mesh,
@ -3594,6 +3544,8 @@ minetest.register_entity(name, setmetatable({
walk_velocity = def.walk_velocity, walk_velocity = def.walk_velocity,
run_velocity = def.run_velocity, run_velocity = def.run_velocity,
damage = max(0, (def.damage or 0) * difficulty), 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 = def.light_damage,
light_damage_min = def.light_damage_min, light_damage_min = def.light_damage_min,
light_damage_max = def.light_damage_max, 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) local numbers = settings:get(name)
if numbers then if numbers then
numbers = numbers:split(",") numbers = numbers:split(",")
chance = tonumber(numbers[1]) or chance chance = tonumber(numbers[1]) or chance
aoc = tonumber(numbers[2]) or aoc aoc = tonumber(numbers[2]) or aoc
if chance == 0 then if chance == 0 then
minetest.log("warning", minetest.log("warning",
string.format("[mobs] %s has spawning disabled", name)) string.format("[mobs] %s has spawning disabled", name))
return return
@ -4127,7 +4081,10 @@ function mobs:register_arrow(name, def)
minetest.register_entity(name, { 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 = def.visual,
visual_size = def.visual_size, visual_size = def.visual_size,
textures = def.textures, textures = def.textures,
@ -4286,7 +4243,7 @@ function mobs:boom(self, pos, radius)
radius = radius, radius = radius,
damage_radius = radius, damage_radius = radius,
sound = self.sounds and self.sounds.explode, sound = self.sounds and self.sounds.explode,
explode_center = true, explode_center = true
}) })
else else
mobs:safe_boom(self, pos, radius) 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 self.health = self.hp_max
if self.htimer < 1 then -- if self.htimer < 1 then
minetest.chat_send_player(clicker:get_player_name(), -- minetest.chat_send_player(clicker:get_player_name(),
S("@1 at full health (@2)", -- S("@1 at full health (@2)",
self.name:split(":")[2], tostring(self.health))) -- self.name:split(":")[2], tostring(self.health)))
self.htimer = 5 -- self.htimer = 5
end -- end
end end
self.object:set_hp(self.health) self.object:set_hp(self.health)
@ -4825,14 +4782,13 @@ function mobs:alias_mob(old_name, new_name)
-- entity -- entity
minetest.register_entity(":" .. old_name, { minetest.register_entity(":" .. old_name, {
physical = false, physical = false, static_save = false,
on_activate = function(self, staticdata) on_activate = function(self, staticdata)
if minetest.registered_entities[new_name] then if minetest.registered_entities[new_name] then
minetest.add_entity(self.object:get_pos(), minetest.add_entity(self.object:get_pos(), new_name, staticdata)
new_name, staticdata)
end end
remove_mob(self) remove_mob(self)

View File

@ -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. '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 'damage' how many health points the mob does to a player or another
mob when melee attacking. 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 'knock_back' when true has mobs falling backwards when hit, the greater
the damage the more they move back. the damage the more they move back.
'fear_height' is how high a cliff or edge has to be before the mob stops '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' same is in minetest.register_entity()
'visual_size' same is in minetest.register_entity() 'visual_size' same is in minetest.register_entity()
'textures' 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 'velocity' the velocity of the arrow
'drop' if set to true any arrows hitting a node will drop as item '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; '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_area_spawn' When true will check surrounding area the size of the
mob for obstructions before spawning, otherwise it mob for obstructions before spawning, otherwise it
defaults to checking the height of the mob only. 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 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 to their minetest.conf file with a new value, the lower the value the more each

View File

@ -299,12 +299,18 @@ minetest.register_tool(":mobs:mob_reset_stick", {
tex_obj = obj 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 name = user:get_player_name()
local tex = ""
minetest.show_formspec(name, "mobs_texture", "size[8,4]" minetest.show_formspec(name, "mobs_texture", "size[8,4]"
.. "field[0.5,1;7.5,0;name;" .. "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;" .. "button_exit[2.5,3.5;3,1;mob_texture_change;"
.. minetest.formspec_escape(S("Change")) .. "]") .. minetest.formspec_escape(S("Change")) .. "]")
end end

View File

@ -22,6 +22,7 @@ end
local function node_is(pos) local function node_is(pos)
local node = node_ok(pos) local node = node_ok(pos)
if node.name == "air" then if node.name == "air" then
@ -69,6 +70,7 @@ end
local function force_detach(player) local function force_detach(player)
local attached_to = player:get_attach() local attached_to = player:get_attach()
if not attached_to then if not attached_to then
@ -97,7 +99,9 @@ minetest.register_on_leaveplayer(function(player)
end) end)
minetest.register_on_shutdown(function() minetest.register_on_shutdown(function()
local players = minetest.get_connected_players() local players = minetest.get_connected_players()
for i = 1, #players do for i = 1, #players do
force_detach(players[i]) force_detach(players[i])
end end
@ -112,6 +116,7 @@ end)
-- Just for correct detaching -- Just for correct detaching
local function find_free_pos(pos) local function find_free_pos(pos)
local check = { local check = {
{x = 1, y = 0, z = 0}, {x = 1, y = 0, z = 0},
{x = 1, y = 1, z = 0}, {x = 1, y = 1, z = 0},
@ -124,10 +129,14 @@ local function find_free_pos(pos)
} }
for _, c in pairs(check) do for _, c in pairs(check) do
local npos = {x = pos.x + c.x, y = pos.y + c.y, z = pos.z + c.z} 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) local node = minetest.get_node_or_nil(npos)
if node and node.name then if node and node.name then
local def = minetest.registered_nodes[node.name] local def = minetest.registered_nodes[node.name]
if def and not def.walkable and if def and not def.walkable and
def.liquidtype == "none" then def.liquidtype == "none" then
return npos return npos
@ -141,6 +150,7 @@ end
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
function mobs.attach(entity, player) function mobs.attach(entity, player)
entity.player_rotation = entity.player_rotation or {x = 0, y = 0, z = 0} 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_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} 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 attach_at = entity.driver_attach_at
local eye_offset = entity.driver_eye_offset local eye_offset = entity.driver_eye_offset
entity.driver = player entity.driver = player
force_detach(player) force_detach(player)
@ -170,6 +181,7 @@ function mobs.attach(entity, player)
}) })
minetest.after(0.2, function() minetest.after(0.2, function()
if player and player:is_player() then if player and player:is_player() then
player_api.set_animation(player, "sit", 30) player_api.set_animation(player, "sit", 30)
end end
@ -183,9 +195,13 @@ function mobs.detach(player)
force_detach(player) force_detach(player)
minetest.after(0.1, function() minetest.after(0.1, function()
if player and player:is_player() then if player and player:is_player() then
local pos = find_free_pos(player:get_pos()) local pos = find_free_pos(player:get_pos())
pos.y = pos.y + 0.5 pos.y = pos.y + 0.5
player:set_pos(pos) player:set_pos(pos)
end end
end) end)
@ -193,8 +209,8 @@ end
function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime) 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 local rot_view = 0
if entity.player_rotation.y == 90 then if entity.player_rotation.y == 90 then
@ -208,14 +224,17 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
-- process controls -- process controls
if entity.driver then if entity.driver then
local ctrl = entity.driver:get_player_control() local ctrl = entity.driver:get_player_control()
-- move forwards -- move forwards
if ctrl.up then if ctrl.up then
entity.v = entity.v + entity.accel / 10 entity.v = entity.v + entity.accel / 10
-- move backwards -- move backwards
elseif ctrl.down then elseif ctrl.down then
if entity.max_speed_reverse == 0 and entity.v == 0 then if entity.max_speed_reverse == 0 and entity.v == 0 then
return return
end end
@ -225,7 +244,9 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
-- mob rotation -- mob rotation
local horz local horz
if entity.alt_turn == true then if entity.alt_turn == true then
horz = yaw horz = yaw
if ctrl.left then if ctrl.left then
@ -243,21 +264,29 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
if can_fly then if can_fly then
-- fly up -- fly up
if ctrl.jump then if ctrl.jump then
velo.y = velo.y + 1 velo.y = velo.y + 1
if velo.y > entity.accel then velo.y = entity.accel end if velo.y > entity.accel then velo.y = entity.accel end
elseif velo.y > 0 then elseif velo.y > 0 then
velo.y = velo.y - 0.1 velo.y = velo.y - 0.1
if velo.y < 0 then velo.y = 0 end if velo.y < 0 then velo.y = 0 end
end end
-- fly down -- fly down
if ctrl.sneak then if ctrl.sneak then
velo.y = velo.y - 1 velo.y = velo.y - 1
if velo.y < -entity.accel then velo.y = -entity.accel end if velo.y < -entity.accel then velo.y = -entity.accel end
elseif velo.y < 0 then elseif velo.y < 0 then
velo.y = velo.y + 0.1 velo.y = velo.y + 0.1
if velo.y > 0 then velo.y = 0 end if velo.y > 0 then velo.y = 0 end
end end
else 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 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 entity.v == 0 and velo.x == 0 and velo.y == 0 and velo.z == 0 then
if stand_anim then if stand_anim then
mobs:set_animation(entity, stand_anim) mobs:set_animation(entity, stand_anim)
end end
@ -292,8 +322,10 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
entity.v = entity.v - 0.02 * s entity.v = entity.v - 0.02 * s
if s ~= get_sign(entity.v) then if s ~= get_sign(entity.v) then
entity.object:set_velocity({x = 0, y = 0, z = 0}) entity.object:set_velocity({x = 0, y = 0, z = 0})
entity.v = 0 entity.v = 0
return return
end end
@ -310,6 +342,7 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
-- Set position, velocity and acceleration -- Set position, velocity and acceleration
local p = entity.object:get_pos() local p = entity.object:get_pos()
if not p then return end if not p then return end
local new_acce = {x = 0, y = -9.81, z = 0} 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 local v = entity.v
if ni == "air" then if ni == "air" then
if can_fly == true then if can_fly == true then
new_acce.y = 0 new_acce.y = 0
end end
elseif ni == "liquid" or ni == "lava" then elseif ni == "liquid" or ni == "lava" then
if ni == "lava" and entity.lava_damage ~= 0 then if ni == "lava" and entity.lava_damage ~= 0 then
entity.lava_counter = (entity.lava_counter or 0) + dtime entity.lava_counter = (entity.lava_counter or 0) + dtime
if entity.lava_counter > 1 then if entity.lava_counter > 1 then
minetest.sound_play("default_punch", { minetest.sound_play("default_punch", {
object = entity.object, object = entity.object,
max_hear_distance = 5 max_hear_distance = 5
}) }, true)
entity.object:punch(entity.object, 1.0, { entity.object:punch(entity.object, 1.0, {
full_punch_interval = 1.0, full_punch_interval = 1.0,
@ -343,11 +381,14 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
end end
local terrain_type = entity.terrain_type local terrain_type = entity.terrain_type
if terrain_type == 2 or terrain_type == 3 then if terrain_type == 2 or terrain_type == 3 then
new_acce.y = 0 new_acce.y = 0
p.y = p.y + 1 p.y = p.y + 1
if node_is(p) == "liquid" then if node_is(p) == "liquid" then
if velo.y >= 5 then if velo.y >= 5 then
velo.y = 5 velo.y = 5
elseif velo.y < 0 then elseif velo.y < 0 then
@ -357,7 +398,9 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
end end
else else
if abs(velo.y) < 1 then if abs(velo.y) < 1 then
local pos = entity.object:get_pos() local pos = entity.object:get_pos()
if not pos then return end if not pos then return end
pos.y = floor(pos.y) + 0.5 pos.y = floor(pos.y) + 0.5
@ -371,6 +414,7 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
end end
local new_velo = get_velocity(v, yaw - rot_view, velo.y) local new_velo = get_velocity(v, yaw - rot_view, velo.y)
new_acce.y = new_acce.y + acce_y new_acce.y = new_acce.y + acce_y
entity.object:set_velocity(new_velo) entity.object:set_velocity(new_velo)
@ -382,11 +426,14 @@ end
-- directional flying routine by D00Med (edited by TenPlus1) -- directional flying routine by D00Med (edited by TenPlus1)
function mobs.fly(entity, _, speed, shoots, arrow, moving_anim, stand_anim) function mobs.fly(entity, _, speed, shoots, arrow, moving_anim, stand_anim)
local ctrl = entity.driver:get_player_control() local ctrl = entity.driver:get_player_control()
local velo = entity.object:get_velocity() local velo = entity.object:get_velocity()
local dir = entity.driver:get_look_dir() local dir = entity.driver:get_look_dir()
local yaw = entity.driver:get_look_horizontal() + 1.57 -- offset fix between old and new commands 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 if ctrl.up then
entity.object:set_velocity({ entity.object:set_velocity({
x = dir.x * speed, x = dir.x * speed,
@ -395,6 +442,7 @@ function mobs.fly(entity, _, speed, shoots, arrow, moving_anim, stand_anim)
}) })
elseif ctrl.down then elseif ctrl.down then
entity.object:set_velocity({ entity.object:set_velocity({
x = -dir.x * speed, x = -dir.x * speed,
y = dir.y * speed + 2, y = dir.y * speed + 2,
@ -409,6 +457,7 @@ function mobs.fly(entity, _, speed, shoots, arrow, moving_anim, stand_anim)
-- firing arrows -- firing arrows
if ctrl.LMB and ctrl.sneak and shoots then if ctrl.LMB and ctrl.sneak and shoots then
local pos = entity.object:get_pos() local pos = entity.object:get_pos()
local obj = minetest.add_entity({ local obj = minetest.add_entity({
x = pos.x + 0 + dir.x * 2.5, 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) z = pos.z + 0 + dir.z * 2.5}, arrow)
local ent = obj:get_luaentity() local ent = obj:get_luaentity()
if ent then if ent then
ent.switch = 1 -- for mob specific arrows ent.switch = 1 -- for mob specific arrows
ent.owner_id = tostring(entity.object) -- so arrows dont hurt entity you are riding 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} local vec = {x = dir.x * 6, y = dir.y * 6, z = dir.z * 6}
yaw = entity.driver:get_look_horizontal() yaw = entity.driver:get_look_horizontal()
obj:set_yaw(yaw + pi / 2) obj:set_yaw(yaw + pi / 2)
obj:set_velocity(vec) obj:set_velocity(vec)
else else

View File

@ -39,3 +39,6 @@ mob_area_spawn (Mob Area Spawn) bool false
# Enable peaceful player attack prevention # Enable peaceful player attack prevention
enable_peaceful_player (Mobs do not attack peaceful player without reason) bool false 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

View File

@ -222,8 +222,30 @@ This is best left explicit. First, you shouldn't be using numbered field keys if
4. [`json`](https://json.org) 4. [`json`](https://json.org)
* Not recommended * 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 ## Release Notes
### `rolling-69`
* Fixes various things, **most importantly modules indexing the global table**
### `rolling-68` ### `rolling-68`
* Replace changelog by release notes (see the commit log for changes) * Replace changelog by release notes (see the commit log for changes)

View File

@ -1,6 +1,12 @@
--! experimental --! experimental
local bluon = getfenv(1) 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) function new(self)
return setmetatable(self or {}, metatable) return setmetatable(self or {}, metatable)
@ -95,23 +101,28 @@ local function is_map_key(key, list_len)
end end
function len(self, object) function len(self, object)
if object == nil then
return 0
end
if constants[object] then if constants[object] then
return 1 return 1
end end
local object_ids = {}
local current_id = 0
local _type = type(object) local _type = type(object)
if _type == "number" then if _type == "number" then
if object ~= object then if object ~= object then
stream:write(constant_nan) return 1
return
end end
if object % 1 == 0 then if object % 1 == 0 then
return 1 + uint_len(object > 0 and object or -object) return 1 + uint_len(object > 0 and object or -object)
end end
-- TODO ensure this check is proper -- HACK use write_float to get the length
if mantissa % 2^-23 > 0 then local bytes = 4
return 9 write_float(no_op, object, function(double)
end if double then bytes = 8 end
return 5 end)
return 1 + bytes
end end
local id = object_ids[object] local id = object_ids[object]
if id then if id then
@ -126,7 +137,6 @@ function len(self, object)
if _type == "table" then if _type == "table" then
if next(object) == nil then if next(object) == nil then
-- empty {} table -- empty {} table
byte(type_ranges.string + 1)
return 1 return 1
end end
local list_len = #object local list_len = #object
@ -138,14 +148,14 @@ function len(self, object)
end end
local table_len = 1 + uint_len(list_len) + uint_len(kv_len) local table_len = 1 + uint_len(list_len) + uint_len(kv_len)
for index = 1, list_len do for index = 1, list_len do
table_len = table_len + len(self, object[index]) table_len = table_len + self:len(object[index])
end end
for key, value in pairs(object) do for key, value in pairs(object) do
if is_map_key(key, list_len) then 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
end end
return len return kv_len + table_len
end end
return self.aux_len(object) return self.aux_len(object)
end end
@ -169,7 +179,6 @@ function write(self, object, stream)
byte(base + type_offset) byte(base + type_offset)
uint(type_offset, _uint) uint(type_offset, _uint)
end end
local write_float = modlib.binary.write_float
local function float_on_write(double) local function float_on_write(double)
byte(double and type_ranges.number or type_ranges.number_f32) byte(double and type_ranges.number or type_ranges.number_f32)
end end

View File

@ -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

View File

@ -1,34 +1,43 @@
local function gather_info() function variables(stacklevel)
local locals = {} stacklevel = (stacklevel or 1) + 1
local index = 1 local locals = {}
while true do local index = 1
local name, value = debug.getlocal(2, index) while true do
if not name then break end local name, value = debug.getlocal(stacklevel, index)
table.insert(locals, {name, value}) if not name then break end
index = index + 1 table.insert(locals, {name, value})
end index = index + 1
local upvalues = {} end
local func = debug.getinfo(2).func local upvalues = {}
local envs = getfenv(func) local func = debug.getinfo(stacklevel).func
index = 1 local fenv = getfenv(func)
while true do index = 1
local name, value = debug.getupvalue(func, index) while true do
if not name then break end local name, value = debug.getupvalue(func, index)
table.insert(upvalues, {name, value}) if not name then break end
index = index + 1 table.insert(upvalues, {name, value})
end index = index + 1
return { end
locals = locals, return {
upvalues = upvalues, locals = locals,
[envs == _G and "globals" or "envs"] = envs upvalues = upvalues,
} fenv = fenv,
fenv_global = fenv == _G
}
end end
local c = 3 function stack(stacklevel)
function test() stacklevel = (stacklevel or 1) + 1
local a = 1 local stack = {}
b = 2 while true do
error(gather_info().upvalues[1][1]) local info = debug.getinfo(stacklevel, "nfSlu")
end if not info then
break
test() end
info.func = tostring(info.func)
info.variables = variables(stacklevel)
stack[stacklevel - 1] = info
stacklevel = stacklevel + 1
end
return stack
end

View File

@ -38,4 +38,76 @@ end
--+ Calls func using the provided arguments, deepcopies all arguments --+ Calls func using the provided arguments, deepcopies all arguments
function call_by_value(func, ...) function call_by_value(func, ...)
return func(unpack(modlib.table.deepcopy{...})) 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 end

View File

@ -53,7 +53,8 @@ for _, file in pairs{
"binary", "binary",
"b3d", "b3d",
"bluon", "bluon",
"persistence" "persistence",
"debug"
} do } do
modules[file] = file modules[file] = file
end end
@ -64,10 +65,10 @@ if minetest then
"liquid", "liquid",
"raycast", "raycast",
"wielditem_change", "wielditem_change",
"colorspec" "colorspec",
"schematic"
} }
for _, file in pairs{ for _, file in pairs{
"data",
"log", "log",
"player", "player",
-- deprecated -- deprecated
@ -80,7 +81,7 @@ end
local load_module, get_resource, loadfile_exports local load_module, get_resource, loadfile_exports
modlib = setmetatable({ modlib = setmetatable({
-- TODO bump on release -- TODO bump on release
version = 68, version = 69,
modname = minetest and minetest.get_current_modname(), modname = minetest and minetest.get_current_modname(),
dir_delim = rawget(_G, "DIR_DELIM") or "/", dir_delim = rawget(_G, "DIR_DELIM") or "/",
_RG = setmetatable({}, { _RG = setmetatable({}, {
@ -99,14 +100,21 @@ modlib = setmetatable({
}, { }, {
__index = function(self, module_name) __index = function(self, module_name)
local files = modules[module_name] local files = modules[module_name]
local module local environment
if type(files) == "string" then if type(files) == "string" then
module = load_module(files) environment = load_module(files)
elseif files then 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 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 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 end
self[module_name] = module self[module_name] = module
return module return module
@ -154,8 +162,6 @@ end
_ml = modlib _ml = modlib
modlib.mod.include"test.lua"
--modlib.mod.include"bench.lua"
--[[ --[[
--modlib.mod.include"test.lua" --modlib.mod.include"test.lua"
]] ]]

View File

@ -14,7 +14,6 @@ local function get_gametime_init(dtime)
return return
end end
get_gametime_initialized = true get_gametime_initialized = true
assert(dtime == 0)
local gametime = minetest.get_gametime() local gametime = minetest.get_gametime()
assert(gametime) assert(gametime)
function modlib.minetest.get_gametime() function modlib.minetest.get_gametime()

View File

@ -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

View File

@ -80,14 +80,17 @@ function lua_log_file:_dump(value, is_key)
if _type == "number" then if _type == "number" then
return ("%.17g"):format(value) return ("%.17g"):format(value)
end end
if self.references[value] then local reference = self.references[value]
return "R[" .. self.references[value] .. "]" if reference then
return "R[" .. reference .."]"
end end
self.reference_count = self.reference_count + 1 reference = self.reference_count + 1
local reference = self.reference_count
local key = "R[" .. reference .."]" local key = "R[" .. reference .."]"
self.references[value] = reference
local formatted local formatted
local function create_reference()
self.reference_count = reference
self.references[value] = reference
end
if _type == "string" then if _type == "string" then
if is_key and value:len() <= key:len() and value:match"[%a_][%a%d_]*" then if is_key and value:len() <= key:len() and value:match"[%a_][%a%d_]*" then
-- Short key -- Short key
@ -98,13 +101,18 @@ function lua_log_file:_dump(value, is_key)
-- Short string -- Short string
return formatted return formatted
end end
-- Use reference
create_reference()
elseif _type == "table" then elseif _type == "table" then
-- Tables always need a reference before they are traversed to prevent infinite recursion
create_reference()
local entries = {} local entries = {}
for _, value in ipairs(value) do for _, value in ipairs(value) do
table.insert(entries, self:_dump(value)) table.insert(entries, self:_dump(value))
end end
local tablelen = #value
for key, value in pairs(value) do 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) local dumped, short = self:_dump(key, true)
table.insert(entries, (short and dumped or ("[" .. dumped .. "]")) .. "=" .. self:_dump(value)) table.insert(entries, (short and dumped or ("[" .. dumped .. "]")) .. "=" .. self:_dump(value))
end end

View File

@ -214,7 +214,7 @@ local function _delete(self, key, is_rank)
sidemost = sidemost[other_side] sidemost = sidemost[other_side]
end end
-- Replace deleted key -- Replace deleted key
tree.key = rightmost.key tree.key = sidemost.key
-- Replace the successor by it's single child -- Replace the successor by it's single child
parents[len][sides[len]] = sidemost[side] parents[len][sides[len]] = sidemost[side]
else else

View File

@ -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 random, huge = math.random, math.huge
local parent_env = getfenv(1) local parent_env = getfenv(1)
setfenv(1, setmetatable({}, { setfenv(1, setmetatable({}, {

View File

@ -102,6 +102,11 @@ local function lay_down(player, pos, bed_pos, state, skip)
return false return false
end end
-- Check if player is attached to an object
if player:get_attach() then
return false
end
if beds.player[name] then if beds.player[name] then
-- player already in bed, do nothing -- player already in bed, do nothing
return false return false

View File

@ -53,6 +53,7 @@ minetest.register_craftitem("binoculars:binoculars", {
description = S("Binoculars") .. "\n" .. S("Use with 'Zoom' key"), description = S("Binoculars") .. "\n" .. S("Use with 'Zoom' key"),
inventory_image = "binoculars_binoculars.png", inventory_image = "binoculars_binoculars.png",
stack_max = 1, stack_max = 1,
groups = {tool = 1},
on_use = function(itemstack, user, pointed_thing) on_use = function(itemstack, user, pointed_thing)
binoculars.update_player_property(user) binoculars.update_player_property(user)

View File

@ -53,31 +53,24 @@ function boat.on_rightclick(self, clicker)
end end
local name = clicker:get_player_name() local name = clicker:get_player_name()
if self.driver and name == self.driver then if self.driver and name == self.driver then
self.driver = nil -- Cleanup happens in boat.on_detach_child
self.auto = false
clicker:set_detach() 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() local pos = clicker:get_pos()
pos = {x = pos.x, y = pos.y + 0.2, z = pos.z} pos = {x = pos.x, y = pos.y + 0.2, z = pos.z}
minetest.after(0.1, function() minetest.after(0.1, function()
clicker:set_pos(pos) clicker:set_pos(pos)
end) end)
elseif not self.driver then 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, "", clicker:set_attach(self.object, "",
{x = 0.5, y = 1, z = -3}, {x = 0, y = 0, z = 0}) {x = 0.5, y = 1, z = -3}, {x = 0, y = 0, z = 0})
self.driver = name
player_api.player_attached[name] = true player_api.player_attached[name] = true
minetest.after(0.2, function() minetest.after(0.2, function()
player_api.set_animation(clicker, "sit" , 30) player_api.set_animation(clicker, "sit", 30)
end) end)
clicker:set_look_horizontal(self.object:get_yaw()) clicker:set_look_horizontal(self.object:get_yaw())
end end
@ -86,8 +79,12 @@ end
-- If driver leaves server while driving boat -- If driver leaves server while driving boat
function boat.on_detach_child(self, child) function boat.on_detach_child(self, child)
self.driver = nil if child and child:get_player_name() == self.driver then
self.auto = false player_api.player_attached[child:get_player_name()] = false
self.driver = nil
self.auto = false
end
end end

View File

@ -29,15 +29,10 @@ function cart_entity:on_rightclick(clicker)
end end
local player_name = clicker:get_player_name() local player_name = clicker:get_player_name()
if self.driver and player_name == self.driver then if self.driver and player_name == self.driver then
self.driver = nil
carts:manage_attachment(clicker, nil) carts:manage_attachment(clicker, nil)
elseif not self.driver then elseif not self.driver then
self.driver = player_name
carts:manage_attachment(clicker, self.object) carts:manage_attachment(clicker, self.object)
self.driver = player_name
-- player_api does not update the animation
-- when the player is attached, reset to default animation
player_api.set_animation(clicker, "stand")
end end
end end
@ -66,8 +61,9 @@ end
-- 0.5.x and later: When the driver leaves -- 0.5.x and later: When the driver leaves
function cart_entity:on_detach_child(child) function cart_entity:on_detach_child(child)
if child and child:get_player_name() == self.driver then if child and child:get_player_name() == self.driver then
self.driver = nil -- Clean up eye height
carts:manage_attachment(child, nil) carts:manage_attachment(child, nil)
self.driver = nil
end end
end end

View File

@ -12,7 +12,7 @@ function carts:manage_attachment(player, obj)
end end
local status = obj ~= nil local status = obj ~= nil
local player_name = player:get_player_name() 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 return
end end
player_api.player_attached[player_name] = status player_api.player_attached[player_name] = status
@ -20,6 +20,10 @@ function carts:manage_attachment(player, obj)
if status then if status then
player:set_attach(obj, "", {x=0, y=-4.5, z=0}, {x=0, y=0, z=0}) 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: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 else
player:set_detach() player:set_detach()
player:set_eye_offset({x=0, y=0, z=0},{x=0, y=0, z=0}) player:set_eye_offset({x=0, y=0, z=0},{x=0, y=0, z=0})

View File

@ -178,7 +178,7 @@ Gambit (CC BY-SA 3.0):
default_iron_lump.png default_iron_lump.png
default_gold_lump.png default_gold_lump.png
default_clay_lump.png default_clay_lump.png
default_coal.png default_coal_lump.png
default_grass_*.png default_grass_*.png
default_paper.png default_paper.png
default_diamond_block.png default_diamond_block.png

View File

@ -248,7 +248,7 @@ end
minetest.register_abm({ minetest.register_abm({
label = "Mushroom spread", label = "Mushroom spread",
nodenames = {"flowers:mushroom_brown", "flowers:mushroom_red"}, nodenames = {"group:mushroom"},
interval = 11, interval = 11,
chance = 150, chance = 150,
action = function(...) action = function(...)

View File

@ -51,7 +51,7 @@ minetest.register_craftitem("map:mapping_kit", {
description = S("Mapping Kit") .. "\n" .. S("Use with 'Minimap' key"), description = S("Mapping Kit") .. "\n" .. S("Use with 'Minimap' key"),
inventory_image = "map_mapping_kit.png", inventory_image = "map_mapping_kit.png",
stack_max = 1, stack_max = 1,
groups = {flammable = 3}, groups = {flammable = 3, tool = 1},
on_use = function(itemstack, user, pointed_thing) on_use = function(itemstack, user, pointed_thing)
map.update_hud_flags(user) map.update_hud_flags(user)

View File

@ -227,6 +227,8 @@ if minetest.get_modpath("doors") then
sounds = default.node_sound_metal_defaults(), sounds = default.node_sound_metal_defaults(),
sound_open = "xpanes_steel_bar_door_open", sound_open = "xpanes_steel_bar_door_open",
sound_close = "xpanes_steel_bar_door_close", sound_close = "xpanes_steel_bar_door_close",
gain_open = 0.15,
gain_close = 0.13,
recipe = { recipe = {
{"xpanes:bar_flat", "xpanes:bar_flat"}, {"xpanes:bar_flat", "xpanes:bar_flat"},
{"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(), sounds = default.node_sound_metal_defaults(),
sound_open = "xpanes_steel_bar_door_open", sound_open = "xpanes_steel_bar_door_open",
sound_close = "xpanes_steel_bar_door_close", sound_close = "xpanes_steel_bar_door_close",
gain_open = 0.15,
gain_close = 0.13,
}) })
minetest.register_craft({ minetest.register_craft({

View File

@ -61,8 +61,9 @@ function petz.throw(self, dtime, damage, effect, particles, sound)
z = node_pos.z, z = node_pos.z,
} }
local node_above = minetest.get_node(pos_above) local node_above = minetest.get_node(pos_above)
if minetest.get_item_group(node_name, "flammable") > 1 then if minetest.get_item_group(node_name, "flammable") > 1
minetest.set_node(node_pos, {name = "fire:basic_flame"}) and not minetest.is_protected(node_pos, "") then
minetest.set_node(node_pos, {name = "fire:basic_flame"})
end end
if node_above.name == "air" then if node_above.name == "air" then
--if minetest.get_node(pos_above).name == "air" then --if minetest.get_node(pos_above).name == "air" then

View File

@ -78,7 +78,7 @@ minetest.register_chatcommand("wl_lb", {
params = "", params = "",
description = "list biomes", description = "list biomes",
privs = {interact = true}, privs = {interact = true},
func = function() func = function(name)
local biom = water_life.get_biomes() local biom = water_life.get_biomes()
@ -86,7 +86,7 @@ minetest.register_chatcommand("wl_lb", {
if not biom then return end if not biom then return end
for i=1,#biom,1 do 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 end

0
mods/mobs/mobs_mobs/advanced_npc/npc.lua Executable file → Normal file
View File

View File

@ -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)

View File

@ -29,6 +29,7 @@ dofile(path .. "lava_flan.lua") -- Zeg9
dofile(path .. "mese_monster.lua") dofile(path .. "mese_monster.lua")
dofile(path .. "spider.lua") -- AspireMint dofile(path .. "spider.lua") -- AspireMint
dofile(path .. "land_guard.lua") dofile(path .. "land_guard.lua")
dofile(path .. "fire_spirit.lua")
-- Load custom spawning -- Load custom spawning

View File

@ -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. - 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 Lucky Blocks: 11

Binary file not shown.

After

Width:  |  Height:  |  Size: 274 B

View File

@ -200,6 +200,10 @@ armor.update_player_visuals = function(self, player)
self:run_callbacks("on_update", player) self:run_callbacks("on_update", player)
end 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) armor.set_player_armor = function(self, player)
local name, armor_inv = self:get_valid_player(player, "[set_player_armor]") local name, armor_inv = self:get_valid_player(player, "[set_player_armor]")
if not name then if not name then
@ -258,7 +262,9 @@ armor.set_player_armor = function(self, player)
tex = tex:gsub(".png$", "") tex = tex:gsub(".png$", "")
local prev = def.preview or tex.."_preview" local prev = def.preview or tex.."_preview"
prev = prev:gsub(".png$", "") prev = prev:gsub(".png$", "")
texture = texture.."^"..tex..".png" if not transparent_armor then
texture = texture.."^"..tex..".png"
end
preview = preview.."^"..prev..".png" preview = preview.."^"..prev..".png"
state = state + stack:get_wear() state = state + stack:get_wear()
count = count + 1 count = count + 1

View File

@ -58,6 +58,9 @@ armor_punch_damage (Enable damage effects) bool true
# Enable migration of old armor inventories. # Enable migration of old armor inventories.
armor_migrate_old_inventory (Migrate old armor inventories) bool true armor_migrate_old_inventory (Migrate old armor inventories) bool true
# Don't show armor on character model.
armor_transparent (Transparent armor) bool false
[shields] [shields]