Compare commits

...

52 Commits

Author SHA1 Message Date
codiac 4cf865a36c Fix passive threshold in nether and end (#4030)
Fix light check for passive mobs in other dimensions. It is apparently the same in all dimensions. If a mob has it's own spawn_check function then that should be used regardless of it's type.

Fixes #4029

Reviewed-on: MineClone2/MineClone2#4030
Reviewed-by: the-real-herowl <the-real-herowl@noreply.git.minetest.land>
Co-authored-by: codiac <codiac@inbox.lv>
Co-committed-by: codiac <codiac@inbox.lv>
2023-11-28 02:45:18 +00:00
Eliy21 b57f6be81d Make showing advancement chat messages into a setting (#4032)
Reviewed-on: MineClone2/MineClone2#4032
Reviewed-by: the-real-herowl <the-real-herowl@noreply.git.minetest.land>
Co-authored-by: Eliy21 <eliy21@noreply.git.minetest.land>
Co-committed-by: Eliy21 <eliy21@noreply.git.minetest.land>
2023-11-28 01:37:45 +00:00
the-real-herowl cd40861b3b Merge pull request 'Add stonecutter functionality' (#3999) from stonecutter_functionality into master
Reviewed-on: MineClone2/MineClone2#3999
2023-11-27 23:37:57 +00:00
the-real-herowl 19728c5a19 Merge pull request 'hopper reimplementation' (#3980) from Morik666/MineClone2:hopper into master
Reviewed-on: MineClone2/MineClone2#3980
Reviewed-by: the-real-herowl <the-real-herowl@noreply.git.minetest.land>
2023-11-27 23:34:47 +00:00
Kostinatyn Tsiupa 1da7bb0bdc hopper reimplementation
Reimplemented hoppers and all (blast_furnace, furnace, smoker, composters, double chaets, shulker_boxes, droppers, bookshelvs and brewing_stands) connected nodes
2023-11-27 14:33:01 +02:00
the-real-herowl 1044163717 Fixed the ambiguous /clear command being dangerous (#4026)
Implements #3826

Reviewed-on: MineClone2/MineClone2#4026
Co-authored-by: the-real-herowl <wiktor_t-i@proton.me>
Co-committed-by: the-real-herowl <wiktor_t-i@proton.me>
2023-11-27 02:22:39 +00:00
ThePython10110 570ea114ec Fix weathered cut copper crafting (#4033)
Just fixing a typo.

Reviewed-on: MineClone2/MineClone2#4033
Reviewed-by: the-real-herowl <the-real-herowl@noreply.git.minetest.land>
Co-authored-by: ThePython10110 <thepython10110@noreply.git.minetest.land>
Co-committed-by: ThePython10110 <thepython10110@noreply.git.minetest.land>
2023-11-27 02:21:48 +00:00
the-real-herowl 8fd988da11 Increased cut copper recipe output 2023-11-25 23:52:04 +00:00
the-real-herowl f1c5f0ca1c Fixed duplication bug 2023-11-25 23:52:04 +00:00
the-real-herowl b4080b6275 Credits update in mod.conf 2023-11-25 23:52:04 +00:00
the-real-herowl bb48e47488 Made stonecutter player metadata consistent 2023-11-25 23:52:04 +00:00
the-real-herowl a6025b751a Uneven crafts support
-taking part of the resulting stack now produces well-defined results
-stonecutter won't allow amount undivisible by recipe count anymore
2023-11-25 23:52:04 +00:00
the-real-herowl af2f58248f Added the ability to stonecut up to full stack 2023-11-25 23:52:04 +00:00
AFCMS e324a1a74b Make inventory use the util functions 2023-11-25 23:52:04 +00:00
AFCMS 4836418cf6 Rework Stonecutter 2023-11-25 23:52:04 +00:00
AFCMS a001f84786 Add utility functions to clean inventory lists 2023-11-25 23:52:04 +00:00
AFCMS 2128dd4c15 Add basic table ordered keys iterator 2023-11-25 23:52:04 +00:00
the-real-herowl c183da7714 Updated README 2023-11-25 23:52:04 +00:00
the-real-herowl fd17bf1a29 Removed old implementation groups 2023-11-25 23:52:04 +00:00
the-real-herowl 0c7b4d473c Copper blocks stonecutter recipes 2023-11-25 23:52:04 +00:00
the-real-herowl 6ebd3ccb7d Third batch of stonecutter recipes
-deepslate
-blackstone
-quartz bricks
2023-11-25 23:52:04 +00:00
the-real-herowl d46b9071a0 Added nether and end stonecutter recipes 2023-11-25 23:52:04 +00:00
the-real-herowl ead2e772c2 First batch of stonecutter recipes under new API
-core blocks
-stairs
-slabs
-walls
2023-11-25 23:52:04 +00:00
the-real-herowl 19cea45c17 Stonecutter fixes and improvements
-improved stonecutter API, making it more robust
-fixed a dupe bug
2023-11-25 23:52:04 +00:00
the-real-herowl b252e577ec Implement recipe registering API 2023-11-25 23:52:04 +00:00
Chris Page 12568a6749 use on_destruct instead of after dig node 2023-11-25 23:52:04 +00:00
Chris Page 559f500322 Update readme for stonecutter 2023-11-25 23:52:04 +00:00
Chris Page 40fb043de2 Add stage so smooth items can't be reverted 2023-11-25 23:52:04 +00:00
Chris Page 5dda3033a5 Prevent input from being a selectable option 2023-11-25 23:52:04 +00:00
Chris Page 524c9c1bcc Dupe glitch fizes and remove item label 2023-11-25 23:52:04 +00:00
Chris Page a9f26fb354 use item groups to determine the cuttable items 2023-11-25 23:52:04 +00:00
Chris Page 01d43bb33a Remove unused meta on drop items 2023-11-25 23:52:04 +00:00
Chris Page ca37ce5744 Remove hardcoded one element array 2023-11-25 23:52:04 +00:00
Chris Page 5f0ad98dae Use node group for items that can be used in the stonecutter 2023-11-25 23:52:04 +00:00
Chris Page 0e60231c2e Only reset output if input is empty 2023-11-25 23:52:04 +00:00
Chris Page 7fcc2e3be3 Minor output fixes 2023-11-25 23:52:04 +00:00
Chris Page 356045b3e3 Add comments and drop items when destroyed 2023-11-25 23:52:04 +00:00
Chris Page 07d2759ae4 Check if item is a slab or not 2023-11-25 23:52:04 +00:00
Chris Page 9da07af370 Check if item can be made into stairs, slabs and walls 2023-11-25 23:52:04 +00:00
Chris Page 47990eec2b begin adding check if item canbe cut 2023-11-25 23:52:04 +00:00
Chris Page 7523727521 take output from stonecutter 2023-11-25 23:52:04 +00:00
Chris Page 2af08c3188 clear formspec on taking input item 2023-11-25 23:52:04 +00:00
Chris Page 45532ebe6d Add gui to list craft recipes for some stones 2023-11-25 23:52:04 +00:00
3raven 86da47b922 French translation update (#4006)
Update french translation, add missing chain, fix typo

Reviewed-on: MineClone2/MineClone2#4006
Reviewed-by: AFCMS <afcm.contact@gmail.com>
Co-authored-by: 3raven <3raven@noreply.git.minetest.land>
Co-committed-by: 3raven <3raven@noreply.git.minetest.land>
2023-11-25 01:08:06 +00:00
Eliy21 7cbba73d50 Combat (mostly PvE) rebalancing (#4005)
-Added short mob invulnerability time after being hit
-Added separate shorter range for hitting mobs (as opposed to node interaction)
-Reworked mob knockback
-Slowed down natural health regeneration from saturation
-Added a setting for the saturation health regen speed

Reviewed-on: MineClone2/MineClone2#4005
Reviewed-by: the-real-herowl <the-real-herowl@noreply.git.minetest.land>
Co-authored-by: Eliy21 <eliy21@noreply.git.minetest.land>
Co-committed-by: Eliy21 <eliy21@noreply.git.minetest.land>
2023-11-23 00:32:23 +00:00
José M 4df6f82c64 Fix spanish translation errors (#4018)
Reviewed-on: MineClone2/MineClone2#4018
Reviewed-by: the-real-herowl <the-real-herowl@noreply.git.minetest.land>
Co-authored-by: José M <dr.cabra@disroot.org>
Co-committed-by: José M <dr.cabra@disroot.org>
2023-11-18 22:20:02 +00:00
chmodsayshello 6ee2dbe70c Add MineCraft like sleeping player hud (#4011)
This adds a sleeping hud/actionbar that'll be displayed to players currently not sleeping.

Reviewed-on: MineClone2/MineClone2#4011
Reviewed-by: the-real-herowl <the-real-herowl@noreply.git.minetest.land>
Co-authored-by: chmodsayshello <chmodsayshello@hotmail.com>
Co-committed-by: chmodsayshello <chmodsayshello@hotmail.com>
2023-11-18 21:21:17 +00:00
the-real-herowl 613ab897b2 Merge pull request 'Fix item not dropping at tool last use' (#4009) from tool_destruction into master
Reviewed-on: MineClone2/MineClone2#4009
2023-11-18 01:32:01 +00:00
the-real-herowl e53d9ec8d7 Added comments 2023-11-18 02:31:07 +01:00
Mikita Wiśniewski a764818e13 Add a new 'pumpkin' group (#4012)
Creates a new 'pumpkin' group, which combines Pumpkin, Faceless Pumkin and Jack o'Lantern under a shared category. This helps tidy up the mesecons_noteblock code a bit, and possibly other mods too.

Reviewed-on: MineClone2/MineClone2#4012
Reviewed-by: the-real-herowl <the-real-herowl@noreply.git.minetest.land>
Co-authored-by: Mikita Wiśniewski <rudzik8@protonmail.com>
Co-committed-by: Mikita Wiśniewski <rudzik8@protonmail.com>
2023-11-14 15:35:30 +00:00
the-real-herowl 378b8f8f6c Fix item not dropping at tool last use 2023-11-13 13:35:12 +01:00
Aliaksei Urbanski 32ef89aca3 Fix minor README's imperfections (#4001)
I've prepared some minor changes for `README`s.

Reviewed-on: MineClone2/MineClone2#4001
Reviewed-by: the-real-herowl <the-real-herowl@noreply.git.minetest.land>
Co-authored-by: Aliaksei Urbanski <aliaksei.urbanski@gmail.com>
Co-committed-by: Aliaksei Urbanski <aliaksei.urbanski@gmail.com>
2023-11-11 21:01:45 +00:00
84 changed files with 1587 additions and 631 deletions

View File

@ -170,16 +170,8 @@ These groups are used mostly for informational purposes
* `ammo_bow=1`: Item is used as ammo for bows * `ammo_bow=1`: Item is used as ammo for bows
* `non_combat_armor=1`: Item can be equipped as armor, but is not made for combat (e.g. zombie head, pumpkin) * `non_combat_armor=1`: Item can be equipped as armor, but is not made for combat (e.g. zombie head, pumpkin)
* `container`: Node is a container which physically stores items within and has at least 1 inventory * `container`: Node is a container which physically stores items within and has at least 1 inventory
* `container=2`: Has one inventory with list name `"main"`. Items can be placed and taken freely * `container=1`: Container type, which does not allow hoppers to transfer items
* `container=3`: Same as `container=2`, but shulker boxes can not be inserted * `container=2`: Items can be placed and taken freely. Can have inventory with list name `"main"` or define `_mcl_hoppers_on_try_pull`, `_mcl_hoppers_on_try_push`, `_mcl_hoppers_on_after_pull`, `_mcl_hoppers_on_after_push` to play along hoppers nicely.
* `container=4`: Furnace-like, has lists `"src"`, `"fuel"` and `"dst"`.
It is expected that this also reacts on `on_timer`;
the node timer must be started from other mods when they add into `"src"` or `"fuel"`
* `container=5`: Left part of a 2-part horizontal connected container. Both parts have a `"main"` inventory
list. Both inventories are considered to belong together. This is used for large chests.
* `container=6`: Same as above, but for the right part.
* `container=7`: Has inventory list "`main`", no movement allowed
* `container=1`: Other/unspecified container type
* `spawn_egg=1`: Spawn egg * `spawn_egg=1`: Spawn egg
* `pressure_plate=1`: Pressure plate (off) * `pressure_plate=1`: Pressure plate (off)

View File

@ -27,7 +27,7 @@ Or you can play in “creative mode” in which you can build almost anything in
## How to play (quick start) ## How to play (quick start)
### Getting started ### Getting started
* **Punch a tree** trunk until it breaks and collect wood * **Punch a tree** trunk until it breaks and collect wood
* Place the **wood into the 2×2 grid** (your “crafting grid” in your inventory menu and craft 4 wood planks * Place the **wood into the 2×2 grid** (your “crafting grid” in your inventory menu) and craft 4 wood planks
* Place the 4 wood planks in a 2×2 shape in the crafting grid to **make a crafting table** * Place the 4 wood planks in a 2×2 shape in the crafting grid to **make a crafting table**
* **Rightclick the crafting table** for a 3×3 crafting grid to craft more complex things * **Rightclick the crafting table** for a 3×3 crafting grid to craft more complex things
* Use the **crafting guide** (book icon) to learn all the possible crafting recipes * Use the **crafting guide** (book icon) to learn all the possible crafting recipes
@ -37,15 +37,15 @@ Or you can play in “creative mode” in which you can build almost anything in
### Farming ### Farming
* Find seeds * Find seeds
* Craft hoe * Craft a hoe
* Rightclick dirt or similar block with hoe to create farmland * Rightclick dirt or a similar block with a hoe to create farmland
* Place seeds on farmland and watch them grow * Place seeds on farmland and watch them grow
* Collect plant when fully grown * Collect plants when fully grown
* If near water, farmland becomes wet and speeds up growth * If near water, farmland becomes wet and speeds up growth
### Furnace ### Furnace
* Craft furnace * Craft a furnace
* Furnace allows you to obtain more items * The furnace allows you to obtain more items
* Upper slot must contain a smeltable item (example: iron ore) * Upper slot must contain a smeltable item (example: iron ore)
* Lower slot must contain a fuel item (example: coal) * Lower slot must contain a fuel item (example: coal)
* See tooltips in crafting guide to learn about fuels and smeltable items * See tooltips in crafting guide to learn about fuels and smeltable items
@ -162,7 +162,7 @@ Bonus features (not found in Minecraft):
* Built-in crafting guide which shows you crafting and smelting recipes * Built-in crafting guide which shows you crafting and smelting recipes
* In-game help system containing extensive help about gameplay basics, blocks, items and more * In-game help system containing extensive help about gameplay basics, blocks, items and more
* Temporary crafting recipes. They only exist to make some otherwise unaccessible items available when you're not in creative mode. These recipes will be removed as development goes on an more features become available * Temporary crafting recipes. They only exist to make some otherwise unaccessible items available when you're not in creative mode. These recipes will be removed as development goes on an more features become available
* Saplings in chests in mapgen v6 * Saplings in chests in [mapgen v6](https://wiki.minetest.net/Map_generator#v6)
* Fully moddable (thanks to Minetest's powerful Lua API) * Fully moddable (thanks to Minetest's powerful Lua API)
* New blocks and items: * New blocks and items:
* Lookup tool, shows you the help for whatever it touches * Lookup tool, shows you the help for whatever it touches

View File

@ -137,7 +137,7 @@ Fonctionnalités bonus (absentes de Minecraft) :
* Guide d'artisanat intégré au jeu qui montre les recettes d'artisanat et de cuisson * Guide d'artisanat intégré au jeu qui montre les recettes d'artisanat et de cuisson
* Système d'aide intégré au jeu contenant des informations à propos des techniques de base, blocs, objets et plus * Système d'aide intégré au jeu contenant des informations à propos des techniques de base, blocs, objets et plus
* Recettes d'artisanat temporaires. Elles existent uniquement pour rendre des objets accessibles qui ne le seraient pas autrement sauf en mode créatif. Elles seront retirées au cours de l'avancement du développement et de l'ajout de nouvelles fonctionnalités. * Recettes d'artisanat temporaires. Elles existent uniquement pour rendre des objets accessibles qui ne le seraient pas autrement sauf en mode créatif. Elles seront retirées au cours de l'avancement du développement et de l'ajout de nouvelles fonctionnalités.
* Pousses dans les coffres en mapgen v6 * Pousses dans les coffres en [mapgen v6](https://wiki.minetest.net/Map_generator#v6)
* Entièrement moddable (grâce la puissante API Lua de Minetest) * Entièrement moddable (grâce la puissante API Lua de Minetest)
* Nouveaux blocs et objets : * Nouveaux blocs et objets :
* Outil de recherche, montre l'aide de ce qu'il touche * Outil de recherche, montre l'aide de ce qu'il touche

View File

@ -154,12 +154,12 @@ Mineclone2, то ветка master обычно относительно ста
* Некоторые вагонетки (с сундуком и с воронкой уже работают) * Некоторые вагонетки (с сундуком и с воронкой уже работают)
* Пара нетривиальных блоков и предметов * Пара нетривиальных блоков и предметов
Бонусные воронкой (нет в Minecraft-е): Бонусные возможности (нет в Minecraft-е):
* Встроенный гайд для крафта покажет вам рецепты крафта и переплавки * Встроенный гайд для крафта покажет вам рецепты крафта и переплавки
* Внутриигровая справка содержит всестороннюю информацию об основах игры, блоках, предметах и прочее * Внутриигровая справка содержит всестороннюю информацию об основах игры, блоках, предметах и прочее
* Временные рецепты крафта. Они существуют, чтобы получить доступ к ранее недоступным предметам вне творческого режима. Они будут удалены как только разработка позволит им стать доступными * Временные рецепты крафта. Они существуют, чтобы получить доступ к ранее недоступным предметам вне творческого режима. Они будут удалены как только разработка позволит им стать доступными
* Саженцы в сундуках мапгена v6 * Саженцы в сундуках в [mapgen v6](https://wiki.minetest.net/Map_generator#v6)
* Полностью модифицируема (благодаря мощному Lua API в Minetest) * Полностью модифицируема (благодаря мощному Lua API в Minetest)
* Новые блоки и предметы: * Новые блоки и предметы:
* Инструмент просмотра покажет справку о том чего коснется * Инструмент просмотра покажет справку о том чего коснется
@ -177,7 +177,7 @@ Mineclone2, то ветка master обычно относительно ста
* Недостающие блоки, предметы, мобы * Недостающие блоки, предметы, мобы
* Некоторые предметы с другими названиями, чтобы лучше их различать * Некоторые предметы с другими названиями, чтобы лучше их различать
* Другая музыка для проигрывателей * Другая музыка для проигрывателей
* Другие текступы (Pixel Perfection) * Другие текстуры (Pixel Perfection)
* Другие звуки (разные источники) * Другие звуки (разные источники)
* Другой движок (Minetest) * Другой движок (Minetest)
* Другие пасхалки * Другие пасхалки

View File

@ -22,6 +22,30 @@ function table.update_nil(t, ...)
return t return t
end end
---Works the same as `pairs`, but order returned by keys
---
---Taken from https://www.lua.org/pil/19.3.html
---@generic T: table, K, V, C
---@param t T
---@param f? fun(a: C, b: C):boolean
---@return fun():K, V
function table.pairs_by_keys(t, f)
local a = {}
for n in pairs(t) do table.insert(a, n) end
table.sort(a, f)
local i = 0 -- iterator variable
local function iter() -- iterator function
i = i + 1
if a[i] == nil then
return nil
else
return a[i], t[a[i]]
end
end
return iter
end
local LOGGING_ON = minetest.settings:get_bool("mcl_logging_default", false) local LOGGING_ON = minetest.settings:get_bool("mcl_logging_default", false)
local LOG_MODULE = "[MCL2]" local LOG_MODULE = "[MCL2]"
function mcl_util.mcl_log(message, module, bypass_default_logger) function mcl_util.mcl_log(message, module, bypass_default_logger)
@ -241,34 +265,25 @@ function mcl_util.get_double_container_neighbor_pos(pos, param2, side)
end end
end end
-- Iterates through all items in the given inventory and --- Selects item stack to transfer from
-- returns the slot of the first item which matches a condition. ---@param src_inventory InvRef Source innentory to pull from
-- Returns nil if no item was found. ---@param src_list string Name of source inventory list to pull from
--- source_inventory: Inventory to take the item from ---@param dst_inventory InvRef Destination inventory to push to
--- source_list: List name of the source inventory from which to take the item ---@param dst_list string Name of destination inventory list to push to
--- destination_inventory: Put item into this inventory ---@param condition? fun(stack: ItemStack) Condition which items are allowed to be transfered.
--- destination_list: List name of the destination inventory to which to put the item into ---@return integer Item stack number to be transfered
--- condition: Function which takes an itemstack and returns true if it matches the desired item condition. function mcl_util.select_stack(src_inventory, src_list, dst_inventory, dst_list, condition)
--- If set to nil, the slot of the first item stack will be taken unconditionally. local src_size = src_inventory:get_size(src_list)
-- dst_inventory and dst_list can also be nil if condition is nil.
function mcl_util.get_eligible_transfer_item_slot(src_inventory, src_list, dst_inventory, dst_list, condition)
local size = src_inventory:get_size(src_list)
local stack local stack
for i = 1, size do for i = 1, src_size do
stack = src_inventory:get_stack(src_list, i) stack = src_inventory:get_stack(src_list, i)
if not stack:is_empty() and (condition == nil or condition(stack, src_inventory, src_list, dst_inventory, dst_list)) then if not stack:is_empty() and dst_inventory:room_for_item(dst_list, stack) and ((condition == nil or condition(stack))) then
return i return i
end end
end end
return nil return nil
end end
-- Returns true if itemstack is a shulker box
local function is_not_shulker_box(itemstack)
local g = minetest.get_item_group(itemstack:get_name(), "shulker_box")
return g == 0 or g == nil
end
-- Moves a single item from one inventory to another. -- Moves a single item from one inventory to another.
--- source_inventory: Inventory to take the item from --- source_inventory: Inventory to take the item from
--- source_list: List name of the source inventory from which to take the item --- source_list: List name of the source inventory from which to take the item
@ -279,13 +294,6 @@ end
-- Returns true on success and false on failure -- Returns true on success and false on failure
-- Possible failures: No item in source slot, destination inventory full -- Possible failures: No item in source slot, destination inventory full
function mcl_util.move_item(source_inventory, source_list, source_stack_id, destination_inventory, destination_list) function mcl_util.move_item(source_inventory, source_list, source_stack_id, destination_inventory, destination_list)
if source_stack_id == -1 then
source_stack_id = mcl_util.get_first_occupied_inventory_slot(source_inventory, source_list)
if source_stack_id == nil then
return false
end
end
if not source_inventory:is_empty(source_list) then if not source_inventory:is_empty(source_list) then
local stack = source_inventory:get_stack(source_list, source_stack_id) local stack = source_inventory:get_stack(source_list, source_stack_id)
if not stack:is_empty() then if not stack:is_empty() then
@ -303,150 +311,75 @@ function mcl_util.move_item(source_inventory, source_list, source_stack_id, dest
return false return false
end end
-- Moves a single item from one container node into another. Performs a variety of high-level --- Try pushing item from hopper inventory to destination inventory
-- checks to prevent invalid transfers such as shulker boxes into shulker boxes ---@param pos Vector
--- source_pos: Position ({x,y,z}) of the node to take the item from ---@param dst_pos Vector
--- destination_pos: Position ({x,y,z}) of the node to put the item into function mcl_util.hopper_push(pos, dst_pos)
--- source_list (optional): List name of the source inventory from which to take the item. Default is normally "main"; "dst" for furnace local hop_inv = minetest.get_meta(pos):get_inventory()
--- source_stack_id (optional): The inventory position ID of the source inventory to take the item from (-1 for slot of the first valid item; -1 is default) local hop_list = 'main'
--- destination_list (optional): List name of the destination inventory. Default is normally "main"; "src" for furnace
-- Returns true on success and false on failure.
function mcl_util.move_item_container(source_pos, destination_pos, source_list, source_stack_id, destination_list)
local dpos = table.copy(destination_pos)
local spos = table.copy(source_pos)
local snode = minetest.get_node(spos)
local dnode = minetest.get_node(dpos)
local dctype = minetest.get_item_group(dnode.name, "container") -- Get node pos' for item transfer
local sctype = minetest.get_item_group(snode.name, "container") local dst = minetest.get_node(dst_pos)
if not minetest.registered_nodes[dst.name] then return end
local dst_type = minetest.get_item_group(dst.name, "container")
if dst_type ~= 2 then return end
local dst_def = minetest.registered_nodes[dst.name]
-- Container type 7 does not allow any movement local dst_list = 'main'
if sctype == 7 then local dst_inv, stack_id
return false
if dst_def._mcl_hoppers_on_try_push then
dst_inv, dst_list, stack_id = dst_def._mcl_hoppers_on_try_push(dst_pos, pos, hop_inv, hop_list)
else
local dst_meta = minetest.get_meta(dst_pos)
dst_inv = dst_meta:get_inventory()
stack_id = mcl_util.select_stack(hop_inv, hop_list, dst_inv, dst_list)
end end
-- Normalize double container by forcing to always use the left segment first if stack_id ~= nil then
local function normalize_double_container(pos, node, ctype) local ok = mcl_util.move_item(hop_inv, hop_list, stack_id, dst_inv, dst_list)
if ctype == 6 then if dst_def._mcl_hoppers_on_after_push then
pos = mcl_util.get_double_container_neighbor_pos(pos, node.param2, "right") dst_def._mcl_hoppers_on_after_push(dst_pos)
if not pos then
return false
end
node = minetest.get_node(pos)
ctype = minetest.get_item_group(node.name, "container")
-- The left segment seems incorrect? We better bail out!
if ctype ~= 5 then
return false
end
end end
return pos, node, ctype if ok then
end return true
spos, snode, sctype = normalize_double_container(spos, snode, sctype)
dpos, dnode, dctype = normalize_double_container(dpos, dnode, dctype)
if not spos or not dpos then return false end
local smeta = minetest.get_meta(spos)
local dmeta = minetest.get_meta(dpos)
local sinv = smeta:get_inventory()
local dinv = dmeta:get_inventory()
-- Default source lists
if not source_list then
-- Main inventory for most container types
if sctype == 2 or sctype == 3 or sctype == 5 or sctype == 6 or sctype == 7 then
source_list = "main"
-- Furnace: output
elseif sctype == 4 then
source_list = "dst"
-- Unknown source container type. Bail out
else
return false
end end
end end
-- Automatically select stack slot ID if set to automatic
if not source_stack_id then
source_stack_id = -1
end
if source_stack_id == -1 then
local cond = nil
-- Prevent shulker box inception
if dctype == 3 then
cond = is_not_shulker_box
end
source_stack_id = mcl_util.get_eligible_transfer_item_slot(sinv, source_list, dinv, dpos, cond)
if not source_stack_id then
-- Try again if source is a double container
if sctype == 5 then
spos = mcl_util.get_double_container_neighbor_pos(spos, snode.param2, "left")
smeta = minetest.get_meta(spos)
sinv = smeta:get_inventory()
source_stack_id = mcl_util.get_eligible_transfer_item_slot(sinv, source_list, dinv, dpos, cond)
if not source_stack_id then
return false
end
else
return false
end
end
end
-- Abort transfer if shulker box wants to go into shulker box
if dctype == 3 then
local stack = sinv:get_stack(source_list, source_stack_id)
if stack and minetest.get_item_group(stack:get_name(), "shulker_box") == 1 then
return false
end
end
-- Container type 7 does not allow any placement
if dctype == 7 then
return false
end
-- If it's a container, put it into the container
if dctype ~= 0 then
-- Automatically select a destination list if omitted
if not destination_list then
-- Main inventory for most container types
if dctype == 2 or dctype == 3 or dctype == 5 or dctype == 6 or dctype == 7 then
destination_list = "main"
-- Furnace source slot
elseif dctype == 4 then
destination_list = "src"
end
end
if destination_list then
-- Move item
local ok = mcl_util.move_item(sinv, source_list, source_stack_id, dinv, destination_list)
-- Try transfer to neighbor node if transfer failed and double container
if not ok and dctype == 5 then
dpos = mcl_util.get_double_container_neighbor_pos(dpos, dnode.param2, "left")
dmeta = minetest.get_meta(dpos)
dinv = dmeta:get_inventory()
ok = mcl_util.move_item(sinv, source_list, source_stack_id, dinv, destination_list)
end
-- Update furnace
if ok and dctype == 4 then
-- Start furnace's timer function, it will sort out whether furnace can burn or not.
minetest.get_node_timer(dpos):start(1.0)
end
return ok
end
end
return false return false
end end
-- Returns the ID of the first non-empty slot in the given inventory list -- Try pulling from source inventory to hopper inventory
-- or nil, if inventory is empty. ---@param pos Vector
function mcl_util.get_first_occupied_inventory_slot(inventory, listname) ---@param src_pos Vector
return mcl_util.get_eligible_transfer_item_slot(inventory, listname) function mcl_util.hopper_pull(pos, src_pos)
local hop_inv = minetest.get_meta(pos):get_inventory()
local hop_list = 'main'
-- Get node pos' for item transfer
local src = minetest.get_node(src_pos)
if not minetest.registered_nodes[src.name] then return end
local src_type = minetest.get_item_group(src.name, "container")
if src_type ~= 2 then return end
local src_def = minetest.registered_nodes[src.name]
local src_list = 'main'
local src_inv, stack_id
if src_def._mcl_hoppers_on_try_pull then
src_inv, src_list, stack_id = src_def._mcl_hoppers_on_try_pull(src_pos, pos, hop_inv, hop_list)
else
local src_meta = minetest.get_meta(src_pos)
src_inv = src_meta:get_inventory()
stack_id = mcl_util.select_stack(src_inv, src_list, hop_inv, hop_list)
end
if stack_id ~= nil then
local ok = mcl_util.move_item(src_inv, src_list, stack_id, hop_inv, hop_list)
if src_def._mcl_hoppers_on_after_pull then
src_def._mcl_hoppers_on_after_pull(src_pos)
end
end
end end
local function drop_item_stack(pos, stack) local function drop_item_stack(pos, stack)
@ -1113,3 +1046,53 @@ function mcl_util.get_colorwallmounted_rotation(pos)
end end
end end
end end
---Move items from one inventory list to another, drop items that do not fit in provided pos and direction.
---@param src_inv mt.InvRef
---@param src_listname string
---@param out_inv mt.InvRef
---@param out_listname string
---@param pos mt.Vector Position to throw items at
---@param dir? mt.Vector Direction to throw items in
---@param insta_collect? boolean Enable instant collection, let players collect dropped items instantly. Default `false`
function mcl_util.move_list(src_inv, src_listname, out_inv, out_listname, pos, dir, insta_collect)
local src_list = src_inv:get_list(src_listname)
if not src_list then return end
for i, stack in ipairs(src_list) do
if out_inv:room_for_item(out_listname, stack) then
out_inv:add_item(out_listname, stack)
else
local p = vector.copy(pos)
p.x = p.x + (math.random(1, 3) * 0.2)
p.z = p.z + (math.random(1, 3) * 0.2)
local obj = minetest.add_item(p, stack)
if obj then
if dir then
local v = vector.copy(dir)
v.x = v.x * 4
v.y = v.y * 4 + 2
v.z = v.z * 4
obj:set_velocity(v)
minetest.log("error", vector.to_string(v))
end
if not insta_collect then
obj:get_luaentity()._insta_collect = false
end
end
end
stack:clear()
src_inv:set_stack(src_listname, i, stack)
end
end
---Move items from a player's inventory list to its main inventory list, drop items that do not fit in front of him.
---@param player mt.PlayerObjectRef
---@param src_listname string
function mcl_util.move_player_list(player, src_listname)
mcl_util.move_list(player:get_inventory(), src_listname, player:get_inventory(), "main",
vector.offset(player:get_pos(), 0, 1.2, 0),
player:get_look_dir(), false)
end

View File

@ -12,6 +12,7 @@ Water vehicle=Véhicule aquatique
Sneak to dismount=Se baisser pour descendre Sneak to dismount=Se baisser pour descendre
Obsidian Boat=Bateau en obsidienne Obsidian Boat=Bateau en obsidienne
Mangrove Boat=Bateau en palétuvier Mangrove Boat=Bateau en palétuvier
Cherry Boat=Bateau en cerisier
Oak Chest Boat=Bateau en chêne avec coffre Oak Chest Boat=Bateau en chêne avec coffre
Spruce Chest Boat=Bateau en sapin avec coffre Spruce Chest Boat=Bateau en sapin avec coffre
Birch Chest Boat=Bateau en bouleau avec coffre Birch Chest Boat=Bateau en bouleau avec coffre
@ -19,3 +20,4 @@ Jungle Chest Boat=Bateau en acajou avec coffre
Acacia Chest Boat=Bateau en acacia avec coffre Acacia Chest Boat=Bateau en acacia avec coffre
Dark Oak Chest Boat=Bateau en chêne noir avec coffre Dark Oak Chest Boat=Bateau en chêne noir avec coffre
Mangrove Chest Boat=Bateau en palétuvier avec coffre Mangrove Chest Boat=Bateau en palétuvier avec coffre
Cherry Chest Boat=Bateau en cerisier avec coffre

View File

@ -362,6 +362,121 @@ function minetest.handle_node_drops(pos, drops, digger)
end end
end end
-- the following code is pulled from Minetest builtin without changes except for the call order being changed,
-- until a comment saying explicitly it's the end of such code
-- TODO if this gets a fix in the engine, remove the block of code
local function user_name(user)
return user and user:get_player_name() or ""
end
-- Returns a logging function. For empty names, does not log.
local function make_log(name)
return name ~= "" and minetest.log or function() end
end
function minetest.node_dig(pos, node, digger)
local diggername = user_name(digger)
local log = make_log(diggername)
local def = minetest.registered_nodes[node.name]
-- Copy pos because the callback could modify it
if def and (not def.diggable or
(def.can_dig and not def.can_dig(vector.copy(pos), digger))) then
log("info", diggername .. " tried to dig "
.. node.name .. " which is not diggable "
.. minetest.pos_to_string(pos))
return false
end
if minetest.is_protected(pos, diggername) then
log("action", diggername
.. " tried to dig " .. node.name
.. " at protected position "
.. minetest.pos_to_string(pos))
minetest.record_protection_violation(pos, diggername)
return false
end
log('action', diggername .. " digs "
.. node.name .. " at " .. minetest.pos_to_string(pos))
local wielded = digger and digger:get_wielded_item()
local drops = minetest.get_node_drops(node, wielded and wielded:get_name())
-- Check to see if metadata should be preserved.
if def and def.preserve_metadata then
local oldmeta = minetest.get_meta(pos):to_table().fields
-- Copy pos and node because the callback can modify them.
local pos_copy = vector.copy(pos)
local node_copy = {name=node.name, param1=node.param1, param2=node.param2}
local drop_stacks = {}
for k, v in pairs(drops) do
drop_stacks[k] = ItemStack(v)
end
drops = drop_stacks
def.preserve_metadata(pos_copy, node_copy, oldmeta, drops)
end
-- Handle drops
minetest.handle_node_drops(pos, drops, digger)
if wielded then
local wdef = wielded:get_definition()
local tp = wielded:get_tool_capabilities()
local dp = minetest.get_dig_params(def and def.groups, tp, wielded:get_wear())
if wdef and wdef.after_use then
wielded = wdef.after_use(wielded, digger, node, dp) or wielded
else
-- Wear out tool
if not minetest.is_creative_enabled(diggername) then
wielded:add_wear(dp.wear)
if wielded:get_count() == 0 and wdef.sound and wdef.sound.breaks then
minetest.sound_play(wdef.sound.breaks, {
pos = pos,
gain = 0.5
}, true)
end
end
end
digger:set_wielded_item(wielded)
end
local oldmetadata = nil
if def and def.after_dig_node then
oldmetadata = minetest.get_meta(pos):to_table()
end
-- Remove node and update
minetest.remove_node(pos)
-- Play sound if it was done by a player
if diggername ~= "" and def and def.sounds and def.sounds.dug then
minetest.sound_play(def.sounds.dug, {
pos = pos,
exclude_player = diggername,
}, true)
end
-- Run callback
if def and def.after_dig_node then
-- Copy pos and node because callback can modify them
local pos_copy = vector.copy(pos)
local node_copy = {name=node.name, param1=node.param1, param2=node.param2}
def.after_dig_node(pos_copy, node_copy, oldmetadata, digger)
end
-- Run script hook
for _, callback in ipairs(minetest.registered_on_dignodes) do
local origin = minetest.callback_origins[callback]
minetest.set_last_run_mod(origin.mod)
-- Copy pos and node because callback can modify them
local pos_copy = vector.copy(pos)
local node_copy = {name=node.name, param1=node.param1, param2=node.param2}
callback(pos_copy, node_copy, digger)
end
return true
end
-- end of code pulled from Minetest
-- Drop single items by default -- Drop single items by default
function minetest.item_drop(itemstack, dropper, pos) function minetest.item_drop(itemstack, dropper, pos)
if dropper and dropper:is_player() then if dropper and dropper:is_player() then

View File

@ -532,11 +532,28 @@ function mob_class:on_punch(hitter, tflp, tool_capabilities, dir)
return return
end end
local time_now = minetest.get_us_time()
local is_player = hitter:is_player() local is_player = hitter:is_player()
if is_player then if is_player then
local time_diff = time_now - self.invul_timestamp
-- check for invulnerability time in microseconds (0.5 second)
if time_diff <= 500000 and time_diff >= 0 then
return
end
local mob_pos = self.object:get_pos()
local player_pos = hitter:get_pos()
-- is mob out of reach?
if vector.distance(mob_pos, player_pos) > 3 then
return
end
-- is mob protected? -- is mob protected?
if self.protected and minetest.is_protected(self.object:get_pos(), hitter:get_player_name()) then if self.protected and minetest.is_protected(mob_pos, hitter:get_player_name()) then
return return
end end
@ -545,7 +562,7 @@ function mob_class:on_punch(hitter, tflp, tool_capabilities, dir)
end end
-- set/update 'drop xp' timestamp if hitted by player -- set/update 'drop xp' timestamp if hitted by player
self.xp_timestamp = minetest.get_us_time() self.xp_timestamp = time_now
end end
@ -657,6 +674,9 @@ function mob_class:on_punch(hitter, tflp, tool_capabilities, dir)
-- do damage -- do damage
self.health = self.health - damage self.health = self.health - damage
-- give invulnerability
self.invul_timestamp = time_now
-- skip future functions if dead, except alerting others -- skip future functions if dead, except alerting others
if self:check_for_death( "hit", {type = "punch", puncher = hitter}) then if self:check_for_death( "hit", {type = "punch", puncher = hitter}) then
die = true die = true
@ -672,10 +692,10 @@ function mob_class:on_punch(hitter, tflp, tool_capabilities, dir)
if not v then return end if not v then return end
local r = 1.4 - math.min(punch_interval, 1.4) local r = 1.4 - math.min(punch_interval, 1.4)
local kb = r * (math.abs(v.x)+math.abs(v.z)) local kb = r * (math.abs(v.x)+math.abs(v.z))
local up = 2 local up = 2.625
if die==true then if die==true then
kb=kb*2 kb=kb*1.25
end end
-- if already in air then dont go up anymore when hit -- if already in air then dont go up anymore when hit
@ -689,7 +709,7 @@ function mob_class:on_punch(hitter, tflp, tool_capabilities, dir)
if tool_capabilities.damage_groups["knockback"] then if tool_capabilities.damage_groups["knockback"] then
kb = tool_capabilities.damage_groups["knockback"] kb = tool_capabilities.damage_groups["knockback"]
else else
kb = kb * 1.5 kb = kb * 1.25
end end
@ -699,9 +719,19 @@ function mob_class:on_punch(hitter, tflp, tool_capabilities, dir)
end end
if hitter and is_player then if hitter and is_player then
local wielditem = hitter:get_wielded_item() local wielditem = hitter:get_wielded_item()
kb = kb + 3 * mcl_enchanting.get_enchantment(wielditem, "knockback") local hv = hitter:get_velocity()
elseif luaentity and luaentity._knockback then local dir_dot = (hv.x * dir.x) + (hv.z * dir.z)
local player_mag = math.sqrt((hv.x * hv.x) + (hv.z * hv.z))
local mob_mag = math.sqrt((v.x * v.x) + (v.z * v.z))
kb = kb + 9 * mcl_enchanting.get_enchantment(wielditem, "knockback")
-- add player velocity to mob knockback
if dir_dot > 0 and mob_mag <= player_mag * 0.625 then
kb = kb + ((math.abs(hv.x) + math.abs(hv.z)) * r)
end
elseif luaentity and luaentity._knockback and die == false then
kb = kb + luaentity._knockback kb = kb + luaentity._knockback
elseif luaentity and luaentity._knockback and die == true then
kb = kb + luaentity._knockback * 0.25
end end
self._kb_turn = true self._kb_turn = true
self._turn_to=self.object:get_yaw()-1.57 self._turn_to=self.object:get_yaw()-1.57

View File

@ -171,6 +171,7 @@ function mcl_mobs.register_mob(name, def)
xp_min = def.xp_min or 0, xp_min = def.xp_min or 0,
xp_max = def.xp_max or 0, xp_max = def.xp_max or 0,
xp_timestamp = 0, xp_timestamp = 0,
invul_timestamp = 0,
breath_max = def.breath_max or 15, breath_max = def.breath_max or 15,
breathes_in_water = def.breathes_in_water or false, breathes_in_water = def.breathes_in_water or false,
physical = true, physical = true,

View File

@ -732,27 +732,26 @@ local function spawn_check(pos, spawn_def)
local sky_light = minetest.get_natural_light(pos) local sky_light = minetest.get_natural_light(pos)
local art_light = minetest.get_artificial_light(my_node.param1) local art_light = minetest.get_artificial_light(my_node.param1)
if dimension == "nether" then if mob_def.spawn_check then
if art_light <= nether_threshold then return mob_def.spawn_check(pos, gotten_light, art_light, sky_light)
return true elseif mob_type == "monster" then
end if dimension == "nether" then
elseif dimension == "end" then if art_light <= nether_threshold then
if art_light <= end_threshold then
return true
end
elseif dimension == "overworld" then
if mob_type == "monster" then
if mob_def.spawn_check then
return mob_def.spawn_check(pos, gotten_light, art_light, sky_light)
elseif art_light <= overworld_threshold and sky_light <= overworld_sky_threshold then
return true return true
end end
else elseif dimension == "end" then
if mob_def.spawn_check then if art_light <= end_threshold then
return mob_def.spawn_check(pos, gotten_light, art_light, sky_light)
elseif gotten_light > overworld_passive_threshold then
return true return true
end end
elseif dimension == "overworld" then
if art_light <= overworld_threshold and sky_light <= overworld_sky_threshold then
return true
end
end
else
-- passive threshold is apparently the same in all dimensions ...
if gotten_light > overworld_passive_threshold then
return true
end end
end end
else else

View File

@ -21,6 +21,7 @@ Mule=Mule
Iron Golem=Golem de fer Iron Golem=Golem de fer
Llama=Lama Llama=Lama
Ocelot=Ocelot Ocelot=Ocelot
Cat=Chat
Parrot=Perroquet Parrot=Perroquet
Pig=Cochon Pig=Cochon
Polar Bear=Ours blanc Polar Bear=Ours blanc
@ -48,8 +49,15 @@ Witch=Sorcière
Wither=Wither Wither=Wither
Wolf=Loup Wolf=Loup
Husk=Zombie Momifié Husk=Zombie Momifié
Baby Husk=Bébé Zombie Momifié
Zombie=Zombie Zombie=Zombie
Zombie Piglin=Zombie Cochon Baby Zombie=Bébé Zombie
Piglin=Piglin
Baby Piglin=Bébé Piglin
Zombie Piglin=Piglin Zombie
Baby Zombie Piglin=Bébé Piglin Zombie
Sword Piglin=Piglin avec une épée
Piglin Brute=Piglin Barbare
Farmer=Fermier Farmer=Fermier
Fisherman=Pêcheur Fisherman=Pêcheur
Fletcher=Archer Fletcher=Archer
@ -69,5 +77,7 @@ Dolphin=Dauphin
Pillager=Pilleur Pillager=Pilleur
Tropical fish=Poisson tropical Tropical fish=Poisson tropical
Hoglin=Hoglin Hoglin=Hoglin
Baby hoglin=Bébé Hoglin
Zoglin=Zoglin
Strider=Arpenteur Strider=Arpenteur
Glow Squid=Poulpe Brillant Glow Squid=Poulpe Brillant

View File

@ -1,4 +1,3 @@
# textdomain: lightning # textdomain: lightning
@1 was struck by lightning.=@ 1 fue alcanzado por un rayo. Let lightning strike at the specified position or player.No parameter will strike yourself.=Deje que un rayo golpee en la posición especificada o jugador.Ningún parámetro le golpeará a usted mismo.
Let lightning strike at the specified position or yourself=Deje que un rayo golpee en la posición especificada o sobre usted mismo.
No position specified and unknown player=Ninguna posición especificada y jugador desconocido No position specified and unknown player=Ninguna posición especificada y jugador desconocido

View File

@ -0,0 +1,2 @@
# textdomain: mcl_raids
Ominous Banner=Bannière de mauvais augure

View File

@ -2,6 +2,7 @@
Water can flow into this block and cause it to drop as an item.= Water can flow into this block and cause it to drop as an item.=
This block can be turned into dirt with a hoe.= This block can be turned into dirt with a hoe.=
This block can be turned into farmland with a hoe.= This block can be turned into farmland with a hoe.=
This block can be turned into grass path with a shovel.=
This block acts as a soil for all saplings.= This block acts as a soil for all saplings.=
This block acts as a soil for some saplings.= This block acts as a soil for some saplings.=
Sugar canes will grow on this block.= Sugar canes will grow on this block.=

View File

@ -217,7 +217,9 @@ function awards.unlock(name, award)
-- Get award -- Get award
minetest.log("action", name.." has gotten award "..award) minetest.log("action", name.." has gotten award "..award)
minetest.chat_send_all(S("@1 has made the advancement @2", name, minetest.colorize(mcl_colors.GREEN, "[" .. (awdef.title or award) .. "]"))) if minetest.settings:get_bool("mcl_showAdvancementMessages", true) then
minetest.chat_send_all(S("@1 has made the advancement @2", name, minetest.colorize(mcl_colors.GREEN, "[" .. (awdef.title or award) .. "]")))
end
data.unlocked[award] = award data.unlocked[award] = award
awards.save() awards.save()

View File

@ -62,3 +62,9 @@ Advancement “@1” does not exist.=Le progrès «@1» n'existe pas.
Mine a block: @1=Miner un bloc : @1 Mine a block: @1=Miner un bloc : @1
Mine blocks: @1×@2=Miner des blocs : @1×@2 Mine blocks: @1×@2=Miner des blocs : @1×@2
Awards are disabled, enable them first by using /awards enable!=Les récompenses sont désactivées, activez les d'abord en utilisant /awards enable ! Awards are disabled, enable them first by using /awards enable!=Les récompenses sont désactivées, activez les d'abord en utilisant /awards enable !
Goal Completed:=Objectif atteint :
Goal Completed!=Objectif atteint !
Goal Completed: @1=Objectif atteint : @1
Challenge Completed:=Défi relevé :
Challenge Completed!=Défi relevé !
Challenge Completed: @1=Défi relevé : @1

View File

@ -108,7 +108,10 @@ Put lava in a bucket.=Pon lava en un cubo.
Hero of the Village=Héroe de la aldea Hero of the Village=Héroe de la aldea
Successfully defend a village from a raid=Defiende una aldea de una invasión Successfully defend a village from a raid=Defiende una aldea de una invasión
Voluntary Exile=Exilio voluntario Voluntary Exile=Exilio voluntario
Kill a raid captain. Maybe consider staying away from the local villages for the time being...=Mata al capitán de una invasión. Kill a raid captain. Maybe consider staying away from the local villages for the time being...=Mata al capitán de una invasión. Sería mejor alejarte de las aldeas por un tiempo...
Sería mejor alejarte de las aldeas por un tiempo...
Tactical Fishing=Pesca táctica Tactical Fishing=Pesca táctica
Catch a fish... without a fishing rod!=Atrapa a un pez... ¡sin una caña de pescar! Catch a fish... without a fishing rod!=Atrapa a un pez... ¡sin una caña de pescar!
Crafting a New Look=Forjando una nueva imagen
Craft a trimmed armor at a Smithing Table=Decora una armadura en una mesa de herrería
Smithing with Style=Forjando con estilo
Apply these smithing templates at least once: Spire, Snout, Rib, Ward, Silence, Vex, Tide, Wayfinder=Aplica estos moldes de herrería al menos una vez: agujas, hocico, costillas, guardián, silencio, vex, mareas, buscacaminos

View File

@ -111,3 +111,7 @@ Voluntary Exile=Exil volontaire
Kill a raid captain. Maybe consider staying away from the local villages for the time being...=Tuez un capitaine de pillards. Mieux vaut rester loin des villages pour l'instant... Kill a raid captain. Maybe consider staying away from the local villages for the time being...=Tuez un capitaine de pillards. Mieux vaut rester loin des villages pour l'instant...
Tactical Fishing=Pêche tactique Tactical Fishing=Pêche tactique
Catch a fish... without a fishing rod!=Attrapez un poisson... sans canne à pêche ! Catch a fish... without a fishing rod!=Attrapez un poisson... sans canne à pêche !
Crafting a New Look=Motif de Jalousie
Craft a trimmed armor at a Smithing Table=Fabriquez une pièce d'armure ornée sur la table de forge
Smithing with Style=La classe de la cuirasse
Apply these smithing templates at least once: Spire, Snout, Rib, Ward, Silence, Vex, Tide, Wayfinder=Appliquez ces modèles de forge au moins une fois : Tour, Groin, Côte, Abîme, Silence, Vex, Marée, Éclaireur

View File

@ -5,10 +5,15 @@ Contributors=Contributeurs
Creator of MineClone=Créateur de MineClone Creator of MineClone=Créateur de MineClone
Creator of MineClone2=Créateur de MineClone2 Creator of MineClone2=Créateur de MineClone2
Developers=Développeurs Developers=Développeurs
Past Developers=Anciens Développeurs
Jump to speed up (additionally sprint)=Saut pour accélérer (peut être combiné avec sprint) Jump to speed up (additionally sprint)=Saut pour accélérer (peut être combiné avec sprint)
Maintainers=Mainteneurs Maintainers=Mainteneurs
Previous Maintainers=Anciens Mainteneurs
MineClone5=MineClone5 MineClone5=MineClone5
Original Mod Authors=Auteurs des mods originaux Original Mod Authors=Auteurs des mods originaux
Sneak to skip=Shift pour passer Sneak to skip=Shift pour passer
Textures=Textures Textures=Textures
Translations=Traductions Translations=Traductions
Music=Musique
Funders=Fondateurs
Special thanks=Remerciements spéciaux

View File

@ -3,56 +3,6 @@ mcl_inventory = {}
dofile(minetest.get_modpath(minetest.get_current_modname()) .. "/creative.lua") dofile(minetest.get_modpath(minetest.get_current_modname()) .. "/creative.lua")
dofile(minetest.get_modpath(minetest.get_current_modname()) .. "/survival.lua") dofile(minetest.get_modpath(minetest.get_current_modname()) .. "/survival.lua")
--local mod_player = minetest.get_modpath("mcl_player")
--local mod_craftguide = minetest.get_modpath("mcl_craftguide")
---Returns a single itemstack in the given inventory to the main inventory, or drop it when there's no space left.
---@param itemstack mt.ItemStack
---@param dropper mt.ObjectRef
---@param pos mt.Vector
---@param inv mt.InvRef
local function return_item(itemstack, dropper, pos, inv)
if dropper:is_player() then
-- Return to main inventory
if inv:room_for_item("main", itemstack) then
inv:add_item("main", itemstack)
else
-- Drop item on the ground
local v = dropper:get_look_dir()
local p = vector.offset(pos, 0, 1.2, 0)
p.x = p.x + (math.random(1, 3) * 0.2)
p.z = p.z + (math.random(1, 3) * 0.2)
local obj = minetest.add_item(p, itemstack)
if obj then
v.x = v.x * 4
v.y = v.y * 4 + 2
v.z = v.z * 4
obj:set_velocity(v)
obj:get_luaentity()._insta_collect = false
end
end
else
-- Fallback for unexpected cases
minetest.add_item(pos, itemstack)
end
return itemstack
end
---Return items in the given inventory list (name) to the main inventory, or drop them if there is no space left.
---@param player mt.PlayerObjectRef
---@param name string
local function return_fields(player, name)
local inv = player:get_inventory()
local list = inv:get_list(name)
if not list then return end
for i, stack in ipairs(list) do
return_item(stack, player, player:get_pos(), inv)
stack:clear()
inv:set_stack(name, i, stack)
end
end
---@param player mt.PlayerObjectRef ---@param player mt.PlayerObjectRef
---@param armor_change_only? boolean ---@param armor_change_only? boolean
local function set_inventory(player, armor_change_only) local function set_inventory(player, armor_change_only)
@ -72,9 +22,9 @@ end
-- Drop items in craft grid and reset inventory on closing -- Drop items in craft grid and reset inventory on closing
minetest.register_on_player_receive_fields(function(player, formname, fields) minetest.register_on_player_receive_fields(function(player, formname, fields)
if fields.quit then if fields.quit then
return_fields(player, "craft") mcl_util.move_player_list(player, "craft")
return_fields(player, "enchanting_lapis") mcl_util.move_player_list(player, "enchanting_lapis")
return_fields(player, "enchanting_item") mcl_util.move_player_list(player, "enchanting_item")
if not minetest.is_creative_enabled(player:get_player_name()) and (formname == "" or formname == "main") then if not minetest.is_creative_enabled(player:get_player_name()) and (formname == "" or formname == "main") then
set_inventory(player) set_inventory(player)
end end
@ -88,9 +38,9 @@ end
-- Drop crafting grid items on leaving -- Drop crafting grid items on leaving
minetest.register_on_leaveplayer(function(player) minetest.register_on_leaveplayer(function(player)
return_fields(player, "craft") mcl_util.move_player_list(player, "craft")
return_fields(player, "enchanting_lapis") mcl_util.move_player_list(player, "enchanting_lapis")
return_fields(player, "enchanting_item") mcl_util.move_player_list(player, "enchanting_item")
end) end)
minetest.register_on_joinplayer(function(player) minetest.register_on_joinplayer(function(player)
@ -116,9 +66,9 @@ minetest.register_on_joinplayer(function(player)
items remaining in the crafting grid from the previous join; this is likely items remaining in the crafting grid from the previous join; this is likely
when the server has been shutdown and the server didn't clean up the player when the server has been shutdown and the server didn't clean up the player
inventories. ]] inventories. ]]
return_fields(player, "craft") mcl_util.move_player_list(player, "craft")
return_fields(player, "enchanting_item") mcl_util.move_player_list(player, "enchanting_lapis")
return_fields(player, "enchanting_lapis") mcl_util.move_player_list(player, "enchanting_item")
end) end)
---@param player mt.PlayerObjectRef ---@param player mt.PlayerObjectRef

View File

@ -1,2 +1,3 @@
# textdomain: mcl_ver_info # textdomain: mcl_ver_info
Sorry, but your version of Minetest doesn't support the latest API. Please upgrade your minetest.=Désolé, mais votre version de Minetest ne supporte la dernière API. Veuillez mettre à jour minetest. Sorry, but your version of Minetest doesn't support the latest API. Please upgrade your minetest.=Désolé, mais votre version de Minetest ne supporte la dernière API. Veuillez mettre à jour minetest.
Display Mineclone 2 game version.=Affiche la version de Mineclone 2.

View File

@ -2,12 +2,13 @@
Dispenser=Dispensador Dispenser=Dispensador
A dispenser is a block which acts as a redstone component which, when powered with redstone power, dispenses an item. It has a container with 9 inventory slots.=Un dispensador es un bloque que actúa como un componente de redstone que, cuando se alimenta con energía de redstone, dispensa un artículo. Tiene un contenedor con 9 ranuras de inventario. A dispenser is a block which acts as a redstone component which, when powered with redstone power, dispenses an item. It has a container with 9 inventory slots.=Un dispensador es un bloque que actúa como un componente de redstone que, cuando se alimenta con energía de redstone, dispensa un artículo. Tiene un contenedor con 9 ranuras de inventario.
Place the dispenser in one of 6 possible directions. The “hole” is where items will fly out of the dispenser. Use the dispenser to access its inventory. Insert the items you wish to dispense. Supply the dispenser with redstone energy once to dispense a random item.=Coloque el dispensador en una de las 6 direcciones posibles. El "agujero" es donde los artículos saldrán volando del dispensador. Use el dispensador para acceder a su inventario. Inserte los artículos que desea dispensar. Proporcione al dispensador energía de redstone una vez para dispensar un elemento aleatorio: Place the dispenser in one of 6 possible directions. The “hole” is where items will fly out of the dispenser. Use the dispenser to access its inventory. Insert the items you wish to dispense. Supply the dispenser with redstone energy once to dispense a random item.=Coloque el dispensador en una de las 6 direcciones posibles. El "agujero" es donde los artículos saldrán volando del dispensador. Use el dispensador para acceder a su inventario. Inserte los artículos que desea dispensar. Proporcione al dispensador energía de redstone una vez para dispensar un elemento aleatorio:
The dispenser will do different things, depending on the dispensed item:= El dispensador hará diferentes cosas, dependiendo del artículo dispensado:
• Arrows: Are launched=• Flechas: Se lanzan • Arrows: Are launched=• Flechas: Se lanzan
• Eggs and snowballs: Are thrown=• Huevos y bolas de nieve: Son lanzados • Eggs and snowballs: Are thrown=• Huevos y bolas de nieve: Son lanzados
• Fire charges: Are fired in a straight line=• Cargas de fuego: Se disparan en línea recta • Fire charges: Are fired in a straight line=• Cargas de fuego: Se disparan en línea recta
• Armor: Will be equipped to players and armor stands=• Armadura: Estará equipada para jugadores y armaduras • Armor: Will be equipped to players and armor stands=• Armadura: Estará equipada para jugadores y armaduras
• Boats: Are placed on water or are dropped=• Barcas: Se colocan en el agua o se dejan caer • Boats: Are placed on water or are dropped=• Barcas: Se colocan en el agua o se dejan caer
• Minecart: Are placed on rails or are dropped=• Carro de minas: Se colocan sobre rieles o se dejan caer = • Minecart: Are placed on rails or are dropped=• Carro de minas: Se colocan sobre rieles o se dejan caer
• Bone meal: Is applied on the block it is facing=• Harina de hueso: Se aplica en el bloque que está enfrentando • Bone meal: Is applied on the block it is facing=• Harina de hueso: Se aplica en el bloque que está enfrentando
• Empty buckets: Are used to collect a liquid source=• Cubos vacíos: Se utilizan para recolectar una fuente líquida • Empty buckets: Are used to collect a liquid source=• Cubos vacíos: Se utilizan para recolectar una fuente líquida
• Filled buckets: Are used to place a liquid source=• Cubos llenos: Se utilizan para colocar una fuente de líquido • Filled buckets: Are used to place a liquid source=• Cubos llenos: Se utilizan para colocar una fuente de líquido
@ -20,3 +21,5 @@ Place the dispenser in one of 6 possible directions. The “hole” is where ite
Downwards-Facing Dispenser=Dispensador orientado hacia abajo Downwards-Facing Dispenser=Dispensador orientado hacia abajo
Upwards-Facing Dispenser=Dispensador orientado hacia arriba Upwards-Facing Dispenser=Dispensador orientado hacia arriba
Inventory=Inventario Inventory=Inventario
9 inventory slots=9 ranuras de inventario
Launches item when powered by redstone power=Laza un artículo cuando recibe energía de redstone

View File

@ -125,7 +125,11 @@ local dropperdef = {
local dropnode = minetest.get_node(droppos) local dropnode = minetest.get_node(droppos)
-- Do not drop into solid nodes, unless they are containers -- Do not drop into solid nodes, unless they are containers
local dropnodedef = minetest.registered_nodes[dropnode.name] local dropnodedef = minetest.registered_nodes[dropnode.name]
if dropnodedef.walkable and not dropnodedef.groups.container then if dropnodedef.groups.container == 2 then
-- If they are containers - double down as hopper
mcl_util.hopper_push(pos, droppos)
end
if dropnodedef.walkable then
return return
end end
local stacks = {} local stacks = {}
@ -141,25 +145,18 @@ local dropperdef = {
local dropitem = ItemStack(stack) local dropitem = ItemStack(stack)
dropitem:set_count(1) dropitem:set_count(1)
local stack_id = stacks[r].stackpos local stack_id = stacks[r].stackpos
local pos_variation = 100
-- If it's a container, attempt to put it into the container droppos = vector.offset(droppos,
local dropped = mcl_util.move_item_container(pos, droppos, nil, stack_id) math.random(-pos_variation, pos_variation) / 1000,
-- No container? math.random(-pos_variation, pos_variation) / 1000,
if not dropped and not dropnodedef.groups.container then math.random(-pos_variation, pos_variation) / 1000
-- Drop item normally )
local pos_variation = 100 local item_entity = minetest.add_item(droppos, dropitem)
droppos = vector.offset(droppos, local drop_vel = vector.subtract(droppos, pos)
math.random(-pos_variation, pos_variation) / 1000, local speed = 3
math.random(-pos_variation, pos_variation) / 1000, item_entity:set_velocity(vector.multiply(drop_vel, speed))
math.random(-pos_variation, pos_variation) / 1000 stack:take_item()
) inv:set_stack("main", stack_id, stack)
local item_entity = minetest.add_item(droppos, dropitem)
local drop_vel = vector.subtract(droppos, pos)
local speed = 3
item_entity:set_velocity(vector.multiply(drop_vel, speed))
stack:take_item()
inv:set_stack("main", stack_id, stack)
end
end end
end, end,
rules = mesecon.rules.alldirs, rules = mesecon.rules.alldirs,

View File

@ -108,7 +108,7 @@ function mesecon.register_button(basename, description, texture, recipeitem, sou
if groups_off.material_wood ~= 0 then if groups_off.material_wood ~= 0 then
longdesc = S("A wooden button is a redstone component made out of wood which can be pushed to provide redstone power. When pushed, it powers adjacent redstone components for 1.5 seconds. Wooden buttons may also be pushed by arrows.") longdesc = S("A wooden button is a redstone component made out of wood which can be pushed to provide redstone power. When pushed, it powers adjacent redstone components for 1.5 seconds. Wooden buttons may also be pushed by arrows.")
else else
longdesc = S("A button is a redstone compent which can be pushed to provide redstone power. When pushed, it powers adjacent redstone components for @1 seconds.", button_timer) longdesc = S("A button is a redstone component which can be pushed to provide redstone power. When pushed, it powers adjacent redstone components for @1 seconds.", button_timer)
end end
end end

View File

@ -17,3 +17,4 @@ A wooden button is a redstone component made out of wood which can be pushed to
Provides redstone power when pushed=Fournit une puissance de redstone lorsqu'il est poussé Provides redstone power when pushed=Fournit une puissance de redstone lorsqu'il est poussé
Push duration: @1s=Durée de poussée : @1s Push duration: @1s=Durée de poussée : @1s
Pushable by arrow=Poussable par une flèche Pushable by arrow=Poussable par une flèche
A button is a redstone component which can be pushed to provide redstone power. When pushed, it powers adjacent redstone components for @1 seconds.=Un bouton est un composant redstone qui peut être poussé afin de fournir de la puissance redstone. Lorsqu'il est poussé, il fournit de la puissance redstone pendant @1 seconde.

View File

@ -17,4 +17,4 @@ A wooden button is a redstone component made out of wood which can be pushed to
Provides redstone power when pushed=Выдаёт сигнал редстоуна при нажатии Provides redstone power when pushed=Выдаёт сигнал редстоуна при нажатии
Push duration: @1s=Длительность нажатия: @1с Push duration: @1s=Длительность нажатия: @1с
Pushable by arrow=Нажимается стрелами Pushable by arrow=Нажимается стрелами
A button is a redstone compent which can be pushed to provide redstone power. When pushed, it powers adjacent redstone components for @1 seconds.=Кнопка это компонент редстоуна, её можно нажать, чтобы получить сигнал редстоуна. При нажатии она включает соседние компоненты редстоуна на @1 с. A button is a redstone component which can be pushed to provide redstone power. When pushed, it powers adjacent redstone components for @1 seconds.=Кнопка это компонент редстоуна, её можно нажать, чтобы получить сигнал редстоуна. При нажатии она включает соседние компоненты редстоуна на @1 с.

View File

@ -17,4 +17,4 @@ A wooden button is a redstone component made out of wood which can be pushed to
Provides redstone power when pushed= Provides redstone power when pushed=
Push duration: @1s= Push duration: @1s=
Pushable by arrow= Pushable by arrow=
A button is a redstone compent which can be pushed to provide redstone power. When pushed, it powers adjacent redstone components for @1 seconds.= A button is a redstone component which can be pushed to provide redstone power. When pushed, it powers adjacent redstone components for @1 seconds.=

View File

@ -152,8 +152,6 @@ function mesecon.noteblock_play(pos, param2)
soundname="mesecons_noteblock_xylophone_metal" soundname="mesecons_noteblock_xylophone_metal"
elseif block_below_name == "mcl_nether:soul_sand" then elseif block_below_name == "mcl_nether:soul_sand" then
soundname="mesecons_noteblock_cowbell" soundname="mesecons_noteblock_cowbell"
elseif block_below_name == "mcl_farming:pumpkin" or block_below_name == "mcl_farming:pumpkin_face" or block_below_name == "mcl_farming:pumpkin_face_light" then
soundname="mesecons_noteblock_didgeridoo"
elseif block_below_name == "mcl_core:emeraldblock" then elseif block_below_name == "mcl_core:emeraldblock" then
soundname="mesecons_noteblock_squarewave" soundname="mesecons_noteblock_squarewave"
elseif block_below_name == "mcl_farming:hay_block" then elseif block_below_name == "mcl_farming:hay_block" then
@ -162,6 +160,8 @@ function mesecon.noteblock_play(pos, param2)
soundname="mesecons_noteblock_piano_digital" soundname="mesecons_noteblock_piano_digital"
elseif minetest.get_item_group(block_below_name, "wool") ~= 0 then elseif minetest.get_item_group(block_below_name, "wool") ~= 0 then
soundname="mesecons_noteblock_guitar" soundname="mesecons_noteblock_guitar"
elseif minetest.get_item_group(block_below_name, "pumpkin") ~= 0 then
soundname="mesecons_noteblock_didgeridoo"
elseif minetest.get_item_group(block_below_name, "material_glass") ~= 0 then elseif minetest.get_item_group(block_below_name, "material_glass") ~= 0 then
soundname="mesecons_noteblock_hit" soundname="mesecons_noteblock_hit"
elseif minetest.get_item_group(block_below_name, "material_wood") ~= 0 then elseif minetest.get_item_group(block_below_name, "material_wood") ~= 0 then

View File

@ -47,4 +47,5 @@ Thorns=Épines
Reflects some of the damage taken when hit, at the cost of reducing durability with each proc.=Reflète une partie des dégâts subis lors de la frappe, au prix d'une réduction de la durabilité à chaque déclenchement. Reflects some of the damage taken when hit, at the cost of reducing durability with each proc.=Reflète une partie des dégâts subis lors de la frappe, au prix d'une réduction de la durabilité à chaque déclenchement.
Aqua Affinity=Affinité aquatique Aqua Affinity=Affinité aquatique
#Translations for armor trims
Smithing Template '@1'=Modèle à forger '@1'

View File

@ -24,6 +24,7 @@ Bamboo Mosaic Stair=Escalier mosaïque de bambou
Bamboo Plank Slab=Dalle de planches de bambou Bamboo Plank Slab=Dalle de planches de bambou
Bamboo Plank Stair=Escalier de planches de bambou Bamboo Plank Stair=Escalier de planches de bambou
Bamboo Pressure Plate=Plaque de pression de bambou Bamboo Pressure Plate=Plaque de pression de bambou
Bamboo Sign=Panneau de bambou
Bamboo Slab=Dalle de bambou Bamboo Slab=Dalle de bambou
Bamboo Stair=Escalier de bambou Bamboo Stair=Escalier de bambou
Bamboo Trapdoor=Trappe de bambou Bamboo Trapdoor=Trappe de bambou

View File

@ -76,3 +76,4 @@ You can copy the pattern of a banner by placing two banners of the same color in
And one additional layer=Et une couche supplémentaire And one additional layer=Et une couche supplémentaire
And @1 additional layers=Et @1 couches supplémentaires And @1 additional layers=Et @1 couches supplémentaires
Paintable decoration=Décoration à peindre Paintable decoration=Décoration à peindre
Preview Banner=Aperçu de la bannière

View File

@ -383,6 +383,15 @@ function mcl_beds.on_rightclick(pos, player, is_top)
end end
if message then if message then
mcl_title.set(player, "actionbar", {text=message, color="white", stay=60}) mcl_title.set(player, "actionbar", {text=message, color="white", stay=60})
else -- someone just successfully entered a bed
local connected_players = minetest.get_connected_players()
local sleep_hud_message = S("@1/@2 players currently in bed.", player_in_bed, players_in_bed_setting() * #connected_players / 100)
for _, player in pairs(connected_players) do
if not mcl_beds.player[player:get_player_name()] then -- only send message to players not sleeping.
if mcl_title.params_get(player) then mcl_title.clear(player) end -- clear, old message is still being displayed
mcl_title.set(player, "actionbar", {text=sleep_hud_message, color="white", stay=60})
end
end
end end
else else
lay_down(player, nil, nil, false) lay_down(player, nil, nil, false)

View File

@ -46,4 +46,5 @@ send!=senden!
You are missing the 'shout' privilege! It's required in order to talk in chat...=Ihnen fehlt das 'shout' Privileg! Es wird benötigt, um im Chat reden zu können... You are missing the 'shout' privilege! It's required in order to talk in chat...=Ihnen fehlt das 'shout' Privileg! Es wird benötigt, um im Chat reden zu können...
You exceeded the maximum number of messages per 10 seconds!=Sie haben die maximale Anzahl an Chatnachrichten pro 10 Sekunden überschritten! You exceeded the maximum number of messages per 10 seconds!=Sie haben die maximale Anzahl an Chatnachrichten pro 10 Sekunden überschritten!
Hey! Would you guys mind sleeping?=Hey, würdet Ihr bitte zu Bett gehen? Hey! Would you guys mind sleeping?=Hey, würdet Ihr bitte zu Bett gehen?
Sorry, but you have to wait @1 seconds until you may use this button again!=Sie müssen leider noch @1 Sekunden warten, bevor sie diesen Knopf erneut benutzen können! Sorry, but you have to wait @1 seconds until you may use this button again!=Sie müssen leider noch @1 Sekunden warten, bevor sie diesen Knopf erneut benutzen können!
@1/@2 players currently in bed.=@1/@2 Spieler aktuell im Bett.

View File

@ -41,3 +41,9 @@ You will fall asleep when @1% of all players are in bed.=Vous vous endormirez lo
You're in bed.=Tu es au lit. You're in bed.=Tu es au lit.
Allows you to sleep=Vous permet de dormir Allows you to sleep=Vous permet de dormir
Respawn Anchor=Ancre de réapparition Respawn Anchor=Ancre de réapparition
Chat:=Discussion
send!=envoyé !
You are missing the 'shout' privilege! It's required in order to talk in chat...=Il vous manque le privilège 'shout' ! C'est indispensable pour participer à la discussion...
You exceeded the maximum number of messages per 10 seconds!=Vous avez dépassé le nombre maximal de message par 10 secondes !
Hey! Would you guys mind sleeping?=Eh, vous ne voulez pas dormir ?
Sorry, but you have to wait @1 seconds until you may use this button again!=Désolé, mais il faut attendre @1 seconde avant de réutiliser ce bouton !

View File

@ -46,4 +46,5 @@ send!=
You are missing the 'shout' privilege! It's required in order to talk in chat...= You are missing the 'shout' privilege! It's required in order to talk in chat...=
You exceeded the maximum number of messages per 10 seconds!= You exceeded the maximum number of messages per 10 seconds!=
Hey! Would you guys mind sleeping?= Hey! Would you guys mind sleeping?=
Sorry, but you have to wait @1 seconds until you may use this button again!= Sorry, but you have to wait @1 seconds until you may use this button again!=
@1/@2 players currently in bed.=

View File

@ -193,16 +193,50 @@ minetest.registered_nodes["mcl_fire:fire"].on_construct=function(pos)
end end
--slabs/stairs --slabs/stairs
mcl_stairs.register_stair_and_slab_simple("blackstone", "mcl_blackstone:blackstone", S("Blackstone Stair"), S("Blackstone Slab"), S("Double Blackstone Slab")) mcl_stairs.register_stair_and_slab("blackstone", "mcl_blackstone:blackstone",
mcl_stairs.register_stair_and_slab_simple("blackstone_polished", "mcl_blackstone:blackstone_polished", S("Polished Blackstone Stair"), S("Polished Blackstone Slab"), S("Polished Double Blackstone Slab")) {cracky=3, pickaxey=1, material_stone=1},
mcl_stairs.register_stair_and_slab_simple("blackstone_chiseled_polished", "mcl_blackstone:blackstone_chiseled_polished", S("Chiseled Polished Blackstone Stair"), S("Chiseled Polished Blackstone Slab"), S("Double Chiseled Polished Blackstone Slab")) {"mcl_blackstone_top.png", "mcl_blackstone_top.png", "mcl_blackstone_side.png"},
mcl_stairs.register_stair_and_slab_simple("blackstone_brick_polished", "mcl_blackstone:blackstone_brick_polished", S("Polished Blackstone Brick Stair"), S("Polished Blackstone Brick Slab"), S("Double Polished Blackstone Brick Slab")) S("Blackstone Stairs"),
S("Blackstone Slab"),
mcl_sounds.node_sound_stone_defaults(), 6, 2,
S("Double Blackstone Slab"), nil)
mcl_stairs.register_stair_and_slab("blackstone_polished", "mcl_blackstone:blackstone_polished",
{cracky=3, pickaxey=1, material_stone=1},
{"mcl_blackstone_polished.png"},
S("Polished Blackstone Stairs"),
S("Polished Blackstone Slab"),
mcl_sounds.node_sound_stone_defaults(), 6, 2,
S("Double Polished Blackstone Slab"), nil)
mcl_stairs.register_stair_and_slab("blackstone_chiseled_polished", "mcl_blackstone:blackstone_chiseled_polished",
{cracky=3, pickaxey=1, material_stone=1},
{"mcl_blackstone_chiseled_polished.png"},
S("Chiseled Polished Blackstone Stairs"),
S("Chiseled Polished Blackstone Slab"),
mcl_sounds.node_sound_stone_defaults(), 6, 2,
S("Double Chiseled Polished Blackstone Slab"), nil)
mcl_stairs.register_stair_and_slab("blackstone_brick_polished", "mcl_blackstone:blackstone_brick_polished",
{cracky=3, pickaxey=1, material_stone=1},
{"mcl_blackstone_polished_bricks.png"},
S("Polished Blackstone Brick Stair Stairs"),
S("Polished Blackstone Brick Stair Slab"),
mcl_sounds.node_sound_stone_defaults(), 6, 2,
S("Double Polished Blackstone Brick Stair Slab"), nil)
--Wall --Wall
mcl_walls.register_wall( mcl_walls.register_wall(
"mcl_blackstone:wall", "mcl_blackstone:wall",
S("Blackstone Wall"), S("Blackstone Wall"),
"mcl_blackstone:blackstone" "mcl_blackstone:blackstone",
{
"mcl_blackstone_top.png",
"mcl_blackstone_top.png",
"mcl_blackstone_side.png"
},
"",
{ cracky=3, pickaxey=1, material_stone=1 }
) )
--lavacooling --lavacooling
@ -366,3 +400,10 @@ minetest.register_craft({
{ "group:soul_block" }, { "group:soul_block" },
} }
}) })
-- stonecutter recipes
mcl_stonecutter.register_recipe("mcl_blackstone:basalt", "mcl_blackstone:basalt_polished")
mcl_stonecutter.register_recipe("mcl_blackstone:blackstone", "mcl_blackstone:blackstone_polished")
mcl_stonecutter.register_recipe("mcl_blackstone:blackstone_polished", "mcl_blackstone:blackstone_chiseled_polished")
mcl_stonecutter.register_recipe("mcl_blackstone:blackstone_polished", "mcl_blackstone:blackstone_brick_polished")
mcl_stonecutter.register_recipe("mcl_nether:quartz_block", "mcl_blackstone:quartz_brick")

View File

@ -1,3 +1,3 @@
name = mcl_blackstone name = mcl_blackstone
author = debian044 author = debian044
depends = mcl_core, screwdriver, mcl_stairs, mclx_stairs, mcl_walls, mclx_fences, mcl_torches, mcl_fire depends = mcl_core, screwdriver, mcl_stairs, mclx_stairs, mcl_walls, mclx_fences, mcl_torches, mcl_fire, mcl_stonecutter, mcl_nether

View File

@ -453,7 +453,7 @@ minetest.register_node("mcl_blast_furnace:blast_furnace", {
"blast_furnace_side.png", "blast_furnace_front.png" "blast_furnace_side.png", "blast_furnace_front.png"
}, },
paramtype2 = "facedir", paramtype2 = "facedir",
groups = { pickaxey = 1, container = 4, deco_block = 1, material_stone = 1 }, groups = { pickaxey = 1, container = 2, deco_block = 1, material_stone = 1 },
is_ground_content = false, is_ground_content = false,
sounds = mcl_sounds.node_sound_stone_defaults(), sounds = mcl_sounds.node_sound_stone_defaults(),
@ -514,6 +514,11 @@ minetest.register_node("mcl_blast_furnace:blast_furnace", {
_mcl_blast_resistance = 3.5, _mcl_blast_resistance = 3.5,
_mcl_hardness = 3.5, _mcl_hardness = 3.5,
on_rotate = on_rotate, on_rotate = on_rotate,
_mcl_hoppers_on_try_pull = mcl_furnaces.hoppers_on_try_pull,
_mcl_hoppers_on_try_push = mcl_furnaces.hoppers_on_try_push,
_mcl_hoppers_on_after_push = function(pos)
minetest.get_node_timer(pos):start(1.0)
end,
}) })
minetest.register_node("mcl_blast_furnace:blast_furnace_active", { minetest.register_node("mcl_blast_furnace:blast_furnace_active", {
@ -531,7 +536,7 @@ minetest.register_node("mcl_blast_furnace:blast_furnace_active", {
paramtype = "light", paramtype = "light",
light_source = LIGHT_ACTIVE_FURNACE, light_source = LIGHT_ACTIVE_FURNACE,
drop = "mcl_blast_furnace:blast_furnace", drop = "mcl_blast_furnace:blast_furnace",
groups = { pickaxey = 1, container = 4, deco_block = 1, not_in_creative_inventory = 1, material_stone = 1 }, groups = { pickaxey = 1, container = 2, deco_block = 1, not_in_creative_inventory = 1, material_stone = 1 },
is_ground_content = false, is_ground_content = false,
sounds = mcl_sounds.node_sound_stone_defaults(), sounds = mcl_sounds.node_sound_stone_defaults(),
on_timer = blast_furnace_node_timer, on_timer = blast_furnace_node_timer,
@ -574,6 +579,8 @@ minetest.register_node("mcl_blast_furnace:blast_furnace_active", {
_mcl_hardness = 3.5, _mcl_hardness = 3.5,
on_rotate = on_rotate, on_rotate = on_rotate,
after_rotate = after_rotate_active, after_rotate = after_rotate_active,
_mcl_hoppers_on_try_pull = mcl_furnaces.hoppers_on_try_pull,
_mcl_hoppers_on_try_push = mcl_furnaces.hoppers_on_try_push,
}) })
minetest.register_craft({ minetest.register_craft({

View File

@ -438,7 +438,7 @@ minetest.register_node("mcl_books:bookshelf", {
flammable = 3, flammable = 3,
fire_encouragement = 30, fire_encouragement = 30,
fire_flammability = 20, fire_flammability = 20,
container = 1 container = 2
}, },
drop = "mcl_books:book 3", drop = "mcl_books:book 3",
sounds = wood_sound, sounds = wood_sound,
@ -472,6 +472,12 @@ minetest.register_node("mcl_books:bookshelf", {
on_blast = on_blast, on_blast = on_blast,
on_rightclick = bookshelf_gui, on_rightclick = bookshelf_gui,
on_destruct = close_forms, on_destruct = close_forms,
_mcl_hoppers_on_try_push = function(pos, hop_pos, hop_inv, hop_list)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
return inv, "main", mcl_util.select_stack(hop_inv, hop_list, inv, "main",
function(stack) return minetest.get_item_group(stack:get_name(), "book") == 1 or stack:get_name() == "mcl_enchanting:book_enchanted" end)
end,
}) })
minetest.register_craft({ minetest.register_craft({

View File

@ -48,7 +48,7 @@ function mcl_bows.shoot_arrow(arrow_item, pos, dir, yaw, shooter, power, damage,
damage = damage + (enchantments.power + 1) / 4 damage = damage + (enchantments.power + 1) / 4
end end
if enchantments.punch then if enchantments.punch then
knockback = enchantments.punch * 3 knockback = enchantments.punch * 21
end end
if enchantments.flame then if enchantments.flame then
mcl_burning.set_on_fire(obj, math.huge) mcl_burning.set_on_fire(obj, math.huge)

View File

@ -15,4 +15,4 @@ Damage from dispenser: 3=Dégâts du distributeur : 3
Launches arrows=Lance des flèches Launches arrows=Lance des flèches
Crossbow=Arbalète Crossbow=Arbalète
Crossbows are ranged weapons to shoot arrows at your foes.=Les arbalètes sont des armes à distance pour tirer des flèches sur vos ennemis. Crossbows are ranged weapons to shoot arrows at your foes.=Les arbalètes sont des armes à distance pour tirer des flèches sur vos ennemis.
To use the crossbow, you first need to have at least one arrow anywhere in your inventory (unless in Creative Mode). Hold down the right mouse button to charge, release to shoot.=Pour utiliser l'arbalète, vous devez d'abord avoir au moins une flèche n'importe où dans votre inventaire (sauf en mode créatif). Maintenez enfoncé le bouton droit de la souris pour charger, relâchez pour tirer. To use the crossbow, you first need to have at least one arrow anywhere in your inventory (unless in Creative Mode). Hold down the right mouse button to charge, release to load an arrow into the chamber, then to shoot press left mouse.=Pour utiliser l'arbalète, vous devez d'abord avoir au moins une flèche n'importe où dans votre inventaire (sauf en mode créatif). Maintenez enfoncé le bouton droit de la souris pour charger, relâchez pour charger la flèche dans la chambre, puis pour tirer cliquez droit.

View File

@ -376,13 +376,41 @@ local function allow_take(pos, listname, index, stack, player)
end end
end end
local function hoppers_on_try_push(pos, hop_pos, hop_inv, hop_list)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
if math.abs(pos.y - hop_pos.y) > math.abs(pos.x - hop_pos.x) and math.abs(pos.y - hop_pos.y) > math.abs(pos.z - hop_pos.z) then
return inv, "input", mcl_util.select_stack(hop_inv, hop_list, inv, "input",
function(stack) return minetest.get_item_group(stack:get_name(), "brewitem") == 1 and minetest.get_item_group(stack:get_name(), "bottle") == 0 end)
else
local stack = mcl_util.select_stack(hop_inv, hop_list, inv, "fuel", function(stack) return stack:get_name() == "mcl_mobitems:blaze_powder" end)
if stack then
return inv, "fuel", stack
else
return inv, "stand", mcl_util.select_stack(hop_inv, hop_list, inv, "stand",
function(stack) return minetest.get_item_group(stack:get_name(), "bottle") == 1 end)
end
end
end
local function hoppers_on_try_pull(pos, hop_pos, hop_inv, hop_list)
local meta = minetest.get_meta(pos)
local stand_timer = meta:get_float("stand_timer") or 0
if stand_timer > 0 then
return nil, nil, nil
end
local inv = meta:get_inventory()
local stack = mcl_util.select_stack(inv, "stand", hop_inv, hop_list)
return inv, "stand", stack
end
minetest.register_node("mcl_brewing:stand_000", { minetest.register_node("mcl_brewing:stand_000", {
description = S("Brewing Stand"), description = S("Brewing Stand"),
_doc_items_longdesc = S("The stand allows you to brew potions!"), _doc_items_longdesc = S("The stand allows you to brew potions!"),
_doc_items_usagehelp = doc_string, _doc_items_usagehelp = doc_string,
_tt_help = S("Brew Potions"), _tt_help = S("Brew Potions"),
groups = {pickaxey=1, brewitem=1 }, groups = {pickaxey=1, container = 2, brewitem=1 },
tiles = tiles, tiles = tiles,
use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true, use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true,
drop = "mcl_brewing:stand", drop = "mcl_brewing:stand",
@ -444,12 +472,20 @@ minetest.register_node("mcl_brewing:stand_000", {
on_timer = brewing_stand_timer, on_timer = brewing_stand_timer,
on_rotate = on_rotate, on_rotate = on_rotate,
_mcl_hoppers_on_try_push = hoppers_on_try_push,
_mcl_hoppers_on_try_pull = hoppers_on_try_pull,
_mcl_hoppers_on_after_push = function(pos)
on_put(pos, nil, nil, nil, nil)
end,
_mcl_hoppers_on_after_pull = function(pos)
on_put(pos, nil, nil, nil, nil)
end,
}) })
minetest.register_node("mcl_brewing:stand_100", { minetest.register_node("mcl_brewing:stand_100", {
description = S("Brewing Stand"), description = S("Brewing Stand"),
_doc_items_create_entry = false, _doc_items_create_entry = false,
_tt_help = S("Brew Potions"), _tt_help = S("Brew Potions"),
groups = {pickaxey=1, not_in_creative_inventory = 1, not_in_craft_guide = 1}, groups = { pickaxey=1, container = 2, not_in_creative_inventory = 1, not_in_craft_guide = 1 },
tiles = tiles, tiles = tiles,
use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true, use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true,
drop = "mcl_brewing:stand", drop = "mcl_brewing:stand",
@ -514,13 +550,21 @@ minetest.register_node("mcl_brewing:stand_100", {
end, end,
on_timer = brewing_stand_timer, on_timer = brewing_stand_timer,
on_rotate = on_rotate, on_rotate = on_rotate,
_mcl_hoppers_on_try_push = hoppers_on_try_push,
_mcl_hoppers_on_try_pull = hoppers_on_try_pull,
_mcl_hoppers_on_after_push = function(pos)
on_put(pos, nil, nil, nil, nil)
end,
_mcl_hoppers_on_after_pull = function(pos)
on_put(pos, nil, nil, nil, nil)
end,
}) })
minetest.register_node("mcl_brewing:stand_010", { minetest.register_node("mcl_brewing:stand_010", {
description = S("Brewing Stand"), description = S("Brewing Stand"),
_doc_items_create_entry = false, _doc_items_create_entry = false,
_tt_help = S("Brew Potions"), _tt_help = S("Brew Potions"),
groups = {pickaxey=1, not_in_creative_inventory = 1, not_in_craft_guide = 1}, groups = {pickaxey=1, container = 2, not_in_creative_inventory = 1, not_in_craft_guide = 1},
tiles = tiles, tiles = tiles,
use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true, use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true,
drop = "mcl_brewing:stand", drop = "mcl_brewing:stand",
@ -586,13 +630,21 @@ minetest.register_node("mcl_brewing:stand_010", {
end, end,
on_timer = brewing_stand_timer, on_timer = brewing_stand_timer,
on_rotate = on_rotate, on_rotate = on_rotate,
_mcl_hoppers_on_try_push = hoppers_on_try_push,
_mcl_hoppers_on_try_pull = hoppers_on_try_pull,
_mcl_hoppers_on_after_push = function(pos)
on_put(pos, nil, nil, nil, nil)
end,
_mcl_hoppers_on_after_pull = function(pos)
on_put(pos, nil, nil, nil, nil)
end,
}) })
minetest.register_node("mcl_brewing:stand_001", { minetest.register_node("mcl_brewing:stand_001", {
description = S("Brewing Stand"), description = S("Brewing Stand"),
_doc_items_create_entry = false, _doc_items_create_entry = false,
_tt_help = S("Brew Potions"), _tt_help = S("Brew Potions"),
groups = {pickaxey=1, not_in_creative_inventory = 1, not_in_craft_guide = 1}, groups = {pickaxey=1, container = 2, not_in_creative_inventory = 1, not_in_craft_guide = 1},
tiles = tiles, tiles = tiles,
use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true, use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true,
drop = "mcl_brewing:stand", drop = "mcl_brewing:stand",
@ -653,13 +705,21 @@ minetest.register_node("mcl_brewing:stand_001", {
end, end,
on_timer = brewing_stand_timer, on_timer = brewing_stand_timer,
on_rotate = on_rotate, on_rotate = on_rotate,
_mcl_hoppers_on_try_push = hoppers_on_try_push,
_mcl_hoppers_on_try_pull = hoppers_on_try_pull,
_mcl_hoppers_on_after_push = function(pos)
on_put(pos, nil, nil, nil, nil)
end,
_mcl_hoppers_on_after_pull = function(pos)
on_put(pos, nil, nil, nil, nil)
end,
}) })
minetest.register_node("mcl_brewing:stand_110", { minetest.register_node("mcl_brewing:stand_110", {
description = S("Brewing Stand"), description = S("Brewing Stand"),
_doc_items_create_entry = false, _doc_items_create_entry = false,
_tt_help = S("Brew Potions"), _tt_help = S("Brew Potions"),
groups = {pickaxey=1, not_in_creative_inventory = 1, not_in_craft_guide = 1}, groups = {pickaxey=1, container = 2, not_in_creative_inventory = 1, not_in_craft_guide = 1},
tiles = tiles, tiles = tiles,
use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true, use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true,
drop = "mcl_brewing:stand", drop = "mcl_brewing:stand",
@ -730,13 +790,21 @@ minetest.register_node("mcl_brewing:stand_110", {
end, end,
on_timer = brewing_stand_timer, on_timer = brewing_stand_timer,
on_rotate = on_rotate, on_rotate = on_rotate,
_mcl_hoppers_on_try_push = hoppers_on_try_push,
_mcl_hoppers_on_try_pull = hoppers_on_try_pull,
_mcl_hoppers_on_after_push = function(pos)
on_put(pos, nil, nil, nil, nil)
end,
_mcl_hoppers_on_after_pull = function(pos)
on_put(pos, nil, nil, nil, nil)
end,
}) })
minetest.register_node("mcl_brewing:stand_101", { minetest.register_node("mcl_brewing:stand_101", {
description = S("Brewing Stand"), description = S("Brewing Stand"),
_doc_items_create_entry = false, _doc_items_create_entry = false,
_tt_help = S("Brew Potions"), _tt_help = S("Brew Potions"),
groups = {pickaxey=1, not_in_creative_inventory = 1, not_in_craft_guide = 1}, groups = {pickaxey=1, container = 2, not_in_creative_inventory = 1, not_in_craft_guide = 1},
tiles = tiles, tiles = tiles,
use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true, use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true,
drop = "mcl_brewing:stand", drop = "mcl_brewing:stand",
@ -803,13 +871,21 @@ minetest.register_node("mcl_brewing:stand_101", {
end, end,
on_timer = brewing_stand_timer, on_timer = brewing_stand_timer,
on_rotate = on_rotate, on_rotate = on_rotate,
_mcl_hoppers_on_try_push = hoppers_on_try_push,
_mcl_hoppers_on_try_pull = hoppers_on_try_pull,
_mcl_hoppers_on_after_push = function(pos)
on_put(pos, nil, nil, nil, nil)
end,
_mcl_hoppers_on_after_pull = function(pos)
on_put(pos, nil, nil, nil, nil)
end,
}) })
minetest.register_node("mcl_brewing:stand_011", { minetest.register_node("mcl_brewing:stand_011", {
description = S("Brewing Stand"), description = S("Brewing Stand"),
_doc_items_create_entry = false, _doc_items_create_entry = false,
_tt_help = S("Brew Potions"), _tt_help = S("Brew Potions"),
groups = {pickaxey=1, not_in_creative_inventory = 1, not_in_craft_guide = 1}, groups = {pickaxey=1, container = 2, not_in_creative_inventory = 1, not_in_craft_guide = 1},
tiles = tiles, tiles = tiles,
use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true, use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true,
drop = "mcl_brewing:stand", drop = "mcl_brewing:stand",
@ -876,13 +952,21 @@ minetest.register_node("mcl_brewing:stand_011", {
end, end,
on_timer = brewing_stand_timer, on_timer = brewing_stand_timer,
on_rotate = on_rotate, on_rotate = on_rotate,
_mcl_hoppers_on_try_push = hoppers_on_try_push,
_mcl_hoppers_on_try_pull = hoppers_on_try_pull,
_mcl_hoppers_on_after_push = function(pos)
on_put(pos, nil, nil, nil, nil)
end,
_mcl_hoppers_on_after_pull = function(pos)
on_put(pos, nil, nil, nil, nil)
end,
}) })
minetest.register_node("mcl_brewing:stand_111", { minetest.register_node("mcl_brewing:stand_111", {
description = S("Brewing Stand"), description = S("Brewing Stand"),
_doc_items_create_entry = false, _doc_items_create_entry = false,
_tt_help = S("Brew Potions"), _tt_help = S("Brew Potions"),
groups = {pickaxey=1, not_in_creative_inventory = 1, not_in_craft_guide = 1}, groups = {pickaxey=1, container = 2, not_in_creative_inventory = 1, not_in_craft_guide = 1},
tiles = tiles, tiles = tiles,
use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true, use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true,
drop = "mcl_brewing:stand", drop = "mcl_brewing:stand",
@ -956,6 +1040,14 @@ minetest.register_node("mcl_brewing:stand_111", {
end, end,
on_timer = brewing_stand_timer, on_timer = brewing_stand_timer,
on_rotate = on_rotate, on_rotate = on_rotate,
_mcl_hoppers_on_try_push = hoppers_on_try_push,
_mcl_hoppers_on_try_pull = hoppers_on_try_pull,
_mcl_hoppers_on_after_push = function(pos)
on_put(pos, nil, nil, nil, nil)
end,
_mcl_hoppers_on_after_pull = function(pos)
on_put(pos, nil, nil, nil, nil)
end,
}) })
minetest.register_craft({ minetest.register_craft({

View File

@ -0,0 +1,24 @@
# textdomain: mcl_cherry_blossom
Cherry Log=Bûche de cerisier
The trunk of a cherry blossom tree.=Le tronc d'un cerisier.
Stripped Cherry Log=Bûche de cerisier écorcée
The stripped trunk of a cherry blossom tree.=Le tronc écorcé d'un cerisier.
Cherry Bark=Bois de cerisier
This is a decorative block surrounded by the bark of a tree trunk.=Ceci est un bloc décoratif entouré de bois de cerisier
Stripped Cherry Wood=Bois de cerisier écorcé
The stripped wood of a cherry blossom tree.=Le bois écorcé d'un cerisier
Cherry Wood Planks=Planches de cerisier
Cherry Leaves=Feuilles de cerisier
Cherry blossom leaves are grown from cherry blossom trees.=Les feuilles de cerisier poussent sur les cerisiers
Cherry Sapling=Pousse de cerisier
Cherry blossom sapling can be planted to grow cherry trees.=Les pousses de cerisier peuvent être plantées pour faire pousser des cerisiers.
Cherry Door=Porte en cerisier
Cherry Trapdoor=Trappe en cerisier
Cherry Stairs=Escalier en cerisier
Cherry Slab=Dalle en cerisier
Double Cherry Slab=Double Dalle en cerisier
Cherry Sign=Panneau de cerisier
Cherry Fence=Barrière en cerisier
Cherry Gate=Portillion en cerisier
Cherry Pressure Plate=Plaque de pression en cerisier
Cherry Button=Bouton de Cerisier

View File

@ -10,6 +10,8 @@ local sf = string.format
local mod_doc = minetest.get_modpath("doc") local mod_doc = minetest.get_modpath("doc")
mcl_chests = {}
-- Christmas chest setup -- Christmas chest setup
local it_is_christmas = false local it_is_christmas = false
local date = os.date("*t") local date = os.date("*t")
@ -596,7 +598,7 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile
groups = { groups = {
handy = 1, handy = 1,
axey = 1, axey = 1,
container = 5, container = 2,
not_in_creative_inventory = 1, not_in_creative_inventory = 1,
material_wood = 1, material_wood = 1,
flammable = -1, flammable = -1,
@ -751,6 +753,34 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile
end, end,
mesecons = mesecons, mesecons = mesecons,
on_rotate = no_rotate, on_rotate = no_rotate,
_mcl_hoppers_on_try_pull = function(pos, hop_pos, hop_inv, hop_list)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local stack_id = mcl_util.select_stack(inv, "main", hop_inv, hop_list)
if stack_id ~= nil then
return inv, "main", stack_id
end
local node = minetest.get_node(pos)
local pos_other = mcl_util.get_double_container_neighbor_pos(pos, node.param2, "left")
local meta_other = minetest.get_meta(pos_other)
local inv_other = meta_other:get_inventory()
stack_id = mcl_util.select_stack(inv_other, "main", hop_inv, hop_list)
return inv_other, "main", stack_id
end,
_mcl_hoppers_on_try_push = function(pos, hop_pos, hop_inv, hop_list)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local stack_id = mcl_util.select_stack(hop_inv, hop_list, inv, "main")
if stack_id ~= nil then
return inv, "main", stack_id
end
local node = minetest.get_node(pos)
local pos_other = mcl_util.get_double_container_neighbor_pos(pos, node.param2, "left")
local meta_other = minetest.get_meta(pos_other)
local inv_other = meta_other:get_inventory()
stack_id = mcl_util.select_stack(hop_inv, hop_list, inv_other, "main")
return inv_other, "main", stack_id
end,
}) })
minetest.register_node("mcl_chests:" .. basename .. "_right", { minetest.register_node("mcl_chests:" .. basename .. "_right", {
@ -766,7 +796,7 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile
groups = { groups = {
handy = 1, handy = 1,
axey = 1, axey = 1,
container = 6, container = 2,
not_in_creative_inventory = 1, not_in_creative_inventory = 1,
material_wood = 1, material_wood = 1,
flammable = -1, flammable = -1,
@ -916,6 +946,34 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile
end, end,
mesecons = mesecons, mesecons = mesecons,
on_rotate = no_rotate, on_rotate = no_rotate,
_mcl_hoppers_on_try_pull = function(pos, hop_pos, hop_inv, hop_list)
local node = minetest.get_node(pos)
local pos_other = mcl_util.get_double_container_neighbor_pos(pos, node.param2, "right")
local meta_other = minetest.get_meta(pos_other)
local inv_other = meta_other:get_inventory()
local stack_id = mcl_util.select_stack(inv_other, "main", hop_inv, hop_list)
if stack_id ~= nil then
return inv_other, "main", stack_id
end
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
stack_id = mcl_util.select_stack(inv, "main", hop_inv, hop_list)
return inv, "main", stack_id
end,
_mcl_hoppers_on_try_push = function(pos, hop_pos, hop_inv, hop_list)
local node = minetest.get_node(pos)
local pos_other = mcl_util.get_double_container_neighbor_pos(pos, node.param2, "right")
local meta_other = minetest.get_meta(pos_other)
local inv_other = meta_other:get_inventory()
local stack_id = mcl_util.select_stack(hop_inv, hop_list, inv_other, "main")
if stack_id ~= nil then
return inv_other, "main", stack_id
end
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
stack_id = mcl_util.select_stack(hop_inv, hop_list, inv, "main")
return inv, "main", stack_id
end,
}) })
if mod_doc then if mod_doc then
@ -1305,7 +1363,7 @@ for color, desc in pairs(boxtypes) do
groups = { groups = {
handy = 1, handy = 1,
pickaxey = 1, pickaxey = 1,
container = 3, container = 2,
deco_block = 1, deco_block = 1,
dig_by_piston = 1, dig_by_piston = 1,
shulker_box = 1, shulker_box = 1,
@ -1378,7 +1436,7 @@ for color, desc in pairs(boxtypes) do
groups = { groups = {
handy = 1, handy = 1,
pickaxey = 1, pickaxey = 1,
container = 3, container = 2,
deco_block = 1, deco_block = 1,
dig_by_piston = 1, dig_by_piston = 1,
shulker_box = 1, shulker_box = 1,
@ -1471,6 +1529,11 @@ for color, desc in pairs(boxtypes) do
end, end,
_mcl_blast_resistance = 6, _mcl_blast_resistance = 6,
_mcl_hardness = 2, _mcl_hardness = 2,
_mcl_hoppers_on_try_push = function(pos, hop_pos, hop_inv, hop_list)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
return inv, "main", mcl_util.select_stack(hop_inv, hop_list, inv, "main", mcl_chests.is_not_shulker_box)
end,
}) })
if mod_doc and not is_canonical then if mod_doc and not is_canonical then
@ -1487,6 +1550,14 @@ for color, desc in pairs(boxtypes) do
}) })
end end
--- Returns false if itemstack is a shulker box
---@param itemstack ItemStack
---@return boolean
function mcl_chests.is_not_shulker_box(stack)
local g = minetest.get_item_group(stack:get_name(), "shulker_box")
return g == 0 or g == nil
end
minetest.register_craft({ minetest.register_craft({
output = "mcl_chests:violet_shulker_box", output = "mcl_chests:violet_shulker_box",
recipe = { recipe = {

View File

@ -81,34 +81,44 @@ local function composter_add_item(pos, node, player, itemstack, pointed_thing)
max_hear_distance = 16, max_hear_distance = 16,
}, true) }, true)
end end
-- calculate leveling up chance composter_progress_chance(pos, node, chance)
local rand = math.random(0,100) end
if chance >= rand then return itemstack
-- get current compost level end
local level = registered_nodes[node.name]["_mcl_compost_level"]
-- spawn green particles above new layer --- Math and node swap during compost progression
mcl_dye.add_bone_meal_particle(vector_offset(pos, 0, level/8, 0)) ---@param pos Vector Position of the node
-- update composter block ---@param node node
if level < 7 then ---@param chance integer Value of "compostability" group of inserted item
level = level + 1 function composter_progress_chance(pos, node, chance)
else -- calculate leveling up chance
level = "ready" local rand = math.random(0,100)
end if chance >= rand then
swap_node(pos, {name = "mcl_composters:composter_" .. level}) -- get current compost level
minetest.sound_play({name="default_grass_footstep", gain=0.4}, { local level = registered_nodes[node.name]["_mcl_compost_level"]
pos = pos, -- spawn green particles above new layer
gain= 0.4, mcl_dye.add_bone_meal_particle(vector_offset(pos, 0, level/8, 0))
max_hear_distance = 16, -- update composter block
}, true) if level < 7 then
-- a full composter becomes ready for harvest after one second level = level + 1
-- the block will get updated by the node timer callback set in node reg def else
if level == 7 then level = "ready"
local timer = get_node_timer(pos) end
swap_node(pos, {name = "mcl_composters:composter_" .. level})
minetest.sound_play({name="default_grass_footstep", gain=0.4}, {
pos = pos,
gain= 0.4,
max_hear_distance = 16,
}, true)
-- a full composter becomes ready for harvest after one second
-- the block will get updated by the node timer callback set in node reg def
if level == 7 then
local timer = get_node_timer(pos)
if not timer:is_started() then
timer:start(1) timer:start(1)
end end
end end
end end
return itemstack
end end
--- Update a full composter block to ready for harvesting. --- Update a full composter block to ready for harvesting.
@ -147,6 +157,10 @@ local function composter_harvest(pos, node, player, itemstack, pointed_thing)
record_protection_violation(pos, name) record_protection_violation(pos, name)
return itemstack return itemstack
end end
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
--remove bone meal from internal inventory
inv:set_stack("dst", 1, ItemStack())
-- reset ready type composter to empty type -- reset ready type composter to empty type
swap_node(pos, {name="mcl_composters:composter"}) swap_node(pos, {name="mcl_composters:composter"})
-- spawn bone meal item -- spawn bone meal item
@ -175,6 +189,14 @@ local function composter_get_nodeboxes(level)
} }
end end
local function hopper_push_condition(stack)
local chance = get_item_group(stack:get_name(), "compostability")
if chance > 0 then
return true
end
return false
end
--- Register empty composter node. --- Register empty composter node.
-- --
-- This is the craftable base model that can be placed in an inventory. -- This is the craftable base model that can be placed in an inventory.
@ -197,12 +219,40 @@ minetest.register_node("mcl_composters:composter", {
groups = { groups = {
handy=1, material_wood=1, deco_block=1, dirtifier=1, handy=1, material_wood=1, deco_block=1, dirtifier=1,
flammable=2, fire_encouragement=3, fire_flammability=4, flammable=2, fire_encouragement=3, fire_flammability=4,
container = 2
}, },
sounds = mcl_sounds.node_sound_wood_defaults(), sounds = mcl_sounds.node_sound_wood_defaults(),
_mcl_hardness = 0.6, _mcl_hardness = 0.6,
_mcl_blast_resistance = 0.6, _mcl_blast_resistance = 0.6,
_mcl_compost_level = 0, _mcl_compost_level = 0,
on_rightclick = composter_add_item on_rightclick = composter_add_item,
on_construct = function(pos)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
inv:set_size("src", 1)
inv:set_size("dst", 1)
end,
_mcl_hoppers_on_try_pull = function(pos, hop_pos, hop_inv, hop_list)
return nil, nil, nil
end,
_mcl_hoppers_on_try_push = function(pos, hop_pos, hop_inv, hop_list)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
return inv, "src", mcl_util.select_stack(hop_inv, hop_list, inv, "src", hopper_push_condition)
end,
_mcl_hoppers_on_after_push = function(pos)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local stack = inv:get_stack("src", 1)
if not stack:is_empty() then
local chance = get_item_group(stack:get_name(), "compostability")
if chance > 0 then
local node = minetest.get_node(pos)
composter_progress_chance(pos, node, chance)
end
end
inv:remove_item("src", stack)
end,
}) })
--- Template function for composters with compost. --- Template function for composters with compost.
@ -228,7 +278,7 @@ local function register_filled_composter(level)
handy=1, material_wood=1, deco_block=1, dirtifier=1, handy=1, material_wood=1, deco_block=1, dirtifier=1,
not_in_creative_inventory=1, not_in_craft_guide=1, not_in_creative_inventory=1, not_in_craft_guide=1,
flammable=2, fire_encouragement=3, fire_flammability=4, flammable=2, fire_encouragement=3, fire_flammability=4,
comparator_signal=level comparator_signal=level, container = 2
}, },
sounds = mcl_sounds.node_sound_wood_defaults(), sounds = mcl_sounds.node_sound_wood_defaults(),
drop = "mcl_composters:composter", drop = "mcl_composters:composter",
@ -236,7 +286,28 @@ local function register_filled_composter(level)
_mcl_blast_resistance = 0.6, _mcl_blast_resistance = 0.6,
_mcl_compost_level = level, _mcl_compost_level = level,
on_rightclick = composter_add_item, on_rightclick = composter_add_item,
on_timer = composter_ready on_timer = composter_ready,
_mcl_hoppers_on_try_pull = function(pos, hop_pos, hop_inv, hop_list)
return nil, nil, nil
end,
_mcl_hoppers_on_try_push = function(pos, hop_pos, hop_inv, hop_list)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
return inv, "src", mcl_util.select_stack(hop_inv, hop_list, inv, "src", hopper_push_condition)
end,
_mcl_hoppers_on_after_push = function(pos)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local stack = inv:get_stack("src", 1)
if not stack:is_empty() then
local chance = get_item_group(stack:get_name(), "compostability")
if chance > 0 then
local node = minetest.get_node(pos)
composter_progress_chance(pos, node, chance)
end
end
inv:remove_item("src", stack)
end,
}) })
-- Add entry aliases for the Help -- Add entry aliases for the Help
@ -270,14 +341,32 @@ minetest.register_node("mcl_composters:composter_ready", {
handy=1, material_wood=1, deco_block=1, dirtifier=1, handy=1, material_wood=1, deco_block=1, dirtifier=1,
not_in_creative_inventory=1, not_in_craft_guide=1, not_in_creative_inventory=1, not_in_craft_guide=1,
flammable=2, fire_encouragement=3, fire_flammability=4, flammable=2, fire_encouragement=3, fire_flammability=4,
comparator_signal=8 comparator_signal=8, container = 2
}, },
sounds = mcl_sounds.node_sound_wood_defaults(), sounds = mcl_sounds.node_sound_wood_defaults(),
drop = "mcl_composters:composter", drop = "mcl_composters:composter",
_mcl_hardness = 0.6, _mcl_hardness = 0.6,
_mcl_blast_resistance = 0.6, _mcl_blast_resistance = 0.6,
_mcl_compost_level = 7, _mcl_compost_level = 7,
on_rightclick = composter_harvest on_rightclick = composter_harvest,
_mcl_hoppers_on_try_push = function(pos, hop_pos, hop_inv, hop_list)
return nil, nil, nil
end,
_mcl_hoppers_on_try_pull = function(pos, hop_pos, hop_inv, hop_list)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
--remove bone meal from internal inventory
inv:set_stack("dst", 1, ItemStack())
inv:add_item("dst", "mcl_bone_meal:bone_meal")
local stack = inv:get_stack("dst", 1)
if not stack:is_empty() and hop_inv:room_for_item(hop_list, stack) then
return inv, "dst", 1
end
return nil, nil, nil
end,
_mcl_hoppers_on_after_pull = function(pos)
minetest.swap_node(pos, {name = "mcl_composters:composter"})
end,
}) })
-- Add entry aliases for the Help -- Add entry aliases for the Help

View File

@ -1,5 +1,5 @@
name = mcl_composters name = mcl_composters
author = kabou author = kabou
description = Composters can convert various organic items into bonemeal. description = Composters can convert various organic items into bonemeal.
depends = mcl_core, mcl_sounds, mcl_dye depends = mcl_core, mcl_sounds, mcl_dye, mcl_hoppers
optional_depends = doc optional_depends = doc

View File

@ -41,7 +41,7 @@ minetest.register_craft({
}) })
minetest.register_craft({ minetest.register_craft({
output = "mcl_copper:mcl_copper:block_weathered_cut 4", output = "mcl_copper:block_weathered_cut 4",
recipe = { recipe = {
{ "mcl_copper:block_weathered", "mcl_copper:block_weathered" }, { "mcl_copper:block_weathered", "mcl_copper:block_weathered" },
{ "mcl_copper:block_weathered", "mcl_copper:block_weathered" }, { "mcl_copper:block_weathered", "mcl_copper:block_weathered" },
@ -59,6 +59,12 @@ for _, w in ipairs(waxable_blocks) do
}) })
end end
local cuttable_blocks = { "block", "waxed_block", "block_exposed", "waxed_block_exposed", "block_weathered", "waxed_block_weathered", "block_oxidized", "waxed_block_oxidized" }
for _, c in ipairs(cuttable_blocks) do
mcl_stonecutter.register_recipe("mcl_copper:"..c, "mcl_copper:"..c.."_cut", 4)
end
minetest.register_craft({ minetest.register_craft({
output = "mcl_copper:copper_ingot 9", output = "mcl_copper:copper_ingot 9",
recipe = { recipe = {

View File

@ -1,4 +1,4 @@
name = mcl_copper name = mcl_copper
author = NO11 author = NO11
depends = mcl_core, mcl_sounds, mcl_stairs, mcl_util, mcl_oxidation depends = mcl_core, mcl_sounds, mcl_stairs, mcl_util, mcl_oxidation, mcl_stonecutter
description = Adds Copper Ore, blocks and items. description = Adds Copper Ore, blocks and items.

View File

@ -1,4 +1,4 @@
name = mcl_core name = mcl_core
description = Core items of MineClone 2: Basic biome blocks (dirt, sand, stones, etc.), derived items, glass, sugar cane, cactus, barrier, mining tools, hand, craftitems, and misc. items which don't really fit anywhere else. description = Core items of MineClone 2: Basic biome blocks (dirt, sand, stones, etc.), derived items, glass, sugar cane, cactus, barrier, mining tools, hand, craftitems, and misc. items which don't really fit anywhere else.
depends = mcl_autogroup, mcl_init, mcl_sounds, mcl_particles, mcl_util, mcl_worlds, doc_items, mcl_enchanting, mcl_colors depends = mcl_autogroup, mcl_init, mcl_sounds, mcl_particles, mcl_util, mcl_worlds, doc_items, mcl_enchanting, mcl_colors, mcl_stonecutter
optional_depends = doc optional_depends = doc

View File

@ -1124,6 +1124,19 @@ minetest.register_node("mcl_core:snowblock", {
_mcl_silk_touch_drop = true, _mcl_silk_touch_drop = true,
}) })
-- Stonecutter recipes
mcl_stonecutter.register_recipe("mcl_core:stone", "mcl_core:stonebrick")
mcl_stonecutter.register_recipe("mcl_core:stone", "mcl_core:stonebrickcarved")
mcl_stonecutter.register_recipe("mcl_core:stonebrick", "mcl_core:stonebrickcarved")
mcl_stonecutter.register_recipe("mcl_core:granite", "mcl_core:granite_smooth")
mcl_stonecutter.register_recipe("mcl_core:andesite", "mcl_core:andesite_smooth")
mcl_stonecutter.register_recipe("mcl_core:diorite", "mcl_core:diorite_smooth")
mcl_stonecutter.register_recipe("mcl_core:sandstone", "mcl_core:sandstonesmooth")
mcl_stonecutter.register_recipe("mcl_core:sandstone", "mcl_core:sandstonecarved")
mcl_stonecutter.register_recipe("mcl_core:redsandstone", "mcl_core:redsandstonesmooth")
mcl_stonecutter.register_recipe("mcl_core:redsandstone", "mcl_core:redsandstonecarved")
-- Add entry aliases for the Help -- Add entry aliases for the Help
if minetest.get_modpath("doc") then if minetest.get_modpath("doc") then
doc.add_entry_alias("nodes", "mcl_core:stone_with_redstone", "nodes", "mcl_core:stone_with_redstone_lit") doc.add_entry_alias("nodes", "mcl_core:stone_with_redstone", "nodes", "mcl_core:stone_with_redstone_lit")

View File

@ -243,6 +243,10 @@ for i = 1, 3 do
output = "mcl_deepslate:deepslate_"..deepslate_variants[i+1][1].." 4", output = "mcl_deepslate:deepslate_"..deepslate_variants[i+1][1].." 4",
recipe = { { s, s }, { s, s } } recipe = { { s, s }, { s, s } }
}) })
mcl_stonecutter.register_recipe(
"mcl_deepslate:deepslate_"..deepslate_variants[i][1],
"mcl_deepslate:deepslate_"..deepslate_variants[i+1][1]
)
end end
for _, p in pairs({ "bricks", "tiles" }) do for _, p in pairs({ "bricks", "tiles" }) do
@ -275,3 +279,5 @@ minetest.register_craft({
{ "mcl_stairs:slab_deepslate_cobbled" }, { "mcl_stairs:slab_deepslate_cobbled" },
}, },
}) })
mcl_stonecutter.register_recipe("mcl_deepslate:deepslate_cobbled", "mcl_deepslate:deepslate_chiseled")

View File

@ -1,4 +1,4 @@
name = mcl_deepslate name = mcl_deepslate
author = NO11 author = NO11
depends = mcl_raw_ores, mcl_core, mcl_sounds, mcl_dye, mcl_util, screwdriver, mobs_mc, walkover, mcl_walls, mcl_stairs, mcl_brewing, mcl_mobitems, mcl_furnaces, mcl_farming, mcl_worlds depends = mcl_raw_ores, mcl_core, mcl_sounds, mcl_dye, mcl_util, screwdriver, mobs_mc, walkover, mcl_walls, mcl_stairs, mcl_brewing, mcl_mobitems, mcl_furnaces, mcl_farming, mcl_worlds, mcl_stonecutter
optional_depends = mcl_copper optional_depends = mcl_copper

View File

@ -22,3 +22,5 @@ Iron Trapdoor=Trappe en fer
Iron trapdoors are horizontal barriers which can only be opened and closed by redstone signals, but not by hand. They occupy the upper or lower part of a block, depending on how they have been placed. When open, they can be climbed like a ladder.=Les trappes en fer sont des barrières horizontales qui ne peuvent être ouvertes et fermées que par des signaux de redstone, mais pas à la main. Ils occupent la partie supérieure ou inférieure d'un bloc, selon la façon dont ils ont été placés. Lorsqu'elles sont ouvertes, elles peuvent être montées comme une échelle. Iron trapdoors are horizontal barriers which can only be opened and closed by redstone signals, but not by hand. They occupy the upper or lower part of a block, depending on how they have been placed. When open, they can be climbed like a ladder.=Les trappes en fer sont des barrières horizontales qui ne peuvent être ouvertes et fermées que par des signaux de redstone, mais pas à la main. Ils occupent la partie supérieure ou inférieure d'un bloc, selon la façon dont ils ont été placés. Lorsqu'elles sont ouvertes, elles peuvent être montées comme une échelle.
Openable by players and redstone power=Ouvrable par les joueurs et puissance redstone Openable by players and redstone power=Ouvrable par les joueurs et puissance redstone
Openable by redstone power=Ouvrable par la puissance redstone Openable by redstone power=Ouvrable par la puissance redstone
This door is a 2-block high barrier which can only be opened by redstone power, not by hand.=Cette porte est une barrière d'une hauteur de 2 blocs qui ne peut être ouverte que par la puissance redstone et pas à la main.
This door is a 2-block high barrier which can be opened or closed by hand or by redstone power.=Cette porte est une barrière d'une hauteur de 2 blocs qui peut être ouverte ou fermée à la main ou par la puissance redstone.

View File

@ -211,3 +211,5 @@ minetest.register_craft({
}, },
}) })
mcl_stonecutter.register_recipe("mcl_end:end_stone", "mcl_end:end_bricks")
mcl_stonecutter.register_recipe("mcl_end:purpur_block", "mcl_end:purpur_pillar")

View File

@ -1,2 +1,2 @@
name = mcl_end name = mcl_end
depends = screwdriver, mcl_sounds, mcl_util, doc_items, mcl_worlds, mcl_structures depends = screwdriver, mcl_sounds, mcl_util, doc_items, mcl_worlds, mcl_structures, mcl_stonecutter

View File

@ -101,7 +101,7 @@ local pumpkin_base_def = {
tiles = {"farming_pumpkin_top.png", "farming_pumpkin_top.png", "farming_pumpkin_side.png"}, tiles = {"farming_pumpkin_top.png", "farming_pumpkin_top.png", "farming_pumpkin_side.png"},
groups = { groups = {
handy = 1, axey = 1, plant = 1, building_block = 1, dig_by_piston = 1, dig_immediate_piston = 1, handy = 1, axey = 1, plant = 1, building_block = 1, dig_by_piston = 1, dig_immediate_piston = 1,
enderman_takable = 1, compostability = 65 pumpkin = 1, enderman_takable = 1, compostability = 65
}, },
sounds = mcl_sounds.node_sound_wood_defaults(), sounds = mcl_sounds.node_sound_wood_defaults(),
on_rotate = on_rotate, on_rotate = on_rotate,
@ -199,7 +199,7 @@ minetest.register_node("mcl_farming:pumpkin_face_light", {
paramtype2 = "facedir", paramtype2 = "facedir",
light_source = minetest.LIGHT_MAX, light_source = minetest.LIGHT_MAX,
tiles = {"farming_pumpkin_top.png", "farming_pumpkin_top.png", "farming_pumpkin_side.png", "farming_pumpkin_side.png", "farming_pumpkin_side.png", "farming_pumpkin_face_light.png"}, tiles = {"farming_pumpkin_top.png", "farming_pumpkin_top.png", "farming_pumpkin_side.png", "farming_pumpkin_side.png", "farming_pumpkin_side.png", "farming_pumpkin_face_light.png"},
groups = {handy=1,axey=1, building_block=1, dig_by_piston=1 }, groups = {handy=1, axey=1, pumpkin=1, building_block=1, dig_by_piston=1 },
sounds = mcl_sounds.node_sound_wood_defaults(), sounds = mcl_sounds.node_sound_wood_defaults(),
on_construct = function(pos) on_construct = function(pos)
-- Attempt to spawn iron golem or snow golem -- Attempt to spawn iron golem or snow golem

View File

@ -24,3 +24,4 @@ Flower Pot=Pot de fleurs
Flower pots are decorative blocks in which flowers and other small plants can be placed.=Les pots de fleurs sont des blocs décoratifs dans lesquels des fleurs et d'autres petites plantes peuvent être placées. Flower pots are decorative blocks in which flowers and other small plants can be placed.=Les pots de fleurs sont des blocs décoratifs dans lesquels des fleurs et d'autres petites plantes peuvent être placées.
Just place a plant on the flower pot. Flower pots can hold small flowers (not higher than 1 block), saplings, ferns, dead bushes, mushrooms and cacti. Rightclick a potted plant to retrieve the plant.=Placez simplement une plante sur le pot de fleurs. Les pots de fleurs peuvent contenir de petites fleurs (pas plus d'un bloc), des pousses, des fougères, des buissons morts, des champignons et des cactus. Cliquez avec le bouton droit sur une plante en pot pour récupérer la plante. Just place a plant on the flower pot. Flower pots can hold small flowers (not higher than 1 block), saplings, ferns, dead bushes, mushrooms and cacti. Rightclick a potted plant to retrieve the plant.=Placez simplement une plante sur le pot de fleurs. Les pots de fleurs peuvent contenir de petites fleurs (pas plus d'un bloc), des pousses, des fougères, des buissons morts, des champignons et des cactus. Cliquez avec le bouton droit sur une plante en pot pour récupérer la plante.
Can hold a small flower or plant=Peut contenir une petite fleur ou plante Can hold a small flower or plant=Peut contenir une petite fleur ou plante
Cherry Sapling Flower Pot=Pousse de Cerisier en pot

View File

@ -4,6 +4,8 @@ local F = minetest.formspec_escape
local LIGHT_ACTIVE_FURNACE = 13 local LIGHT_ACTIVE_FURNACE = 13
mcl_furnaces = {}
-- --
-- Formspecs -- Formspecs
-- --
@ -445,6 +447,31 @@ local function furnace_node_timer(pos, elapsed)
return result return result
end end
function mcl_furnaces.hoppers_on_try_pull(pos, hop_pos, hop_inv, hop_list)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local stack = inv:get_stack("dst", 1)
if not stack:is_empty() and hop_inv:room_for_item(hop_list, stack) then
return inv, "dst", 1
end
-- Allow empty bucket extraction
stack = inv:get_stack("fuel", 1)
if not stack:is_empty() and not mcl_util.is_fuel(stack) and hop_inv:room_for_item(hop_list, stack) then
return inv, "fuel", 1
end
return nil, nil, nil
end
function mcl_furnaces.hoppers_on_try_push(pos, hop_pos, hop_inv, hop_list)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
if math.abs(pos.y - hop_pos.y) > math.abs(pos.x - hop_pos.x) and math.abs(pos.y - hop_pos.y) > math.abs(pos.z - hop_pos.z) then
return inv, "src", mcl_util.select_stack(hop_inv, hop_list, inv, "src")
else
return inv, "fuel", mcl_util.select_stack(hop_inv, hop_list, inv, "fuel", mcl_util.is_fuel)
end
end
local on_rotate, after_rotate_active local on_rotate, after_rotate_active
if minetest.get_modpath("screwdriver") then if minetest.get_modpath("screwdriver") then
on_rotate = screwdriver.rotate_simple on_rotate = screwdriver.rotate_simple
@ -475,7 +502,7 @@ minetest.register_node("mcl_furnaces:furnace", {
"default_furnace_side.png", "default_furnace_front.png" "default_furnace_side.png", "default_furnace_front.png"
}, },
paramtype2 = "facedir", paramtype2 = "facedir",
groups = { pickaxey = 1, container = 4, deco_block = 1, material_stone = 1 }, groups = { pickaxey = 1, container = 2, deco_block = 1, material_stone = 1 },
is_ground_content = false, is_ground_content = false,
sounds = mcl_sounds.node_sound_stone_defaults(), sounds = mcl_sounds.node_sound_stone_defaults(),
@ -538,6 +565,11 @@ minetest.register_node("mcl_furnaces:furnace", {
_mcl_blast_resistance = 3.5, _mcl_blast_resistance = 3.5,
_mcl_hardness = 3.5, _mcl_hardness = 3.5,
on_rotate = on_rotate, on_rotate = on_rotate,
_mcl_hoppers_on_try_pull = mcl_furnaces.hoppers_on_try_pull,
_mcl_hoppers_on_try_push = mcl_furnaces.hoppers_on_try_push,
_mcl_hoppers_on_after_push = function(pos)
minetest.get_node_timer(pos):start(1.0)
end,
}) })
minetest.register_node("mcl_furnaces:furnace_active", { minetest.register_node("mcl_furnaces:furnace_active", {
@ -552,7 +584,7 @@ minetest.register_node("mcl_furnaces:furnace_active", {
paramtype = "light", paramtype = "light",
light_source = LIGHT_ACTIVE_FURNACE, light_source = LIGHT_ACTIVE_FURNACE,
drop = "mcl_furnaces:furnace", drop = "mcl_furnaces:furnace",
groups = { pickaxey = 1, container = 4, deco_block = 1, not_in_creative_inventory = 1, material_stone = 1 }, groups = { pickaxey = 1, container = 2, deco_block = 1, not_in_creative_inventory = 1, material_stone = 1 },
is_ground_content = false, is_ground_content = false,
sounds = mcl_sounds.node_sound_stone_defaults(), sounds = mcl_sounds.node_sound_stone_defaults(),
on_timer = furnace_node_timer, on_timer = furnace_node_timer,
@ -592,6 +624,8 @@ minetest.register_node("mcl_furnaces:furnace_active", {
_mcl_hardness = 3.5, _mcl_hardness = 3.5,
on_rotate = on_rotate, on_rotate = on_rotate,
after_rotate = after_rotate_active, after_rotate = after_rotate_active,
_mcl_hoppers_on_try_pull = mcl_furnaces.hoppers_on_try_pull,
_mcl_hoppers_on_try_push = mcl_furnaces.hoppers_on_try_push,
}) })
minetest.register_craft({ minetest.register_craft({

View File

@ -470,31 +470,38 @@ minetest.register_abm({
if entity and entity.name then if entity and entity.name then
--mcl_log("Name of object near: " .. tostring(entity.name)) --mcl_log("Name of object near: " .. tostring(entity.name))
if entity.name == "mcl_minecarts:hopper_minecart" or entity.name == "mcl_minecarts:chest_minecart" then if entity.name == "mcl_minecarts:hopper_minecart" or entity.name == "mcl_minecarts:chest_minecart" or entity.name == "mcl_boats:chest_boat" then
local hm_pos = entity.object:get_pos() local hm_pos = entity.object:get_pos()
mcl_log("We have a minecart with inventory close: " .. minetest.pos_to_string(hm_pos)) mcl_log("We have a minecart with inventory close: " .. minetest.pos_to_string(hm_pos))
--if hm_pos.y == pos.y + 1 then mcl_log("y is correct") end local ent_pos_y
if entity.name == "mcl_minecarts:hopper_minecart" or entity.name == "mcl_minecarts:chest_minecart" then
ent_pos_y = hm_pos.y
elseif entity.name == "mcl_boats:chest_boat" then
ent_pos_y = math.floor(hm_pos.y + 0.8)
end
local DIST_FROM_MC = 1.5
--if ent_pos_y == pos.y - 1 then mcl_log("y is correct") end
--if (hm_pos.x >= pos.x - DIST_FROM_MC and hm_pos.x <= pos.x + DIST_FROM_MC) then mcl_log("x is within range") end --if (hm_pos.x >= pos.x - DIST_FROM_MC and hm_pos.x <= pos.x + DIST_FROM_MC) then mcl_log("x is within range") end
--if (hm_pos.z >= pos.z - DIST_FROM_MC and hm_pos.z <= pos.z + DIST_FROM_MC) then mcl_log("z is within range") end --if (hm_pos.z >= pos.z - DIST_FROM_MC and hm_pos.z <= pos.z + DIST_FROM_MC) then mcl_log("z is within range") end
local DIST_FROM_MC = 1.5 if (ent_pos_y == pos.y + 1)
if (hm_pos.y == pos.y + 1)
and (hm_pos.x >= pos.x - DIST_FROM_MC and hm_pos.x <= pos.x + DIST_FROM_MC) and (hm_pos.x >= pos.x - DIST_FROM_MC and hm_pos.x <= pos.x + DIST_FROM_MC)
and (hm_pos.z >= pos.z - DIST_FROM_MC and hm_pos.z <= pos.z + DIST_FROM_MC) then and (hm_pos.z >= pos.z - DIST_FROM_MC and hm_pos.z <= pos.z + DIST_FROM_MC) then
mcl_log("Minecart close enough") mcl_log("Minecart close enough")
if entity.name == "mcl_minecarts:hopper_minecart" then if entity.name == "mcl_minecarts:hopper_minecart" then
hopper_pull_from_mc(entity, pos, 5) hopper_pull_from_mc(entity, pos, 5)
elseif entity.name == "mcl_minecarts:chest_minecart" then elseif entity.name == "mcl_minecarts:chest_minecart" or entity.name == "mcl_boats:chest_boat" then
hopper_pull_from_mc(entity, pos, 27) hopper_pull_from_mc(entity, pos, 27)
end end
elseif (hm_pos.y == pos.y - 1) elseif (ent_pos_y == pos.y - 1)
and (hm_pos.x >= pos.x - DIST_FROM_MC and hm_pos.x <= pos.x + DIST_FROM_MC) and (hm_pos.x >= pos.x - DIST_FROM_MC and hm_pos.x <= pos.x + DIST_FROM_MC)
and (hm_pos.z >= pos.z - DIST_FROM_MC and hm_pos.z <= pos.z + DIST_FROM_MC) then and (hm_pos.z >= pos.z - DIST_FROM_MC and hm_pos.z <= pos.z + DIST_FROM_MC) then
mcl_log("Minecart close enough") mcl_log("Minecart close enough")
if entity.name == "mcl_minecarts:hopper_minecart" then if entity.name == "mcl_minecarts:hopper_minecart" then
hopper_push_to_mc(entity, pos, 5) hopper_push_to_mc(entity, pos, 5)
elseif entity.name == "mcl_minecarts:chest_minecart" then elseif entity.name == "mcl_minecarts:chest_minecart" or entity.name == "mcl_boats:chest_boat" then
hopper_push_to_mc(entity, pos, 27) hopper_push_to_mc(entity, pos, 27)
end end
end end
@ -545,25 +552,7 @@ minetest.register_abm({
end, end,
}) })
---Returns true if itemstack is fuel, but not for lava bucket if destination already has one -- Register push/pull for "straight" hopper
---@param itemstack ItemStack
---@param src_inventory InvRef
---@param src_list string
---@param dst_inventory InvRef
---@param dst_list string
---@return boolean
local function is_transferrable_fuel(itemstack, src_inventory, src_list, dst_inventory, dst_list)
if mcl_util.is_fuel(itemstack) then
if itemstack:get_name() == "mcl_buckets:bucket_lava" then
return dst_inventory:is_empty(dst_list)
else
return true
end
else
return false
end
end
minetest.register_abm({ minetest.register_abm({
label = "Hopper/container item exchange", label = "Hopper/container item exchange",
nodenames = { "mcl_hoppers:hopper" }, nodenames = { "mcl_hoppers:hopper" },
@ -571,31 +560,26 @@ minetest.register_abm({
interval = 1.0, interval = 1.0,
chance = 1, chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider) action = function(pos, node, active_object_count, active_object_count_wider)
-- Get node pos' for item transfer if minetest.get_node_timer(pos):is_started() then
local uppos = vector.offset(pos, 0, 1, 0) return
local downpos = vector.offset(pos, 0, -1, 0)
-- Suck an item from the container above into the hopper
local upnode = minetest.get_node(uppos)
if not minetest.registered_nodes[upnode.name] then return end
local g = minetest.get_item_group(upnode.name, "container")
local sucked = mcl_util.move_item_container(uppos, pos)
-- Also suck in non-fuel items from furnace fuel slot
if not sucked and g == 4 then
local finv = minetest.get_inventory({type = "node", pos = uppos})
if finv and not mcl_util.is_fuel(finv:get_stack("fuel", 1)) then
mcl_util.move_item_container(uppos, pos, "fuel")
end
end end
-- Move an item from the hopper into container below -- Move from internal inventory to dst first
local downnode = minetest.get_node(downpos) local dst_pos = vector.offset(pos, 0, -1, 0)
if not minetest.registered_nodes[downnode.name] then return end local pushed = mcl_util.hopper_push(pos, dst_pos)
mcl_util.move_item_container(pos, downpos)
local src_pos = vector.offset(pos, 0, 1, 0)
mcl_util.hopper_pull(pos, src_pos)
local dst_node = minetest.get_node(dst_pos)
if pushed and (dst_node.name == "mcl_hoppers:hopper" or dst_node.name == "mcl_hoppers:hopper_side") then
--Pause destination hopper
minetest.get_node_timer(dst_pos):start(1.0)
end
end, end,
}) })
-- Register push/pull for "bent" hopper
minetest.register_abm({ minetest.register_abm({
label = "Side-hopper/container item exchange", label = "Side-hopper/container item exchange",
nodenames = { "mcl_hoppers:hopper_side" }, nodenames = { "mcl_hoppers:hopper_side" },
@ -603,164 +587,36 @@ minetest.register_abm({
interval = 1.0, interval = 1.0,
chance = 1, chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider) action = function(pos, node, active_object_count, active_object_count_wider)
if minetest.get_node_timer(pos):is_started() then
--Pause if already recived item this tick
return
end
-- Determine to which side the hopper is facing, get nodes -- Determine to which side the hopper is facing, get nodes
local face = minetest.get_node(pos).param2 local face = minetest.get_node(pos).param2
local front = {} local dst_pos = {}
if face == 0 then if face == 0 then
front = vector.offset(pos, -1, 0, 0) dst_pos = vector.offset(pos, -1, 0, 0)
elseif face == 1 then elseif face == 1 then
front = vector.offset(pos, 0, 0, 1) dst_pos = vector.offset(pos, 0, 0, 1)
elseif face == 2 then elseif face == 2 then
front = vector.offset(pos, 1, 0, 0) dst_pos = vector.offset(pos, 1, 0, 0)
elseif face == 3 then elseif face == 3 then
front = vector.offset(pos, 0, 0, -1) dst_pos = vector.offset(pos, 0, 0, -1)
end end
local above = vector.offset(pos, 0, 1, 0) local pushed = mcl_util.hopper_push(pos, dst_pos)
local frontnode = minetest.get_node(front) local src_pos = vector.offset(pos, 0, 1, 0)
if not minetest.registered_nodes[frontnode.name] then return end mcl_util.hopper_pull(pos, src_pos)
-- Suck an item from the container above into the hopper local dst_node = minetest.get_node(dst_pos)
local abovenode = minetest.get_node(above) if pushed and (dst_node.name == "mcl_hoppers:hopper" or dst_node.name == "mcl_hoppers:hopper_side") then
if not minetest.registered_nodes[abovenode.name] then return end --Pause destination hopper
local g = minetest.get_item_group(abovenode.name, "container") minetest.get_node_timer(dst_pos):start(1.0)
local sucked = mcl_util.move_item_container(above, pos)
-- Also suck in non-fuel items from furnace fuel slot
if not sucked and g == 4 then
local finv = minetest.get_inventory({type = "node", pos = above})
if finv and not mcl_util.is_fuel(finv:get_stack("fuel", 1)) then
mcl_util.move_item_container(above, pos, "fuel")
end
end end
end,
-- Move an item from the hopper into the container to which the hopper points to
local g = minetest.get_item_group(frontnode.name, "container")
if g == 2 or g == 3 or g == 5 or g == 6 then
mcl_util.move_item_container(pos, front)
elseif g == 4 then
-- Put fuel into fuel slot
local sinv = minetest.get_inventory({type = "node", pos = pos})
local dinv = minetest.get_inventory({type = "node", pos = front})
local slot_id, _ = mcl_util.get_eligible_transfer_item_slot(sinv, "main", dinv, "fuel", is_transferrable_fuel)
if slot_id then
mcl_util.move_item_container(pos, front, nil, slot_id, "fuel")
end
end
end
}) })
if minetest.get_modpath("mcl_composters") then
minetest.register_abm({
label = "Bonemeal extraction from composter",
nodenames = {"mcl_hoppers:hopper", "mcl_hoppers:hopper_side"},
neighbors = {"mcl_composters:composter_ready"},
interval = 1.0,
chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider)
local uppos = vector.offset(pos, 0, 1, 0)
--local downpos = vector.offset(pos, 0, -1, 0)
-- Get bonemeal from composter above
local upnode = minetest.get_node(uppos)
if upnode.name == "mcl_composters:composter_ready" then
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
minetest.swap_node(uppos, {name = "mcl_composters:composter"})
inv:add_item("main", "mcl_bone_meal:bone_meal")
end
end,
})
---@param node node
---@return integer?
---@nodiscard
local function composter_level(node)
local nn = node.name
if nn == "mcl_composters:composter" then
return 0
elseif nn == "mcl_composters:composter_1" then
return 1
elseif nn == "mcl_composters:composter_2" then
return 2
elseif nn == "mcl_composters:composter_3" then
return 3
elseif nn == "mcl_composters:composter_4" then
return 4
elseif nn == "mcl_composters:composter_5" then
return 5
elseif nn == "mcl_composters:composter_6" then
return 6
elseif nn == "mcl_composters:composter_7" then
return 7
else
return nil
end
end
for i = 1, 7 do
assert(composter_level({name = "mcl_composters:composter_" .. i}) == i)
end
assert(composter_level({name = "mcl_composters:composter"}) == 0)
assert(composter_level({name = "mcl_composters:some_other_node"}) == nil)
minetest.register_abm({
label = "Add compostable items on composter",
nodenames = {"mcl_hoppers:hopper"},
neighbors = {
"mcl_composters:composter",
"mcl_composters:composter_1",
"mcl_composters:composter_2",
"mcl_composters:composter_3",
"mcl_composters:composter_4",
"mcl_composters:composter_5",
"mcl_composters:composter_6",
"mcl_composters:composter_7",
},
interval = 1.0,
chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider)
--local uppos = vector.offset(pos, 0, 1, 0)
local downpos = vector.offset(pos, 0, -1, 0)
local downnode = minetest.get_node(downpos)
---@type integer|string|nil
local level = composter_level(downnode)
--Consume compostable items and update composter below
if level then
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
for i = 1, 5 do
local stack = inv:get_stack("main", i)
local compchance = minetest.get_item_group(stack:get_name(), "compostability")
if compchance > 0 then
stack:take_item()
inv:set_stack("main", i, stack)
if compchance >= math.random(0, 100) then
mcl_dye.add_bone_meal_particle(vector.offset(downpos, 0, level / 8, 0))
if level < 7 then
level = level + 1
else
level = "ready"
end
minetest.swap_node(downpos, {name = "mcl_composters:composter_" .. level})
end
break
end
end
end
end,
})
end
minetest.register_craft({ minetest.register_craft({
output = "mcl_hoppers:hopper", output = "mcl_hoppers:hopper",
recipe = { recipe = {

View File

@ -638,7 +638,7 @@ function mcl_itemframes.create_base_definitions()
paramtype = "light", paramtype = "light",
paramtype2 = "facedir", paramtype2 = "facedir",
sunlight_propagates = true, sunlight_propagates = true,
groups = { dig_immediate = 3, deco_block = 1, dig_by_piston = 1, container = 7, }, -- attached_node_facedir = 1 }, -- allows for more placement options. groups = { dig_immediate = 3, deco_block = 1, dig_by_piston = 1, container = 1, }, -- attached_node_facedir = 1 }, -- allows for more placement options.
sounds = mcl_sounds.node_sound_defaults(), sounds = mcl_sounds.node_sound_defaults(),
node_placement_prediction = "", node_placement_prediction = "",

View File

@ -121,7 +121,7 @@ minetest.register_node("mcl_jukebox:jukebox", {
_doc_items_usagehelp = S("Place a music disc into an empty jukebox to insert the music disc and play music. If the jukebox already has a music disc, you will retrieve this music disc first. The music can only be heard by you, not by other players."), _doc_items_usagehelp = S("Place a music disc into an empty jukebox to insert the music disc and play music. If the jukebox already has a music disc, you will retrieve this music disc first. The music can only be heard by you, not by other players."),
tiles = {"mcl_jukebox_top.png", "mcl_jukebox_side.png", "mcl_jukebox_side.png"}, tiles = {"mcl_jukebox_top.png", "mcl_jukebox_side.png", "mcl_jukebox_side.png"},
sounds = mcl_sounds.node_sound_wood_defaults(), sounds = mcl_sounds.node_sound_wood_defaults(),
groups = {handy=1,axey=1, container=7, deco_block=1, material_wood=1, flammable=-1}, groups = {handy=1,axey=1, container=1, deco_block=1, material_wood=1, flammable=-1},
is_ground_content = false, is_ground_content = false,
on_construct = function(pos) on_construct = function(pos)
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)

View File

@ -62,4 +62,4 @@ minetest.register_craft({
{"mcl_mud:packed_mud", "mcl_mud:packed_mud"}, {"mcl_mud:packed_mud", "mcl_mud:packed_mud"},
{"mcl_mud:packed_mud", "mcl_mud:packed_mud"} {"mcl_mud:packed_mud", "mcl_mud:packed_mud"}
} }
}) })

View File

@ -415,5 +415,9 @@ minetest.register_craft({
} }
}) })
-- TODO register stonecutter recipe for chiseled nether brick when it is added
mcl_stonecutter.register_recipe("mcl_nether:quartz_block", "mcl_nether:quartz_chiseled")
mcl_stonecutter.register_recipe("mcl_nether:quartz_block", "mcl_nether:quartz_pillar")
dofile(minetest.get_modpath(minetest.get_current_modname()).."/nether_wart.lua") dofile(minetest.get_modpath(minetest.get_current_modname()).."/nether_wart.lua")
dofile(minetest.get_modpath(minetest.get_current_modname()).."/lava.lua") dofile(minetest.get_modpath(minetest.get_current_modname()).."/lava.lua")

View File

@ -1,3 +1,3 @@
name = mcl_nether name = mcl_nether
depends = mcl_core, mcl_sounds, mcl_util, walkover, doc_items, mcl_colors depends = mcl_core, mcl_sounds, mcl_util, walkover, doc_items, mcl_colors, mcl_stonecutter
optional_depends = doc, screwdriver optional_depends = doc, screwdriver

View File

@ -6,14 +6,14 @@ Hop into the portal to teleport. Entering an End portal in the Overworld telepor
End Portal Frame=Cadre de portail de l'End End Portal Frame=Cadre de portail de l'End
End portal frames are used in the construction of End portals. Each block has a socket for an eye of ender.=Les portails de l'End sont utilisés dans la construction de portails de l'End. Chaque bloc a une prise pour un œil d'Ender. End portal frames are used in the construction of End portals. Each block has a socket for an eye of ender.=Les portails de l'End sont utilisés dans la construction de portails de l'End. Chaque bloc a une prise pour un œil d'Ender.
NOTE: The End dimension is currently incomplete and might change in future versions.=REMARQUE : la dimension de l'End est actuellement incomplète et pourrait changer dans les futures versions. NOTE: The End dimension is currently incomplete and might change in future versions.=REMARQUE : la dimension de l'End est actuellement incomplète et pourrait changer dans les futures versions.
To create an End portal, you need 12 end portal frames and 12 eyes of ender. The end portal frames have to be arranged around a horizontal 3×3 area with each block facing inward. Any other arrangement will fail.= To create an End portal, you need 12 end portal frames and 12 eyes of ender. The end portal frames have to be arranged around a horizontal 3×3 area with each block facing inward. Any other arrangement will fail.=Pour créer un portail de l'End, vous avez besoin de 12 cadres de portail de l'End et 12 œil d'Ender. Les cadres de portail doivent être placé sur une surface horizontal 3*3 avec chaque bloc tourné vers l'intérieur. Tout autre disposition échouera.
Place an eye of ender into each block. The end portal appears in the middle after placing the final eye.= Place an eye of ender into each block. The end portal appears in the middle after placing the final eye.=Placer un œil d'Ender dans chaque bloc. Le portail apparaît au milieu après avoir placé l'œil final.
Once placed, an eye of ender can not be taken back.=Une fois placé, un œil d'Ender ne peut pas être repris. Once placed, an eye of ender can not be taken back.=Une fois placé, un œil d'Ender ne peut pas être repris.
End Portal Frame with Eye of Ender=Cadre de portail de l'End avec œil d'Ender End Portal Frame with Eye of Ender=Cadre de portail de l'End avec œil d'Ender
End Gateway Portal= End Gateway Portal=Portail de Passage de l'End
Used to construct end gateway portals= Used to construct end gateway portals=Utilisé pour construire des portails de passage de l'End.
An End gateway portal teleports creatures and objects to the outer End (and back!).= An End gateway portal teleports creatures and objects to the outer End (and back!).=Un portail de passage de l'End téléporte des créatures et objets vers la bordure de l'End (et les ramène !).
Throw an ender pearl into the portal to teleport. Entering an Gateway portal near the Overworld teleports you to the outer End. At this destination another gateway portal will be constructed, which you can use to get back.= Throw an ender pearl into the portal to teleport. Entering an Gateway portal near the Overworld teleports you to the outer End. At this destination another gateway portal will be constructed, which you can use to get back.=Jetez une perle d'Ender dans le portail pour vous téléporter. Entrer dans un portail de passage de l'End près de l'Overworld vous téléporte vers la bordure de l'End. À cette destination un autre portail de passage sera généré, qui pourra être utilisé pour revenir.
Nether Portal=Portail du Nether Nether Portal=Portail du Nether
A Nether portal teleports creatures and objects to the hot and dangerous Nether dimension (and back!). Enter at your own risk!=Un portail du Nether téléporte des créatures et des objets dans la chaude et dangereuse dimension du Nether (et vice-versa !). Entrez à vos risques et périls ! A Nether portal teleports creatures and objects to the hot and dangerous Nether dimension (and back!). Enter at your own risk!=Un portail du Nether téléporte des créatures et des objets dans la chaude et dangereuse dimension du Nether (et vice-versa !). Entrez à vos risques et périls !
Stand in the portal for a moment to activate the teleportation. Entering a Nether portal for the first time will also create a new portal in the other dimension. If a Nether portal has been built in the Nether, it will lead to the Overworld. A Nether portal is destroyed if the any of the obsidian which surrounds it is destroyed, or if it was caught in an explosion.=Tenez-vous un instant dans le portail pour activer la téléportation. Entrer pour la première fois sur un portail Nether créera également un nouveau portail dans l'Overworld. Si un portail du Nether a été construit dans le Nether, il mènera à l'Overworld. Un portail du Nether est détruit si l'une des obsidiennes qui l'entourent est détruite, ou s'il a été pris dans une explosion. Stand in the portal for a moment to activate the teleportation. Entering a Nether portal for the first time will also create a new portal in the other dimension. If a Nether portal has been built in the Nether, it will lead to the Overworld. A Nether portal is destroyed if the any of the obsidian which surrounds it is destroyed, or if it was caught in an explosion.=Tenez-vous un instant dans le portail pour activer la téléportation. Entrer pour la première fois sur un portail Nether créera également un nouveau portail dans l'Overworld. Si un portail du Nether a été construit dans le Nether, il mènera à l'Overworld. Un portail du Nether est détruit si l'une des obsidiennes qui l'entourent est détruite, ou s'il a été pris dans une explosion.

View File

@ -256,7 +256,7 @@ minetest.register_craftitem("mcl_potions:water", {
stack_max = 1, stack_max = 1,
inventory_image = potion_image("#0022FF"), inventory_image = potion_image("#0022FF"),
wield_image = potion_image("#0022FF"), wield_image = potion_image("#0022FF"),
groups = {brewitem=1, food=3, can_eat_when_full=1, water_bottle=1}, groups = {brewitem=1, food=3, can_eat_when_full=1, water_bottle=1, bottle=1},
on_place = water_bottle_on_place, on_place = water_bottle_on_place,
_on_dispense = dispense_water_bottle, _on_dispense = dispense_water_bottle,
_dispense_into_walkable = true, _dispense_into_walkable = true,
@ -273,7 +273,7 @@ minetest.register_craftitem("mcl_potions:river_water", {
stack_max = 1, stack_max = 1,
inventory_image = potion_image("#0044FF"), inventory_image = potion_image("#0044FF"),
wield_image = potion_image("#0044FF"), wield_image = potion_image("#0044FF"),
groups = {brewitem=1, food=3, can_eat_when_full=1, water_bottle=1}, groups = {brewitem=1, food=3, can_eat_when_full=1, water_bottle=1, bottle=1},
on_place = water_bottle_on_place, on_place = water_bottle_on_place,
_on_dispense = dispense_water_bottle, _on_dispense = dispense_water_bottle,
_dispense_into_walkable = true, _dispense_into_walkable = true,

View File

@ -102,7 +102,7 @@ function mcl_potions.register_lingering(name, descr, color, def)
_doc_items_longdesc = longdesc, _doc_items_longdesc = longdesc,
_doc_items_usagehelp = S("Use the “Punch” key to throw it."), _doc_items_usagehelp = S("Use the “Punch” key to throw it."),
inventory_image = lingering_image(color), inventory_image = lingering_image(color),
groups = {brewitem=1, not_in_creative_inventory=0}, groups = {brewitem=1, not_in_creative_inventory=0, bottle=1},
on_use = function(item, placer, pointed_thing) on_use = function(item, placer, pointed_thing)
local velocity = 10 local velocity = 10
local dir = placer:get_look_dir(); local dir = placer:get_look_dir();

View File

@ -163,7 +163,7 @@ local function register_potion(def)
stack_max = def.stack_max or 1, stack_max = def.stack_max or 1,
inventory_image = def.image or potion_image(def.color), inventory_image = def.image or potion_image(def.color),
wield_image = def.image or potion_image(def.color), wield_image = def.image or potion_image(def.color),
groups = def.groups or {brewitem=1, food=3, can_eat_when_full=1 }, groups = def.groups or {brewitem=1, food=3, can_eat_when_full=1, bottle=1},
on_place = on_use, on_place = on_use,
on_secondary_use = on_use, on_secondary_use = on_use,
}) })
@ -260,7 +260,7 @@ local function register_potion(def)
stack_max = def.stack_max or 1, stack_max = def.stack_max or 1,
inventory_image = def.image or potion_image(def.color), inventory_image = def.image or potion_image(def.color),
wield_image = def.image or potion_image(def.color), wield_image = def.image or potion_image(def.color),
groups = def.groups or {brewitem=1, food=3, can_eat_when_full=1}, groups = def.groups or {brewitem=1, food=3, can_eat_when_full=1, bottle=1},
on_place = on_use, on_place = on_use,
on_secondary_use = on_use, on_secondary_use = on_use,
}) })
@ -343,7 +343,7 @@ local function register_potion(def)
stack_max = 1, stack_max = 1,
inventory_image = def.image or potion_image(def.color), inventory_image = def.image or potion_image(def.color),
wield_image = def.image or potion_image(def.color), wield_image = def.image or potion_image(def.color),
groups = def.groups or {brewitem=1, food=3, can_eat_when_full=1}, groups = def.groups or {brewitem=1, food=3, can_eat_when_full=1, bottle=1},
on_place = on_use, on_place = on_use,
on_secondary_use = on_use, on_secondary_use = on_use,
}) })
@ -411,7 +411,7 @@ local awkward_def = {
_tt = S("No effect"), _tt = S("No effect"),
_longdesc = S("Has an awkward taste and is used for brewing potions."), _longdesc = S("Has an awkward taste and is used for brewing potions."),
color = "#0000FF", color = "#0000FF",
groups = {brewitem=1, food=3, can_eat_when_full=1}, groups = {brewitem=1, food=3, can_eat_when_full=1, bottle=1},
on_use = minetest.item_eat(0, "mcl_potions:glass_bottle"), on_use = minetest.item_eat(0, "mcl_potions:glass_bottle"),
} }
@ -450,7 +450,7 @@ local dragon_breath_def = {
no_effect = true, no_effect = true,
_longdesc = S("This item is used in brewing and can be combined with splash potions to create lingering potions."), _longdesc = S("This item is used in brewing and can be combined with splash potions to create lingering potions."),
image = "mcl_potions_dragon_breath.png", image = "mcl_potions_dragon_breath.png",
groups = { brewitem = 1 }, groups = { brewitem = 1, bottle = 1 },
on_use = nil, on_use = nil,
stack_max = 64, stack_max = 64,
} }

View File

@ -26,7 +26,7 @@ function mcl_potions.register_splash(name, descr, color, def)
_doc_items_longdesc = longdesc, _doc_items_longdesc = longdesc,
_doc_items_usagehelp = S("Use the “Punch” key to throw it."), _doc_items_usagehelp = S("Use the “Punch” key to throw it."),
inventory_image = splash_image(color), inventory_image = splash_image(color),
groups = {brewitem=1, not_in_creative_inventory=0}, groups = {brewitem=1, not_in_creative_inventory=0, bottle=1},
on_use = function(item, placer, pointed_thing) on_use = function(item, placer, pointed_thing)
local velocity = 10 local velocity = 10
local dir = placer:get_look_dir(); local dir = placer:get_look_dir();

View File

@ -453,7 +453,7 @@ minetest.register_node("mcl_smoker:smoker", {
"smoker_side.png", "smoker_front.png" "smoker_side.png", "smoker_front.png"
}, },
paramtype2 = "facedir", paramtype2 = "facedir",
groups = { pickaxey = 1, container = 4, deco_block = 1, material_stone = 1 }, groups = { pickaxey = 1, container = 2, deco_block = 1, material_stone = 1 },
is_ground_content = false, is_ground_content = false,
sounds = mcl_sounds.node_sound_stone_defaults(), sounds = mcl_sounds.node_sound_stone_defaults(),
@ -519,6 +519,11 @@ minetest.register_node("mcl_smoker:smoker", {
_mcl_blast_resistance = 3.5, _mcl_blast_resistance = 3.5,
_mcl_hardness = 3.5, _mcl_hardness = 3.5,
on_rotate = on_rotate, on_rotate = on_rotate,
_mcl_hoppers_on_try_pull = mcl_furnaces.hoppers_on_try_pull,
_mcl_hoppers_on_try_push = mcl_furnaces.hoppers_on_try_push,
_mcl_hoppers_on_after_push = function(pos)
minetest.get_node_timer(pos):start(1.0)
end,
}) })
minetest.register_node("mcl_smoker:smoker_active", { minetest.register_node("mcl_smoker:smoker_active", {
@ -536,7 +541,7 @@ minetest.register_node("mcl_smoker:smoker_active", {
paramtype = "light", paramtype = "light",
light_source = LIGHT_ACTIVE_FURNACE, light_source = LIGHT_ACTIVE_FURNACE,
drop = "mcl_smoker:smoker", drop = "mcl_smoker:smoker",
groups = { pickaxey = 1, container = 4, deco_block = 1, not_in_creative_inventory = 1, material_stone = 1 }, groups = { pickaxey = 1, container = 2, deco_block = 1, not_in_creative_inventory = 1, material_stone = 1 },
is_ground_content = false, is_ground_content = false,
sounds = mcl_sounds.node_sound_stone_defaults(), sounds = mcl_sounds.node_sound_stone_defaults(),
on_timer = smoker_node_timer, on_timer = smoker_node_timer,
@ -579,6 +584,8 @@ minetest.register_node("mcl_smoker:smoker_active", {
_mcl_hardness = 3.5, _mcl_hardness = 3.5,
on_rotate = on_rotate, on_rotate = on_rotate,
after_rotate = after_rotate_active, after_rotate = after_rotate_active,
_mcl_hoppers_on_try_pull = mcl_furnaces.hoppers_on_try_pull,
_mcl_hoppers_on_try_push = mcl_furnaces.hoppers_on_try_push,
}) })
minetest.register_craft({ minetest.register_craft({

View File

@ -173,6 +173,9 @@ function mcl_stairs.register_stair(subname, recipeitem, groups, images, descript
{recipeitem, recipeitem, recipeitem}, {recipeitem, recipeitem, recipeitem},
}, },
}) })
-- Stonecutter recipe
mcl_stonecutter.register_recipe(recipeitem, "mcl_stairs:stair_".. subname)
end end
mcl_stairs.cornerstair.add("mcl_stairs:stair_"..subname, corner_stair_texture_override) mcl_stairs.cornerstair.add("mcl_stairs:stair_"..subname, corner_stair_texture_override)
@ -343,6 +346,8 @@ function mcl_stairs.register_slab(subname, recipeitem, groups, images, descripti
}, },
}) })
mcl_stonecutter.register_recipe(recipeitem, lower_slab, 2)
end end
-- Help alias for the upper slab -- Help alias for the upper slab

View File

@ -1,2 +1,2 @@
name = mcl_stairs name = mcl_stairs
depends = mcl_core, mcl_sounds, mcl_nether, mcl_end, mcl_ocean, mcl_mud depends = mcl_core, mcl_sounds, mcl_nether, mcl_end, mcl_ocean, mcl_mud, mcl_stonecutter

View File

@ -30,7 +30,18 @@ for w=1, #woods do
wood[5]) wood[5])
end end
mcl_stairs.register_stair_and_slab_simple("stone_rough", "mcl_core:stone", S("Stone Stairs"), S("Stone Slab"), S("Double Stone Slab"))
mcl_stairs.register_slab("stone_rough", "mcl_core:stone",
{pickaxey=1, material_stone=1},
{"default_stone.png"},
S("Stone Slab"),
mcl_sounds.node_sound_stone_defaults(), 6, 2,
S("Double Stone Slab"))
mcl_stairs.register_stair("stone_rough", "mcl_core:stone",
{pickaxey=1, material_stone=1},
{"default_stone.png"},
S("Stone Stairs"),
mcl_sounds.node_sound_stone_defaults(), 0.8, 0.8)
mcl_stairs.register_slab("stone", "mcl_core:stone_smooth", mcl_stairs.register_slab("stone", "mcl_core:stone_smooth",
{pickaxey=1, material_stone=1}, {pickaxey=1, material_stone=1},
@ -39,43 +50,127 @@ mcl_stairs.register_slab("stone", "mcl_core:stone_smooth",
mcl_sounds.node_sound_stone_defaults(), 6, 2, mcl_sounds.node_sound_stone_defaults(), 6, 2,
S("Double Polished Stone Slab")) S("Double Polished Stone Slab"))
mcl_stairs.register_stair_and_slab_simple("andesite", "mcl_core:andesite", S("Andesite Stairs"), S("Andesite Slab"), S("Double Andesite Slab")) mcl_stairs.register_stair("andesite", "mcl_core:andesite",
mcl_stairs.register_stair_and_slab_simple("granite", "mcl_core:granite", S("Granite Stairs"), S("Granite Slab"), S("Double Granite Slab")) {pickaxey=1, material_stone=1},
mcl_stairs.register_stair_and_slab_simple("diorite", "mcl_core:diorite", S("Diorite Stairs"), S("Diorite Slab"), S("Double Diorite Slab")) {"mcl_core_andesite.png"},
S("Andesite Stairs"),
mcl_sounds.node_sound_stone_defaults(), 0.8, 0.8)
mcl_stairs.register_slab("andesite", "mcl_core:andesite",
{pickaxey=1, material_stone=1},
{"mcl_core_andesite.png"},
S("Andesite Slab"),
mcl_sounds.node_sound_stone_defaults(), 6, 2,
S("Double Andesite Slab"))
mcl_stairs.register_stair_and_slab_simple("cobble", "mcl_core:cobble", S("Cobblestone Stairs"), S("Cobblestone Slab"), S("Double Cobblestone Slab")) mcl_stairs.register_stair("granite", "mcl_core:granite",
mcl_stairs.register_stair_and_slab_simple("mossycobble", "mcl_core:mossycobble", S("Mossy Cobblestone Stairs"), S("Mossy Cobblestone Slab"), S("Double Mossy Cobblestone Slab")) {pickaxey=1, material_stone=1},
{"mcl_core_granite.png"},
S("Granite Stairs"),
mcl_sounds.node_sound_stone_defaults(), 0.8, 0.8)
mcl_stairs.register_slab("granite", "mcl_core:granite",
{pickaxey=1, material_stone=1},
{"mcl_core_granite.png"},
S("Granite Slab"),
mcl_sounds.node_sound_stone_defaults(), 6, 2,
S("Double Granite Slab"))
mcl_stairs.register_stair_and_slab_simple("brick_block", "mcl_core:brick_block", S("Brick Stairs"), S("Brick Slab"), S("Double Brick Slab")) mcl_stairs.register_stair("diorite", "mcl_core:diorite",
{pickaxey=1, material_stone=1},
{"mcl_core_diorite.png"},
S("Granite Stairs"),
mcl_sounds.node_sound_stone_defaults(), 0.8, 0.8)
mcl_stairs.register_slab("diorite", "mcl_core:diorite",
{pickaxey=1, material_stone=1},
{"mcl_core_diorite.png"},
S("Diorite Slab"),
mcl_sounds.node_sound_stone_defaults(), 6, 2,
S("Double Diorite Slab"))
mcl_stairs.register_stair("cobble", "mcl_core:cobble",
{pickaxey=1, material_stone=1},
{"default_cobble.png"},
S("Cobblestone Stairs"),
mcl_sounds.node_sound_stone_defaults(), 0.8, 0.8)
mcl_stairs.register_slab("cobble", "mcl_core:cobble",
{pickaxey=1, material_stone=1},
{"default_cobble.png"},
S("Cobblestone Slab"),
mcl_sounds.node_sound_stone_defaults(), 6, 2,
S("Double Cobblestone Slab"))
mcl_stairs.register_stair("sandstone", "group:normal_sandstone", mcl_stairs.register_stair("mossycobble", "mcl_core:mossycobble",
{pickaxey=1, material_stone=1},
{"default_mossycobble.png"},
S("Mossy Cobblestone Stairs"),
mcl_sounds.node_sound_stone_defaults(), 0.8, 0.8)
mcl_stairs.register_slab("mossycobble", "mcl_core:mossycobble",
{pickaxey=1, material_stone=1},
{"default_mossycobble.png"},
S("Mossy Cobblestone Slab"),
mcl_sounds.node_sound_stone_defaults(), 6, 2,
S("Double Mossy Cobblestone Slab"))
mcl_stairs.register_stair("brick_block", "mcl_core:brick_block",
{pickaxey=1, material_stone=1},
{"default_brick.png"},
S("Brick Stairs"),
mcl_sounds.node_sound_stone_defaults(), 0.8, 0.8)
mcl_stairs.register_slab("brick_block", "mcl_core:brick_block",
{pickaxey=1, material_stone=1},
{"default_brick.png"},
S("Brick Slab"),
mcl_sounds.node_sound_stone_defaults(), 6, 2,
S("Double Brick Slab"))
mcl_stairs.register_stair("sandstone", "mcl_core:sandstone",
{pickaxey=1, material_stone=1}, {pickaxey=1, material_stone=1},
{"mcl_core_sandstone_top.png", "mcl_core_sandstone_bottom.png", "mcl_core_sandstone_normal.png"}, {"mcl_core_sandstone_top.png", "mcl_core_sandstone_bottom.png", "mcl_core_sandstone_normal.png"},
S("Sandstone Stairs"), S("Sandstone Stairs"),
mcl_sounds.node_sound_stone_defaults(), 0.8, 0.8, mcl_sounds.node_sound_stone_defaults(), 0.8, 0.8,
nil, "mcl_core:sandstone") --fixme: extra parameter from previous release nil, "mcl_core:sandstone") --fixme: extra parameter from previous release
mcl_stairs.register_slab("sandstone", "group:normal_sandstone", mcl_stairs.register_slab("sandstone", "mcl_core:sandstone",
{pickaxey=1, material_stone=1}, {pickaxey=1, material_stone=1},
{"mcl_core_sandstone_top.png", "mcl_core_sandstone_bottom.png", "mcl_core_sandstone_normal.png"}, {"mcl_core_sandstone_top.png", "mcl_core_sandstone_bottom.png", "mcl_core_sandstone_normal.png"},
S("Sandstone Slab"), S("Sandstone Slab"),
mcl_sounds.node_sound_stone_defaults(), 6, 2, mcl_sounds.node_sound_stone_defaults(), 6, 2,
S("Double Sandstone Slab"), "mcl_core:sandstone") --fixme: extra parameter from previous release S("Double Sandstone Slab"), "mcl_core:sandstone") --fixme: extra parameter from previous release
mcl_stairs.register_stair_and_slab_simple("sandstonesmooth2", "mcl_core:sandstonesmooth2", S("Smooth Sandstone Stairs"), S("Smooth Sandstone Slab"), S("Double Smooth Sandstone Slab"))
mcl_stairs.register_stair("redsandstone", "group:red_sandstone", mcl_stairs.register_stair("sandstonesmooth2", "mcl_core:sandstonesmooth2",
{pickaxey=1, material_stone=1},
{"mcl_core_sandstone_top.png"},
S("Smooth Sandstone Stairs"),
mcl_sounds.node_sound_stone_defaults(), 0.8, 0.8)
mcl_stairs.register_slab("sandstonesmooth2", "mcl_core:sandstonesmooth2",
{pickaxey=1, material_stone=1},
{"mcl_core_sandstone_top.png"},
S("Smooth Sandstone Slab"),
mcl_sounds.node_sound_stone_defaults(), 6, 2,
S("Double Smooth Sandstone Slab"))
mcl_stairs.register_stair("redsandstone", "mcl_core:redsandstone",
{pickaxey=1, material_stone=1}, {pickaxey=1, material_stone=1},
{"mcl_core_red_sandstone_top.png", "mcl_core_red_sandstone_bottom.png", "mcl_core_red_sandstone_normal.png"}, {"mcl_core_red_sandstone_top.png", "mcl_core_red_sandstone_bottom.png", "mcl_core_red_sandstone_normal.png"},
S("Red Sandstone Stairs"), S("Red Sandstone Stairs"),
mcl_sounds.node_sound_stone_defaults(), 0.8, 0.8, mcl_sounds.node_sound_stone_defaults(), 0.8, 0.8,
nil, "mcl_core:redsandstone") --fixme: extra parameter from previous release nil, "mcl_core:redsandstone") --fixme: extra parameter from previous release
mcl_stairs.register_slab("redsandstone", "group:red_sandstone", mcl_stairs.register_slab("redsandstone", "mcl_core:redsandstone",
{pickaxey=1, material_stone=1}, {pickaxey=1, material_stone=1},
{"mcl_core_red_sandstone_top.png", "mcl_core_red_sandstone_bottom.png", "mcl_core_red_sandstone_normal.png"}, {"mcl_core_red_sandstone_top.png", "mcl_core_red_sandstone_bottom.png", "mcl_core_red_sandstone_normal.png"},
S("Red Sandstone Slab"), S("Red Sandstone Slab"),
mcl_sounds.node_sound_stone_defaults(), 6, 2, mcl_sounds.node_sound_stone_defaults(), 6, 2,
S("Double Red Sandstone Slab"), "mcl_core:redsandstone") --fixme: extra parameter from previous release S("Double Red Sandstone Slab"), "mcl_core:redsandstone") --fixme: extra parameter from previous release
mcl_stairs.register_stair_and_slab_simple("redsandstonesmooth2", "mcl_core:redsandstonesmooth2", S("Smooth Red Sandstone Stairs"), S("Smooth Red Sandstone Slab"), S("Double Smooth Red Sandstone Slab"))
mcl_stairs.register_stair("redsandstonesmooth2", "mcl_core:redsandstonesmooth2",
{pickaxey=1, material_stone=1},
{"mcl_core_red_sandstone_top.png"},
S("Smooth Red Sandstone Stairs"),
mcl_sounds.node_sound_stone_defaults(), 0.8, 0.8)
mcl_stairs.register_slab("redsandstonesmooth2", "mcl_core:redsandstonesmooth2",
{pickaxey=1, material_stone=1},
{"mcl_core_red_sandstone_top.png"},
S("Smooth Red Sandstone Slab"),
mcl_sounds.node_sound_stone_defaults(), 6, 2,
S("Double Smooth Red Sandstone Slab"))
-- Intentionally not group:stonebrick because of mclx_stairs -- Intentionally not group:stonebrick because of mclx_stairs
mcl_stairs.register_stair("stonebrick", "mcl_core:stonebrick", mcl_stairs.register_stair("stonebrick", "mcl_core:stonebrick",
@ -91,20 +186,30 @@ mcl_stairs.register_slab("stonebrick", "mcl_core:stonebrick",
mcl_sounds.node_sound_stone_defaults(), 6, 2, mcl_sounds.node_sound_stone_defaults(), 6, 2,
S("Double Stone Bricks Slab"), "mcl_core:stonebrick") --fixme: extra parameter from previous release S("Double Stone Bricks Slab"), "mcl_core:stonebrick") --fixme: extra parameter from previous release
mcl_stairs.register_stair("quartzblock", "group:quartz_block", mcl_stairs.register_stair("quartzblock", "mcl_nether:quartz_block",
{pickaxey=1, material_stone=1}, {pickaxey=1, material_stone=1},
{"mcl_nether_quartz_block_top.png", "mcl_nether_quartz_block_bottom.png", "mcl_nether_quartz_block_side.png"}, {"mcl_nether_quartz_block_top.png", "mcl_nether_quartz_block_bottom.png", "mcl_nether_quartz_block_side.png"},
S("Quartz Stairs"), S("Quartz Stairs"),
mcl_sounds.node_sound_stone_defaults(), 0.8, 0.8, mcl_sounds.node_sound_stone_defaults(), 0.8, 0.8,
nil, "mcl_nether:quartz_block") --fixme: extra parameter from previous release nil, "mcl_nether:quartz_block") --fixme: extra parameter from previous release
mcl_stairs.register_slab("quartzblock", "group:quartz_block", mcl_stairs.register_slab("quartzblock", "mcl_nether:quartz_block",
{pickaxey=1, material_stone=1}, {pickaxey=1, material_stone=1},
{"mcl_nether_quartz_block_top.png", "mcl_nether_quartz_block_bottom.png", "mcl_nether_quartz_block_side.png"}, {"mcl_nether_quartz_block_top.png", "mcl_nether_quartz_block_bottom.png", "mcl_nether_quartz_block_side.png"},
S("Quartz Slab"), S("Quartz Slab"),
mcl_sounds.node_sound_stone_defaults(), 6, 2, mcl_sounds.node_sound_stone_defaults(), 6, 2,
S("Double Quartz Slab"), "mcl_nether:quartz_block") --fixme: extra parameter from previous release S("Double Quartz Slab"), "mcl_nether:quartz_block") --fixme: extra parameter from previous release
mcl_stairs.register_stair_and_slab_simple("quartz_smooth", "mcl_nether:quartz_smooth", S("Smooth Quartz Stairs"), S("Smooth Quartz Slab"), S("Double Smooth Quartz Slab")) mcl_stairs.register_stair("quartz_smooth", "mcl_nether:quartz_smooth",
{pickaxey=1, material_stone=1},
{"mcl_nether_quartz_block_bottom.png"},
S("Smooth Quartz Stairs"),
mcl_sounds.node_sound_stone_defaults(), 0.8, 0.8)
mcl_stairs.register_slab("quartz_smooth", "mcl_nether:quartz_smooth",
{pickaxey=1, material_stone=1},
{"mcl_nether_quartz_block_bottom.png"},
S("Smooth Quartz Slab"),
mcl_sounds.node_sound_stone_defaults(), 6, 2,
S("Double Smooth Quartz Slab"))
mcl_stairs.register_stair_and_slab("nether_brick", "mcl_nether:nether_brick", mcl_stairs.register_stair_and_slab("nether_brick", "mcl_nether:nether_brick",
{pickaxey=1, material_stone=1}, {pickaxey=1, material_stone=1},
@ -121,27 +226,73 @@ mcl_stairs.register_stair_and_slab("red_nether_brick", "mcl_nether:red_nether_br
mcl_sounds.node_sound_stone_defaults(), 6, 2, mcl_sounds.node_sound_stone_defaults(), 6, 2,
S("Double Red Nether Brick Slab"), nil) S("Double Red Nether Brick Slab"), nil)
mcl_stairs.register_stair_and_slab_simple("end_bricks", "mcl_end:end_bricks", S("End Stone Brick Stairs"), S("End Stone Brick Slab"), S("Double End Stone Brick Slab")) mcl_stairs.register_stair_and_slab("end_bricks", "mcl_end:end_bricks",
{pickaxey=1, material_stone=1},
{"mcl_end_end_bricks.png"},
S("End Stone Brick Stairs"),
S("End Stone Brick Slab"),
mcl_sounds.node_sound_stone_defaults(), 6, 2,
S("Double End Stone Brick Slab"), nil)
mcl_stairs.register_stair("purpur_block", "group:purpur_block", mcl_stairs.register_stair("purpur_block", "mcl_end:purpur_block",
{pickaxey=1, material_stone=1}, {pickaxey=1, material_stone=1},
{"mcl_end_purpur_block.png"}, {"mcl_end_purpur_block.png"},
S("Purpur Stairs"), S("Purpur Stairs"),
mcl_sounds.node_sound_stone_defaults(), 6, 1.5, mcl_sounds.node_sound_stone_defaults(), 6, 1.5,
nil) nil)
mcl_stairs.register_slab("purpur_block", "group:purpur_block", mcl_stairs.register_slab("purpur_block", "mcl_end:purpur_block",
{pickaxey=1, material_stone=1}, {pickaxey=1, material_stone=1},
{"mcl_end_purpur_block.png"}, {"mcl_end_purpur_block.png"},
S("Purpur Slab"), S("Purpur Slab"),
mcl_sounds.node_sound_stone_defaults(), 6, 2, mcl_sounds.node_sound_stone_defaults(), 6, 2,
S("Double Purpur Slab")) S("Double Purpur Slab"))
mcl_stairs.register_stair_and_slab_simple("prismarine", "mcl_ocean:prismarine", S("Prismarine Stairs"), S("Prismarine Slab"), S("Double Prismarine Slab")) mcl_stairs.register_stair("prismarine", "mcl_ocean:prismarine",
{pickaxey=1, material_stone=1},
{{name="mcl_ocean_prismarine_anim.png", animation={type="vertical_frames", aspect_w=32, aspect_h=32, length=45.0}}},
S("Prismarine Stairs"),
mcl_sounds.node_sound_stone_defaults(), 6, 1.5,
nil)
mcl_stairs.register_slab("prismarine", "mcl_ocean:prismarine",
{pickaxey=1, material_stone=1},
{{name="mcl_ocean_prismarine_anim.png", animation={type="vertical_frames", aspect_w=32, aspect_h=32, length=45.0}}},
S("Prismarine Slab"),
mcl_sounds.node_sound_stone_defaults(), 6, 2,
S("Double Prismarine Slab"))
mcl_stairs.register_stair_and_slab_simple("mud_brick", "mcl_mud:mud_bricks", S("Mud Brick Stair"), S("Mud Brick Slab"), S("Double Mud Brick Slab")) mcl_stairs.register_stair("prismarine_brick", "mcl_ocean:prismarine_brick",
{pickaxey=1, material_stone=1},
{"mcl_ocean_prismarine_bricks.png"},
S("prismarine Brick Stairs"),
mcl_sounds.node_sound_stone_defaults(), 6, 1.5,
nil)
mcl_stairs.register_slab("prismarine_brick", "mcl_ocean:prismarine_brick",
{pickaxey=1, material_stone=1},
{"mcl_ocean_prismarine_bricks.png"},
S("prismarine Brick Slab"),
mcl_sounds.node_sound_stone_defaults(), 6, 2,
S("Double prismarine_brick Slab"))
mcl_stairs.register_stair_and_slab_simple("prismarine_brick", "mcl_ocean:prismarine_brick", S("Prismarine Brick Stairs"), S("Prismarine Brick Slab"), S("Double Prismarine Brick Slab")) mcl_stairs.register_stair("prismarine_dark", "mcl_ocean:prismarine_dark",
mcl_stairs.register_stair_and_slab_simple("prismarine_dark", "mcl_ocean:prismarine_dark", S("Dark Prismarine Stairs"), S("Dark Prismarine Slab"), S("Double Dark Prismarine Slab")) {pickaxey=1, material_stone=1},
{"mcl_ocean_prismarine_dark.png"},
S("prismarine Brick Stairs"),
mcl_sounds.node_sound_stone_defaults(), 6, 1.5,
nil)
mcl_stairs.register_slab("prismarine_dark", "mcl_ocean:prismarine_dark",
{pickaxey=1, material_stone=1},
{"mcl_ocean_prismarine_dark.png"},
S("Dark Prismarine Slab"),
mcl_sounds.node_sound_stone_defaults(), 6, 2,
S("Double Dark Prismarine Slab"))
mcl_stairs.register_stair_and_slab("mud_brick", "mcl_mud:mud_bricks",
{pickaxey=1, material_stone=1},
{"mcl_mud_bricks.png"},
S("Mud Brick Stairs"),
S("Mud Brick Slab"),
mcl_sounds.node_sound_stone_defaults(), 6, 2,
S("Double Mud Brick Slab"), nil)
mcl_stairs.register_slab("andesite_smooth", "mcl_core:andesite_smooth", mcl_stairs.register_slab("andesite_smooth", "mcl_core:andesite_smooth",
{pickaxey=1}, {pickaxey=1},

View File

@ -2,10 +2,24 @@ mcl_stonecutter
=============== ===============
Adds the stonecutter block. Used to cut stone like materials into stairs, slabs, etc. Also used as the Stone Mason Villager's jobsite. Adds the stonecutter block. Used to cut stone like materials into stairs, slabs, etc. Also used as the Stone Mason Villager's jobsite.
### Adding recipes
* To add a new custom stonecutter recipe, use `mcl_stonecutter.register_recipe(input, output, count)`
* `input` must be a name of a registered item
* `output` must also be a name of a registered item
* `count` should be a number denoting output count, this defaults to 1 for `nil` and invalid values
* a number with a fraction passed as count will be rounded down
* Stairs, slabs and walls get their recipes registered automatically
* Recipe chains are followed automatically, so any recipes taking `output` of another recipe as input will also be taking `input` of that recipe as their input
### Displaying the Stonecutter menu
* To display the stonecutter formspec to a player use `mcl_stonecutter.show_stonecutter_form(player)`
License of code License of code
--------------- ---------------
See the main MineClone 2 README.md file. See the main MineClone 2 README.md file.
Author: PrairieWind Author: PrairieWind, ChrisPHP, cora, Herowl, AFCMS
License of media License of media
---------------- ----------------

View File

@ -2,10 +2,371 @@
--||||| STONECUTTER ||||| --||||| STONECUTTER |||||
--||||||||||||||||||||||| --|||||||||||||||||||||||
-- TO-DO: -- The stonecutter is implemented just like the crafting table, meaning the node doesn't have any state.
-- * Add GUI -- Instead it trigger the display of a per-player menu. The input and output slots, the wanted item are stored into the player meta.
--
-- Player inventory lists:
-- * stonecutter_input (1)
-- * stonecutter_output (1)
-- Player meta:
-- * mcl_stonecutter:selected (string, wanted item name)
-- * mcl_stonecutter:switch_stack (int, wanted craft count: 1 or 64 = once or until full stack)
local S = minetest.get_translator(minetest.get_current_modname())
local S = minetest.get_translator("mcl_stonecutter")
local C = minetest.colorize
local show_formspec = minetest.show_formspec
local formspec_name = "mcl_stonecutter:stonecutter"
mcl_stonecutter = {}
---Table of registered recipes
---
---```lua
---mcl_stonecutter.registered_recipes = {
--- ["mcl_core:input_item"] = {
--- ["mcl_core:output_item"] = 1,
--- ["mcl_core:output_item2"] = 2,
--- },
---}
---```
---@type table<string, table<string, integer>>
mcl_stonecutter.registered_recipes = {}
---Registers a recipe for the stonecutter
---@param input string Name of a registered item
---@param output string Name of a registered item
---@param count? integer Number of the output, defaults to `1`
function mcl_stonecutter.register_recipe(input, output, count)
if mcl_stonecutter.registered_recipes[input] and mcl_stonecutter.registered_recipes[input][output] then
minetest.log("warning",
"[mcl_stonecutter] Recipe already registered: [" .. input .. "] -> [" .. output .. " " .. count .. "]")
return
end
if not minetest.registered_items[input] then
error("Input is not a registered item: " .. input)
end
if not minetest.registered_items[output] then
error("Output is not a registered item: " .. output)
end
count = count or 1
if not mcl_stonecutter.registered_recipes[input] then
mcl_stonecutter.registered_recipes[input] = {}
end
mcl_stonecutter.registered_recipes[input][output] = count
local fallthrough = mcl_stonecutter.registered_recipes[output]
if fallthrough then
for o, c in pairs(fallthrough) do
mcl_stonecutter.register_recipe(input, o, c * count)
end
end
for i, recipes in pairs(mcl_stonecutter.registered_recipes) do
for name, c in pairs(recipes) do
if name == input then
mcl_stonecutter.register_recipe(i, output, c * count)
end
end
end
end
---Minetest currently (5.7) doesn't prevent using `:` characters in field names
---But using them prevent the buttons from beeing styled with `style[]` elements
---https://github.com/minetest/minetest/issues/14013
---@param itemname string
local function itenname_to_fieldname(itemname)
return string.gsub(itemname, ":", "__")
end
---@param fieldname string
local function fieldname_to_itemname(fieldname)
return string.gsub(fieldname, "__", ":")
end
-- Get the player configured stack size when taking items from creative inventory
---@param player mt.PlayerObjectRef
---@return integer
local function get_stack_size(player)
return player:get_meta():get_int("mcl_stonecutter:switch_stack")
end
-- Set the player configured stack size when taking items from creative inventory
---@param player mt.PlayerObjectRef
---@param n integer
local function set_stack_size(player, n)
player:get_meta():set_int("mcl_stonecutter:switch_stack", n)
end
---Build the formspec for the stonecutter with given output button
---@param player mt.PlayerObjectRef
---@param items? table<string, integer>
local function build_stonecutter_formspec(player, items)
local meta = player:get_meta()
local selected = meta:get_string("mcl_stonecutter:selected")
items = items or {}
-- Buttons are 3.5 / 4 = 0.875 wide
local c = 0
local items_content = "style_type[item_image_button;noclip=false;content_offset=0]" ..
(selected ~= "" and "style[" .. itenname_to_fieldname(selected) .. ";border=false;bgimg=mcl_inventory_button9_pressed.png;bgimg_pressed=mcl_inventory_button9_pressed.png;bgimg_middle=2,2]" or "")
for name, count in table.pairs_by_keys(items) do
c = c + 1
local x = ((c - 1) % 4) * 0.875
local y = (math.floor((c - 1) / 4)) * 0.875
items_content = items_content ..
string.format("item_image_button[%f,%f;0.875,0.875;%s;%s;]", x, y,
name, itenname_to_fieldname(name), tostring(count))
end
local formspec = table.concat({
"formspec_version[4]",
"size[11.75,10.425]",
"label[0.375,0.375;" .. C(mcl_formspec.label_color, S("Stone Cutter")) .. "]",
-- Pattern input slot
mcl_formspec.get_itemslot_bg_v4(1.625, 2, 1, 1),
"list[current_player;stonecutter_input;1.625,2;1,1;]",
-- Container background
"image[4.075,0.7;3.6,3.6;mcl_inventory_background9.png;2]",
-- Style for item image buttons
"style_type[item_image_button;noclip=false;content_offset=0]",
-- Scroll Container with buttons if needed
"scroll_container[4.125,0.75;3.5,3.5;scroll;vertical;0.875]",
items_content,
"scroll_container_end[]",
-- Scrollbar
-- TODO: style the scrollbar correctly when possible
"scrollbaroptions[min=0;max=" ..
math.max(math.floor(#items / 4) + 1 - 4, 0) .. ";smallstep=1;largesteps=1]",
"scrollbar[7.625,0.7;0.75,3.6;vertical;scroll;0]",
-- Switch stack size button
"image_button[9.75,0.75;1,1;mcl_stonecutter_saw.png^[verticalframe:3:1;__switch_stack;]",
"label[10.25,1.5;" .. C("#FFFFFF", tostring(get_stack_size(player))) .. "]",
"tooltip[__switch_stack;" .. S("Switch stack size") .. "]",
-- Output slot
mcl_formspec.get_itemslot_bg_v4(9.75, 2, 1, 1, 0.2),
"list[current_player;stonecutter_output;9.75,2;1,1;]",
-- Player inventory
"label[0.375,4.7;" .. C(mcl_formspec.label_color, S("Inventory")) .. "]",
mcl_formspec.get_itemslot_bg_v4(0.375, 5.1, 9, 3),
"list[current_player;main;0.375,5.1;9,3;9]",
mcl_formspec.get_itemslot_bg_v4(0.375, 9.05, 9, 1),
"list[current_player;main;0.375,9.05;9,1;]",
"listring[current_player;stonecutter_output]",
"listring[current_player;main]",
"listring[current_player;stonecutter_input]",
"listring[current_player;main]",
})
return formspec
end
---Display stonecutter menu to a player
---@param player mt.PlayerObjectRef
function mcl_stonecutter.show_stonecutter_form(player)
show_formspec(player:get_player_name(), formspec_name,
build_stonecutter_formspec(player,
mcl_stonecutter.registered_recipes[player:get_inventory():get_stack("stonecutter_input", 1):get_name()]))
end
---Change the selected output item.
---@param player mt.PlayerObjectRef
---@param item_name? string The item name of the output
function set_selected_item(player, item_name)
player:get_meta():set_string("mcl_stonecutter:selected", item_name and item_name or "")
end
minetest.register_on_joinplayer(function(player)
local inv = player:get_inventory()
inv:set_size("stonecutter_input", 1)
inv:set_size("stonecutter_output", 1)
set_selected_item(player, nil)
--The player might have items remaining in the slots from the previous join; this is likely
--when the server has been shutdown and the server didn't clean up the player inventories.
mcl_util.move_player_list(player, "stonecutter_input")
player:get_inventory():set_list("stonecutter_output", {})
end)
minetest.register_on_leaveplayer(function(player)
set_selected_item(player, nil)
mcl_util.move_player_list(player, "stonecutter_input")
player:get_inventory():set_list("stonecutter_output", {})
end)
---Update content of the stonecutter output slot with the input slot and the selected item
---@param player mt.PlayerObjectRef
function update_stonecutter_slots(player)
local meta = player:get_meta()
local inv = player:get_inventory()
local input = inv:get_stack("stonecutter_input", 1)
local recipes = mcl_stonecutter.registered_recipes[input:get_name()]
local output_item = meta:get_string("mcl_stonecutter:selected")
local stack_size = meta:get_int("mcl_stonecutter:switch_stack")
if recipes then
if output_item then
local recipe = recipes[output_item]
if recipe then
local cut_item = ItemStack(output_item)
local count = math.min(math.floor(stack_size/recipe), input:get_count()) * recipe
if count < recipe then count = recipe end
cut_item:set_count(count)
inv:set_stack("stonecutter_output", 1, cut_item)
else
inv:set_stack("stonecutter_output", 1, nil)
end
else
inv:set_stack("stonecutter_output", 1, nil)
end
else
inv:set_stack("stonecutter_output", 1, nil)
end
mcl_stonecutter.show_stonecutter_form(player)
end
--Drop items in slots and reset selected item on closing
minetest.register_on_player_receive_fields(function(player, formname, fields)
if formname ~= formspec_name then return end
if fields.quit then
mcl_util.move_player_list(player, "stonecutter_input")
player:get_inventory():set_list("stonecutter_output", {})
return
end
if fields.__switch_stack then
local switch = 1
if get_stack_size(player) == 1 then
switch = 64
end
set_stack_size(player, switch)
update_stonecutter_slots(player)
mcl_stonecutter.show_stonecutter_form(player)
return
end
for field_name, value in pairs(fields) do
if field_name ~= "scroll" then
local itemname = fieldname_to_itemname(field_name)
player:get_meta():set_string("mcl_stonecutter:selected", itemname)
set_selected_item(player, itemname)
update_stonecutter_slots(player)
mcl_stonecutter.show_stonecutter_form(player)
break
end
end
end)
minetest.register_allow_player_inventory_action(function(player, action, inventory, inventory_info)
if action == "move" then
if inventory_info.to_list == "stonecutter_output" then
return 0
end
if inventory_info.from_list == "stonecutter_output" and inventory_info.to_list == "stonecutter_input" then
if inventory:get_stack(inventory_info.to_list, inventory_info.to_index):is_empty() then
return inventory_info.count
else
return 0
end
end
if inventory_info.from_list == "stonecutter_output" then
local selected = player:get_meta():get_string("mcl_stonecutter:selected")
local istack = inventory:get_stack("stonecutter_input", 1)
local recipes = mcl_stonecutter.registered_recipes[istack:get_name()]
if not selected or not recipes then return 0 end
local recipe = recipes[selected]
local remainder = inventory_info.count % recipe
if remainder ~= 0 then
return 0
end
end
elseif action == "put" then
if inventory_info.to_list == "stonecutter_output" then
return 0
end
if inventory_info.from_list == "stonecutter_output" then
local selected = player:get_meta():get_string("mcl_stonecutter:selected")
local istack = inventory:get_stack("stonecutter_input", 1)
local recipes = mcl_stonecutter.registered_recipes[istack:get_name()]
if not selected or not recipes then return 0 end
local recipe = recipes[selected]
local remainder = inventory_info.stack:get_count() % recipe
if remainder ~= 0 then
return 0
end
end
end
end)
function remove_from_input(player, inventory, crafted_count)
local meta = player:get_meta()
local selected = meta:get_string("mcl_stonecutter:selected")
local istack = inventory:get_stack("stonecutter_input", 1)
local recipes = mcl_stonecutter.registered_recipes[istack:get_name()]
local stack_size = meta:get_int("mcl_stonecutter:switch_stack")
-- selected should normally never be nil, but just in case
if selected and recipes then
local recipe = recipes[selected]
local count = crafted_count/recipe
if count < 1 then count = 1 end
istack:set_count(math.max(0, istack:get_count() - count))
inventory:set_stack("stonecutter_input", 1, istack)
end
end
minetest.register_on_player_inventory_action(function(player, action, inventory, inventory_info)
if action == "move" then
if inventory_info.to_list == "stonecutter_input" or inventory_info.from_list == "stonecutter_input" then
update_stonecutter_slots(player)
return
elseif inventory_info.from_list == "stonecutter_output" then
remove_from_input(player, inventory, inventory_info.count)
update_stonecutter_slots(player)
end
elseif action == "put" then
if inventory_info.listname == "stonecutter_input" or inventory_info.listname == "stonecutter_input" then
update_stonecutter_slots(player)
end
elseif action == "take" then
if inventory_info.listname == "stonecutter_output" then
remove_from_input(player, inventory, inventory_info.stack:get_count())
update_stonecutter_slots(player)
end
end
end)
minetest.register_node("mcl_stonecutter:stonecutter", { minetest.register_node("mcl_stonecutter:stonecutter", {
description = S("Stone Cutter"), description = S("Stone Cutter"),
@ -16,36 +377,45 @@ minetest.register_node("mcl_stonecutter:stonecutter", {
"mcl_stonecutter_bottom.png", "mcl_stonecutter_bottom.png",
"mcl_stonecutter_side.png", "mcl_stonecutter_side.png",
"mcl_stonecutter_side.png", "mcl_stonecutter_side.png",
{name="mcl_stonecutter_saw.png", {
animation={ name = "mcl_stonecutter_saw.png",
type="vertical_frames", animation = {
aspect_w=16, type = "vertical_frames",
aspect_h=16, aspect_w = 16,
length=1 aspect_h = 16,
}}, length = 1
{name="mcl_stonecutter_saw.png", }
animation={ },
type="vertical_frames", {
aspect_w=16, name = "mcl_stonecutter_saw.png",
aspect_h=16, animation = {
length=1 type = "vertical_frames",
}} aspect_w = 16,
aspect_h = 16,
length = 1
}
}
}, },
use_texture_alpha = "clip", use_texture_alpha = "clip",
drawtype = "nodebox", drawtype = "nodebox",
paramtype = "light", paramtype = "light",
paramtype2 = "facedir", paramtype2 = "facedir",
groups = { pickaxey=1, material_stone=1 }, groups = { pickaxey = 1, material_stone = 1 },
node_box = { node_box = {
type = "fixed", type = "fixed",
fixed = { fixed = {
{-0.5, -0.5, -0.5, 0.5, 0.0625, 0.5}, -- NodeBox1 { -0.5, -0.5, -0.5, 0.5, 0.0625, 0.5 }, -- NodeBox1
{-0.4375, 0.0625, 0, 0.4375, 0.5, 0}, -- NodeBox2 { -0.4375, 0.0625, 0, 0.4375, 0.5, 0 }, -- NodeBox2
} }
}, },
_mcl_blast_resistance = 3.5, _mcl_blast_resistance = 3.5,
_mcl_hardness = 3.5, _mcl_hardness = 3.5,
sounds = mcl_sounds.node_sound_stone_defaults(), sounds = mcl_sounds.node_sound_stone_defaults(),
on_rightclick = function(pos, node, player, itemstack)
if not player:get_player_control().sneak then
mcl_stonecutter.show_stonecutter_form(player)
end
end,
}) })
minetest.register_craft({ minetest.register_craft({

View File

@ -1,4 +1,4 @@
name = mcl_stonecutter name = mcl_stonecutter
author = PrairieWind author = PrairieWind, ChrisPHP, cora, Herowl, AFCMS
description = This mod adds a stonecutter, which is used to cut stone like materials, and used as the jobsite for the Stone Mason Villager. description = This mod adds a stonecutter, which is used to cut stone like materials, and used as the jobsite for the Stone Mason Villager.
depends = mcl_sounds depends = mcl_sounds, mcl_util

View File

@ -0,0 +1,2 @@
# textdomain: mcl_sus_stew
Suspicious Stew=Soupe suspecte

View File

@ -282,6 +282,8 @@ function mcl_walls.register_wall(nodename, description, source, tiles, inventory
{source, source, source}, {source, source, source},
} }
}) })
mcl_stonecutter.register_recipe(source, nodename)
end end
end end

View File

@ -1,3 +1,3 @@
name = mcl_walls name = mcl_walls
depends = mcl_core, mcl_end, mcl_ocean, mcl_nether, mcl_sounds, mcl_mud depends = mcl_core, mcl_end, mcl_ocean, mcl_nether, mcl_sounds, mcl_mud, mcl_stonecutter
optional_depends = doc optional_depends = doc

View File

@ -14,4 +14,4 @@ mcl_walls.register_wall("mcl_walls:prismarine", S("Prismarine Wall"), "mcl_ocean
mcl_walls.register_wall("mcl_walls:endbricks", S("End Stone Brick Wall"), "mcl_end:end_bricks") mcl_walls.register_wall("mcl_walls:endbricks", S("End Stone Brick Wall"), "mcl_end:end_bricks")
mcl_walls.register_wall("mcl_walls:netherbrick", S("Nether Brick Wall"), "mcl_nether:nether_brick") mcl_walls.register_wall("mcl_walls:netherbrick", S("Nether Brick Wall"), "mcl_nether:nether_brick")
mcl_walls.register_wall("mcl_walls:rednetherbrick", S("Red Nether Brick Wall"), "mcl_nether:red_nether_brick") mcl_walls.register_wall("mcl_walls:rednetherbrick", S("Red Nether Brick Wall"), "mcl_nether:red_nether_brick")
mcl_walls.register_wall("mcl_walls:mudbrick", S("Mud Brick Wall"), "mcl_mud:mud_bricks") mcl_walls.register_wall("mcl_walls:mudbrick", S("Mud Brick Wall"), "mcl_mud:mud_bricks")

View File

@ -18,7 +18,7 @@ if minetest.settings:get_bool("mcl_builtin_commands_overide", true) then
register_chatcommand_alias("tell", "msg") register_chatcommand_alias("tell", "msg")
register_chatcommand_alias("w", "msg") register_chatcommand_alias("w", "msg")
register_chatcommand_alias("tp", "teleport") register_chatcommand_alias("tp", "teleport")
rename_chatcommand("clear", "clearinv") register_chatcommand_alias("clearinventory", "clearinv")
minetest.register_chatcommand("banlist", { minetest.register_chatcommand("banlist", {
description = S("List bans"), description = S("List bans"),
@ -27,4 +27,14 @@ if minetest.settings:get_bool("mcl_builtin_commands_overide", true) then
return true, S("Ban list: @1", minetest.get_ban_list()) return true, S("Ban list: @1", minetest.get_ban_list())
end, end,
}) })
end
minetest.register_chatcommand("clear", {
description = S("List clear commands"),
func = function(name)
return true, S("To clear inventory use /clearinv or /clearinventory").."\n"..
S("To clear mobs use /clearmobs").."\n"..
S("To clear the weather use /weather clear").."\n"..
S("Clearing the chat is not possible, you can hide the chat using \"Toggle chat log\" key (default F2) on PC or the chat icon on the mobile version")
end,
})
end

View File

@ -146,8 +146,9 @@ minetest.register_globalstep(function(dtime)
local food_level = mcl_hunger.get_hunger(player) local food_level = mcl_hunger.get_hunger(player)
local food_saturation_level = mcl_hunger.get_saturation(player) local food_saturation_level = mcl_hunger.get_saturation(player)
local player_health = player:get_hp() local player_health = player:get_hp()
local max_tick_timer = tonumber(minetest.settings:get("mcl_health_regen_delay")) or 4
if food_tick_timer > 4.0 then if food_tick_timer > max_tick_timer then
food_tick_timer = 0 food_tick_timer = 0
-- let hunger work always -- let hunger work always
@ -173,7 +174,7 @@ minetest.register_globalstep(function(dtime)
end end
end end
elseif food_tick_timer > 0.5 and food_level == 20 and food_saturation_level > 0 then -- fast regeneration elseif food_tick_timer > max_tick_timer and food_level == 20 and food_saturation_level > 0 then -- fast regeneration
if player_health > 0 and player_health < 20 then if player_health > 0 and player_health < 20 then
food_tick_timer = 0 food_tick_timer = 0
player:set_hp(player_health+1) player:set_hp(player_health+1)

View File

@ -0,0 +1,7 @@
# textdomain: mcl_music
You need the debug privilege in order to turn ingame music on or off for somebody else!=Vous avez besoin du privilège "debug“ pour allumer ou éteindre la musique pour une autre personne dans le jeu !
Couldn't find player @1!= Le joueur @1 est introuvable !
Set music for @1 to: @2=Jouer la musique @2 pour @1
Turns music for yourself or another player on or off.=Joue ou arrête la musique pour vous ou un autre joueur.
on=on
off=off

View File

@ -73,6 +73,9 @@ mcl_elytra_rocket_speed (Elytra rocket speed cap) float 3.5 2.0 5.5
# If enabled, chat messages are shown to everyone when a player dies. # If enabled, chat messages are shown to everyone when a player dies.
mcl_showDeathMessages (Show death messages) bool true mcl_showDeathMessages (Show death messages) bool true
# If enabled, chat messages are shown to everyone when a player makes an advancement.
mcl_showAdvancementMessages (Show advancement messages) bool true
# If enabled, the recipe book will progressively be filled with new recipes that can be crafted from all items you ever have had in your inventory. # If enabled, the recipe book will progressively be filled with new recipes that can be crafted from all items you ever have had in your inventory.
# Recommended for new players and for a spoiler-free gameplay experience. # Recommended for new players and for a spoiler-free gameplay experience.
# If disabled, all recipes will be shown. # If disabled, all recipes will be shown.
@ -95,6 +98,10 @@ mcl_creative_dig_speed (Creative mode dig speed) float 0.2
# If enabled the hunger mechanic will be active # If enabled the hunger mechanic will be active
mcl_enable_hunger (Hunger mechanic) bool true mcl_enable_hunger (Hunger mechanic) bool true
# Health regeneration delay when hunger bar is full
# Default:4
mcl_health_regen_delay (Health regen delay) float 4 0
[Mobs] [Mobs]
# If enabled, mobs will spawn naturally. This does not affect # If enabled, mobs will spawn naturally. This does not affect
# affect mob spawners. # affect mob spawners.