master
root 2020-11-04 23:10:21 +01:00
parent e1b75eda4a
commit 18cf672d33
110 changed files with 2457 additions and 191 deletions

View File

@ -160,6 +160,22 @@ Adds wear to a single armor itemstack, triggers `on_damage` callbacks and
updates the necessary inventories. Also handles item destruction callbacks
and so should NOT be called from `on_unequip` to avoid an infinite loop.
armor:remove_all(player)
Removes all armors from the player's inventory without triggering any callback.
armor:equip(player, armor_name)
Equip the armor, removing the itemstack from the main inventory if there's one.
armor:unequip(player, armor_name)
Unequip the armor, adding the itemstack to the main inventory.
armor:update_skin(player_name)
Triggers a skin update with the same action as if a field with `skins_set` was submitted.
Item Callbacks:
on_equip = func(player, index, stack)
@ -189,3 +205,8 @@ armor:register_on_update(function(player)
print(player:get_player_name().." armor updated!")
end)
Note:
The player physics modifications won't be applied via `set_physics_override` if `player_physics_locked` is set to 1
in the respective player's meta.

View File

@ -5,6 +5,7 @@ local skin_previews = {}
local use_player_monoids = minetest.global_exists("player_monoids")
local use_armor_monoid = minetest.global_exists("armor_monoid")
local use_pova_mod = minetest.get_modpath("pova")
local use_playerphysics = minetest.global_exists("playerphysics")
local armor_def = setmetatable({}, {
__index = function()
return setmetatable({
@ -103,6 +104,19 @@ armor.config = {
-- Armor Registration
armor.register_armor = function(self, name, def)
def.on_secondary_use = function(itemstack, player)
return armor:equip(player, itemstack)
end
def.on_place = function(itemstack, player, pointed_thing)
if pointed_thing.type == "node" and player and not player:get_player_control().sneak then
local node = minetest.get_node(pointed_thing.under)
local ndef = minetest.registered_nodes[node.name]
if ndef and ndef.on_rightclick then
return ndef.on_rightclick(pointed_thing.under, node, player, itemstack, pointed_thing)
end
end
return armor:equip(player, itemstack)
end
minetest.register_tool(name, def)
end
@ -184,7 +198,7 @@ armor.set_player_armor = function(self, player)
local state = 0
local count = 0
local material = {count=1}
local preview = armor:get_preview(player, name)
local preview = armor:get_preview(name)
local texture = "3d_armor_trans.png"
local physics = {}
local attributes = {}
@ -286,7 +300,14 @@ armor.set_player_armor = function(self, player)
end
player:set_armor_groups(groups)
end
if use_player_monoids then
if use_playerphysics then
playerphysics.remove_physics_factor(player, "speed", "3d_armor:physics")
playerphysics.remove_physics_factor(player, "jump", "3d_armor:physics")
playerphysics.remove_physics_factor(player, "gravity", "3d_armor:physics")
playerphysics.add_physics_factor(player, "speed", "3d_armor:physics", physics.speed)
playerphysics.add_physics_factor(player, "jump", "3d_armor:physics", physics.jump)
playerphysics.add_physics_factor(player, "gravity", "3d_armor:physics", physics.gravity)
elseif use_player_monoids then
player_monoids.speed:add_change(player, physics.speed,
"3d_armor:physics")
player_monoids.jump:add_change(player, physics.jump,
@ -302,7 +323,10 @@ armor.set_player_armor = function(self, player)
})
pova.do_override(player)
else
player:set_physics_override(physics)
local player_physics_locked = player:get_meta():get_int("player_physics_locked")
if player_physics_locked == nil or player_physics_locked == 0 then
player:set_physics_override(physics)
end
end
self.textures[name].armor = texture
self.textures[name].preview = preview
@ -406,11 +430,69 @@ armor.damage = function(self, player, index, stack, use)
end
end
armor.get_player_skin = function(self, player, name)
local meta = player:get_meta()
if player:get_meta():get_string("gender") == "female" then
return "female.png"
armor.get_weared_armor_elements = function(self, player)
local name, inv = self:get_valid_player(player, "[get_weared_armor]")
local weared_armor = {}
if not name then
return
end
for i=1, inv:get_size("armor") do
local item_name = inv:get_stack("armor", i):get_name()
local element = self:get_element(item_name)
if element ~= nil then
weared_armor[element] = item_name
end
end
return weared_armor
end
armor.equip = function(self, player, itemstack)
local name, armor_inv = self:get_valid_player(player, "[equip]")
local weared_armor = self:get_weared_armor_elements(player)
local armor_element = self:get_element(itemstack:get_name())
if name and armor_element then
if weared_armor[armor_element] ~= nil then
self:unequip(player, armor_element)
end
armor_inv:add_item("armor", itemstack:take_item())
self:set_player_armor(player)
self:save_armor_inventory(player)
end
return itemstack
end
armor.unequip = function(self, player, armor_element)
local name, armor_inv = self:get_valid_player(player, "[unequip]")
local weared_armor = self:get_weared_armor_elements(player)
if not name or not weared_armor[armor_element] then
return
end
local itemstack = armor_inv:remove_item("armor", ItemStack(weared_armor[armor_element]))
minetest.after(0, function()
local inv = player:get_inventory()
if inv:room_for_item("main", itemstack) then
inv:add_item("main", itemstack)
else
minetest.add_item(player:get_pos(), itemstack)
end
end)
self:set_player_armor(player)
self:save_armor_inventory(player)
end
armor.remove_all = function(self, player)
local name, inv = self:get_valid_player(player, "[remove_all]")
if not name then
return
end
inv:set_list("armor", {})
self:set_player_armor(player)
self:save_armor_inventory(player)
end
armor.get_player_skin = function(self, name)
local player = minetest.get_player_by_name(name)
local meta = player:get_meta()
if (self.skin_mod == "skins" or self.skin_mod == "simple_skins") and skins.skins[name] then
return skins.skins[name]..".png"
elseif self.skin_mod == "u_skins" and u_skins.u_skins[name] then
@ -418,7 +500,21 @@ armor.get_player_skin = function(self, player, name)
elseif self.skin_mod == "wardrobe" and wardrobe.playerSkins and wardrobe.playerSkins[name] then
return wardrobe.playerSkins[name]
end
return armor.default_skin..".png"
if player:get_meta():get_string("gender") == "female" then
return "female.png"
else
return "character.png"
end
end
armor.update_skin = function(self, name)
minetest.after(0, function()
local pplayer = minetest.get_player_by_name(name)
if pplayer then
self.textures[name].skin = self:get_player_skin(name)
self:set_player_armor(pplayer)
end
end)
end
armor.add_preview = function(self, preview)

View File

@ -246,7 +246,7 @@ local function init_player_armor(initplayer)
for group, _ in pairs(armor.registered_groups) do
armor.def[name].groups[group] = 0
end
local skin = armor:get_player_skin(initplayer, name)
local skin = armor:get_player_skin(name)
armor.textures[name] = {
skin = skin,
armor = "3d_armor_trans.png",
@ -311,14 +311,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
local player_name = player:get_player_name()
for field, _ in pairs(fields) do
if string.find(field, "skins_set") then
minetest.after(0, function()
local pplayer = minetest.get_player_by_name(player_name)
if player then
local skin = armor:get_player_skin(player, name)
armor.textures[name].skin = skin
armor:set_player_armor(pplayer)
end
end)
armor:update_skin(player_name)
end
end
end)

View File

@ -3,9 +3,9 @@
### api.lua ###
3d_armor: Detached armor inventory is nil @1=3d_armor: L'inventario staccato dell'armatura è nullo @1
3d_armor: Player name is nil @1=3d_armor: Il nome della/del gicatrice/tore è nullo @1
3d_armor: Player reference is nil @1=3d_armor: Il riferimento alla/al giocatrice/tore è nullo @1
3d_armor: Detached armor inventory is nil @1=3d_armor: L'inventario separato dell'armatura è nullo @1
3d_armor: Player name is nil @1=3d_armor: Il nome dell'utente è nullo @1
3d_armor: Player reference is nil @1=3d_armor: Il riferimento all'utente è nullo @1
### armor.lua ###
@ -37,10 +37,10 @@ Mithril Boots=Stivali di mithril
Mithril Chestplate=Corazza di mithril
Mithril Helmet=Elmo di mithril
Mithril Leggings=Gambali di mithril
Steel Boots=Stivali di acciaio
Steel Chestplate=Corazza di acciaio
Steel Helmet=Elmo di acciaio
Steel Leggings=Gambali di acciaio
Steel Boots=Stivali d'acciaio
Steel Chestplate=Corazza d'acciaio
Steel Helmet=Elmo d'acciaio
Steel Leggings=Gambali d'acciaio
Wood Boots=Stivali di legno
Wood Chestplate=Corazza di legno
Wood Helmet=Elmo di legno
@ -48,28 +48,28 @@ Wood Leggings=Gambali di legno
### init.lua ###
3d_armor: Failed to initialize player=3d_armor: Inizializzazione della/del giocatrice/tore fallita
3d_armor: Failed to initialize player=3d_armor: Inizializzazione dell'utente fallita
Fire=Fuoco
Heal=Guarigione
Level=Livello
Radiation=Radiazione
Your @1 got destroyed!=Il/i vostro/i @1 è/sono stato/i distrutto/i!
Your @1 is almost broken!=
Your @1 got destroyed!=@1 in frantumi!
Your @1 is almost broken!=@1 quasi in frantumi!
[3d_armor] Fire Nodes disabled=[3d_armor] Nodi fuoco disabilitati
##### not used anymore #####
3d_armor_ip: Mod loaded but unused.=3d_armor_ip: Mod caricato ma inutilizzato.
3d_armor_ip: Mod loaded but unused.=3d_armor_ip: Mod caricata ma inutilizzata.
Back=Indietro
Armor=Armatura
3d_armor_sfinv: Mod loaded but unused.=3d_armor_sfinv: Mod caricato ma inutilizzato.
3d_armor_sfinv: Mod loaded but unused.=3d_armor_sfinv: Mod caricata ma inutilizzata.
Armor stand top=Parte superiore del supporto per armatura
Armor stand=Supporto per armatura
Armor Stand=Supporto per armatura
Locked Armor stand=Supporto per armatura chiuso a chiave
Armor Stand (owned by @1)=Supporto per armatura (di proprietà di @1)
3d_armor_ui: Mod loaded but unused.=3d_armor_ui: Mod caricato ma inutilizzato.
3d_armor_ui: Mod loaded but unused.=3d_armor_ui: Mod caricata ma inutilizzata.
3d Armor=Armatura 3D
Armor not initialized!=Armatura non inizializzata!
Admin Shield=Scudo dell'amministratrice/tore
@ -77,7 +77,7 @@ Wooden Shield=Scudo di legno
Enhanced Wood Shield=Scudo di legno migliorato
Cactus Shield=Scudo di cactus
Enhanced Cactus Shield=Scudo di cactus migliorato
Steel Shield=Scudo di acciaio
Steel Shield=Scudo d'acciaio
Bronze Shield=Scudo di bronzo
Diamond Shield=Scudo di diamante
Gold Shield=Scudo d'oro

View File

@ -86,20 +86,36 @@ end
-- Decoration
--
local place_on
local biomes
local offset
local scale
if minetest.get_modpath("rainf") then
place_on = "rainf:meadow"
biomes = "rainf"
offset = 0.01
scale = 0.001
else
place_on = "default:dirt_with_grass"
biomes = "grassland"
offset = 0.008
scale = 0.001
end
minetest.register_decoration({
deco_type = "schematic",
place_on = {"rainf:meadow"},
place_on = {place_on},
sidelen = 16,
noise_params = {
offset = 0.01,
scale = 0.001,
offset = offset,
scale = scale,
spread = {x = 255, y = 255, z = 255},
seed = 32,
octaves = 3,
persist = 0.67
},
biomes = {"rainf"},
biomes = {biomes},
y_min = 1,
y_max = 80,
schematic = birch.birchtree,
@ -252,3 +268,20 @@ if minetest.get_modpath("bonemeal") ~= nil then
{"birch:sapling", grow_new_birch_tree, "soil"},
})
end
--Door
if minetest.get_modpath("doors") ~= nil then
doors.register("door_birch_wood", {
tiles = {{ name = "birch_door_wood.png", backface_culling = true }},
description = S("Birch Wood Door"),
inventory_image = "birch_item_wood.png",
groups = {node = 1, choppy = 2, oddly_breakable_by_hand = 2, flammable = 2},
recipe = {
{"birch:wood", "birch:wood"},
{"birch:wood", "birch:wood"},
{"birch:wood", "birch:wood"},
}
})
end

View File

@ -7,4 +7,5 @@ Birch Tree Stair=Escaleras de abedul
Birch Tree Slab=Losa de abedul
Inner Birch Tree Stair=Escaleras de abedul interior
Outer Birch Tree Stair=Escaleras de abedul exterior
Birch Slab=Losa de abedul
Birch Slab=Losa de abedul
Birch Wood Door=Puerta de abedul

View File

@ -1,4 +1,4 @@
name = birch
description = Birch Tree for Grassland
depends = rainf, default
optional_depends = stairs, bonemeal
depends = default
optional_depends = stairs, bonemeal, rainf, doors

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -67,19 +67,37 @@ end
--
if mg_name ~= "v6" and mg_name ~= "singlenode" then
local place_on
local biomes
local offset
local scale
if minetest.get_modpath("rainf") then
place_on = "rainf:meadow"
biomes = "rainf"
offset = 0.0008
scale = 0.00004
else
place_on = "default:dirt_with_grass"
biomes = "grassland"
offset = 0.00005
scale = 0.00004
end
minetest.register_decoration({
deco_type = "schematic",
place_on = {"rainf:meadow"},
place_on = {place_on},
sidelen = 16,
noise_params = {
offset = 0.0008,
scale = 0.00004,
offset = offset,
scale = scale,
spread = {x = 250, y = 250, z = 250},
seed = 278,
octaves = 3,
persist = 0.66
},
biomes = {"rainf"},
biomes = {biomes},
y_min = 1,
y_max = 80,
schematic = modpath.."/schematics/chestnuttree.mts",
@ -232,3 +250,19 @@ if minetest.get_modpath("bonemeal") ~= nil then
{"chestnuttree:sapling", grow_new_chestnuttree_tree, "soil"},
})
end
--Door
if minetest.get_modpath("doors") ~= nil then
doors.register("door_chestnut_wood", {
tiles = {{ name = "chesnuttree_door_wood.png", backface_culling = true }},
description = S("Chestnut Wood Door"),
inventory_image = "chestnuttree_item_wood.png",
groups = {node = 1, choppy = 2, oddly_breakable_by_hand = 2, flammable = 2},
recipe = {
{"chestnuttree:wood", "chestnuttree:wood"},
{"chestnuttree:wood", "chestnuttree:wood"},
{"chestnuttree:wood", "chestnuttree:wood"},
}
})
end

View File

@ -8,4 +8,5 @@ Chestnut Tree Slab=Losa de castaño
Chestnut Tree Stair=Escalera de castaño
Chestnut Tree Sapling=Retoño de castaño
Chestnut Tree Trunk=Madera de castaño
Chestnut Tree Wood=Tablas de castaño
Chestnut Tree Wood=Tablas de castaño
Chestnut Wood Door=Puerta de castaño

View File

@ -1,4 +1,4 @@
name = chestnuttree
description = Chesnut Tree for Grassland
depends = rainf, default
optional_depends = stairs, bonemeal
depends = default
optional_depends = stairs, bonemeal, rainf, doors

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

View File

@ -213,3 +213,20 @@ if minetest.get_modpath("bonemeal") ~= nil then
{"clementinetree:sapling", grow_new_clementinetree_tree, "soil"},
})
end
--Door
if minetest.get_modpath("doors") ~= nil then
doors.register("door_clementinetree_wood", {
tiles = {{ name = "clementinetree_door_wood.png", backface_culling = true }},
description = S("Clementine Wood Door"),
inventory_image = "clementinetree_item_wood.png",
groups = {node = 1, choppy = 2, oddly_breakable_by_hand = 2, flammable = 2},
recipe = {
{"clementinetree:wood", "clementinetree:wood"},
{"clementinetree:wood", "clementinetree:wood"},
{"clementinetree:wood", "clementinetree:wood"},
}
})
end

View File

@ -7,4 +7,5 @@ Clementine Tree Slab=Losa de clementinero
Clementine Tree Stair=Escalera de clementinero
Clementine Tree Sapling=Retoño de clementinero
Clementine Tree Trunk=Madera de clementinero
Clementine Tree Wood=Tablas de clementinero
Clementine Tree Wood=Tablas de clementinero
Clementine Wood Door=Puerta de clementinero

View File

@ -1,4 +1,4 @@
name = clementinetree
description = Clementine Tree for Decidious Forest
depends = default
optional_depends = stairs, bonemeal
optional_depends = stairs, bonemeal, doors

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View File

@ -25,19 +25,37 @@ end
--
if mg_name ~= "v6" and mg_name ~= "singlenode" then
local place_on
local biomes
local offset
local scale
if minetest.get_modpath("rainf") then
place_on = "rainf:meadow"
biomes = "rainf"
offset = 0.0008
scale = 0.00005
else
place_on = "default:dirt_with_grass"
biomes = "grassland"
offset = 0.00008
scale = 0.00005
end
minetest.register_decoration({
deco_type = "schematic",
place_on = {"rainf:meadow"},
place_on = {place_on},
sidelen = 16,
noise_params = {
offset = 0.0008,
scale = 0.00005,
offset = offset,
scale = scale,
spread = {x = 250, y = 250, z = 250},
seed = 789,
octaves = 3,
persist = 0.66
},
biomes = {"rainf"},
biomes = {biomes},
y_min = 1,
y_max = 32,
schematic = modpath.."/schematics/hollytree.mts",

View File

@ -1,4 +1,4 @@
name = hollytree
description = Hollytree
depends = rainf, default
optional_depends = stairs, bonemeal
depends = default
optional_depends = stairs, bonemeal, rainf

View File

@ -214,3 +214,20 @@ if minetest.get_modpath("bonemeal") ~= nil then
{"larch:sapling", grow_new_larch_tree, "soil"},
})
end
--Door
if minetest.get_modpath("doors") ~= nil then
doors.register("door_larch_wood", {
tiles = {{ name = "larch_door_wood.png", backface_culling = true }},
description = S("Larch Wood Door"),
inventory_image = "larch_item_wood.png",
groups = {node = 1, choppy = 2, oddly_breakable_by_hand = 2, flammable = 2},
recipe = {
{"larch:wood", "larch:wood"},
{"larch:wood", "larch:wood"},
{"larch:wood", "larch:wood"},
}
})
end

View File

@ -2,4 +2,8 @@
Larch Sapling=Retoño de alerce
Larch Trunk=Madera de alerce
Larch Wood=Tablas de alerce
Larch Leaves=Hojas de alerce
Larch Leaves=Hojas de alerce
Larch Tree Outer Stair=Escalera exterior de alerce
Larch Tree Slab=Losa de alerce
Larch Stair=Escalera de alerce
Larch Wood Door=Puerta de alerce

View File

@ -1,3 +1,3 @@
name = larch
description = Larch Tree
optional_depends = stairs, bonemeal
optional_depends = stairs, bonemeal, doors

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -1,4 +1,4 @@
name = mahogany
description = Mahogany Tree for Rainforest Biome
depends = default
optional_depends = stairs, bonemeal
optional_depends = stairs, bonemeal, rainf

View File

@ -26,19 +26,32 @@ end
--
if mg_name ~= "v6" and mg_name ~= "singlenode" then
if minetest.get_modpath("rainf") then
place_on = "rainf:meadow"
biomes = "rainf"
offset = 0.0005
scale = 0.0002
else
place_on = "default:dirt_with_grass"
biomes = "grassland"
offset = 0.0002
scale = 0.0002
end
minetest.register_decoration({
deco_type = "schematic",
place_on = {"rainf:meadow"},
place_on = {place_on},
sidelen = 16,
noise_params = {
offset = 0.0005,
scale = 0.0002,
offset = offset,
scale = scale,
spread = {x = 250, y = 250, z = 250},
seed = 3462,
octaves = 3,
persist = 0.66
},
biomes = {"rainf"},
biomes = {biomes},
y_min = 1,
y_max = 62,
schematic = modpath.."/schematics/maple.mts",
@ -192,3 +205,21 @@ if minetest.get_modpath("bonemeal") ~= nil then
{"maple:sapling", grow_new_maple_tree, "soil"},
})
end
--Door
if minetest.get_modpath("doors") ~= nil then
doors.register("door_maple_wood", {
tiles = {{ name = "maple_door_wood.png", backface_culling = true }},
description = S("Maple Wood Door"),
inventory_image = "maple_item_wood.png",
groups = {node = 1, choppy = 2, oddly_breakable_by_hand = 2, flammable = 2},
recipe = {
{"maple:wood", "maple:wood"},
{"maple:wood", "maple:wood"},
{"maple:wood", "maple:wood"},
}
})
end

View File

@ -7,3 +7,4 @@ Maple Stair=Escaleras de arce
Inner Maple Stair=Escaleras de arce
Outer Maple Stair=Escaleras de arce
Maple Slab=Losa de arce
Maple Wood Door=Puerta de arce

View File

@ -1,4 +1,4 @@
name = maple
description = Maple Tree
depends = rainf, default
optional_depends = stairs, bonemeal
depends = default
optional_depends = stairs, bonemeal, rainf, doors

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

View File

@ -51,19 +51,32 @@ end
--
if mg_name ~= "v6" and mg_name ~= "singlenode" then
if minetest.get_modpath("rainf") then
place_on = "rainf:meadow"
biomes = "rainf"
offset = 0.0008
scale = 0.00004
else
place_on = "default:dirt_with_grass"
biomes = "grassland"
offset = 0.0008
scale = 0.00004
end
minetest.register_decoration({
deco_type = "schematic",
place_on = {"rainf:meadow"},
place_on = {place_on},
sidelen = 16,
noise_params = {
offset = 0.0008,
scale = 0.00004,
offset = offset,
scale = scale,
spread = {x = 250, y = 250, z = 250},
seed = 6431,
octaves = 3,
persist = 0.66
},
biomes = {"rainf"},
biomes = {biomes},
y_min = 1,
y_max = 80,
schematic = modpath.."/schematics/oak.mts",
@ -216,3 +229,17 @@ if minetest.get_modpath("bonemeal") ~= nil then
{"oak:sapling", grow_new_oak_tree, "soil"},
})
end
if minetest.get_modpath("doors") ~= nil then
doors.register("door_oak_wood", {
tiles = {{ name = "oak_door_wood.png", backface_culling = true }},
description = S("Oak Wood Door"),
inventory_image = "oak_item_wood.png",
groups = {node = 1, choppy = 2, oddly_breakable_by_hand = 2, flammable = 2},
recipe = {
{"oak:wood", "oak:wood"},
{"oak:wood", "oak:wood"},
{"oak:wood", "oak:wood"},
}
})
end

View File

@ -8,3 +8,4 @@ Oak Leaves=Hojas de roble
Oak Outer Stair=Escalera exterior de roble
Oak Slab=Losa de roble
Oak Stair=Escalera de roble
Oak Wood Door=Puerta de roble

View File

@ -1,4 +1,4 @@
name = oak
description = Oak Tree
depends = rainf, default
optional_depends = stairs, bonemeal
depends = default
optional_depends = stairs, bonemeal, rainf, doors

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -81,6 +81,21 @@ local function lay_down(player, pos, bed_pos, state, skip)
-- lay down
else
-- Check if bed is occupied
for _, other_pos in pairs(beds.bed_position) do
if vector.distance(bed_pos, other_pos) < 0.1 then
minetest.chat_send_player(name, S("This bed is already occupied!"))
return false
end
end
-- Check if player is moving
if vector.length(player:get_player_velocity()) > 0.001 then
minetest.chat_send_player(name, S("You have to stop moving before going to bed!"))
return false
end
beds.pos[name] = pos
beds.bed_position[name] = bed_pos
beds.player[name] = 1
@ -230,6 +245,19 @@ minetest.register_on_leaveplayer(function(player)
end
end)
minetest.register_on_dieplayer(function(player)
local name = player:get_player_name()
local in_bed = beds.player
local pos = player:get_pos()
local yaw = get_look_yaw(pos)
if in_bed[name] then
lay_down(player, nil, pos, false)
player:set_look_horizontal(yaw)
player:set_pos(pos)
end
end)
minetest.register_on_player_receive_fields(function(player, formname, fields)
if formname ~= "beds_form" then
return
@ -256,3 +284,4 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
end
end
end)

View File

@ -62,8 +62,8 @@ for i in ipairs (butter_list) do
minetest.register_node("butterflies:hidden_butterfly_"..name, {
drawtype = "airlike",
inventory_image = "butterflies_butterfly_"..name..".png",
wield_image = "butterflies_butterfly_"..name..".png",
inventory_image = "butterflies_butterfly_"..name..".png^default_invisible_node_overlay.png",
wield_image = "butterflies_butterfly_"..name..".png^default_invisible_node_overlay.png",
paramtype = "light",
sunlight_propagates = true,
walkable = false,

View File

@ -264,32 +264,17 @@ Glass breaking sounds (CC BY 3.0):
3: http://www.freesound.org/people/lsprice/sounds/88808/
Mito551 (sounds) (CC BY-SA 3.0):
default_dig_choppy.ogg
default_dig_cracky.ogg
default_dig_crumbly.1.ogg
default_dig_crumbly.2.ogg
default_dig_crumbly.*.ogg
default_dig_dig_immediate.ogg
default_dig_oddly_breakable_by_hand.ogg
default_dug_node.1.ogg
default_dug_node.2.ogg
default_dug_node.*.ogg
default_grass_footstep.1.ogg
default_grass_footstep.2.ogg
default_grass_footstep.3.ogg
default_gravel_footstep.1.ogg
default_gravel_footstep.2.ogg
default_gravel_footstep.3.ogg
default_gravel_footstep.4.ogg
default_grass_footstep.1.ogg
default_place_node.1.ogg
default_place_node.2.ogg
default_place_node.3.ogg
default_place_node_hard.1.ogg
default_place_node_hard.2.ogg
default_hard_footstep.1.ogg
default_hard_footstep.2.ogg
default_hard_footstep.3.ogg
default_sand_footstep.1.ogg
default_sand_footstep.2.ogg
default_gravel_footstep.*.ogg
default_place_node.*.ogg
default_place_node_hard.*.ogg
default_glass_footstep.ogg
default_wood_footstep.1.ogg
default_wood_footstep.2.ogg
default_dirt_footstep.1.ogg
@ -301,8 +286,8 @@ Metal sounds:
- https://www.freesound.org/people/yadronoff/sounds/320397/
default_dug_metal.*.ogg - Iwan Gabovitch - qubodup - CC0
- http://opengameart.org/users/qubodup
default_metal_footstep.*.ogg - Ottomaani138 - CC0
- https://www.freesound.org/people/Ottomaani138/sounds/232692/
default_metal_footstep.*.ogg - (CC0 1.0) - CC0 1.0
- https://freesound.org/people/mypantsfelldown/sounds/398937/
default_place_node_metal.*.ogg - Ogrebane - CC0
- http://opengameart.org/content/wood-and-metal-sound-effects-volume-2
@ -340,6 +325,39 @@ sonictechtonic (CC BY 3.0):
https://www.freesound.org/people/sonictechtonic/sounds/241872/
player_damage.ogg
Sheyvan (CC0 1.0):
https://freesound.org/people/Sheyvan/sounds/476113/
default_dig_choppy.*.ogg
lolamadeus (CC0 1.0):
https://freesound.org/people/lolamadeus/sounds/179341/
default_gravel_dig.*.ogg
default_gravel_dug.*.ogg
Benboncan (CC BY 3.0):
https://freesound.org/people/Benboncan/sounds/71823/
default_dig_cracky.*.ogg
Erdie (CC BY 3.0):
https://freesound.org/people/Erdie/sounds/41579/
default_hard_footstep.*.ogg
worthahep88 (CC0 1.0):
https://freesound.org/people/worthahep88/sounds/319224/
default_sand_footstep.*.ogg
dheming (CC BY 3.0):
https://freesound.org/people/dheming/sounds/268023/
default_ice_dig.*.ogg
InspectorJ (CC BY 3.0):
https://freesound.org/people/InspectorJ/sounds/416967/
default_ice_footstep.*.ogg
Angel_Perez_Grandi (CC BY 3.0):
https://freesound.org/people/Angel_Perez_Grandi/sounds/49190/
default_ice_dug.ogg
iankath (CC0 1.0)
https://freesound.org/people/iankath/sounds/173991/
default_furnace_active.ogg

View File

@ -300,15 +300,6 @@ minetest.register_craft({
}
})
minetest.register_craft({
output = "default:mese_post_light 3",
recipe = {
{"", "default:glass", ""},
{"default:mese_crystal", "default:mese_crystal", "default:mese_crystal"},
{"", "group:wood", ""},
}
})
minetest.register_craft({
output = "default:obsidian",
recipe = {

View File

@ -38,9 +38,9 @@ end
function default.node_sound_sand_defaults(table)
table = table or {}
table.footstep = table.footstep or
{name = "default_sand_footstep", gain = 0.12}
{name = "default_sand_footstep", gain = 0.05}
table.dug = table.dug or
{name = "default_sand_footstep", gain = 0.24}
{name = "default_sand_footstep", gain = 0.15}
table.place = table.place or
{name = "default_place_node", gain = 1.0}
default.node_sound_defaults(table)
@ -50,9 +50,11 @@ end
function default.node_sound_gravel_defaults(table)
table = table or {}
table.footstep = table.footstep or
{name = "default_gravel_footstep", gain = 0.4}
{name = "default_gravel_footstep", gain = 0.1}
table.dig = table.dig or
{name = "default_gravel_dig", gain = 0.35}
table.dug = table.dug or
{name = "default_gravel_footstep", gain = 1.0}
{name = "default_gravel_dug", gain = 1.0}
table.place = table.place or
{name = "default_place_node", gain = 1.0}
default.node_sound_defaults(table)
@ -93,6 +95,18 @@ function default.node_sound_glass_defaults(table)
return table
end
function default.node_sound_ice_defaults(table)
table = table or {}
table.footstep = table.footstep or
{name = "default_ice_footstep", gain = 0.3}
table.dig = table.dig or
{name = "default_ice_dig", gain = 0.5}
table.dug = table.dug or
{name = "default_ice_dug", gain = 0.5}
default.node_sound_defaults(table)
return table
end
function default.node_sound_metal_defaults(table)
table = table or {}
table.footstep = table.footstep or
@ -421,6 +435,51 @@ function default.register_fence_rail(name, def)
minetest.register_node(name, def)
end
--
-- Mese post registration helper
--
function default.register_mesepost(name, def)
minetest.register_craft({
output = name .. " 4",
recipe = {
{'', 'default:glass', ''},
{'default:mese_crystal', 'default:mese_crystal', 'default:mese_crystal'},
{'', def.material, ''},
}
})
local post_texture = def.texture .. "^default_mese_post_light_side.png^[makealpha:0,0,0"
local post_texture_dark = def.texture .. "^default_mese_post_light_side_dark.png^[makealpha:0,0,0"
-- Allow almost everything to be overridden
local default_fields = {
wield_image = post_texture,
drawtype = "nodebox",
node_box = {
type = "fixed",
fixed = {
{-2 / 16, -8 / 16, -2 / 16, 2 / 16, 8 / 16, 2 / 16},
},
},
paramtype = "light",
tiles = {def.texture, def.texture, post_texture_dark, post_texture_dark, post_texture, post_texture},
light_source = default.LIGHT_MAX,
sunlight_propagates = true,
is_ground_content = false,
groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2},
sounds = default.node_sound_wood_defaults(),
}
for k, v in pairs(default_fields) do
if def[k] == nil then
def[k] = v
end
end
def.texture = nil
def.material = nil
minetest.register_node(name, def)
end
--
-- Leafdecay

View File

@ -318,6 +318,10 @@ minetest.register_node("default:furnace", {
-- start timer function, it will sort out whether furnace can burn or not.
minetest.get_node_timer(pos):start(1.0)
end,
on_metadata_inventory_take = function(pos)
-- check whether the furnace is empty or not.
minetest.get_node_timer(pos):start(1.0)
end,
on_blast = function(pos)
local drops = {}
default.get_inventory_drops(pos, "src", drops)

View File

@ -74,5 +74,5 @@ local item = {
}
-- set defined item as new __builtin:item, with the old one as fallback table
setmetatable(item, builtin_item)
setmetatable(item, { __index = builtin_item })
minetest.register_entity(":__builtin:item", item)

View File

@ -59,15 +59,18 @@ Silver Sandstone Block=银砂岩方块
Obsidian=黑曜石
Obsidian Brick=黑曜石砖
Obsidian Block=黑曜石方块
Dirt=土
Dirt with Grass=带草的土
Dirt with Grass and Footsteps=带草的土及脚印
Dirt with Dry Grass=带干草的土
Dirt with Snow=带雪的土
Dirt=土方块
Dirt with Grass=草方块
Dirt with Grass and Footsteps=草方块及脚印
Dirt with Dry Grass=干草土方块
Dirt with Snow=雪土方块
Dirt with Rainforest Litter=雨林腐土
Dirt with Coniferous Litter=针叶林腐土
Dry Dirt=干土
Dry Dirt with Dry Grass=干土和干草
Savanna Dirt=草原土
Dirt with Savanna Grass=草原草方块
Savanna Dirt with Savanna Grass=草原草方块(草原土)
Permafrost=多年冻土
Permafrost with Stones=带石头的多年冻土
Permafrost with Moss=生苔的多年冻土
@ -174,7 +177,13 @@ Glass=玻璃
Obsidian Glass=黑曜石玻璃
Brick Block=砖方块
Mese Lamp=黄石灯
Mese Post Light=黄石柱灯
Apple Wood Mese Post Light=苹果木黄石灯柱
Acacia Wood Mese Post Light=金合欢木黄石灯柱
Aspen Wood Mese Post Light=白杨木黄石灯柱
Jungle Wood Mese Post Light=丛林木黄石灯柱
Pine Wood Mese Post Light=松木黄石灯柱
Cloud=云
Wooden Pickaxe=木镐
Stone Pickaxe=石镐

View File

@ -59,15 +59,18 @@ Silver Sandstone Block=銀砂岩方塊
Obsidian=黑曜石
Obsidian Brick=黑曜石磚
Obsidian Block=黑曜石方塊
Dirt=土
Dirt with Grass=帶草的土
Dirt with Grass and Footsteps=帶草的土及腳印
Dirt with Dry Grass=帶乾草的土
Dirt with Snow=帶雪的土
Dirt=土方塊
Dirt with Grass=草方塊
Dirt with Grass and Footsteps=草方塊及腳印
Dirt with Dry Grass=乾草土方塊
Dirt with Snow=雪土方塊
Dirt with Rainforest Litter=雨林腐土
Dirt with Coniferous Litter=針葉林腐土
Dry Dirt=乾土
Dry Dirt with Dry Grass=乾土和乾草
Savanna Dirt=草原土
Dirt with Savanna Grass=草原草方塊
Savanna Dirt with Savanna Grass=草原草方塊(草原土)
Permafrost=多年凍土
Permafrost with Stones=帶石頭的多年凍土
Permafrost with Moss=生苔的多年凍土
@ -174,7 +177,13 @@ Glass=玻璃
Obsidian Glass=黑曜石玻璃
Brick Block=磚方塊
Mese Lamp=黃石燈
Mese Post Light=黃石柱燈
Apple Wood Mese Post Light=蘋果木黃石燈柱
Acacia Wood Mese Post Light=金合歡木黃石燈柱
Aspen Wood Mese Post Light=白楊木黃石燈柱
Jungle Wood Mese Post Light=叢林木黃石燈柱
Pine Wood Mese Post Light=松木黃石燈柱
Cloud=雲
Wooden Pickaxe=木鎬
Stone Pickaxe=石鎬

View File

@ -221,6 +221,10 @@ default:brick
default:meselamp
default:mese_post_light
default:mese_post_light_acacia_wood
default:mese_post_light_junglewood
default:mese_post_light_pine_wood
default:mese_post_light_aspen_wood
Misc
----
@ -656,7 +660,7 @@ minetest.register_node("default:ice", {
is_ground_content = false,
paramtype = "light",
groups = {cracky = 3, cools_lava = 1, slippery = 3},
sounds = default.node_sound_glass_defaults(),
sounds = default.node_sound_ice_defaults(),
})
-- Mapgen-placed ice with 'is ground content = true' to contain tunnels
@ -667,7 +671,7 @@ minetest.register_node("default:cave_ice", {
groups = {cracky = 3, cools_lava = 1, slippery = 3,
not_in_creative_inventory = 1},
drop = "default:ice",
sounds = default.node_sound_glass_defaults(),
sounds = default.node_sound_ice_defaults(),
})
--
@ -792,6 +796,8 @@ minetest.register_node("default:apple", {
minetest.register_node("default:apple_mark", {
description = S("Apple Marker"),
inventory_image = "default_apple.png^default_invisible_node_overlay.png",
wield_image = "default_apple.png^default_invisible_node_overlay.png",
drawtype = "airlike",
paramtype = "light",
sunlight_propagates = true,
@ -1588,6 +1594,7 @@ end
minetest.register_node("default:fern_1", {
description = S("Fern"),
drawtype = "plantlike",
visual_scale = 0.8,
waving = 1,
tiles = {"default_fern_1.png"},
inventory_image = "default_fern_1.png",
@ -1617,7 +1624,7 @@ for i = 2, 3 do
description = S("Fern"),
drawtype = "plantlike",
waving = 1,
visual_scale = 2,
visual_scale = 1.0,
tiles = {"default_fern_" .. i .. ".png"},
inventory_image = "default_fern_" .. i .. ".png",
wield_image = "default_fern_" .. i .. ".png",
@ -1708,7 +1715,6 @@ minetest.register_node("default:bush_stem", {
minetest.register_node("default:bush_leaves", {
description = S("Bush Leaves"),
drawtype = "allfaces_optional",
waving = 1,
tiles = {"default_leaves_simple.png"},
paramtype = "light",
groups = {snappy = 3, flammable = 2, leaves = 1},
@ -1762,7 +1768,6 @@ minetest.register_node("default:bush_sapling", {
minetest.register_node("default:blueberry_bush_leaves_with_berries", {
description = S("Blueberry Bush Leaves with Berries"),
drawtype = "allfaces_optional",
waving = 1,
tiles = {"default_blueberry_bush_leaves.png^default_blueberry_overlay.png"},
paramtype = "light",
groups = {snappy = 3, flammable = 2, leaves = 1, dig_immediate = 3},
@ -1779,7 +1784,6 @@ minetest.register_node("default:blueberry_bush_leaves_with_berries", {
minetest.register_node("default:blueberry_bush_leaves", {
description = S("Blueberry Bush Leaves"),
drawtype = "allfaces_optional",
waving = 1,
tiles = {"default_blueberry_bush_leaves.png"},
paramtype = "light",
groups = {snappy = 3, flammable = 2, leaves = 1},
@ -1858,7 +1862,6 @@ minetest.register_node("default:acacia_bush_stem", {
minetest.register_node("default:acacia_bush_leaves", {
description = S("Acacia Bush Leaves"),
drawtype = "allfaces_optional",
waving = 1,
tiles = {"default_acacia_leaves_simple.png"},
paramtype = "light",
groups = {snappy = 3, flammable = 2, leaves = 1},
@ -1929,7 +1932,6 @@ minetest.register_node("default:pine_bush_stem", {
minetest.register_node("default:pine_bush_needles", {
description = S("Pine Bush Needles"),
drawtype = "allfaces_optional",
waving = 1,
tiles = {"default_pine_needles.png"},
paramtype = "light",
groups = {snappy = 3, flammable = 2, leaves = 1},
@ -1980,6 +1982,7 @@ minetest.register_node("default:pine_bush_sapling", {
end,
})
minetest.register_node("default:sand_with_kelp", {
description = S("Kelp"),
drawtype = "plantlike_rooted",
@ -2873,25 +2876,34 @@ minetest.register_node("default:meselamp", {
light_source = default.LIGHT_MAX,
})
minetest.register_node("default:mese_post_light", {
description = S("Mese Post Light"),
tiles = {"default_mese_post_light_top.png", "default_mese_post_light_top.png",
"default_mese_post_light_side_dark.png", "default_mese_post_light_side_dark.png",
"default_mese_post_light_side.png", "default_mese_post_light_side.png"},
wield_image = "default_mese_post_light_side.png",
drawtype = "nodebox",
node_box = {
type = "fixed",
fixed = {
{-2 / 16, -8 / 16, -2 / 16, 2 / 16, 8 / 16, 2 / 16},
},
},
paramtype = "light",
light_source = default.LIGHT_MAX,
sunlight_propagates = true,
is_ground_content = false,
groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2},
sounds = default.node_sound_wood_defaults(),
default.register_mesepost("default:mese_post_light", {
description = S("Apple Wood Mese Post Light"),
texture = "default_fence_wood.png",
material = "default:wood",
})
default.register_mesepost("default:mese_post_light_acacia", {
description = S("Acacia Wood Mese Post Light"),
texture = "default_fence_acacia_wood.png",
material = "default:acacia_wood",
})
default.register_mesepost("default:mese_post_light_junglewood", {
description = S("Jungle Wood Mese Post Light"),
texture = "default_fence_junglewood.png",
material = "default:junglewood",
})
default.register_mesepost("default:mese_post_light_pine_wood", {
description = S("Pine Wood Mese Post Light"),
texture = "default_fence_pine_wood.png",
material = "default:pine_wood",
})
default.register_mesepost("default:mese_post_light_aspen_wood", {
description = S("Aspen Wood Mese Post Light"),
texture = "default_fence_aspen_wood.png",
material = "default:aspen_wood",
})
--

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 851 B

After

Width:  |  Height:  |  Size: 294 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 851 B

After

Width:  |  Height:  |  Size: 301 B

View File

@ -78,6 +78,8 @@ end
-- nodes from being placed in the top half of the door.
minetest.register_node("doors:hidden", {
description = S("Hidden Door Segment"),
inventory_image = "doors_hidden_segment.png^default_invisible_node_overlay.png",
wield_image = "doors_hidden_segment.png^default_invisible_node_overlay.png",
drawtype = "airlike",
paramtype = "light",
paramtype2 = "facedir",
@ -431,6 +433,7 @@ function doors.register(name, def)
def.sunlight_propagates = true
def.walkable = true
def.is_ground_content = false
use_texture_alpha = true
def.buildable_to = false
def.selection_box = {type = "fixed", fixed = {-1/2,-1/2,-1/2,1/2,3/2,-6/16}}
def.collision_box = {type = "fixed", fixed = {-1/2,-1/2,-1/2,1/2,3/2,-6/16}}

View File

@ -11,7 +11,7 @@ You do not own this trapdoor.=这个活板门不属于你所有。
a locked trapdoor=一扇已上锁的活板门
Wooden Trapdoor=木活板门
Steel Trapdoor=铁活板门
Apple Wood Fence Gate=苹果树做的木栅栏门
Apple Wood Fence Gate=苹果木栅栏门
Acacia Wood Fence Gate=相思木栅栏门
Jungle Wood Fence Gate=丛林木栅栏门
Pine Wood Fence Gate=松木栅栏门

View File

@ -11,7 +11,7 @@ You do not own this trapdoor.=這個活板門不屬於你所有。
a locked trapdoor=一扇已上鎖的活板門
Wooden Trapdoor=木活板門
Steel Trapdoor=鐵活板門
Apple Wood Fence Gate=蘋果樹做的木柵欄門
Apple Wood Fence Gate=蘋果木柵欄門
Acacia Wood Fence Gate=相思木柵欄門
Jungle Wood Fence Gate=叢林木柵欄門
Pine Wood Fence Gate=松木柵欄門

Binary file not shown.

After

Width:  |  Height:  |  Size: 280 B

View File

@ -54,8 +54,8 @@ minetest.register_node("fireflies:firefly", {
minetest.register_node("fireflies:hidden_firefly", {
description = S("Hidden Firefly"),
drawtype = "airlike",
inventory_image = "fireflies_firefly.png",
wield_image = "fireflies_firefly.png",
inventory_image = "fireflies_firefly.png^default_invisible_node_overlay.png",
wield_image = "fireflies_firefly.png^default_invisible_node_overlay.png",
paramtype = "light",
sunlight_propagates = true,
walkable = false,

View File

@ -0,0 +1,3 @@
name = Minetest Game
author = Minetest
description = A basic exploration, mining, crafting and building sandbox game with no NPCs, monsters or animals. Minetest Game is usually used with mods added and many mods are available for this game. Reliably maintained by Minetest Engine core developers.

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,25 @@
Minetest Game mod: mtg_craftguide
=================================
Adds a "Recipes" tab to the inventory. Click an item to see it's recipes.
Click again to show usages.
Based on [craftguide](https://github.com/minetest-mods/craftguide).
Authors of media
----------------
paramat (CC BY-SA 3.0):
* craftguide_clear_icon.png
* craftguide_next_icon.png
* craftguide_prev_icon.png
* craftguide_search_icon.png
Neuromancer (CC BY-SA 3.0):
* craftguide_furnace.png
Wuzzy (CC BY-SA 3.0):
* craftguide_shapeless.png

View File

@ -0,0 +1,432 @@
local S = minetest.get_translator("mtg_craftguide")
local esc = minetest.formspec_escape
local player_data = {}
local init_items = {}
local recipes_cache = {}
local usages_cache = {}
local group_stereotypes = {
dye = "dye:white",
wool = "wool:white",
coal = "default:coal_lump",
vessel = "vessels:glass_bottle",
flower = "flowers:dandelion_yellow"
}
local group_names = {
coal = S("Any coal"),
sand = S("Any sand"),
wool = S("Any wool"),
stick = S("Any stick"),
vessel = S("Any vessel"),
wood = S("Any wood planks"),
stone = S("Any kind of stone block"),
["color_red,flower"] = S("Any red flower"),
["color_blue,flower"] = S("Any blue flower"),
["color_black,flower"] = S("Any black flower"),
["color_green,flower"] = S("Any green flower"),
["color_white,flower"] = S("Any white flower"),
["color_orange,flower"] = S("Any orange flower"),
["color_violet,flower"] = S("Any violet flower"),
["color_yellow,flower"] = S("Any yellow flower"),
["color_red,dye"] = S("Any red dye"),
["color_blue,dye"] = S("Any blue dye"),
["color_cyan,dye"] = S("Any cyan dye"),
["color_grey,dye"] = S("Any grey dye"),
["color_pink,dye"] = S("Any pink dye"),
["color_black,dye"] = S("Any black dye"),
["color_brown,dye"] = S("Any brown dye"),
["color_green,dye"] = S("Any green dye"),
["color_white,dye"] = S("Any white dye"),
["color_orange,dye"] = S("Any orange dye"),
["color_violet,dye"] = S("Any violet dye"),
["color_yellow,dye"] = S("Any yellow dye"),
["color_magenta,dye"] = S("Any magenta dye"),
["color_dark_grey,dye"] = S("Any dark grey dye"),
["color_dark_green,dye"] = S("Any dark green dye")
}
local function table_replace(t, val, new)
for k, v in pairs(t) do
if v == val then
t[k] = new
end
end
end
local function extract_groups(str)
if str:sub(1, 6) == "group:" then
return str:sub(7):split()
end
return nil
end
local function item_has_groups(item_groups, groups)
for _, group in ipairs(groups) do
if not item_groups[group] then
return false
end
end
return true
end
local function groups_to_item(groups)
if #groups == 1 then
local group = groups[1]
if group_stereotypes[group] then
return group_stereotypes[group]
elseif minetest.registered_items["default:"..group] then
return "default:"..group
end
end
for name, def in pairs(minetest.registered_items) do
if item_has_groups(def.groups, groups) then
return name
end
end
return ":unknown"
end
local function get_craftable_recipes(output)
local recipes = minetest.get_all_craft_recipes(output)
if not recipes then
return nil
end
for i = #recipes, 1, -1 do
for _, item in pairs(recipes[i].items) do
local groups = extract_groups(item)
if groups then
item = groups_to_item(groups)
end
if not minetest.registered_items[item] then
table.remove(recipes, i)
break
end
end
end
if #recipes > 0 then
return recipes
end
end
local function show_item(def)
return def.groups.not_in_craft_guide ~= 1 and def.description ~= ""
end
local function cache_usages(recipe)
local added = {}
for _, item in pairs(recipe.items) do
if not added[item] then
local groups = extract_groups(item)
if groups then
for name, def in pairs(minetest.registered_items) do
if not added[name] and show_item(def)
and item_has_groups(def.groups, groups) then
local usage = table.copy(recipe)
table_replace(usage.items, item, name)
usages_cache[name] = usages_cache[name] or {}
table.insert(usages_cache[name], usage)
added[name] = true
end
end
elseif show_item(minetest.registered_items[item]) then
usages_cache[item] = usages_cache[item] or {}
table.insert(usages_cache[item], recipe)
end
added[item] = true
end
end
end
minetest.register_on_mods_loaded(function()
for name, def in pairs(minetest.registered_items) do
if show_item(def) then
local recipes = get_craftable_recipes(name)
if recipes then
recipes_cache[name] = recipes
for _, recipe in ipairs(recipes) do
cache_usages(recipe)
end
end
end
end
for name, def in pairs(minetest.registered_items) do
if recipes_cache[name] or usages_cache[name] then
table.insert(init_items, name)
end
end
table.sort(init_items)
end)
local function coords(i, cols)
return i % cols, math.floor(i / cols)
end
local function is_fuel(item)
return minetest.get_craft_result({method="fuel", items={item}}).time > 0
end
local function item_button_fs(fs, x, y, item, element_name, groups)
table.insert(fs, ("item_image_button[%s,%s;1.05,1.05;%s;%s;%s]")
:format(x, y, item, element_name, groups and "\n"..esc(S("G")) or ""))
local tooltip
if groups then
table.sort(groups)
tooltip = group_names[table.concat(groups, ",")]
if not tooltip then
local groupstr = {}
for _, group in ipairs(groups) do
table.insert(groupstr, minetest.colorize("yellow", group))
end
groupstr = table.concat(groupstr, ", ")
tooltip = S("Any item belonging to the group(s): @1", groupstr)
end
elseif is_fuel(item) then
local itemdef = minetest.registered_items[item:match("%S*")]
local desc = itemdef and itemdef.description or S("Unknown Item")
tooltip = desc.."\n"..minetest.colorize("orange", S("Fuel"))
end
if tooltip then
table.insert(fs, ("tooltip[%s;%s]"):format(element_name, esc(tooltip)))
end
end
local function recipe_fs(fs, data)
local recipe = data.recipes[data.rnum]
local width = recipe.width
local cooktime, shapeless
if recipe.method == "cooking" then
cooktime, width = width, 1
elseif width == 0 then
shapeless = true
if #recipe.items == 1 then
width = 1
elseif #recipe.items <= 4 then
width = 2
else
width = 3
end
end
table.insert(fs, ("label[5.5,1;%s]"):format(esc(data.show_usages
and S("Usage @1 of @2", data.rnum, #data.recipes)
or S("Recipe @1 of @2", data.rnum, #data.recipes))))
if #data.recipes > 1 then
table.insert(fs,
"image_button[5.5,1.6;0.8,0.8;craftguide_prev_icon.png;recipe_prev;]"..
"image_button[6.2,1.6;0.8,0.8;craftguide_next_icon.png;recipe_next;]"..
"tooltip[recipe_prev;"..esc(S("Previous recipe")).."]"..
"tooltip[recipe_next;"..esc(S("Next recipe")).."]")
end
local rows = math.ceil(table.maxn(recipe.items) / width)
if width > 3 or rows > 3 then
table.insert(fs, ("label[0,1;%s]")
:format(esc(S("Recipe is too big to be displayed."))))
return
end
local base_x = 3 - width
local base_y = rows == 1 and 1 or 0
for i, item in pairs(recipe.items) do
local x, y = coords(i - 1, width)
local groups = extract_groups(item)
if groups then
item = groups_to_item(groups)
end
item_button_fs(fs, base_x + x, base_y + y, item, item, groups)
end
if shapeless or recipe.method == "cooking" then
table.insert(fs, ("image[3.2,0.5;0.5,0.5;craftguide_%s.png]")
:format(shapeless and "shapeless" or "furnace"))
local tooltip = shapeless and S("Shapeless") or
S("Cooking time: @1", minetest.colorize("yellow", cooktime))
table.insert(fs, "tooltip[3.2,0.5;0.5,0.5;"..esc(tooltip).."]")
end
table.insert(fs, "image[3,1;1,1;sfinv_crafting_arrow.png]")
item_button_fs(fs, 4, 1, recipe.output, recipe.output:match("%S*"))
end
local function get_formspec(player)
local name = player:get_player_name()
local data = player_data[name]
data.pagemax = math.max(1, math.ceil(#data.items / 32))
local fs = {}
table.insert(fs,
"style_type[item_image_button;padding=2]"..
"field[0.3,4.2;2.8,1.2;filter;;"..esc(data.filter).."]"..
"label[5.8,4.15;"..minetest.colorize("yellow", data.pagenum).." / "..
data.pagemax.."]"..
"image_button[2.63,4.05;0.8,0.8;craftguide_search_icon.png;search;]"..
"image_button[3.25,4.05;0.8,0.8;craftguide_clear_icon.png;clear;]"..
"image_button[5,4.05;0.8,0.8;craftguide_prev_icon.png;prev;]"..
"image_button[7.25,4.05;0.8,0.8;craftguide_next_icon.png;next;]"..
"tooltip[search;"..esc(S("Search")).."]"..
"tooltip[clear;"..esc(S("Reset")).."]"..
"tooltip[prev;"..esc(S("Previous page")).."]"..
"tooltip[next;"..esc(S("Next page")).."]"..
"field_close_on_enter[filter;false]")
if #data.items == 0 then
table.insert(fs, "label[3,2;"..esc(S("No items to show.")).."]")
else
local first_item = (data.pagenum - 1) * 32
for i = first_item, first_item + 31 do
local item = data.items[i + 1]
if not item then
break
end
local x, y = coords(i % 32, 8)
item_button_fs(fs, x, y, item, item)
end
end
table.insert(fs, "container[0,5.6]")
if data.recipes then
recipe_fs(fs, data)
elseif data.prev_item then
table.insert(fs, ("label[2,1;%s]"):format(esc(data.show_usages
and S("No usages.").."\n"..S("Click again to show recipes.")
or S("No recipes.").."\n"..S("Click again to show usages."))))
end
table.insert(fs, "container_end[]")
return table.concat(fs)
end
local function imatch(str, filter)
return str:lower():find(filter, 1, true) ~= nil
end
local function execute_search(data)
local filter = data.filter
if filter == "" then
data.items = init_items
return
end
data.items = {}
for _, item in ipairs(init_items) do
local def = minetest.registered_items[item]
local desc = def and minetest.get_translated_string(data.lang_code, def.description)
if imatch(item, filter) or desc and imatch(desc, filter) then
table.insert(data.items, item)
end
end
end
local function on_receive_fields(player, fields)
local name = player:get_player_name()
local data = player_data[name]
if fields.clear then
data.filter = ""
data.pagenum = 1
data.prev_item = nil
data.recipes = nil
data.items = init_items
return true
elseif fields.key_enter_field == "filter" or fields.search then
local new = fields.filter:lower()
if data.filter == new then
return
end
data.filter = new
data.pagenum = 1
execute_search(data)
return true
elseif fields.prev or fields.next then
if data.pagemax == 1 then
return
end
data.pagenum = data.pagenum + (fields.next and 1 or -1)
if data.pagenum > data.pagemax then
data.pagenum = 1
elseif data.pagenum == 0 then
data.pagenum = data.pagemax
end
return true
elseif fields.recipe_next or fields.recipe_prev then
data.rnum = data.rnum + (fields.recipe_next and 1 or -1)
if data.rnum > #data.recipes then
data.rnum = 1
elseif data.rnum == 0 then
data.rnum = #data.recipes
end
return true
else
local item
for field in pairs(fields) do
if field:find(":") then
item = field
break
end
end
if not item then
return
end
if item == data.prev_item then
data.show_usages = not data.show_usages
else
data.show_usages = nil
end
if data.show_usages then
data.recipes = usages_cache[item]
else
data.recipes = recipes_cache[item]
end
data.prev_item = item
data.rnum = 1
return true
end
end
minetest.register_on_joinplayer(function(player)
local name = player:get_player_name()
local info = minetest.get_player_information(name)
player_data[name] = {
filter = "",
pagenum = 1,
items = init_items,
lang_code = info.lang_code
}
end)
minetest.register_on_leaveplayer(function(player)
local name = player:get_player_name()
player_data[name] = nil
end)
sfinv.register_page("mtg_craftguide:craftguide", {
title = esc(S("Recipes")),
get = function(self, player, context)
return sfinv.make_formspec(player, context, get_formspec(player))
end,
on_player_receive_fields = function(self, player, context, fields)
if on_receive_fields(player, fields) then
sfinv.set_player_inventory_formspec(player)
end
end
})

View File

@ -0,0 +1,63 @@
License of source code
----------------------
The MIT License (MIT)
Copyright (C) 2015-2019 Jean-Patrick Guerrero and contributors.
Copyright (C) 2020 pauloue
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
Licenses of media (textures)
----------------------------
Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0)
Copyright (C) 2018 paramat
Copyright (C) Neuromancer
Copyright (C) 2017 Wuzzy
You are free to:
Share — copy and redistribute the material in any medium or format.
Adapt — remix, transform, and build upon the material for any purpose, even commercially.
The licensor cannot revoke these freedoms as long as you follow the license terms.
Under the following terms:
Attribution — You must give appropriate credit, provide a link to the license, and
indicate if changes were made. You may do so in any reasonable manner, but not in any way
that suggests the licensor endorses you or your use.
ShareAlike — If you remix, transform, or build upon the material, you must distribute
your contributions under the same license as the original.
No additional restrictions — You may not apply legal terms or technological measures that
legally restrict others from doing anything the license permits.
Notices:
You do not have to comply with the license for elements of the material in the public
domain or where your use is permitted by an applicable exception or limitation.
No warranties are given. The license may not give you all of the permissions necessary
for your intended use. For example, other rights such as publicity, privacy, or moral
rights may limit how you use the material.
For more details:
http://creativecommons.org/licenses/by-sa/3.0/

View File

@ -0,0 +1,41 @@
# textdomain: mtg_craftguide
### init.lua ###
Any black dye=Quelconque colorant noir
Any black flower=Quelconque fleur noire
Any blue dye=Quelconque colorant bleu
Any blue flower=Quelconque fleur bleue
Any brown dye=Quelconque colorant marron
Any coal=Quelconque charbon
Any cyan dye=Quelconque colorant bleu ciel
Any dark green dye=Quelconque colorant vert foncé
Any dark grey dye=Quelconque colorant gris foncé
Any green dye=Quelconque colorant vert
Any green flower=Quelconque fleur verte
Any grey dye=Quelconque colorant gris
Any item belonging to the group(s): @1=Tout item appartenant au(x) groupe(s) : @1
Any kind of stone block=Quelconque roche
Any magenta dye=Quelconque colorant magenta
Any orange dye=Quelconque colorant orange
Any orange flower=Quelconque fleur orange
Any pink dye=Quelconque colorant rose
Any red dye=Quelconque colorant rouge
Any red flower=Quelconque fleur rouge
Any sand=Quelconque sable
Any stick=Quelconque bâton
Any vessel=Quelconque couvert
Any violet dye=Quelconque colorant violet
Any violet flower=Quelconque fleur violette
Any white dye=Quelconque colorant blanc
Any white flower=Quelconque fleur blanche
Any wood planks=Quelconques planches de bois
Any wool=Quelconque laine
Any yellow dye=Quelconque colorant jaune
Any yellow flower=Quelconque fleur jaune
Cooking time: @1=Temps de cuisson : @1
Recipe @1 of @2=Recette @1 sur @2
Recipes=Recettes
Shapeless=Sans forme
Usage @1 of @2=Usage @1 sur @2

View File

@ -0,0 +1,57 @@
# textdomain: mtg_craftguide
### init.lua ###
Any black dye=
Any black flower=
Any blue dye=
Any blue flower=
Any brown dye=
Any coal=
Any cyan dye=
Any dark green dye=
Any dark grey dye=
Any green dye=
Any green flower=
Any grey dye=
Any item belonging to the group(s): @1=
Any kind of stone block=
Any magenta dye=
Any orange dye=
Any orange flower=
Any pink dye=
Any red dye=
Any red flower=
Any sand=
Any stick=
Any vessel=
Any violet dye=
Any violet flower=
Any white dye=
Any white flower=
Any wood planks=
Any wool=
Any yellow dye=
Any yellow flower=
Click again to show recipes.=
Click again to show usages.=
Cooking time: @1=
Fuel=
# Label for group ingredients
G=
Next page=
Next recipe=
No items to show.=
No recipes.=
No usages.=
Previous page=
Previous recipe=
Recipe @1 of @2=
Recipe is too big to be displayed.=
Recipes=
Reset=
Search=
Shapeless=
Unknown Item=
Usage @1 of @2=

View File

@ -0,0 +1,3 @@
name = mtg_craftguide
description = Minetest Game mod: mtg_craftguide
depends = sfinv

Binary file not shown.

After

Width:  |  Height:  |  Size: 545 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 715 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 640 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 640 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 170 B

View File

@ -13,13 +13,11 @@ Various Minetest developers and contributors (LGPLv2.1+)
Authors of media (textures, models and sounds)
----------------------------------------------
stujones11 (CC BY-SA 3.0):
Original model by MirceaKitsune (CC BY-SA 3.0).
Various alterations and fixes by kilbith, sofar, xunto, Rogier-5, TeTpaAka, Desour,
stujones11, An0n3m0us (CC BY-SA 3.0):
character.b3d
character.blend -- Both derived from a model by MirceaKitsune (CC BY-SA 3.0)
An0n3m0us (CC BY-SA 3.0):
character.b3d
character.blend -- Player animation improvement
character.blend
Jordach (CC BY-SA 3.0):
character.png

View File

@ -107,7 +107,7 @@ function player_api.set_textures(player, textures)
local model = models[player_model[name]]
local model_textures = model and model.textures or nil
player_textures[name] = textures or model_textures
player:set_properties({textures = textures or model_textures,})
player:set_properties({textures = textures or model_textures})
end
function player_api.set_animation(player, anim_name, speed)
@ -129,6 +129,8 @@ minetest.register_on_leaveplayer(function(player)
player_model[name] = nil
player_anim[name] = nil
player_textures[name] = nil
player_sneak[name] = nil
player_api.player_attached[name] = nil
end)
-- Localize for better performance.
@ -219,6 +221,14 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
local gender_model = player_api.get_gender_model(gender)
player_api.set_model(player, gender_model)
if minetest.get_modpath("3d_armor")~=nil then
local player_name = player:get_player_name()
if gender == "male" then
armor.default_skin = "character.png"
armor.textures[player_name].skin = "character.png"
else
armor.default_skin = "female.png"
armor.textures[player_name].skin = "female.png"
end
player_api.set_textures(player, models[gender_model].textures)
end
end)

Some files were not shown because too many files have changed in this diff Show More